nghttpx: Reset stream if invalid header field is received in h2
This commit is contained in:
parent
79b07f0ce2
commit
1064e017c6
|
@ -904,6 +904,47 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int on_invalid_header_callback2(nghttp2_session *session,
|
||||||
|
const nghttp2_frame *frame, nghttp2_rcbuf *name,
|
||||||
|
nghttp2_rcbuf *value, uint8_t flags,
|
||||||
|
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));
|
||||||
|
if (!sd || !sd->dconn) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto downstream = sd->dconn->get_downstream();
|
||||||
|
if (!downstream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t stream_id;
|
||||||
|
|
||||||
|
if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||||
|
stream_id = frame->push_promise.promised_stream_id;
|
||||||
|
} else {
|
||||||
|
stream_id = frame->hd.stream_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
auto namebuf = nghttp2_rcbuf_get_buf(name);
|
||||||
|
auto valuebuf = nghttp2_rcbuf_get_buf(value);
|
||||||
|
|
||||||
|
SSLOG(INFO, http2session)
|
||||||
|
<< "Invalid header field for stream_id=" << stream_id
|
||||||
|
<< " in frame type=" << static_cast<uint32_t>(frame->hd.type)
|
||||||
|
<< ": name=[" << StringRef{namebuf.base, namebuf.len} << "], value=["
|
||||||
|
<< StringRef{valuebuf.base, valuebuf.len} << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
http2session->submit_rst_stream(stream_id, NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
|
||||||
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int on_begin_headers_callback(nghttp2_session *session,
|
int on_begin_headers_callback(nghttp2_session *session,
|
||||||
const nghttp2_frame *frame, void *user_data) {
|
const nghttp2_frame *frame, void *user_data) {
|
||||||
|
@ -1486,6 +1527,9 @@ nghttp2_session_callbacks *create_http2_downstream_callbacks() {
|
||||||
nghttp2_session_callbacks_set_on_header_callback2(callbacks,
|
nghttp2_session_callbacks_set_on_header_callback2(callbacks,
|
||||||
on_header_callback2);
|
on_header_callback2);
|
||||||
|
|
||||||
|
nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
||||||
|
callbacks, on_invalid_header_callback2);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,34 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int on_invalid_header_callback2(nghttp2_session *session,
|
||||||
|
const nghttp2_frame *frame, nghttp2_rcbuf *name,
|
||||||
|
nghttp2_rcbuf *value, uint8_t flags,
|
||||||
|
void *user_data) {
|
||||||
|
auto upstream = static_cast<Http2Upstream *>(user_data);
|
||||||
|
auto downstream = static_cast<Downstream *>(
|
||||||
|
nghttp2_session_get_stream_user_data(session, frame->hd.stream_id));
|
||||||
|
if (!downstream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG_ENABLED(INFO)) {
|
||||||
|
auto namebuf = nghttp2_rcbuf_get_buf(name);
|
||||||
|
auto valuebuf = nghttp2_rcbuf_get_buf(value);
|
||||||
|
|
||||||
|
ULOG(INFO, upstream) << "Invalid header field for stream_id="
|
||||||
|
<< frame->hd.stream_id << ": name=["
|
||||||
|
<< StringRef{namebuf.base, namebuf.len} << "], value=["
|
||||||
|
<< StringRef{valuebuf.base, valuebuf.len} << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
upstream->rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
|
||||||
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int on_begin_headers_callback(nghttp2_session *session,
|
int on_begin_headers_callback(nghttp2_session *session,
|
||||||
const nghttp2_frame *frame, void *user_data) {
|
const nghttp2_frame *frame, void *user_data) {
|
||||||
|
@ -852,6 +880,9 @@ nghttp2_session_callbacks *create_http2_upstream_callbacks() {
|
||||||
nghttp2_session_callbacks_set_on_header_callback2(callbacks,
|
nghttp2_session_callbacks_set_on_header_callback2(callbacks,
|
||||||
on_header_callback2);
|
on_header_callback2);
|
||||||
|
|
||||||
|
nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
||||||
|
callbacks, on_invalid_header_callback2);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue