# Redirection problem again in new rules

**URL:** <https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461>\
**Category:** NGINX\
**Created:** [April 14, 2016, 4:03pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461 "2016-04-14T16:03:52Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [April 14, 2016, 4:03pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/1 "2016-04-14T16:03:52Z")

</div>

Hi,

there are multiple apache redirection rules that were working  
successfully.  
for example something like this

Redirect 301 /aaaa/bbbbbbb /aaaaa/bbbbbb.html

Now i have converted this rule in nginx like this

location /aaaa/bbbbbbbb {  
rewrite ^(.\*)$ /aaaa/bbbbbbbbbb.html redirect;  
}

i also tried adding “permanent” and rewrite line but also didn;t wrok.

now all redirection rules are keep giving error “redirection loops”.  
and when i disable the rule things back to normal. there is no  
duplication  
happening as far as config is concern. i can confirm.

can you guys please advice how can i troubleshoot this and fix the  
issue.

your friendly advice is highly appreciated.

Thanks,  
Yousuf

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 14, 2016, 5:18pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/2 "2016-04-14T17:18:38Z")

</div>

Le 14 avr. 2016 16:03, Muhammad Yousuf K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) a crit :

> Redirect 301 /aaaa/bbbbbbb /aaaaa/bbbbbb.html
> 
> Now i have converted this rule in nginx like this
> 
> location /aaaa/bbbbbbbb {  
> rewrite ^(.\*)$ /aaaa/bbbbbbbbbb.html redirect;  
> }

You should use break instead redirect :

> **[Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite)**
>
> The ngx\_http\_rewrite\_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations.

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 14, 2016, 7:04pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/3 "2016-04-14T19:04:58Z")

</div>

On Thu, Apr 14, 2016 at 07:03:19PM +0500, Muhammad Yousuf K. wrote:

Hi there,

> there are multiple apache redirection rules that were working successfully.  
> for example something like this
> 
> Redirect 301 /aaaa/bbbbbbb /aaaaa/bbbbbb.html
> 
> Now i have converted this rule in nginx like this
> 
> location /aaaa/bbbbbbbb {  
> rewrite ^(.\*)$ /aaaa/bbbbbbbbbb.html redirect;  
> }

You have different numbers of a:s and b:s there, which makes it quite  
difficult to know what it is that you actually want to do.

> now all redirection rules are keep giving error “redirection loops”.  
> and when i disable the rule things back to normal. there is no duplication  
> happening as far as config is concern. i can confirm.

Do note that “location /x” can match anything that starts with /x; and  
if a request for /x.html returns a redirect to /x.html, you’ve got a  
loop.

_Possibly_ you want your “rewrite/redirect” to only happen for specific  
requests; in that case, set the first argument to “rewrite” to be as  
specific as you want. Or leave the “rewrite” applying to everything,  
but have it in an exact-match location{}.

(And if you are doing the same “rewrite…redirect” for all inputs,  
“return” may be a better directive to use instead.)

> can you guys please advice how can i troubleshoot this and fix the issue.

“troubleshoot” is “turn on the debug log to see, or otherwise work out,  
what you have asked nginx to do”. Then compare that with what you want  
nginx to do.

Good luck with it,

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 15, 2016, 9:27am UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/4 "2016-04-15T09:27:47Z")

</div>

Hi All,

Thanks for your help. Ph. Gras and Francis for your support and advice i  
really appreciate that.

Ph. Gras, i tried “break” but now it is showing 404.

Francis,

Sorry for the mistake in a’s and b’s i was typing that in general  
because  
the context was not the URL but the problem.

> Do note that “location /x” can match anything that starts with /x; and  
> if a request for /x.html returns a redirect to /x.html, you’ve got a loop.

Yes , i have double checked but my redirection rules are not created  
wrong.  
so i am sure no loop is happening there.

BTW just to update you guys. i am using wordpress.

i am doing two redirections , one domain base and second URL base.

domain base is working fine however URL redirections are giving me  
issues.

could this be related to wordpress?

Thanks,  
MYK

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 15, 2016, 6:36pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/5 "2016-04-15T18:36:18Z")

</div>

On Fri, Apr 15, 2016 at 12:27:11PM +0500, Muhammad Yousuf K. wrote:

Hi there,

> Sorry for the mistake in a’s and b’s i was typing that in general because  
> the context was not the URL but the problem.

If you can show one specific url which does show the problem, then it  
makes it much easier to see what is going on.

If you can also include one small but complete config file that shows  
the problem, that makes it much easier for someone else to repeat your  
experiment.

(And sometimes, the act of making a small config that shows the problem,  
will show you what the fix is.)

> > Do note that “location /x” can match anything that starts with /x; and  
> > if a request for /x.html returns a redirect to /x.html, you’ve got a loop.
> 
> Yes , i have double checked but my redirection rules are not created wrong.  
> so i am sure no loop is happening there.

Part of the point of you asking the question, is that you do not know  
where the problem is.

So usually, the best thing is to run a test nginx with your config, then  
remove as much as possible while still showing the problem. Maybe that  
config will just have two location{} blocks, and the loop will be  
obvious.

> BTW just to update you guys. i am using wordpress.
> 
> i am doing two redirections , one domain base and second URL base.
> 
> domain base is working fine however URL redirections are giving me issues.

Use “curl” to test your broken url and see what exactly is returned.

Do something like

curl -i [http://your-server/aaaa/bbbbbbbb](http://your-server/aaaa/bbbbbbbb)

and you should get a http 301 response, with something in the Location:  
header.

Then do “curl -i” against that url, and see if you get the loop.

The _rest_ of the headers may show that PHP was, or was not, involved  
in the redirections.

> could this be related to wordpress?

It could be.

If the “curl” responses show that PHP is involved, then it probably is.

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 16, 2016, 9:23am UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/6 "2016-04-16T09:23:02Z")

</div>

Here is our nginx default configuration file.

server {  
server\_name [www.mydomain.com](http://www.mydomain.com);  
return 301 $scheme://mydomain.com$request\_uri;  
}

server {  
server\_name [mydomain.com](http://mydomain.com);  
#listen 80;  
root /var/www/html/mydomain/public\_html;  
index index.php info.php;

access\_log /var/log/nginx/mydomain/access.log;  
error\_log /var/log/nginx/mydomain/error.log;

```
    location ~ \.php$ {
            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            #fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            }

    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)$  
{  
add\_header Access-Control-Allow-Origin [mydomain.com](http://mydomain.com);  
}

```
    location / {
            try_files $uri $uri/ /index.php?q=$request_uri;
             autoindex off;
            rewrite ^/([^_]*)_([^_]*_.*)\.html /$1-$2;
            rewrite ^/([^_]*)_([^_]*)\.html$ /$1-$2.html redirect;
            #if (!-e $request_filename){
            #rewrite ^(.*)$ /index.php redirect;
            #}
            }

```

if ( $request\_filename ~ /action/cycling/cycling-is-best-for-health ) {  
rewrite ^ /action/cycling/cycling-is-best-for-health.html? permanent;  
}

#Server HTTP End  
}

Thanks for your troubleshooting tip. the redirection rule is working  
great  
however but the.html link again redirection to the .html link. i can not  
get this thing. where is the second 301 rule once the link is redirected  
why again html is redirecting.

here is the test run of curl -i  
[http://mydomain.com/action/cycling/cycling-is-best-for-health](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](http://mydomain.com/action/cycling/cycling-is-best-for-health.html)  
Connection: keep-alive

301 Moved Permanently
# 301 Moved Permanently

* * *
nginx/1.6.2

test run with “.html” at the end.  
curl -i  
[http://mydomain.com/action/cycling/cycling-is-best-for-health.html](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](http://mydomain.com/action/cycling/cycling-is-best-for-health.html)  
Connection: keep-alive

301 Moved Permanently
# 301 Moved Permanently

* * *
nginx/1.6.2

what i found out is that 2nd test on .html is again redirecting to  
.html.  
now what is causing this second redirection i have no clue.

any advice would be highly appreciated.

Thanks,  
Yousuf

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 16, 2016, 2:36pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/7 "2016-04-16T14:36:43Z")

</div>

On Sat, Apr 16, 2016 at 12:22:46PM +0500, Muhammad Yousuf K. 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”?

> **[Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if)**
>
> The ngx\_http\_rewrite\_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations.

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.

> **[Module ngx\_http\_rewrite\_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite)**
>
> The ngx\_http\_rewrite\_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations.

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.)

> 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://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](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 D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 18, 2016, 3:38pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/8 "2016-04-18T15:38:31Z")

</div>

Thanks alot Francis D. :). the try\_file option worked for me and  
location  
tip also worked but try\_file seems more better approach.

Btw, can you please explain this paragraph. actually i am really sorry  
for  
this newbie type question. actually i have been working as ssytem admin  
for  
last 5 years. now my Firewall concepts of rules are collapsing with  
nginx  
rules.

> 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

can you please explain how the second request creates the loop. if i use  
break instead of redirect?

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 19, 2016, 1:23am UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/9 "2016-04-19T01:23:51Z")

</div>

On Mon, Apr 18, 2016 at 06:37:59PM +0500, Muhammad Yousuf K. wrote:

Hi there,

> Thanks alot Francis D. :). the try\_file option worked for me and location  
> tip also worked but try\_file seems more better approach.

I’m glad you got it working for you.

> Btw, can you please explain this paragraph. actually i am really sorry for  
> this newbie type question. actually i have been working as ssytem admin for  
> last 5 years. now my Firewall concepts of rules are collapsing with nginx  
> rules.

No worries - nginx config follows its own rules, which are generally  
consistent but not necessarily the same as any other program.

> > 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
> 
> can you please explain how the second request creates the loop. if i use  
> break instead of redirect?

I don’t understand the question.

What break, and what loop?

I thought you had said that when you used “break” instead of “redirect”  
in the above “location /x”, you got a 404. And that is what I would  
expect if the file $document\_root/x.html does not exist. 404 is not a  
loop.

Can you start with one specific configuration, and use the documentation  
(probably at [Module ngx\_http\_rewrite\_module](http://nginx.org/r/rewrite), since that seems to be the  
troublesome one) to work out what will happen?

Note: when a request arrives, the server-level “rewrite”-module  
directives  
(basically: if and rewrite) are used; if that does not complete the  
request, then the location is chosen, and the “rewrite”-modules  
directives  
in that location are used.

If a “rewrite” leads to an external redirect, that completes the  
request; and the browser may then come back with a whole new request  
that is handled afresh.

If the “rewrite” leads to an internal rewrite (to a new url), then the  
“subrequest” of the new url is handled according to the docs – possibly  
with a whole new selection of the location to use, depending on the  
arguments given to the rewrite.

So: show your (simplified, but complete) config; show your http request;  
show your http response; and if appropriate, describe the response that  
you wanted to get instead.

“break” does exactly what it says in the documentation. If that is  
unclear, let’s fix the documentation.

## f

Francis D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![muhammad\_k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/47e85d/32.png) [@muhammad\_k](https://www.ruby-forum.com/u/muhammad_k)\
**Post date:** [April 20, 2016, 12:34pm UTC](https://www.ruby-forum.com/t/redirection-problem-again-in-new-rules/244461/10 "2016-04-20T12:34:35Z")

</div>

Thanks Alot Francis D., actually i was trying to understand the  
working  
of rewrite and location rules how they handle the query. you explain it  
very well. Thanks again for sharing such useful and detailed  
explanation. i  
really appreciate that. 🙂
