I try to move my server from Apache towards a Nginx based setting. However, I get into problems getting a part of my htaccess Apache magic to work in Nginx.
The .htaccess code I would like to transfer is:
RewriteRule ^([a-zA-Z0-9_]+)/$ /index.php?page=$1 [L,QSA]
RewriteRule ^([a-zA-Z0-9_]+).html$ /index.php?page=$1 [L,QSA]
RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/.*/([a-zA-Z0-9_]+)$ /index.php?page=$1&id=$2&sub=$3 [L,QSA]
RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/.*$ /index.php?page=$1&id=$2 [L,QSA]
I used an online converter that gave me the following location block:
location / {
rewrite ^/([a-zA-Z0-9_]+)/$ /index.php?page=$1 break;
rewrite ^/([a-zA-Z0-9_]+).html$ /index.php?page=$1 break;
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/.*/([a-zA-Z0-9_]+)$ /index.php?page=$1&id=$2&sub=$3 break;
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/.*$ /index.php?page=$1&id=$2 break;
}
Sadly, I'm only able to get a single location rewrite to be working at a time (the one I put "last;" behind). I don't seem to be able to do this dynamic rewriting of a multiple subfolder URL into arguments for a single PHP script.
Any help on this? What is the Nginx way of doing such a rewrite? I tried using several location's for different subfolders but I would rather have a generic solution that work no-matter what url's are thrown at it.
Use a different location block for each rule:
location ~ ^/[a-zA-Z0-9_]+/$ {
rewrite ^/([a-zA-Z0-9_]+)/$ /index.php?page=$1 last;
}
location ~ ^/[a-zA-Z0-9_]+.html$ {
rewrite ^/([a-zA-Z0-9_]+).html$ /index.php?page=$1 last;
}
location ~ ^/[a-zA-Z0-9_]+/[0-9]+/.*/[a-zA-Z0-9_]+$ {
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/.*/([a-zA-Z0-9_]+)$ /index.php?page=$1&id=$2&sub=$3 last;
}
location ~ ^/[a-zA-Z0-9_]+/[0-9]+/.*$ {
rewrite ^/([a-zA-Z0-9_]+)/([0-9]+)/.*$ /index.php?page=$1&id=$2 last;
}
location = /index.php {
# your proxy rules here...
}
The rewrite rules above use the last option, which is explained in the nginx docs:
last
stops processing the current set of ngx_http_rewrite_module
directives and starts a search for a new location matching the
changed URI;
Related
In my code I am trying to convert Apache .htaccess into Nginx using online convertor. I even edited this file etc/nginx/conf.d/domainname.conf but the rewrite URLS won't work. I have two htaccess files, one of which used in root folder and the second one used in administration folder of my script.
Here is the root's htaccess file content
RewriteEngine On
RewriteRule ^([a-zA-Z0-9-/]+)$ index.php?slug=$1
RewriteRule ^([a-zA-Z0-9-/]+)/$ index.php?slug=$1
htaccess converted code for Nginx
location / {
rewrite ^/([a-zA-Z0-9-/]+)$ /index.php?slug=$1;
rewrite ^/([a-zA-Z0-9-/]+)/$ /index.php?slug=$1;
}
Here is the administration folder htaccess file content
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* $0.php [L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php($|\ |\?)
RewriteRule ^(.*)/$ /$1.php [L,R=301]
Administration folder htaccess converted code for Nginx
location /administration {
if (!-e $request_filename){
rewrite ^(.*)$ /$0.php break;
}
rewrite ^/(.*)/$ /$1.php redirect;
}
I pasted the converted content into domainname.conf (domainname is my domain) and restart the ngnix but it won't work at all. I don't know whether my converted code is accurate or not or any thing else I am missing through it.
Simply edit the file i.e. etc/nginx/conf.d/yourdomain.tld.conf and look for the following code like this:
#location / {
#Uncomment 3 lines and set your rules here!
#}
You need to un-comment these 3 lines of code or paste this code instead:
location / {
if (!-e $request_filename) {
rewrite ^/([a-zA-Z0-9-/]+)$ /index.php?slug=$1;
rewrite ^/([a-zA-Z0-9-/]+)/$ /index.php?slug=$1;
}
}
location /administration/ {
if (!-e $request_filename){
rewrite ^(.*)$ $1.php last;
}
}
Then you must require to restart Nginx, if restarted without any errors it will work accurately otherwise Nginx will stop working, this step is important.
I have the following rewrites in .htaccess:
#exception for shorthand phpthumb links eg /userfiles/myimage.jpg?w=300
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|png|gif|bmp|JPG|)$
RewriteCond %{QUERY_STRING} ^(.+)$
RewriteRule ^(.*)$ application/third_party/phpThumb/phpThumb.php?src=../../../$1&%1 [NE,L]
It checks that request is for one of the specified (image) files and that has some query string arguments. In that case it should rewrite to an automatic thumbnail script.
I am trying to rewrite that into nginx config. So far I've got this:
location \.(jpg|jpeg|png|gif|bmp|JPG)$ {
if($args ~ "^(.+)$"){
rewrite ^/(.*)$ /application/third_party/phpThumb/phpThumb.php?src=../../../$1 last;
}
}
I am new to nginx and tried to glue together the new config from some manuals and this converter:
http://www.anilcetin.com/convert-apache-htaccess-to-nginx/
But it doesn't seem to work. What am I doing wrong?
I have replaced the rewrite with the following:
location ~ /(images|userfiles)/ {
if ($args) {
# alternative shorthand phpthumb links eg /userfiles/myimage.jpg?w=300
rewrite .(jpg|jpeg|png|gif)$ /application/third_party/phpThumb/phpThumb.php?src=../../..$uri last;
}
}
I have these apache (htaccess) rules and I want to convert them to nginx rules. I have tried a lot of combinations but in vain.
You have the rules below:
RewriteRule ^candybooru/_images/([0-9a-f]{2})([0-9a-f]{30}).*$ /candybooru/images/$1/$1$2
RewriteRule ^candybooru/_thumbs/([0-9a-f]{2})([0-9a-f]{30}).*$ /candybooru/thumbs/$1/$1$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^candybooru/(.*)$ /candybooru/index.php?q=$1&%{QUERY_STRING}
Maybe you could use this page to convert the rules: http://winginx.com/en/htaccess
The converted rule is:
# nginx configuration
location / {
rewrite "^/candybooru/_images/([0-9a-f]{2})([0-9a-f]{30}).*$" /candybooru/images/$1/$1$2;
rewrite "^/candybooru/_thumbs/([0-9a-f]{2})([0-9a-f]{30}).*$" /candybooru/thumbs/$1/$1$2;
}
location /candybooru {
rewrite ^/candybooru/(.*)$ /candybooru/index.php?q=$1&$query_string;
}
Check out try_files. I haven't tested this, but it should work (or come close):
location /candybooru/ {
location ~ "^/candybooru/_(images|thumbs)/([0-9a-f]{2})([0-9a-f]{30})" {
try_files /candybooru/$1/$2/$2$3 /candybooru/index.php?q=$2&$query_string;
}
}
I have app and public folders in my project. I want paths that starts with (css|im|js|lib)/ to be redirected to public folder, and anything else - to index.php file.
For example, http://mysite.com/css/s.css should be redirected to SITE_ROOT/public/css/s.css and http://mysite.com/absde should be redirected to SITE_ROOT/index.php
Here's working config for nginx:
server {
listen 80;
server_name mysite.com;
root /home/mysite/html;
location ~ \/(css|im|js|lib)\/ {
root /home/mysite/html/public;
expires 30;
try_files $uri =404;
}
location {
rewrite ^(.*)$ /index.php break;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
Now I try to rewrite this for apache, I write something like that in .htaccess:
RewriteEngine On
RewriteRule ^(css|im|js|lib)\/(.*)$ public/$1/$2 [L]
RewriteRule . index.php [L]
This does not work. It seems RewriteRule . index.php applies before the second line so that everything goes to index.php. But why?
Nothing changes if I change the third row to
RewriteRule ^(.*)$ index.php [L]
And that means that the type of equation doesn't affect on the order of rules.
And only if I remove ^ symbol from the regex in the second line, site starts working as expected. But I don't want to remove it! Now http://mysite.com/abcde/css/s.css rewrites to css/s.css, and it shouldn't be that way. Also the second line starts working if I remove the third one (that means it's correct by itself).
That's so stupid simple but I can't find a mistake in theese three rows. Please help.
The problem is that internal redirects are treated as new requests, and so the rules are being evaluated again, where the first rule now won't match anymore, but the second one does, and so you'll always end up at index.php.
One way to avoid this would be to bind the last rule to the condition that it doesn't start with /public/:
RewriteCond %{REQUEST_URI} !^/public/.*
RewriteRule . index.php [L]
My site is running on Nginx and I am trying to add a software in the sub-directory of the site that uses Apache's mod_rewrite rules. E.g. www.mydomain.com/mySubfolder
Here is the Apache .htaccess
#Options -Indexes
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/system.*
RewriteRule ^(.*)$ index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?/$1 [L]
</ifModule>
So far I managed to get the main page to work but when requesting the login page, it is causing a URL redirect loop. E.g. www.myDomain.com/login
With this:
location /mySubfolder {
if (!-e $request_filename) {
rewrite ^(.*)$ /mySubfolder/index.php?q=$1 last;
break;
}
}
I have been reading and trying to learn how to convert Apache to Nginx and even used the .htaccess to Nginx converter I found at http://winginx.com/htaccess but the tool doesn't seem to recognize the %{REQUEST_URI} ^/system.* part. Upon my research and study, I came up with:
location /mySubfolder {
if ($request_uri ~ "^/(system.*)$") {
rewrite ^/(.*)$ index.php?/$1 last;
}
if (!-e $request_filename) {
rewrite ^(.+)$ /mySubfolder/index.php?q=$1 last;
break;
}
}
I am a complete noob at this and was even wondering if I am even close to accomplish this conversion to work. Please help.
Thank you.
was even wondering if I am even close to accomplish this conversion to
work
You've basically taken the wrong approach to use in Nginx.
Although it is kind of natural to assume that the rewrite rules in Apache would be mapped to the rewrite in Nginx, they aren't. Instead they are mostly mapped to the location rules.
Your block for mySubfolder should look like:
location ^/mySubfolder {
try_files /mySubfolder/index.php?$args =404;
}
You aren't actually rewriting anything - you are just telling nginx that any requests that start with /MySubfolder should be served by the files listed in try_files. btw you have to tell Nginx to pass the query string through which is what the args is doing.
You can append the original URL (i think) though it may be easier just to use $_SERVER['REQUEST_URI'] inside your script.
I believe the rewrite rule you have to the same start URI is causing the /mySubFolder to keep matching.
In Nginx rewriting is only used when you want to make external URL paths be served by different internal urls, and normally the rewrite rule is not inside a location block.
For example I have a file server, that serves up images and other files. I have these rewrite rules in the server block:
rewrite ^/image/(\d+)/(\w+)/(.+)\.([^\.]*)$ /proxy/proxyImage.php?typeID=$1&mode=$2&imagePath=$3.$4&resizeAllowed=TRUE&type=image last;
rewrite ^/image/(\d+)/(.+)\.([^\.]*)$ /proxy/proxyImage.php?typeID=$1&imagePath=$2.$3&resizeAllowed=TRUE last;
rewrite ^/file/(\d+)/(.+)\.([^\.]*)$ /proxy/proxyFile.php?typeID=$1&imagePath=$2.$3&resizeAllowed=FALSE last;
to make the external URLs look nice. But then they are all served by the location block:
location ~* ^/proxy {
try_files $uri =404;
fastcgi_pass unix:/opt/local/var/run/php54/php-fpm-images.sock;
include /documents/projects/intahwebz/intahwebz/conf/fastcgi.conf;
}
The location block doesn't need to know about the URL rewrites because they are done before the location block is encountered.