How to rewrite randomly generated nginx path by taking the first segment? - nginx

I have a prestashop instance that generates a random URL for admin access. The only rule is that the path starts with "admin".
The following rule works just fine, but its hardcoded by hand:
location /admin6908ewwh6/ {
if (!-e $request_filename) {
rewrite ^/.*$ /admin6908ewwh6/index.php last;
}
}
I tried to rewrite it into this:
location ^(/admin.*?)(\w+)/ {
if (!-e $request_filename) {
rewrite ^/.*$ $1/index.php last;
}
}
But this is not working, and I don't know why since according to this regex matcher ( https://www.regextester.com/102896 ) when I put a ^(/admin.*?)(\w+) regex against a test string /admin6908ewwh6/index.php/sell/catalog/products/new?_token=_JC1fQPwgvwnhZTWyeGVTy4nET350GC4Aro888TuzDA& it just grabs what I need to take.
Can somebody explain me why these two location blocks are not equivalent?

The problem is $1. Numeric captures are assigned by the last regular expression to be evaluated, which in this case is the rewrite statement (despite there being no parentheses in the regular expression).
One solution is to make the capture in the rewrite statement, for example:
location /admin {
if (!-e $request_filename) {
rewrite ^(/admin[^/]+)/ $1/index.php last;
}
}
Or without the if block:
location /admin {
try_files $uri $uri/ #admin;
}
location #admin {
rewrite ^(/admin[^/]+)/ $1/index.php last;
}
Or without the rewrite statement:
location ~ ^(/admin[^/]+)/ {
try_files $uri $uri/ $1/index.php$is_args$args;
}
Ensure that this last location block is below the block that processes .php URIs.

Related

Nginx rewrite - not working

I have simple nginx rewrite I can't get to work.
I have this url:
https://example.com/accessories/3427-tote-bag-grey-212345050033.html
I want to redirect to:
https://example.com/dk/accessories/3427-tote-bag-grey-212345050033.html
My nginx config:
location / {
index /index.php;
rewrite ^/dk/$1/$2.html /$1/$2.html last;
}
any idea want is wrong here?
$1 and $2 are used for captures. You have to use pattern to with groups to create captures
Try below
location / {
index /index.php;
rewrite ^/([^/]+)/([^/]+).html$ /dk/$1/$2.html last;
}
Or you can do something like below
location / {
index /index.php;
location /accessories/ {
alias <yourroot>/dk/accessories/;
}
}

Nginx Proxy_pass try_files drop to location handler

I'm running into small hick up with try_files in combination with proxy_pass (or alias for that matter).
Current config:
location /staticsrv {
alias /var/www/static/trunk/;
#proxy_pass http://static.localtest.nl/;
}
location ~ ^/staticsrv/images/gallery/(.*)$ {
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^(.*)$ /index.php/?c=media&m=index&imag=$uri;
}
However for every file it gets dropped to the rewrite rule as it doesn't exist.
Is there a "trick" (read correct config) to fix my misfortune? Or is it just not possible? Both domains will eventually be on the same server so we can work with alias and proxy_pass.
Thanks in advance
Your location ~ ^/staticsrv/images/gallery/(.*)$ needs a root or an alias to construct a local path for try_files to try. Also, you do not necessarily need a regular expression here:
location /staticsrv/images/gallery/ {
alias /var/www/static/trunk/images/gallery/;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}
proxy_pass will not work with try_files as one deals with remote content and the other with local content.
I try to avoid using alias and try_files in the same location block because of this open bug.
A possible work around would be to use another intermediate URI that closely matches the document root:
location /staticsrv/images/gallery/ {
rewrite ^/staticsrv(.+)$ /trunk$1 last;
}
location /trunk {
internal;
root /var/www/static;
try_files $uri #img_proxy;
}
location #img_proxy {
rewrite ^ /index.php/?c=media&m=index&imag=$uri last;
}

Rewriting URL with nginx

