Nginx: Using the try_files Directive to create a pretty URLs - url-rewriting

I want anything inside the /widget/ folder IE:
www.site.com/widget/1/2/3
rewritten as
www.site.com/index.php?type=widget&a=1&b=2&c=3
using the try_files directive
any files outside of the widget folder IE:
www.site.com/cool_stuff.php
should be unaffected by this rewrite
After many failed attempts I'm unable to get this to work. Any help would be much appreciated!

try_files receives a list of arguments representing which files Nginx should pass the request on to. For example: try_files $uri $uri/ index.php =404 informs Nginx that it should try to match a request against $uri (the requested path as a file name, post-rewrites) $uri/ (the requested path as a directory, post-rewrites), then to try index.php, and if all else fails, return an HTTP 404 Not Found error code. Another example: to map every request to a index.php, regardless of it's URI, use try_files index.php =404;.
In this case, I don't think try_files is the best directive for your requirements. Instead, consider using rewrite rules to transform /widget/1/2/3 into /index.php?type=widget&a=1&b=2&c=3

Related

Rewrite rules for image sharing

I am making an image storage for screencloud, doing so i'd like to have theses urls working:
Any urls that ends with a file extension redirects as normal:
http://serv/ -> /index.php
http://serv/index.php -> /index.php
Any urls that do not have extension or is png as returns the file:
http: // serv/scr1801172229 -> /scr/scr1801172229.png
http: // serv/scr1801172229.png -> /scr/scr1801172229.png
I tried to learn how to use rewrite from nginx though I can't find any good tutorial. And every thing I tried did not work, including this which is the closest thing I got:
rewrite /index /index.php break;
rewrite /(.*)$ /scr/$1.png break;
rewrite /(.*)$.png /scr/$1.png break;
The last line does nothing (It goes 404)
The first line works to get the index displayed though resources are not loaded, anything else than index won't work and I can't get my .php in the url as usual.
The middle line actually works correctly
I do not understand all of your requirements, but it seems that some of your URIs map to files in the document root, and some map to files in a subdirectory called scr.
Rather than using rewrite ... break you may be able to test the various locations and file extensions by using a try_files directive. For example:
root /path/to/root;
location / {
try_files $uri /scr$uri /src$uri.png /index.php;
}
location ~ \.php$ {
...
}
See this document for more.

nginx cache check with try_files

I have an image server that writes to a cache directory (it just uses the same path in the url request at present). I have confirmed that on the initial request (i.e. nothing in the cache), a new file is written however on following requests, try_files does not successfully find the file.
My nginx.conf is:
http {
server {
listen 8080;
# serve tiles if not in the cache
location #image_server {
content_by_lua_file "/Users/tim/work/chickpea/serve_image.lua";
}
# capture tile request e.g. /tile/l8/091080/rgb/20160924/10/938/597.jpg
# regex named capture groups for each param
location ~ ^/tile/(?<layer>[^/]+)/(?<pathrow>[^/]+)/(?<type>[^/]+)/(?<date>[^/]+)/(?<z>[^/]+)/(?<x>[^/]+)/(?<y>[^.]+) {
root cache;
set $cachepath "cache/$layer/$pathrow/$type/$date/$z/$x/$y.jpg";
try_files $cachepath #image_server;
add_header X-Static hit;
}
..
I have confirmed that on a request of /tile/l8/091080/rgb/20160924/10/938/597.jpg, the $cachepath is cache/l8/091080/rgb/20160924/10/938/597.jpg and that the 597.jpg is in the correct path. I have tried a $cachepath both with and without the leading cache/ and neither seems to work.
There were two changes required to make this work:
Make the root directive an absolute path, otherwise it was effectively /usr/local/nginx/cache
Add a leading forward slash to the $cachepath variable. As the root directive value and $cachepath are appended together to determine the complete filepath.

NGINX rewrite condition issues

I have a location on my nginx server like /folder/. In that folder there are .jpg files and a .php script.
What I am trying to achieve is the following:
When a user accesses a url like: http://mywebsite.com/folder/10-11 nginx will search for 10-11 file, 10-11.png file, 10-11.jpg file and display it (if the file is on the server). This section works just fine.
Now when a user accesses the same url, if the file does not exist I want the user to be redirected to that php script.
Bellow is the part of the nginx config which works. All the image files in that folder are like 10-10, 21-19, 90-20 etc (2 digit number - 2 digit number).
location /app/comics/lqthumb/ {
try_files $uri /$uri.png /$uri.jpg;
}
The other nginx section should look like this:
location /app/comics/lqthumb/ {
rewrite ^/app/comics/lqthumb/(.*?)-(.*?)$ /app/comics/lqthumb/thumbgen.php?chapter=$1&page=$2 permanent;
}
The ideea is to combine this rule together. How can I do an if else statement or something similar? I have tried several combination, read a lot of forum posts or even answers from here but I cant make it work.
If you have questions please let me know!
You combine these by using a named location. The last element of a try_files can invoke a default action to enter a named location to process the rewrite.
root /path/to/root;
location /app/comics/lqthumb {
try_files $uri $uri.png $uri.jpg #thumbgen;
}
location #thumbgen {
rewrite ^/app/comics/lqthumb/(.*?)-(.*?)$ /app/comics/lqthumb/thumbgen.php?chapter=$1&page=$2;
}
location ~ \.php$ { ... }
I have removed the spurious / you placed before $uri. I assume you have a location which invokes the PHP interpreter, otherwise, you could put those directives into the named location. I wasn't sure if you intended the redirect to be permanent. With no flag an internal redirect is performed transparently to the user.
See try_files documentation.

