Score:2

How to change HTTP-status based on origin's header?

cn flag

I'm dealing with a proprietary HTTP-server, which always responds with code 200 -- even when an error occurred. The indication of an error, if any, can only be found in the custom header, for example: MyApp-Status: SECURITY_EXCEPTION (in successful requests that header contains OK).

I'm putting Apache-based proxy in front of it and would like to fix this nonsense.

How would I change the very status of the response from the origin-specified (bogus) 200 to a more appropriate value depending on the origin's header MyApp-Status?

I know, mod_headers modifies the headers of the response -- can it modify the status as well?

And mod_rewrite can set the status -- but can it be applied to the response?

ws flag
Why apache? I presume you mean httpd rather than, say Apache Traffic Server. Apache httpd is great as an origin server but IMHO there are better choices as a proxy (notably haproxy and nginx.....and particularly nginx for your use-case)
cn flag
Yes, httpd. Because we already have it running on this machine and adding the proxy functionality is just a matter of adding one more VHost to an existing configuration -- no new server to watch, no new logs to rotate, and so on.
Score:1
in flag

mod_headers does "late" processing, just before the complete response gets sent back to the client. In reverse proxy scenario should allow it make changes and set headers based on the headers the back-end server sent.

Example scenario #4 from the examples in the manual https://httpd.apache.org/docs/2.4/mod/mod_headers.html would seem appropriate for your use case.

In theory something like this should work:

<LocationMatch "/myapp">
    ProxyPass http://hostname:8080/myapp 
    ProxyPassReverse http://hostname:8080/myapp
    SetEnvIf MyApp-Status SECURITY_EXCEPTION HAVE_MyRequestHeader
    Header set Status "403" env=HAVE_MyRequestHeader
</LocationMatch>

But please test and report back.

kz flag
`Header set Status` - But doesn't this just set another (custom) HTTP response header (called `Status`) - it doesn't actually change the HTTP status of the response? Also, is this being applied to the request from the client or the response from the origin?
cn flag
`mod_headers` does apply to _outgoing_ (response) headers, @HBruijn is correct. As for the HTTP-status being treated as "just another header", I have the same doubts, but will test anyway...
cn flag
First of all, the `SetEnvIf` is not needed -- the syntax can be simply `Header set Status "403" "expr=resp('MyApp-Status') == 'SECURITY_EXCEPTION'"`. I tested it, and it works. Unfortunately, as @MrWhite and I both suspected, it does not achieve the goal -- a new header named `Status` is added to the response, but the first line of it still reads `HTTP/1.1 200`...
kz flag
@MikhailT. "mod_headers does apply to outgoing (response) headers" - I was really referring to the `SetEnvIf` line that sets the env var based on the "request" header. The `Status` header can be used by some CGI-scripts to indicate to the webserver the intended status of the response (but that would not seem to apply here). Have you tried mod_rewrite?
cn flag
I do have mod_rewrite -- and it does seem like the only module, that can set HTTP-status -- but I don't know, how to make it apply to the origin's response on its way out from the proxy to the requester. All the documentation/examples of mod_rewrite pertain to it looking at the _request_...
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.