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