Merge branch 'nginx:master' into feature/PROXY_V2_SUPPORT

This commit is contained in:
mdewitt11 2025-12-09 11:47:57 -06:00 committed by GitHub
commit e973dec3ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 4417 additions and 139 deletions

View File

@ -729,7 +729,7 @@ if [ $HTTP = YES ]; then
ngx_module_name=ngx_http_proxy_module
ngx_module_incs=
ngx_module_deps=
ngx_module_deps=src/http/modules/ngx_http_proxy_module.h
ngx_module_srcs=src/http/modules/ngx_http_proxy_module.c
ngx_module_libs=
ngx_module_link=$HTTP_PROXY
@ -781,6 +781,17 @@ if [ $HTTP = YES ]; then
. auto/module
fi
if [ $HTTP_PROXY = YES -a $HTTP_V2 = YES ]; then
ngx_module_name=ngx_http_proxy_v2_module
ngx_module_incs=
ngx_module_deps=
ngx_module_srcs=src/http/modules/ngx_http_proxy_v2_module.c
ngx_module_libs=
ngx_module_link=$HTTP_V2
. auto/module
fi
if [ $HTTP_PERL != NO ]; then
ngx_module_name=ngx_http_perl_module
ngx_module_incs=src/http/modules/perl

View File

@ -185,7 +185,13 @@ ngx_quic_cbs_release_rcd(ngx_ssl_conn_t *ssl_conn, size_t bytes_read, void *arg)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic ngx_quic_cbs_release_rcd len:%uz", bytes_read);
/* already closed on handshake failure */
qc = ngx_quic_get_connection(c);
if (qc == NULL) {
return 1;
}
ctx = ngx_quic_get_send_ctx(qc, qc->read_level);
cl = ngx_quic_read_buffer(c, &ctx->crypto, bytes_read);

View File

@ -8,6 +8,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_http_proxy_module.h>
#define NGX_HTTP_PROXY_COOKIE_SECURE 0x0001
@ -23,11 +24,6 @@
#define NGX_HTTP_PROXY_COOKIE_SAMESITE_OFF 0x0400
typedef struct {
ngx_array_t caches; /* ngx_http_file_cache_t * */
} ngx_http_proxy_main_conf_t;
typedef struct ngx_http_proxy_rewrite_s ngx_http_proxy_rewrite_t;
typedef ngx_int_t (*ngx_http_proxy_rewrite_pt)(ngx_http_request_t *r,
@ -61,96 +57,6 @@ typedef struct {
} ngx_http_proxy_cookie_flags_t;
typedef struct {
ngx_str_t key_start;
ngx_str_t schema;
ngx_str_t host_header;
ngx_str_t port;
ngx_str_t uri;
} ngx_http_proxy_vars_t;
typedef struct {
ngx_array_t *flushes;
ngx_array_t *lengths;
ngx_array_t *values;
ngx_hash_t hash;
} ngx_http_proxy_headers_t;
typedef struct {
ngx_http_upstream_conf_t upstream;
ngx_array_t *body_flushes;
ngx_array_t *body_lengths;
ngx_array_t *body_values;
ngx_str_t body_source;
ngx_http_proxy_headers_t headers;
#if (NGX_HTTP_CACHE)
ngx_http_proxy_headers_t headers_cache;
#endif
ngx_array_t *headers_source;
ngx_array_t *proxy_lengths;
ngx_array_t *proxy_values;
ngx_array_t *redirects;
ngx_array_t *cookie_domains;
ngx_array_t *cookie_paths;
ngx_array_t *cookie_flags;
ngx_http_complex_value_t *method;
ngx_str_t location;
ngx_str_t url;
#if (NGX_HTTP_CACHE)
ngx_http_complex_value_t cache_key;
#endif
ngx_http_proxy_vars_t vars;
ngx_flag_t redirect;
ngx_uint_t http_version;
ngx_uint_t headers_hash_max_size;
ngx_uint_t headers_hash_bucket_size;
#if (NGX_HTTP_SSL)
ngx_uint_t ssl;
ngx_uint_t ssl_protocols;
ngx_str_t ssl_ciphers;
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
ngx_array_t *ssl_conf_commands;
#endif
} ngx_http_proxy_loc_conf_t;
typedef struct {
ngx_http_status_t status;
ngx_http_chunked_t chunked;
ngx_http_proxy_vars_t vars;
off_t internal_body_length;
ngx_chain_t *free;
ngx_chain_t *busy;
ngx_buf_t *trailers;
unsigned head:1;
unsigned internal_chunked:1;
unsigned header_sent:1;
} ngx_http_proxy_ctx_t;
static ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r,
ngx_http_proxy_ctx_t *ctx, ngx_http_proxy_loc_conf_t *plcf);
#if (NGX_HTTP_CACHE)
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);
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);
@ -178,15 +84,14 @@ static ngx_int_t ngx_http_proxy_port_variable(ngx_http_request_t *r,
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);
static ngx_int_t ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
ngx_table_elt_t *h, size_t prefix);
static ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r,
ngx_table_elt_t *h);
static ngx_int_t ngx_http_proxy_parse_cookie(ngx_str_t *value,
ngx_array_t *attrs);
static ngx_int_t ngx_http_proxy_rewrite_cookie_value(ngx_http_request_t *r,
@ -293,6 +198,9 @@ static ngx_conf_post_t ngx_http_proxy_ssl_conf_command_post =
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"), NGX_HTTP_VERSION_20 },
#endif
{ ngx_null_string, 0 }
};
@ -840,8 +748,8 @@ 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_host") },
{ ngx_string("Connection"), ngx_string("close") },
{ ngx_string("Host"), ngx_string("$proxy_internal_host") },
{ 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("") },
@ -868,8 +776,8 @@ 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_host") },
{ ngx_string("Connection"), ngx_string("close") },
{ ngx_string("Host"), ngx_string("$proxy_internal_host") },
{ 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("") },
@ -904,6 +812,14 @@ static ngx_http_variable_t ngx_http_proxy_vars[] = {
{ ngx_string("proxy_add_via"), NULL, NULL, 0, NGX_HTTP_VAR_NOHASH, 0 },
#endif
{ ngx_string("proxy_internal_host"), NULL,
ngx_http_proxy_host_variable, 1,
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 },
{ 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 },
@ -962,6 +878,14 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
ngx_http_proxy_main_conf_t *pmcf;
#endif
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
#if (NGX_HTTP_V2)
if (plcf->http_version == NGX_HTTP_VERSION_20) {
return ngx_http_proxy_v2_handler(r);
}
#endif
if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
@ -971,9 +895,9 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ngx_http_set_ctx(r, ctx, ngx_http_proxy_module);
ctx->legacy = 1;
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
ngx_http_set_ctx(r, ctx, ngx_http_proxy_module);
u = r->upstream;
@ -1050,7 +974,7 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
}
static ngx_int_t
ngx_int_t
ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
ngx_http_proxy_loc_conf_t *plcf)
{
@ -1154,7 +1078,7 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
#if (NGX_HTTP_CACHE)
static ngx_int_t
ngx_int_t
ngx_http_proxy_create_key(ngx_http_request_t *r)
{
size_t len, loc_len;
@ -2119,7 +2043,7 @@ ngx_http_proxy_input_filter_init(void *data)
/* chunked */
u->pipe->input_filter = ngx_http_proxy_chunked_filter;
u->pipe->length = 3; /* "0" LF LF */
u->pipe->length = 5; /* "0" CRLF CRLF */
u->input_filter = ngx_http_proxy_non_buffered_chunked_filter;
u->length = 1;
@ -2768,6 +2692,11 @@ ngx_http_proxy_host_variable(ngx_http_request_t *r,
return NGX_OK;
}
if (data == 1 && !ctx->legacy) {
v->not_found = 1;
return NGX_OK;
}
v->len = ctx->vars.host_header.len;
v->valid = 1;
v->no_cacheable = 0;
@ -2848,6 +2777,29 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
}
static ngx_int_t
ngx_http_proxy_internal_connection_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
ngx_http_proxy_ctx_t *ctx;
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (ctx == NULL || !ctx->legacy) {
v->not_found = 1;
return NGX_OK;
}
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
ngx_str_set(v, "close");
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)
@ -2901,7 +2853,7 @@ ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r,
}
static ngx_int_t
ngx_int_t
ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
size_t prefix)
{
@ -2933,7 +2885,7 @@ ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r, ngx_table_elt_t *h,
}
static ngx_int_t
ngx_int_t
ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r, ngx_table_elt_t *h)
{
u_char *p;
@ -3578,6 +3530,7 @@ 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;
@ -4153,6 +4106,7 @@ 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,
@ -4185,6 +4139,7 @@ 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;
}
return NGX_CONF_OK;
@ -4237,6 +4192,12 @@ 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;
}
s = ngx_array_push(&headers_merged);
if (s == NULL) {
return NGX_ERROR;

View File

@ -0,0 +1,127 @@
/*
* Copyright (C) Igor Sysoev
* Copyright (C) Nginx, Inc.
*/
#ifndef _NGX_HTTP_PROXY_H_INCLUDED_
#define _NGX_HTTP_PROXY_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
typedef struct {
ngx_array_t caches; /* ngx_http_file_cache_t * */
} ngx_http_proxy_main_conf_t;
typedef struct {
ngx_str_t key_start;
ngx_str_t schema;
ngx_str_t host_header;
ngx_str_t port;
ngx_str_t uri;
} ngx_http_proxy_vars_t;
typedef struct {
ngx_array_t *flushes;
ngx_array_t *lengths;
ngx_array_t *values;
ngx_hash_t hash;
} ngx_http_proxy_headers_t;
typedef struct {
ngx_http_upstream_conf_t upstream;
ngx_array_t *body_flushes;
ngx_array_t *body_lengths;
ngx_array_t *body_values;
ngx_str_t body_source;
ngx_http_proxy_headers_t headers;
#if (NGX_HTTP_CACHE)
ngx_http_proxy_headers_t headers_cache;
#endif
ngx_array_t *headers_source;
ngx_uint_t host_set;
ngx_array_t *proxy_lengths;
ngx_array_t *proxy_values;
ngx_array_t *redirects;
ngx_array_t *cookie_domains;
ngx_array_t *cookie_paths;
ngx_array_t *cookie_flags;
ngx_http_complex_value_t *method;
ngx_str_t location;
ngx_str_t url;
#if (NGX_HTTP_CACHE)
ngx_http_complex_value_t cache_key;
#endif
ngx_http_proxy_vars_t vars;
ngx_flag_t redirect;
ngx_uint_t http_version;
ngx_uint_t headers_hash_max_size;
ngx_uint_t headers_hash_bucket_size;
#if (NGX_HTTP_SSL || NGX_COMPAT)
ngx_uint_t ssl;
ngx_uint_t ssl_protocols;
ngx_str_t ssl_ciphers;
ngx_uint_t ssl_verify_depth;
ngx_str_t ssl_trusted_certificate;
ngx_str_t ssl_crl;
ngx_array_t *ssl_conf_commands;
#endif
} ngx_http_proxy_loc_conf_t;
typedef struct {
ngx_http_status_t status;
ngx_http_chunked_t chunked;
ngx_http_proxy_vars_t vars;
off_t internal_body_length;
ngx_chain_t *free;
ngx_chain_t *busy;
ngx_buf_t *trailers;
unsigned head:1;
unsigned internal_chunked:1;
unsigned header_sent:1;
unsigned legacy:1;
} ngx_http_proxy_ctx_t;
ngx_int_t ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
ngx_http_proxy_loc_conf_t *plcf);
#if (NGX_HTTP_CACHE)
ngx_int_t ngx_http_proxy_create_key(ngx_http_request_t *r);
#endif
ngx_int_t ngx_http_proxy_rewrite_redirect(ngx_http_request_t *r,
ngx_table_elt_t *h, size_t prefix);
ngx_int_t ngx_http_proxy_rewrite_cookie(ngx_http_request_t *r,
ngx_table_elt_t *h);
#if (NGX_HTTP_V2)
ngx_int_t ngx_http_proxy_v2_handler(ngx_http_request_t *r);
#endif
extern ngx_module_t ngx_http_proxy_module;
#endif /* _NGX_HTTP_PROXY_H_INCLUDED_ */

