Is it possible to set the Apache protocols directive conditionally 1-time rather than in all VirtualHost blocks

apache-2.4

Rather than adding protocols h2 http/1.1 in all 45 of my VirtualHost *:443 blocks, I was wondering if there is way to check for the appropriate condtion and then set protocols based on that? I think, but not 100% certain, that the appropriate test should be to see if the request was for https. Maybe I should test port instead, though?

This is what I've got so far and it isn't working.

Define PROTOCOLS "http/1.1"

<If "%{HTTPS} == 'on'">
    Define PROTOCOLS "h2 http/1.1"
</If>

Protocols ${PROTOCOLS}

Edit

Protocols does not work in a directory context.

Edit 2

I just don't think it's possible, given that the Protocols directive, if defined globally, cannot be dynamically modified like this. The server has already parsed the directive. It's set. Correct me if I'm wrong.

Best Answer

From the documentation:

Protocols Directive
Description: Protocols available for a server/virtual host
Syntax: Protocols protocol ...
Default: Protocols http/1.1
Context: server config, virtual host

Protocols is allowed in the server config, not only in the virtual host. Just set it once outside of a VirtualHost and it is set for the whole server. You can then omit it in the VirtualHost definition.

A very simple configuration would be:

# define defaults
Protocols h2 http/1.1

# single VirtualHost for all HTTP redirects
<VirtualHost *:80>
    Protocols http/1.1
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
    RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
</VirtualHost>

# Now all HTTPS VirtualHost definitions
<VirtualHost *:443>
    # ...
</VirtualHost>