Hello, Observed nginx's version 1.22.1 questionable behaviour with two virtual hosts, one with H2 - enabled, second without http2 support. Both on the same IP and port, with different domain names/server names. When browsers make requests to a second domain, h2 being ALPN-negotiated, and data transferred via HTTP/2, in spite of http2 was not configured on that virtual host.
Sample config snippet: http { ... server { listen 1985 http2 ssl; server_name 'mavr.cp.eu'; ssl_certificate domain.cer; ssl_certificate_key domain.key; location / { return 302 https://zavr.cp.eu:1985$request_uri; } } server { listen 1985 ssl; # NO h2! server_name 'zavr.cp.eu'; ssl_certificate domain.cer; ssl_certificate_key domain.key; location / { # Doesn't really matter what's here, for simplicity I've used ngx_lua_module. echo "Server protocol: $server_protocol H2 connection: $http2 ."; } } ... } When I type https://mavr.cp.eu:1985 in browser I see: 1. Browser negotiates h2 ALPN with the server with SNI mavr.cp.eu ; 2. Server replied with 302 redirect to https://zavr.cp.eu:1985 (expected) 3. Browser makes NEW TCP-connection with the server with SNI zavr.cp.eu; (expected) 4. Server replied with h2 ALPN (unexpected) 5. Browser shows "Server protocol: HTTP/2.0 H2 connection: h2 ." When I browsed source code, I spotted following line: http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460 #if (NGX_HTTP_V2) <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l459> if (hc->addr_conf->http2) { <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l460> srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS; <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l461> srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1; <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l462> } else <http://hg.nginx.org/nginx/file/tip/src/http/modules/ngx_http_ssl_module.c#l463>#endif My assumption (could be wrong) that it means, when http2 is enabled on the address, related to (possibly) many virtual hosts, we always add h2 ALPN. Regardless of negotiated SNI. At least I see that ngx_http_find_virtual_server() being called here: http://hg.nginx.org/nginx/file/tip/src/http/ngx_http_request.c#l2236 on already established http(s) connection, not during TLS handshake. This behaviour caused some pain in my neck today, so could please someone be so kind to enlighten me, is it like it supposed to be, or is it possible to change this in the way, so http1 and http2 virtual hosts could be served on the same IP:port? Is it a bug, feature, my misconfiguration or just not needed by anyone? Quick Googling did not reveal that anyone had complained about it too much. If one will manage to implement a patch, correcting this behaviour, will it be even considered to review? -- Andrey P.S. Under "Browser" here I meant Chrome, Chromium, and Firefox on Windows. But, according to unconfirmed information, "some", yet unidentified, versions of browsers do NOT make a second TCP-connection to another domain after redirection in the provided example. And put a second request to the same h2 connection, despite the fact that it was negotiated for different SNI. Shame on them.
_______________________________________________ nginx mailing list nginx@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx