nghttpx: Allow accepting trailer part in h1 frontend
Downstream's headers mutation functions have been rewritten to share code.
This commit is contained in:
parent
9ffbc45ba6
commit
b9d6fff962
|
@ -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 {
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
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(
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
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:
|
||||||
// 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:
|
||||||
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:
|
||||||
// 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:
|
||||||
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:
|
||||||
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) {
|
||||||
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,15 +83,20 @@ 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
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (downstream->get_request_header_key_prev()) {
|
if (downstream->get_request_header_key_prev()) {
|
||||||
downstream->append_last_request_header_key(data, len);
|
downstream->append_last_request_header_key(data, len);
|
||||||
} else {
|
} else {
|
||||||
downstream->add_request_header(std::string(data, len), "");
|
downstream->add_request_header(std::string(data, len), "");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 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)) {
|
||||||
ULOG(INFO, upstream) << "Too large header block size="
|
ULOG(INFO, upstream) << "Too large header block size="
|
||||||
|
@ -107,15 +112,19 @@ 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
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (downstream->get_request_header_key_prev()) {
|
if (downstream->get_request_header_key_prev()) {
|
||||||
downstream->set_last_request_header_value(std::string(data, len));
|
downstream->set_last_request_header_value(data, len);
|
||||||
} else {
|
} else {
|
||||||
downstream->append_last_request_header_value(data, len);
|
downstream->append_last_request_header_value(data, len);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
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)) {
|
||||||
ULOG(INFO, upstream) << "Too large header block size="
|
ULOG(INFO, upstream) << "Too large header block size="
|
||||||
|
|
Loading…
Reference in New Issue