File diff suppressed because it is too large Load Diff

View File

@ -2254,12 +2254,6 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
case CR:
state = sw_last_chunk_extension_almost_done;
break;
case LF:
if (keep_trailers) {
goto done;
}
state = sw_trailer;
break;
case ';':
case ' ':
case '\t':
@ -2276,9 +2270,6 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
case CR:
state = sw_chunk_extension_almost_done;
break;
case LF:
state = sw_chunk_data;
break;
case ';':
case ' ':
case '\t':
@ -2296,7 +2287,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
state = sw_chunk_extension_almost_done;
break;
case LF:
state = sw_chunk_data;
goto invalid;
}
break;
@ -2316,9 +2307,6 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
case CR:
state = sw_after_data_almost_done;
break;
case LF:
state = sw_chunk_start;
break;
default:
goto invalid;
}
@ -2337,10 +2325,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
state = sw_last_chunk_extension_almost_done;
break;
case LF:
if (keep_trailers) {
goto done;
}
state = sw_trailer;
goto invalid;
}
break;
@ -2360,7 +2345,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
state = sw_trailer_almost_done;
break;
case LF:
goto done;
goto invalid;
default:
state = sw_trailer_header;
}
@ -2378,7 +2363,7 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
state = sw_trailer_header_almost_done;
break;
case LF:
state = sw_trailer;
goto invalid;
}
break;
@ -2404,35 +2389,45 @@ data:
switch (state) {
case sw_chunk_start:
ctx->length = 3 /* "0" LF LF */;
ctx->length = 5 /* "0" CRLF CRLF */;
break;
case sw_chunk_size:
ctx->length = 1 /* LF */
+ (ctx->size ? ctx->size + 4 /* LF "0" LF LF */
: 1 /* LF */);
ctx->length = 2 /* CRLF */
+ (ctx->size ? ctx->size + 7 /* CRLF "0" CRLF CRLF */
: 2 /* CRLF */);
break;
case sw_chunk_extension:
ctx->length = 2 /* CRLF */ + ctx->size + 7 /* CRLF "0" CRLF CRLF */;
break;
case sw_chunk_extension_almost_done:
ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */;
ctx->length = 1 /* LF */ + ctx->size + 7 /* CRLF "0" CRLF CRLF */;
break;
case sw_chunk_data:
ctx->length = ctx->size + 4 /* LF "0" LF LF */;
ctx->length = ctx->size + 7 /* CRLF "0" CRLF CRLF */;
break;
case sw_after_data:
ctx->length = 7 /* CRLF "0" CRLF CRLF */;
break;
case sw_after_data_almost_done:
ctx->length = 4 /* LF "0" LF LF */;
ctx->length = 6 /* LF "0" CRLF CRLF */;
break;
case sw_last_chunk_extension:
ctx->length = 4 /* CRLF CRLF */;
break;
case sw_last_chunk_extension_almost_done:
ctx->length = 2 /* LF LF */;
ctx->length = 3 /* LF CRLF */;
break;
case sw_trailer:
ctx->length = 2 /* CRLF */;
break;
case sw_trailer_almost_done:
ctx->length = 1 /* LF */;
break;
case sw_trailer_header:
ctx->length = 4 /* CRLF CRLF */;
break;
case sw_trailer_header_almost_done:
ctx->length = 2 /* LF LF */;
ctx->length = 3 /* LF CRLF */;
break;
}

View File

@ -1771,6 +1771,23 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
}
}
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
if (u->ssl_alpn_protocol.len) {
if (SSL_set_alpn_protos(c->ssl->connection, u->ssl_alpn_protocol.data,
u->ssl_alpn_protocol.len)
!= 0)
{
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
"SSL_set_alpn_protos() failed");
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
}
#endif
if (u->conf->ssl_session_reuse) {
c->ssl->save_session = ngx_http_upstream_ssl_save_session;

View File

@ -390,6 +390,7 @@ struct ngx_http_upstream_s {
#if (NGX_HTTP_SSL || NGX_COMPAT)
ngx_str_t ssl_name;
ngx_str_t ssl_alpn_protocol;
#endif
ngx_http_cleanup_pt *cleanup;