3

I am trying to create redirect to add trailing slash,

location / {
  if($request_uri ~ ^([^.]*[^/])$){
    return 301 https://$host$request_uri/;
  }
}

I have no idea how to do matching in if, when I simply create redirect with / - it works, just this regex seems broken.

UPDATE

Rewrite I tried

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

and

if ($http_x_forwarded_proto != "https") {
  return 301 https://$host$request_uri;
}

works fine, redirects to https, I wanted to create regex with it aswell

sdooo
  • 171
  • 1
  • 1
  • 8
  • Show full config and describe the reason to do so – Alexey Ten May 15 '15 at 15:30
  • What do you have against rewrite ? Note that `if` is in most cases not what you want : http://wiki.nginx.org/IfIsEvil – krisFR May 15 '15 at 15:31
  • I updated my answer, I can't share code here, so if you have some insights about it that would be cool, if not I'll try to manage myself. Rewrite adds some custom port, and config file is quite big so I don't want to mess with its proxies etc. – sdooo May 15 '15 at 15:35
  • 1
    Try this rewrite : `rewrite ^(.*[^/])$ $1/ permanent;` – krisFR May 15 '15 at 16:05
  • This adds slash to index.html etc. so this isn't what I wanted, although it works with files that already exist, like it will work with /index.html, but won't work with /admin, here goes redirect to some custom port, any idea how to add slash to directory? – sdooo May 15 '15 at 16:21
  • 1
    You are really unclear about what you want ! ;) – krisFR May 15 '15 at 17:54
  • @Sindis you didn't mention that not all requests should be redirected – Alexey Ten May 16 '15 at 08:54
  • Yeah, my bad, but this doesn't work anyway - it adds slash only to files, not to directories – sdooo May 16 '15 at 11:31
  • @krisFR as stands in title, I want to add trailing slash. Obviously nginx shouldn't add one to /index.html but should add to /admin. So since it doesn't work for me with rewrite I wanted to add `if` statement for any uri that matches a regex given above – sdooo May 16 '15 at 11:39

3 Answers3

4

Long time ago solved but I see many people check this question, so if I recall correctly I didn't have this line of code, and it was redirecting me:

port_in_redirect off;

I know, I didn't mention ports in question, no way it could be answered but I'll just leave it here if someone had same problem

sdooo
  • 171
  • 1
  • 1
  • 8
3

If I understand the question correctly, you want to automatically serve, without using a 301 redirect, http://example.com/foo/index.html when the request is for http://example.com/foo with no trailing slash?

If so I've found this try_files configuration to work:

try_files $uri $uri/index.html $uri/ =404;
  • The first $uri matches the uri exactly
  • The second $uri/index.html matches a directory containing the index.html where the last element of the path matches the directory name, with no trailing slash
  • The third $uri/ matches the directory
  • The fourth =404 returns the 404 error page if none of the preceding patterns match.
John Weldon
  • 413
  • 1
  • 3
  • 13
0

This seems to work as expected :

location / {
    if ($request_uri ~ ^([^.]*[^/])$) {
        return 301 https://$host$request_uri/;
    }
    try_files $uri $uri/ /index.html;
    ....
}

Not sure to see the difference with the one you have tried, except the syntax error you should have encountered because of missing spaces in the if statement (could be a typo). ...or maybe because you have other directives you don't show us that override this one.

krisFR
  • 13,280
  • 4
  • 36
  • 42