nghttpx: Return 502 if HTTP/1 downstream receives multiple CLs

This commit is contained in:
Tatsuhiro Tsujikawa 2015-01-20 23:11:54 +09:00
parent a789008f17
commit ca7288ae38
3 changed files with 28 additions and 27 deletions

View File

@ -286,9 +286,10 @@ const std::string &Downstream::get_assembled_request_cookie() const {
return assembled_request_cookie_; return assembled_request_cookie_;
} }
int Downstream::index_request_headers() { namespace {
for (size_t i = 0; i < request_headers_.size(); ++i) { int index_headers(int *hdidx, Headers &headers, int64_t &content_length) {
auto &kv = request_headers_[i]; for (size_t i = 0; i < headers.size(); ++i) {
auto &kv = headers[i];
util::inp_strlower(kv.name); util::inp_strlower(kv.name);
auto token = http2::lookup_token( auto token = http2::lookup_token(
@ -297,21 +298,27 @@ int Downstream::index_request_headers() {
continue; continue;
} }
http2::index_header(request_hdidx_, token, i); http2::index_header(hdidx, token, i);
if (token == http2::HD_CONTENT_LENGTH) { if (token == http2::HD_CONTENT_LENGTH) {
auto len = util::parse_uint(kv.value); auto len = util::parse_uint(kv.value);
if (len == -1) { if (len == -1) {
return -1; return -1;
} }
if (request_content_length_ != -1 && request_content_length_ != len) { if (content_length != -1 && content_length != len) {
return -1; return -1;
} }
request_content_length_ = len; content_length = len;
} }
} }
return 0; 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 { const Headers::value_type *Downstream::get_request_header(int token) const {
return http2::get_header(request_hdidx_, token, request_headers_); return http2::get_header(request_hdidx_, token, request_headers_);
@ -511,11 +518,9 @@ const Headers &Downstream::get_response_headers() const {
return response_headers_; return response_headers_;
} }
void Downstream::index_response_headers() { int Downstream::index_response_headers() {
for (auto &kv : response_headers_) { return index_headers(response_hdidx_, response_headers_,
util::inp_strlower(kv.name); response_content_length_);
}
http2::index_headers(response_hdidx_, response_headers_);
} }
const Headers::value_type *Downstream::get_response_header(int token) const { 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() { void Downstream::inspect_http1_response() {
auto idx = response_hdidx_[http2::HD_TRANSFER_ENCODING]; auto idx = response_hdidx_[http2::HD_TRANSFER_ENCODING];
if (idx != -1 && if (idx != -1) {
util::strifind(response_headers_[idx].value.c_str(), "chunked")) { response_content_length_ = -1;
chunked_response_ = true; if (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;
}
} }
} }
} }

View File

@ -184,8 +184,10 @@ public:
Memchunks4K *get_request_buf(); Memchunks4K *get_request_buf();
// downstream response API // downstream response API
const Headers &get_response_headers() const; const Headers &get_response_headers() const;
// Lower the response header field names and indexes response headers // Lower the response header field names and indexes response
void index_response_headers(); // 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 // Returns pointer to the response header with the name |name|. If
// multiple header have |name| as name, return last occurrence from // multiple header have |name| as name, return last occurrence from
// the beginning. If no such header is found, returns nullptr. // the beginning. If no such header is found, returns nullptr.

View File

@ -469,7 +469,10 @@ int htp_hdrs_completecb(http_parser *htp) {
downstream->set_response_major(htp->http_major); downstream->set_response_major(htp->http_major);
downstream->set_response_minor(htp->http_minor); 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()) { if (downstream->get_non_final_response()) {
// For non-final response code, we just call // For non-final response code, we just call