[PATCH 12 of 14] Proxy: add HTTP/2 support
Piotr Sikora
piotrsikora at google.com
Thu Jun 22 20:33:16 UTC 2017
# HG changeset patch
# User Piotr Sikora <piotrsikora at google.com>
# Date 1490769087 25200
# Tue Mar 28 23:31:27 2017 -0700
# Node ID 7eb807b056da7abe9c679b59e94595d59a1406e6
# Parent 0637acdb51e29e1f68f5f3e762115c702cab4e72
Proxy: add HTTP/2 support.
Signed-off-by: Piotr Sikora <piotrsikora at google.com>
diff -r 0637acdb51e2 -r 7eb807b056da src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -125,6 +125,9 @@ static ngx_int_t ngx_http_proxy_eval(ngx
static ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r);
#endif
static ngx_int_t ngx_http_proxy_create_request(ngx_http_request_t *r);
+#if (NGX_HTTP_V2)
+static ngx_int_t ngx_http_proxy_create_v2_request(ngx_http_request_t *r);
+#endif
static ngx_int_t ngx_http_proxy_reinit_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_proxy_body_output_filter(void *data, ngx_chain_t *in);
static ngx_int_t ngx_http_proxy_process_status_line(ngx_http_request_t *r);
@@ -149,6 +152,8 @@ static ngx_int_t ngx_http_proxy_port_var
static ngx_int_t
ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_proxy_internal_connection_variable(
+ ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t
ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
@@ -245,6 +250,9 @@ static ngx_conf_bitmask_t ngx_http_prox
static ngx_conf_enum_t ngx_http_proxy_http_version[] = {
{ ngx_string("1.0"), NGX_HTTP_VERSION_10 },
{ ngx_string("1.1"), NGX_HTTP_VERSION_11 },
+#if (NGX_HTTP_V2)
+ { ngx_string("2.0"), NGX_HTTP_VERSION_20 },
+#endif
{ ngx_null_string, 0 }
};
@@ -765,7 +773,7 @@ static char ngx_http_proxy_version_11[]
static ngx_keyval_t ngx_http_proxy_headers[] = {
{ ngx_string("Host"), ngx_string("$proxy_host") },
- { ngx_string("Connection"), ngx_string("close") },
+ { ngx_string("Connection"), ngx_string("$proxy_internal_connection") },
{ ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
{ ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") },
{ ngx_string("TE"), ngx_string("") },
@@ -793,7 +801,7 @@ static ngx_str_t ngx_http_proxy_hide_he
static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
{ ngx_string("Host"), ngx_string("$proxy_host") },
- { ngx_string("Connection"), ngx_string("close") },
+ { ngx_string("Connection"), ngx_string("$proxy_internal_connection") },
{ ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") },
{ ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") },
{ ngx_string("TE"), ngx_string("") },
@@ -828,6 +836,10 @@ static ngx_http_variable_t ngx_http_pro
{ ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 },
#endif
+ { ngx_string("proxy_internal_connection"), NULL,
+ ngx_http_proxy_internal_connection_variable, 0,
+ NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
+
{ ngx_string("proxy_internal_body_length"), NULL,
ngx_http_proxy_internal_body_length_variable, 0,
NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
@@ -902,6 +914,18 @@ ngx_http_proxy_handler(ngx_http_request_
u->finalize_request = ngx_http_proxy_finalize_request;
r->state = 0;
+#if (NGX_HTTP_V2)
+
+ if (plcf->http_version == NGX_HTTP_VERSION_20) {
+ u->http2 = 1;
+
+ u->create_request = ngx_http_proxy_create_v2_request;
+ u->output.output_filter = ngx_http_v2_upstream_output_filter;
+ u->output.filter_ctx = r;
+ }
+
+#endif
+
if (plcf->redirects) {
u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
}
@@ -929,7 +953,7 @@ ngx_http_proxy_handler(ngx_http_request_
if (!plcf->upstream.request_buffering
&& plcf->body_values == NULL && plcf->upstream.pass_request_body
&& (!r->headers_in.chunked
- || plcf->http_version == NGX_HTTP_VERSION_11))
+ || plcf->http_version >= NGX_HTTP_VERSION_11))
{
r->request_body_no_buffering = 1;
}
@@ -1521,6 +1545,509 @@ ngx_http_proxy_create_request(ngx_http_r
}
+#if (NGX_HTTP_V2)
+
+static ngx_int_t
+ngx_http_proxy_create_v2_request(ngx_http_request_t *r)
+{
+ size_t len, uri_len, loc_len, body_len;
+ size_t key_len, val_len, tmp_len;
+ u_char *p, *code_tmp, *huff_tmp;
+ uintptr_t escape;
+ ngx_buf_t *b;
+ ngx_str_t method;
+ ngx_uint_t i, unparsed_uri;
+ ngx_chain_t *cl, *body;
+ ngx_list_part_t *part;
+ ngx_table_elt_t *header;
+ ngx_http_upstream_t *u;
+ ngx_http_proxy_ctx_t *ctx;
+ ngx_http_script_code_pt code;
+ ngx_http_proxy_headers_t *headers;
+ ngx_http_script_engine_t e, le;
+ ngx_http_proxy_loc_conf_t *plcf;
+ ngx_http_script_len_code_pt lcode;
+
+ u = r->upstream;
+
+ plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
+
+#if (NGX_HTTP_CACHE)
+ headers = u->cacheable ? &plcf->headers_cache : &plcf->headers;
+#else
+ headers = &plcf->headers;
+#endif
+
+ if (u->method.len) {
+ /* HEAD was changed to GET to cache response */
+ method = u->method;
+
+ } else if (plcf->method) {
+ if (ngx_http_complex_value(r, plcf->method, &method) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ } else {
+ method = r->method_name;
+ }
+
+ tmp_len = 0;
+
+ if (method.len == 3
+ && ngx_strncasecmp(method.data, (u_char *) "GET", 3) == 0)
+ {
+ len = 1;
+
+ } else if (method.len == 4
+ && ngx_strncasecmp(method.data, (u_char *) "POST", 4) == 0)
+ {
+ len = 1;
+
+ } else {
+ len = 1 + NGX_HTTP_V2_INT_OCTETS + method.len;
+ tmp_len = method.len;
+ }
+
+ escape = 0;
+ loc_len = 0;
+ unparsed_uri = 0;
+
+ ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
+
+ if (plcf->proxy_lengths && ctx->vars.uri.len) {
+ uri_len = ctx->vars.uri.len;
+
+ } else if (ctx->vars.uri.len == 0 && r->valid_unparsed_uri && r == r->main)
+ {
+ unparsed_uri = 1;
+ uri_len = r->unparsed_uri.len;
+
+ } else {
+ loc_len = (r->valid_location && ctx->vars.uri.len)
+ ? plcf->location.len : 0;
+
+ if (r->quoted_uri || r->space_in_uri || r->internal) {
+ escape = 2 * ngx_escape_uri(NULL, r->uri.data + loc_len,
+ r->uri.len - loc_len, NGX_ESCAPE_URI);
+ }
+
+ uri_len = ctx->vars.uri.len + r->uri.len - loc_len + escape
+ + sizeof("?") - 1 + r->args.len;
+ }
+
+ if (uri_len == 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "zero length URI to proxy");
+ return NGX_ERROR;
+ }
+
+ len += 1 + NGX_HTTP_V2_INT_OCTETS + uri_len;
+
+ if (uri_len > tmp_len) {
+ tmp_len = uri_len;
+ }
+
+
+ ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
+
+ ngx_http_script_flush_no_cacheable_variables(r, plcf->body_flushes);
+ ngx_http_script_flush_no_cacheable_variables(r, headers->flushes);
+
+ body_len = 0;
+
+ if (plcf->body_lengths) {
+ le.ip = plcf->body_lengths->elts;
+ le.request = r;
+ le.flushed = 1;
+
+ while (*(uintptr_t *) le.ip) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ body_len += lcode(&le);
+ }
+
+ ctx->internal_body_length = body_len;
+
+ } else if (r->headers_in.chunked && r->reading_body) {
+ ctx->internal_body_length = -1;
+ ctx->internal_chunked = 1;
+
+ } else {
+ ctx->internal_body_length = r->headers_in.content_length_n;
+ }
+
+ le.ip = headers->lengths->elts;
+ le.request = r;
+ le.flushed = 1;
+
+ while (*(uintptr_t *) le.ip) {
+
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ key_len = lcode(&le);
+
+ for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ }
+ le.ip += sizeof(uintptr_t);
+
+ if (val_len == 0) {
+ continue;
+ }
+
+ len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len
+ + NGX_HTTP_V2_INT_OCTETS + val_len;
+
+ if (key_len > tmp_len) {
+ tmp_len = key_len;
+ }
+
+ if (val_len > tmp_len) {
+ tmp_len = val_len;
+ }
+ }
+
+
+ if (plcf->upstream.pass_request_headers) {
+ part = &r->headers_in.headers.part;
+ header = part->elts;
+
+ for (i = 0; /* void */; i++) {
+
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ header = part->elts;
+ i = 0;
+ }
+
+ if (ngx_hash_find(&headers->hash, header[i].hash,
+ header[i].lowcase_key, header[i].key.len))
+ {
+ continue;
+ }
+
+ if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "too long request header name: \"%V\"",
+ &header[i].key);
+ return NGX_ERROR;
+ }
+
+ if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "too long request header value: \"%V: %V\"",
+ &header[i].key, &header[i].value);
+ return NGX_ERROR;
+ }
+
+ len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len
+ + NGX_HTTP_V2_INT_OCTETS + header[i].value.len;
+
+ if (header[i].key.len > tmp_len) {
+ tmp_len = header[i].key.len;
+ }
+
+ if (header[i].value.len > tmp_len) {
+ tmp_len = header[i].value.len;
+ }
+ }
+ }
+
+ code_tmp = ngx_pnalloc(r->pool, tmp_len);
+ if (code_tmp == NULL) {
+ return NGX_ERROR;
+ }
+
+ huff_tmp = ngx_palloc(r->pool, tmp_len);
+ if (huff_tmp == NULL) {
+ return NGX_ERROR;
+ }
+
+ b = ngx_create_temp_buf(r->pool, len);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl = ngx_alloc_chain_link(r->pool);
+ if (cl == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl->buf = b;
+ cl->next = NULL;
+
+ /* :method header */
+
+ if (method.len == 3
+ && ngx_strncasecmp(method.data, (u_char *) "GET", 3) == 0)
+ {
+ *b->last++ = ngx_http_v2_indexed(NGX_HTTP_V2_METHOD_GET_INDEX);
+
+ } else if (method.len == 4
+ && ngx_strncasecmp(method.data, (u_char *) "POST", 4) == 0)
+ {
+ *b->last++ = ngx_http_v2_indexed(NGX_HTTP_V2_METHOD_POST_INDEX);
+
+ } else {
+ *b->last++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_METHOD_INDEX);
+ b->last = ngx_http_v2_write_value(b->last, method.data, method.len,
+ huff_tmp);
+ }
+
+ /* :scheme header */
+
+ if (u->schema.len == 8
+ && ngx_strncasecmp(u->schema.data, (u_char *) "https://", 8) == 0)
+ {
+ *b->last++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTPS_INDEX);
+
+ } else {
+ *b->last++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTP_INDEX);
+ }
+
+ /* :authority header */
+
+ le.ip = headers->lengths->elts;
+
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ (void) lcode(&le);
+
+ for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ }
+ le.ip += sizeof(uintptr_t);
+
+ if (val_len == 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "missing or empty \"Host\" header");
+ return NGX_ERROR;
+ }
+
+ ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
+
+ e.ip = headers->values->elts;
+ e.request = r;
+ e.flushed = 1;
+ e.skip = 1;
+
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+
+ e.skip = 0;
+ e.pos = code_tmp;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+ }
+ e.ip += sizeof(uintptr_t);
+
+ *b->last++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_AUTHORITY_INDEX);
+ b->last = ngx_http_v2_write_value(b->last, code_tmp, e.pos - code_tmp,
+ huff_tmp);
+
+ /* :path header */
+
+ if (plcf->proxy_lengths && ctx->vars.uri.len) {
+ u->uri = ctx->vars.uri;
+
+ } else if (unparsed_uri) {
+ u->uri = r->unparsed_uri;
+
+ } else {
+ p = ngx_pnalloc(r->pool, uri_len);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ u->uri.data = p;
+
+ if (r->valid_location) {
+ p = ngx_copy(p, ctx->vars.uri.data, ctx->vars.uri.len);
+ }
+
+ if (escape) {
+ ngx_escape_uri(p, r->uri.data + loc_len, r->uri.len - loc_len,
+ NGX_ESCAPE_URI);
+ p += r->uri.len - loc_len + escape;
+
+ } else {
+ p = ngx_copy(p, r->uri.data + loc_len, r->uri.len - loc_len);
+ }
+
+ if (r->args.len > 0) {
+ *p++ = '?';
+ p = ngx_copy(p, r->args.data, r->args.len);
+ }
+
+ u->uri.len = p - u->uri.data;
+ }
+
+ if (uri_len == 1) {
+ *b->last++ = ngx_http_v2_indexed(NGX_HTTP_V2_PATH_ROOT_INDEX);
+
+ } else {
+ *b->last++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_PATH_INDEX);
+ b->last = ngx_http_v2_write_value(b->last, u->uri.data, u->uri.len,
+ huff_tmp);
+ }
+
+
+ while (*(uintptr_t *) le.ip) {
+
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ (void) lcode(&le);
+
+ for (val_len = 0; *(uintptr_t *) le.ip; val_len += lcode(&le)) {
+ lcode = *(ngx_http_script_len_code_pt *) le.ip;
+ }
+ le.ip += sizeof(uintptr_t);
+
+ if (val_len == 0) {
+ e.skip = 1;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+ }
+ e.ip += sizeof(uintptr_t);
+
+ e.skip = 0;
+
+ continue;
+ }
+
+ e.pos = code_tmp;
+
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+
+ *b->last++ = '\0';
+ b->last = ngx_http_v2_write_name(b->last, code_tmp, e.pos - code_tmp,
+ huff_tmp);
+
+ e.pos = code_tmp;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+ }
+ e.ip += sizeof(uintptr_t);
+
+ b->last = ngx_http_v2_write_value(b->last, code_tmp, e.pos - code_tmp,
+ huff_tmp);
+ }
+
+
+ if (plcf->upstream.pass_request_headers) {
+ part = &r->headers_in.headers.part;
+ header = part->elts;
+
+ for (i = 0; /* void */; i++) {
+
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ header = part->elts;
+ i = 0;
+ }
+
+ if (ngx_hash_find(&headers->hash, header[i].hash,
+ header[i].lowcase_key, header[i].key.len))
+ {
+ continue;
+ }
+
+ *b->last++ = '\0';
+
+ b->last = ngx_http_v2_write_name(b->last, header[i].key.data,
+ header[i].key.len, huff_tmp);
+
+ b->last = ngx_http_v2_write_value(b->last, header[i].value.data,
+ header[i].value.len, huff_tmp);
+
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "proxy http2 header: \"%*s: %V\"",
+ header[i].key.len, header[i].lowcase_key,
+ &header[i].value);
+ }
+ }
+
+
+ if (plcf->body_values && body_len) {
+ b = ngx_create_temp_buf(r->pool, body_len);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ e.ip = plcf->body_values->elts;
+ e.pos = b->last;
+ e.skip = 0;
+
+ while (*(uintptr_t *) e.ip) {
+ code = *(ngx_http_script_code_pt *) e.ip;
+ code((ngx_http_script_engine_t *) &e);
+ }
+
+ b->last = e.pos;
+
+ cl->next = ngx_alloc_chain_link(r->pool);
+ if (cl->next == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl->next->buf = b;
+ cl->next->next = NULL;
+ }
+
+
+ if (r->request_body_no_buffering) {
+ u->request_bufs = cl;
+ b->flush = 1;
+
+ } else if (plcf->body_values == NULL && plcf->upstream.pass_request_body) {
+
+ body = u->request_bufs;
+ u->request_bufs = cl;
+
+ while (body) {
+ b = ngx_alloc_buf(r->pool);
+ if (b == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(b, body->buf, sizeof(ngx_buf_t));
+
+ cl->next = ngx_alloc_chain_link(r->pool);
+ if (cl->next == NULL) {
+ return NGX_ERROR;
+ }
+
+ cl = cl->next;
+ cl->buf = b;
+
+ body = body->next;
+ }
+
+ cl->next = NULL;
+ b->last_buf = 1;
+
+ } else {
+ u->request_bufs = cl;
+ b->last_buf = 1;
+ }
+
+ return NGX_OK;
+}
+
+#endif
+
+
static ngx_int_t
ngx_http_proxy_reinit_request(ngx_http_request_t *r)
{
@@ -1966,6 +2493,14 @@ ngx_http_proxy_input_filter_init(void *d
u->headers_in.status_n, ctx->head, u->headers_in.chunked,
u->headers_in.content_length_n);
+#if (NGX_HTTP_V2)
+
+ if (u->stream) {
+ return NGX_OK;
+ }
+
+#endif
+
/* as per RFC2616, 4.4 Message Length */
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
@@ -2480,6 +3015,34 @@ ngx_http_proxy_add_x_forwarded_for_varia
static ngx_int_t
+ngx_http_proxy_internal_connection_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+#if (NGX_HTTP_V2)
+
+ ngx_http_proxy_loc_conf_t *plcf;
+
+ plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
+
+ if (plcf->http_version == NGX_HTTP_VERSION_20) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+#endif
+
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ v->data = (u_char *) "close";
+ v->len = sizeof("close") - 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
@@ -2512,7 +3075,20 @@ static ngx_int_t
ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- ngx_http_proxy_ctx_t *ctx;
+ ngx_http_proxy_ctx_t *ctx;
+
+#if (NGX_HTTP_V2)
+
+ ngx_http_proxy_loc_conf_t *plcf;
+
+ plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
+
+ if (plcf->http_version == NGX_HTTP_VERSION_20) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+#endif
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
@@ -3407,6 +3983,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
#if (NGX_HTTP_CACHE)
if (conf->upstream.cache) {
+
+#if (NGX_HTTP_V2)
+
+ if (conf->http_version == NGX_HTTP_VERSION_20) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"proxy_cache\" doesn't work with "
+ "\"proxy_http_version 2.0\"");
+ return NGX_CONF_ERROR;
+ }
+
+#endif
+
rc = ngx_http_proxy_init_headers(cf, conf, &conf->headers_cache,
ngx_http_proxy_cache_headers);
if (rc != NGX_OK) {
@@ -4361,6 +4949,15 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n
case NGX_HTTP_VERSION_11:
ngx_str_set(&alpn, NGX_HTTP_11_ALPN_ADVERTISE);
break;
+
+#if (NGX_HTTP_V2)
+
+ case NGX_HTTP_VERSION_20:
+ ngx_str_set(&alpn, NGX_HTTP_V2_ALPN_ADVERTISE);
+ break;
+
+#endif
+
}
if (ngx_ssl_alpn_protos(cf, plcf->upstream.ssl, &alpn) != NGX_OK) {
diff -r 0637acdb51e2 -r 7eb807b056da src/http/v2/ngx_http_v2.h
--- a/src/http/v2/ngx_http_v2.h
+++ b/src/http/v2/ngx_http_v2.h
@@ -13,6 +13,28 @@
#include <ngx_http.h>
+#define ngx_http_v2_indexed(i) (128 + (i))
+#define ngx_http_v2_inc_indexed(i) (64 + (i))
+
+
+// :authority
+#define NGX_HTTP_V2_AUTHORITY_INDEX 1
+
+// :method
+#define NGX_HTTP_V2_METHOD_INDEX 2
+#define NGX_HTTP_V2_METHOD_GET_INDEX 2
+#define NGX_HTTP_V2_METHOD_POST_INDEX 3
+
+// :path
+#define NGX_HTTP_V2_PATH_INDEX 4
+#define NGX_HTTP_V2_PATH_ROOT_INDEX 4
+
+// :scheme
+#define NGX_HTTP_V2_SCHEME_INDEX 6
+#define NGX_HTTP_V2_SCHEME_HTTP_INDEX 6
+#define NGX_HTTP_V2_SCHEME_HTTPS_INDEX 7
+
+
#define NGX_HTTP_V2_ALPN_ADVERTISE "\x02h2"
#define NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_V2_ALPN_ADVERTISE
@@ -325,6 +347,9 @@ void ngx_http_v2_finalize_connection(ngx
ngx_uint_t status);
+u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
+ u_char *tmp, ngx_uint_t lower);
+
ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
ngx_http_v2_stream_t *stream, u_char *pos, u_char *end, ngx_uint_t fin);
@@ -415,4 +440,11 @@ size_t ngx_http_v2_huff_encode(u_char *s
#define ngx_http_v2_write_sid ngx_http_v2_write_uint32
+
+#define ngx_http_v2_write_name(dst, src, len, tmp) \
+ ngx_http_v2_string_encode(dst, src, len, tmp, 1)
+#define ngx_http_v2_write_value(dst, src, len, tmp) \
+ ngx_http_v2_string_encode(dst, src, len, tmp, 0)
+
+
#endif /* _NGX_HTTP_V2_H_INCLUDED_ */
diff -r 0637acdb51e2 -r 7eb807b056da src/http/v2/ngx_http_v2_filter_module.c
--- a/src/http/v2/ngx_http_v2_filter_module.c
+++ b/src/http/v2/ngx_http_v2_filter_module.c
@@ -22,14 +22,6 @@
#define ngx_http_v2_literal_size(h) \
(ngx_http_v2_integer_octets(sizeof(h) - 1) + sizeof(h) - 1)
-#define ngx_http_v2_indexed(i) (128 + (i))
-#define ngx_http_v2_inc_indexed(i) (64 + (i))
-
-#define ngx_http_v2_write_name(dst, src, len, tmp) \
- ngx_http_v2_string_encode(dst, src, len, tmp, 1)
-#define ngx_http_v2_write_value(dst, src, len, tmp) \
- ngx_http_v2_string_encode(dst, src, len, tmp, 0)
-
#define NGX_HTTP_V2_ENCODE_RAW 0
#define NGX_HTTP_V2_ENCODE_HUFF 0x80
@@ -53,8 +45,6 @@
#define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1
-static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
- u_char *tmp, ngx_uint_t lower);
static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix,
ngx_uint_t value);
static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
@@ -740,7 +730,7 @@ ngx_http_v2_create_trailers_frame(ngx_ht
}
-static u_char *
+u_char *
ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp,
ngx_uint_t lower)
{
More information about the nginx-devel
mailing list