Nginx rewrite to remove first (generic) path node

5,474

The rewrite in your location block gets evaluated first, then proxy_pass is used. This is the reason your map block won't work with $uri. Because when the map block is triggered the URL is already rewritten. I have this config in my lab which works as expected:

map $custom_service $custom_backend {
        google "https://www.google.com";
        bing "https://www.bing.com";
}
location ~ ^/([^\/]+)/.* {
        set $custom_service $1;
        rewrite ^/[^\/]+(/.*)$ $1 break;
        proxy_pass $custom_backend;
}

The map block goes into the http block and the location block into the server block.

Your URLs look like this:

http://nginx/google/some/params -> backend is now -> https://www.google.com/some/params
http://nginx/bing/some/params -> backend is now -> https://www.bing.com/some/params
Share:
5,474

Related videos on Youtube

leifg
Author by

leifg

Updated on September 18, 2022

Comments

  • leifg
    leifg over 1 year

    I am currently writing a dispatcher that will dispatch different URLs to specific service URLS.

    I essentially want to dispatch something like:

    POST http://nginx/awesome_service/a/lot/of/params/and?so=on
    

    to

    POST http://awesome_service/a/lot/of/params/and?so=on
    

    I already achieved by hard coding the service name:

    location /awesome_service {
        rewrite ^/awesome_service(/.*)$ $1 break;
        proxy_pass http://awesome_service;
    }
    

    However I have different services with different names and I don't want to duplicate the routes.

    I used a map to from name to url:

    map $uri $service_url {
      ~^/awesome_service/ "http://awesome_service";
      ~^/mediocre_service/ "http://mediocre_service";
    }
    

    So it's easy to dispatch to a variable proxy url:

    location /awesome_service {
        rewrite ^/awesome_service(/.*)$ $1 break;
        proxy_pass $service_url;
    }
    

    However, I'm still struggling with the rewriting.

    This is what I came up with so far:

    location ~ ^/([^\/]+)/.* {
        set $service $1;
        rewrite ^/$service(/.*)$ $1 break;
        proxy_pass $service_url;
    }
    

    The request is captured and passed on. But the rewriting fails. The service still sees the first part of the url.

    Is there maybe a mixup with the regex or am I passing in the variable wrong?

    • Alexey Ten
      Alexey Ten almost 10 years
      Do you have tens or hundreds of applications? If not it's better stick with several explicit location blocks.