How to modify "on the fly" 302 back-end location header?

Hi all,

We are using Caddy for several months as a proxy for our back-end servers without any issue: Great!

Today we would like to use in a better way the 301/302 responses coming from our back-end servers by merging their answer with our current path.

What is our standard configuration? More or less the following one:

hostname/platform { bind {$ADDRESS} proxy / <back-end server> { transparent without /platform header_downstream location /platform/mydir/index.html } rewrite /preprod/ / }

When a user connect to hostname/platform/, back-end server sends a 302 response with the location header /mydir/index.html. In the header_downstream directive, we would like to use the {>location} place-holder, but it remains blank so we have to hardcode mydir/index.html. Bad, really bad. :slight_smile:
From the documentation, only latency, size and status placeholders are available in responses. I have searched a solution for a hours but I was not able to do it in an “elegant” way.

By the way, do you know a way to use this header_downstream directive only with 301 or 302 responses? Kind of if {status}

Thanks!

Dams

Sounds interesting, I’m trying to get a grasp of your setup.

By this I understand you want to redirect them to {path}{$SOME_DIR}/index.html?

Do the clients send location headers to Caddy? From where would you pull a soft coded value for mydir/index.html, exactly?

To me the docs don’t read like those are the only placeholders available, I thought you could use request placeholders anywhere also. Are there other response placeholders you’d use?

What would a perfect solution look like for you?

I haven’t tried, but could you use something like:

rewrite {
    if {status} is 301
    if {status} is 302
    if_op or
    to /redirect
}
redir /redirect /some-destination

Yes, that’s correct. Precisely to hostname/platform/mydir/index.html.

Back-end server sends mydir/index.html in the location header. I just need to add the initial URL (more or less {path}) before the location value.
(Actually I cannot use {path} as I get / instead of platform (maybe rewritten due to one directive or the other such as without platform).)

A solution as simple as : header_download location {path}{>location} where path would be the request path value and {>location} the response location header value.
On a long term, an issue on Caddy side would be to make a difference between request and answer headers.

Thanks, I will try. Just a question: rewrite is about URL rewriting, not header value rewriting. In this case I would like to change only the location header. So, is rewrite fine?

I’ve used rewriting in the past to apply conditional logic to things that otherwise wouldn’t have conditionals available. Doesn’t have to have that redir on the end; you could set up another vhost for hostname/redirect and configure anything you need there. Although looking over your setup again I’m not sure how effective it would be, sorry.

I’d wager you’re correct re: without /platform. I’ve got a feeling that Caddy won’t be able to do the kind of header manipulation you require. I don’t think the placeholder and proxy structure was built with the concept of accessing and working with the headers from upstream specifically in mind, just downstream.

I don’t know how much control you have over the backend servers, but perhaps you could have Caddy forward the request in a custom header and have the backend manipulate the header itself before returning it to Caddy to pass on to the client.

Thanks Matthew for your different answers, we have now a clear status of what can be done or not.

We will check what solution will be more relevant on a long-term basis between providing a specific header to the back-end or push some new Caddy plug-in.

Bests,

Damien

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.