nghttpx: Fix backend stall if header and request body are sent in 2 packets

This commit is contained in:
Tatsuhiro Tsujikawa 2019-01-23 17:57:12 +09:00
parent 8dc2b263ba
commit d93842db3e
4 changed files with 39 additions and 2 deletions

View File

@ -640,7 +640,7 @@ int Downstream::push_request_headers() {
int Downstream::push_upload_data_chunk(const uint8_t *data, size_t datalen) { int Downstream::push_upload_data_chunk(const uint8_t *data, size_t datalen) {
req_.recv_body_length += datalen; req_.recv_body_length += datalen;
if (!request_header_sent_) { if (!dconn_ && !request_header_sent_) {
blocked_request_buf_.append(data, datalen); blocked_request_buf_.append(data, datalen);
req_.unconsumed_body_length += datalen; req_.unconsumed_body_length += datalen;
return 0; return 0;
@ -662,7 +662,7 @@ int Downstream::push_upload_data_chunk(const uint8_t *data, size_t datalen) {
} }
int Downstream::end_upload_data() { int Downstream::end_upload_data() {
if (!request_header_sent_) { if (!dconn_ && !request_header_sent_) {
blocked_request_data_eof_ = true; blocked_request_data_eof_ = true;
return 0; return 0;
} }
@ -1141,6 +1141,10 @@ bool Downstream::get_blocked_request_data_eof() const {
return blocked_request_data_eof_; return blocked_request_data_eof_;
} }
void Downstream::set_blocked_request_data_eof(bool f) {
blocked_request_data_eof_ = f;
}
void Downstream::set_ws_key(const StringRef &key) { ws_key_ = key; } void Downstream::set_ws_key(const StringRef &key) { ws_key_ = key; }
} // namespace shrpx } // namespace shrpx

View File

@ -388,6 +388,7 @@ public:
DefaultMemchunks *get_blocked_request_buf(); DefaultMemchunks *get_blocked_request_buf();
bool get_blocked_request_data_eof() const; bool get_blocked_request_data_eof() const;
void set_blocked_request_data_eof(bool f);
// downstream response API // downstream response API
const Response &response() const { return resp_; } const Response &response() const { return resp_; }

View File

@ -499,6 +499,14 @@ int Http2DownstreamConnection::push_request_headers() {
int Http2DownstreamConnection::push_upload_data_chunk(const uint8_t *data, int Http2DownstreamConnection::push_upload_data_chunk(const uint8_t *data,
size_t datalen) { size_t datalen) {
if (!downstream_->get_request_header_sent()) {
auto output = downstream_->get_blocked_request_buf();
auto &req = downstream_->request();
output->append(data, datalen);
req.unconsumed_body_length += datalen;
return 0;
}
int rv; int rv;
auto output = downstream_->get_request_buf(); auto output = downstream_->get_request_buf();
output->append(data, datalen); output->append(data, datalen);
@ -516,6 +524,11 @@ int Http2DownstreamConnection::push_upload_data_chunk(const uint8_t *data,
} }
int Http2DownstreamConnection::end_upload_data() { int Http2DownstreamConnection::end_upload_data() {
if (!downstream_->get_request_header_sent()) {
downstream_->set_blocked_request_data_eof(true);
return 0;
}
int rv; int rv;
if (downstream_->get_downstream_stream_id() != -1) { if (downstream_->get_downstream_stream_id() != -1) {
rv = http2session_->resume_data(this); rv = http2session_->resume_data(this);

View File

@ -705,6 +705,17 @@ int HttpDownstreamConnection::process_blocked_request_buf() {
int HttpDownstreamConnection::push_upload_data_chunk(const uint8_t *data, int HttpDownstreamConnection::push_upload_data_chunk(const uint8_t *data,
size_t datalen) { size_t datalen) {
if (!downstream_->get_request_header_sent()) {
auto output = downstream_->get_blocked_request_buf();
auto &req = downstream_->request();
output->append(data, datalen);
req.unconsumed_body_length += datalen;
if (request_header_written_) {
signal_write();
}
return 0;
}
auto chunked = downstream_->get_chunked_request(); auto chunked = downstream_->get_chunked_request();
auto output = downstream_->get_request_buf(); auto output = downstream_->get_request_buf();
@ -726,6 +737,14 @@ int HttpDownstreamConnection::push_upload_data_chunk(const uint8_t *data,
} }
int HttpDownstreamConnection::end_upload_data() { int HttpDownstreamConnection::end_upload_data() {
if (!downstream_->get_request_header_sent()) {
downstream_->set_blocked_request_data_eof(true);
if (request_header_written_) {
signal_write();
}
return 0;
}
signal_write(); signal_write();
if (!downstream_->get_chunked_request()) { if (!downstream_->get_chunked_request()) {