nghttpx: Use NGHTTP2_DATA_FLAG_NO_COPY for backend HTTP/2 session
This commit is contained in:
parent
8026bdd45a
commit
b011012d8f
|
@ -179,24 +179,11 @@ ssize_t http2_data_read_callback(nghttp2_session *session, int32_t stream_id,
|
||||||
}
|
}
|
||||||
const auto &req = downstream->request();
|
const auto &req = downstream->request();
|
||||||
auto input = downstream->get_request_buf();
|
auto input = downstream->get_request_buf();
|
||||||
auto nread = input->remove(buf, length);
|
|
||||||
auto input_empty = input->rleft() == 0;
|
|
||||||
|
|
||||||
if (nread > 0) {
|
auto nread = std::min(input->rleft(), length);
|
||||||
// This is important because it will handle flow control
|
auto input_empty = input->rleft() == nread;
|
||||||
// stuff.
|
|
||||||
if (downstream->get_upstream()->resume_read(SHRPX_NO_BUFFER, downstream,
|
|
||||||
nread) != 0) {
|
|
||||||
// In this case, downstream may be deleted.
|
|
||||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check dconn is still alive because Upstream::resume_read()
|
*data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
|
||||||
// may delete downstream which will delete dconn.
|
|
||||||
if (sd->dconn == nullptr) {
|
|
||||||
return NGHTTP2_ERR_DEFERRED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (input_empty &&
|
if (input_empty &&
|
||||||
downstream->get_request_state() == Downstream::MSG_COMPLETE &&
|
downstream->get_request_state() == Downstream::MSG_COMPLETE &&
|
||||||
|
@ -229,12 +216,6 @@ ssize_t http2_data_read_callback(nghttp2_session *session, int32_t stream_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!input_empty) {
|
|
||||||
downstream->reset_downstream_wtimer();
|
|
||||||
} else {
|
|
||||||
downstream->disable_downstream_wtimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nread == 0 && (*data_flags & NGHTTP2_DATA_FLAG_EOF) == 0) {
|
if (nread == 0 && (*data_flags & NGHTTP2_DATA_FLAG_EOF) == 0) {
|
||||||
downstream->disable_downstream_wtimer();
|
downstream->disable_downstream_wtimer();
|
||||||
|
|
||||||
|
|
|
@ -1362,6 +1362,54 @@ int on_frame_not_send_callback(nghttp2_session *session,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr auto PADDING = std::array<uint8_t, 256>{};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
|
||||||
|
const uint8_t *framehd, size_t length,
|
||||||
|
nghttp2_data_source *source, void *user_data) {
|
||||||
|
auto http2session = static_cast<Http2Session *>(user_data);
|
||||||
|
auto sd = static_cast<StreamData *>(
|
||||||
|
nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
|
||||||
|
auto dconn = sd->dconn;
|
||||||
|
auto downstream = dconn->get_downstream();
|
||||||
|
auto input = downstream->get_request_buf();
|
||||||
|
auto wb = http2session->get_request_buf();
|
||||||
|
|
||||||
|
size_t padlen = 0;
|
||||||
|
|
||||||
|
wb->append(framehd, 9);
|
||||||
|
if (frame->data.padlen > 0) {
|
||||||
|
padlen = frame->data.padlen - 1;
|
||||||
|
wb->append(static_cast<uint8_t>(padlen));
|
||||||
|
}
|
||||||
|
|
||||||
|
input->remove(*wb, length);
|
||||||
|
|
||||||
|
wb->append(PADDING.data(), padlen);
|
||||||
|
|
||||||
|
downstream->reset_downstream_wtimer();
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
// This is important because it will handle flow control
|
||||||
|
// stuff.
|
||||||
|
if (downstream->get_upstream()->resume_read(SHRPX_NO_BUFFER, downstream,
|
||||||
|
length) != 0) {
|
||||||
|
// In this case, downstream may be deleted.
|
||||||
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here sd->dconn could be nullptr, because
|
||||||
|
// Upstream::resume_read() may delete downstream which will delete
|
||||||
|
// dconn. Is this still really true?
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
nghttp2_session_callbacks *create_http2_downstream_callbacks() {
|
nghttp2_session_callbacks *create_http2_downstream_callbacks() {
|
||||||
int rv;
|
int rv;
|
||||||
nghttp2_session_callbacks *callbacks;
|
nghttp2_session_callbacks *callbacks;
|
||||||
|
@ -1393,6 +1441,9 @@ nghttp2_session_callbacks *create_http2_downstream_callbacks() {
|
||||||
nghttp2_session_callbacks_set_on_begin_headers_callback(
|
nghttp2_session_callbacks_set_on_begin_headers_callback(
|
||||||
callbacks, on_begin_headers_callback);
|
callbacks, on_begin_headers_callback);
|
||||||
|
|
||||||
|
nghttp2_session_callbacks_set_send_data_callback(callbacks,
|
||||||
|
send_data_callback);
|
||||||
|
|
||||||
if (get_config()->padding) {
|
if (get_config()->padding) {
|
||||||
nghttp2_session_callbacks_set_select_padding_callback(
|
nghttp2_session_callbacks_set_select_padding_callback(
|
||||||
callbacks, http::select_padding_callback);
|
callbacks, http::select_padding_callback);
|
||||||
|
@ -2115,4 +2166,6 @@ void Http2Session::exclude_from_scheduling() {
|
||||||
freelist_zone_ = FREELIST_ZONE_GONE;
|
freelist_zone_ = FREELIST_ZONE_GONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefaultMemchunks *Http2Session::get_request_buf() { return &wb_; }
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -195,6 +195,8 @@ public:
|
||||||
// server initiated concurrency limit.
|
// server initiated concurrency limit.
|
||||||
bool max_concurrency_reached(size_t extra = 0) const;
|
bool max_concurrency_reached(size_t extra = 0) const;
|
||||||
|
|
||||||
|
DefaultMemchunks *get_request_buf();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
// Disconnected
|
// Disconnected
|
||||||
DISCONNECTED,
|
DISCONNECTED,
|
||||||
|
|
Loading…
Reference in New Issue