Nginx ignore part of the URL - nginx

I want nginx to ignore the first 4 characters of a URL. For example, I want /1234/test.html to be served by the file /test.html.
How can I do that with nginx?

This can be achieved with a rewrite, probably inside the server block.
The regular expression needs to be pretty specific to avoid a rewrite loop, so careful consideration of all URIs is necessary.
If the four character prefix is always digits, this may work for you:
rewrite "^/\d{4}/(.*)$" /$1 last;
Notice the "s around the regex because of the presence of {}s.

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.

Rewrite url without hash in 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.

Different rewrite rule redirect same url

rewrite ^/old-url /new-url permanent;
rewrite ^/old-url/old-url-sub /new-url/new-url-sub permanent;
2 urls are (/old-url and old-url/old-url-sub) redirected to same url (/new-url)
What is the problem ?
The problem is that the regular expression ^/old-url matches /old-url and /old-url/old-url-sub and /old-url/anything-else.
So the first rewrite statement is invoked for both URIs.
If you want a regular expression to match the entire string only, you need to use an anchor at the front and the back of the pattern. As you know, the ^ anchors the front of the pattern, whereas $ anchors the back of the pattern.
Try:
rewrite ^/old-url$ /new-url permanent;
If you were trying to redirect /old-url/xxx to /new-url/xxx where xxx is anything, you would use a single rewrite statement with a capture:
rewrite ^/old-url(/.*)?$ /new-url$1 permanent;
See this useful resource on regular expressions.

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 "/".

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