I want to rewrite urls with nginx.
Samples:
/something.php (not regular file) -> /index.php?site=something
/somthingelse.php (regular file) -> /somethingelse.php
My current rules doesn't work:
location / {
try_files $uri $uri/ #rules;
}
location #rules {
rewrite ^/([a-z]*)\.php$ /index.php?s=$1;
}
Your /something.php url is catched by location ~ \.php$, so you need rewrite it there.
location ~ \.php$ {
try_files $uri #rules;
# usual php stuff
...;
}
location #rules {
rewrite ^/([a-z]*)\.php$ /index.php?s=$1 last;
return 404;
}
For existing file /somefile.php it will be processed by PHP as usual.
For non-existent /other.php it will be internally redirected to #rules where it will be rewritten to /index.php?s=other and gets again into location ~ \.php and finally processed by PHP.
And for non-existent /w31rd.php (where w31rd doesn't match [a-z]* regexp) you will get 404 Not Found error page.

Nginx rewrites static files to index.html

I'm trying to work on a single page app - I need to rewrite all urls to index.html but allow existing static files (.css and .js) to be served as they normally would be in a browser.
This is the code that I'm trying to use to re-write but it serves my static files to the re-write as well
if (!-e $request_filename)
{
rewrite ^/(.*)$ /?/$1 last;
break;
}
you don't actually need a rewrite for that in nginx, just use try_files like so:
location / {
try_files $uri /index.html;
}
what this does is for all url's:
try the exact static filename match, and serve it if present
if 1 didn't serve anything, then server /index.html instead
see http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files
This should work:
server {
listen 1.2.3.4:80;
server_name domain.eu;
root /usr/local/www/domain.eu/public;
try_files $uri #rewrites;
location #rewrites {
rewrite ^/favicon.ico$ /pictures/favicon.ico last;
rewrite ^ /index.html last;
}
}

nginx : rewrite rule to remove /index.html from the $request_uri

I've seen a few ways to rewrite the $request_uri and add the index.html to it when that particular file exists in the file system, like so:
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
but i was wondering if the opposite is achievable:
i.e. when somebody requests http://example.com/index.html, they're redirected to http://example.com
Because the nginx regexp is perl compatible, i tried something like this:
if ( $request_uri ~* "index\.html$" ) {
set $new_uri $request_uri ~* s/index\.html//
rewrite $1 permanent;
}
but it was mostly a guesswork, is there any good documentation describing the modrewrite for nginx ?
I use the following rewrite in the top level server clause:
rewrite ^(.*)/index\.html$ $1 permanent;
Using this alone works for most URLs, like http://example.com/bar/index.html, but it breaks http://example.com/index.html. To resolve this, I have the following additional rule:
location = /index.html {
rewrite ^ / permanent;
try_files /index.html =404;
}
The =404 part returns a 404 error when the file is not found.
I have no idea why the first rewrite alone isn't sufficient.
The following config allowed me to redirect /index.html to / and /subdir/index.html to /subdir/:
# Strip "index.html" (for canonicalization)
if ( $request_uri ~ "/index.html" ) {
rewrite ^(.*)/ $1/ permanent;
}
For some reason most of the solutions mentioned here did not work. The ones that worked gave me errors with missing / in the url. This solution works for me.
Paste in your location directive.
if ( $request_uri ~ "/index.html" ) {
rewrite ^/(.*)/ /$1 permanent;
}
This one works:
# redirect dumb search engines
location /index.html {
if ($request_uri = /index.html) {
rewrite ^ $scheme://$host? permanent;
}
}
For the root /index.html, the answer from Nicolas resulted in a redirect loop, so I had to search for other answers.
This question was asked on the nginx forums and the answer there worked better.
http://forum.nginx.org/read.php?2,217899,217915
Use either
location = / {
try_files /index.html =404;
}
location = /index.html {
internal;
error_page 404 =301 $scheme://domain.com/;
}
or
location = / {
index index.html;
}
location = /index.html {
internal;
error_page 404 =301 $scheme://domain.com/;
}
This is working for me:
rewrite ^(|/(.*))/index\.html$ /$2 permanent;
It covers both the root instance /index.html and lower instances /bar/index.html
The first part of the regex basically translates as: [nothing] or /[something] - in the first case $2 is an empty string so you redirect to just /, in the second case $2 is [something] so you redirect to /[something]
I actually went a bit fancier to cover index.html, index.htm, and index.php
rewrite ^(|/(.*))/index\.(html?|php)$ /$2 permanent;
The solutions quoting $scheme://domain.com/ assume that the domain is hard-coded. It was not in my case and so I used:
location / {
...
rewrite index.html $scheme://$http_host/ redirect;
... }

Resources