Beginner's question: redirecting /dir/index.html to /dir/

Greetings,

I’m trying to send all …/dir/index.html requests to …/dir/ . I
looked this up in forums but I’m only able to do it for the root
directory:

location / {
    root   /var/www/mysite;
    index  index.html index.htm;
    if ($request_uri = /index.html) {
    rewrite ^ http://$host? permanent;
    }
}

Some day I’ll try to stop this copy-and-paste madness, but “in the
meantime”… could someone please give me a hand? I would greatly
appreciate it.

Thanks and cheers,

Ezequiel

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,128951#msg-128951

something like:
rewrite (.*)/index.html $1;

should do it.

On Thu, Sep 09, 2010 at 06:22:23PM -0400, ez77 wrote:

if ($request_uri = /index.html) {
rewrite ^ http://$host? permanent;
}   

}
[/code]

Some day I’ll try to stop this copy-and-paste madness, but “in the
meantime”… could someone please give me a hand? I would greatly
appreciate it.

You may do it using:

  • if ($request_uri = /index.html) {
  • if ($request_uri ~ /index.html) {

However, using “if ($request_uri …” means that you should use
“location”
instead of “if”. Nevertheless, the right configuration:

 location / {
     root   /var/www/mysite;
     index   index.html;
 }

 location ~ /index.html$ {
     rewrite ^ http://$host/? permanent;
 }

does not work, because “index index.html” redirects internally “/” to
“/index.html” and you will get endless loop with browsers.
However, you may avoid the internal redirect via try_files:

 location / {
     root       /var/www/mysite;
     try_files  $uri  ${uri}index.html  =404;
 }

 location ~ /index.html$ {
     rewrite ^ http://$host/? permanent;
 }


Igor S.
http://sysoev.ru/en/

On Fri, Sep 10, 2010 at 07:58:52AM +0400, Igor S. wrote:

root   /var/www/mysite;
     index   index.html;
 location / {
     root       /var/www/mysite;
     try_files  $uri  ${uri}index.html  =404;
 }

 location ~ /index.html$ {
     rewrite ^ http://$host/? permanent;
 }

The configurations above rerirect to root only.
Here is the right way:

  location / {
      root   /var/www/mysite;
      index   index.html;
  }

  location ~ ^(/.+/)index.html$ {
      internal;
      error_page  404   http://$host$1?;
  }


Igor S.
http://sysoev.ru/en/

On Fri, Sep 10, 2010 at 12:51:52PM -0400, ez77 wrote:

internal;
error_page 404 http://$host$1?;
}

, redirects to the root of my site: site.com/ instead of site.com/dir/.
To be precise, to site.com/? . (What’s the point of that “?”?)

Sorry, this “?” is usefull in "rewrite"s only.
Upgrade to the lastest 0.8.50 and try

location ~ ^(?.*/)index.html$ {
internal;
root /var/www/mysite;
error_page 404 http://$host$DIR;
}


Igor S.
http://sysoev.ru/en/

Upgrade to the lastest 0.8.50 and try

location ~ ^(?.*/)index.html$ {
internal;
root /var/www/mysite;
error_page 404 http://$host$DIR;
}

Nice! It worked! Thank you very much, once again. At the risk of pushing
it… is there a way to make the redirect 301 rather than 302?

Cheers,

Ezequiel

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,129575#msg-129575

Thank you all for your replies. It’s indeed an honor to receive help
from the very creator of nginx! Not meaning to bug any of you any
more… but this last configuration,

location / {
root /var/www/mysite;
index index.html;
}

location ~ ^(/.+/)index.html$ {
internal;
error_page 404 http://$host$1?;
}

, redirects to the root of my site: site.com/ instead of site.com/dir/.
To be precise, to site.com/? . (What’s the point of that “?”?)

Thank you again,

Ezequiel

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,129247#msg-129247

rewrite ^(.*/)index.html http://$host$1 permanent;

At the risk of pushing it… is there a way to make the redirect 301
rather than 302?

In case anybody is interested, the following code (very similar to the
original I found elsewhere) works OK in the latest version, 0.8.50, with
a 301 response:

  location / {
        root   /var/www/mysite;
        index  index.html index.htm;
        if ($request_uri ~ (.*/)index.html) {
        set $files $1;
        rewrite ^ http://$host$files permanent;
        }
    }

By now I don’t even know if I tried this exactly with an older
version… certainly something like this, but it didn’t work.

Cheers!

Ezequiel

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,129630#msg-129630

rewrite ^(.*/)index.html http://$host$1 permanent;

Hi Mat,

I like your proposal better, which looks more elegant without the if
clause, but I don’t know where to include it. Under location / I get a
redirect loop.

Thanks,

Ezequiel

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,129754#msg-129754

On Sun, Sep 12, 2010 at 12:13:11PM -0400, ez77 wrote:

rewrite ^(.*/)index.html http://$host$1 permanent;

Hi Mat,

I like your proposal better, which looks more elegant without the if
clause, but I don’t know where to include it. Under location / I get a
redirect loop.

You should set it on server level.


Igor S.
http://sysoev.ru/en/

Location / would also work although server is probably better

Must I include an if clause? I still get a redirect loop without one.

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,129926#msg-129926

no you shouldnt need an if clause.

Location / would also work although server is probably better

Sent from my iPod

On Mon, Sep 13, 2010 at 03:46:55PM +1000, Splitice wrote:

Location / would also work although server is probably better

No. If you request “/dir/” with the confuguration

 location / {
     rewrite ^(.*/)index.html http://$host$1 permanent;
     index   index.html;
 }

then nginx will do an internal redirect to “/dir/index.html”.
If the redirect will be handled in the “location /”, then
nginx will rewrite it to an external redirect “http://host/dir/”.
And so on.

In this configuration:

 rewrite ^(.*/)index.html http://$host$1 permanent;

 location / {
     index   index.html;
 }

nginx will not run the server level rewrite, after the internal redrect,
so there will not be the loop.

I like your proposal better, which looks more elegant without the if


nginx mailing list
[email protected]
http://nginx.org/mailman/listinfo/nginx


nginx mailing list
[email protected]
http://nginx.org/mailman/listinfo/nginx


Igor S.
http://sysoev.ru/en/

Change ‘permanent’ to ‘redirect’.

Marcus.

In this configuration:

rewrite ^(.*/)index.html http://$host$1 permanent;

location / {
index index.html;
}

nginx will not run the server level rewrite, after the internal
redrect,
so there will not be the loop.In this configuration:

rewrite ^(.*/)index.html http://$host$1 permanent;>

location / {
index index.html;
}

nginx will not run the server level rewrite, after the internal
redrect,
so there will not be the loop.

I still get a redirect this way. Let me point out the “mysite”
configuration file under /etc/nginx/sites-available/ (too embarrassed to
give the actual highly-in-construction site):

server {
listen mysite:80;
server_name .mysite;
if ($host ~* ..(mysite.)) {
set $host_without_www $1;
rewrite ^(.
)$ http://$host_without_www$1 permanent;
}

access_log /var/log/nginx/mysite.access.log;

rewrite ^(.*/)index.html http://$host$1 permanent;

location / {
root /var/www/mysite;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/mysite;
}
}

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,130089#msg-130089

On Mon, Sep 13, 2010 at 01:39:05PM -0400, ez77 wrote:

so there will not be the loop.In this configuration:

    }

location = /50x.html {
root /var/www/mysite;
}
}

Sorry, I was wrong: after an internal redirect nginx runs server level
rewrite’s. It does not run them if it looks for a new location after
location
level rewrite’s. So here is working configuration for 0.8.50:

server {
    root   /var/www/mysite;

    location / {
        try_files  $uri  $uri/index.html  $uri/index.htm  =404;
    }

    location ~ ^(?<DIR>.*/)index.html$ {
        return  301  http://$host$DIR;
    }
}

or you may use

    location ~ ^(?<DIR>.*/)index.html$ {
        rewrite ^ http://$host$DIR permanent;
    }

for 0.7.x and earlier:

    location ~ ^.*/index.html$ {
        rewrite ^(.*/)index.html http://$host$1 permanent;
    }

As to

     if ($host ~* .\.(mysite.*)) {
             set $host_without_www $1;
             rewrite ^(.*)$ http://$host_without_www$1 permanent;
     }

please look this:
http://nginx.org/en/docs/http/converting_rewrite_rules.html


Igor S.
http://sysoev.ru/en/

Thank you, Igor. I have cleaned up my subdomain redirection the way it
should be. Moreover, your instructions for “dir/index.html -> dir/” work
under version 0.8.50.

As the whole point of my pet peeve was to have unique, canonical URLs
for every document, I found it surprising that now URLs such as …/dir
are not automatically rewritten (301) as …/dir/ . I know I’m a royal
pain… but (if you don’t mind) what is the difference now?

Thanks again!

Ezequiel

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,130146#msg-130146

Can the catch-all virtual host redirect with 301 instead of 302?

I got this one: adding “permanent” after the rewrite directive… Sorry.

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,128951,130156#msg-130156