I have a strange issue with a trailing /

I'm using nginx and it is functioning correctly with one small exception.
I have the following site config

    server {
listen         80;
return         301 https://$server_name$request_uri/;
server_name    sub1.sub2.domain.com;
    server {
 listen              443 ssl; # The ssl directive tells NGINX to decrypt
                              # the traffic
 server_name         sub1.sub2.domain.com;
 ssl_certificate     /etc/nginx/ssl/sub1.sub2.domain.com/server.crt; # This is the certificate file
 ssl_certificate_key /etc/nginx/ssl/sub1.sub2.domain.com/server.key; # This is the private key file
 location / {
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    

I have an offsite authentication service running and securing a subfolder called secure, so if a request for either /secure or /secure/ is requested they are sent to the off-site authentication service. Once they are authenticated they are redirected back to the whatever url they initial requested. If after authentication they happen to request /secure/ everything works perfectly. If they type /secure (no trailing /) nginx does a 301 redirect after authentication and replaces the https with http, so they get to http://sub1.sub2.domain.com/secure and then go through another redirect back to https

From what I've read here http://nginx.org/en/docs/http/ngx_http_core_module.html#location this is the correct behaviour, but the solution to define /secure/ and /secure as seperate location files doesn't seem to work, and it also doesn't mention anything in that example about the https to http change. Any help would be greatly appreciated.

  • I see nothing in nginx config that could lead to redirect. Look for it in your backend server. BTW, you don't need trailing slash in your http->https redirect directive. – Alexey Ten May 5 '15 at 16:55

Your app is responsible for this and that's because you need to forward the current scheme with extra headers like X-Forwarded-Proto since you disabled proxy_redirect which means redirects are left intact from you upstream server and sent directly to visitors without nginx making it relative to the location context or the scheme being used in the current server block.

So fix it there or use nginx's proxy_redirect a relevant way instead.

  • 1
    Hi Xavier. After reading your answer I found this (serverfault.com/questions/372886/…) which seems to apply. I followed the answer there and it is now no longer doing the https > http redirect. – Drifter104 May 6 '15 at 9:52

You are explicitly adding the trailing slash in your redirect:

return         301 https://$server_name$request_uri/;

This obviously isn't what you want.

So don't add a trailing slash:

return         301 https://$server_name$request_uri;
  • Thanks for spotting this, I was wondering why I was getting a double // when trying the http site. – Drifter104 May 6 '15 at 9:53
  • I would plus one this but not enough rep, sorry – Drifter104 May 6 '15 at 10:07

So it turns out the documentation was right (who knew), I had introduced more issues while trying to resolve the first problem of the trailing /

I was able to fix the issue by making the following changes.

return         301 https://$server_name$request_uri;

(Removing the trailing / for the http redirect)

location = /secure {
            return  301 https://$server_name$request_uri/;

This performs a redirect for anyone not putting / at the end of secure prior to going to the authentication service.

proxy_redirect http:// $scheme://;  

This rewrites every http redirect from the application to https

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.