Nginx rewrite local file path - nginx

Is it possible to make this kind of url rewrite?
Request url:
https://image.domain.com/listing/1_10_iP2LROSEafC01584630756.jpg
Rewrite to:
https://image.domain.com/images/i/P/2/L/iP2LROSEafC01584630756.jpg
If /images/i/P/2/L/iP2LROSEafC01584630756.jpg exists in server, it's served, if not then query is redirected to php file /make_image.php
Thank you!

Request url: https://image.domain.com/listing/1_10_iP2LROSEafC01584630756.jpg Rewrite to: https://image.domain.com/images/i/P/2/L/iP2LROSEafC01584630756.jpg
If you mean an external redirect, then this is achieved using the rewrite directive. Place the statement in the server block, or within a location block that handles these kinds of request (i.e. URIs beginning with /listing/ and/or ending with .jpg).
Your question does not state what 1_10_ means, but let's assume that you want the two arbitrary numbers ignored.
For example:
rewrite ^/listing/\d+_\d+_(.)(.)(.)(.)(.*)$ /images/$1/$2/$3/$4/$5 permanent;
See this document for details.
If /images/i/P/2/L/iP2LROSEafC01584630756.jpg exists in server, it's served, if not then query is redirected to php file /make_image.php
This is achieved using a try_files statement within a location block that processes requests for URIs beginning with /images/.
For example:
location /images/ {
try_files $uri /make_image.php;
}
See this document for details.

Related

Nginx serve files on specific location from specific folder

I want NGINX to serve serve files from a location within a server.
As an example, I would like the url http://domain/ss/image.png to serve the file located within /home/data/screenshots/image.png
So far, I have attempted to use a regex in this manner
location ~ ^/ss/(.*) {
root /home/data/screenshots;
add_header content-type "image/png";
try_files $1 /$1;
}
however it appears that this location is never reached, being handled by the location spefcified to / (which in my case is a redirect).
I am not flexible with renaming/changing any of the file structure of the project and want to achieve this result with just the NGINX config modification.
As described by Richard's comment on the question, it appears that my regex approach was correct, however my issue was the usage of the try_files function.

Nginx redirect to different location with part of the request header

I want to redirect certain requests to different location, but with part of the request header, example:
https://example.com/something/value ---> https://example.com/something/index.php?var=value
pseudo-code:
location ^~ /something/$value {
return 301 https://$host/something/index.php?var=$value;
}
The location only needs to match that part of the URI which is constant. If /something/index.php and /something/value is the same prefix, then you do not want to use the ^~ modifier, otherwise the PHP file will not be found. See this document for details.
Use rewrite to capture the "value" part of the URI and append it as an argument.
For example:
location /something/ {
rewrite ^/something/(.*)$ /something/index.php?var=$1 last;
}
If you want an external redirection use rewrite...permanent instead of rewrite...last. See this document for details.

double try_files directive for the same location in nginx

I discovered a nginx config snippet in serveral gists and config examples (mostly for PHP apps):
#site root is redirected to the app boot script
location = / {
try_files #site #site;
}
#all other locations try other files first and go to our front controller if none of them exists
location / {
try_files $uri $uri/ #site;
}
But I just do not get it: Does the first try_files directive ever match? To me this looks like some nonsense hacking.
Please confirm or explain why not - thanks :)
This is what happens here:
The first location = / is only used when the path in the request is /, e.g. http://example.com/. The second location /is used for all other URLs, e.g. http://example.com/foo or http://example.com/bar.
The reason for the first location is to avoid any interference from index-directives that do a redirect to index.html or something similar.
Inside the first location the try_files-directive first looks for a file named #site, which does not exist and then redirects to the named location #site. The reason for this construct is that the redirect to the named location is purely internal, i.e. the #site location can not be accessed directly from the client and the $uri is kept unmodified during this redirect (which would not be the case for other redirects). The first parameter #site can be anything except a real existing file. I prefer to call it DUMMY for clarity.
The second location tries static files first and, if not found, then also redirects to the named location.

Rewrite all params requests to index.php with Nginx

i've URL like this
http://www.example.com/index.php?page=profile&id=324&opt=edit&cat=23&...
I wish I had
http://www.example.com/profile/324/edit/23...
I read several tutorials on how to remove php extension but do not know how to pass other parameters
Thanks to everyone
UPDATE
Sovled with PHP solution.
nginx:
location / {
try_files $uri $uri/ /index.php;
}
PHP:
$params = explode("/",$_SERVER['REQUEST_URI']);
and use them
Actually it's pretty easy if those params are always in the same order as your example.
Add a rewrite rule in your nginx config.
rewrite ^/index.php?page=(.*)&id=(.*)&opt=(.*)&cat=(.*)(&.*)$ /$1/$2/$3/$4
But if the order of params changes in every request, we may need another solution.
UPDATE
nginx stores request args in variables like $arg_name, the name after $arg_ if the actual request param name. So you just need to rewrite requests to index.php with a tailing question mark to url style you want.
rewrite ^/index.php? /$arg_page/$arg_id/$arg_opt/$arg_cat;

Nginx match location for root path and all other paths separately

I am running Play framework server behind nginx server. At the root path, I am serving static website and all other paths should be redirected to the Play server. I have the following default.conf file in /etc/nginx/conf.d (The system is RHEL 6.7)
# to match the root path only to serve static website
location = / {
root /usr/share/nginx/html;
index index.html index.htm;
# try_files $uri $uri.html $uri/ /index.html;
}
# to match the cms login page
location /cms/ {
proxy_pass http://localhost:9000/;
}
# to match all the requests from the cms
location / {
proxy_pass http://localhost:9000/;
}
However, this configuration doesn't match the root path request. It gives 404 error. However, if I remove the third location rule, then it serves the static page at the root path.
Also, I noticed that first time I tried this, it worked. But now, it's not working any more. Please help.
The result you are getting is most likely due to the 2nd and 3rd location blocks not having "index" directives set. Except for well understood specific reasons, such as overriding the default index file type(s), the "index" should always be set at least within the server context or, preferably, within the http context. Similarly, the "root" directive should be set in the server context.
With your config, when a request hits the 3rd location block, there is no information your what to do with it. Actually, the 2nd block should not be needed from what you have described.
Also, as you are proxying to what appears to be another webserver, you need to ensure that this has the equivalent of "index" and "root" set.
Not sure exactly how the backend you are using works with respect to these. If not configurable there, then you must ensure that that every request hitting it has the URI spelt out fully.
To start with, depending on how exactly things are set up on your server, I will move the "index" and "root" directives up to the "server" level

Resources