NGINX : How to capture headers and use them in subsequent responses
- How to capture headers returned by the proxied upstream server in NGINX ?
- How to intercept redirects and follow location while hiding the upstream URL in NGINX ?
- How to add headers to the HTTP response in NGINX ?
Official documentation
This article is based on the official documentation and the following modules:
Cheat sheet
Requests
- proxy_set_header : Sets headers in
Proxied HTTP Request
- proxy_hide_header : Removes headers in
Proxied HTTP Request
- $http_< header_in_snake_case > : Header value from a
HTTP Request
Responses
- add_header : Sets headers in
HTTP Response
- $upstream_http_< header_in_snake_case > : Header value from a
Proxied HTTP Response
A quick overview of the request/response flow
Given the following diagram, we defined 2 zones :
- The frontend zone : This is where NGINX receives requests from clients
- The proxied zone : This is where NGINX acts as a HTTP client towards the upstream app server
The mapping between NGINX directives and this diagram are the following :
- When a client performs a HTTP request, a specific
Location
is matched. proxy_pass
performs both sending and receiving data from the upstream server. It manages both arrows (Proxied HTTP Request
andProxied HTTP Response
)
Capturing headers returned by the proxied upstream server
NGINX performs some kind of dynamic variable definition based on the HTTP headers. This allows us to get headers from the upstream server (in Proxied HTTP Response
in the diagram) with the following : $upstream_http_< name_of_the_header_in_snake_case >
Example : Proxying a S3 bucket from a third party cloud provider
How to Intercepting redirects, following location while hiding the upstream URL
location / {
#: Disable buffering, so we are only hiding the upstream URL
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://upstream_app_server;
proxy_intercept_errors on;
error_page 302 = @proxy_redirects_302;
}
location @proxy_redirects_302 {
#: The following line performs exactly what we want : capturing the header
#: from the `Proxied HTTP Response`
set $saved_redirect_location '$upstream_http_location';
#: We need this line in order to resolve URLs provided by the upstream server
resolver 8.8.8.8;
#: We are connecting to a dynamic upstream location
proxy_pass $saved_redirect_location;
}
The updated diagram is then :
Adding back headers
Let's say you want to add headers, such as Content-Disposition
to trigger a download from the browser. Adding headers is done with the add_header
directive and influences the HTTP Response
:
location @proxy_redirects_302 {
#: The following line performs exactly what we want : capturing the header
#: from the `Proxied HTTP Response`
set $saved_redirect_location '$upstream_http_location';
#: Capture `Content-Disposition` header from upstream to add it back to the final response
set $saved_content_disposition '$upstream_http_content_disposition';
#: We need this line in order to resolve URLs provided by the upstream server
resolver 8.8.8.8;
#: We are connecting to a dynamic upstream location
proxy_pass $saved_redirect_location;
#: Adding header to `HTTP Response`
add_header Content-Disposition $saved_content_disposition;
}
Discover more content ?
Do you want to learn more and faster with dense and tailored technical resources ?