proxy - Nginx rewrite to remove first (generic) path node

08
2014-07
  • leifg

    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?

  • Answers
    Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

    Related Question

    ssl - Nginx-Remove WWW from HTTPS
  • NetStudent

    I would like to ask for some help with the following Nginx configuration, so that URLs such as https://www.mywebsite.com get rewritten as https://mywebsite.com. I am currently using the following configuration:

    server {
        server_name www.mywebsite.com;
        return 301 $scheme://mywebsite.com$request_uri;
    }
    server {
        listen 80;
        server_name mywebsite.com;
    
        # Some more settings...
    }
    server {
        listen 443 ssl;
        server_name mywebsite.com;
    
        ssl_certificate path_to_ssl_certificate;
        ssl_certificate_key path_to_ssl_certificate_key;
    
        # Some more settings...
    }
    

    In case that matters, the certificate I am using is a wildcard SSL certificate that was self-signed using OpenSSL on the server itself (Ubuntu 12.04). What is happening is that www.mywebsite.com correctly redirects to mywebsite.com, but https://www.mywebsite.com does not redirect to https://www.mywebsite.com (i.e., the www still appears when viewing the page in a browser). What can I be doing wrong?


  • Related Answers
  • Dmitry Verkhoturov

    The solution is fixing first server block to this:

    server {
        listen 80;
        listen 443;
        server_name www.mywebsite.com;
        return 301 $scheme://mywebsite.com$request_uri;
    }
    

    E.g. you forgot to catch www.mywebsite.com connections on ssl port, that's all. By the way, it's the best way to remove www from site name, good choice.

  • mgorven

    Your redirect happens in a virtual host only listening on port 80. To redirect requests coming in over SSL you need a virtual host listening on port 443 with SSL. Unless your browsers all support SNI, you can only have one SSL virtual host, and so the rule needs to go into your existing SSL server block.

    if ($host = www.mywebsite.com) {
        rewrite ^ https://mywebsite.com$request_uri? permanent;
    }