Problem:
I have a backend server, with an Nginx reverse-proxy, and a file store in S3.
Current behaviour is:
- Request comes from client
- Through Nginx to backend
- Backend returns response with
X-Accel-Redirect
header, pointing to S3 - Nginx internally redirects (possibly incorrect terminology) to S3
- Client receives file response
This is achieved with the following config, and is working correctly:
upstream platform {
server localhost:8000;
}
server {
error_log /dev/stderr;
access_log /dev/stdout;
listen 80;
location ~ ^/document_store/(.*?)/(.*?)/(.*) {
internal;
resolver 8.8.8.8 ipv6=off;
set $download_protocol $1;
set $download_host $2;
set $download_path $3;
set $download_url $download_protocol://$download_host/$download_path;
proxy_hide_header Content-Disposition;
proxy_hide_header Access-Control-Allow-Origin;
add_header Content-Disposition $upstream_http_content_disposition;
add_header Access-Control-Allow-Origin *;
proxy_max_temp_file_size 0;
proxy_pass $download_url$is_args$args;
}
location / {
proxy_pass http://platform;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
I would now like the behaviour to be this:
- Request comes from client
- Through Nginx to backend
- Backend returns response with
X-Accel-Redirect
header, pointing to S3, and a customX-Foo
header. - Nginx internally redirects (possibly incorrect terminology) to S3
- Client receives file response, with
X-Foo
header from backend.
I have read several SO questions on this topic, and none of them seem to work.
I have tried referencing the $upstream_http_x_foo
variable, but it seems to be empty. My understanding is that this is because the upstream
has become S3, which does not provide this header. From a particular SO question (Nginx pass upstream headers to the remote request), I tried this:
upstream platform {
server localhost:8000;
}
proxy_pass_header X-Accel-Redirect;
server {
error_log /dev/stderr;
access_log /dev/stdout;
listen 80;
location ^~ /document_store/ {
internal;
set $custom_header_value $upstream_http_x_foo;
rewrite ^/(.+) /redirect_$1;
}
location ~ ^/redirect_document_store/(.*?)/(.*?)/(.*) {
resolver 8.8.8.8 ipv6=off;
set $download_protocol $1;
set $download_host $2;
set $download_path $3;
set $download_url $download_protocol://$download_host/$download_path;
proxy_hide_header Content-Disposition;
proxy_hide_header Access-Control-Allow-Origin;
add_header Content-Disposition $upstream_http_content_disposition;
add_header Access-Control-Allow-Origin *;
proxy_max_temp_file_size 0;
proxy_pass_header X-Foo;
add_header X-Foo $custom_header_value;
proxy_pass $download_url$is_args$args;
}
location / {
proxy_pass http://platform;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
With the idea being that the value of the header is stored while the upstream
is the backend, so that it can be later added when the upstream
becomes S3.
This did not work either. There is no obvious error, the response simply did not contain the header. I cannot find any alternative options on S3 or in the docs. I am not particularly knowledgeable on Nginx, so it is possible that the solution above is simply incorrectly implemented by me.
Edit: I also tried adding the add_header
directive below the proxy_pass
directive, but that did not help either.