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_;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue