Commit b9d6fff9 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Allow accepting trailer part in h1 frontend

Downstream's headers mutation functions have been rewritten to share
code.
parent 9ffbc45b
...@@ -120,10 +120,10 @@ Downstream::Downstream(Upstream *upstream, int32_t stream_id, int32_t priority) ...@@ -120,10 +120,10 @@ Downstream::Downstream(Upstream *upstream, int32_t stream_id, int32_t priority)
response_minor_(1), upgrade_request_(false), upgraded_(false), response_minor_(1), upgrade_request_(false), upgraded_(false),
http2_upgrade_seen_(false), chunked_request_(false), http2_upgrade_seen_(false), chunked_request_(false),
request_connection_close_(false), request_header_key_prev_(false), request_connection_close_(false), request_header_key_prev_(false),
request_http2_expect_body_(false), chunked_response_(false), request_trailer_key_prev_(false), request_http2_expect_body_(false),
response_connection_close_(false), response_header_key_prev_(false), chunked_response_(false), response_connection_close_(false),
response_trailer_key_prev_(false), expect_final_response_(false), response_header_key_prev_(false), response_trailer_key_prev_(false),
request_pending_(false) { expect_final_response_(false), request_pending_(false) {
ev_timer_init(&upstream_rtimer_, &upstream_rtimeoutcb, 0., ev_timer_init(&upstream_rtimer_, &upstream_rtimeoutcb, 0.,
get_config()->stream_read_timeout); get_config()->stream_read_timeout);
...@@ -288,6 +288,45 @@ const std::string &Downstream::get_assembled_request_cookie() const { ...@@ -288,6 +288,45 @@ const std::string &Downstream::get_assembled_request_cookie() const {
return assembled_request_cookie_; return assembled_request_cookie_;
} }
namespace {
void add_header(bool &key_prev, size_t &sum, Headers &headers, std::string name,
std::string value) {
key_prev = true;
sum += name.size() + value.size();
headers.emplace_back(std::move(name), std::move(value));
}
} // namespace
namespace {
void append_last_header_key(bool key_prev, size_t &sum, Headers &headers,
const char *data, size_t len) {
assert(key_prev);
sum += len;
auto &item = headers.back();
item.name.append(data, len);
}
} // namespace
namespace {
void append_last_header_value(bool key_prev, size_t &sum, Headers &headers,
const char *data, size_t len) {
assert(!key_prev);
sum += len;
auto &item = headers.back();
item.value.append(data, len);
}
} // namespace
namespace {
void set_last_header_value(bool &key_prev, size_t &sum, Headers &headers,
const char *data, size_t len) {
key_prev = false;
sum += len;
auto &item = headers.back();
item.value.assign(data, len);
}
} // namespace
namespace { namespace {
int index_headers(http2::HeaderIndex &hdidx, Headers &headers, int index_headers(http2::HeaderIndex &hdidx, Headers &headers,
int64_t &content_length) { int64_t &content_length) {
...@@ -334,16 +373,13 @@ Downstream::get_request_header(const std::string &name) const { ...@@ -334,16 +373,13 @@ Downstream::get_request_header(const std::string &name) const {
} }
void Downstream::add_request_header(std::string name, std::string value) { void Downstream::add_request_header(std::string name, std::string value) {
request_header_key_prev_ = true; add_header(request_header_key_prev_, request_headers_sum_, request_headers_,
request_headers_sum_ += name.size() + value.size(); std::move(name), std::move(value));
request_headers_.emplace_back(std::move(name), std::move(value));
} }
void Downstream::set_last_request_header_value(std::string value) { void Downstream::set_last_request_header_value(const char *data, size_t len) {
request_header_key_prev_ = false; set_last_header_value(request_header_key_prev_, request_headers_sum_,
request_headers_sum_ += value.size(); request_headers_, data, len);
Headers::value_type &item = request_headers_.back();
item.value = std::move(value);
} }
void Downstream::add_request_header(const uint8_t *name, size_t namelen, void Downstream::add_request_header(const uint8_t *name, size_t namelen,
...@@ -360,18 +396,14 @@ bool Downstream::get_request_header_key_prev() const { ...@@ -360,18 +396,14 @@ bool Downstream::get_request_header_key_prev() const {
} }
void Downstream::append_last_request_header_key(const char *data, size_t len) { void Downstream::append_last_request_header_key(const char *data, size_t len) {
assert(request_header_key_prev_); append_last_header_key(request_header_key_prev_, request_headers_sum_,
request_headers_sum_ += len; request_headers_, data, len);
auto &item = request_headers_.back();
item.name.append(data, len);
} }
void Downstream::append_last_request_header_value(const char *data, void Downstream::append_last_request_header_value(const char *data,
size_t len) { size_t len) {
assert(!request_header_key_prev_); append_last_header_value(request_header_key_prev_, request_headers_sum_,
request_headers_sum_ += len; request_headers_, data, len);
auto &item = request_headers_.back();
item.value.append(data, len);
} }
void Downstream::clear_request_headers() { void Downstream::clear_request_headers() {
...@@ -397,6 +429,31 @@ const Headers &Downstream::get_request_trailers() const { ...@@ -397,6 +429,31 @@ const Headers &Downstream::get_request_trailers() const {
return request_trailers_; return request_trailers_;
} }
void Downstream::add_request_trailer(std::string name, std::string value) {
add_header(request_trailer_key_prev_, request_headers_sum_, request_trailers_,
std::move(name), std::move(value));
}
void Downstream::set_last_request_trailer_value(const char *data, size_t len) {
set_last_header_value(request_trailer_key_prev_, request_headers_sum_,
request_trailers_, data, len);
}
bool Downstream::get_request_trailer_key_prev() const {
return request_trailer_key_prev_;
}
void Downstream::append_last_request_trailer_key(const char *data, size_t len) {
append_last_header_key(request_trailer_key_prev_, request_headers_sum_,
request_trailers_, data, len);
}
void Downstream::append_last_request_trailer_value(const char *data,
size_t len) {
append_last_header_value(request_trailer_key_prev_, request_headers_sum_,
request_trailers_, data, len);
}
void Downstream::set_request_method(std::string method) { void Downstream::set_request_method(std::string method) {
request_method_ = std::move(method); request_method_ = std::move(method);
} }
...@@ -607,16 +664,13 @@ void Downstream::rewrite_location_response_header( ...@@ -607,16 +664,13 @@ void Downstream::rewrite_location_response_header(
} }
void Downstream::add_response_header(std::string name, std::string value) { void Downstream::add_response_header(std::string name, std::string value) {
response_header_key_prev_ = true; add_header(response_header_key_prev_, response_headers_sum_,
response_headers_sum_ += name.size() + value.size(); response_headers_, std::move(name), std::move(value));
response_headers_.emplace_back(std::move(name), std::move(value));
} }
void Downstream::set_last_response_header_value(std::string value) { void Downstream::set_last_response_header_value(const char *data, size_t len) {
response_header_key_prev_ = false; set_last_header_value(response_header_key_prev_, response_headers_sum_,
response_headers_sum_ += value.size(); response_headers_, data, len);
auto &item = response_headers_.back();
item.value = std::move(value);
} }
void Downstream::add_response_header(std::string name, std::string value, void Downstream::add_response_header(std::string name, std::string value,
...@@ -641,18 +695,14 @@ bool Downstream::get_response_header_key_prev() const { ...@@ -641,18 +695,14 @@ bool Downstream::get_response_header_key_prev() const {
} }
void Downstream::append_last_response_header_key(const char *data, size_t len) { void Downstream::append_last_response_header_key(const char *data, size_t len) {
assert(response_header_key_prev_); append_last_header_key(response_header_key_prev_, response_headers_sum_,
response_headers_sum_ += len; response_headers_, data, len);
auto &item = response_headers_.back();
item.name.append(data, len);
} }
void Downstream::append_last_response_header_value(const char *data, void Downstream::append_last_response_header_value(const char *data,
size_t len) { size_t len) {
assert(!response_header_key_prev_); append_last_header_value(response_header_key_prev_, response_headers_sum_,
response_headers_sum_ += len; response_headers_, data, len);
auto &item = response_headers_.back();
item.value.append(data, len);
} }
void Downstream::clear_response_headers() { void Downstream::clear_response_headers() {
...@@ -681,9 +731,13 @@ unsigned int Downstream::get_response_http_status() const { ...@@ -681,9 +731,13 @@ unsigned int Downstream::get_response_http_status() const {
} }
void Downstream::add_response_trailer(std::string name, std::string value) { void Downstream::add_response_trailer(std::string name, std::string value) {
response_trailer_key_prev_ = true; add_header(response_trailer_key_prev_, response_headers_sum_,
response_headers_sum_ += name.size() + value.size(); response_trailers_, std::move(name), std::move(value));
response_trailers_.emplace_back(std::move(name), std::move(value)); }
void Downstream::set_last_response_trailer_value(const char *data, size_t len) {
set_last_header_value(response_trailer_key_prev_, response_headers_sum_,
response_trailers_, data, len);
} }
bool Downstream::get_response_trailer_key_prev() const { bool Downstream::get_response_trailer_key_prev() const {
...@@ -692,25 +746,14 @@ bool Downstream::get_response_trailer_key_prev() const { ...@@ -692,25 +746,14 @@ bool Downstream::get_response_trailer_key_prev() const {
void Downstream::append_last_response_trailer_key(const char *data, void Downstream::append_last_response_trailer_key(const char *data,
size_t len) { size_t len) {
assert(response_trailer_key_prev_); append_last_header_key(response_trailer_key_prev_, response_headers_sum_,
response_headers_sum_ += len; response_trailers_, data, len);
auto &item = response_trailers_.back();
item.name.append(data, len);
} }
void Downstream::append_last_response_trailer_value(const char *data, void Downstream::append_last_response_trailer_value(const char *data,
size_t len) { size_t len) {
assert(!response_trailer_key_prev_); append_last_header_value(response_trailer_key_prev_, response_headers_sum_,
response_headers_sum_ += len; response_trailers_, data, len);
auto &item = response_trailers_.back();
item.value.append(data, len);
}
void Downstream::set_last_response_trailer_value(std::string value) {
response_trailer_key_prev_ = false;
response_headers_sum_ += value.size();
auto &item = response_trailers_.back();
item.value = std::move(value);
} }
void Downstream::set_response_http_status(unsigned int status) { void Downstream::set_response_http_status(unsigned int status) {
......
...@@ -113,7 +113,7 @@ public: ...@@ -113,7 +113,7 @@ public:
// no such header is found, returns nullptr. // no such header is found, returns nullptr.
const Headers::value_type *get_request_header(const std::string &name) const; const Headers::value_type *get_request_header(const std::string &name) const;
void add_request_header(std::string name, std::string value); void add_request_header(std::string name, std::string value);
void set_last_request_header_value(std::string value); void set_last_request_header_value(const char *data, size_t len);
void add_request_header(const uint8_t *name, size_t namelen, void add_request_header(const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen, bool no_index, const uint8_t *value, size_t valuelen, bool no_index,
...@@ -131,6 +131,11 @@ public: ...@@ -131,6 +131,11 @@ public:
void add_request_trailer(const uint8_t *name, size_t namelen, void add_request_trailer(const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen, bool no_index, const uint8_t *value, size_t valuelen, bool no_index,
int16_t token); int16_t token);
void add_request_trailer(std::string name, std::string value);
void set_last_request_trailer_value(const char *data, size_t len);
bool get_request_trailer_key_prev() const;
void append_last_request_trailer_key(const char *data, size_t len);
void append_last_request_trailer_value(const char *data, size_t len);
void set_request_method(std::string method); void set_request_method(std::string method);
const std::string &get_request_method() const; const std::string &get_request_method() const;
...@@ -206,7 +211,7 @@ public: ...@@ -206,7 +211,7 @@ public:
// Rewrites the location response header field. // Rewrites the location response header field.
void rewrite_location_response_header(const std::string &upstream_scheme); void rewrite_location_response_header(const std::string &upstream_scheme);
void add_response_header(std::string name, std::string value); void add_response_header(std::string name, std::string value);
void set_last_response_header_value(std::string value); void set_last_response_header_value(const char *data, size_t len);
void add_response_header(std::string name, std::string value, int16_t token); void add_response_header(std::string name, std::string value, int16_t token);
void add_response_header(const uint8_t *name, size_t namelen, void add_response_header(const uint8_t *name, size_t namelen,
...@@ -226,10 +231,10 @@ public: ...@@ -226,10 +231,10 @@ public:
const uint8_t *value, size_t valuelen, const uint8_t *value, size_t valuelen,
bool no_index, int16_t token); bool no_index, int16_t token);
void add_response_trailer(std::string name, std::string value); void add_response_trailer(std::string name, std::string value);
void set_last_response_trailer_value(const char *data, size_t len);
bool get_response_trailer_key_prev() const; bool get_response_trailer_key_prev() const;
void append_last_response_trailer_key(const char *data, size_t len); void append_last_response_trailer_key(const char *data, size_t len);
void append_last_response_trailer_value(const char *data, size_t len); void append_last_response_trailer_value(const char *data, size_t len);
void set_last_response_trailer_value(std::string value);
unsigned int get_response_http_status() const; unsigned int get_response_http_status() const;
void set_response_http_status(unsigned int status); void set_response_http_status(unsigned int status);
...@@ -405,6 +410,7 @@ private: ...@@ -405,6 +410,7 @@ private:
bool chunked_request_; bool chunked_request_;
bool request_connection_close_; bool request_connection_close_;
bool request_header_key_prev_; bool request_header_key_prev_;
bool request_trailer_key_prev_;
bool request_http2_expect_body_; bool request_http2_expect_body_;
bool chunked_response_; bool chunked_response_;
......
...@@ -594,13 +594,13 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) { ...@@ -594,13 +594,13 @@ int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
auto downstream = static_cast<Downstream *>(htp->data); auto downstream = static_cast<Downstream *>(htp->data);
if (downstream->get_response_state() == Downstream::INITIAL) { if (downstream->get_response_state() == Downstream::INITIAL) {
if (downstream->get_response_header_key_prev()) { if (downstream->get_response_header_key_prev()) {
downstream->set_last_response_header_value(std::string(data, len)); downstream->set_last_response_header_value(data, len);
} else { } else {
downstream->append_last_response_header_value(data, len); downstream->append_last_response_header_value(data, len);
} }
} else { } else {
if (downstream->get_response_trailer_key_prev()) { if (downstream->get_response_trailer_key_prev()) {
downstream->set_last_response_trailer_value(std::string(data, len)); downstream->set_last_response_trailer_value(data, len);
} else { } else {
downstream->append_last_response_trailer_value(data, len); downstream->append_last_response_trailer_value(data, len);
} }
......
...@@ -83,14 +83,19 @@ namespace { ...@@ -83,14 +83,19 @@ namespace {
int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) { int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
auto upstream = static_cast<HttpsUpstream *>(htp->data); auto upstream = static_cast<HttpsUpstream *>(htp->data);
auto downstream = upstream->get_downstream(); auto downstream = upstream->get_downstream();
if (downstream->get_request_state() != Downstream::INITIAL) { if (downstream->get_request_state() == Downstream::INITIAL) {
// ignore trailers if (downstream->get_request_header_key_prev()) {
return 0; downstream->append_last_request_header_key(data, len);
} } else {
if (downstream->get_request_header_key_prev()) { downstream->add_request_header(std::string(data, len), "");
downstream->append_last_request_header_key(data, len); }
} else { } else {
downstream->add_request_header(std::string(data, len), ""); // trailer part
if (downstream->get_request_trailer_key_prev()) {
downstream->append_last_request_trailer_key(data, len);
} else {
downstream->add_request_trailer(std::string(data, len), "");
}
} }
if (downstream->get_request_headers_sum() > Downstream::MAX_HEADERS_SUM) { if (downstream->get_request_headers_sum() > Downstream::MAX_HEADERS_SUM) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
...@@ -107,14 +112,18 @@ namespace { ...@@ -107,14 +112,18 @@ namespace {
int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) { int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
auto upstream = static_cast<HttpsUpstream *>(htp->data); auto upstream = static_cast<HttpsUpstream *>(htp->data);
auto downstream = upstream->get_downstream(); auto downstream = upstream->get_downstream();
if (downstream->get_request_state() != Downstream::INITIAL) { if (downstream->get_request_state() == Downstream::INITIAL) {
// ignore trailers if (downstream->get_request_header_key_prev()) {
return 0; downstream->set_last_request_header_value(data, len);
} } else {
if (downstream->get_request_header_key_prev()) { downstream->append_last_request_header_value(data, len);
downstream->set_last_request_header_value(std::string(data, len)); }
} else { } else {
downstream->append_last_request_header_value(data, len); if (downstream->get_request_trailer_key_prev()) {
downstream->set_last_request_trailer_value(data, len);
} else {
downstream->append_last_request_trailer_value(data, len);
}
} }
if (downstream->get_request_headers_sum() > Downstream::MAX_HEADERS_SUM) { if (downstream->get_request_headers_sum() > Downstream::MAX_HEADERS_SUM) {
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment