[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