[PATCH 2 of 3] HTTP/2: "http2" directive

Sergey Kandaurov pluknet at nginx.com
Thu Feb 9 11:28:02 UTC 2023


> On 7 Feb 2023, at 18:50, Roman Arutyunyan <arut at nginx.com> wrote:
> 
> # HG changeset patch
> # User Roman Arutyunyan <arut at nginx.com>
> # Date 1675781276 -14400
> #      Tue Feb 07 18:47:56 2023 +0400
> # Branch quic
> # Node ID 735f9e501922e4b0a1b20730d62bac35ea398336
> # Parent  38eec3d9f2c0d2e6d041efe3ee6d9c1618d8f1e6
> HTTP/2: "http2" directive.
> 
> The directive enables HTTP/2 in the current server.  The previous way to
> enable HTTP/2 via "listen ... http2" is now deprecated.  The new approach
> allows to share HTTP/2 and HTTP/0.9-1.1 on the same port.
> 
> For SSL connections, HTTP/2 is now selected by ALPN callback based on whether
> the protocol is enabled in the virtual server chosen by SNI.  This however only
> works since OpenSSL 1.0.2h, where ALPN callback is invoked after SNI callback.
> For older versions of OpenSSL, HTTP/2 is enabled based on the default virtual
> server configuration.
> 
> For plain TCP connections, HTTP/2 is now auto-detected by HTTP/2 preface, if
> HTTP/2 is enabled in the default virtual server.  If preface is not matched,
> HTTP/0.9-1.1 is assumed.
> 
> diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
> --- a/src/http/modules/ngx_http_ssl_module.c
> +++ b/src/http/modules/ngx_http_ssl_module.c
> @@ -427,6 +427,9 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t 
> #if (NGX_HTTP_V2 || NGX_HTTP_V3)
>     ngx_http_connection_t   *hc;
> #endif
> +#if (NGX_HTTP_V2)
> +    ngx_http_v2_srv_conf_t  *h2scf;
> +#endif
> #if (NGX_HTTP_V3)
>     ngx_http_v3_srv_conf_t  *h3scf;
> #endif
> @@ -448,12 +451,9 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t 
>     hc = c->data;
> #endif
> 
> -#if (NGX_HTTP_V2)
> -    if (hc->addr_conf->http2) {
> -        srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS;
> -        srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1;
> -    } else
> -#endif
> +    srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
> +    srvlen = sizeof(NGX_HTTP_ALPN_PROTOS) - 1;
> +
> #if (NGX_HTTP_V3)
>     if (hc->addr_conf->quic) {
> 
> @@ -479,10 +479,16 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t 
> 
>     } else
> #endif
> +#if (NGX_HTTP_V2)
>     {
> -        srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
> -        srvlen = sizeof(NGX_HTTP_ALPN_PROTOS) - 1;
> +        h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);
> +
> +        if (h2scf->enable || hc->addr_conf->http2) {
> +            srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS;
> +            srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1;
> +        }
>     }
> +#endif

With NGX_HTTP_V3 defined but NGX_HTTP_V2 not,
the else part will go to the SSL_select_next_proto() call.
So, to fix this, NGX_HTTP_ALPN_PROTOS still has to be the last resort,
for simplicity (and also reduces diff).

My version:

diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -427,6 +427,9 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t 
 #if (NGX_HTTP_V2 || NGX_HTTP_V3)
     ngx_http_connection_t   *hc;
 #endif
+#if (NGX_HTTP_V2)
+    ngx_http_v2_srv_conf_t  *h2scf;
+#endif
 #if (NGX_HTTP_V3)
     ngx_http_v3_srv_conf_t  *h3scf;
 #endif
@@ -449,7 +452,9 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t 
 #endif
 
 #if (NGX_HTTP_V2)
-    if (hc->addr_conf->http2) {
+    h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);
+
+    if (h2scf->enable || hc->addr_conf->http2) {
         srv = (unsigned char *) NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS;
         srvlen = sizeof(NGX_HTTP_V2_ALPN_PROTO NGX_HTTP_ALPN_PROTOS) - 1;
     } else

> 
>     if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
>                               in, inlen)

[..]

-- 
Sergey Kandaurov


More information about the nginx-devel mailing list