ChatGPT解决这个技术问题 Extra ChatGPT

How to preserve request url with nginx proxy_pass

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?

"Thin" now points to a 404

a
ansidev

I think the proxy_set_header directive could help:

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

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 proxy_pass directive. http://my_app_upstream vs http://my_app_upstream/
For me what was happening is that when JSP was doing redirect, my_app_upstream host name was showing up. Using proxy_set_header Host $host modified and made Tomcat/JSP to think that it's an actual client requested domain. Thanks for the help
@HugoJosefson wow thanks god I notice your post. This should be explicit in the answer
In my case, @HugoJosefson's solution would not work. I was pointing to localhost:port; I had to set the header.
It's an improvement but the scheme (http or https) is not preserved. Now my https://example.com/page uris become http://example.com/page
G
Grigory Kislin

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;


Thanks, this was the piece I was missing (the $server_port) to get OAuth verification working on the endpoint behind the proxy.
I'm using rack-protection with sinatra and was getting Forbidden on POST URLs. Adding the port to the Host proxy header fixed it for me.
this doesn't work anymore in latest versions of Nginx I think stackoverflow.com/questions/31482796/…
W
Walf

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;
}

C
Chris Stryczynski

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.


r
rahul

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;

V
Velkan

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/


M
Mansur Ul Hasan

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


K
Kai Gouthro

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;
    }
}