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_;
}
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;
}
response_content_length_ = -1;
if (util::strifind(response_headers_[idx].value.c_str(), "chunked")) {
chunked_response_ = true;
}
}
}

View File

@ -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.

View File

@ -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