mirror of
https://github.com/nginx/nginx.git
synced 2024-11-21 16:28:40 +00:00
Merged with the default branch.
This commit is contained in:
commit
c64e2ec1e9
1
.hgtags
1
.hgtags
@ -467,3 +467,4 @@ bfbc52374adcbf2f9060afd62de940f6fab3bba5 release-1.21.2
|
||||
39be8a682c58308d9399cddd57e37f9fdb7bdf3e release-1.21.4
|
||||
d986378168fd4d70e0121cabac274c560cca9bdf release-1.21.5
|
||||
714eb4b2c09e712fb2572a2164ce2bf67638ccac release-1.21.6
|
||||
5da2c0902e8e2aa4534008a582a60c61c135960e release-1.23.0
|
||||
|
2
README
2
README
@ -15,7 +15,7 @@ Experimental QUIC support for nginx
|
||||
|
||||
The code is developed in a separate "quic" branch available
|
||||
at https://hg.nginx.org/nginx-quic. Currently it is based
|
||||
on nginx mainline 1.21.x. We merge new nginx releases into
|
||||
on nginx mainline 1.23.x. We merge new nginx releases into
|
||||
this branch regularly.
|
||||
|
||||
The project code base is under the same BSD license as nginx.
|
||||
|
@ -110,7 +110,7 @@ case "$NGX_MACHINE" in
|
||||
NGX_MACH_CACHE_LINE=64
|
||||
;;
|
||||
|
||||
aarch64 )
|
||||
aarch64 | arm64)
|
||||
have=NGX_ALIGNMENT value=16 . auto/define
|
||||
NGX_MACH_CACHE_LINE=64
|
||||
;;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,107 @@
|
||||
<change_log title="nginx">
|
||||
|
||||
|
||||
<changes ver="1.23.0" date="2022-06-21">
|
||||
|
||||
<change>
|
||||
<para lang="ru">
|
||||
Изменение во внутреннем API:
|
||||
теперь строки заголовков представлены связными списками.
|
||||
</para>
|
||||
<para lang="en">
|
||||
Change in internal API:
|
||||
now header lines are represented as linked lists.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
теперь nginx объединяет произвольные строки заголовков с одинаковыми именами
|
||||
при отправке на FastCGI-, SCGI- и uwsgi-бэкенды,
|
||||
в методе $r->header_in() модуля ngx_http_perl_module,
|
||||
и при доступе через переменные "$http_...", "$sent_http_...",
|
||||
"$sent_trailer_...", "$upstream_http_..." и "$upstream_trailer_...".
|
||||
</para>
|
||||
<para lang="en">
|
||||
now nginx combines arbitrary header lines with identical names
|
||||
when sending to FastCGI, SCGI, and uwsgi backends,
|
||||
in the $r->header_in() method of the ngx_http_perl_module,
|
||||
and during lookup of the "$http_...", "$sent_http_...",
|
||||
"$sent_trailer_...", "$upstream_http_...", and "$upstream_trailer_..."
|
||||
variables.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
если в заголовке ответа бэкенда было несколько строк "Vary",
|
||||
при кэшировании nginx учитывал только последнюю из них.
|
||||
</para>
|
||||
<para lang="en">
|
||||
if there were multiple "Vary" header lines in the backend response,
|
||||
nginx only used the last of them when caching.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
если в заголовке ответа бэкенда было несколько строк "WWW-Authenticate"
|
||||
и использовался перехват ошибок с кодом 401 от бэкенда
|
||||
или директива auth_request,
|
||||
nginx пересылал клиенту только первую из этих строк.
|
||||
</para>
|
||||
<para lang="en">
|
||||
if there were multiple "WWW-Authenticate" header lines in the backend response
|
||||
and errors with code 401 were intercepted
|
||||
or the "auth_request" directive was used,
|
||||
nginx only sent the first of the header lines to the client.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="change">
|
||||
<para lang="ru">
|
||||
уровень логгирования ошибок SSL "application data after close notify"
|
||||
понижен с уровня crit до info.
|
||||
</para>
|
||||
<para lang="en">
|
||||
the logging level of the "application data after close notify" SSL errors
|
||||
has been lowered from "crit" to "info".
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
соединения могли зависать, если nginx был собран на Linux 2.6.17 и новее,
|
||||
а использовался на системах без поддержки EPOLLRDHUP, в частности, на
|
||||
системах с эмуляцией epoll;
|
||||
ошибка появилась в 1.17.5.<br/>
|
||||
Спасибо Marcus Ball.
|
||||
</para>
|
||||
<para lang="en">
|
||||
connections might hang if nginx was built on Linux 2.6.17 or newer,
|
||||
but was used on systems without EPOLLRDHUP support, notably with epoll
|
||||
emulation layers;
|
||||
the bug had appeared in 1.17.5.<br/>
|
||||
Thanks to Marcus Ball.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
<change type="bugfix">
|
||||
<para lang="ru">
|
||||
nginx не кэшировал ответ,
|
||||
если строка заголовка ответа "Expires" запрещала кэширование,
|
||||
а последующая строка заголовка "Cache-Control" разрешала кэширование.
|
||||
</para>
|
||||
<para lang="en">
|
||||
nginx did not cache the response
|
||||
if the "Expires" response header line disabled caching,
|
||||
but following "Cache-Control" header line enabled caching.
|
||||
</para>
|
||||
</change>
|
||||
|
||||
</changes>
|
||||
|
||||
|
||||
<changes ver="1.21.6" date="2022-01-25">
|
||||
|
||||
<change type="bugfix">
|
||||
|
@ -6,8 +6,8 @@ TEMP = tmp
|
||||
|
||||
CC = cl
|
||||
OBJS = objs.msvc8
|
||||
OPENSSL = openssl-1.1.1m
|
||||
ZLIB = zlib-1.2.11
|
||||
OPENSSL = openssl-1.1.1p
|
||||
ZLIB = zlib-1.2.12
|
||||
PCRE = pcre2-10.39
|
||||
|
||||
|
||||
@ -15,12 +15,6 @@ release: export
|
||||
|
||||
mv $(TEMP)/$(NGINX)/auto/configure $(TEMP)/$(NGINX)
|
||||
|
||||
# delete incomplete sources
|
||||
rm $(TEMP)/$(NGINX)/src/event/ngx_event_acceptex.c
|
||||
rm $(TEMP)/$(NGINX)/src/event/ngx_event_connectex.c
|
||||
rm $(TEMP)/$(NGINX)/src/event/modules/ngx_iocp_module.*
|
||||
rm -r $(TEMP)/$(NGINX)/src/os/win32
|
||||
|
||||
mv $(TEMP)/$(NGINX)/docs/text/LICENSE $(TEMP)/$(NGINX)
|
||||
mv $(TEMP)/$(NGINX)/docs/text/README $(TEMP)/$(NGINX)
|
||||
mv $(TEMP)/$(NGINX)/docs/html $(TEMP)/$(NGINX)
|
||||
|
@ -9,8 +9,8 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1021007
|
||||
#define NGINX_VERSION "1.21.7"
|
||||
#define nginx_version 1023000
|
||||
#define NGINX_VERSION "1.23.0"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
@ -89,12 +89,15 @@ typedef struct {
|
||||
} ngx_hash_keys_arrays_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
typedef struct ngx_table_elt_s ngx_table_elt_t;
|
||||
|
||||
struct ngx_table_elt_s {
|
||||
ngx_uint_t hash;
|
||||
ngx_str_t key;
|
||||
ngx_str_t value;
|
||||
u_char *lowcase_key;
|
||||
} ngx_table_elt_t;
|
||||
ngx_table_elt_t *next;
|
||||
};
|
||||
|
||||
|
||||
void *ngx_hash_find(ngx_hash_t *hash, ngx_uint_t key, u_char *name, size_t len);
|
||||
|
@ -1389,6 +1389,7 @@ ngx_resolver_send_tcp_query(ngx_resolver_t *r, ngx_resolver_connection_t *rec,
|
||||
|
||||
rec->tcp->data = rec;
|
||||
rec->tcp->write->handler = ngx_resolver_tcp_write;
|
||||
rec->tcp->write->cancelable = 1;
|
||||
rec->tcp->read->handler = ngx_resolver_tcp_read;
|
||||
rec->tcp->read->resolver = 1;
|
||||
|
||||
|
@ -339,6 +339,7 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
|
||||
*p = '"';
|
||||
|
||||
r->headers_out.www_authenticate->hash = 1;
|
||||
r->headers_out.www_authenticate->next = NULL;
|
||||
ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate");
|
||||
r->headers_out.www_authenticate->value.data = basic;
|
||||
r->headers_out.www_authenticate->value.len = len;
|
||||
|
@ -101,7 +101,7 @@ ngx_module_t ngx_http_auth_request_module = {
|
||||
static ngx_int_t
|
||||
ngx_http_auth_request_handler(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_table_elt_t *h, *ho;
|
||||
ngx_table_elt_t *h, *ho, **ph;
|
||||
ngx_http_request_t *sr;
|
||||
ngx_http_post_subrequest_t *ps;
|
||||
ngx_http_auth_request_ctx_t *ctx;
|
||||
@ -147,15 +147,21 @@ ngx_http_auth_request_handler(ngx_http_request_t *r)
|
||||
h = sr->upstream->headers_in.www_authenticate;
|
||||
}
|
||||
|
||||
if (h) {
|
||||
ph = &r->headers_out.www_authenticate;
|
||||
|
||||
while (h) {
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
r->headers_out.www_authenticate = ho;
|
||||
*ph = ho;
|
||||
ph = &ho->next;
|
||||
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
return ctx->status;
|
||||
|
@ -1082,6 +1082,7 @@ ngx_http_dav_location(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->next = NULL;
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
|
||||
escape = 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len, NGX_ESCAPE_URI);
|
||||
|
@ -835,14 +835,14 @@ static ngx_int_t
|
||||
ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
{
|
||||
off_t file_pos;
|
||||
u_char ch, *pos, *lowcase_key;
|
||||
u_char ch, sep, *pos, *lowcase_key;
|
||||
size_t size, len, key_len, val_len, padding,
|
||||
allocated;
|
||||
ngx_uint_t i, n, next, hash, skip_empty, header_params;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl, *body;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header, **ignored;
|
||||
ngx_table_elt_t *header, *hn, **ignored;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_script_engine_t e, le;
|
||||
@ -900,7 +900,11 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
allocated = 0;
|
||||
lowcase_key = NULL;
|
||||
|
||||
if (params->number) {
|
||||
if (ngx_http_link_multi_headers(r) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (params->number || r->headers_in.multi) {
|
||||
n = 0;
|
||||
part = &r->headers_in.headers.part;
|
||||
|
||||
@ -930,6 +934,12 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for (n = 0; n < header_params; n++) {
|
||||
if (&header[i] == ignored[n]) {
|
||||
goto next_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (params->number) {
|
||||
if (allocated < header[i].key.len) {
|
||||
allocated = header[i].key.len + 16;
|
||||
@ -959,15 +969,23 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
ignored[header_params++] = &header[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
n += sizeof("HTTP_") - 1;
|
||||
|
||||
} else {
|
||||
n = sizeof("HTTP_") - 1 + header[i].key.len;
|
||||
}
|
||||
|
||||
len += ((n > 127) ? 4 : 1) + ((header[i].value.len > 127) ? 4 : 1)
|
||||
+ n + header[i].value.len;
|
||||
key_len = sizeof("HTTP_") - 1 + header[i].key.len;
|
||||
|
||||
val_len = header[i].value.len;
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
val_len += hn->value.len + 2;
|
||||
ignored[header_params++] = hn;
|
||||
}
|
||||
|
||||
len += ((key_len > 127) ? 4 : 1) + key_len
|
||||
+ ((val_len > 127) ? 4 : 1) + val_len;
|
||||
|
||||
next_length:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1109,7 +1127,7 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
|
||||
for (n = 0; n < header_params; n++) {
|
||||
if (&header[i] == ignored[n]) {
|
||||
goto next;
|
||||
goto next_value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1125,6 +1143,11 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
val_len = header[i].value.len;
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
val_len += hn->value.len + 2;
|
||||
}
|
||||
|
||||
if (val_len > 127) {
|
||||
*b->last++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
|
||||
*b->last++ = (u_char) ((val_len >> 16) & 0xff);
|
||||
@ -1150,13 +1173,34 @@ ngx_http_fastcgi_create_request(ngx_http_request_t *r)
|
||||
*b->last++ = ch;
|
||||
}
|
||||
|
||||
b->last = ngx_copy(b->last, header[i].value.data, val_len);
|
||||
b->last = ngx_copy(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
|
||||
if (header[i].next) {
|
||||
|
||||
if (header[i].key.len == sizeof("Cookie") - 1
|
||||
&& ngx_strncasecmp(header[i].key.data, (u_char *) "Cookie",
|
||||
sizeof("Cookie") - 1)
|
||||
== 0)
|
||||
{
|
||||
sep = ';';
|
||||
|
||||
} else {
|
||||
sep = ',';
|
||||
}
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
*b->last++ = sep;
|
||||
*b->last++ = ' ';
|
||||
b->last = ngx_copy(b->last, hn->value.data, hn->value.len);
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"fastcgi param: \"%*s: %*s\"",
|
||||
key_len, b->last - (key_len + val_len),
|
||||
val_len, b->last - val_len);
|
||||
next:
|
||||
next_value:
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -1963,8 +2007,12 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
||||
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
|
||||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (hh) {
|
||||
rc = hh->handler(r, h, hh->offset);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -327,15 +327,15 @@ static ngx_int_t
|
||||
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx,
|
||||
ngx_addr_t *addr)
|
||||
{
|
||||
ngx_array_t *xfwd;
|
||||
ngx_table_elt_t *xfwd;
|
||||
|
||||
if (ngx_http_geo_real_addr(r, ctx, addr) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
xfwd = &r->headers_in.x_forwarded_for;
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
if (xfwd->nelts > 0 && ctx->proxies != NULL) {
|
||||
if (xfwd != NULL && ctx->proxies != NULL) {
|
||||
(void) ngx_http_get_forwarded_addr(r, addr, xfwd, NULL,
|
||||
ctx->proxies, ctx->proxy_recursive);
|
||||
}
|
||||
|
@ -240,16 +240,16 @@ static u_long
|
||||
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
|
||||
{
|
||||
ngx_addr_t addr;
|
||||
ngx_array_t *xfwd;
|
||||
ngx_table_elt_t *xfwd;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
addr.sockaddr = r->connection->sockaddr;
|
||||
addr.socklen = r->connection->socklen;
|
||||
/* addr.name = r->connection->addr_text; */
|
||||
|
||||
xfwd = &r->headers_in.x_forwarded_for;
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
if (xfwd->nelts > 0 && gcf->proxies != NULL) {
|
||||
if (xfwd != NULL && gcf->proxies != NULL) {
|
||||
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
|
||||
gcf->proxies, gcf->proxy_recursive);
|
||||
}
|
||||
@ -292,7 +292,7 @@ static geoipv6_t
|
||||
ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
|
||||
{
|
||||
ngx_addr_t addr;
|
||||
ngx_array_t *xfwd;
|
||||
ngx_table_elt_t *xfwd;
|
||||
in_addr_t addr4;
|
||||
struct in6_addr addr6;
|
||||
struct sockaddr_in *sin;
|
||||
@ -302,9 +302,9 @@ ngx_http_geoip_addr_v6(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
|
||||
addr.socklen = r->connection->socklen;
|
||||
/* addr.name = r->connection->addr_text; */
|
||||
|
||||
xfwd = &r->headers_in.x_forwarded_for;
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
if (xfwd->nelts > 0 && gcf->proxies != NULL) {
|
||||
if (xfwd != NULL && gcf->proxies != NULL) {
|
||||
(void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
|
||||
gcf->proxies, gcf->proxy_recursive);
|
||||
}
|
||||
|
@ -1891,8 +1891,12 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
|
||||
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
|
||||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (hh) {
|
||||
rc = hh->handler(r, h, hh->offset);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
@ -4902,8 +4906,9 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (glcf->upstream.ssl_certificate) {
|
||||
|
||||
if (glcf->upstream.ssl_certificate
|
||||
&& glcf->upstream.ssl_certificate->value.len)
|
||||
{
|
||||
if (glcf->upstream.ssl_certificate_key == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"grpc_ssl_certificate_key\" is defined "
|
||||
|
@ -280,6 +280,7 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
h->next = NULL;
|
||||
ngx_str_set(&h->key, "Content-Encoding");
|
||||
ngx_str_set(&h->value, "gzip");
|
||||
r->headers_out.content_encoding = h;
|
||||
|
@ -242,6 +242,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
h->next = NULL;
|
||||
ngx_str_set(&h->key, "Content-Encoding");
|
||||
ngx_str_set(&h->value, "gzip");
|
||||
r->headers_out.content_encoding = h;
|
||||
|
@ -329,8 +329,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
time_t now, expires_time, max_age;
|
||||
ngx_str_t value;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *e, *cc, **ccp;
|
||||
ngx_table_elt_t *e, *cc;
|
||||
ngx_http_expires_t expires;
|
||||
|
||||
expires = conf->expires;
|
||||
@ -363,6 +362,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
}
|
||||
|
||||
r->headers_out.expires = e;
|
||||
e->next = NULL;
|
||||
|
||||
e->hash = 1;
|
||||
ngx_str_set(&e->key, "Expires");
|
||||
@ -371,38 +371,29 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
|
||||
e->value.len = len - 1;
|
||||
|
||||
ccp = r->headers_out.cache_control.elts;
|
||||
cc = r->headers_out.cache_control;
|
||||
|
||||
if (ccp == NULL) {
|
||||
|
||||
if (ngx_array_init(&r->headers_out.cache_control, r->pool,
|
||||
1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
if (cc == NULL) {
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
e->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_out.cache_control = cc;
|
||||
cc->next = NULL;
|
||||
|
||||
cc->hash = 1;
|
||||
ngx_str_set(&cc->key, "Cache-Control");
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ccp = cc;
|
||||
|
||||
} else {
|
||||
for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
|
||||
ccp[i]->hash = 0;
|
||||
for (cc = cc->next; cc; cc = cc->next) {
|
||||
cc->hash = 0;
|
||||
}
|
||||
|
||||
cc = ccp[0];
|
||||
cc = r->headers_out.cache_control;
|
||||
cc->next = NULL;
|
||||
}
|
||||
|
||||
if (expires == NGX_HTTP_EXPIRES_EPOCH) {
|
||||
@ -420,6 +411,8 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
|
||||
e->value.data = ngx_pnalloc(r->pool, len);
|
||||
if (e->value.data == NULL) {
|
||||
e->hash = 0;
|
||||
cc->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@ -457,6 +450,7 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
cc->value.data = ngx_pnalloc(r->pool,
|
||||
sizeof("max-age=") + NGX_TIME_T_LEN + 1);
|
||||
if (cc->value.data == NULL) {
|
||||
cc->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@ -564,22 +558,12 @@ static ngx_int_t
|
||||
ngx_http_add_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_http_header_val_t *hv, ngx_str_t *value)
|
||||
{
|
||||
ngx_array_t *pa;
|
||||
ngx_table_elt_t *h, **ph;
|
||||
|
||||
if (value->len == 0) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
pa = (ngx_array_t *) ((char *) &r->headers_out + hv->offset);
|
||||
|
||||
if (pa->elts == NULL) {
|
||||
if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
@ -589,12 +573,12 @@ ngx_http_add_multi_header_lines(ngx_http_request_t *r,
|
||||
h->key = hv->key;
|
||||
h->value = *value;
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
|
||||
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -642,6 +626,7 @@ ngx_http_set_response_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
|
||||
}
|
||||
|
||||
*old = h;
|
||||
h->next = NULL;
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
|
@ -401,6 +401,7 @@ found:
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
h->next = NULL;
|
||||
ngx_str_set(&h->key, "Content-Encoding");
|
||||
ngx_str_set(&h->value, "gzip");
|
||||
r->headers_out.content_encoding = h;
|
||||
|
@ -2331,7 +2331,7 @@ ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
|
||||
}
|
||||
|
||||
start_sample += count;
|
||||
start_time -= count * duration;
|
||||
start_time -= (uint64_t) count * duration;
|
||||
entries--;
|
||||
entry++;
|
||||
}
|
||||
|
@ -1930,8 +1930,12 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
||||
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
|
||||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (hh) {
|
||||
rc = hh->handler(r, h, hh->offset);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
@ -1965,6 +1969,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
||||
ngx_str_set(&h->key, "Server");
|
||||
ngx_str_null(&h->value);
|
||||
h->lowcase_key = (u_char *) "server";
|
||||
h->next = NULL;
|
||||
}
|
||||
|
||||
if (r->upstream->headers_in.date == NULL) {
|
||||
@ -1978,6 +1983,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
||||
ngx_str_set(&h->key, "Date");
|
||||
ngx_str_null(&h->value);
|
||||
h->lowcase_key = (u_char *) "date";
|
||||
h->next = NULL;
|
||||
}
|
||||
|
||||
/* clear content length if response is chunked */
|
||||
@ -2559,22 +2565,20 @@ 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)
|
||||
{
|
||||
size_t len;
|
||||
u_char *p;
|
||||
ngx_uint_t i, n;
|
||||
ngx_table_elt_t **h;
|
||||
size_t len;
|
||||
u_char *p;
|
||||
ngx_table_elt_t *h, *xfwd;
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
n = r->headers_in.x_forwarded_for.nelts;
|
||||
h = r->headers_in.x_forwarded_for.elts;
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
len = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
len += h[i]->value.len + sizeof(", ") - 1;
|
||||
for (h = xfwd; h; h = h->next) {
|
||||
len += h->value.len + sizeof(", ") - 1;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
@ -2593,8 +2597,8 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r,
|
||||
v->len = len;
|
||||
v->data = p;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
|
||||
for (h = xfwd; h; h = h->next) {
|
||||
p = ngx_copy(p, h->value.data, h->value.len);
|
||||
*p++ = ','; *p++ = ' ';
|
||||
}
|
||||
|
||||
@ -4951,8 +4955,9 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (plcf->upstream.ssl_certificate) {
|
||||
|
||||
if (plcf->upstream.ssl_certificate
|
||||
&& plcf->upstream.ssl_certificate->value.len)
|
||||
{
|
||||
if (plcf->upstream.ssl_certificate_key == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"proxy_ssl_certificate_key\" is defined "
|
||||
|
@ -258,6 +258,7 @@ next_filter:
|
||||
}
|
||||
|
||||
r->headers_out.accept_ranges->hash = 1;
|
||||
r->headers_out.accept_ranges->next = NULL;
|
||||
ngx_str_set(&r->headers_out.accept_ranges->key, "Accept-Ranges");
|
||||
ngx_str_set(&r->headers_out.accept_ranges->value, "bytes");
|
||||
|
||||
@ -427,6 +428,7 @@ ngx_http_range_singlepart_header(ngx_http_request_t *r,
|
||||
r->headers_out.content_range = content_range;
|
||||
|
||||
content_range->hash = 1;
|
||||
content_range->next = NULL;
|
||||
ngx_str_set(&content_range->key, "Content-Range");
|
||||
|
||||
content_range->value.data = ngx_pnalloc(r->pool,
|
||||
@ -599,6 +601,7 @@ ngx_http_range_not_satisfiable(ngx_http_request_t *r)
|
||||
r->headers_out.content_range = content_range;
|
||||
|
||||
content_range->hash = 1;
|
||||
content_range->next = NULL;
|
||||
ngx_str_set(&content_range->key, "Content-Range");
|
||||
|
||||
content_range->value.data = ngx_pnalloc(r->pool,
|
||||
|
@ -134,9 +134,8 @@ ngx_http_realip_handler(ngx_http_request_t *r)
|
||||
ngx_str_t *value;
|
||||
ngx_uint_t i, hash;
|
||||
ngx_addr_t addr;
|
||||
ngx_array_t *xfwd;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_table_elt_t *header, *xfwd;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_realip_ctx_t *ctx;
|
||||
ngx_http_realip_loc_conf_t *rlcf;
|
||||
@ -168,9 +167,9 @@ ngx_http_realip_handler(ngx_http_request_t *r)
|
||||
|
||||
case NGX_HTTP_REALIP_XFWD:
|
||||
|
||||
xfwd = &r->headers_in.x_forwarded_for;
|
||||
xfwd = r->headers_in.x_forwarded_for;
|
||||
|
||||
if (xfwd->elts == NULL) {
|
||||
if (xfwd == NULL) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
@ -633,14 +633,14 @@ static ngx_int_t
|
||||
ngx_http_scgi_create_request(ngx_http_request_t *r)
|
||||
{
|
||||
off_t content_length_n;
|
||||
u_char ch, *key, *val, *lowcase_key;
|
||||
u_char ch, sep, *key, *val, *lowcase_key;
|
||||
size_t len, key_len, val_len, allocated;
|
||||
ngx_buf_t *b;
|
||||
ngx_str_t content_length;
|
||||
ngx_uint_t i, n, hash, skip_empty, header_params;
|
||||
ngx_chain_t *cl, *body;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header, **ignored;
|
||||
ngx_table_elt_t *header, *hn, **ignored;
|
||||
ngx_http_scgi_params_t *params;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_script_engine_t e, le;
|
||||
@ -707,7 +707,11 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
||||
allocated = 0;
|
||||
lowcase_key = NULL;
|
||||
|
||||
if (params->number) {
|
||||
if (ngx_http_link_multi_headers(r) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (params->number || r->headers_in.multi) {
|
||||
n = 0;
|
||||
part = &r->headers_in.headers.part;
|
||||
|
||||
@ -737,6 +741,12 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for (n = 0; n < header_params; n++) {
|
||||
if (&header[i] == ignored[n]) {
|
||||
goto next_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (params->number) {
|
||||
if (allocated < header[i].key.len) {
|
||||
allocated = header[i].key.len + 16;
|
||||
@ -770,6 +780,15 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
||||
|
||||
len += sizeof("HTTP_") - 1 + header[i].key.len + 1
|
||||
+ header[i].value.len + 1;
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
len += hn->value.len + 2;
|
||||
ignored[header_params++] = hn;
|
||||
}
|
||||
|
||||
next_length:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -869,7 +888,7 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
||||
|
||||
for (n = 0; n < header_params; n++) {
|
||||
if (&header[i] == ignored[n]) {
|
||||
goto next;
|
||||
goto next_value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -893,12 +912,33 @@ ngx_http_scgi_create_request(ngx_http_request_t *r)
|
||||
|
||||
val = b->last;
|
||||
b->last = ngx_copy(val, header[i].value.data, header[i].value.len);
|
||||
|
||||
if (header[i].next) {
|
||||
|
||||
if (header[i].key.len == sizeof("Cookie") - 1
|
||||
&& ngx_strncasecmp(header[i].key.data, (u_char *) "Cookie",
|
||||
sizeof("Cookie") - 1)
|
||||
== 0)
|
||||
{
|
||||
sep = ';';
|
||||
|
||||
} else {
|
||||
sep = ',';
|
||||
}
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
*b->last++ = sep;
|
||||
*b->last++ = ' ';
|
||||
b->last = ngx_copy(b->last, hn->value.data, hn->value.len);
|
||||
}
|
||||
}
|
||||
|
||||
*b->last++ = (u_char) 0;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"scgi param: \"%s: %s\"", key, val);
|
||||
|
||||
next:
|
||||
next_value:
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -1074,8 +1114,12 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
|
||||
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
|
||||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (hh) {
|
||||
rc = hh->handler(r, h, hh->offset);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
|
@ -195,6 +195,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->next = NULL;
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
r->headers_out.location->value.len = len;
|
||||
r->headers_out.location->value.data = location;
|
||||
|
@ -319,10 +319,9 @@ ngx_http_userid_set_variable(ngx_http_request_t *r,
|
||||
static ngx_http_userid_ctx_t *
|
||||
ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
|
||||
{
|
||||
ngx_int_t n;
|
||||
ngx_str_t src, dst;
|
||||
ngx_table_elt_t **cookies;
|
||||
ngx_http_userid_ctx_t *ctx;
|
||||
ngx_str_t src, dst;
|
||||
ngx_table_elt_t *cookie;
|
||||
ngx_http_userid_ctx_t *ctx;
|
||||
|
||||
ctx = ngx_http_get_module_ctx(r, ngx_http_userid_filter_module);
|
||||
|
||||
@ -339,9 +338,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_userid_filter_module);
|
||||
}
|
||||
|
||||
n = ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &conf->name,
|
||||
&ctx->cookie);
|
||||
if (n == NGX_DECLINED) {
|
||||
cookie = ngx_http_parse_multi_header_lines(r, r->headers_in.cookie,
|
||||
&conf->name, &ctx->cookie);
|
||||
if (cookie == NULL) {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@ -349,10 +348,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
|
||||
"uid cookie: \"%V\"", &ctx->cookie);
|
||||
|
||||
if (ctx->cookie.len < 22) {
|
||||
cookies = r->headers_in.cookies.elts;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client sent too short userid cookie \"%V\"",
|
||||
&cookies[n]->value);
|
||||
&cookie->value);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@ -370,10 +368,9 @@ ngx_http_userid_get_uid(ngx_http_request_t *r, ngx_http_userid_conf_t *conf)
|
||||
dst.data = (u_char *) ctx->uid_got;
|
||||
|
||||
if (ngx_decode_base64(&dst, &src) == NGX_ERROR) {
|
||||
cookies = r->headers_in.cookies.elts;
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"client sent invalid userid cookie \"%V\"",
|
||||
&cookies[n]->value);
|
||||
&cookie->value);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
@ -845,13 +845,13 @@ ngx_http_uwsgi_create_key(ngx_http_request_t *r)
|
||||
static ngx_int_t
|
||||
ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||
{
|
||||
u_char ch, *lowcase_key;
|
||||
u_char ch, sep, *lowcase_key;
|
||||
size_t key_len, val_len, len, allocated;
|
||||
ngx_uint_t i, n, hash, skip_empty, header_params;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl, *body;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header, **ignored;
|
||||
ngx_table_elt_t *header, *hn, **ignored;
|
||||
ngx_http_uwsgi_params_t *params;
|
||||
ngx_http_script_code_pt code;
|
||||
ngx_http_script_engine_t e, le;
|
||||
@ -905,7 +905,11 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||
allocated = 0;
|
||||
lowcase_key = NULL;
|
||||
|
||||
if (params->number) {
|
||||
if (ngx_http_link_multi_headers(r) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (params->number || r->headers_in.multi) {
|
||||
n = 0;
|
||||
part = &r->headers_in.headers.part;
|
||||
|
||||
@ -935,6 +939,12 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
for (n = 0; n < header_params; n++) {
|
||||
if (&header[i] == ignored[n]) {
|
||||
goto next_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (params->number) {
|
||||
if (allocated < header[i].key.len) {
|
||||
allocated = header[i].key.len + 16;
|
||||
@ -968,6 +978,15 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||
|
||||
len += 2 + sizeof("HTTP_") - 1 + header[i].key.len
|
||||
+ 2 + header[i].value.len;
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
len += hn->value.len + 2;
|
||||
ignored[header_params++] = hn;
|
||||
}
|
||||
|
||||
next_length:
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1086,7 +1105,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||
|
||||
for (n = 0; n < header_params; n++) {
|
||||
if (&header[i] == ignored[n]) {
|
||||
goto next;
|
||||
goto next_value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1109,15 +1128,41 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
val_len = header[i].value.len;
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
val_len += hn->value.len + 2;
|
||||
}
|
||||
|
||||
*b->last++ = (u_char) (val_len & 0xff);
|
||||
*b->last++ = (u_char) ((val_len >> 8) & 0xff);
|
||||
b->last = ngx_copy(b->last, header[i].value.data, val_len);
|
||||
b->last = ngx_copy(b->last, header[i].value.data,
|
||||
header[i].value.len);
|
||||
|
||||
if (header[i].next) {
|
||||
|
||||
if (header[i].key.len == sizeof("Cookie") - 1
|
||||
&& ngx_strncasecmp(header[i].key.data, (u_char *) "Cookie",
|
||||
sizeof("Cookie") - 1)
|
||||
== 0)
|
||||
{
|
||||
sep = ';';
|
||||
|
||||
} else {
|
||||
sep = ',';
|
||||
}
|
||||
|
||||
for (hn = header[i].next; hn; hn = hn->next) {
|
||||
*b->last++ = sep;
|
||||
*b->last++ = ' ';
|
||||
b->last = ngx_copy(b->last, hn->value.data, hn->value.len);
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"uwsgi param: \"%*s: %*s\"",
|
||||
key_len, b->last - (key_len + 2 + val_len),
|
||||
val_len, b->last - val_len);
|
||||
next:
|
||||
next_value:
|
||||
|
||||
continue;
|
||||
}
|
||||
@ -1295,8 +1340,12 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
|
||||
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
|
||||
h->lowcase_key, h->key.len);
|
||||
|
||||
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
if (hh) {
|
||||
rc = hh->handler(r, h, hh->offset);
|
||||
|
||||
if (rc != NGX_OK) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
@ -2438,8 +2487,9 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (uwcf->upstream.ssl_certificate) {
|
||||
|
||||
if (uwcf->upstream.ssl_certificate
|
||||
&& uwcf->upstream.ssl_certificate->value.len)
|
||||
{
|
||||
if (uwcf->upstream.ssl_certificate_key == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"uwsgi_ssl_certificate_key\" is defined "
|
||||
|
@ -269,10 +269,9 @@ header_in(r, key)
|
||||
u_char *p, *lowcase_key, *value, sep;
|
||||
STRLEN len;
|
||||
ssize_t size;
|
||||
ngx_uint_t i, n, hash;
|
||||
ngx_array_t *a;
|
||||
ngx_uint_t i, hash;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *h, **ph;
|
||||
ngx_table_elt_t *h, *header, **ph;
|
||||
ngx_http_header_t *hh;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
@ -302,78 +301,23 @@ header_in(r, key)
|
||||
|
||||
if (hh) {
|
||||
|
||||
if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) {
|
||||
if (hh->offset == offsetof(ngx_http_headers_in_t, cookie)) {
|
||||
sep = ';';
|
||||
goto multi;
|
||||
}
|
||||
#if (NGX_HTTP_X_FORWARDED_FOR)
|
||||
if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) {
|
||||
|
||||
} else {
|
||||
sep = ',';
|
||||
goto multi;
|
||||
}
|
||||
#endif
|
||||
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset);
|
||||
|
||||
if (*ph) {
|
||||
ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
XSRETURN_UNDEF;
|
||||
|
||||
multi:
|
||||
|
||||
/* Cookie, X-Forwarded-For */
|
||||
|
||||
a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset);
|
||||
|
||||
n = a->nelts;
|
||||
|
||||
if (n == 0) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
ph = a->elts;
|
||||
|
||||
if (n == 1) {
|
||||
ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
size = - (ssize_t) (sizeof("; ") - 1);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
size += ph[i]->value.len + sizeof("; ") - 1;
|
||||
}
|
||||
|
||||
value = ngx_pnalloc(r->pool, size);
|
||||
if (value == NULL) {
|
||||
ctx->error = 1;
|
||||
croak("ngx_pnalloc() failed");
|
||||
}
|
||||
|
||||
p = value;
|
||||
|
||||
for (i = 0; /* void */ ; i++) {
|
||||
p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len);
|
||||
|
||||
if (i == n - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = sep; *p++ = ' ';
|
||||
}
|
||||
|
||||
ngx_http_perl_set_targ(value, size);
|
||||
|
||||
goto done;
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* iterate over all headers */
|
||||
|
||||
sep = ',';
|
||||
ph = &header;
|
||||
|
||||
part = &r->headers_in.headers.part;
|
||||
h = part->elts;
|
||||
|
||||
@ -395,12 +339,49 @@ header_in(r, key)
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_http_perl_set_targ(h[i].value.data, h[i].value.len);
|
||||
*ph = &h[i];
|
||||
ph = &h[i].next;
|
||||
}
|
||||
|
||||
*ph = NULL;
|
||||
ph = &header;
|
||||
|
||||
found:
|
||||
|
||||
if (*ph == NULL) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
if ((*ph)->next == NULL) {
|
||||
ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);
|
||||
goto done;
|
||||
}
|
||||
|
||||
XSRETURN_UNDEF;
|
||||
size = - (ssize_t) (sizeof("; ") - 1);
|
||||
|
||||
for (h = *ph; h; h = h->next) {
|
||||
size += h->value.len + sizeof("; ") - 1;
|
||||
}
|
||||
|
||||
value = ngx_pnalloc(r->pool, size);
|
||||
if (value == NULL) {
|
||||
ctx->error = 1;
|
||||
croak("ngx_pnalloc() failed");
|
||||
}
|
||||
|
||||
p = value;
|
||||
|
||||
for (h = *ph; h; h = h->next) {
|
||||
p = ngx_copy(p, h->value.data, h->value.len);
|
||||
|
||||
if (h->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = sep; *p++ = ' ';
|
||||
}
|
||||
|
||||
ngx_http_perl_set_targ(value, size);
|
||||
|
||||
done:
|
||||
|
||||
@ -591,6 +572,7 @@ header_out(r, key, value)
|
||||
}
|
||||
|
||||
header->hash = 1;
|
||||
header->next = NULL;
|
||||
|
||||
if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) {
|
||||
header->hash = 0;
|
||||
|
@ -108,10 +108,10 @@ ngx_int_t ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
ngx_str_t *args, ngx_uint_t *flags);
|
||||
ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_buf_t *b,
|
||||
ngx_uint_t allow_underscores);
|
||||
ngx_int_t ngx_http_parse_multi_header_lines(ngx_array_t *headers,
|
||||
ngx_str_t *name, ngx_str_t *value);
|
||||
ngx_int_t ngx_http_parse_set_cookie_lines(ngx_array_t *headers,
|
||||
ngx_str_t *name, ngx_str_t *value);
|
||||
ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
|
||||
ngx_table_elt_t *ngx_http_parse_set_cookie_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value);
|
||||
ngx_int_t ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len,
|
||||
ngx_str_t *value);
|
||||
void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri,
|
||||
|
@ -1007,6 +1007,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->next = NULL;
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
|
||||
if (r->args.len == 0) {
|
||||
@ -1087,6 +1088,7 @@ ngx_int_t
|
||||
ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
if (r != r->main) {
|
||||
@ -1121,8 +1123,8 @@ ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
|
||||
if (rc == NGX_OK) {
|
||||
r->access_code = 0;
|
||||
|
||||
if (r->headers_out.www_authenticate) {
|
||||
r->headers_out.www_authenticate->hash = 0;
|
||||
for (h = r->headers_out.www_authenticate; h; h = h->next) {
|
||||
h->hash = 0;
|
||||
}
|
||||
|
||||
r->phase_handler = ph->next;
|
||||
@ -1687,6 +1689,7 @@ ngx_http_set_etag(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
etag->hash = 1;
|
||||
etag->next = NULL;
|
||||
ngx_str_set(&etag->key, "ETag");
|
||||
|
||||
etag->value.data = ngx_pnalloc(r->pool, NGX_OFF_T_LEN + NGX_TIME_T_LEN + 3);
|
||||
@ -1781,6 +1784,7 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
|
||||
}
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->next = NULL;
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
r->headers_out.location->value = val;
|
||||
|
||||
@ -2024,8 +2028,7 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
|
||||
{
|
||||
time_t date, expires;
|
||||
ngx_uint_t p;
|
||||
ngx_array_t *cc;
|
||||
ngx_table_elt_t *e, *d, *ae;
|
||||
ngx_table_elt_t *e, *d, *ae, *cc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
r->gzip_tested = 1;
|
||||
@ -2118,30 +2121,30 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
cc = &r->headers_out.cache_control;
|
||||
cc = r->headers_out.cache_control;
|
||||
|
||||
if (cc->elts) {
|
||||
if (cc) {
|
||||
|
||||
if ((p & NGX_HTTP_GZIP_PROXIED_NO_CACHE)
|
||||
&& ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_cache,
|
||||
&& ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_cache,
|
||||
NULL)
|
||||
>= 0)
|
||||
!= NULL)
|
||||
{
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if ((p & NGX_HTTP_GZIP_PROXIED_NO_STORE)
|
||||
&& ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_no_store,
|
||||
&& ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_no_store,
|
||||
NULL)
|
||||
>= 0)
|
||||
!= NULL)
|
||||
{
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if ((p & NGX_HTTP_GZIP_PROXIED_PRIVATE)
|
||||
&& ngx_http_parse_multi_header_lines(cc, &ngx_http_gzip_private,
|
||||
&& ngx_http_parse_multi_header_lines(r, cc, &ngx_http_gzip_private,
|
||||
NULL)
|
||||
>= 0)
|
||||
!= NULL)
|
||||
{
|
||||
goto ok;
|
||||
}
|
||||
@ -2712,12 +2715,12 @@ ngx_http_set_disable_symlinks(ngx_http_request_t *r,
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
|
||||
ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
|
||||
ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies,
|
||||
int recursive)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, found;
|
||||
ngx_table_elt_t **h;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t found;
|
||||
ngx_table_elt_t *h, *next;
|
||||
|
||||
if (headers == NULL) {
|
||||
return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
|
||||
@ -2725,16 +2728,23 @@ ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
|
||||
recursive);
|
||||
}
|
||||
|
||||
i = headers->nelts;
|
||||
h = headers->elts;
|
||||
/* revert headers order */
|
||||
|
||||
for (h = headers, headers = NULL; h; h = next) {
|
||||
next = h->next;
|
||||
h->next = headers;
|
||||
headers = h;
|
||||
}
|
||||
|
||||
/* iterate over all headers in reverse order */
|
||||
|
||||
rc = NGX_DECLINED;
|
||||
|
||||
found = 0;
|
||||
|
||||
while (i-- > 0) {
|
||||
rc = ngx_http_get_forwarded_addr_internal(r, addr, h[i]->value.data,
|
||||
h[i]->value.len, proxies,
|
||||
for (h = headers; h; h = h->next) {
|
||||
rc = ngx_http_get_forwarded_addr_internal(r, addr, h->value.data,
|
||||
h->value.len, proxies,
|
||||
recursive);
|
||||
|
||||
if (!recursive) {
|
||||
@ -2753,6 +2763,14 @@ ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
|
||||
found = 1;
|
||||
}
|
||||
|
||||
/* restore headers order */
|
||||
|
||||
for (h = headers, headers = NULL; h; h = next) {
|
||||
next = h->next;
|
||||
h->next = headers;
|
||||
headers = h;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2802,6 +2820,80 @@ ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_link_multi_headers(ngx_http_request_t *r)
|
||||
{
|
||||
ngx_uint_t i, j;
|
||||
ngx_list_part_t *part, *ppart;
|
||||
ngx_table_elt_t *header, *pheader, **ph;
|
||||
|
||||
if (r->headers_in.multi_linked) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
r->headers_in.multi_linked = 1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
header[i].next = NULL;
|
||||
|
||||
/*
|
||||
* search for previous headers with the same name;
|
||||
* if there are any, link to them
|
||||
*/
|
||||
|
||||
ppart = &r->headers_in.headers.part;
|
||||
pheader = ppart->elts;
|
||||
|
||||
for (j = 0; /* void */; j++) {
|
||||
|
||||
if (j >= ppart->nelts) {
|
||||
if (ppart->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
ppart = ppart->next;
|
||||
pheader = ppart->elts;
|
||||
j = 0;
|
||||
}
|
||||
|
||||
if (part == ppart && i == j) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (header[i].key.len == pheader[j].key.len
|
||||
&& ngx_strncasecmp(header[i].key.data, pheader[j].key.data,
|
||||
header[i].key.len)
|
||||
== 0)
|
||||
{
|
||||
ph = &pheader[j].next;
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
*ph = &header[i];
|
||||
|
||||
r->headers_in.multi = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
|
||||
{
|
||||
|
@ -533,9 +533,11 @@ ngx_int_t ngx_http_set_disable_symlinks(ngx_http_request_t *r,
|
||||
ngx_http_core_loc_conf_t *clcf, ngx_str_t *path, ngx_open_file_info_t *of);
|
||||
|
||||
ngx_int_t ngx_http_get_forwarded_addr(ngx_http_request_t *r, ngx_addr_t *addr,
|
||||
ngx_array_t *headers, ngx_str_t *value, ngx_array_t *proxies,
|
||||
ngx_table_elt_t *headers, ngx_str_t *value, ngx_array_t *proxies,
|
||||
int recursive);
|
||||
|
||||
ngx_int_t ngx_http_link_multi_headers(ngx_http_request_t *r);
|
||||
|
||||
|
||||
extern ngx_module_t ngx_http_core_module;
|
||||
|
||||
|
@ -1960,27 +1960,24 @@ unsafe:
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
ngx_str_t *value)
|
||||
ngx_table_elt_t *
|
||||
ngx_http_parse_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
u_char *start, *last, *end, ch;
|
||||
ngx_table_elt_t **h;
|
||||
u_char *start, *last, *end, ch;
|
||||
ngx_table_elt_t *h;
|
||||
|
||||
h = headers->elts;
|
||||
for (h = headers; h; h = h->next) {
|
||||
|
||||
for (i = 0; i < headers->nelts; i++) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"parse header: \"%V: %V\"", &h->key, &h->value);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0,
|
||||
"parse header: \"%V: %V\"", &h[i]->key, &h[i]->value);
|
||||
|
||||
if (name->len > h[i]->value.len) {
|
||||
if (name->len > h->value.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
start = h[i]->value.data;
|
||||
end = h[i]->value.data + h[i]->value.len;
|
||||
start = h->value.data;
|
||||
end = h->value.data + h->value.len;
|
||||
|
||||
while (start < end) {
|
||||
|
||||
@ -1994,7 +1991,7 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
|
||||
if (value == NULL) {
|
||||
if (start == end || *start == ',') {
|
||||
return i;
|
||||
return h;
|
||||
}
|
||||
|
||||
goto skip;
|
||||
@ -2014,7 +2011,7 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
value->len = last - start;
|
||||
value->data = start;
|
||||
|
||||
return i;
|
||||
return h;
|
||||
|
||||
skip:
|
||||
|
||||
@ -2029,31 +2026,28 @@ ngx_http_parse_multi_header_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
ngx_str_t *value)
|
||||
ngx_table_elt_t *
|
||||
ngx_http_parse_set_cookie_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *headers, ngx_str_t *name, ngx_str_t *value)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
u_char *start, *last, *end;
|
||||
ngx_table_elt_t **h;
|
||||
u_char *start, *last, *end;
|
||||
ngx_table_elt_t *h;
|
||||
|
||||
h = headers->elts;
|
||||
for (h = headers; h; h = h->next) {
|
||||
|
||||
for (i = 0; i < headers->nelts; i++) {
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"parse header: \"%V: %V\"", &h->key, &h->value);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, headers->pool->log, 0,
|
||||
"parse header: \"%V: %V\"", &h[i]->key, &h[i]->value);
|
||||
|
||||
if (name->len >= h[i]->value.len) {
|
||||
if (name->len >= h->value.len) {
|
||||
continue;
|
||||
}
|
||||
|
||||
start = h[i]->value.data;
|
||||
end = h[i]->value.data + h[i]->value.len;
|
||||
start = h->value.data;
|
||||
end = h->value.data + h->value.len;
|
||||
|
||||
if (ngx_strncasecmp(start, name->data, name->len) != 0) {
|
||||
continue;
|
||||
@ -2077,10 +2071,10 @@ ngx_http_parse_set_cookie_lines(ngx_array_t *headers, ngx_str_t *name,
|
||||
value->len = last - start;
|
||||
value->data = start;
|
||||
|
||||
return i;
|
||||
return h;
|
||||
}
|
||||
|
||||
return NGX_DECLINED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,8 +22,6 @@ static ngx_int_t ngx_http_process_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_unique_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_host(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
|
||||
@ -159,7 +157,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
||||
#if (NGX_HTTP_X_FORWARDED_FOR)
|
||||
{ ngx_string("X-Forwarded-For"),
|
||||
offsetof(ngx_http_headers_in_t, x_forwarded_for),
|
||||
ngx_http_process_multi_header_lines },
|
||||
ngx_http_process_header_line },
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_REALIP)
|
||||
@ -191,8 +189,8 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
||||
ngx_http_process_header_line },
|
||||
#endif
|
||||
|
||||
{ ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies),
|
||||
ngx_http_process_multi_header_lines },
|
||||
{ ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookie),
|
||||
ngx_http_process_header_line },
|
||||
|
||||
{ ngx_null_string, 0, NULL }
|
||||
};
|
||||
@ -1752,9 +1750,10 @@ ngx_http_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->headers_in + offset);
|
||||
|
||||
if (*ph == NULL) {
|
||||
*ph = h;
|
||||
}
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -1770,6 +1769,7 @@ ngx_http_process_unique_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
|
||||
if (*ph == NULL) {
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -1802,6 +1802,7 @@ ngx_http_process_host(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
r->headers_in.host = h;
|
||||
h->next = NULL;
|
||||
|
||||
host = h->value;
|
||||
|
||||
@ -1837,6 +1838,10 @@ static ngx_int_t
|
||||
ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
|
||||
r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
|
||||
|
||||
@ -1854,12 +1859,10 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
{
|
||||
u_char *user_agent, *msie;
|
||||
|
||||
if (r->headers_in.user_agent) {
|
||||
return NGX_OK;
|
||||
if (ngx_http_process_header_line(r, h, offset) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->headers_in.user_agent = h;
|
||||
|
||||
/* check some widespread browsers while the header is in CPU cache */
|
||||
|
||||
user_agent = h->value.data;
|
||||
@ -1921,35 +1924,6 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
ngx_array_t *headers;
|
||||
ngx_table_elt_t **ph;
|
||||
|
||||
headers = (ngx_array_t *) ((char *) &r->headers_in + offset);
|
||||
|
||||
if (headers->elts == NULL) {
|
||||
if (ngx_array_init(headers, r->pool, 1, sizeof(ngx_table_elt_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ph = ngx_array_push(headers);
|
||||
if (ph == NULL) {
|
||||
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ph = h;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_process_request_header(ngx_http_request_t *r)
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ typedef struct {
|
||||
ngx_table_elt_t *keep_alive;
|
||||
|
||||
#if (NGX_HTTP_X_FORWARDED_FOR)
|
||||
ngx_array_t x_forwarded_for;
|
||||
ngx_table_elt_t *x_forwarded_for;
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_REALIP)
|
||||
@ -232,17 +232,19 @@ typedef struct {
|
||||
ngx_table_elt_t *date;
|
||||
#endif
|
||||
|
||||
ngx_table_elt_t *cookie;
|
||||
|
||||
ngx_str_t user;
|
||||
ngx_str_t passwd;
|
||||
|
||||
ngx_array_t cookies;
|
||||
|
||||
ngx_str_t server;
|
||||
off_t content_length_n;
|
||||
time_t keep_alive_n;
|
||||
|
||||
unsigned connection_type:2;
|
||||
unsigned chunked:1;
|
||||
unsigned multi:1;
|
||||
unsigned multi_linked:1;
|
||||
unsigned msie:1;
|
||||
unsigned msie6:1;
|
||||
unsigned opera:1;
|
||||
@ -273,6 +275,9 @@ typedef struct {
|
||||
ngx_table_elt_t *expires;
|
||||
ngx_table_elt_t *etag;
|
||||
|
||||
ngx_table_elt_t *cache_control;
|
||||
ngx_table_elt_t *link;
|
||||
|
||||
ngx_str_t *override_charset;
|
||||
|
||||
size_t content_type_len;
|
||||
@ -281,9 +286,6 @@ typedef struct {
|
||||
u_char *content_type_lowcase;
|
||||
ngx_uint_t content_type_hash;
|
||||
|
||||
ngx_array_t cache_control;
|
||||
ngx_array_t link;
|
||||
|
||||
off_t content_length_n;
|
||||
off_t content_offset;
|
||||
time_t date_time;
|
||||
|
@ -1243,6 +1243,7 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
|
||||
}
|
||||
|
||||
r->headers_out.location->hash = 1;
|
||||
r->headers_out.location->next = NULL;
|
||||
ngx_str_set(&r->headers_out.location->key, "Location");
|
||||
r->headers_out.location->value = e->buf;
|
||||
|
||||
|
@ -649,6 +649,7 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
|
||||
}
|
||||
|
||||
location->hash = 1;
|
||||
location->next = NULL;
|
||||
ngx_str_set(&location->key, "Location");
|
||||
location->value = uri;
|
||||
|
||||
|
@ -101,6 +101,9 @@ static void ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
||||
|
||||
static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_process_content_length(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
static ngx_int_t ngx_http_upstream_process_last_modified(ngx_http_request_t *r,
|
||||
@ -147,11 +150,6 @@ static ngx_int_t ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r,
|
||||
static ngx_int_t ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
static ngx_int_t ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset);
|
||||
#endif
|
||||
|
||||
static ngx_int_t ngx_http_upstream_add_variables(ngx_conf_t *cf);
|
||||
static ngx_int_t ngx_http_upstream_addr_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
@ -231,7 +229,7 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
offsetof(ngx_http_headers_out_t, server), 0 },
|
||||
|
||||
{ ngx_string("WWW-Authenticate"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
ngx_http_upstream_process_multi_header_lines,
|
||||
offsetof(ngx_http_upstream_headers_in_t, www_authenticate),
|
||||
ngx_http_upstream_copy_header_line, 0, 0 },
|
||||
|
||||
@ -241,12 +239,13 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
ngx_http_upstream_rewrite_location, 0, 0 },
|
||||
|
||||
{ ngx_string("Refresh"),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, refresh),
|
||||
ngx_http_upstream_rewrite_refresh, 0, 0 },
|
||||
|
||||
{ ngx_string("Set-Cookie"),
|
||||
ngx_http_upstream_process_set_cookie,
|
||||
offsetof(ngx_http_upstream_headers_in_t, cookies),
|
||||
offsetof(ngx_http_upstream_headers_in_t, set_cookie),
|
||||
ngx_http_upstream_rewrite_set_cookie, 0, 1 },
|
||||
|
||||
{ ngx_string("Content-Disposition"),
|
||||
@ -264,8 +263,7 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
offsetof(ngx_http_headers_out_t, expires), 1 },
|
||||
|
||||
{ ngx_string("Accept-Ranges"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, accept_ranges),
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_copy_allow_ranges,
|
||||
offsetof(ngx_http_headers_out_t, accept_ranges), 1 },
|
||||
|
||||
@ -316,12 +314,10 @@ static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
ngx_http_upstream_process_transfer_encoding, 0,
|
||||
ngx_http_upstream_ignore_header_line, 0, 0 },
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
{ ngx_string("Content-Encoding"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
offsetof(ngx_http_upstream_headers_in_t, content_encoding),
|
||||
ngx_http_upstream_copy_content_encoding, 0, 0 },
|
||||
#endif
|
||||
ngx_http_upstream_ignore_header_line, 0,
|
||||
ngx_http_upstream_copy_header_line,
|
||||
offsetof(ngx_http_headers_out_t, content_encoding), 0 },
|
||||
|
||||
{ ngx_null_string, NULL, 0, NULL, 0, 0 }
|
||||
};
|
||||
@ -1714,8 +1710,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
||||
}
|
||||
}
|
||||
|
||||
if (u->conf->ssl_certificate && (u->conf->ssl_certificate->lengths
|
||||
|| u->conf->ssl_certificate_key->lengths))
|
||||
if (u->conf->ssl_certificate
|
||||
&& u->conf->ssl_certificate->value.len
|
||||
&& (u->conf->ssl_certificate->lengths
|
||||
|| u->conf->ssl_certificate_key->lengths))
|
||||
{
|
||||
if (ngx_http_upstream_ssl_certificate(r, u, c) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
@ -2671,7 +2669,7 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
|
||||
{
|
||||
ngx_int_t status;
|
||||
ngx_uint_t i;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_table_elt_t *h, *ho, **ph;
|
||||
ngx_http_err_page_t *err_page;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
@ -2700,23 +2698,36 @@ ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
|
||||
if (status == NGX_HTTP_UNAUTHORIZED
|
||||
&& u->headers_in.www_authenticate)
|
||||
{
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
h = u->headers_in.www_authenticate;
|
||||
ph = &r->headers_out.www_authenticate;
|
||||
|
||||
if (h == NULL) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
while (h) {
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
|
||||
if (ho == NULL) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_OK;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
*ph = ho;
|
||||
ph = &ho->next;
|
||||
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
*h = *u->headers_in.www_authenticate;
|
||||
|
||||
r->headers_out.www_authenticate = h;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (r->cache) {
|
||||
|
||||
if (u->headers_in.no_cache || u->headers_in.expired) {
|
||||
u->cacheable = 0;
|
||||
}
|
||||
|
||||
if (u->cacheable) {
|
||||
time_t valid;
|
||||
|
||||
@ -2811,6 +2822,10 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
|
||||
|
||||
if (u->headers_in.no_cache || u->headers_in.expired) {
|
||||
u->cacheable = 0;
|
||||
}
|
||||
|
||||
if (u->headers_in.x_accel_redirect
|
||||
&& !(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT))
|
||||
{
|
||||
@ -2831,6 +2846,10 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (h[i].hash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hh = ngx_hash_find(&umcf->headers_in_hash, h[i].hash,
|
||||
h[i].lowcase_key, h[i].key.len);
|
||||
|
||||
@ -2884,6 +2903,10 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (h[i].hash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash,
|
||||
h[i].lowcase_key, h[i].key.len))
|
||||
{
|
||||
@ -4635,10 +4658,36 @@ ngx_http_upstream_process_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset);
|
||||
|
||||
if (*ph == NULL) {
|
||||
*ph = h;
|
||||
if (*ph) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\", ignored",
|
||||
&h->key, &h->value,
|
||||
&(*ph)->key, &(*ph)->value);
|
||||
h->hash = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_table_elt_t **ph;
|
||||
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->upstream->headers_in + offset);
|
||||
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -4659,9 +4708,34 @@ ngx_http_upstream_process_content_length(ngx_http_request_t *r,
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->headers_in.content_length) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\"",
|
||||
&h->key, &h->value,
|
||||
&u->headers_in.content_length->key,
|
||||
&u->headers_in.content_length->value);
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
if (u->headers_in.transfer_encoding) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent \"Content-Length\" and "
|
||||
"\"Transfer-Encoding\" headers at the same time");
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
h->next = NULL;
|
||||
u->headers_in.content_length = h;
|
||||
u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len);
|
||||
|
||||
if (u->headers_in.content_length_n == NGX_ERROR) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent invalid \"Content-Length\" header: "
|
||||
"\"%V: %V\"", &h->key, &h->value);
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -4674,6 +4748,18 @@ ngx_http_upstream_process_last_modified(ngx_http_request_t *r,
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->headers_in.last_modified) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\", ignored",
|
||||
&h->key, &h->value,
|
||||
&u->headers_in.last_modified->key,
|
||||
&u->headers_in.last_modified->value);
|
||||
h->hash = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
h->next = NULL;
|
||||
u->headers_in.last_modified = h;
|
||||
u->headers_in.last_modified_time = ngx_parse_http_time(h->value.data,
|
||||
h->value.len);
|
||||
@ -4686,26 +4772,16 @@ static ngx_int_t
|
||||
ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
ngx_array_t *pa;
|
||||
ngx_table_elt_t **ph;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
pa = &u->headers_in.cookies;
|
||||
ph = &u->headers_in.set_cookie;
|
||||
|
||||
if (pa->elts == NULL) {
|
||||
if (ngx_array_init(pa, r->pool, 1, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
|
||||
@ -4721,26 +4797,16 @@ static ngx_int_t
|
||||
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_array_t *pa;
|
||||
ngx_table_elt_t **ph;
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_table_elt_t **ph;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
pa = &u->headers_in.cache_control;
|
||||
ph = &u->headers_in.cache_control;
|
||||
|
||||
if (pa->elts == NULL) {
|
||||
if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
{
|
||||
@ -4755,18 +4821,18 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
start = h->value.data;
|
||||
last = start + h->value.len;
|
||||
|
||||
if (r->cache->valid_sec != 0 && u->headers_in.x_accel_expires != NULL) {
|
||||
goto extensions;
|
||||
}
|
||||
|
||||
if (ngx_strlcasestrn(start, last, (u_char *) "no-cache", 8 - 1) != NULL
|
||||
|| ngx_strlcasestrn(start, last, (u_char *) "no-store", 8 - 1) != NULL
|
||||
|| ngx_strlcasestrn(start, last, (u_char *) "private", 7 - 1) != NULL)
|
||||
{
|
||||
u->cacheable = 0;
|
||||
u->headers_in.no_cache = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -4796,13 +4862,16 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
u->cacheable = 0;
|
||||
u->headers_in.no_cache = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
r->cache->valid_sec = ngx_time() + n;
|
||||
u->headers_in.expired = 0;
|
||||
}
|
||||
|
||||
extensions:
|
||||
|
||||
p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=",
|
||||
23 - 1);
|
||||
|
||||
@ -4862,7 +4931,20 @@ ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->headers_in.expires) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\", ignored",
|
||||
&h->key, &h->value,
|
||||
&u->headers_in.expires->key,
|
||||
&u->headers_in.expires->value);
|
||||
h->hash = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
u->headers_in.expires = h;
|
||||
h->next = NULL;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
{
|
||||
@ -4883,7 +4965,7 @@ ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
expires = ngx_parse_http_time(h->value.data, h->value.len);
|
||||
|
||||
if (expires == NGX_ERROR || expires < ngx_time()) {
|
||||
u->cacheable = 0;
|
||||
u->headers_in.expired = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -4902,7 +4984,20 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->headers_in.x_accel_expires) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\", ignored",
|
||||
&h->key, &h->value,
|
||||
&u->headers_in.x_accel_expires->key,
|
||||
&u->headers_in.x_accel_expires->value);
|
||||
h->hash = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
u->headers_in.x_accel_expires = h;
|
||||
h->next = NULL;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
{
|
||||
@ -4934,6 +5029,8 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
|
||||
|
||||
default:
|
||||
r->cache->valid_sec = ngx_time() + n;
|
||||
u->headers_in.no_cache = 0;
|
||||
u->headers_in.expired = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
}
|
||||
@ -4945,6 +5042,8 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
|
||||
|
||||
if (n != NGX_ERROR) {
|
||||
r->cache->valid_sec = n;
|
||||
u->headers_in.no_cache = 0;
|
||||
u->headers_in.expired = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -4961,7 +5060,20 @@ ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->headers_in.x_accel_limit_rate) {
|
||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\", ignored",
|
||||
&h->key, &h->value,
|
||||
&u->headers_in.x_accel_limit_rate->key,
|
||||
&u->headers_in.x_accel_limit_rate->value);
|
||||
h->hash = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
u->headers_in.x_accel_limit_rate = h;
|
||||
h->next = NULL;
|
||||
|
||||
if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE) {
|
||||
return NGX_OK;
|
||||
@ -5020,7 +5132,11 @@ static ngx_int_t
|
||||
ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
if (r->upstream->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) {
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
|
||||
if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@ -5034,13 +5150,22 @@ static ngx_int_t
|
||||
ngx_http_upstream_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
ngx_uint_t offset)
|
||||
{
|
||||
r->upstream->headers_in.connection = h;
|
||||
ngx_table_elt_t **ph;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
ph = &u->headers_in.connection;
|
||||
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len,
|
||||
(u_char *) "close", 5 - 1)
|
||||
!= NULL)
|
||||
{
|
||||
r->upstream->headers_in.connection_close = 1;
|
||||
u->headers_in.connection_close = 1;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@ -5051,13 +5176,40 @@ static ngx_int_t
|
||||
ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
r->upstream->headers_in.transfer_encoding = h;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len,
|
||||
(u_char *) "chunked", 7 - 1)
|
||||
!= NULL)
|
||||
u = r->upstream;
|
||||
|
||||
if (u->headers_in.transfer_encoding) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent duplicate header line: \"%V: %V\", "
|
||||
"previous value: \"%V: %V\"",
|
||||
&h->key, &h->value,
|
||||
&u->headers_in.transfer_encoding->key,
|
||||
&u->headers_in.transfer_encoding->value);
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
if (u->headers_in.content_length) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent \"Content-Length\" and "
|
||||
"\"Transfer-Encoding\" headers at the same time");
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
u->headers_in.transfer_encoding = h;
|
||||
h->next = NULL;
|
||||
|
||||
if (h->value.len == 7
|
||||
&& ngx_strncasecmp(h->value.data, (u_char *) "chunked", 7) == 0)
|
||||
{
|
||||
r->upstream->headers_in.chunked = 1;
|
||||
u->headers_in.chunked = 1;
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"upstream sent unknown \"Transfer-Encoding\": \"%V\"",
|
||||
&h->value);
|
||||
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@ -5068,29 +5220,74 @@ static ngx_int_t
|
||||
ngx_http_upstream_process_vary(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_http_upstream_t *u;
|
||||
ngx_table_elt_t **ph;
|
||||
ngx_http_upstream_t *u;
|
||||
|
||||
u = r->upstream;
|
||||
u->headers_in.vary = h;
|
||||
ph = &u->headers_in.vary;
|
||||
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = h;
|
||||
h->next = NULL;
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
{
|
||||
u_char *p;
|
||||
size_t len;
|
||||
ngx_str_t vary;
|
||||
|
||||
if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_VARY) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (r->cache == NULL) {
|
||||
if (r->cache == NULL || !u->cacheable) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (h->value.len > NGX_HTTP_CACHE_VARY_LEN
|
||||
|| (h->value.len == 1 && h->value.data[0] == '*'))
|
||||
{
|
||||
if (h->value.len == 1 && h->value.data[0] == '*') {
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (u->headers_in.vary->next) {
|
||||
|
||||
len = 0;
|
||||
|
||||
for (h = u->headers_in.vary; h; h = h->next) {
|
||||
len += h->value.len + 2;
|
||||
}
|
||||
|
||||
len -= 2;
|
||||
|
||||
p = ngx_pnalloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
vary.len = len;
|
||||
vary.data = p;
|
||||
|
||||
for (h = u->headers_in.vary; h; h = h->next) {
|
||||
p = ngx_copy(p, h->value.data, h->value.len);
|
||||
|
||||
if (h->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = ','; *p++ = ' ';
|
||||
}
|
||||
|
||||
} else {
|
||||
vary = h->value;
|
||||
}
|
||||
|
||||
if (vary.len > NGX_HTTP_CACHE_VARY_LEN) {
|
||||
u->cacheable = 0;
|
||||
}
|
||||
|
||||
r->cache->vary = h->value;
|
||||
|
||||
r->cache->vary = vary;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
@ -5113,6 +5310,7 @@ ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
if (offset) {
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset);
|
||||
*ph = ho;
|
||||
ho->next = NULL;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@ -5123,18 +5321,8 @@ static ngx_int_t
|
||||
ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_array_t *pa;
|
||||
ngx_table_elt_t *ho, **ph;
|
||||
|
||||
pa = (ngx_array_t *) ((char *) &r->headers_out + offset);
|
||||
|
||||
if (pa->elts == NULL) {
|
||||
if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
@ -5142,12 +5330,12 @@ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
|
||||
|
||||
*ho = *h;
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
ph = (ngx_table_elt_t **) ((char *) &r->headers_out + offset);
|
||||
|
||||
while (*ph) { ph = &(*ph)->next; }
|
||||
|
||||
*ph = ho;
|
||||
ho->next = NULL;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -5217,6 +5405,7 @@ ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
r->headers_out.last_modified = ho;
|
||||
r->headers_out.last_modified_time =
|
||||
@ -5239,6 +5428,7 @@ ngx_http_upstream_rewrite_location(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
if (r->upstream->rewrite_redirect) {
|
||||
rc = r->upstream->rewrite_redirect(r, ho, 0);
|
||||
@ -5284,6 +5474,7 @@ ngx_http_upstream_rewrite_refresh(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
if (r->upstream->rewrite_redirect) {
|
||||
|
||||
@ -5329,6 +5520,7 @@ ngx_http_upstream_rewrite_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
if (r->upstream->rewrite_cookie) {
|
||||
rc = r->upstream->rewrite_cookie(r, ho);
|
||||
@ -5382,6 +5574,7 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
ho->next = NULL;
|
||||
|
||||
r->headers_out.accept_ranges = ho;
|
||||
|
||||
@ -5389,29 +5582,6 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_copy_content_encoding(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *h, ngx_uint_t offset)
|
||||
{
|
||||
ngx_table_elt_t *ho;
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
r->headers_out.content_encoding = ho;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
@ -5723,7 +5893,7 @@ ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
|
||||
return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data,
|
||||
&r->upstream->headers_in.headers.part,
|
||||
sizeof("upstream_http_") - 1);
|
||||
}
|
||||
@ -5738,7 +5908,7 @@ ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
|
||||
return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data,
|
||||
&r->upstream->headers_in.trailers.part,
|
||||
sizeof("upstream_trailer_") - 1);
|
||||
}
|
||||
@ -5760,9 +5930,9 @@ ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
s.len = name->len - (sizeof("upstream_cookie_") - 1);
|
||||
s.data = name->data + sizeof("upstream_cookie_") - 1;
|
||||
|
||||
if (ngx_http_parse_set_cookie_lines(&r->upstream->headers_in.cookies,
|
||||
if (ngx_http_parse_set_cookie_lines(r, r->upstream->headers_in.set_cookie,
|
||||
&s, &cookie)
|
||||
== NGX_DECLINED)
|
||||
== NULL)
|
||||
{
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
|
@ -280,23 +280,21 @@ typedef struct {
|
||||
|
||||
ngx_table_elt_t *last_modified;
|
||||
ngx_table_elt_t *location;
|
||||
ngx_table_elt_t *accept_ranges;
|
||||
ngx_table_elt_t *refresh;
|
||||
ngx_table_elt_t *www_authenticate;
|
||||
ngx_table_elt_t *transfer_encoding;
|
||||
ngx_table_elt_t *vary;
|
||||
|
||||
#if (NGX_HTTP_GZIP)
|
||||
ngx_table_elt_t *content_encoding;
|
||||
#endif
|
||||
|
||||
ngx_array_t cache_control;
|
||||
ngx_array_t cookies;
|
||||
ngx_table_elt_t *cache_control;
|
||||
ngx_table_elt_t *set_cookie;
|
||||
|
||||
off_t content_length_n;
|
||||
time_t last_modified_time;
|
||||
|
||||
unsigned connection_close:1;
|
||||
unsigned chunked:1;
|
||||
unsigned no_cache:1;
|
||||
unsigned expired:1;
|
||||
} ngx_http_upstream_headers_in_t;
|
||||
|
||||
|
||||
|
@ -27,8 +27,6 @@ static ngx_int_t ngx_http_variable_header(ngx_http_request_t *r,
|
||||
|
||||
static ngx_int_t ngx_http_variable_cookies(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_headers(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_variable_headers_internal(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data, u_char sep);
|
||||
|
||||
@ -178,12 +176,12 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
#endif
|
||||
|
||||
#if (NGX_HTTP_X_FORWARDED_FOR)
|
||||
{ ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_headers,
|
||||
{ ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
|
||||
#endif
|
||||
|
||||
{ ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
|
||||
offsetof(ngx_http_request_t, headers_in.cookies), 0, 0 },
|
||||
offsetof(ngx_http_request_t, headers_in.cookie), 0, 0 },
|
||||
|
||||
{ ngx_string("content_length"), NULL, ngx_http_variable_content_length,
|
||||
0, 0, 0 },
|
||||
@ -327,10 +325,10 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
{ ngx_string("sent_http_transfer_encoding"), NULL,
|
||||
ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_headers,
|
||||
{ ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },
|
||||
|
||||
{ ngx_string("sent_http_link"), NULL, ngx_http_variable_headers,
|
||||
{ ngx_string("sent_http_link"), NULL, ngx_http_variable_header,
|
||||
offsetof(ngx_http_request_t, headers_out.link), 0, 0 },
|
||||
|
||||
{ ngx_string("limit_rate"), ngx_http_variable_set_limit_rate,
|
||||
@ -807,22 +805,7 @@ static ngx_int_t
|
||||
ngx_http_variable_header(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
uintptr_t data)
|
||||
{
|
||||
ngx_table_elt_t *h;
|
||||
|
||||
h = *(ngx_table_elt_t **) ((char *) r + data);
|
||||
|
||||
if (h) {
|
||||
v->len = h->value.len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = h->value.data;
|
||||
|
||||
} else {
|
||||
v->not_found = 1;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
return ngx_http_variable_headers_internal(r, v, data, ',');
|
||||
}
|
||||
|
||||
|
||||
@ -834,38 +817,25 @@ ngx_http_variable_cookies(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_headers(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
return ngx_http_variable_headers_internal(r, v, data, ',');
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_variable_headers_internal(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data, u_char sep)
|
||||
{
|
||||
size_t len;
|
||||
u_char *p, *end;
|
||||
ngx_uint_t i, n;
|
||||
ngx_array_t *a;
|
||||
ngx_table_elt_t **h;
|
||||
size_t len;
|
||||
u_char *p;
|
||||
ngx_table_elt_t *h, *th;
|
||||
|
||||
a = (ngx_array_t *) ((char *) r + data);
|
||||
|
||||
n = a->nelts;
|
||||
h = a->elts;
|
||||
h = *(ngx_table_elt_t **) ((char *) r + data);
|
||||
|
||||
len = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
for (th = h; th; th = th->next) {
|
||||
|
||||
if (h[i]->hash == 0) {
|
||||
if (th->hash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
len += h[i]->value.len + 2;
|
||||
len += th->value.len + 2;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
@ -879,9 +849,9 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
|
||||
if (n == 1) {
|
||||
v->len = (*h)->value.len;
|
||||
v->data = (*h)->value.data;
|
||||
if (h->next == NULL) {
|
||||
v->len = h->value.len;
|
||||
v->data = h->value.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -894,17 +864,15 @@ ngx_http_variable_headers_internal(ngx_http_request_t *r,
|
||||
v->len = len;
|
||||
v->data = p;
|
||||
|
||||
end = p + len;
|
||||
for (th = h; th; th = th->next) {
|
||||
|
||||
for (i = 0; /* void */ ; i++) {
|
||||
|
||||
if (h[i]->hash == 0) {
|
||||
if (th->hash == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
p = ngx_copy(p, h[i]->value.data, h[i]->value.len);
|
||||
p = ngx_copy(p, th->value.data, th->value.len);
|
||||
|
||||
if (p == end) {
|
||||
if (th->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -919,7 +887,7 @@ static ngx_int_t
|
||||
ngx_http_variable_unknown_header_in(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
|
||||
return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data,
|
||||
&r->headers_in.headers.part,
|
||||
sizeof("http_") - 1);
|
||||
}
|
||||
@ -929,7 +897,7 @@ static ngx_int_t
|
||||
ngx_http_variable_unknown_header_out(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
|
||||
return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data,
|
||||
&r->headers_out.headers.part,
|
||||
sizeof("sent_http_") - 1);
|
||||
}
|
||||
@ -939,19 +907,26 @@ static ngx_int_t
|
||||
ngx_http_variable_unknown_trailer_out(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
|
||||
return ngx_http_variable_unknown_header(r, v, (ngx_str_t *) data,
|
||||
&r->headers_out.trailers.part,
|
||||
sizeof("sent_trailer_") - 1);
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
|
||||
ngx_http_variable_unknown_header(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, ngx_str_t *var,
|
||||
ngx_list_part_t *part, size_t prefix)
|
||||
{
|
||||
u_char ch;
|
||||
u_char *p, ch;
|
||||
size_t len;
|
||||
ngx_uint_t i, n;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_table_elt_t *header, *h, **ph;
|
||||
|
||||
ph = &h;
|
||||
#if (NGX_SUPPRESS_WARN)
|
||||
len = 0;
|
||||
#endif
|
||||
|
||||
header = part->elts;
|
||||
|
||||
@ -971,7 +946,11 @@ ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
|
||||
continue;
|
||||
}
|
||||
|
||||
for (n = 0; n + prefix < var->len && n < header[i].key.len; n++) {
|
||||
if (header[i].key.len != var->len - prefix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (n = 0; n < var->len - prefix; n++) {
|
||||
ch = header[i].key.data[n];
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z') {
|
||||
@ -986,18 +965,59 @@ ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var,
|
||||
}
|
||||
}
|
||||
|
||||
if (n + prefix == var->len && n == header[i].key.len) {
|
||||
v->len = header[i].value.len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = header[i].value.data;
|
||||
|
||||
return NGX_OK;
|
||||
if (n != var->len - prefix) {
|
||||
continue;
|
||||
}
|
||||
|
||||
len += header[i].value.len + 2;
|
||||
|
||||
*ph = &header[i];
|
||||
ph = &header[i].next;
|
||||
}
|
||||
|
||||
v->not_found = 1;
|
||||
*ph = NULL;
|
||||
|
||||
if (h == NULL) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
len -= 2;
|
||||
|
||||
if (h->next == NULL) {
|
||||
|
||||
v->len = h->value.len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = h->value.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
p = ngx_pnalloc(r->pool, len);
|
||||
if (p == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
v->len = len;
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->data = p;
|
||||
|
||||
for ( ;; ) {
|
||||
|
||||
p = ngx_copy(p, h->value.data, h->value.len);
|
||||
|
||||
if (h->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
*p++ = ','; *p++ = ' ';
|
||||
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
@ -1050,8 +1070,8 @@ ngx_http_variable_cookie(ngx_http_request_t *r, ngx_http_variable_value_t *v,
|
||||
s.len = name->len - (sizeof("cookie_") - 1);
|
||||
s.data = name->data + sizeof("cookie_") - 1;
|
||||
|
||||
if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &s, &cookie)
|
||||
== NGX_DECLINED)
|
||||
if (ngx_http_parse_multi_header_lines(r, r->headers_in.cookie, &s, &cookie)
|
||||
== NULL)
|
||||
{
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
@ -1879,7 +1899,7 @@ ngx_http_variable_sent_location(ngx_http_request_t *r,
|
||||
|
||||
ngx_str_set(&name, "sent_http_location");
|
||||
|
||||
return ngx_http_variable_unknown_header(v, &name,
|
||||
return ngx_http_variable_unknown_header(r, v, &name,
|
||||
&r->headers_out.headers.part,
|
||||
sizeof("sent_http_") - 1);
|
||||
}
|
||||
|
@ -57,8 +57,9 @@ ngx_http_variable_value_t *ngx_http_get_flushed_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r,
|
||||
ngx_str_t *name, ngx_uint_t key);
|
||||
|
||||
ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
|
||||
ngx_str_t *var, ngx_list_part_t *part, size_t prefix);
|
||||
ngx_int_t ngx_http_variable_unknown_header(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, ngx_str_t *var, ngx_list_part_t *part,
|
||||
size_t prefix);
|
||||
|
||||
|
||||
#if (NGX_PCRE)
|
||||
|
@ -674,14 +674,14 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
static ngx_int_t
|
||||
ngx_http_v2_push_resources(ngx_http_request_t *r)
|
||||
{
|
||||
u_char *start, *end, *last;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t path;
|
||||
ngx_uint_t i, push;
|
||||
ngx_table_elt_t **h;
|
||||
ngx_http_v2_loc_conf_t *h2lcf;
|
||||
ngx_http_complex_value_t *pushes;
|
||||
ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS];
|
||||
u_char *start, *end, *last;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t path;
|
||||
ngx_uint_t i, push;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_http_v2_loc_conf_t *h2lcf;
|
||||
ngx_http_complex_value_t *pushes;
|
||||
ngx_str_t binary[NGX_HTTP_V2_PUSH_HEADERS];
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http2 push resources");
|
||||
@ -725,15 +725,13 @@ ngx_http_v2_push_resources(ngx_http_request_t *r)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
h = r->headers_out.link.elts;
|
||||
|
||||
for (i = 0; i < r->headers_out.link.nelts; i++) {
|
||||
for (h = r->headers_out.link; h; h = h->next) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http2 parse link: \"%V\"", &h[i]->value);
|
||||
"http2 parse link: \"%V\"", &h->value);
|
||||
|
||||
start = h[i]->value.data;
|
||||
end = h[i]->value.data + h[i]->value.len;
|
||||
start = h->value.data;
|
||||
end = h->value.data + h->value.len;
|
||||
|
||||
next_link:
|
||||
|
||||
|
@ -609,13 +609,13 @@ ngx_http_v3_header_filter(ngx_http_request_t *r)
|
||||
static ngx_int_t
|
||||
ngx_http_v3_push_resources(ngx_http_request_t *r, ngx_chain_t ***out)
|
||||
{
|
||||
u_char *start, *end, *last;
|
||||
ngx_str_t path;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, push;
|
||||
ngx_table_elt_t **h;
|
||||
ngx_http_v3_loc_conf_t *h3lcf;
|
||||
ngx_http_complex_value_t *pushes;
|
||||
u_char *start, *end, *last;
|
||||
ngx_str_t path;
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t i, push;
|
||||
ngx_table_elt_t *h;
|
||||
ngx_http_v3_loc_conf_t *h3lcf;
|
||||
ngx_http_complex_value_t *pushes;
|
||||
|
||||
h3lcf = ngx_http_get_module_loc_conf(r, ngx_http_v3_module);
|
||||
|
||||
@ -654,15 +654,13 @@ ngx_http_v3_push_resources(ngx_http_request_t *r, ngx_chain_t ***out)
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
h = r->headers_out.link.elts;
|
||||
|
||||
for (i = 0; i < r->headers_out.link.nelts; i++) {
|
||||
for (h = r->headers_out.link; h; h = h->next) {
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http3 parse link: \"%V\"", &h[i]->value);
|
||||
"http3 parse link: \"%V\"", &h->value);
|
||||
|
||||
start = h[i]->value.data;
|
||||
end = h[i]->value.data + h[i]->value.len;
|
||||
start = h->value.data;
|
||||
end = h->value.data + h->value.len;
|
||||
|
||||
next_link:
|
||||
|
||||
|
@ -55,7 +55,9 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit)
|
||||
|
||||
#if (NGX_HAVE_EPOLLRDHUP)
|
||||
|
||||
if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
|
||||
if ((ngx_event_flags & NGX_USE_EPOLL_EVENT)
|
||||
&& ngx_use_epoll_rdhup)
|
||||
{
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"readv: eof:%d, avail:%d",
|
||||
rev->pending_eof, rev->available);
|
||||
|
@ -52,7 +52,9 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
|
||||
|
||||
#if (NGX_HAVE_EPOLLRDHUP)
|
||||
|
||||
if (ngx_event_flags & NGX_USE_EPOLL_EVENT) {
|
||||
if ((ngx_event_flags & NGX_USE_EPOLL_EVENT)
|
||||
&& ngx_use_epoll_rdhup)
|
||||
{
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||
"recv: eof:%d, avail:%d",
|
||||
rev->pending_eof, rev->available);
|
||||
|
@ -1069,8 +1069,10 @@ ngx_stream_proxy_ssl_init_connection(ngx_stream_session_t *s)
|
||||
}
|
||||
}
|
||||
|
||||
if (pscf->ssl_certificate && (pscf->ssl_certificate->lengths
|
||||
|| pscf->ssl_certificate_key->lengths))
|
||||
if (pscf->ssl_certificate
|
||||
&& pscf->ssl_certificate->value.len
|
||||
&& (pscf->ssl_certificate->lengths
|
||||
|| pscf->ssl_certificate_key->lengths))
|
||||
{
|
||||
if (ngx_stream_proxy_ssl_certificate(s) != NGX_OK) {
|
||||
ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
|
||||
@ -1735,7 +1737,7 @@ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream,
|
||||
|
||||
cl->buf->temporary = (n ? 1 : 0);
|
||||
cl->buf->last_buf = src->read->eof;
|
||||
cl->buf->flush = 1;
|
||||
cl->buf->flush = !src->read->eof;
|
||||
|
||||
(*packets)++;
|
||||
*received += n;
|
||||
@ -2240,8 +2242,9 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (pscf->ssl_certificate) {
|
||||
|
||||
if (pscf->ssl_certificate
|
||||
&& pscf->ssl_certificate->value.len)
|
||||
{
|
||||
if (pscf->ssl_certificate_key == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"no \"proxy_ssl_certificate_key\" is defined "
|
||||
|
Loading…
Reference in New Issue
Block a user