Could it be done by only config?
And are there reverse_proxy response placeholders? Such as headers, status_code, body etc.
Hi, welcome to the issue tracker!
I am not entirely sure that I understand your post. Do you have 2 questions here?
Arguably, you'd say that those configurations should be the responsibility of the upstreams you are passing the request to, i.e. a proxy would only act as a middle-man in a request transaction.
If you want conditionals for different responses then caddy would not be the right answer for you since I'm sure @mholt is steering away from directives like if
Hmmm no I believe this should be possible with Caddy 2, without imperative syntax -- if it's not possible already, then we should implement it. I just need to know exactly what needs to be implemented. So first, we need some clarification from @hackwaly.
I need to use config to achieve:
I almost understand -- can you give an actual example of one such configuration you're trying to accomplish?
BTW: I already wrote a go program to get what i want.
Config may like this:
{
"apps": {
"proxy_app": {
"servers": {
"proxy_server": {
"routes": [
{
"handle": [
{
"handler": "reverse_proxy",
"upstreams": [
{
"dial": "{http.request.header.X-Host}"
}
],
"headers": {
"handler": "headers",
"response": {
"delete": ["Set-Cookie"],
"set": {
"X-Set-Cookie": ["{http.handlers.reverse_proxy.response.header.Set-Cookie}"],
"Access-Control-Allow-Origin": ["*"]
},
"set_status_code": "{http.handlers.reverse_proxy.response.status_code >= 400 ? 500 : 200}"
}
}
}
],
"terminal": true
}
]
}
}
}
}
}
@hackwaly Neat, is the source anywhere?
(Reopening until we implement it here)
Ping @hackwaly -- how did you implement that feature?
@mholt
clarify: I haven't implement that for caddy. I implement my need in plain go program -- not use caddy.
Chiming in here since I want to feature that is in the title even though the issue kind of derailed:
My use case is the following. I have a MinIO backend where I serve a static website from. In case it responds with 404 I have an error handler that rewrites the request to /404.html and reverse proxies again to the same minio backend. Tada 馃帀 404-page gets rendered.
The problem is that this will result in a 200 status code for the 404 page which is arguably not ideal. So overwrite the status code would be great.
@fahrradflucht So, in your use case, you don't actually want to _overwrite_ the status code, but you just want Caddy's error handler routes to be invoked on whatever error status is returned from the backend, right? Kind of like nginx's intercept_errors directive?
Maybe I don't fully understand you, but I think I actually want to overwrite the status code. Let me make an example.
Given a Caddyfile like this:
example.com {
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.html
}
reverse_proxy https://minio.example.com {
header_up Host {http.reverse_proxy.upstream.hostport}
}
}
The 404.html page will be returned for https://example.com/unknown. The problem is that it will be returned with a 200 status code which is not what you usually want. This is why I thought "Well, I need something to tell the reverse_proxy directive to overwrite the status code if the path is /404.html".
Does that make sense? Or am I approaching this totally wrong?
For the sake of correctness, I'm pretty sure the CEL expression should be the following:
expression {http.error.status_code} == 404
Status codes are ints
For the sake of correctness, I'm pretty sure the CEL expression should be the following:
expression {http.error.status_code} == 404Status codes are ints
Corrected, sorry. I typed this from memory because I don't have the file where I actually had a config like this at hand.
@fahrradflucht Is the backend originating the 404 error? I.e. does minio.example.com return a 404 to Caddy for a request to /unknown?
@fahrradflucht Is the backend originating the 404 error? I.e. does
minio.example.comreturn a 404 to Caddy for a request to/unknown?
Yes, exactly.
@fahrradflucht Okay, then you don't actually want to "overwrite" the status code, you want Caddy to handle the response from the backend as an error, rather than passing it through to the client.
This is possible with commit https://github.com/caddyserver/caddy/commit/7a99835dab64f7864186185761bbf5194216f8b6
@fahrradflucht Sorry for hijacking this issue but I am trying to use the exact same setup (Caddy reverse proxying to MinIO) and have everything working __but__ custom 404 pages.
I tried using the snippet you provided here:
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.html
}
but it's not having any effect. Did you ever get that setup working?
For the record, this is my complete config:
example.com {
handle_errors {
@404 {
expression {http.error.status_code} == 404
}
rewrite @404 /404.html
}
reverse_proxy minio:9000
@document {
expression {uri}.endsWith("/")
}
@noslash {
not expression {uri}.endsWith("/")
path_regexp ^[a-z\-/]*$
}
handle @noslash {
redir {uri}/
}
handle {
route @document {
rewrite {uri}index.html
}
rewrite * /static{uri}
}
log
}
@m90 it's not currently possible from the Caddyfile (but it is via JSON). Follow the progress on https://github.com/caddyserver/caddy/pull/3712, where Caddyfile support is being worked on.