I have a web server sitting behind Nginx. If there is an error, then I want to fetch some information from the url and pass it on to a static file as parameters. I have configured Nginx to fetch the url parameters from the url using $arg_param_name. However, I also need to fetch a String from the url path itself. So if the url is as below:
www.website.com/path1/path2?arg1=val&arg2=someval
Now, how can I parse this url to fetch the last path (path2 in this case)? My location directive is as below:
location ~*/path1/{
...
}
The url need not always have the same number of paths. It can also have 3 paths. So I can't use $1, $2 etc. I need to fetch the last path, i.e the path which is immediately followed by the url parameters (the ? symbol).
Related
Quick question. We have two apps. Ports 3001 and 3002. Our domain is www.domain.com.
What we want to have it once person enters www.domain.com/pathname we want them to be redirected into another app's specific path.
How to do it?
We already came up to this in my nginx
location /pathname/ {
proxy_pass http://127.0.0.1:3002/;
}
It nearly works. However, our app under 3002 works on path /#/pathname.
We can access it by typing www.domain.com/pathname/#/pathname. We want to access same link by typing www.domain.com/pathname.
How to shorten it? What do I miss?
(upd) Just redirect /pathname to /pathname/#/pathname
According to your comment, you want just redirect from /pathname to /pathname/#/pathname
Try these combined directives:
rewrite to append # and fragment identifier
and proxy_pass to reverse proxy to the app.
E.g.:
location /short_path_name/ {
rewrite ^ /pathname/#/$uri permanent;
break;
}
location /pathname/ {
proxy_pass http://127.0.0.1:3002/;
}
And use www.domain.com/short_path_name/ link for your app.
Unfortunately, nginx can't see the fragment identifier
Unfortunately, you can't. Because server never get the fragment identifier from browser.
The fragment identifier functions differently to the rest of the URI: its processing is exclusively client-sided with no participation from the web server
Naming a bit amusing, but it has a long history. See TBL (1997): Fragment Identifiers on URIs:
The URI reference is a thing you build by taking a URI for an information object, adding a "#" sign and then a Fragement identifier. (The last term is historical, so try not to thinl of it necessarily identifying a fragment).
Workarounds
There are workarounds, e.g. encode hashtag symbol into %23 but I'm not sure is it your way.
Handle request arguments with nginx
Note: rewriting url, nginx can preserve request arguments if you add ? at the end of rewrite directive.
See Nginx rewrite manual:
If a replacement string includes the new request arguments, the previous request arguments are appended after them. If this is undesired, putting a question mark at the end of a replacement string avoids having them appended, for example:
rewrite ^/users/(.*)$ /show?user=$1? last;
I'm using http.FileServer in Go to serve some static file into a directory.
This is how I map it using mux as a router:
r.PathPrefix("/download").Handler(http.StripPrefix("/download", http.FileServer(http.Dir(dirPath)))).Methods("GET")
where dirPath is an absolute path of a directory in my file system.
Now it seems to work fine when asking the directory listing with localhost:8080/download, because it returns a page like this
<pre>
a.xml
b.zip
</pre>
Unfortunately the links are broken because I expect them to be mapped, for example to localhost:8080/download/a.xml , while file server maps them to localhost:8080/a.xml.
How can I make my directory listing keep the /download path prefix in links?
The problem is the pattern you register you handler with: "/download".
There are 2 problems with it:
The generated URLs are wrong because the handler returned by the http.FileServer() function generates relative URLs to files and subfolders; relative to the root folder passed to http.FileServer(), and if your page is available under the path /download, a relative URL like href="a.xml" will be resolved to /a.xml, and not to /download/a.xml.
Even if the URLs would be good, the files would not be served as the requests would not get routed to your handled (to the file server handler). You must add a trailing slash, as "/download" only matches this single path, and not all paths starting with it. Add a trailing slash: "/download/" and it will match the rooted subtree /download/*.
So the solution is:
r.PathPrefix("/download/").Handler(
http.StripPrefix("/download", http.FileServer(http.Dir(dirPath))),
).Methods("GET")
This is documented at http.ServeMux:
Patterns name fixed, rooted paths, like "/favicon.ico", or rooted subtrees, like "/images/" (note the trailing slash).
Note that even though we're now using the "/download/" registered path, users are not required to type the trailing slash in the browser, as leaving that out the server will send a redirect to the path that ends with a trailing slash. This will happen automatically. This is also documented at http.ServeMux:
If a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering "/images/" causes ServeMux to redirect a request for "/images" to "/images/", unless "/images" has been registered separately.
Read related question: Go web server is automatically redirecting POST requests
Here's a simple file server app using only the standard library:
http.Handle("/dl/",
http.StripPrefix("/dl", http.FileServer(http.Dir("/home/bob/Downloads"))),
)
panic(http.ListenAndServe("localhost:8080", nil))
I want to create an HTTP nginx server which will take whatever POST request comes in
/some/path
will append the post body to some_internal_path/some/path.log
Where some and path would be variables. So /another/place would append to some_internal_path/another/place.log
How can I do this with nginx?
I want to be able to use a relative path in a query string parameter but it seems that I can't without a rewrite rule to point to the absolute path on the server. This is my pseudo-working url with the query string:
www.example.com/service?req=/var/www/nginx/public/files/name.jpg
but I would like to have my users and website use the following url:
www.example.com/service?req=/files/name.jpg
(ie. hiding the root directory/path of the site and making the url shorter/cleaner)
The rewrite is needed either ways, either on nginx level, or app level, and I would prefer the app level more than splitting my config into 2 places, it should be a simple append.
In NGINX how can I redirect any URL that contains ?SID=(insert long string of numbers/letters)
To a clean URL that is exactly the same but without this query? Other get query must remain untouched.
Also I only want to perform this redirect if the URL also does not contain '/sgps/'
Any takers?