nghttpx: Support response trailer part handling in h1 backend
This commit is contained in:
parent
60c2fe5a2e
commit
6ad63a06b0
|
@ -122,7 +122,8 @@ Downstream::Downstream(Upstream *upstream, int32_t stream_id, int32_t priority)
|
|||
request_connection_close_(false), request_header_key_prev_(false),
|
||||
request_http2_expect_body_(false), chunked_response_(false),
|
||||
response_connection_close_(false), response_header_key_prev_(false),
|
||||
expect_final_response_(false), request_pending_(false) {
|
||||
response_trailer_key_prev_(false), expect_final_response_(false),
|
||||
request_pending_(false) {
|
||||
|
||||
ev_timer_init(&upstream_rtimer_, &upstream_rtimeoutcb, 0.,
|
||||
get_config()->stream_read_timeout);
|
||||
|
@ -679,6 +680,39 @@ unsigned int Downstream::get_response_http_status() const {
|
|||
return response_http_status_;
|
||||
}
|
||||
|
||||
void Downstream::add_response_trailer(std::string name, std::string value) {
|
||||
response_trailer_key_prev_ = true;
|
||||
response_headers_sum_ += name.size() + value.size();
|
||||
response_trailers_.emplace_back(std::move(name), std::move(value));
|
||||
}
|
||||
|
||||
bool Downstream::get_response_trailer_key_prev() const {
|
||||
return response_trailer_key_prev_;
|
||||
}
|
||||
|
||||
void Downstream::append_last_response_trailer_key(const char *data,
|
||||
size_t len) {
|
||||
assert(response_trailer_key_prev_);
|
||||
response_headers_sum_ += len;
|
||||
auto &item = response_trailers_.back();
|
||||
item.name.append(data, len);
|
||||
}
|
||||
|
||||
void Downstream::append_last_response_trailer_value(const char *data,
|
||||
size_t len) {
|
||||
assert(!response_trailer_key_prev_);
|
||||
response_headers_sum_ += 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) {
|
||||
response_http_status_ = status;
|
||||
}
|
||||
|
|
|
@ -225,6 +225,11 @@ public:
|
|||
void add_response_trailer(const uint8_t *name, size_t namelen,
|
||||
const uint8_t *value, size_t valuelen,
|
||||
bool no_index, int16_t token);
|
||||
void add_response_trailer(std::string name, std::string value);
|
||||
bool get_response_trailer_key_prev() const;
|
||||
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 set_last_response_trailer_value(std::string value);
|
||||
|
||||
unsigned int get_response_http_status() const;
|
||||
void set_response_http_status(unsigned int status);
|
||||
|
@ -405,6 +410,7 @@ private:
|
|||
bool chunked_response_;
|
||||
bool response_connection_close_;
|
||||
bool response_header_key_prev_;
|
||||
bool response_trailer_key_prev_;
|
||||
bool expect_final_response_;
|
||||
// true if downstream request is pending because backend connection
|
||||
// has not been established or should be checked before use;
|
||||
|
|
|
@ -555,14 +555,19 @@ int htp_hdrs_completecb(http_parser *htp) {
|
|||
namespace {
|
||||
int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
||||
auto downstream = static_cast<Downstream *>(htp->data);
|
||||
if (downstream->get_response_state() != Downstream::INITIAL) {
|
||||
// ignore trailers
|
||||
return 0;
|
||||
}
|
||||
if (downstream->get_response_header_key_prev()) {
|
||||
downstream->append_last_response_header_key(data, len);
|
||||
if (downstream->get_response_state() == Downstream::INITIAL) {
|
||||
if (downstream->get_response_header_key_prev()) {
|
||||
downstream->append_last_response_header_key(data, len);
|
||||
} else {
|
||||
downstream->add_response_header(std::string(data, len), "");
|
||||
}
|
||||
} else {
|
||||
downstream->add_response_header(std::string(data, len), "");
|
||||
// trailer part
|
||||
if (downstream->get_response_trailer_key_prev()) {
|
||||
downstream->append_last_response_trailer_key(data, len);
|
||||
} else {
|
||||
downstream->add_response_trailer(std::string(data, len), "");
|
||||
}
|
||||
}
|
||||
if (downstream->get_response_headers_sum() > Downstream::MAX_HEADERS_SUM) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
|
@ -578,14 +583,18 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
|||
namespace {
|
||||
int htp_hdr_valcb(http_parser *htp, const char *data, size_t len) {
|
||||
auto downstream = static_cast<Downstream *>(htp->data);
|
||||
if (downstream->get_response_state() != Downstream::INITIAL) {
|
||||
// ignore trailers
|
||||
return 0;
|
||||
}
|
||||
if (downstream->get_response_header_key_prev()) {
|
||||
downstream->set_last_response_header_value(std::string(data, len));
|
||||
if (downstream->get_response_state() == Downstream::INITIAL) {
|
||||
if (downstream->get_response_header_key_prev()) {
|
||||
downstream->set_last_response_header_value(std::string(data, len));
|
||||
} else {
|
||||
downstream->append_last_response_header_value(data, len);
|
||||
}
|
||||
} else {
|
||||
downstream->append_last_response_header_value(data, len);
|
||||
if (downstream->get_response_trailer_key_prev()) {
|
||||
downstream->set_last_response_trailer_value(std::string(data, len));
|
||||
} else {
|
||||
downstream->append_last_response_trailer_value(data, len);
|
||||
}
|
||||
}
|
||||
if (downstream->get_response_headers_sum() > Downstream::MAX_HEADERS_SUM) {
|
||||
if (LOG_ENABLED(INFO)) {
|
||||
|
|
Loading…
Reference in New Issue