On Sat, Apr 16, 2016 at 12:22:46PM +0500, Muhammad Yousuf Khan wrote: Hi there,
> location ~ \.php$ { > location ~* > \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|woff|woff2)$ > location / { > try_files $uri $uri/ /index.php?q=$request_uri; > autoindex off; > rewrite ^/([^_]*)_([^_]*_.*)\.html /$1-$2; > rewrite ^/([^_]*)_([^_]*)\.html$ /$1-$2.html redirect; > } > if ( $request_filename ~ /action/cycling/cycling-is-best-for-health ) { > rewrite ^ /action/cycling/cycling-is-best-for-health.html? permanent; > } To recap: A loop is when the second (redirected) request is handled in the same way as the first request. So to avoid or break the loop, the second request must not get the same response as the first one. You know that location /x { rewrite ^ /x.html redirect; } fails because "location /x" will match /x.html, so the second request will match the same location as the first one and the same redirect will happen again; and one way to avoid the loop is to make the "location" only match exactly "/x". Based on that, can you guess what the "~" in if ( $request_filename ~ /action/cycling/cycling-is-best-for-health ) { means, in the context of "matching both the first request and the second request"? http://nginx.org/r/if One way to avoid the loop is the make the "if" only match exactly the first request. Also, you know that rewrite ^ /x.html redirect; fails because the first argument to "rewrite" is a pattern, and both your original /x and your rewritten /x.html match it; so another way to avoid the loop is to make the "rewrite" only match exactly "/x". So you could try that approach instead. http://nginx.org/r/rewrite Anyhow: since your example redirect is static, not depending on anything other than the first request, what you probably want here is a series of exact location matches, of the form location = /action/cycling/cycling-is-best-for-health { return 301 /action/cycling/cycling-is-best-for-health.html; } But *if* what you want is always-and-only serve the file of "the original request with .html on the end", then you don't necessarily need a redirect at all. Depending on what the full requirements are, you might be able to get away with adjusting your try_files line instead: > try_files $uri $uri/ /index.php?q=$request_uri; Make that try_files $uri $uri.html $uri/ /index.php?q=$request_uri; and it might do what you want without any redirects. (Whether the new $uri.html goes before or after "$uri/" depends on the requirements.) > here is the test run of curl -i > http://mydomain.com/action/cycling/cycling-is-best-for-health > > > HTTP/1.1 301 Moved Permanently > Server: nginx/1.6.2 > Date: Sat, 16 Apr 2016 07:10:33 GMT > Content-Type: text/html > Content-Length: 184 > Location: http://mydomain.com/action/cycling/cycling-is-best-for-health.html > Connection: keep-alive We know from the config that that is handled directly by nginx; additionally, if it were handled by PHP or wordpress, there would probably be an extra header in there to indicate that. > test run with ".html" at the end. > curl -i http://mydomain.com/action/cycling/cycling-is-best-for-health.html > > HTTP/1.1 301 Moved Permanently > Server: nginx/1.6.2 > Date: Sat, 16 Apr 2016 07:10:37 GMT > Content-Type: text/html > Content-Length: 184 > Location: http://mydomain.com/action/cycling/cycling-is-best-for-health.html > Connection: keep-alive Since that extra PHP-or-wordpress header is not there, we can suspect that it is also handled directly by nginx. (To be sure, you would have to check the headers for a wordpress response as well.) But from the analysis above, we already now that it is handled directly by nginx, because your "if/rewrite" configuration is the loop. Cheers, f -- Francis Daly fran...@daoine.org _______________________________________________ nginx mailing list nginx@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx