-
Notifications
You must be signed in to change notification settings - Fork 222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
reopen: more_set_input_headers/more_clear_input_headers cannot set header "Host" #129
Comments
With no context, this is probably because |
@sevmonster that doesn't seem to make any difference I think
However, I don't think that this is literally how it works. These two headers cannot be affected by
But nevertheless, this still does not allow I think the documentation for this module needs to be updated. Neither |
@cateiru In my experience, the best workaround is:
This avoids the pitfalls of both directives. |
The I am no expert in nginx internals or the execution order of its various components, so take that as you will and rely your own research. But last I more thoroughly investigated, it did work—the proxy headers, as set by the proxy module, were overridden by the headers_more module before sending the request to the proxy. |
I figured some code was worth more than words, so I set up a simple test. Running this Python server as the # http-echo-headers.py
from http.server import BaseHTTPRequestHandler, HTTPServer, HTTPStatus
class EchoHeadersHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(HTTPStatus.OK)
self.send_header("Content-Type", "text/plain; charset=UTF-8")
self.end_headers()
for key, value in self.headers.items():
self.wfile.write(f"{key}: {value}\n".encode("utf_8"))
if __name__ == "__main__":
server_address = ("", 8000)
httpd = HTTPServer(server_address, EchoHeadersHandler)
httpd.serve_forever() Using the following configuration as # conf/default.conf
server {
listen 8080 default_server;
server_name _;
location / {
return 404;
}
}
server {
listen 8080;
server_name more-set-host.example;
location / {
more_set_input_headers "Host: $host";
proxy_pass http://localhost:8000;
}
}
server {
listen 8080;
server_name proxy-set-host.example;
location / {
proxy_set_header Host $host;
proxy_pass http://localhost:8000;
}
}
server {
listen 8080;
server_name dummy-header.example;
location / {
proxy_set_header X-Dummy "";
more_set_input_headers "Host: $host";
proxy_pass http://localhost:8000;
}
}
server {
listen 8080;
server_name delete-host.example;
location / {
proxy_set_header Host "";
more_set_input_headers "Host: $host";
proxy_pass http://localhost:8000;
}
} With the openresty docker image running on the host: $ docker pull openresty/openresty
Using default tag: latest
latest: Pulling from openresty/openresty
1efc276f4ff9: Pull complete
403035b88bb5: Pull complete
4e8d5f0d1a02: Pull complete
aa6116de5cfa: Pull complete
Digest: sha256:168033f0b908546f874e1ccfcb196f39e7e0ab30562e20e35cf54252c3fa0698
Status: Downloaded newer image for openresty/openresty:latest
docker.io/openresty/openresty:latest
$ docker run docker.io/openresty/openresty:latest openresty -v
nginx version: openresty/1.21.4.1
$ docker run -it --network=host -v $PWD/conf:/etc/nginx/conf.d:ro docker.io/openresty/openresty:latest And with a shell script to run tests against each of the defined servers, using # run-curl-tests.sh
for http_host in \
more-set-host.example \
proxy-set-host.example \
dummy-header.example \
delete-host.example
do
echo REQUESTING $http_host
curl --resolve ${http_host}:8080:127.0.0.1 http://${http_host}:8080/
echo DONE
echo
done Finally, this all yields the following results: $ bash run-curl-tests.sh
REQUESTING more-set-host.example
Host: localhost:8000
Connection: close
User-Agent: curl/7.84.0
Accept: */*
DONE
REQUESTING proxy-set-host.example
Host: proxy-set-host.example
Connection: close
User-Agent: curl/7.84.0
Accept: */*
DONE
REQUESTING dummy-header.example
Host: localhost:8000
Connection: close
User-Agent: curl/7.84.0
Accept: */*
DONE
REQUESTING delete-host.example
Connection: close
User-Agent: curl/7.84.0
Accept: */*
DONE |
Yea, I am able to reproduce what @kbolino showed above. My entire purpose for using more_set_headers, is so I can inherit the ones set at the server level. server {
listen 8080;
server_name localhost;
proxy_set_header 'Inherit' 'Me';
location / {
proxy_pass http://localhost:8000;
}
location /api/1 {
more_set_headers "Host: override-api-1.host.com";
proxy_pass http://localhost:8000;
}
location /api/2 {
proxy_set_header Host override-api-2.host.com;
proxy_pass http://localhost:8000;
}
} My goal here is to inherit the server level headers and add my own host header within each location block.
|
Hi!
I am currently suffering from this issue.
It seems to be closed, but I think it has not been resolved.
Is there a solution or workaround?
The text was updated successfully, but these errors were encountered: