mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
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.
This commit is contained in:
parent
cb70d5954c
commit
aefd862ab1
@ -435,6 +435,9 @@ 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_V2)
|
||||||
|
ngx_http_v2_srv_conf_t *h2scf;
|
||||||
|
#endif
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
ngx_http_v3_srv_conf_t *h3scf;
|
ngx_http_v3_srv_conf_t *h3scf;
|
||||||
#endif
|
#endif
|
||||||
@ -456,12 +459,6 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
|||||||
hc = c->data;
|
hc = c->data;
|
||||||
#endif
|
#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
|
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
if (hc->addr_conf->quic) {
|
if (hc->addr_conf->quic) {
|
||||||
|
|
||||||
@ -488,8 +485,19 @@ ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out,
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
|
#if (NGX_HTTP_V2)
|
||||||
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;
|
||||||
|
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
srv = (unsigned char *) NGX_HTTP_ALPN_PROTOS;
|
||||||
|
srvlen = sizeof(NGX_HTTP_ALPN_PROTOS) - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
|
if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen,
|
||||||
|
@ -4176,6 +4176,11 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
if (ngx_strcmp(value[n].data, "http2") == 0) {
|
if (ngx_strcmp(value[n].data, "http2") == 0) {
|
||||||
#if (NGX_HTTP_V2)
|
#if (NGX_HTTP_V2)
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"the \"listen ... http2\" directive "
|
||||||
|
"is deprecated, use "
|
||||||
|
"the \"http2\" directive instead");
|
||||||
|
|
||||||
lsopt.http2 = 1;
|
lsopt.http2 = 1;
|
||||||
continue;
|
continue;
|
||||||
#else
|
#else
|
||||||
|
@ -318,12 +318,6 @@ ngx_http_init_connection(ngx_connection_t *c)
|
|||||||
rev->handler = ngx_http_wait_request_handler;
|
rev->handler = ngx_http_wait_request_handler;
|
||||||
c->write->handler = ngx_http_empty_handler;
|
c->write->handler = ngx_http_empty_handler;
|
||||||
|
|
||||||
#if (NGX_HTTP_V2)
|
|
||||||
if (hc->addr_conf->http2) {
|
|
||||||
rev->handler = ngx_http_v2_init;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (NGX_HTTP_V3)
|
#if (NGX_HTTP_V3)
|
||||||
if (hc->addr_conf->quic) {
|
if (hc->addr_conf->quic) {
|
||||||
ngx_http_v3_init_stream(c);
|
ngx_http_v3_init_stream(c);
|
||||||
@ -383,6 +377,9 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
|
|||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_http_connection_t *hc;
|
ngx_http_connection_t *hc;
|
||||||
|
#if (NGX_HTTP_V2)
|
||||||
|
ngx_http_v2_srv_conf_t *h2scf;
|
||||||
|
#endif
|
||||||
ngx_http_core_srv_conf_t *cscf;
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
c = rev->data;
|
c = rev->data;
|
||||||
@ -429,6 +426,8 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
|
|||||||
b->end = b->last + size;
|
b->end = b->last + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = b->end - b->last;
|
||||||
|
|
||||||
n = c->recv(c, b->last, size);
|
n = c->recv(c, b->last, size);
|
||||||
|
|
||||||
if (n == NGX_AGAIN) {
|
if (n == NGX_AGAIN) {
|
||||||
@ -443,12 +442,16 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (b->pos == b->last) {
|
||||||
* We are trying to not hold c->buffer's memory for an idle connection.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
/*
|
||||||
b->start = NULL;
|
* We are trying to not hold c->buffer's memory for an
|
||||||
|
* idle connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ngx_pfree(c->pool, b->start) == NGX_OK) {
|
||||||
|
b->start = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -489,6 +492,29 @@ ngx_http_wait_request_handler(ngx_event_t *rev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_HTTP_V2)
|
||||||
|
|
||||||
|
h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);
|
||||||
|
|
||||||
|
if (!hc->ssl && (h2scf->enable || hc->addr_conf->http2)) {
|
||||||
|
|
||||||
|
size = ngx_min(sizeof(NGX_HTTP_V2_PREFACE) - 1,
|
||||||
|
(size_t) (b->last - b->pos));
|
||||||
|
|
||||||
|
if (ngx_memcmp(b->pos, NGX_HTTP_V2_PREFACE, size) == 0) {
|
||||||
|
|
||||||
|
if (size == sizeof(NGX_HTTP_V2_PREFACE) - 1) {
|
||||||
|
ngx_http_v2_init(rev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_post_event(rev, &ngx_posted_events);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
c->log->action = "reading client request line";
|
c->log->action = "reading client request line";
|
||||||
|
|
||||||
ngx_reusable_connection(c, 0);
|
ngx_reusable_connection(c, 0);
|
||||||
@ -808,13 +834,16 @@ ngx_http_ssl_handshake_handler(ngx_connection_t *c)
|
|||||||
#if (NGX_HTTP_V2 \
|
#if (NGX_HTTP_V2 \
|
||||||
&& defined TLSEXT_TYPE_application_layer_protocol_negotiation)
|
&& defined TLSEXT_TYPE_application_layer_protocol_negotiation)
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
const unsigned char *data;
|
const unsigned char *data;
|
||||||
ngx_http_connection_t *hc;
|
ngx_http_connection_t *hc;
|
||||||
|
ngx_http_v2_srv_conf_t *h2scf;
|
||||||
|
|
||||||
hc = c->data;
|
hc = c->data;
|
||||||
|
|
||||||
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) {
|
||||||
|
|
||||||
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
|
SSL_get0_alpn_selected(c->ssl->connection, &data, &len);
|
||||||
|
|
||||||
|
@ -63,8 +63,6 @@ static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
|
|||||||
static void ngx_http_v2_lingering_close(ngx_connection_t *c);
|
static void ngx_http_v2_lingering_close(ngx_connection_t *c);
|
||||||
static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);
|
static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);
|
||||||
|
|
||||||
static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c,
|
|
||||||
u_char *pos, u_char *end);
|
|
||||||
static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c,
|
static u_char *ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c,
|
||||||
u_char *pos, u_char *end);
|
u_char *pos, u_char *end);
|
||||||
static u_char *ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c,
|
static u_char *ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c,
|
||||||
@ -232,6 +230,7 @@ static ngx_http_v2_parse_header_t ngx_http_v2_parse_headers[] = {
|
|||||||
void
|
void
|
||||||
ngx_http_v2_init(ngx_event_t *rev)
|
ngx_http_v2_init(ngx_event_t *rev)
|
||||||
{
|
{
|
||||||
|
u_char *p, *end;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_pool_cleanup_t *cln;
|
ngx_pool_cleanup_t *cln;
|
||||||
ngx_http_connection_t *hc;
|
ngx_http_connection_t *hc;
|
||||||
@ -314,8 +313,7 @@ ngx_http_v2_init(ngx_event_t *rev)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2c->state.handler = hc->proxy_protocol ? ngx_http_v2_state_proxy_protocol
|
h2c->state.handler = ngx_http_v2_state_preface;
|
||||||
: ngx_http_v2_state_preface;
|
|
||||||
|
|
||||||
ngx_queue_init(&h2c->waiting);
|
ngx_queue_init(&h2c->waiting);
|
||||||
ngx_queue_init(&h2c->dependencies);
|
ngx_queue_init(&h2c->dependencies);
|
||||||
@ -335,6 +333,23 @@ ngx_http_v2_init(ngx_event_t *rev)
|
|||||||
c->idle = 1;
|
c->idle = 1;
|
||||||
ngx_reusable_connection(c, 0);
|
ngx_reusable_connection(c, 0);
|
||||||
|
|
||||||
|
if (c->buffer) {
|
||||||
|
p = c->buffer->pos;
|
||||||
|
end = c->buffer->last;
|
||||||
|
|
||||||
|
do {
|
||||||
|
p = h2c->state.handler(h2c, p, end);
|
||||||
|
|
||||||
|
if (p == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (p != end);
|
||||||
|
|
||||||
|
h2c->total_bytes += p - c->buffer->pos;
|
||||||
|
c->buffer->pos = p;
|
||||||
|
}
|
||||||
|
|
||||||
ngx_http_v2_read_handler(rev);
|
ngx_http_v2_read_handler(rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -846,32 +861,11 @@ ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static u_char *
|
|
||||||
ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|
||||||
u_char *end)
|
|
||||||
{
|
|
||||||
ngx_log_t *log;
|
|
||||||
|
|
||||||
log = h2c->connection->log;
|
|
||||||
log->action = "reading PROXY protocol";
|
|
||||||
|
|
||||||
pos = ngx_proxy_protocol_read(h2c->connection, pos, end);
|
|
||||||
|
|
||||||
log->action = "processing HTTP/2 connection";
|
|
||||||
|
|
||||||
if (pos == NULL) {
|
|
||||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ngx_http_v2_state_preface(h2c, pos, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos,
|
ngx_http_v2_state_preface(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||||
u_char *end)
|
u_char *end)
|
||||||
{
|
{
|
||||||
static const u_char preface[] = "PRI * HTTP/2.0\r\n";
|
static const u_char preface[] = NGX_HTTP_V2_PREFACE_START;
|
||||||
|
|
||||||
if ((size_t) (end - pos) < sizeof(preface) - 1) {
|
if ((size_t) (end - pos) < sizeof(preface) - 1) {
|
||||||
return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_preface);
|
return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_preface);
|
||||||
@ -892,7 +886,7 @@ static u_char *
|
|||||||
ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos,
|
ngx_http_v2_state_preface_end(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||||
u_char *end)
|
u_char *end)
|
||||||
{
|
{
|
||||||
static const u_char preface[] = "\r\nSM\r\n\r\n";
|
static const u_char preface[] = NGX_HTTP_V2_PREFACE_END;
|
||||||
|
|
||||||
if ((size_t) (end - pos) < sizeof(preface) - 1) {
|
if ((size_t) (end - pos) < sizeof(preface) - 1) {
|
||||||
return ngx_http_v2_state_save(h2c, pos, end,
|
return ngx_http_v2_state_save(h2c, pos, end,
|
||||||
@ -3943,10 +3937,22 @@ static void
|
|||||||
ngx_http_v2_run_request(ngx_http_request_t *r)
|
ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
ngx_connection_t *fc;
|
ngx_connection_t *fc;
|
||||||
|
ngx_http_v2_srv_conf_t *h2scf;
|
||||||
ngx_http_v2_connection_t *h2c;
|
ngx_http_v2_connection_t *h2c;
|
||||||
|
|
||||||
fc = r->connection;
|
fc = r->connection;
|
||||||
|
|
||||||
|
h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
|
||||||
|
|
||||||
|
if (!h2scf->enable && !r->http_connection->addr_conf->http2) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, fc->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);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_http_v2_construct_request_line(r) != NGX_OK) {
|
if (ngx_http_v2_construct_request_line(r) != NGX_OK) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,16 @@ typedef u_char *(*ngx_http_v2_handler_pt) (ngx_http_v2_connection_t *h2c,
|
|||||||
u_char *pos, u_char *end);
|
u_char *pos, u_char *end);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_flag_t enable;
|
||||||
|
size_t pool_size;
|
||||||
|
ngx_uint_t concurrent_streams;
|
||||||
|
ngx_uint_t concurrent_pushes;
|
||||||
|
size_t preread_size;
|
||||||
|
ngx_uint_t streams_index_mask;
|
||||||
|
} ngx_http_v2_srv_conf_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ngx_str_t name;
|
ngx_str_t name;
|
||||||
ngx_str_t value;
|
ngx_str_t value;
|
||||||
@ -408,9 +418,17 @@ ngx_int_t ngx_http_v2_table_size(ngx_http_v2_connection_t *h2c, size_t size);
|
|||||||
#define NGX_HTTP_V2_USER_AGENT_INDEX 58
|
#define NGX_HTTP_V2_USER_AGENT_INDEX 58
|
||||||
#define NGX_HTTP_V2_VARY_INDEX 59
|
#define NGX_HTTP_V2_VARY_INDEX 59
|
||||||
|
|
||||||
|
#define NGX_HTTP_V2_PREFACE_START "PRI * HTTP/2.0\r\n"
|
||||||
|
#define NGX_HTTP_V2_PREFACE_END "\r\nSM\r\n\r\n"
|
||||||
|
#define NGX_HTTP_V2_PREFACE NGX_HTTP_V2_PREFACE_START \
|
||||||
|
NGX_HTTP_V2_PREFACE_END
|
||||||
|
|
||||||
|
|
||||||
u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
|
u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
|
||||||
u_char *tmp, ngx_uint_t lower);
|
u_char *tmp, ngx_uint_t lower);
|
||||||
|
|
||||||
|
|
||||||
|
extern ngx_module_t ngx_http_v2_module;
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_HTTP_V2_H_INCLUDED_ */
|
#endif /* _NGX_HTTP_V2_H_INCLUDED_ */
|
||||||
|
@ -75,6 +75,13 @@ static ngx_conf_post_t ngx_http_v2_chunk_size_post =
|
|||||||
|
|
||||||
static ngx_command_t ngx_http_v2_commands[] = {
|
static ngx_command_t ngx_http_v2_commands[] = {
|
||||||
|
|
||||||
|
{ ngx_string("http2"),
|
||||||
|
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||||
|
ngx_conf_set_flag_slot,
|
||||||
|
NGX_HTTP_SRV_CONF_OFFSET,
|
||||||
|
offsetof(ngx_http_v2_srv_conf_t, enable),
|
||||||
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("http2_recv_buffer_size"),
|
{ ngx_string("http2_recv_buffer_size"),
|
||||||
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_size_slot,
|
ngx_conf_set_size_slot,
|
||||||
@ -314,6 +321,8 @@ ngx_http_v2_create_srv_conf(ngx_conf_t *cf)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2scf->enable = NGX_CONF_UNSET;
|
||||||
|
|
||||||
h2scf->pool_size = NGX_CONF_UNSET_SIZE;
|
h2scf->pool_size = NGX_CONF_UNSET_SIZE;
|
||||||
|
|
||||||
h2scf->concurrent_streams = NGX_CONF_UNSET_UINT;
|
h2scf->concurrent_streams = NGX_CONF_UNSET_UINT;
|
||||||
@ -333,6 +342,8 @@ ngx_http_v2_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
ngx_http_v2_srv_conf_t *prev = parent;
|
ngx_http_v2_srv_conf_t *prev = parent;
|
||||||
ngx_http_v2_srv_conf_t *conf = child;
|
ngx_http_v2_srv_conf_t *conf = child;
|
||||||
|
|
||||||
|
ngx_conf_merge_value(conf->enable, prev->enable, 0);
|
||||||
|
|
||||||
ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
|
ngx_conf_merge_size_value(conf->pool_size, prev->pool_size, 4096);
|
||||||
|
|
||||||
ngx_conf_merge_uint_value(conf->concurrent_streams,
|
ngx_conf_merge_uint_value(conf->concurrent_streams,
|
||||||
|
@ -20,15 +20,6 @@ typedef struct {
|
|||||||
} ngx_http_v2_main_conf_t;
|
} ngx_http_v2_main_conf_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
size_t pool_size;
|
|
||||||
ngx_uint_t concurrent_streams;
|
|
||||||
ngx_uint_t concurrent_pushes;
|
|
||||||
size_t preread_size;
|
|
||||||
ngx_uint_t streams_index_mask;
|
|
||||||
} ngx_http_v2_srv_conf_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t chunk_size;
|
size_t chunk_size;
|
||||||
|
|
||||||
@ -39,7 +30,4 @@ typedef struct {
|
|||||||
} ngx_http_v2_loc_conf_t;
|
} ngx_http_v2_loc_conf_t;
|
||||||
|
|
||||||
|
|
||||||
extern ngx_module_t ngx_http_v2_module;
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _NGX_HTTP_V2_MODULE_H_INCLUDED_ */
|
#endif /* _NGX_HTTP_V2_MODULE_H_INCLUDED_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user