Mercurial > hg > nginx
comparison src/http/ngx_http_upstream.c @ 8033:2bf7792c262e
Upstream: header handlers can now return parsing errors.
With this change, duplicate Content-Length and Transfer-Encoding headers
are now rejected. Further, responses with invalid Content-Length or
Transfer-Encoding headers are now rejected, as well as responses with both
Content-Length and Transfer-Encoding.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 30 May 2022 21:25:48 +0300 |
parents | 2025aae94739 |
children | 413dbda22f7d |
comparison
equal
deleted
inserted
replaced
8032:2025aae94739 | 8033:2bf7792c262e |
---|---|
4631 { | 4631 { |
4632 ngx_http_upstream_t *u; | 4632 ngx_http_upstream_t *u; |
4633 | 4633 |
4634 u = r->upstream; | 4634 u = r->upstream; |
4635 | 4635 |
4636 if (u->headers_in.content_length) { | |
4637 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
4638 "upstream sent duplicate header line: \"%V: %V\", " | |
4639 "previous value: \"%V: %V\"", | |
4640 &h->key, &h->value, | |
4641 &u->headers_in.content_length->key, | |
4642 &u->headers_in.content_length->value); | |
4643 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
4644 } | |
4645 | |
4646 if (u->headers_in.transfer_encoding) { | |
4647 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
4648 "upstream sent \"Content-Length\" and " | |
4649 "\"Transfer-Encoding\" headers at the same time"); | |
4650 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
4651 } | |
4652 | |
4636 h->next = NULL; | 4653 h->next = NULL; |
4637 u->headers_in.content_length = h; | 4654 u->headers_in.content_length = h; |
4638 u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len); | 4655 u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len); |
4656 | |
4657 if (u->headers_in.content_length_n == NGX_ERROR) { | |
4658 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
4659 "upstream sent invalid \"Content-Length\" header: " | |
4660 "\"%V: %V\"", &h->key, &h->value); | |
4661 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
4662 } | |
4639 | 4663 |
4640 return NGX_OK; | 4664 return NGX_OK; |
4641 } | 4665 } |
4642 | 4666 |
4643 | 4667 |
5019 ngx_table_elt_t *h, ngx_uint_t offset) | 5043 ngx_table_elt_t *h, ngx_uint_t offset) |
5020 { | 5044 { |
5021 ngx_http_upstream_t *u; | 5045 ngx_http_upstream_t *u; |
5022 | 5046 |
5023 u = r->upstream; | 5047 u = r->upstream; |
5048 | |
5049 if (u->headers_in.transfer_encoding) { | |
5050 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
5051 "upstream sent duplicate header line: \"%V: %V\", " | |
5052 "previous value: \"%V: %V\"", | |
5053 &h->key, &h->value, | |
5054 &u->headers_in.transfer_encoding->key, | |
5055 &u->headers_in.transfer_encoding->value); | |
5056 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
5057 } | |
5058 | |
5059 if (u->headers_in.content_length) { | |
5060 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
5061 "upstream sent \"Content-Length\" and " | |
5062 "\"Transfer-Encoding\" headers at the same time"); | |
5063 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
5064 } | |
5065 | |
5024 u->headers_in.transfer_encoding = h; | 5066 u->headers_in.transfer_encoding = h; |
5025 h->next = NULL; | 5067 h->next = NULL; |
5026 | 5068 |
5027 if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, | 5069 if (h->value.len == 7 |
5028 (u_char *) "chunked", 7 - 1) | 5070 && ngx_strncasecmp(h->value.data, (u_char *) "chunked", 7) == 0) |
5029 != NULL) | |
5030 { | 5071 { |
5031 u->headers_in.chunked = 1; | 5072 u->headers_in.chunked = 1; |
5073 | |
5074 } else { | |
5075 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
5076 "upstream sent unknown \"Transfer-Encoding\": \"%V\"", | |
5077 &h->value); | |
5078 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | |
5032 } | 5079 } |
5033 | 5080 |
5034 return NGX_OK; | 5081 return NGX_OK; |
5035 } | 5082 } |
5036 | 5083 |