Trailing Slash Redirect Loop Help

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Trailing Slash Redirect Loop Help

rnburn
Hi,

I am having an issue getting rid of the trailing slashes for directories.  I
have used the following to get rid off the trailing slash:


#rewrite all URIs without any '.' in them that end with a '/'        
        #rewrite ^([^.]*)/$ $1 permanent;

&
#rewrite all URIs that end with a '/'  
rewrite ^/(.*)/$ /$1 permanent;

They both work, but they do not when it comes to directories.  When it is a
directory the page is not displayed because it has different redirects.
Here is the code that I have used inside the LOCATION definition as well as
in the SERVER block and they just do not work.


if (!-e $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}

Or, I have used this one:

if (!-e $request_filename) {
rewrite ^([^.]*)/$ $1 permanent;
}

Note:  I have tested individually the two rules either in the server block
or the location block and I still get the redirection problems with files or
directories.


Could any of you please help me and tell me what I am doing wrong.
Basically, when I enable the rewrite rule to get rid off the trailing slash
all directories get multiple redirects and end up in a loop.

Here is the nginx configuration.


user www-data;
worker_processes X;
pid /xxxx.pid;

events {
        worker_connections xxxx;
        # multi_accept on;
}



http {
        ##
        # Basic Settings
        ##

        sendfile off;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        #below hides the version of nginx
        server_tokens off;

        server_names_hash_bucket_size 64;
        #this sets the url hash map table size for url rewrites
        map_hash_bucket_size 128;
        map_hash_max_size 2048;
        # server_name_in_redirect off;

        include /xxxx.types;
        default_type application/octet-stream;

     

        ##
        # Gzip Settings
        ##

        gzip on;

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 7;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
  # Disable for IE < 6 because there are some known problems
        gzip_disable "MSIE [1-6].(?!.*SV1)";

        gzip_types
                text/plain
                text/css
                text/javascript
                application/javascript
                application/json
                application/x-javascript
                application/xml;

        ##
        # Buffer Size
        ##
        proxy_buffering on;
        proxy_buffers   4 256k;
        proxy_buffer_size   128k;
        proxy_busy_buffers_size   256k;

     


        ##
        ## URL REWRITE MAP
        ## File that contains all url rewrite rules for server
        include xxxurlmap.conf;


# SERVER DEFINITIONS




###FORWARD ALL 80 INCOMING REQUEST TO SSL
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name example.com www.example.com;
        return 301 https://www.example.com$request_uri;
}

#HTTPS server

#CHANGE DOMAIN NAME from NO-WWW to WWW - CREATE ONE SERVER INSTANCE AND
RETURN IT
server {
    listen       443 ssl http2;
    server_name  example.com;
    ssl_certificate     /xxx.pem;
    ssl_certificate_key /xxxx.pem;
   return       301 https://www.example.com$request_uri;
}


# Secure Server Configuration HTTPS Server

server {

        listen 443 ssl http2;
        listen [::]:443 ssl http2;        
        server_name www.example.com;

 
        ssl_certificate     /etc/ssl/fullchain.pem;
        ssl_certificate_key /etc/ssl/privkey.pem;
            ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        ssl_session_cache shared:SSL:20m;
        ssl_session_timeout 60m;
       
     
 
       ## THIS CONDITION REWRITES ALL URLS TO THE NEW ONES
        if ( $redirect_uri ) {
        return 301 $redirect_uri;
           }
   

        location / {
            proxy_pass <a href="https://xxxx:xportNumber;">https://xxxx:xportNumber;
            proxy_set_header  Host $host;
            proxy_set_header  X-Real-IP $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 600;
            proxy_send_timeout 600;
            proxy_read_timeout 600;
            proxy_redirect off;
   #this deletes all the traling slash of all Content
   if (!-e $request_filename) {
        rewrite ^/(.*)/$ /$1 permanent;
         }


                }


        }

}

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

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

Steven Hartland
If is evil I'd suggest using try_files instead, which is typically something like:

location / {
     try_files $uri $uri/ =404;
}

    Regards
    Steve


On 28/04/2017 15:27, Alex Med wrote:
Hi,

I am having an issue getting rid of the trailing slashes for directories.  I
have used the following to get rid off the trailing slash:


#rewrite all URIs without any '.' in them that end with a '/'         
        #rewrite ^([^.]*)/$ $1 permanent;

&
#rewrite all URIs that end with a '/'  
rewrite ^/(.*)/$ /$1 permanent;

They both work, but they do not when it comes to directories.  When it is a
directory the page is not displayed because it has different redirects. 
Here is the code that I have used inside the LOCATION definition as well as
in the SERVER block and they just do not work.


if (!-e $request_filename) {
rewrite ^/(.*)/$ /$1 permanent;
}

Or, I have used this one:

if (!-e $request_filename) {
rewrite ^([^.]*)/$ $1 permanent;
}

Note:  I have tested individually the two rules either in the server block
or the location block and I still get the redirection problems with files or
directories.


Could any of you please help me and tell me what I am doing wrong. 
Basically, when I enable the rewrite rule to get rid off the trailing slash
all directories get multiple redirects and end up in a loop.

Here is the nginx configuration.


user www-data;
worker_processes X;
pid /xxxx.pid;

events {
	worker_connections xxxx;
	# multi_accept on;
}



http {
        ##
        # Basic Settings
        ##

        sendfile off;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        #below hides the version of nginx 
	server_tokens off;

        server_names_hash_bucket_size 64;
        #this sets the url hash map table size for url rewrites
        map_hash_bucket_size 128;
        map_hash_max_size 2048;
	# server_name_in_redirect off;

        include /xxxx.types;
        default_type application/octet-stream;

     

        ##
        # Gzip Settings
        ##

        gzip on;

        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 7;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
 	# Disable for IE < 6 because there are some known problems
        gzip_disable "MSIE [1-6].(?!.*SV1)";

        gzip_types
		text/plain
                text/css 
		text/javascript
		application/javascript
	        application/json
		application/x-javascript
		application/xml;

        ##
        # Buffer Size
        ##
        proxy_buffering on;
        proxy_buffers   4 256k;
        proxy_buffer_size   128k;
        proxy_busy_buffers_size   256k;

     


        ##
        ## URL REWRITE MAP
        ## File that contains all url rewrite rules for server
        include xxxurlmap.conf;


# SERVER DEFINITIONS




###FORWARD ALL 80 INCOMING REQUEST TO SSL
server {
	listen 80 default_server;
	listen [::]:80 default_server;
	server_name example.com www.example.com;
	return 301 https://www.example.com$request_uri;
}

#HTTPS server

#CHANGE DOMAIN NAME from NO-WWW to WWW - CREATE ONE SERVER INSTANCE AND
RETURN IT
server {
    listen       443 ssl http2;
    server_name  example.com;
    ssl_certificate     /xxx.pem;
    ssl_certificate_key /xxxx.pem;
   return       301 https://www.example.com$request_uri;
}


# Secure Server Configuration HTTPS Server

server {

        listen 443 ssl http2;
        listen [::]:443 ssl http2;        
        server_name www.example.com;

 
        ssl_certificate     /etc/ssl/fullchain.pem;
        ssl_certificate_key /etc/ssl/privkey.pem;
	    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        ssl_session_cache shared:SSL:20m;
        ssl_session_timeout 60m;
	
     
 
       ## THIS CONDITION REWRITES ALL URLS TO THE NEW ONES
        if ( $redirect_uri ) {
        return 301 $redirect_uri;
           }
   

        location / {
            proxy_pass https://xxxx:xportNumber;
            proxy_set_header  Host $host;
            proxy_set_header  X-Real-IP $remote_addr;
            proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout 600;
            proxy_send_timeout 600;
            proxy_read_timeout 600;
            proxy_redirect off;
   #this deletes all the traling slash of all Content 
   if (!-e $request_filename) {
        rewrite ^/(.*)/$ /$1 permanent;
         }


                } 


        }

}

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

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


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

rnburn
Steveh:

Thank you for your reply.

So what you are suggesting me to do is something like this:

location / {
    try_files $uri $uri/ @rewrite;
}

location @rewrite {
     rewrite ^/(.*)/$ /$1 permanent;
}

Put try files inside the location block and create a new block with the
rewrite?

Thank you for the clarification!

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,273966#msg-273966

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

Steven Hartland
If I understand what you're trying to do correctly, then I think you want something like:
# Ensure no tailing slashes
rewrite ^/(.*)/$ /$1 permanent;

location @upstream {
	proxy_pass https://xxxx:xportNumber;
	proxy_set_header  Host $host;
	proxy_set_header  X-Real-IP $remote_addr;
	proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_connect_timeout 600;
	proxy_send_timeout 600;
	proxy_read_timeout 600;
	proxy_redirect off;
}
location / {
	try_files $uri $uri/ @upstream;
}
This will accept /wibble/ and rewrite it to /wibble (this will be passed back to the client which will then re-request /wibble) when the new request rewritten comes it the server will still look for local matches of /wibble (the file) and /wibble/<index files> (the directory) when searching for the content to serve and if not found will pass the request to your upstream server.
   
    Regards
    Steve

On 28/04/2017 15:48, Alex Med wrote:
Steveh:

Thank you for your reply.

So what you are suggesting me to do is something like this:

location / {
    try_files $uri $uri/ @rewrite;
}

location @rewrite {
     rewrite ^/(.*)/$ /$1 permanent;
}

Put try files inside the location block and create a new block with the
rewrite?

Thank you for the clarification!

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,273966#msg-273966

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


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

rnburn
Steve -

Thank you so much this has brought so much clarity!  I appreciate the time
you spend writing the reply.

So the rewrite ^/(.*)/$ /$1 permanent; needs to be outside of the location
definition and inside the server definition, correct?

Infinite  thanks!

Alex

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,273969#msg-273969

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

Steven Hartland
Yep.

On 28/04/2017 16:43, Alex Med wrote:
Steve -

Thank you so much this has brought so much clarity!  I appreciate the time
you spend writing the reply.

So the rewrite ^/(.*)/$ /$1 permanent; needs to be outside of the location
definition and inside the server definition, correct?

Infinite  thanks!

Alex

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,273969#msg-273969

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


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

rnburn
Steven -

I implemented your suggestion and I still get the same problem with the
directories ... for anything else it works. But when I try to access a
directory ... I can see on the browser address bar the / appearing and
disappearing and then it finally does but the browser gives this error:

Too many redirects occurred trying to open https://xxxx.com/xxx".  This
might occur if you open a page that is redirected to open another page with
then is redirected to open the original page.

I checked and no my configuration I do not redirect anything to a directory
to give that error.

Thanks for your help!

Alex

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,273971#msg-273971

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

Francis Daly
In reply to this post by rnburn
On Fri, Apr 28, 2017 at 10:27:12AM -0400, Alex Med wrote:

Hi there,

> I am having an issue getting rid of the trailing slashes for directories.  I
> have used the following to get rid off the trailing slash:

Why do you want to get rid of the trailing slash for directories?

You can do it; but you will probably have to write the code to tell your
web server how to handle the request, because the common case is that
the slash is wanted.

So - you can make a request for /file/; nginx can issue a redirect to
/file; you can make a request for /file; and nginx can serve the content
of /usr/local/nginx/html/file. All good.

Next - you make a request for /dir/; nginx can issue a redirect to /dir;
you can make a request for /dir; what do you want to happen next? The
nginx-is-serving-this-from-the-filesystem behaviour is for nginx to issue
a redirect to /dir/. If you want something else to happen, you must
decide what that something else is, and then arrange that it happens,
possibly by config and possibly by coding.

Good luck with it,

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

Steven Hartland
In reply to this post by rnburn
My guess would be that your app is redirecting back to the slash urls 

Your could test this with a directory on the webserver that has a matching index file.

Alternatively point a browser at the upstream and check for redirects directly

On 28/04/2017 17:52, Alex Med wrote:
Steven -

I implemented your suggestion and I still get the same problem with the
directories ... for anything else it works. But when I try to access a
directory ... I can see on the browser address bar the / appearing and
disappearing and then it finally does but the browser gives this error:

Too many redirects occurred trying to open https://xxxx.com/xxx".  This
might occur if you open a page that is redirected to open another page with
then is redirected to open the original page.

I checked and no my configuration I do not redirect anything to a directory
to give that error.

Thanks for your help!

Alex

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,273971#msg-273971

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


_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

rnburn
Steve -

You are right something else is adding a trailling slash to directories.  Is
there a way to configure nginx to remove trailing slashes from everything
except from directories?

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,274132#msg-274132

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

rnburn
In reply to this post by Francis Daly
Francis -

Yes, I am realizing that is a nightmare going against the trailing-slashed
directory nature.  So I am going to have this rule take off slashes from
anything but directories.  Do you have any suggestions as how to do it, but
without "if"

Thank you so much!

Alex

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,273964,274134#msg-274134

_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx
Reply | Threaded
Open this post in threaded view
|

Re: Trailing Slash Redirect Loop Help

Francis Daly
On Wed, May 10, 2017 at 11:10:36AM -0400, Alex Med wrote:

Hi there,

> Yes, I am realizing that is a nightmare going against the trailing-slashed
> directory nature.  So I am going to have this rule take off slashes from
> anything but directories.  Do you have any suggestions as how to do it, but
> without "if"

There's a few possibly-useful questions to consider:

Why do you want to do this?

As in: what is the problem that you want to solve? Possibly there is a
better approach than this.

Also: given that you want to do this, why do you want to do this without
"if"?

Sometimes "if" is the correct tool to use.

And: what's a file and what's a directory? Your initial config
example used proxy_pass, which refers to remote urls, not files
or directories. *This* nginx does not know whether an upstream url
corresponds to a file or to something else. So that may want to be
considered before designing the solution.

Good luck with it,

        f
--
Francis Daly        [hidden email]
_______________________________________________
nginx mailing list
[hidden email]
http://mailman.nginx.org/mailman/listinfo/nginx