Renato Pimpão
Renato Pimpão

Reputation: 271

Convert htaccess to nginx, seek solution

I have this nginx setup on all my websites. If I change this too much, usually the website does not work. The problem now is that I have a website that I bought with an htaccess file. I tried to convert using online converters, but nothing works...

MY NGINX CONFIG

server {
    server_name doutor.pt www.doutor.pt;

    access_log   /var/log/nginx/doutor.pt.access.log;
    error_log    /var/log/nginx/doutor.pt.error.log;

    root /var/www/doutor.pt/htdocs;
    index index.php index.html;

    location / {
            try_files $uri $uri/ /index.php?$args;
    }

    location ~ .php$ {
            include fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
    }

}

HTACCESS:

################################
#         MAIN SETTINGS        #
################################

# Remove index
Options -Indexes

# Set directory indexes
DirectoryIndex index.html index.php under-construction.html parking-place.html

################################
#       APACHE REWRITES        #
################################

RewriteEngine On

# Domain page parser for sitemap
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^sitemap-doctors-([0-9]+).xml$ index.php?page_name=sitemap&category=doctors&page=$1 [L,QSA]

# Domain page parser for sitemap
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^sitemap-doctors.xml$ index.php?page_name=sitemap&category=doctors&page=0 [L,QSA]

# Domain page parser for sitemap
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^sitemap.xml$ index.php?page_name=sitemap [L,QSA]

# Domain page parser for category
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^category/([0-9]+)-([^/]+)$ index.php?page_name=doctors&category=$1 [L,QSA]

# Domain page parser for doctor page
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^medico/([^/]+)$ index.php?page_name=medico&doctor_url=$1 [L,QSA]

# Domain page parser for secondary level pages
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)$ index.php?page_name=$2&page_category=$2 [L,QSA]

# Domain page parser for regular pages
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !sitemap$
RewriteRule ^([^/]+)$ index.php?page_name=$1 [L,QSA]

################################
#            CUSTOM            #
################################

Upvotes: 0

Views: 115

Answers (2)

OldFart
OldFart

Reputation: 1721

Nginx is a beautiful thing and enables almost all the time to use a location block instead of a potentially hard to follow/understand/debug rewrite. This htaccess files converts easily and i've tested a bit of it's output (result) a little while back when i was asked if i could help on some other site.

As Richard's code shows, apache's weird negative logic -d and -f translate easily to a try_files $uri $uri/ in nginx where you check the request uri against web root path.

The directory indexing is disabled by default in nginx so one must enable it to use it... nothing to add is better than (again) apache's weird negative logic. Here's what the index would look like...

index index.php index.html under-construction.html parking-place.html;

Here's what the sitemap rewrite translate to, from my understanding:

 # If the URI is bang on /sitemap.xml
 location = /sitemap.xml {
     try_files $uri $uri/ /index.php?page_name=sitemap;
 }

 # If the URI is bang on /sitemap-doctors.xml
 location = /sitemap-doctors.xml {
     try_files $uri $uri/ /index.php?page_name=sitemap&category=doctors&page=0;
 }

 # Enclosing this in the ~* /sitemap block isn't mandatory but it only
 # helps creating cleaner, readable code while also making sure we contain
 # all /sitemap*s requests thus taking care of the !sitemap directive.

 location ~* /sitemap {
     location ~ ^/sitemap-doctors-([0-9]+).xml {
         try_files $uri $uri/ /index.php?page_name=sitemap&category=doctors&page=$1;
     }
 }

Following the same logic, the next one in line would look something like this:

# It seems we are only using the first capture group ( $1 ) here so the
# regex could be modified for something simpler but to make sure we are
# not catching stuff we don't want, leaving this precision will save troubles

location ^/category/([0-9]+)-([^/]+)$ {
    try_files $uri $uri/ /index.php?page_name=doctors&category=$1;
}

Again, for more of the same...

 # The ^ and $ are regex delimiters for start and end, so you know...

 location ^/medico/([^/]+)$ {
     try_files $uri $uri/ /index.php?page_name=medico&doctor_url=$1;
 }

Now that we got rid of all precise stuff, it's time for some generic uri catching and passing to php...

I'm thinking this htaccess isn't proper... I would love to get an explanation..

This here sends the capture block ( $2 ) twice which in my opinion is really unusual and doesn't make sense. That being said, without seeing it in action or looking at the source code, it's a tricky one...

 RewriteRule ^([^/]+)/([^/]+)$ index.php?page_name=$2&page_category=$2 [L,QSA]

a url of http://hungry.man/delicious/pizza would be seen to php as http://hungry.man/index.php?page_name=pizza&page_category=pizza without any reference to it being delicious...

For what's left i would be tempted to just use a @rewrite and write thoses as they are, without challenging my brain too much about it.

Hope it helps, Mat

Upvotes: 1

Richard Smith
Richard Smith

Reputation: 49762

It seems to me that the .htaccess file is trying to do something like this:

location / {
    try_files $uri $uri/ @rewrite;
}
location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
}
location @rewrite {
    rewrite ^/sitemap-doctors-([0-9]+).xml$ /index.php?page_name=sitemap&category=doctors&page=$1 last;
    rewrite ^/sitemap-doctors.xml$ /index.php?page_name=sitemap&category=doctors&page=0 last;
    rewrite ^/sitemap.xml$ /index.php?page_name=sitemap last;
    rewrite ^/category/([0-9]+)-([^/]+)$ /index.php?page_name=doctors&category=$1 last;
    rewrite ^/medico/([^/]+)$ /index.php?page_name=medico&doctor_url=$1 last;
    rewrite ^/([^/]+)/([^/]+)$ /index.php?page_name=$2&page_category=$2 last;

    rewrite ^/([^/]+)$ /index.php?page_name=$1 last;

    # some default action???
    return 404;
}

The main difference between rewrites in Apache and nginx, is that the latter requires the leading / on URIs. I have not implemented the RewriteCond %{REQUEST_URI} !sitemap$ rule or implemented a final default action. You will need to determine what works: return 404 or rewrite everything to /index.php.

Upvotes: 0

Related Questions