Skip to content

HTTP/2 to upstream #771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion auto/modules
Original file line number Diff line number Diff line change
Expand Up @@ -726,10 +726,11 @@ if [ $HTTP = YES ]; then

if [ $HTTP_PROXY = YES ]; then
have=NGX_HTTP_X_FORWARDED_FOR . auto/have
have=NGX_HTTP_PROXY . auto/have

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
Expand Down Expand Up @@ -781,6 +782,17 @@ if [ $HTTP = YES ]; then
. auto/module
fi

if [ $HTTP_V2 = YES ]; then
ngx_module_name=ngx_http_v2_proxy_module
ngx_module_incs=
ngx_module_deps=
ngx_module_srcs=src/http/v2/ngx_http_v2_proxy_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
Expand Down
193 changes: 54 additions & 139 deletions src/http/modules/ngx_http_proxy_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -23,134 +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,
ngx_str_t *value, size_t prefix, size_t len,
ngx_http_proxy_rewrite_t *pr);

struct ngx_http_proxy_rewrite_s {
ngx_http_proxy_rewrite_pt handler;

union {
ngx_http_complex_value_t complex;
#if (NGX_PCRE)
ngx_http_regex_t *regex;
#endif
} pattern;

ngx_http_complex_value_t replacement;
};


typedef struct {
union {
ngx_http_complex_value_t complex;
#if (NGX_PCRE)
ngx_http_regex_t *regex;
#endif
} cookie;

ngx_array_t flags_values;
ngx_uint_t regex;
} 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);
Expand Down Expand Up @@ -178,15 +51,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,
Expand Down Expand Up @@ -293,6 +165,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.0"), NGX_HTTP_VERSION_20 },
#endif
{ ngx_null_string, 0 }
};

Expand Down Expand Up @@ -841,7 +716,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_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("") },
Expand Down Expand Up @@ -904,6 +779,10 @@ 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_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 },
Expand Down Expand Up @@ -962,6 +841,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_v2_proxy_handler(r);
}
#endif

if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
Expand All @@ -971,9 +858,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->connection_type = NGX_HTTP_CONNECTION_CLOSE;

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;

Expand Down Expand Up @@ -1050,7 +937,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)
{
Expand Down Expand Up @@ -1154,7 +1041,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;
Expand Down Expand Up @@ -2847,6 +2734,34 @@ 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->connection_type == 0) {
v->not_found = 1;
return NGX_OK;
}

v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;

if (ctx->connection_type == NGX_HTTP_CONNECTION_CLOSE) {
ngx_str_set(v, "close");

} else if (ctx->connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) {
ngx_str_set(v, "keep-alive");
}

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)
Expand Down Expand Up @@ -2900,7 +2815,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)
{
Expand Down Expand Up @@ -2932,7 +2847,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;
Expand Down
Loading