diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c index a76a14d79..6936c74e1 100644 --- a/src/http/modules/ngx_http_grpc_module.c +++ b/src/http/modules/ngx_http_grpc_module.c @@ -25,7 +25,6 @@ typedef struct { ngx_array_t *headers_source; ngx_str_t host; - ngx_uint_t host_set; ngx_http_complex_value_t *authority; ngx_array_t *grpc_lengths; @@ -204,6 +203,8 @@ static ngx_int_t ngx_http_grpc_init_headers(ngx_conf_t *cf, static char *ngx_http_grpc_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_grpc_set_header(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); #if (NGX_HTTP_SSL) static char *ngx_http_grpc_ssl_certificate_cache(ngx_conf_t *cf, @@ -335,7 +336,7 @@ static ngx_command_t ngx_http_grpc_commands[] = { { ngx_string("grpc_set_header"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, - ngx_conf_set_keyval_slot, + ngx_http_grpc_set_header, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_grpc_loc_conf_t, headers_source), NULL }, @@ -798,15 +799,16 @@ ngx_http_grpc_create_request(ngx_http_request_t *r) } /* :authority header */ + host = &ctx->host; if (glcf->authority != NULL) { if (ngx_http_complex_value(r, glcf->authority, &host_val) != NGX_OK) { return NGX_ERROR; } - host = &host_val; - } else { - host = &ctx->host; + if (host_val.len) { + host = &host_val; + } } if (host->len > NGX_HTTP_V2_MAX_FIELD) { @@ -4443,7 +4445,6 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf) * conf->headers.values = NULL; * conf->headers.hash = { NULL, 0 }; * conf->host = { 0, NULL }; - * conf->host_set = 0; * conf->ssl = 0; * conf->ssl_protocols = 0; * conf->ssl_ciphers = { 0, NULL }; @@ -4646,7 +4647,6 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) if (conf->headers_source == prev->headers_source) { conf->headers = prev->headers; - conf->host_set = prev->host_set; } rc = ngx_http_grpc_init_headers(cf, conf, &conf->headers, @@ -4664,8 +4664,6 @@ ngx_http_grpc_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) && conf->headers_source == prev->headers_source) { prev->headers = conf->headers; - prev->host_set = conf->host_set; - prev->authority = conf->authority; } return NGX_CONF_OK; @@ -4718,37 +4716,6 @@ ngx_http_grpc_init_headers(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *conf, src = conf->headers_source->elts; for (i = 0; i < conf->headers_source->nelts; i++) { - if (src[i].key.len == 4 - && ngx_strncasecmp(src[i].key.data, (u_char *) "Host", 4) == 0) - { - conf->host_set = 1; - - if (conf->authority != NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"grpc_set_header Host\" cannot be " - "used with \"grpc_set_authority\""); - return NGX_ERROR; - - } else { - ngx_http_compile_complex_value_t ccv; - - conf->authority = ngx_palloc(cf->pool, - sizeof(ngx_http_complex_value_t)); - if (conf->authority == NULL) { - return NGX_ERROR; - } - - ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); - ccv.cf = cf; - ccv.value = &src[i].value; - ccv.complex_value = conf->authority; - - if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { - return NGX_ERROR; - } - } - } - s = ngx_array_push(&headers_merged); if (s == NULL) { return NGX_ERROR; @@ -4850,6 +4817,28 @@ ngx_http_grpc_init_headers(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *conf, *code = (uintptr_t) NULL; } + if (conf->authority == NULL) { + ngx_str_t v; + ngx_http_compile_complex_value_t ccv; + + ngx_str_set(&v, "$proxy_internal_host"); + + conf->authority = ngx_palloc(cf->pool, + sizeof(ngx_http_complex_value_t)); + if (conf->authority == NULL) { + return NGX_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = &v; + ccv.complex_value = conf->authority; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_ERROR; + } + } + code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t)); if (code == NULL) { return NGX_ERROR; @@ -4971,6 +4960,48 @@ ngx_http_grpc_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } +static char * +ngx_http_grpc_set_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_grpc_loc_conf_t *glcf = conf; + ngx_str_t *value = cf->args->elts; + + if (value[1].len == 4 + && ngx_strncasecmp(value[1].data, (u_char *) "Host", 4) == 0) + { + ngx_http_compile_complex_value_t ccv; + + if (glcf->authority != NGX_CONF_UNSET_PTR + && glcf->authority != NULL) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"grpc_set_header Host\" cannot be " + "used with \"grpc_set_authority\""); + return NGX_CONF_ERROR; + } + + glcf->authority = ngx_palloc(cf->pool, + sizeof(ngx_http_complex_value_t)); + if (glcf->authority == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = &value[2]; + ccv.complex_value = glcf->authority; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; + } + + return ngx_conf_set_keyval_slot(cf, cmd, conf); +} + + #if (NGX_HTTP_SSL) static char * diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index 880d28e8c..cc9ab972d 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -113,6 +113,8 @@ static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_proxy_set_header(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static char *ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_proxy_cookie_path(ngx_conf_t *cf, ngx_command_t *cmd, @@ -321,7 +323,7 @@ static ngx_command_t ngx_http_proxy_commands[] = { { ngx_string("proxy_set_header"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2, - ngx_conf_set_keyval_slot, + ngx_http_proxy_set_header, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, headers_source), NULL }, @@ -752,7 +754,7 @@ static char ngx_http_proxy_version_11[] = " HTTP/1.1" CRLF; static ngx_keyval_t ngx_http_proxy_headers[] = { - { ngx_string("Host"), ngx_string("$proxy_internal_host") }, + { ngx_string("Host"), ngx_string("") }, { ngx_string("Connection"), ngx_string("") }, { ngx_string("Proxy-Connection"), ngx_string("") }, { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, @@ -781,7 +783,7 @@ static ngx_str_t ngx_http_proxy_hide_headers[] = { #if (NGX_HTTP_CACHE) static ngx_keyval_t ngx_http_proxy_cache_headers[] = { - { ngx_string("Host"), ngx_string("$proxy_internal_host") }, + { ngx_string("Host"), ngx_string("") }, { ngx_string("Connection"), ngx_string("") }, { ngx_string("Proxy-Connection"), ngx_string("") }, { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, @@ -1186,7 +1188,7 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) key_len, val_len; uintptr_t escape; ngx_buf_t *b; - ngx_str_t method; + ngx_str_t method, host_val; ngx_uint_t i, unparsed_uri; ngx_chain_t *cl, *body; ngx_list_part_t *part; @@ -1313,6 +1315,15 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) len += key_len + sizeof(": ") - 1 + val_len + sizeof(CRLF) - 1; } + /* Host header */ + + if (ngx_http_complex_value(r, plcf->authority, &host_val) != NGX_OK) { + return NGX_ERROR; + } + + if (host_val.len) { + len += sizeof("Host: ") - 1 + host_val.len + sizeof(CRLF) - 1; + } if (plcf->upstream.pass_request_headers) { part = &r->headers_in.headers.part; @@ -1400,6 +1411,14 @@ ngx_http_proxy_create_request(ngx_http_request_t *r) sizeof(ngx_http_proxy_version) - 1); } + /* Host header */ + + if (host_val.len) { + b->last = ngx_cpymem(b->last, "Host: ", sizeof("Host: ") - 1); + b->last = ngx_copy(b->last, host_val.data, host_val.len); + *b->last++ = CR; *b->last++ = LF; + } + ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); e.ip = headers->values->elts; @@ -3510,7 +3529,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf) * conf->headers.values = NULL; * conf->headers.hash = { NULL, 0 }; * conf->headers_cache.lengths = NULL; - * conf->host_set = 0; * conf->headers_cache.values = NULL; * conf->headers_cache.hash = { NULL, 0 }; * conf->body_lengths = NULL; @@ -4090,7 +4108,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) #if (NGX_HTTP_CACHE) conf->headers_cache = prev->headers_cache; #endif - conf->host_set = prev->host_set; } rc = ngx_http_proxy_init_headers(cf, conf, &conf->headers, @@ -4123,8 +4140,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) #if (NGX_HTTP_CACHE) prev->headers_cache = conf->headers_cache; #endif - prev->host_set = conf->host_set; - prev->authority = conf->authority; } return NGX_CONF_OK; @@ -4177,37 +4192,6 @@ ngx_http_proxy_init_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf, src = conf->headers_source->elts; for (i = 0; i < conf->headers_source->nelts; i++) { - if (src[i].key.len == 4 - && ngx_strncasecmp(src[i].key.data, (u_char *) "Host", 4) == 0) - { - conf->host_set = 1; - - if (conf->authority != NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_set_header Host\" cannot be " - "used with \"proxy_set_authority\""); - return NGX_ERROR; - - } else { - ngx_http_compile_complex_value_t ccv; - - conf->authority = ngx_palloc(cf->pool, - sizeof(ngx_http_complex_value_t)); - if (conf->authority == NULL) { - return NGX_ERROR; - } - - ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); - ccv.cf = cf; - ccv.value = &src[i].value; - ccv.complex_value = conf->authority; - - if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { - return NGX_ERROR; - } - } - } - s = ngx_array_push(&headers_merged); if (s == NULL) { return NGX_ERROR; @@ -4309,6 +4293,28 @@ ngx_http_proxy_init_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf, *code = (uintptr_t) NULL; } + if (conf->authority == NULL) { + ngx_str_t v; + ngx_http_compile_complex_value_t ccv; + + ngx_str_set(&v, "$proxy_internal_host"); + + conf->authority = ngx_palloc(cf->pool, + sizeof(ngx_http_complex_value_t)); + if (conf->authority == NULL) { + return NGX_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = &v; + ccv.complex_value = conf->authority; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_ERROR; + } + } + code = ngx_array_push_n(headers->lengths, sizeof(uintptr_t)); if (code == NULL) { return NGX_ERROR; @@ -4595,6 +4601,48 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } +static char * +ngx_http_proxy_set_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_proxy_loc_conf_t *plcf = conf; + ngx_str_t *value = cf->args->elts; + + if (value[1].len == 4 + && ngx_strncasecmp(value[1].data, (u_char *) "Host", 4) == 0) + { + ngx_http_compile_complex_value_t ccv; + + if (plcf->authority != NGX_CONF_UNSET_PTR + && plcf->authority != NULL) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"proxy_set_header Host\" cannot be " + "used with \"proxy_set_authority\""); + return NGX_CONF_ERROR; + } + + plcf->authority = ngx_palloc(cf->pool, + sizeof(ngx_http_complex_value_t)); + if (plcf->authority == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = &value[2]; + ccv.complex_value = plcf->authority; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + return NGX_CONF_OK; + } + + return ngx_conf_set_keyval_slot(cf, cmd, conf); +} + + static char * ngx_http_proxy_cookie_domain(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { diff --git a/src/http/modules/ngx_http_proxy_module.h b/src/http/modules/ngx_http_proxy_module.h index fd199cd8a..06ecfb137 100644 --- a/src/http/modules/ngx_http_proxy_module.h +++ b/src/http/modules/ngx_http_proxy_module.h @@ -49,7 +49,6 @@ typedef struct { ngx_http_proxy_headers_t headers_cache; #endif ngx_array_t *headers_source; - ngx_uint_t host_set; ngx_http_complex_value_t *authority; ngx_array_t *proxy_lengths; diff --git a/src/http/modules/ngx_http_proxy_v2_module.c b/src/http/modules/ngx_http_proxy_v2_module.c index 68c4b9c14..7a0b951cb 100644 --- a/src/http/modules/ngx_http_proxy_v2_module.c +++ b/src/http/modules/ngx_http_proxy_v2_module.c @@ -439,14 +439,16 @@ ngx_http_proxy_v2_create_request(ngx_http_request_t *r) /* :authority header */ + host = &ctx->ctx.vars.host_header; + if (plcf->authority != NULL) { if (ngx_http_complex_value(r, plcf->authority, &host_val) != NGX_OK) { return NGX_ERROR; } - host = &host_val; - } else { - host = &ctx->ctx.vars.host_header; + if (host_val.len) { + host = &host_val; + } } if (host->len > NGX_HTTP_V2_MAX_FIELD) {