Scooby
Scooby

Reputation: 3581

reroute nginx request url

I have a reverse nginx proxy where I want to route all request that come in with :

http://dns.com/content/xyz <—to—> http://dns.com/content/1.0/xyz

I have an upstream :

upstream backend_api.content.com {
        server localhost:8080 max_fails=5 fail_timeout=30;
        keepalive 100;
  }

and location :

#Content Service
location ~* ^/content/?(.*) {
     set $proxy_pass "http://backend_api.content.com";
     rewrite ^/content/1.0(/.*)$ /content/1.0$1 break;
     proxy_pass $proxy_pass
     proxy_http_version 1.1;
     proxy_set_header Connection "";
     proxy_set_header  X-Real-IP  $remote_addr;
     proxy_set_header  Host "api.stg.xxx.com";
     proxy_set_header X-3scale-proxy-secret-token $secret_token;
     proxy_set_header Original-Host $http_host;
     proxy_set_header Authorization $outbound_auth_header;
     proxy_set_header Original-Uri $scheme://$http_host$uri;
     post_action /out_of_band_oauth_authrep_action;
    }

but it seems like anything with http://dns/content/xyz fails and only when I give http://dns/content/1.0/xyz does it work.

Upvotes: 1

Views: 99

Answers (1)

Richard Smith
Richard Smith

Reputation: 49792

You seem to be capturing part of the URI on the location ~* ^/content/?(.*) statement, but do nothing with it.

You also have a rewrite ^/content/1.0(/.*)$ /content/1.0$1 break; statement that does nothing, it simply writes the same URI back.

A quick and dirty solution might be to use two rewrite statements like this:

rewrite ^/content/1.0(/.*)$ /content/1.0$1 break;
rewrite ^/content(/.*)$ /content/1.0$1 break;

Which means that anything that does not match the first (non-) rewrite will be processed by the second, and get a /1.0 inserted.

Personally, I do not like it, and would rather use two location blocks:

location /content/1.0 {
    set $proxy_pass "http://backend_api.content.com";
    proxy_pass $proxy_pass;
    proxy_http_version 1.1;
    proxy_set_header ...
    ...
}
location /content {
    rewrite ^/content(/.*)$ /content/1.0$1 last;
}

But check the evaluation order of your other location blocks. Note that prefix location blocks and regular expression location blocks have different evaluation rules. See this document for details.

Upvotes: 1

Related Questions