Search code examples
nginx

Too many redirects when using regex in nginx.conf


I have the following configuration for a swagger.json in nginx:

location /project1/v2 {
      
  absolute_redirect off;
  alias             /project1/v2;
  expires           1d;

  location ~* \.(?:json|yml|yaml)$ {
    # SWAGGER_ROOT
    expires         -1;
    include         /etc/nginx/templates/cors.conf;
  }

  include         /etc/nginx/templates/cors.conf;
}

location /project1{
  set               $args $args&url=http://localhost/project1/v2/swagger.json;
  absolute_redirect off;
  alias             /usr/share/nginx/html/;
  expires           1d;
  include           /etc/nginx/templates/cors.conf;
}

and this works fine. However, I have a second project where I try to capture the name from URL using regex and redirect as follows:

location ~ ^/(project1|project2)/v2 {
      
  absolute_redirect off;
  alias             /$1/v2;
  expires           1d;

  location ~* \.(?:json|yml|yaml)$ {
    # SWAGGER_ROOT
    expires         -1;
    include         /etc/nginx/templates/cors.conf;
  }

  include         /etc/nginx/templates/cors.conf;
}

location ~ ^/(project1|project2) {
  set               $args $args&url=http://localhost/$1/v2/swagger.json;
  absolute_redirect off;
  alias             /usr/share/nginx/html/;
  expires           1d;
  include           /etc/nginx/templates/cors.conf;
}

and this yields to too many redirects error with URL changing to: http://localhost/project1/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/index.html/?&url=http://localhost/project1/v2/swagger.json&url=http://localhost/project1/v2/swagger.json&url=http://localhost/project1/v2/swagger.json&url=http://localhost/project1/v2/swagger.json&url=http://localhost/project1/v2/swagger.json...

What am I missing?


Solution

  • alias works differently when inside a regular expression location.

    In your first block:

    location /project1/v2 {
        alias  /project1/v2;
        ...
    }
    

    You don't need to use alias at all. The alias statement should be replaced by root /;, in which case, it will remain the same when the location is changed to a regex.

    For example:

    location ~ ^/(project1|project2)/v2 {
        root /;
        ...
    }
    

    In your second block:

    location /project1 {
        alias  /usr/share/nginx/html/;
        ...
    }
    

    In order to convert it to a regex location, you must capture the entire URL, and form the entire replacement pathname in the alias expression.

    For example:

    location ~ ^/(project1|project2)(.*)$ {
        alias  /usr/share/nginx/html$2;
        ...
    }
    

    Note that $2 already includes a leading / (if any).