I would like the Apache webserver to normally deliver content with the "http/2"-Protocol, but to fall back to "http/1.1" if the connection stems from a certain user-agent, which has faulty http/2-Support.
My current workaround is to disable http/2 for the considered virtualhost completely, but due to efficiency concerns this protocol should only be disabled for a certain user-agent and should otherwise be used as a default for all other user-agents.
According to my understanding of the Apache documentation, using Apache’s Protocols Directive inside Apache’s <If> Directive will not work, as only directives that support the directory context can be used within the <If> Directive and the Protocols Directive does not support the directory context.
2
Answers
You can’t do this. Whether to use HTTP/1.1 or HTTP/2 is decided as part of the TLS negotiation before the HTTP request (and hence the user agent) is sent.
The best you can do at that point is close the HTTP/2 connection with a
HTTP_1_1_REQUIRED
error code and hope the user agent will retry with an HTTP/1.1 request, but even then it will likely try with a new connection and upgrade again. Plus I’m not aware of any way to send this request via apache.If the goal is reliable clients, preferably using HTTP/2.0 if possible, but falling back to HTTP/1.1 otherwise, then there are a few things you can try.
The first is that there are a collection of Apache options for tweaking the HTTP/2.0 response, some of which break older browsers. I’d probably start by tinkering with these to see if you can find a combination that simply gets all the target browsers working.
The second is that you could try forcing a downgrade for your target agents. This isn’t supported by the standard, so may cause more problems than it solves though. In practice, you’d build a conditional to detect the agent, then use mod_headers to strip any existing upgrade/connection headers, and replace them with:
Third, you could have a pair of virtual hosts, one with both protocols enabled, and a second supporting only HTTP/1.1, then use a conditional to redirect agents as required.