nghttpx: Improve performance with h1 backend when request body is involved
This commit is contained in:
parent
e1dfff8929
commit
231d739b10
|
@ -372,6 +372,10 @@ int Http2Upstream::on_request_headers(Downstream *downstream,
|
|||
|
||||
if (!(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
|
||||
req.http2_expect_body = true;
|
||||
} else if (req.fs.content_length == -1) {
|
||||
// If END_STREAM flag is set to HEADERS frame, we are sure that
|
||||
// content-length is 0.
|
||||
req.fs.content_length = 0;
|
||||
}
|
||||
|
||||
downstream->inspect_http2_request();
|
||||
|
@ -643,6 +647,9 @@ int on_frame_send_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
|||
req.http_major = 2;
|
||||
req.http_minor = 0;
|
||||
|
||||
req.fs.content_length = 0;
|
||||
req.http2_expect_body = false;
|
||||
|
||||
auto &promised_balloc = promised_downstream->get_block_allocator();
|
||||
|
||||
for (size_t i = 0; i < frame->push_promise.nvlen; ++i) {
|
||||
|
@ -2072,6 +2079,9 @@ Http2Upstream::on_downstream_push_promise(Downstream *downstream,
|
|||
promised_req.http_major = 2;
|
||||
promised_req.http_minor = 0;
|
||||
|
||||
promised_req.fs.content_length = 0;
|
||||
promised_req.http2_expect_body = false;
|
||||
|
||||
auto ptr = promised_downstream.get();
|
||||
add_pending_downstream(std::move(promised_downstream));
|
||||
downstream_queue_.mark_active(ptr);
|
||||
|
|
|
@ -525,7 +525,13 @@ int HttpDownstreamConnection::push_request_headers() {
|
|||
<< downstream_->get_stream_id() << "\n" << nhdrs;
|
||||
}
|
||||
|
||||
signal_write();
|
||||
// Don't call signal_write() if we anticipate request body. We call
|
||||
// signal_write() when we received request body chunk, and it
|
||||
// enables us to send headers and data in one writev system call.
|
||||
if (connect_method ||
|
||||
(!req.http2_expect_body && req.fs.content_length == 0)) {
|
||||
signal_write();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -312,10 +312,19 @@ int htp_hdrs_completecb(http_parser *htp) {
|
|||
ULOG(INFO, upstream) << "HTTP request headers\n" << ss.str();
|
||||
}
|
||||
|
||||
// set content-length if no transfer-encoding is given. If
|
||||
// transfer-encoding is given, leave req.fs.content_length to -1.
|
||||
if (!req.fs.header(http2::HD_TRANSFER_ENCODING)) {
|
||||
req.fs.content_length = htp->content_length;
|
||||
// set content-length if method is not CONNECT, and no
|
||||
// transfer-encoding is given. If transfer-encoding is given, leave
|
||||
// req.fs.content_length to -1.
|
||||
if (method != HTTP_CONNECT && !req.fs.header(http2::HD_TRANSFER_ENCODING)) {
|
||||
// http-parser returns (uint64_t)-1 if there is no content-length
|
||||
// header field. If we don't have both transfer-encoding, and
|
||||
// content-length header field, we assume that there is no request
|
||||
// body.
|
||||
if (htp->content_length == std::numeric_limits<uint64_t>::max()) {
|
||||
req.fs.content_length = 0;
|
||||
} else {
|
||||
req.fs.content_length = htp->content_length;
|
||||
}
|
||||
}
|
||||
|
||||
auto host = req.fs.header(http2::HD_HOST);
|
||||
|
|
|
@ -305,6 +305,8 @@ void on_ctrl_recv_callback(spdylay_session *session, spdylay_frame_type type,
|
|||
|
||||
if (!(frame->syn_stream.hd.flags & SPDYLAY_CTRL_FLAG_FIN)) {
|
||||
req.http2_expect_body = true;
|
||||
} else if (req.fs.content_length == -1) {
|
||||
req.fs.content_length = 0;
|
||||
}
|
||||
|
||||
downstream->inspect_http2_request();
|
||||
|
|
Loading…
Reference in New Issue