Configure nginx to rewrite hashes on all paths - nginx

I use nginx as a static file server first and try to rewrite all uri if they contain hashes to point to a mock directory.
It might be more clear with an example
let's say the user request pages url like theses :
/api/some/path/to/ecbac7cb-21ca-3d22-98ed-4d063f138d0b/some/other/path/02167621-5c01-45c5-98ba-eb3ba1bf4b2a/list
/api/some/other/path/to/ecbac7cb-21ca-3d22-98ed-4d063f138d0b
I want to try to get the file at first but the fallback would be somthing like this
/api/some/path/to/__any_hash__/some/other/path/__any_hash__/list.json
/api/some/other/path/to/__any_hash__.json
here is a config I tried to far... but obviously, it's not working.
server {
...
location /api {
try_files $uri $uri/index.html $uri.html $uri.json $uri.xml #rewrites;
}
location #rewrites {
rewrite /([0-9\-a-f]{36})/ __any_hash__ break;
try_files $uri.xml $uri.json #backend;
}
Anyone have an idea?

Your location #rewrites should probably look like this:
location #rewrites {
rewrite "^(.*)/[0-9\-a-f]{36}(/.*)$" $1/__any_hash__$2 last;
return 404;
}
The $1 and $2 capture the URI fragment before and after the hash to be substituted. The last causes the location /api to be reattempted after the substitution. The process will loop until all of the substitutions are made. The return 404 is only invoked if the fully substituted URI fails to find a file.

Related

What's wrong with Nginx location match rule

I do read the Nginx documentation about location matching.
I know about the prioriy of modifier.
And here is my config.
location = /login {
root /usr/share/nginx/mysite;
try_files $uri /index.html;
}
location = / {
root /usr/share/nginx/mysite;
try_files $uri /index.html;
}
location ~ /(.*) {
proxy_pass http://127.0.0.1:8080/$1;
}
What I want is when I type "http://example.com/" "http://example.com/login" , the request will goes index.html which is a React App , and other request will goes proxy pass to my Tomcat application which is bind 8080 port.
But "http://example.com/" "http://example.com/login" request goes proxy_pass , what?
According to Nginx documentation, the "=" modifier is "Priority one"
I expect it is an exact match.
If an exact match is found, the search terminates
I also use https://nginx.viraptor.info/ test for it.
It shows what I expected.
But it looks like the running server not act what Nginx doc said.
Any ideas?
The last parameter of a try_files statement is special. It can be a status code, a named location, or the URI of an internal redirect. See this document for details.
In your current configuration, Nginx generates an internal redirection to /index.html and restarts the search for a matching location. So the /index.html request is sent to the proxy_pass.
Place /index.html before the last parameter so that it's interpreted as a file parameter and is processed within the same location block. The $uri is unnecessary in this particular case.
For example:
root /usr/share/nginx/mysite;
location = /login {
try_files /index.html =404;
}
location = / {
try_files /index.html =404;
}
location / {
proxy_pass http://127.0.0.1:8080;
}
The =404 will never be reached. The final location can be simplified and the capture is unnecessary.

How to use my index.htm in this location script?

I need URL http://myexample.org (root) redirecting to my local index.htm, not rewriting it to Github... How to do it?
I was testing many variations of location = / { try_files ...} but no one works. Using a UBUNTU 16 LTS server.
/etc/nginx/sites-available/myexample.org
server {
server_name myexample.org;
root /var/www/myexample.org;
index index.html index.htm;
# ?? location =/ {...} is not working!
location / {
# also not work a root rewrite
# rewrite ^/?$ index.htm break;
rewrite ^/?git$
http://github.com/myexample-org/test
break;
rewrite ^/?tickets$
http://github.com/myexample-org/test/issues
break;
rewrite ^/?(.+)$
http://github.com/myexample-org/test/$1
break;
}
}
Change your last rewrite directive to match ^/(.+)$
location = / will not work for an index, as the rewritten URI will match location / which will then hit your final rewrite statement.
Your original solution (a few questions ago) with the named location, should work fine:
root /path/to/file;
index index.htm;
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/... http://example.com/...;
rewrite ^/... http://example.com/...;
rewrite ^/... http://example.com/...;
}
Assuming that a file called /path/to/file/index.htm exists on this server. The break flag is unnecessary as the destination URL begins with http://. If you want to add a flag, the redirect or permanent flag would be pertinent. See this document for details.

nginx rewrite & parameter full-url and file extensions

I will try to be brief. I have the following nginx rewrite url:
rewrite ^/(.*)?$ /index.php?completeURL=$1 last;
I want a url like:
http://mywebsite.com/http://www.otherwebsite.com/dir1/dirx/article.php&id=2&category=1
request:
http://mywebsite.com/index.php?completeURL=http://www.otherwebsite.com/dir1/dirx/article.php&id=2&category=1
Currently the nginx rule have a problem. Example: If the parameter contains a .php extension he looks for that file on my server.
Example: http://mywebsite.com/dir1/dirx/article.php
How can I solve this problem in your opinion?
UPDATE:
here the nginx configuration (and rewrite) files:
(config) https://gist.github.com/ivanionut/cc53c9de372b932c3937d9394d3b448c
(rewrite) https://gist.github.com/ivanionut/4df3ad9b858a54ae01461ab078adffb6
The simplest solution (assuming that the server does nothing else other than serve index.php) is to remove the usual location ~ \.php$ block and perform a rewrite ... break; in the same block as the fastcgi_pass. There are a number of ways of achieving this, including:
location / {
rewrite ^/(.*)?$ /index.php?completeURL=$1 break;
fastcgi_pass ...
...
}
An alternative strategy is to perform the rewrite only if a local file does not already exist, but you need to ensure that .php files are tested too. For example:
location / {
try_files $uri $uri/ #rewrite;
}
location ~ \.php$ {
try_files $uri #rewrite;
fastcgi_pass ...
...
}
location #rewrite {
rewrite ^/(.*)?$ /index.php?completeURL=$1 last;
}

Nginx rewrite a folder with exclude

i am working on nginx webserver.
I want to redirect all urls inside folder1 www.site.com/folder1/ but not the subfolder1 www.site.com/folder1/subfolder1
I created these rules to nginx configuration but no luck.
location = /folder/subfolder {
}
location /folder {
rewrite ^/folder(.*) www.redirect.com permanent;
}
Am i missing something?
Ok so here's a refined answer including some of the comments I've read plus one of mine, to be able to access the assets inside the subfolder I added the try_files, and the 301 redirect in all other urls was added for the redirection.
location /folder/subfolder {
try_files $uri $uri/ =404;
}
location /folder {
return 301 $scheme://example.com;
}
Your new set of rules should be as follows. I am assuming that valid file hits are okay (i.e. the user knew the file). If you do not want this behaviour, replace try_files with the content of the #rw block:
location /folder {
try_files $uri $uri/ #rw;
}
location #rw {
rewrite ^/folder/([^\/]*) http://www.redirect.com/ permanent;
}
These should work.
Remove the "=" because that's for "exact" match. So it only matches the folder itself, and a request for "/folder/subfolder/a_file.html" won't match that block. Also you need to add $scheme in your rewrite rule. And if you just want to redirect to the home page (http://www.redirect.com), you can remove the "$1" part.
location /folder/subfolder {
}
location /folder {
rewrite ^/folder(.*)$ $scheme://www.redirect.com$1 permanent;
}

Configuring nginx to return a 404 when a URL matches a pattern

I want nginx to return a 404 code when it receives a request which matches a pattern, e.g., /test/*. How can I configure nginx to do that?
location /test/ {
return 404;
}
Need to add "^~" to give this match a higher priority than regex location blocks.
location ^~ /test/ {
return 404;
}
Otherwise you will be in some tricky situation. For example, if you have another location block such as
location ~ \.php$ {
...
}
and someone sends a request to http://your_domain.com/test/bad.php, that regex location block will be picked by nginx to serve the request. Obviously it's not what you want. So be sure to put "^~" in that location block!
Reference: https://nginx.org/en/docs/http/ngx_http_core_module.html#location
location ^~ /test/ {
internal;
}

Resources