25 ngx_http_regex_t *regex;
101 static ngx_int_t ngx_http_proxy_input_filter_init(
void *data);
106 static ngx_int_t ngx_http_proxy_non_buffered_copy_filter(
void *data,
108 static ngx_int_t ngx_http_proxy_non_buffered_chunked_filter(
void *data,
134 static void *ngx_http_proxy_create_loc_conf(
ngx_conf_t *cf);
135 static char *ngx_http_proxy_merge_loc_conf(
ngx_conf_t *cf,
136 void *parent,
void *child);
157 static char *ngx_http_proxy_lowat_check(
ngx_conf_t *cf,
void *post,
void *data);
170 { ngx_http_proxy_lowat_check };
209 ngx_http_proxy_redirect,
216 ngx_http_proxy_cookie_domain,
223 ngx_http_proxy_cookie_path,
230 ngx_http_proxy_store,
282 &ngx_http_proxy_lowat_post },
305 {
ngx_string(
"proxy_headers_hash_bucket_size"),
372 ngx_http_proxy_cache,
379 ngx_http_proxy_cache_key,
389 &ngx_http_proxy_module },
424 &ngx_http_proxy_next_upstream_masks },
475 &ngx_http_proxy_next_upstream_masks },
503 &ngx_http_proxy_http_version },
521 ngx_http_proxy_add_variables,
530 ngx_http_proxy_create_loc_conf,
531 ngx_http_proxy_merge_loc_conf
537 &ngx_http_proxy_module_ctx,
538 ngx_http_proxy_commands,
551 static char ngx_http_proxy_version[] =
" HTTP/1.0" CRLF;
552 static char ngx_http_proxy_version_11[] =
" HTTP/1.1" CRLF;
567 static ngx_str_t ngx_http_proxy_hide_headers[] = {
604 {
ngx_string(
"proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
607 {
ngx_string(
"proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
610 {
ngx_string(
"proxy_add_x_forwarded_for"), NULL,
617 {
ngx_string(
"proxy_internal_body_length"), NULL,
618 ngx_http_proxy_internal_body_length_variable, 0,
661 if (ngx_http_proxy_eval(r, ctx, plcf) !=
NGX_OK) {
671 u->create_key = ngx_http_proxy_create_key;
691 if (u->
pipe == NULL) {
699 u->
input_filter = ngx_http_proxy_non_buffered_copy_filter;
740 }
else if (proxy.
len > 8
751 "invalid URL prefix in \"%V\"", &proxy);
771 "%s in upstream \"%V\"", url.
err, &url.
url);
794 ngx_http_proxy_set_vars(&url, &ctx->
vars);
841 if (plcf->cache_key.value.data) {
882 +
sizeof(
"?") - 1 + r->
args.
len;
898 p += r->
uri.
len - loc_len + escape;
921 size_t len, uri_len, loc_len, body_len;
961 len = method.
len +
sizeof(ngx_http_proxy_version) - 1 +
sizeof(
CRLF) - 1;
985 +
sizeof(
"?") - 1 + r->
args.
len;
990 "zero length URI to proxy");
1004 while (*(uintptr_t *) le.
ip) {
1006 body_len += lcode(&le);
1020 while (*(uintptr_t *) le.
ip) {
1021 while (*(uintptr_t *) le.
ip) {
1025 le.
ip +=
sizeof(uintptr_t);
1031 header = part->
elts;
1033 for (i = 0; ; i++) {
1035 if (i >= part->
nelts) {
1036 if (part->
next == NULL) {
1041 header = part->
elts;
1051 len += header[
i].
key.
len +
sizeof(
": ") - 1
1052 + header[i].value.len +
sizeof(
CRLF) - 1;
1079 }
else if (unparsed_uri) {
1107 sizeof(ngx_http_proxy_version_11) - 1);
1111 sizeof(ngx_http_proxy_version) - 1);
1123 while (*(uintptr_t *) le.
ip) {
1131 for (len = 0; *(uintptr_t *) le.
ip; len += lcode(&le)) {
1135 e.
skip = (len ==
sizeof(
CRLF) - 1) ? 1 : 0;
1141 le.
ip +=
sizeof(uintptr_t);
1143 while (*(uintptr_t *) e.
ip) {
1147 e.
ip +=
sizeof(uintptr_t);
1155 header = part->
elts;
1157 for (i = 0; ; i++) {
1159 if (i >= part->
nelts) {
1160 if (part->
next == NULL) {
1165 header = part->
elts;
1177 *b->
last++ =
':'; *b->
last++ =
' ';
1185 "http proxy header: \"%V: %V\"",
1198 while (*(uintptr_t *) e.
ip) {
1207 "http proxy header:\n\"%*s\"",
1224 if (cl->
next == NULL) {
1295 #if (NGX_HTTP_CACHE)
1305 "upstream sent no valid HTTP/1.0 header");
1337 "http proxy status %ui \"%V\"",
1346 return ngx_http_proxy_process_header(r);
1409 "http proxy header: \"%V: %V\"",
1420 "http proxy header done");
1434 ngx_hash(
's',
'e'),
'r'),
'v'),
'e'),
'r');
1496 "upstream sent invalid header");
1504 ngx_http_proxy_input_filter_init(
void *data)
1518 "http proxy filter init s:%d h:%d c:%d l:%O",
1541 u->
input_filter = ngx_http_proxy_non_buffered_chunked_filter;
1621 }
else if (p->
length < 0) {
1626 "upstream sent more data than specified in "
1627 "\"Content-Length\" header");
1708 "input buf #%d %p", b->
num, b->
pos);
1748 "upstream sent invalid chunked response");
1754 "http proxy chunked state %d, length %d",
1762 "input buf %p %z", b->
pos, b->
last - b->
pos);
1778 ngx_http_proxy_non_buffered_copy_filter(
void *data, ssize_t bytes)
1824 ngx_http_proxy_non_buffered_chunked_filter(
void *data, ssize_t bytes)
1886 "http proxy out buf %p %z",
1909 "upstream sent invalid chunked response");
1928 "http proxy in memory %p-%p %uz",
1952 "abort http proxy request");
1962 "finalize http proxy request");
2032 for (i = 0; i < n; i++) {
2033 len += h[
i]->
value.
len +
sizeof(
", ") - 1;
2052 for (i = 0; i < n; i++) {
2054 *p++ =
','; *p++ =
' ';
2082 if (v->
data == NULL) {
2113 rc = pr[
i].
handler(r, h, prefix, len, &pr[i]);
2147 rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 7,
2163 rc = ngx_http_proxy_rewrite_cookie_value(r, h, p + 5,
2193 len = p ? (size_t) (p - value) : (h->value.len - prefix);
2195 pr = rewrites->
elts;
2197 for (i = 0; i < rewrites->
nelts; i++) {
2198 rc = pr[
i].
handler(r, h, prefix, len, &pr[i]);
2219 if (pattern.
len > len
2230 return ngx_http_proxy_rewrite(r, h, prefix, pattern.
len, &replacement);
2245 if (ngx_http_regex_exec(r, pr->
pattern.regex, &pattern) !=
NGX_OK) {
2253 if (prefix == 0 && h->
value.
len == len) {
2254 h->
value = replacement;
2258 return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement);
2291 return ngx_http_proxy_rewrite(r, h, prefix, len, &replacement);
2304 if (replacement->
len > len) {
2338 for (v = ngx_http_proxy_vars; v->
name.
len; v++) {
2353 ngx_http_proxy_create_loc_conf(
ngx_conf_t *cf)
2409 #if (NGX_HTTP_CACHE)
2448 ngx_http_proxy_merge_loc_conf(
ngx_conf_t *cf,
void *parent,
void *child)
2503 "there must be at least 2 \"proxy_buffers\"");
2509 if (size < conf->upstream.bufs.size) {
2527 "\"proxy_busy_buffers_size\" must be equal to or greater than "
2528 "the maximum of the value of \"proxy_buffer_size\" and "
2529 "one of the \"proxy_buffers\"");
2538 "\"proxy_busy_buffers_size\" must be less than "
2539 "the size of all \"proxy_buffers\" minus one buffer");
2558 "\"proxy_temp_file_write_size\" must be equal to or greater "
2559 "than the maximum of the value of \"proxy_buffer_size\" and "
2560 "one of the \"proxy_buffers\"");
2580 "\"proxy_max_temp_file_size\" must be equal to zero to disable "
2581 "temporary files usage or must be equal to or greater than "
2582 "the maximum of the value of \"proxy_buffer_size\" and "
2583 "one of the \"proxy_buffers\"");
2607 &ngx_http_proxy_temp_path)
2614 #if (NGX_HTTP_CACHE)
2625 "\"proxy_cache\" zone \"%V\" is unknown",
2648 if (conf->
upstream.cache_methods == 0) {
2655 prev->
upstream.cache_bypass, NULL);
2662 "\"proxy_no_cache\" functionality has been changed in 0.8.46, "
2663 "now it should be used together with \"proxy_cache_bypass\"");
2669 if (conf->cache_key.value.data == NULL) {
2670 conf->cache_key = prev->cache_key;
2677 prev->
upstream.cache_lock_timeout, 5000);
2700 prev->
upstream.ssl_session_reuse, 1);
2729 pr->
handler = ngx_http_proxy_rewrite_complex_handler;
2778 hash.
name =
"proxy_headers_hash";
2781 &prev->
upstream, ngx_http_proxy_hide_headers, &hash)
2800 clcf->
handler = ngx_http_proxy_handler;
2828 if (ngx_http_proxy_merge_headers(cf, conf, prev) !=
NGX_OK) {
2900 #if (NGX_HTTP_CACHE)
2902 h = conf->
upstream.cache ? ngx_http_proxy_cache_headers:
2903 ngx_http_proxy_headers;
2906 h = ngx_http_proxy_headers;
2923 src = headers_merged.
elts;
2924 for (i = 0; i < headers_merged.
nelts; i++) {
2943 src = headers_merged.
elts;
2944 for (i = 0; i < headers_merged.
nelts; i++) {
2953 hk->
value = (
void *) 1;
2955 if (src[i].value.len == 0) {
2968 copy->
len = src[
i].
key.
len +
sizeof(
": ") - 1
2969 + src[i].value.len +
sizeof(
CRLF) - 1;
2973 + src[i].key.
len +
sizeof(
": ") - 1
2975 +
sizeof(uintptr_t) - 1)
2976 & ~(
sizeof(uintptr_t) - 1);
2984 copy->
len = src[
i].
key.
len +
sizeof(
": ") - 1
2985 + src[i].value.len +
sizeof(
CRLF) - 1;
2990 *p++ =
':'; *p++ =
' ';
3003 copy->
len = src[
i].
key.
len +
sizeof(
": ") - 1;
3007 + src[i].key.
len +
sizeof(
": ") - 1 +
sizeof(uintptr_t) - 1)
3008 & ~(
sizeof(uintptr_t) - 1);
3016 copy->
len = src[
i].
key.
len +
sizeof(
": ") - 1;
3020 *p++ =
':'; *p =
' ';
3048 +
sizeof(
CRLF) - 1 +
sizeof(uintptr_t) - 1)
3049 & ~(
sizeof(uintptr_t) - 1);
3068 *code = (uintptr_t) NULL;
3075 *code = (uintptr_t) NULL;
3083 *code = (uintptr_t) NULL;
3090 hash.
name =
"proxy_headers_hash";
3112 return "is duplicate";
3117 clcf->
handler = ngx_http_proxy_handler;
3146 if (ngx_http_proxy_set_ssl(cf, plcf) !=
NGX_OK) {
3161 if (ngx_http_proxy_set_ssl(cf, plcf) !=
NGX_OK) {
3169 "https protocol requires SSL support");
3195 ngx_http_proxy_set_vars(&u, &plcf->
vars);
3207 "\"proxy_pass\" cannot have URI part in "
3208 "location given by regular expression, "
3209 "or inside named location, "
3210 "or inside \"if\" statement, "
3211 "or inside \"limit_except\" block");
3249 if (
ngx_strcmp(value[1].data,
"false") == 0) {
3251 "invalid parameter \"false\", use \"off\" instead");
3257 if (
ngx_strcmp(value[1].data,
"default") != 0) {
3259 "invalid parameter \"%V\"", &value[1]);
3277 if (
ngx_strcmp(value[1].data,
"default") == 0) {
3280 "\"proxy_redirect default\" cannot be used "
3281 "with \"proxy_pass\" directive with variables");
3287 "\"proxy_redirect default\" should be placed "
3288 "after the \"proxy_pass\" directive");
3292 pr->
handler = ngx_http_proxy_rewrite_complex_handler;
3322 if (value[1].data[0] ==
'~') {
3326 if (value[1].data[0] ==
'*') {
3330 if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) !=
NGX_OK) {
3335 if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 0) !=
NGX_OK) {
3345 ccv.
value = &value[1];
3352 pr->
handler = ngx_http_proxy_rewrite_complex_handler;
3359 ccv.
value = &value[2];
3393 "invalid parameter \"%V\"", &value[1]);
3410 if (value[1].data[0] ==
'~') {
3414 if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) !=
NGX_OK) {
3420 if (value[1].data[0] ==
'.') {
3428 ccv.
value = &value[1];
3435 pr->
handler = ngx_http_proxy_rewrite_domain_handler;
3437 if (value[2].data[0] ==
'.') {
3446 ccv.
value = &value[2];
3480 "invalid parameter \"%V\"", &value[1]);
3497 if (value[1].data[0] ==
'~') {
3501 if (value[1].data[0] ==
'*') {
3505 if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 1) !=
NGX_OK) {
3510 if (ngx_http_proxy_rewrite_regex(cf, pr, &value[1], 0) !=
NGX_OK) {
3520 ccv.
value = &value[1];
3527 pr->
handler = ngx_http_proxy_rewrite_complex_handler;
3533 ccv.
value = &value[2];
3562 pr->
pattern.regex = ngx_http_regex_compile(cf, &rc);
3563 if (pr->
pattern.regex == NULL) {
3567 pr->
handler = ngx_http_proxy_rewrite_regex_handler;
3574 "using regex \"%V\" requires PCRE library", regex);
3592 return "is duplicate";
3602 #if (NGX_HTTP_CACHE)
3607 return "is incompatible with \"proxy_cache\"";
3638 #if (NGX_HTTP_CACHE)
3650 return "is duplicate";
3659 return "is incompatible with \"proxy_store\"";
3663 &ngx_http_proxy_module);
3664 if (plcf->
upstream.cache == NULL) {
3682 if (plcf->cache_key.value.data) {
3683 return "is duplicate";
3689 ccv.
value = &value[1];
3703 ngx_http_proxy_lowat_check(
ngx_conf_t *cf,
void *post,
void *data)
3710 "\"proxy_send_lowat\" must be less than %d "
3711 "(sysctl net.inet.tcp.sendspace)",
3717 #elif !(NGX_HAVE_SO_SNDLOWAT)
3721 "\"proxy_send_lowat\" is not supported, ignored");
3771 if (u->
family != AF_UNIX) {