nginx - Passing request header variables to upstream URL as query parameter - nginx

I have an application running on localhost listening on port 8080
nginx is running as reverse proxy, listening on port 80
So, a request coming to nginx on port 80 is sent to this application listening on localhost:8080 and response from this application sent back to the user
Now this application is incapable of reading the header variables from request header and can read only query parameters
So I want nginx to pass header values as query parameters to this application listening on localhost:8080
E.g. let us say in the request header there is a custom variable called 'userid'.
How do we pass this userid as &userid=value appended to the url to application listening on localhost 8080
My current test file of site-available and site-enabled is
server {
location /test {
proxy_pass http://localhost:8080;
}
}

So there is no need to do rewrite or anything else. Simply pass the header parameters that you want to pass as query parameter to the localhost application like below by appending to the arguments.
If you have custom header parameter like userid, then it would be $http_userid
server {
location /test {
set $args $args&host=$http_host;
proxy_pass http://localhost:8080;
}
}

If you have a request header called userid, it will be available within an Nginx variable called $http_userid.
You can alter the query parameters of the original request with a rewrite...break statement.
For example:
location /test {
rewrite ^(.*)$ $1?userid=$http_userid break;
proxy_pass http://localhost:8080;
}
See this document for details.

Related

Nginx proxy remove spesific path and emty Post request body +HTTPS

I'm using nginx for web service proxy. I have rest service as below and i want to proxy my domain
https://www.example.com/myRestservice. Service has some method like this;
http://1.1.1.1:123/api/work/method1
http://1.1.1.1:123/api/work/method2
*By the way services publish on two server as below in nginx.conf
As result i want to access to methods of service like "https://www.example.com/Restservice/api/work/method1"..
When i try to use rewrite in nginx as below, i can access service.
But in this time Post method's request body is emty. I can see service logs.
In my nginx.config
upstream RestService {
server 1.1.1.1:123;
server 1.1.1.2:123;
}
server {
listen 443 ssl;
server name https://www.example.com;
location ~ ^/Restservice/ {
add_header Access-Control-Allow-Origin *;
rewrite ^/Restservice/(.*) /$1 break;
proxy_pass http://Restservice/;
proxy_http_version 1.1;
}
}
Bye the way i try to location part like this, result is same.
location /Restservice {
proxy_pass http://Restservice/;
}
Normally I can access soap service with config from https link.
Is it about http redirection to https ?
In nginx access log;
status : 500
request: POST /Restservice/api/work/method1 HTTP/1.1
I find the reason. Because of the endcoding.
After choosing endcoding type 'UTF-8', I could see request body.

Can a response from an http request alter the base address in the next client request?

I have an octoprint server running at http://192.168.1.205. I also have an nginx server hosting myDomain. I want to be able to use the nginx server to pass on a request for http://myDomain/octo to http://192.168.1.205 using a reverse proxy. Here is my nginx code...
server {
server_name myDomain;
location /octo/ {
rewrite ^/octo/(.*) /$1 break; #strip /octo from url
proxy_pass http://192.168.1.205;
}
}
The first http://myDomain/octo request is passed on to http://192.168.1.205 correctly. But after the first response the code in the client makes another request to http://myDomain/moreUri. Since this uri doesn't have /octo nginx doesn't know to send it to http://192.168.1.205/moreUri. Is there a way to have nginx change something in the first response so that the client then makes following requests to http://myDomain/octo/moreUri?
I was able to accomplish this for a case where the octoprint server responded with a redirect. I used ...
proxy_redirect http://192.168.1.205/ http://myDomain/octo/;
and it worked. But that only works on redirects and the following requests were wrong again.
Is there a way to have nginx change something in the first response so
that the client then makes following requests to
http://myDomain/octo/moreUri?
I am not aware that this is possible.
What about to adjust the nginx configuration accordingly ? using location / to process all requests within that block and add an additional redirect directive to address the "Since this uri doesn't have /octo nginx doesn't know to send it to http://192.168.1.205/moreUri" should do the trick.
server {
server_name myDomain;
location / {
rewrite ^/octo/(.*) /$1 break; #strip /octo from url
rewrite ^/(.*)/(.*) /octo/$2 break; #rewrite /moreURI to /octo/moreURI
proxy_pass http://192.168.1.205;
}
}
No matter if the above nginx reconfiguration fixes your issue, i assume the root cause why you need to configure the nginx as reverse proxy in this way might be a misconfigured (or not optimally configured) application. Check the config file if it is possible to configure the applications base path. If so, set it to /octo/ (so the application itself prepends /octo/ to all the links it presents to the user and all requests to the backend automatically) and adjust the rewrite rules accordingly.

location prefix matching nginx doesn't work with variables

Hi Earlier I was matching location prefix uri matching to get the redirection to website www.example.com/abc/ from www.example.com/bbb/abc(requested uri).
server {
location /bbb/ {
proxy_pass http://www.example.com/;
}
}
Earlier I was requesting on www.example.com/bbb/abc and getting redirected to www.example.com/abc
as I required
However now the problem is I've resolver and I'm also using variable. This is done to ensure that nginx starts even if one of the upstream services are down and it won't show the error of
[nginx] host upstream not found
server {
location /bbb/ {
resolver 127.0.0.11 valid=some secs;
set $example www.example.com
proxy_pass http://$example/;
}
}
Now that I'm using variable, I think url location prefix match is not working as I am sending request on www.example.com/bbb/abc , and it shows the nginx 404 not found.
Can anyone guide me how redirect properly with variable and resolver included.

Nginx server returns 308 status code when trying to proxy pass to external hosted service

I am trying to proxy pass one of my nginx server endpoint to an external service that intern redirects calls to another service with in it.
my config looks like below
location = /proxy/live {
proxy_pass <externalservice ip:port>/live;
proxy_pass_request_body on;
}
with in the external service /live endpoint redirects to another service that is unknown to my nginx server.
with the above configuration I am getting 308 error code (redirection issue). while trying to access /proxy/live endpoint. How can i resolve this issue and get the proxy_pass call through external service up till the end service.
If the URL argument of the proxy_pass directive ends with a trailing slash - then the location path is not appended to this URL. However, if the URL does not end with a trailing slash - then the location path is appended to this URL when passing to the upstream.
This is not very clear from the nginX documentation where they simply refer to the proxy_pass as being either specified with an URI or without an URI:
If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:
location /name/ {
proxy_pass http://127.0.0.1/remote/;
}
If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI:
location /some/path/ {
proxy_pass http://127.0.0.1;
}

Why NGinx don't pass the HOST?

I need to use NGinx as a proxy to another HTTP proxy, and it doesn't works because it doesn't sent the HOST of original url, only the path.
If I perform the request with curl it works and the dump is
curl --proxy http://localhost:81 http://sample.com/sample
http://sample.com/some-path
{ host: 'sample.com' }
If I perform the request with NGinx with the following config - it doesn't works and the dump is (the domain in the path is missing)
upstream proxies {server localhost:81;}
location / {
proxy_set_header Host $host;
proxy_pass http://proxies;
}
/some-path
{ host: 'sample.com' }
How to make NGinx to pass the whole path?
Solution is to add other proxy, for example DeleGate. Yes, NGinx won't pass the HOST properly, but the DeleGate fixes that.
Your Browser or App -> (NGinx -> DeleGate) -> whatever other proxy or app...

Resources