How to preserve request url with nginx proxy_pass

RubyProxyNginxThinUnicorn

Ruby Problem Overview


I was trying to use Thin app server and had one issue.

When nginx proxies the request to Thin (or Unicorn) using proxy_pass http://my_app_upstream; the application receives the modified URL sent by nginx (http://my_app_upstream).

What I want is to pass the original URL and the original request from client with no modification as the app relies heavily on it.

The nginx' doc says:

> If it is necessary to transmit URI in > the unprocessed form then directive > proxy_pass should be used without URI > part.

But I don't understand how exactly to configure that as the related sample is actually using URI:

location  /some/path/ {
  proxy_pass   http://127.0.0.1;
}

So could you please help me figuring out how to preserve the original request URL from the client?

Ruby Solutions


Solution 1 - Ruby

I think the proxy_set_header directive could help:

location / {
    proxy_pass http://my_app_upstream;
    proxy_set_header Host $host;
    # ...
}

Solution 2 - Ruby

Just proxy_set_header Host $host miss port for my case. Solved by:



location / {
 proxy_pass http://BACKENDIP/;
 include /etc/nginx/proxy.conf;
}


and then in the proxy.conf



proxy_redirect off;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


Solution 3 - Ruby

> Note to other people finding this: The heart of the solution to make > nginx not manipulate the URL, is to remove the slash at the end of the > Copy: proxy_pass directive. http://my_app_upstream vs > http://my_app_upstream/ – Hugo Josefson

I found this above in the comments but I think it really should be an answer.

Solution 4 - Ruby

In case something modifies the location that you're trying to serve, e.g. try_files, this preserves the request for the back-end:

location / {
  proxy_pass http://127.0.0.1:8080$request_uri;
}

Solution 5 - Ruby

nginx also provides the $http_host variable which will pass the port for you. its a concatenation of host and port.

So u just need to do:

proxy_set_header Host $http_host;

Solution 6 - Ruby

To perfectly forward without chopping the absoluteURI of the request and the Host in the header:

server {
    listen 35005;

    location / {
        rewrite            ^(.*)$   "://$http_host$uri$is_args$args";
        rewrite            ^(.*)$   "http$uri$is_args$args" break;
        proxy_set_header   Host     $host;
        
        proxy_pass         https://deploy.org.local:35005;
    }
}

Found here: https://opensysnotes.wordpress.com/2016/11/17/nginx-proxy_pass-with-absolute-url/

Solution 7 - Ruby

In my scenario i have make this via below code in nginx vhost configuration

server {
server_name dashboards.etilize.com;

location / {
    proxy_pass http://demo.etilize.com/dashboards/;
    proxy_set_header Host $http_host;
}}

$http_host will set URL in Header same as requested

Solution 8 - Ruby

for my auth server... this works. i like to have options for /auth for my own humanized readability... or also i have it configured by port/upstream for machine to machine.

#.

#at the beginning of conf

####################################################
upstream auth {
    server 127.0.0.1:9011 weight=1 fail_timeout=300s;
    keepalive 16;
  }


    

#Inside my 443 server block

          if (-d $request_filename) {
          rewrite [^/]$ $scheme://$http_host$uri/ permanent;
      }

  location /auth {
          proxy_pass http://$http_host:9011;
          proxy_set_header Origin           http://$host;
          proxy_set_header Host             $http_host:9011;
          proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
          proxy_set_header Upgrade          $http_upgrade;
          proxy_set_header Connection       $http_connection;
          proxy_http_version 1.1;
      }

At the bottom of conf

#####################################################################
#                                                                   #
#     Proxies for all the Other servers on other ports upstream     #
#                                                                   #
#####################################################################


#######################
#        Fusion       #
#######################

server {
    listen 9001 ssl;

#############  Lock it down  ################

# SSL certificate locations
    ssl_certificate /etc/letsencrypt/live/allineed.app/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/allineed.app/privkey.pem;

# Exclusions

    include snippets/exclusions.conf;

# Security

    include snippets/security.conf;
    include snippets/ssl.conf;

# Fastcgi cache rules

    include snippets/fastcgi-cache.conf;
    include snippets/limits.conf;
    include snippets/nginx-cloudflare.conf;

###########  Location upstream ##############

    location  ~ / {
        proxy_pass http://auth;
        proxy_set_header Origin           http://$host;
        proxy_set_header Host             $host:$server_port;
        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header Upgrade          $http_upgrade;
        proxy_set_header Connection       $http_connection;
        proxy_http_version 1.1;
    }
        if (-d $request_filename) {
        rewrite [^/]$ $scheme://$http_host$uri/ permanent;
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDmytrii NagirniakView Question on Stackoverflow
Solution 1 - RubyyibeView Answer on Stackoverflow
Solution 2 - RubyGrigory KislinView Answer on Stackoverflow
Solution 3 - RubyChris StryczynskiView Answer on Stackoverflow
Solution 4 - RubyWalfView Answer on Stackoverflow
Solution 5 - Rubyuser6880399View Answer on Stackoverflow
Solution 6 - RubyVelkanView Answer on Stackoverflow
Solution 7 - RubyMansur Ul HasanView Answer on Stackoverflow
Solution 8 - RubyKai GouthroView Answer on Stackoverflow