Rewrite url without hash in nginx - nginx

I am trying to use Nginx rewrite static file path to strip the hash added for cache busting. The hash is always 10-symbol long. For example,
/min/3rd.party.min.1234567899.js has to become /min/3rd.party.min.js
I have tried this, but it doesn't work (fails at configtest) and also looks way to complicated.
location /min/ {
root /opt/app/public;
rewrite ^.*(?<=(.))[a-z0-9]{10}[.](?=(js|css))[js|css]$ $1$3;
}

I have no idea how you arrived at your regular expression pattern, but the following seems to work:
rewrite "^(.*)\.\w{10}\.(js|css)$" $1.$2 break;
Any pattern that contains a brace, must be placed within quotes. Use the break suffix to process the rewritten URI within the same location. See this document for details, and this useful resource on regular expressions.

Related

nginx rewrite: rewrite and pass original URI arguments along

I simply want to rewrite:
https://example.com/id/123?a=1&b=2 (and maybe more variables, or maybe none)
to
https://example.com/load.php?id=123&a=1&b=2 (...and whatever others, or maybe none after id)
That's it. So simple, right?
Yet I think there is a secret unwritten rule that says docs for nginx URL rewriting must be dense, unclear, and devoid of any useful examples. ;-) I have googled and experimented for a while now. Can't get it to fly.
I tried this, and several variations of it, with no luck:
rewrite ^/id/(.*)$ /load.php?id=$1&$args last;
I think I'm close. Can you help?
The rewrite directive automatically appends the original arguments (adding a ? or & separator as required) unless the replacement string ends with a ?.
For example:
rewrite ^/id/(.*)$ /load.php?id=$1 last;
The above will internally redirect /id/123?x=abc to /load.php?id=123&x=abc.
See this document for details.

Nginx rewrite to css factory

I have a rule which is not working correctly.
I need it so that whenever URL xxx.com/forum/css.php is hit, it is re-written to xxx.com/forum/core/css.php.
I have written the following location block for it:
location ~^ /forum/css.php {
rewrite ^ /forum/core/css.php permanent;
}
Also needing to be taken into account is that the file is a factory so it accepts parameters, the url being hit actually looks like xxx.com/forum/css.php?x=123&y=string. Will this also be taken into account in the re-writes or does it need to be specified? Sorry if the question seems silly I am just beginning to work with servers! Thanks fellow coders!
To rewrite a single URI (with or without query string) you could use a location =:
location = /forum/css.php {
rewrite ^ /forum/core/css.php permanent;
}
The rewrite directive appends the query string (unless terminated with ?). See this and this for more.

Nginx rewrite with conditional destination

I have a site with two RESTful URL schemes:
foo.com/model/id and
foo.com/model/id/action
The actual pages served by these URLs are in the form of
$model.php?id=$id and
$model_$action.php?id=$id respectively.
I have a single regular expression that will match both cases ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ and I'd like to use a single Nginx rule to rewrite for both types of URLs, but I'm not sure how to do this. In pseudocode I imagine the rule would look something like this
rewrite ^(\w+)s/([A-z0-9]+)(?:/(\w+))?/?$ /(($3) ? $1_$3.php?$id=$2 : $1.php?$id=2)
This isn't valid syntax (so far as I know), but can something like this be done in Nginx?
Rewrite the possible urls in turn starting with the longest to the shortest to that overlapping matching strings, "/model/id" in this case, would be matched in the longer url string first.
location / {
# For "/model/id/action" to "$model_$action.php?id=$id"
rewrite ^/(.+)/(.+)/(.+)(/?)$ $1_$3.php?id=$2 last;
# For "/model/id" to "$model.php?id=$id"
rewrite ^/(.+)/(.+)(/?)$ $1.php?id=$2 last;
}
location ~ .+\.php$ {
# Handle PHP
}
The "(/?)" is just in case the urls sometimes come with an ending slash. If they never do, it can be removed. In this case, it will probably be best to specifically always add a closing slash and have "(/?)" as "/".

How to make nginx-gridfs properly use the result of regex location match

In short, this doesn't work:
location ~* /grid/(.+)/ {
gridfs filestore field=filename type=string root_collection=storage.$1;
}
This is using https://github.com/mdirolf/nginx-gridfs
There are multiple problems with it. This is just an FYI, as I don't think it can be done with location regex, because of:
group is not processes, and $1 is being used verbatim as a "storage.$1" collection name
Somehow, probably in the C code, file name is picked up by stripping characters from the match, by removing exact number of characters that is specified in regex. Meaning, "/grid/(.+)/" is 10 characters long, and this is how many characters are stripped from the entire url (minus domain, obviously). I've tested this quite a bit (short from just going through C code), and this is what it's doing.
I'm assuming this can be still done with rewrite somehow or another nginx config.
As a last resort, I'll reach out to the project maintainer, but nginx's configuration is flexible enough, it seems, to work around the issues, as this works as advertized:
location ~* /grid/ABC/ {
gridfs filestore field=filename type=string root_collection=storage.ABC;
}

Rewrite Rule in Nginx

I conisder moving to Nginx but I want you to ask if is possible to rewrite urls into that schema, and if you could help me a bit:
A url like http://example.com/username into profile.php?u=username. But then, will I have problems in accessing other pages like e.g. home.php
A url like http://example.php/questions/102039/that-question into questions.php?quid=102039
Thank you very much!
Yes, it is possible to rewrite URLs with Nginx.
Your first example can be handled easily by wrapping the rewrite with a block which checks if a file (home.php in your example) exists; if it doesn't, then it tries the redirect into the profile.php request. (See the try_files syntax for this.)
Your second example is just as simple:
Rewrite ^/questions/(\d+) /questions.php?quid=$1
(Because the matching expression is not anchored at the end, it should accept any string after the digits, but I haven't checked that so I'd recommend you test it.)

Resources