1. The problem I’m having:
I have some default headers set in a header block.
At this time, if the header is overwritten when connecting with reverse_proxy
or php_fastcgi
, other headers may disappear.
I am not sure if this is a bug or specification, so I asked this question.
2. Error messages and/or full log output:
Curl result
curl -Li localhost:8080/test1
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Custom-Header1: 1
Custom-Header2: 2
Custom-Header3: 3
Server: Caddy
Date: Mon, 25 Nov 2024 11:06:15 GMT
Content-Length: 4
Hey!
→OK
curl -Li localhost:8081
HTTP/1.1 200 OK
Content-Length: 6
Content-Type: text/plain; charset=utf-8
Custom-Header1: 4
Date: Mon, 25 Nov 2024 11:07:00 GMT
Server: Caddy
Server: Caddy
Hello!
→Custom-Header2 and Custom-Header3 do not exist.
Caddy log
2024/11/25 11:06:10.806 INFO using config from file {"file": "./Caddyfile"}
2024/11/25 11:06:10.808 INFO adapted config to JSON {"adapter": "caddyfile"}
2024/11/25 11:06:10.824 INFO admin admin endpoint started {"address": "localhost:2019", "enforce_origin": false, "origins": ["//localhost:2019", "//[::1]:2019", "//127.0.0.1:2019"]}
2024/11/25 11:06:10.824 INFO http.auto_https automatic HTTPS is completely disabled for server {"server_name": "srv0"}
2024/11/25 11:06:10.824 INFO tls.cache.maintenance started background certificate maintenance {"cache": "0xc000532380"}
2024/11/25 11:06:10.824 INFO http.auto_https automatic HTTPS is completely disabled for server {"server_name": "srv1"}
2024/11/25 11:06:10.824 INFO http.auto_https automatic HTTPS is completely disabled for server {"server_name": "srv2"}
2024/11/25 11:06:10.825 DEBUG http.auto_https adjusted config {"tls": {"automation":{"policies":[{}]}}, "http": {"servers":{"srv0":{"listen":[":8080"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"require":{"headers":{"Custom-Header1":null,"Custom-Header2":null,"Custom-Header3":null}},"set":{"Custom-Header1":["1"],"Custom-Header2":["2"],"Custom-Header3":["3"]}}},{"body":"Hey!","handler":"static_response"}]}]}],"terminal":true}],"automatic_https":{"disable":true,"skip":["localhost"]}},"srv1":{"listen":[":8081"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"require":{"headers":{"Custom-Header1":null,"Custom-Header2":null,"Custom-Header3":null}},"set":{"Custom-Header1":["1"],"Custom-Header2":["2"],"Custom-Header3":["3"]}}},{"handler":"reverse_proxy","upstreams":[{"dial":"localhost:9000"}]}]}]}],"terminal":true}],"automatic_https":{"disable":true,"skip":["localhost"]}},"srv2":{"listen":[":9000"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"headers","response":{"set":{"Custom-Header1":["4"]}}},{"body":"Hello!","handler":"static_response"}]}]}],"terminal":true}],"automatic_https":{"disable":true,"skip":["localhost"]}}}}}
2024/11/25 11:06:10.826 DEBUG http starting server loop {"address": "[::]:8080", "tls": false, "http3": false}
2024/11/25 11:06:10.826 INFO http.log server running {"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2024/11/25 11:06:10.828 DEBUG http starting server loop {"address": "[::]:8081", "tls": false, "http3": false}
2024/11/25 11:06:10.828 INFO http.log server running {"name": "srv1", "protocols": ["h1", "h2", "h3"]}
2024/11/25 11:06:10.828 DEBUG http starting server loop {"address": "[::]:9000", "tls": false, "http3": false}
2024/11/25 11:06:10.829 INFO http.log server running {"name": "srv2", "protocols": ["h1", "h2", "h3"]}
2024/11/25 11:06:10.831 INFO autosaved config (load with --resume flag) {"file": "C:\\Users\\riku\\.config\\caddy\\autosave.json"}
2024/11/25 11:06:10.831 INFO serving initial configuration
2024/11/25 11:06:10.835 INFO tls storage cleaning happened too recently; skipping for now {"storage": "FileStorage:C:\\Users\\riku\\AppData\\Roaming\\Caddy", "instance": "0b5f1bdc-2683-472c-ad1d-b34106f76c5c", "try_again": "2024/11/26 11:06:10.835", "try_again_in": 86400}
2024/11/25 11:06:10.836 INFO tls finished cleaning storage units
2024/11/25 11:07:00.129 DEBUG http.handlers.reverse_proxy selected upstream {"dial": "localhost:9000", "total_upstreams": 1}
2024/11/25 11:07:00.143 DEBUG http.handlers.reverse_proxy upstream roundtrip {"upstream": "localhost:9000", "duration": 0.0136276, "request": {"remote_ip": "::1", "remote_port": "3836", "client_ip": "::1", "proto": "HTTP/1.1", "method": "GET", "host": "localhost:8081", "uri": "/", "headers": {"Accept": ["*/*"], "X-Forwarded-For": ["::1"], "X-Forwarded-Proto": ["http"], "X-Forwarded-Host": ["localhost:8081"], "User-Agent": ["curl/8.11.0"]}}, "headers": {"Content-Type": ["text/plain; charset=utf-8"], "Custom-Header1": ["4"], "Server": ["Caddy"], "Date": ["Mon, 25 Nov 2024 11:07:00 GMT"], "Content-Length": ["6"]}, "status": 200}
3. Caddy version:
v2.8.4 h1:q3pe0wpBj1OcHFZ3n/1nl4V4bxBrYoSoab7rL9BMYNk=
4. How I installed and ran Caddy:
scoop install caddy
a. System environment:
Windows11 24H2 64bit
b. Command:
cd E:\caddyfile_test
caddy run --config ./Caddyfile
d. My complete Caddy config:
{
auto_https off
debug
}
(default_headers) {
header {
?Custom-Header1 "1"
?Custom-Header2 "2"
?Custom-Header3 "3"
}
}
http://localhost:8080 {
import default_headers
respond "Hey!"
}
http://localhost:8081 {
import default_headers
reverse_proxy localhost:9000
}
http://localhost:9000 {
header Custom-Header1 "4"
respond "Hello!"
}
P.S
I noticed this while testing in another environment at hand (Ubuntu 24.04.1, installed from the official apt repository and running with Systemd).
The actual environment uses php_fastcgi, but for simplicity this time I created a test Caddyfile with reverse_proxy.
I have also confirmed that setting default_headers
as follows solves the problem.
(default_headers) {
header ?Custom-Header1 "1"
header ?Custom-Header2 "2"
header ?Custom-Header3 "3"
}