Using regex in nginx location block for variables

Using nginx and CodeIgniter, I have a location block in my server config that handles the routing for my project like this:
location /beta/ {
try_files $uri $uri/ /beta/index.php;
}
This works fine, but I perform backups on this CodeIgniter project and move them to another folder. The "beta" project gets renamed (with a time-stamp). So I have a backups folder with CodeIgniter projects named as such:
backups/beta_2013_05_21_0857
backups/beta_2012_05_23_0750
What I'm trying to do is create another location rule that handles these variable-named projects, but all attempts at using regex so far have failed. If I name the project directly it does work.
location /backups/beta_2013_05_21_0857 {
try_files $uri $uri/ /backups/beta_2013_05_21_0857/index.php;
}
But obviously I don't want to create a rule for each and every folder. Does anyone have any idea on how to solve this? This is the how I was trying to solve the problem:
location /backups/^\w+$/ {
try_files $uri $uri/ /backups/$1/index.php;
}
Two possible problems:
You don't have any brackets in your regex so it's not going to be a capturing group. And you missed out the ~* command to tell Nginx to do a regex match.
location ~* ^/backups/(\w+)$ {
try_files $uri $uri/ /backups/$1/index.php;
}
The last parameter in a try_files is magic. It doesn't actually try to see if the file exists. Instead it rewrites the request URI with the last parameter and reprocesses the request, which is moderately surprising. To fix this you can (and should) fall back to either a 404 or other page.
location ~* ^/backups/(\w+)$ {
try_files $uri $uri/ /backups/$1/index.php /404_static.html;
}
location = /404_static.html {
root /documents/projects/intahwebz/intahwebz/data/html/;
internal;
}
btw if you have further issues you should enable rewrite_log on; which will write the matching to the servers error file at notice level, and helps figure out location matching issues.

rewrite rule failing with unicode urls on nginx with pcre 8.3

I'm having a similar problem to the one described on this question. However, I managed to get nginx (1.0.14) compiled with the latest PCRE (8.30), changed the rewrite rule to use UTF8, but it still fails.
My rewrite rule is
location / {
try_files $uri $uri/ /index.php;
rewrite "(*UTF8)^/imgthumb/(.*)$" /timthumb.php?$1 last;
}
This works fine with images without unicode, but fails when the filename contains unicode characters.
so /imgthumb/src=/wp-content/uploads/8姉妹の古いマトリョーシカ.jpg&h=121&w=137&zc=1 fails
but /imgthumb/src=/wp-content/uploads/MOD0005.jpg&h=121&w=137&zc=1 works fine.
On Apache using .htaccess rewrite rule, it works with both
RewriteRule ^/imgthumb/(.*)$ /timthumb.php?$1 [L]
Is my nginx rewrite rule wrong? Is there a way to make this work?
UPDATE:
I noticed that the problem seems to stem from the fact that the PHP script gets only one parameter (src) into the $_GET array with nginx, but with apache rewrite it's broken down to different parameters...
The solution was eventually provided by Valentin V. Bartenev on the nginx forum after I posted the same question there.
Replacing the rewrite rule with this snippet made this work!!
location ~ (*UTF8)^/imgthumb/(.*)$ {
fastcgi_pass unix:/var/spool/phpfpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root/timthumb.php;
fastcgi_param SCRIPT_NAME /timthumb.php;
fastcgi_param QUERY_STRING $1;
}

Resources