I’m having trouble accessing request header info in a reverse_proxy response matcher. Is it possible to do so?
I’d like Caddy to rewrite the status code for OPTIONS requests when a reverse_proxy backend is down/misbehaving, replacing the 502 with 200 so the browser will continue on to make the actual doomed request, receiving the 502 in a manner javascript can see and handle properly rather than triggering the opaque CORS access-blocked behavior in the browser.
2. Error messages and/or full log output:
Well, I see expression cannot be used to match responses. I tried in v2.7.4 though anyway, hoping the feature was added since that post, but it has not:
2023/09/17 19:32:44.326 INFO using provided configuration {"config_file": "/etc/caddy/Caddyfile", "config_adapter": "caddyfile"}
Error: adapting config using caddyfile: parsing caddyfile tokens for 'handle': /etc/caddy/Caddyfile:24 - Error during parsing: parsing caddyfile tokens for 'reverse_proxy': /etc/caddy/Caddyfile:19 - Error during parsing: unrecognized response matcher expression, import chain: [''], import chain: ['']
3. Caddy version:
$ docker run --rm caddy:2.7.4 /usr/bin/caddy version
v2.7.4 h1:J8nisjdOxnYHXlorUKXY75Gr6iBfudfoGhrJ8t7/flI=
4. How I installed and ran Caddy:
a. System environment:
Docker, on Ubuntu 22.04.3, x86_64, Linux 6.2.0-32-generic
I agree this isn’t ideal, I’m still thinking through the best way to implement this kind of functionality in response matchers. For now, only status and header (for response headers) are supported since that’s all we really see in the response (other than the body… but that’s a stream so matching safely is harder and that’s out of scope for this question ).
The above looks like it would handle status code, but to feed the browser with an all-clear CORS response, Caddy would still need to access request data when intercepting the response, primarily for the Access-Control-Allow-Origin response header. (I forgot about the headers while asking, sorry–it’s not just status code.)
thinking through the best way to implement this kind of functionality in response matchers
Just speculating, but since the Caddy logger seems to carry some request headers through the response cycle, perhaps a copy_request_header directive could use a similar mechanism to carry that data along until the response begins? Eg:
Sounds great but now I can’t get a response intercept to work in any form, when the upstream backend is down/missing. Strange, I thought replace_status worked when I tried it but wonder now.
Ah right – you need to use handle_errors to deal with proxy errors emitted by reverse_proxy.
handle_response only deals with responses actually written by the upstream. If the error is produced by Caddy failing to connect, the there’s no 502 response coming from the upstream, the response is produced by Caddy and not proxied.
Ah, very nice. Browser behavior without this is normally just a minor inconvenience or red herring during local development, but for my current project it’s a bigger issue. Thank you for the help!
For the next person, here’s the working caddyfile: