nghttpx: Return 502 if HTTP/1 downstream receives multiple CLs
This commit is contained in:
parent
a789008f17
commit
ca7288ae38
|
@ -286,9 +286,10 @@ const std::string &Downstream::get_assembled_request_cookie() const {
|
|||
return assembled_request_cookie_;
|
||||
}
|
||||
|
||||
int Downstream::index_request_headers() {
|
||||
for (size_t i = 0; i < request_headers_.size(); ++i) {
|
||||
auto &kv = request_headers_[i];
|
||||
namespace {
|
||||
int index_headers(int *hdidx, Headers &headers, int64_t &content_length) {
|
||||
for (size_t i = 0; i < headers.size(); ++i) {
|
||||
auto &kv = headers[i];
|
||||
util::inp_strlower(kv.name);
|
||||
|
||||
auto token = http2::lookup_token(
|
||||
|
@ -297,21 +298,27 @@ int Downstream::index_request_headers() {
|
|||
continue;
|
||||
}
|
||||
|
||||
http2::index_header(request_hdidx_, token, i);
|
||||
http2::index_header(hdidx, token, i);
|
||||
|
||||
if (token == http2::HD_CONTENT_LENGTH) {
|
||||
auto len = util::parse_uint(kv.value);
|
||||
if (len == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (request_content_length_ != -1 && request_content_length_ != len) {
|
||||
if (content_length != -1 && content_length != len) {
|
||||
return -1;
|
||||
}
|
||||
request_content_length_ = len;
|
||||
content_length = len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int Downstream::index_request_headers() {
|
||||
return index_headers(request_hdidx_, request_headers_,
|
||||
request_content_length_);
|
||||
}
|
||||
|
||||
const Headers::value_type *Downstream::get_request_header(int token) const {
|
||||
return http2::get_header(request_hdidx_, token, request_headers_);
|
||||
|
@ -511,11 +518,9 @@ const Headers &Downstream::get_response_headers() const {
|
|||
return response_headers_;
|
||||
}
|
||||
|
||||
void Downstream::index_response_headers() {
|
||||
for (auto &kv : response_headers_) {
|
||||
util::inp_strlower(kv.name);
|
||||
}
|
||||
http2::index_headers(response_hdidx_, response_headers_);
|
||||
int Downstream::index_response_headers() {
|
||||
return index_headers(response_hdidx_, response_headers_,
|
||||
response_content_length_);
|
||||
}
|
||||
|
||||
const Headers::value_type *Downstream::get_response_header(int token) const {
|
||||
|
@ -788,19 +793,10 @@ void Downstream::inspect_http1_request() {
|
|||
|
||||
void Downstream::inspect_http1_response() {
|
||||
auto idx = response_hdidx_[http2::HD_TRANSFER_ENCODING];
|
||||
if (idx != -1 &&
|
||||
util::strifind(response_headers_[idx].value.c_str(), "chunked")) {
|
||||
chunked_response_ = true;
|
||||
}
|
||||
|
||||
// examine Content-Length only when Transfer-Encoding is missing
|
||||
if (idx == -1) {
|
||||
idx = response_hdidx_[http2::HD_CONTENT_LENGTH];
|
||||
if (idx != -1) {
|
||||
auto len = util::parse_uint(response_headers_[idx].value);
|
||||
if (len != -1) {
|
||||
response_content_length_ = len;
|
||||
}
|
||||
if (idx != -1) {
|
||||
response_content_length_ = -1;
|
||||
if (util::strifind(response_headers_[idx].value.c_str(), "chunked")) {
|
||||
chunked_response_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,8 +184,10 @@ public:
|
|||
Memchunks4K *get_request_buf();
|
||||
// downstream response API
|
||||
const Headers &get_response_headers() const;
|
||||
// Lower the response header field names and indexes response headers
|
||||
void index_response_headers();
|
||||
// Lower the response header field names and indexes response
|
||||
// headers. If there are invalid headers (e.g., multiple
|
||||
// Content-Length with different values), returns -1.
|
||||
int index_response_headers();
|
||||
// Returns pointer to the response header with the name |name|. If
|
||||
// multiple header have |name| as name, return last occurrence from
|
||||
// the beginning. If no such header is found, returns nullptr.
|
||||
|
|
|
@ -469,7 +469,10 @@ int htp_hdrs_completecb(http_parser *htp) {
|
|||
downstream->set_response_major(htp->http_major);
|
||||
downstream->set_response_minor(htp->http_minor);
|
||||
|
||||
downstream->index_response_headers();
|
||||
if (downstream->index_response_headers() != 0) {
|
||||
downstream->set_response_state(Downstream::MSG_BAD_HEADER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (downstream->get_non_final_response()) {
|
||||
// For non-final response code, we just call
|
||||
|
|
Loading…
Reference in New Issue