nghttpd: Create Request object in hd_before_frame_send_callback
This is pathological case, but we may get RST_STREAM to the promised stream while we are sending PUSH_PROMISE. To handle this case, instantiate Request object before transmission.
This commit is contained in:
parent
50cda96fa5
commit
c3a361fb52
|
@ -825,6 +825,23 @@ int htdocs_on_request_recv_callback
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int hd_before_frame_send_callback
|
||||||
|
(nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
|
||||||
|
{
|
||||||
|
auto hd = reinterpret_cast<Http2Handler*>(user_data);
|
||||||
|
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||||
|
auto stream_id = frame->push_promise.promised_stream_id;
|
||||||
|
auto req = util::make_unique<Request>(stream_id);
|
||||||
|
auto nva = http2::sort_nva(frame->push_promise.nva,
|
||||||
|
frame->push_promise.nvlen);
|
||||||
|
append_nv(req.get(), nva);
|
||||||
|
hd->add_stream(stream_id, std::move(req));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int hd_on_frame_send_callback
|
int hd_on_frame_send_callback
|
||||||
(nghttp2_session *session, const nghttp2_frame *frame,
|
(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
|
@ -832,15 +849,10 @@ int hd_on_frame_send_callback
|
||||||
{
|
{
|
||||||
auto hd = reinterpret_cast<Http2Handler*>(user_data);
|
auto hd = reinterpret_cast<Http2Handler*>(user_data);
|
||||||
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
if(frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||||
auto req = util::make_unique<Request>
|
auto stream = hd->get_stream(frame->push_promise.promised_stream_id);
|
||||||
(frame->push_promise.promised_stream_id);
|
if(stream) {
|
||||||
auto nva = http2::sort_nva(frame->push_promise.nva,
|
prepare_response(stream, hd, /*allow_push */ false);
|
||||||
frame->push_promise.nvlen);
|
}
|
||||||
append_nv(req.get(), nva);
|
|
||||||
auto req_ptr = req.get();
|
|
||||||
auto stream_id = req->stream_id;
|
|
||||||
hd->add_stream(stream_id, std::move(req));
|
|
||||||
prepare_response(req_ptr, hd, /*allow_push */ false);
|
|
||||||
}
|
}
|
||||||
if(hd->get_config()->verbose) {
|
if(hd->get_config()->verbose) {
|
||||||
print_session_id(hd->session_id());
|
print_session_id(hd->session_id());
|
||||||
|
@ -914,6 +926,7 @@ void fill_callback(nghttp2_session_callbacks& callbacks, const Config *config)
|
||||||
callbacks.recv_callback = hd_recv_callback;
|
callbacks.recv_callback = hd_recv_callback;
|
||||||
callbacks.on_stream_close_callback = on_stream_close_callback;
|
callbacks.on_stream_close_callback = on_stream_close_callback;
|
||||||
callbacks.on_frame_recv_callback = hd_on_frame_recv_callback;
|
callbacks.on_frame_recv_callback = hd_on_frame_recv_callback;
|
||||||
|
callbacks.before_frame_send_callback = hd_before_frame_send_callback;
|
||||||
callbacks.on_frame_send_callback = hd_on_frame_send_callback;
|
callbacks.on_frame_send_callback = hd_on_frame_send_callback;
|
||||||
callbacks.on_data_recv_callback = hd_on_data_recv_callback;
|
callbacks.on_data_recv_callback = hd_on_data_recv_callback;
|
||||||
callbacks.on_data_send_callback = hd_on_data_send_callback;
|
callbacks.on_data_send_callback = hd_on_data_send_callback;
|
||||||
|
|
Loading…
Reference in New Issue