rewrite rule failing with unicode urls on nginx with pcre 8.3 - utf-8

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;
}

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.

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.

Nginx Simple rewrite

I want to make the following url in nginx
comments.php?id=34
becomes
/comments/34
/comments/34/
I am trying with this and it works
rewrite ^/comments/$id/(.*)$ /comments.php?id=$1? last;
My Question is, how to do I force redirect comments.php?id=x to /comments/id
rewrite ^/comments.php$ /comments/$arg_id? permanent;
According to the documentation, "rewrite operates only on path, not parameters."
Try this instead:
if ($args ~ id=(.+)){
rewrite comments\.php /comments/$1 last;
}

Nginx: Using the try_files Directive to create a pretty URLs

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

Nginx rewrite properly quoted ampersand in values causing problem

I am trying to rewrite some urls with following nginx rewrite rule
rewrite ^/some\/url\/(.*)\/$ /some/url/?filter=$1;
Rewriting does not seem to work if a query contains an & e.g.
?filter=key:abcd & efgh
which I am quoting properly to
?filter=abcd%20%26%20N%20efgh
My problem is only rewritten url /som/url/key:abcd%20%26%20N%20efgh do not work. If I access it like /some/url/?filter=abcd%20%26%20N%20efgh it works fine.
Am I missing something?
Thanks.
Putting URL you want to rewrite to another "location" could solve your problem.
(I suppose in location directive nginx doesn't do any escaping)
So for your example it would be:
location /some/url/ {
if ($uri ~* ^/some/url/(.*)$
{
rewrite ^.*$ /some/url/?filter=$1 break;
}
proxy_pass http://127.0.0.1:8080;
#proxy_set... <- and other proxy related things
}
at least it worked for me(in my case even question marks were replaced with "%3f".
Excerpt from official documentation "Note that the $args variable is not decoded, unlike URIs during location matching." http://wiki.nginx.org/HttpRewriteModule
I noticed that I was using an old version of the nginx(7.6) and the problem was solved by upgrading to the latest stable release(1.0).

Resources