HTTP/3: "quic" parameter of "listen" directive.
Now "listen" directve has a new "quic" parameter which enables QUIC protocol for the address. Further, to enable HTTP/3, a new directive "http3" is introduced. The hq-interop protocol is enabled by "http3_hq" as before. Now application protocol is chosen by ALPN. Previously used "http3" parameter of "listen" is deprecated.
This commit is contained in:
parent
fe0c3d7310
commit
eea23ac250
11 changed files with 134 additions and 90 deletions
18
README
18
README
|
@ -102,13 +102,13 @@ Experimental QUIC support for nginx
|
||||||
|
|
||||||
3. Configuration
|
3. Configuration
|
||||||
|
|
||||||
The HTTP "listen" directive got a new option "http3" which enables
|
The HTTP "listen" directive got a new option "quic" which enables
|
||||||
HTTP/3 over QUIC on the specified port.
|
QUIC as client transport protocol instead of TCP.
|
||||||
|
|
||||||
The Stream "listen" directive got a new option "quic" which enables
|
The Stream "listen" directive got a new option "quic" which enables
|
||||||
QUIC as client transport protocol instead of TCP or plain UDP.
|
QUIC as client transport protocol instead of TCP or plain UDP.
|
||||||
|
|
||||||
Along with "http3" or "quic", it's also possible to specify "reuseport"
|
Along with "quic", it's also possible to specify "reuseport"
|
||||||
option [8] to make it work properly with multiple workers.
|
option [8] to make it work properly with multiple workers.
|
||||||
|
|
||||||
To enable address validation:
|
To enable address validation:
|
||||||
|
@ -142,12 +142,13 @@ Experimental QUIC support for nginx
|
||||||
|
|
||||||
A number of directives were added that configure HTTP/3:
|
A number of directives were added that configure HTTP/3:
|
||||||
|
|
||||||
|
http3
|
||||||
|
http3_hq
|
||||||
http3_stream_buffer_size
|
http3_stream_buffer_size
|
||||||
http3_max_concurrent_pushes
|
http3_max_concurrent_pushes
|
||||||
http3_max_concurrent_streams
|
http3_max_concurrent_streams
|
||||||
http3_push
|
http3_push
|
||||||
http3_push_preload
|
http3_push_preload
|
||||||
http3_hq (requires NGX_HTTP_V3_HQ macro)
|
|
||||||
|
|
||||||
In http, an additional variable is available: $http3.
|
In http, an additional variable is available: $http3.
|
||||||
The value of $http3 is "h3" for HTTP/3 connections,
|
The value of $http3 is "h3" for HTTP/3 connections,
|
||||||
|
@ -169,7 +170,7 @@ Example configuration:
|
||||||
server {
|
server {
|
||||||
# for better compatibility it's recommended
|
# for better compatibility it's recommended
|
||||||
# to use the same port for quic and https
|
# to use the same port for quic and https
|
||||||
listen 8443 http3 reuseport;
|
listen 8443 quic reuseport;
|
||||||
listen 8443 ssl;
|
listen 8443 ssl;
|
||||||
|
|
||||||
ssl_certificate certs/example.com.crt;
|
ssl_certificate certs/example.com.crt;
|
||||||
|
@ -299,6 +300,13 @@ Example configuration:
|
||||||
response header fields into push requests.
|
response header fields into push requests.
|
||||||
|
|
||||||
|
|
||||||
|
Syntax: http3 on | off;
|
||||||
|
Default: http3 on;
|
||||||
|
Context: http, server
|
||||||
|
|
||||||
|
Enables HTTP/3 protocol negotiation.
|
||||||
|
|
||||||
|
|
||||||
Syntax: http3_hq on | off;
|
Syntax: http3_hq on | off;
|
||||||
Default: http3_hq off;
|
Default: http3_hq off;
|
||||||
Context: http, server
|
Context: http, server
|
||||||
|
|
|
@ -431,7 +431,7 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
||||||
#if (NGX_HTTP_V2 || NGX_HTTP_V3)
|
#if (NGX_HTTP_V2 || NGX_HTTP_V3)
|
||||||
ngx_http_connection_t *hc;
|
ngx_http_connection_t *hc;
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3 && NGX_HTTP_V3_HQ)
|
#if (NGX_HTTP_V3)
|
||||||
ngx_http_v3_srv_conf_t *h3scf;
|
ngx_http_v3_srv_conf_t *h3scf;
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V2 || NGX_HTTP_V3 || NGX_DEBUG)
|
#if (NGX_HTTP_V2 || NGX_HTTP_V3 || NGX_DEBUG)
|
||||||
|
@ -459,19 +459,26 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
if (hc->addr_conf->http3) {
|
if (hc->addr_conf->quic) {
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
h3scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
|
h3scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
|
||||||
|
|
||||||
if (h3scf->hq) {
|
if (h3scf->enable && h3scf->enable_hq) {
|
||||||
|
srv = (unsigned char *) NGX_HTTP_V3_ALPN_PROTO
|
||||||
|
NGX_HTTP_V3_HQ_ALPN_PROTO;
|
||||||
|
srvlen = sizeof(NGX_HTTP_V3_ALPN_PROTO NGX_HTTP_V3_HQ_ALPN_PROTO)
|
||||||
|
- 1;
|
||||||
|
|
||||||
|
} else if (h3scf->enable_hq) {
|
||||||
srv = (unsigned char *) NGX_HTTP_V3_HQ_ALPN_PROTO;
|
srv = (unsigned char *) NGX_HTTP_V3_HQ_ALPN_PROTO;
|
||||||
srvlen = sizeof(NGX_HTTP_V3_HQ_ALPN_PROTO) - 1;
|
srvlen = sizeof(NGX_HTTP_V3_HQ_ALPN_PROTO) - 1;
|
||||||
} else
|
|
||||||
#endif
|
} else if (h3scf->enable || hc->addr_conf->http3) {
|
||||||
{
|
|
||||||
srv = (unsigned char *) NGX_HTTP_V3_ALPN_PROTO;
|
srv = (unsigned char *) NGX_HTTP_V3_ALPN_PROTO;
|
||||||
srvlen = sizeof(NGX_HTTP_V3_ALPN_PROTO) - 1;
|
srvlen = sizeof(NGX_HTTP_V3_ALPN_PROTO) - 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
@ -1317,15 +1324,15 @@ ngx_http_ssl_init(ngx_conf_t *cf)
|
||||||
addr = port[p].addrs.elts;
|
addr = port[p].addrs.elts;
|
||||||
for (a = 0; a < port[p].addrs.nelts; a++) {
|
for (a = 0; a < port[p].addrs.nelts; a++) {
|
||||||
|
|
||||||
if (!addr[a].opt.ssl && !addr[a].opt.http3) {
|
if (!addr[a].opt.ssl && !addr[a].opt.quic) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cscf = addr[a].default_server;
|
cscf = addr[a].default_server;
|
||||||
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
|
sscf = cscf->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
|
||||||
|
|
||||||
if (addr[a].opt.http3) {
|
if (addr[a].opt.quic) {
|
||||||
name = "http3";
|
name = "quic";
|
||||||
|
|
||||||
#if (NGX_QUIC_OPENSSL_COMPAT)
|
#if (NGX_QUIC_OPENSSL_COMPAT)
|
||||||
if (ngx_quic_compat_init(cf, sscf->ssl.ctx) != NGX_OK) {
|
if (ngx_quic_compat_init(cf, sscf->ssl.ctx) != NGX_OK) {
|
||||||
|
@ -1339,7 +1346,7 @@ ngx_http_ssl_init(ngx_conf_t *cf)
|
||||||
|
|
||||||
if (sscf->certificates) {
|
if (sscf->certificates) {
|
||||||
|
|
||||||
if (addr[a].opt.http3 && !(sscf->protocols & NGX_SSL_TLSv1_3)) {
|
if (addr[a].opt.quic && !(sscf->protocols & NGX_SSL_TLSv1_3)) {
|
||||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||||
"\"ssl_protocols\" must enable TLSv1.3 for "
|
"\"ssl_protocols\" must enable TLSv1.3 for "
|
||||||
"the \"listen ... %s\" directive in %s:%ui",
|
"the \"listen ... %s\" directive in %s:%ui",
|
||||||
|
|
|
@ -1242,6 +1242,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
ngx_uint_t http3;
|
ngx_uint_t http3;
|
||||||
|
ngx_uint_t quic;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1280,6 +1281,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
http3 = lsopt->http3 || addr[i].opt.http3;
|
http3 = lsopt->http3 || addr[i].opt.http3;
|
||||||
|
quic = lsopt->quic || addr[i].opt.quic;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (lsopt->set) {
|
if (lsopt->set) {
|
||||||
|
@ -1319,6 +1321,7 @@ ngx_http_add_addresses(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
addr[i].opt.http3 = http3;
|
addr[i].opt.http3 = http3;
|
||||||
|
addr[i].opt.quic = quic;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
@ -1823,7 +1826,7 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
|
||||||
|
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
|
|
||||||
ls->quic = addr->opt.http3;
|
ls->quic = addr->opt.quic;
|
||||||
|
|
||||||
if (ls->quic) {
|
if (ls->quic) {
|
||||||
ngx_rbtree_init(&ls->rbtree, &ls->sentinel,
|
ngx_rbtree_init(&ls->rbtree, &ls->sentinel,
|
||||||
|
@ -1866,6 +1869,7 @@ ngx_http_add_addrs(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
addrs[i].conf.http3 = addr[i].opt.http3;
|
addrs[i].conf.http3 = addr[i].opt.http3;
|
||||||
|
addrs[i].conf.quic = addr[i].opt.quic;
|
||||||
#endif
|
#endif
|
||||||
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
addrs[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||||
|
|
||||||
|
@ -1934,6 +1938,7 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_http_port_t *hport,
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
addrs6[i].conf.http3 = addr[i].opt.http3;
|
addrs6[i].conf.http3 = addr[i].opt.http3;
|
||||||
|
addrs6[i].conf.quic = addr[i].opt.quic;
|
||||||
#endif
|
#endif
|
||||||
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
addrs6[i].conf.proxy_protocol = addr[i].opt.proxy_protocol;
|
||||||
|
|
||||||
|
|
|
@ -4191,6 +4191,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
|
|
||||||
if (ngx_strcmp(value[n].data, "http3") == 0) {
|
if (ngx_strcmp(value[n].data, "http3") == 0) {
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"the \"http3\" parameter is deprecated, "
|
||||||
|
"use \"quic\" parameter instead");
|
||||||
|
lsopt.quic = 1;
|
||||||
lsopt.http3 = 1;
|
lsopt.http3 = 1;
|
||||||
lsopt.type = SOCK_DGRAM;
|
lsopt.type = SOCK_DGRAM;
|
||||||
continue;
|
continue;
|
||||||
|
@ -4202,6 +4206,19 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_strcmp(value[n].data, "quic") == 0) {
|
||||||
|
#if (NGX_HTTP_V3)
|
||||||
|
lsopt.quic = 1;
|
||||||
|
lsopt.type = SOCK_DGRAM;
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"the \"quic\" parameter requires "
|
||||||
|
"ngx_http_v3_module");
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
|
if (ngx_strncmp(value[n].data, "so_keepalive=", 13) == 0) {
|
||||||
|
|
||||||
if (ngx_strcmp(&value[n].data[13], "on") == 0) {
|
if (ngx_strcmp(&value[n].data[13], "on") == 0) {
|
||||||
|
@ -4304,8 +4321,8 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (NGX_HTTP_SSL && NGX_HTTP_V3)
|
#if (NGX_HTTP_SSL && NGX_HTTP_V3)
|
||||||
if (lsopt.ssl && lsopt.http3) {
|
if (lsopt.ssl && lsopt.quic) {
|
||||||
return "\"ssl\" parameter is incompatible with \"http3\"";
|
return "\"ssl\" parameter is incompatible with \"quic\"";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ typedef struct {
|
||||||
unsigned ssl:1;
|
unsigned ssl:1;
|
||||||
unsigned http2:1;
|
unsigned http2:1;
|
||||||
unsigned http3:1;
|
unsigned http3:1;
|
||||||
|
unsigned quic:1;
|
||||||
#if (NGX_HAVE_INET6)
|
#if (NGX_HAVE_INET6)
|
||||||
unsigned ipv6only:1;
|
unsigned ipv6only:1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -240,6 +241,7 @@ struct ngx_http_addr_conf_s {
|
||||||
unsigned ssl:1;
|
unsigned ssl:1;
|
||||||
unsigned http2:1;
|
unsigned http2:1;
|
||||||
unsigned http3:1;
|
unsigned http3:1;
|
||||||
|
unsigned quic:1;
|
||||||
unsigned proxy_protocol:1;
|
unsigned proxy_protocol:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@ ngx_http_init_connection(ngx_connection_t *c)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
if (hc->addr_conf->http3) {
|
if (hc->addr_conf->quic) {
|
||||||
ngx_http_v3_init_stream(c);
|
ngx_http_v3_init_stream(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,9 @@ static void ngx_http_v3_cleanup_session(void *data);
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_http_v3_init_session(ngx_connection_t *c)
|
ngx_http_v3_init_session(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
ngx_pool_cleanup_t *cln;
|
ngx_pool_cleanup_t *cln;
|
||||||
ngx_http_connection_t *hc;
|
ngx_http_connection_t *hc;
|
||||||
ngx_http_v3_session_t *h3c;
|
ngx_http_v3_session_t *h3c;
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
ngx_http_v3_srv_conf_t *h3scf;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hc = c->data;
|
hc = c->data;
|
||||||
|
|
||||||
|
@ -36,13 +33,6 @@ ngx_http_v3_init_session(ngx_connection_t *c)
|
||||||
h3c->max_push_id = (uint64_t) -1;
|
h3c->max_push_id = (uint64_t) -1;
|
||||||
h3c->goaway_push_id = (uint64_t) -1;
|
h3c->goaway_push_id = (uint64_t) -1;
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
h3scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v3_module);
|
|
||||||
if (h3scf->hq) {
|
|
||||||
h3c->hq = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_queue_init(&h3c->blocked);
|
ngx_queue_init(&h3c->blocked);
|
||||||
ngx_queue_init(&h3c->pushing);
|
ngx_queue_init(&h3c->pushing);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#define NGX_HTTP_V3_ALPN_PROTO "\x02h3"
|
#define NGX_HTTP_V3_ALPN_PROTO "\x02h3"
|
||||||
#define NGX_HTTP_V3_HQ_ALPN_PROTO "\x0Ahq-interop"
|
#define NGX_HTTP_V3_HQ_ALPN_PROTO "\x0Ahq-interop"
|
||||||
|
#define NGX_HTTP_V3_HQ_PROTO "hq-interop"
|
||||||
|
|
||||||
#define NGX_HTTP_V3_VARLEN_INT_LEN 4
|
#define NGX_HTTP_V3_VARLEN_INT_LEN 4
|
||||||
#define NGX_HTTP_V3_PREFIX_INT_LEN 11
|
#define NGX_HTTP_V3_PREFIX_INT_LEN 11
|
||||||
|
@ -101,13 +102,12 @@
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_flag_t enable;
|
||||||
|
ngx_flag_t enable_hq;
|
||||||
size_t max_table_capacity;
|
size_t max_table_capacity;
|
||||||
ngx_uint_t max_blocked_streams;
|
ngx_uint_t max_blocked_streams;
|
||||||
ngx_uint_t max_concurrent_pushes;
|
ngx_uint_t max_concurrent_pushes;
|
||||||
ngx_uint_t max_concurrent_streams;
|
ngx_uint_t max_concurrent_streams;
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
ngx_flag_t hq;
|
|
||||||
#endif
|
|
||||||
ngx_quic_conf_t quic;
|
ngx_quic_conf_t quic;
|
||||||
} ngx_http_v3_srv_conf_t;
|
} ngx_http_v3_srv_conf_t;
|
||||||
|
|
||||||
|
@ -147,9 +147,7 @@ struct ngx_http_v3_session_s {
|
||||||
off_t payload_bytes;
|
off_t payload_bytes;
|
||||||
|
|
||||||
unsigned goaway:1;
|
unsigned goaway:1;
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
unsigned hq:1;
|
unsigned hq:1;
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_connection_t *known_streams[NGX_HTTP_V3_MAX_KNOWN_STREAM];
|
ngx_connection_t *known_streams[NGX_HTTP_V3_MAX_KNOWN_STREAM];
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,20 @@ static ngx_conf_post_t ngx_http_quic_mtu_post =
|
||||||
|
|
||||||
static ngx_command_t ngx_http_v3_commands[] = {
|
static ngx_command_t ngx_http_v3_commands[] = {
|
||||||
|
|
||||||
|
{ ngx_string("http3"),
|
||||||
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
ngx_conf_set_flag_slot,
|
||||||
|
NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
offsetof(ngx_http_v3_srv_conf_t, enable),
|
||||||
|
NULL },
|
||||||
|
|
||||||
|
{ ngx_string("http3_hq"),
|
||||||
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
ngx_conf_set_flag_slot,
|
||||||
|
NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
offsetof(ngx_http_v3_srv_conf_t, enable_hq),
|
||||||
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("http3_max_concurrent_pushes"),
|
{ ngx_string("http3_max_concurrent_pushes"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_num_slot,
|
ngx_conf_set_num_slot,
|
||||||
|
@ -46,15 +60,6 @@ static ngx_command_t ngx_http_v3_commands[] = {
|
||||||
offsetof(ngx_http_v3_srv_conf_t, max_concurrent_streams),
|
offsetof(ngx_http_v3_srv_conf_t, max_concurrent_streams),
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
{ ngx_string("http3_hq"),
|
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
|
||||||
ngx_conf_set_flag_slot,
|
|
||||||
NGX_HTTP_SRV_CONF_OFFSET,
|
|
||||||
offsetof(ngx_http_v3_srv_conf_t, hq),
|
|
||||||
NULL },
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{ ngx_string("http3_push"),
|
{ ngx_string("http3_push"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_http_v3_push,
|
ngx_http_v3_push,
|
||||||
|
@ -160,14 +165,12 @@ static ngx_int_t
|
||||||
ngx_http_v3_variable(ngx_http_request_t *r,
|
ngx_http_v3_variable(ngx_http_request_t *r,
|
||||||
ngx_http_variable_value_t *v, uintptr_t data)
|
ngx_http_variable_value_t *v, uintptr_t data)
|
||||||
{
|
{
|
||||||
|
ngx_http_v3_session_t *h3c;
|
||||||
|
|
||||||
if (r->connection->quic) {
|
if (r->connection->quic) {
|
||||||
#if (NGX_HTTP_V3_HQ)
|
h3c = ngx_http_v3_get_session(r->connection);
|
||||||
|
|
||||||
ngx_http_v3_srv_conf_t *h3scf;
|
if (h3c->hq) {
|
||||||
|
|
||||||
h3scf = ngx_http_get_module_srv_conf(r, ngx_http_v3_module);
|
|
||||||
|
|
||||||
if (h3scf->hq) {
|
|
||||||
v->len = sizeof("hq") - 1;
|
v->len = sizeof("hq") - 1;
|
||||||
v->valid = 1;
|
v->valid = 1;
|
||||||
v->no_cacheable = 0;
|
v->no_cacheable = 0;
|
||||||
|
@ -177,8 +180,6 @@ ngx_http_v3_variable(ngx_http_request_t *r,
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
v->len = sizeof("h3") - 1;
|
v->len = sizeof("h3") - 1;
|
||||||
v->valid = 1;
|
v->valid = 1;
|
||||||
v->no_cacheable = 0;
|
v->no_cacheable = 0;
|
||||||
|
@ -232,12 +233,12 @@ ngx_http_v3_create_srv_conf(ngx_conf_t *cf)
|
||||||
* h3scf->quic.timeout = 0;
|
* h3scf->quic.timeout = 0;
|
||||||
* h3scf->max_blocked_streams = 0;
|
* h3scf->max_blocked_streams = 0;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
h3scf->enable = NGX_CONF_UNSET;
|
||||||
|
h3scf->enable_hq = NGX_CONF_UNSET;
|
||||||
h3scf->max_table_capacity = NGX_HTTP_V3_MAX_TABLE_CAPACITY;
|
h3scf->max_table_capacity = NGX_HTTP_V3_MAX_TABLE_CAPACITY;
|
||||||
h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT;
|
h3scf->max_concurrent_pushes = NGX_CONF_UNSET_UINT;
|
||||||
h3scf->max_concurrent_streams = NGX_CONF_UNSET_UINT;
|
h3scf->max_concurrent_streams = NGX_CONF_UNSET_UINT;
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
h3scf->hq = NGX_CONF_UNSET;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
h3scf->quic.mtu = NGX_CONF_UNSET_SIZE;
|
h3scf->quic.mtu = NGX_CONF_UNSET_SIZE;
|
||||||
h3scf->quic.stream_buffer_size = NGX_CONF_UNSET_SIZE;
|
h3scf->quic.stream_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||||
|
@ -264,6 +265,10 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
ngx_http_ssl_srv_conf_t *sscf;
|
ngx_http_ssl_srv_conf_t *sscf;
|
||||||
|
|
||||||
|
ngx_conf_merge_value(conf->enable, prev->enable, 1);
|
||||||
|
|
||||||
|
ngx_conf_merge_value(conf->enable_hq, prev->enable_hq, 0);
|
||||||
|
|
||||||
ngx_conf_merge_uint_value(conf->max_concurrent_pushes,
|
ngx_conf_merge_uint_value(conf->max_concurrent_pushes,
|
||||||
prev->max_concurrent_pushes, 10);
|
prev->max_concurrent_pushes, 10);
|
||||||
|
|
||||||
|
@ -272,11 +277,6 @@ ngx_http_v3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
|
||||||
conf->max_blocked_streams = conf->max_concurrent_streams;
|
conf->max_blocked_streams = conf->max_concurrent_streams;
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
ngx_conf_merge_value(conf->hq, prev->hq, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
ngx_conf_merge_size_value(conf->quic.mtu, prev->quic.mtu,
|
ngx_conf_merge_size_value(conf->quic.mtu, prev->quic.mtu,
|
||||||
NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
|
NGX_QUIC_MAX_UDP_PAYLOAD_SIZE);
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,10 @@ ngx_http_v3_init_stream(ngx_connection_t *c)
|
||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_http_v3_init(ngx_connection_t *c)
|
ngx_http_v3_init(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
|
unsigned int len;
|
||||||
|
const unsigned char *data;
|
||||||
ngx_http_v3_session_t *h3c;
|
ngx_http_v3_session_t *h3c;
|
||||||
|
ngx_http_v3_srv_conf_t *h3scf;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init");
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init");
|
||||||
|
@ -119,11 +122,23 @@ ngx_http_v3_init(ngx_connection_t *c)
|
||||||
clcf = ngx_http_v3_get_module_loc_conf(c, ngx_http_core_module);
|
clcf = ngx_http_v3_get_module_loc_conf(c, ngx_http_core_module);
|
||||||
ngx_add_timer(&h3c->keepalive, clcf->keepalive_timeout);
|
ngx_add_timer(&h3c->keepalive, clcf->keepalive_timeout);
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
|
||||||
if (h3c->hq) {
|
|
||||||
return NGX_OK;
|
if (h3scf->enable_hq) {
|
||||||
|
if (!h3scf->enable) {
|
||||||
|
h3c->hq = 1;
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
|
||||||
|
|
||||||
|
if (len == sizeof(NGX_HTTP_V3_HQ_PROTO) - 1
|
||||||
|
&& ngx_strncmp(data, NGX_HTTP_V3_HQ_PROTO, len) == 0)
|
||||||
|
{
|
||||||
|
h3c->hq = 1;
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return ngx_http_v3_send_settings(c);
|
return ngx_http_v3_send_settings(c);
|
||||||
}
|
}
|
||||||
|
@ -147,10 +162,7 @@ ngx_http_v3_shutdown(ngx_connection_t *c)
|
||||||
if (!h3c->goaway) {
|
if (!h3c->goaway) {
|
||||||
h3c->goaway = 1;
|
h3c->goaway = 1;
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
if (!h3c->hq) {
|
||||||
if (!h3c->hq)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
(void) ngx_http_v3_send_goaway(c, h3c->next_request_id);
|
(void) ngx_http_v3_send_goaway(c, h3c->next_request_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,10 +217,7 @@ ngx_http_v3_init_request_stream(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
h3c->goaway = 1;
|
h3c->goaway = 1;
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
if (!h3c->hq) {
|
||||||
if (!h3c->hq)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (ngx_http_v3_send_goaway(c, h3c->next_request_id) != NGX_OK) {
|
if (ngx_http_v3_send_goaway(c, h3c->next_request_id) != NGX_OK) {
|
||||||
ngx_http_close_connection(c);
|
ngx_http_close_connection(c);
|
||||||
return;
|
return;
|
||||||
|
@ -236,10 +245,7 @@ ngx_http_v3_init_request_stream(ngx_connection_t *c)
|
||||||
|
|
||||||
rev = c->read;
|
rev = c->read;
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
if (!h3c->hq) {
|
||||||
if (!h3c->hq)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
rev->handler = ngx_http_v3_wait_request_handler;
|
rev->handler = ngx_http_v3_wait_request_handler;
|
||||||
c->write->handler = ngx_http_empty_handler;
|
c->write->handler = ngx_http_empty_handler;
|
||||||
}
|
}
|
||||||
|
@ -398,14 +404,14 @@ ngx_http_v3_wait_request_handler(ngx_event_t *rev)
|
||||||
void
|
void
|
||||||
ngx_http_v3_reset_stream(ngx_connection_t *c)
|
ngx_http_v3_reset_stream(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
|
ngx_http_v3_session_t *h3c;
|
||||||
ngx_http_v3_srv_conf_t *h3scf;
|
ngx_http_v3_srv_conf_t *h3scf;
|
||||||
|
|
||||||
h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
|
h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module);
|
||||||
|
|
||||||
if (h3scf->max_table_capacity > 0 && !c->read->eof
|
h3c = ngx_http_v3_get_session(c);
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
&& !h3scf->hq
|
if (h3scf->max_table_capacity > 0 && !c->read->eof && !h3c->hq
|
||||||
#endif
|
|
||||||
&& (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
|
&& (c->quic->id & NGX_QUIC_STREAM_UNIDIRECTIONAL) == 0)
|
||||||
{
|
{
|
||||||
(void) ngx_http_v3_send_cancel_stream(c, c->quic->id);
|
(void) ngx_http_v3_send_cancel_stream(c, c->quic->id);
|
||||||
|
@ -993,9 +999,11 @@ failed:
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_v3_process_request_header(ngx_http_request_t *r)
|
ngx_http_v3_process_request_header(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
|
ngx_http_v3_session_t *h3c;
|
||||||
|
ngx_http_v3_srv_conf_t *h3scf;
|
||||||
|
|
||||||
c = r->connection;
|
c = r->connection;
|
||||||
|
|
||||||
|
@ -1003,6 +1011,19 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r)
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h3c = ngx_http_v3_get_session(c);
|
||||||
|
h3scf = ngx_http_get_module_srv_conf(r, ngx_http_v3_module);
|
||||||
|
|
||||||
|
if (!r->http_connection->addr_conf->http3) {
|
||||||
|
if ((h3c->hq && !h3scf->enable_hq) || (!h3c->hq && !h3scf->enable)) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"client attempted to request the server name "
|
||||||
|
"for which the negotiated protocol is disabled");
|
||||||
|
ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST);
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_http_v3_construct_cookie_header(r) != NGX_OK) {
|
if (ngx_http_v3_construct_cookie_header(r) != NGX_OK) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,12 +37,9 @@ void
|
||||||
ngx_http_v3_init_uni_stream(ngx_connection_t *c)
|
ngx_http_v3_init_uni_stream(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
uint64_t n;
|
uint64_t n;
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
ngx_http_v3_session_t *h3c;
|
ngx_http_v3_session_t *h3c;
|
||||||
#endif
|
|
||||||
ngx_http_v3_uni_stream_t *us;
|
ngx_http_v3_uni_stream_t *us;
|
||||||
|
|
||||||
#if (NGX_HTTP_V3_HQ)
|
|
||||||
h3c = ngx_http_v3_get_session(c);
|
h3c = ngx_http_v3_get_session(c);
|
||||||
if (h3c->hq) {
|
if (h3c->hq) {
|
||||||
ngx_http_v3_finalize_connection(c,
|
ngx_http_v3_finalize_connection(c,
|
||||||
|
@ -52,7 +49,6 @@ ngx_http_v3_init_uni_stream(ngx_connection_t *c)
|
||||||
ngx_http_v3_close_uni_stream(c);
|
ngx_http_v3_close_uni_stream(c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init uni stream");
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 init uni stream");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue