Add a request header while redirecting in NGINX - http

I have a simple redirect rule like
location = /redirect-me {
return 307 http://localhost:3001/redirect-me;
}
There will be a POST call to the redirect-me url, all I want to do is to redirect the post call to another server.
But how can I add a X-Header to the request header going to http://localhost:3001/.
I tried both add_header and proxy_set_header.add_header is adding the header to the response header not the request header.
location = /redirect-me {
add_header 'X-Header-a' 'cust_info';
proxy_set_header 'X-Header-p' 'cust_info';
return 307 http://localhost:3001/redirect-me;
}
and proxy_set_header is not adding anything.
So how can I add a header to the request while redirecting with 307. ?

Use the proxy_pass directive instead of a redirect. I supplied the link below for the docs which includes an example of setting headers.
location /redirect-me {
proxy_set_header 'X-Header-p' 'cust_info';
proxy_pass http://localhost:3001/redirect-me;
}
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

Related

How do I set default headers for upstream responses in nginx?

I want to make sure that at least the default header value is always returned from upstream. Even if upstream is unavailable, which causes error 5xx.
Now I have tried these nginx config options:
server {
...
#add_header "Access-Control-Allow-Origin" "*"; №0
#add_header "Access-Control-Allow-Origin" "*" always; №1
#more_set_headers "Access-Control-Allow-Origin: *"; №2
#more_set_headers -s '403 500 502 504 503' "Access-Control-Allow-Origin: *"; №3
location /upstream {
proxy_pass http://localhost:1234;
}
...
}
There are problems with all the options:
№0: Duplicates the header, and in the case of 5xx will not return any.
№1: Duplicates the header
№2: Overrides the upstream header
№3: If the upstream ended with a good http code, but did not return a header, it will not add a header.
I think I'm close to the right solution, but I can't find it.
The map below uses a regex, /.+/, to check if the Access-Control-Allow-Origin header is defined. If so, it assigns its value to the $acao custom variable. Otherwise, it assigns the default value * to $acao;
To avoid duplications, use proxy_hide_header
Finally, add the header using the $acao variable content.
http {
map $upstream_http_access_control_allow_origin $acao {
~.+ $upstream_http_access_control_allow_origin;
default '*';
}
server {
#…
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin $acao always;
location /upstream {
proxy_pass http://localhost:1234;
}
}

NGINX keep URL at /location/some-path and serve /location/?

Is this possible?
User enters https://mywebsite.com/location/any-path
Nginx runs https://mywebsite.com/location/
URL displays https://mywebsite.com/location/any-path
Is there a particular name for this type of action also?
You can use nginx redirection here -
location = /location/any-path {
return 301 /location;
}
You want to proxy_pass the request to another url and then proxy_redirect to alter the url displayed to the client.
Something like this:
location ~ /location/(.+) {
resolver 8.8.8.8;
proxy_pass https://mywebsite.com/location/index.php;
proxy_redirect /location/ /location/$1/;
}

Nginx passing url arguments as header

In the following example:
http {
server { # simple reverse-proxy
listen 8080;
location / {
set $token $arg_token;
#return 200 $token;
add_header test "test $token";
proxy_pass http://localhost:5601;
}
} ...
}
if I leave return 200 $token I obtain the token as response + in header (which is a normal behavior) but when I delete return I obtain only "test" as test header value, what am I missing please ?
The proxy_set_header sets header that NGINX will use while communicating to the upstream/backend.
You won't see that added header in the response of NGINX back to the client.
If you want to see it, use add_header as well.

Hot change "Location" in the reply header 302 code from proxy-host.

I have the kubernetes-cluster and a few pods/containers with web-app. Pods connecting to each other by pod's name with listen port 9999 (like security-rest-api:9999, common-rest-api:9999, etc).
To outside listen nginx-pod with outside address http://e.net:30200/.
((app-pods:9999)-(nginx-pod:80)-(nginx-service:30200))-Network
Nginx use follow configuration for interactive with app-pods.
server {
listen 80;
server_name e.net;
location / {
proxy_pass http://web-console:9999/;
proxy_redirect http://web-console:9999/ http://e.net:30200/;
}
location /common {
proxy_pass http://common-rest-api:9999/common;
proxy_redirect http://common-rest-api:9999/ http://e.net:30200/;
}
location /security {
proxy_pass http://security-rest-api:9999/security;
proxy_redirect http://security-rest-api:9999/ http://e.net:30200/;
} }
It's working very well, but I have the one problem with 302-reply from app-pods:
If I try to login in my app, I get follow the 302 reply header:
HTTP/1.1 302 Found
Connection: keep-alive
Content-Length: 0
Date: Wed, 25 Apr 2018 10:37:50 GMT
Location: http://e.net:30200/security/rest/auth/login.html?callbackUrl=http://security-rest-api:9999/security/rest/namespace
Server: nginx/1.13.9
App-pods generated URL parameter "callbackUrl" from the Host request header Inside containers network and this URL parameter to get to the endpoint browser. Of course, next request get 404 code.
I can't to edit app-code (in app-pods don't use nginx), but I want to change 'security-rest-api:9999' to 'e.net:30200' parameter in the Location 302 reply header. How I can do it?
redirect isn't suitable since this generate new 302-reply and not solve my problem.
sub_filter change only reply body, but not reply head (where is Location parameter).
request_uri not working too, since this parameter work with request header only.
No, It's not working.
I tested this situation and finded work's config:
if ($args ~* (.*)(callbackUrl=http://security-rest-api:9999/)(.*)) {
set $args $1callbackUrl=http://e.net:30200/$3;
rewrite ^(.*)$ $1;
}
if ($args ~* (.*)(callbackURL=http%3A%2F%2Fsecurity-rest-api%3A9999%2F)(.*)) {
set $args $1callbackURL=http%3A%2F%2Fe.net%3A30200%2F$3;
rewrite ^(.*)$ $1;
}
location /security {
proxy_pass http://security-rest-api:9999/security;
proxy_set_header Host $http_host;
proxy_redirect http://security-rest-api:9999/ http://e.net:30200/;
}
Later, I will try to use this config on the pre-production stand and if this work (or work after corrects) - I will write it here.
Thanks for help information:
https://blog.imaginea.com/modifying-query-parameters-nginx-in-reverse-proxy-mode/
And thanks for you all, too!
Edit
I tested this config and have 2 edits:
If you to use un-standart port - you need write "proxy_set_header Host $http_host;" in location section;
URL in attributes can be like "http://security-rest-api:9999/" and like "http%3A%2F%2Fsecurity-rest-api%3A9999%2F". You need to use both conditions for each type of attribute.
I corrected code with this edits

configuring proxy_pass multiple params with ngnix

I need to set proxy_pass for the below url pattern.
location ~ ^/hosts/bu/(.*)/app/(.*)$ {
proxy_pass http://appserver.cnma.com:3000/hosts/bu/$1/app/$2;
}
When I try with the URL it does not pass the second parameter correctly. Please let me know where I am going wrong.
Orig docs say:
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;
}
So there is enough:
proxy_pass http://appserver.cnma.com:3000$request_uri;
you can use named capture in nginx while using regular expressions
location ~ ^/hosts/bu/(.*)/app/(.*)$ {
proxy_pass http://appserver.cnma.com:3000/hosts/bu/$1/app/$2;
}
You can modify block to below like this
location ~ ^/hosts/bu/(?<loc1>.+)/app/(?<loc2>.+)$ {
proxy_pass http://appserver.cnma.com:3000/hosts/bu/$1/app/$loc2;
}

Resources