1. The problem I’m having:
Hello Caddy community, I’m attempting to offload some proxy work to Caddy from a backend service. The backend replies with some headers that include the hostname and path that are then passed to a reverse_proxy
wrapped in a handle_response
block.
Ideally I would like to handle an initial request, i.e some hostname (doesn’t matter), which is then reverse proxied to the backend in order to perform the lookup (the backend needs the host header to perform the lookup). A response handler should then dissect the backend headers and proxy them to the correct backend with the appropriate path.
The main goal is to offload the proxy traffic that the backend app would normally handle, and instead have Caddy perform the actual proxying based on the values it receives.
Request (some hostname) → Caddy → Reverse proxy to backend → Handle response based on returned headers → Reverse proxy to destination service.
The backend will respond with 2 headers (backend code below) Location
and Path
, which are then supposed to be routed to another proxy in the handle_response
block:
'Location' : 'cloudflare-ipfs.com',
'Path': '/ipfs/QmQhCuJqSk9fF58wU58oiaJ1qbZwQ1eQ8mVzNWe7tgLNiD/'
However, in my testing it was revealed that Caddy is indeed proxying to the correct backend as specified by {rp.header.Location}
but it is not honoring/including the {rp.header.Path}
URI to pass to the reverse_proxy
.
2. Error messages and/or full log output:
{"level":"error","ts":1681336024.8235428,"logger":"http.log.access.log0","msg":"handled request","request":{"remote_ip":"127.0.0.1","remote_port":"41402","proto":"HTTP/2.0","method":"GET","host":"localhost:8443","uri":"/","headers":{"User-Agent":["curl/7.85.0"],"Accept":["*/*"]},"tls":{"resumed":false,"version":772,"cipher_suite":4865,"proto":"h2","server_name":"localhost"}},"user_id":"","duration":0.600057451,"size":151,"status":403,"resp_headers":{"Cf-Ray":["7b6eaa6e4ec5acf2-ATL"],"Date":["Wed, 12 Apr 2023 21:47:05 GMT"],"Content-Type":["text/html"],"Server":["Caddy","cloudflare"],"Alt-Svc":["h3=\":8443\"; ma=2592000"],"Content-Length":["151"]}}
Based on the log output, Caddy is not proxying to the path specified in {rp.header.Path}
. and instead is defaulting to /
.
3. Caddy version:
v2.6.4 h1:2hwYqiRwk1tf3VruhMpLcYTg+11fCdr8S3jhNAdnPy8=
4. How I installed and ran Caddy:
Downloaded from Caddy site.
a. System environment:
Standalone binary on Fedora 37 for local testing.
b. Command:
caddy run
c. Service/unit/compose file:
n/a
d. My complete Caddy config:
{
auto_https disable_redirects
}
https://:8443 {
bind 0.0.0.0
tls internal {
on_demand
}
log {
level DEBUG
format json
}
route * {
reverse_proxy http://localhost:3000 {
@proxy_redirect status 301
handle_response @proxy_redirect {
rewrite * /{rp.header.Path}
reverse_proxy {rp.header.Location}:443 {
transport http {
tls
dial_timeout 2s
}
}
}
}
}
}
I have also tried the following handle_response
block:
handle_response @proxy_redirect {
@target_path path /{rp.header.Path}
reverse_proxy @target_path {rp.header.Location}:443 {
transport http {
tls
dial_timeout 2s
}
}
}
5. Links to relevant resources:
Backend service responsible for returning the Path
and Location
headers to Caddy:
const http = require('http');
const server = http.createServer((req, res, next) => {
res.writeHead(301, {
'Location' : 'cloudflare-ipfs.com',
'Path': '/ipfs/QmQhCuJqSk9fF58wU58oiaJ1qbZwQ1eQ8mVzNWe7tgLNiD/'
}
);
res.end();
});
server.listen(3000);