<div dir="ltr"><div style="font-family:arial,sans-serif;font-size:13px">Hi everyone,</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">I am trying to move a site with a large number (93) of .htaccess files from Apache to Nginx.<br></div><div style="font-family:arial,sans-serif;font-size:13px">There are over 800 rewrite rules to convert. To optimize performance, I have decided to </div><div style="font-family:arial,sans-serif;font-size:13px">place the rules under separate nested location blocks (61 blocks in total).</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">But I am having problem with rewriting some of the rules. I have created a sample scenario to explain the problem.</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><font size="4"><b>Requirements:</b></font></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><ol><li style="margin-left:15px">/test/abc/pics/ should redirect to /test/abc/wallpapers/<br></li><li style="margin-left:15px">/test/abc/pics/800/a.jpg should be served directly, if the file is present. If it does not exist, then the request should be rewritten to /test/abc/pics/pic.php, which will create the file on first request. Subsequent requests will be served directly.</li><li style="margin-left:15px">/test/abc should redirect to /test/abc.html<br></li><li style="margin-left:15px">/test/abc.html should be rewritten to /test/index.php<br></li><li style="margin-left:15px">/test/abc/def/year-2014.php should be rewritten to /test/abc/def/index.php<br></li><li style="margin-left:15px">All static files (.gif, .jpg, .png, .mpg....) should be served directly with a very long expiry time.<br></li><li style="margin-left:15px">All files ending in .html should be served directly. If the file does not exist the request should be rewritten to /fallback.php<br></li><li style="margin-left:15px">All files ending in .php or / should be executed by PHP-FPM. If the file does not exist it should be rewritten to /fallback.php<br></li></ol></div><div style="font-family:arial,sans-serif;font-size:13px"><b><font size="4">Configuration:</font></b></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><span style="white-space:pre-wrap"><font face="monospace">index index.php;

<font color="#999999">#
# Location Specific Rules
#</font>
location /test/abc/ {
    location /test/abc/pics/ {
       <font color="#999999"> # For ensuring 'serve directly, if file exists' condition of Rule 2</font>
        try_files $uri @rewrite_pics; 
    }

    location /test/abc/def/ {
        try_files $uri $uri/index.php @rewrite_def;
    }
}

location /test/ {
    rewrite "^/test/([a-z-]+)$" /test/$1.html permanent;<font color="#999999"> # Rule 3</font>
    rewrite "^/test/([a-z-]+).html$" /test/index.php?symbol=$1 last; <font color="#999999"># Rule 4</font>
}

location @rewrite_pics {
    rewrite "^/test/abc/pics/$" /test/abc/wallpapers/ permanent;<font color="#999999"> # Rule 1</font>
    rewrite "^/test/abc/pics/([0-9]+)/(.*)$" /test/abc/pics/pic.php?width=$1&height=$1&pic=$2 last;<font color="#999999"> # Rule 2</font>
}

location @rewrite_def {
    rewrite "(?i)^/test/abc/def/year-([a-z]+).php$" /test/abc/def/index.php?year=$1 last;</font></span><span style="color:rgb(153,153,153);font-family:monospace;white-space:pre-wrap"> # Rule 5</span><span style="white-space:pre-wrap"><font face="monospace">
}

<font color="#999999">#
# Fallback Rules
#</font>
location ~* \.(gif|jpg|jpeg|png|ico|3gp|flv|mpg|mpeg|mp4|mp3|swf|txt|xml|pdf|zip)$ {
    expires 1M; <font color="#999999"># Rule 6</font>
    try_files $uri /404.php;
}

location ~ (\.php|\.html|/)$ {
    try_files $uri "${uri}index.php" /fallback.php =404; </font></span><span style="color:rgb(153,153,153);font-family:monospace;white-space:pre-wrap"> # Rules 7 & 8</span><span style="white-space:pre-wrap"><font face="monospace">
    include php-fpm.conf;
}</font></span><br></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><font face="monospace"><b>php-fpm.conf  </b></font></div><div style="font-family:arial,sans-serif;font-size:13px"><font face="monospace"><b><br></b></font></div><div style="font-family:arial,sans-serif;font-size:13px"><font face="monospace">include fastcgi.conf;</font></div><div style="font-family:arial,sans-serif;font-size:13px"><font face="monospace">fastcgi_index index.php;</font></div><div style="font-family:arial,sans-serif;font-size:13px"><font face="monospace">fastcgi_pass <a href="http://127.0.0.1:9000/" target="_blank">127.0.0.1:9000</a>;</font></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"><font size="4"><b>Problem</b></font></div><div style="font-family:arial,sans-serif;font-size:13px"><ol><li style="margin-left:15px">Since the fallback rules are regular expressions, they are selected instead of the location specific rules<br></li><li style="margin-left:15px">If I use ~ prefix for all location specific rules, then the fallback rules are never executed. Request for /test/abc/pics/800/a.jpg will be rewritten to /test/abc/pics/pic.php which will again match the same location config. So the file is not executed and is downloaded as is.</li><li style="margin-left:15px">So, I added 'include php-fpm.conf;' to all location blocks (except named locations). But this causes all requests under /test/abc/pics/ (including existing .jpg files) to pass to the PHP-FPM. Which leads to an access denied error, since only .php extension is allowed by security.limit_extensions.</li></ol></div><div style="font-family:arial,sans-serif;font-size:13px">What am I doing wrong here? Is there a simple way to have all existing files served depending on their extension and only non existent files match the location blocks / rewrite rules?</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">Thanks & Regards,</div><div style="font-family:arial,sans-serif;font-size:13px">Joyce Babu</div></div>