diff --git a/src/nghttp.cc b/src/nghttp.cc index df33e12d..f563edf6 100644 --- a/src/nghttp.cc +++ b/src/nghttp.cc @@ -135,8 +135,8 @@ Request::Request(const std::string &uri, const http_parser_url &u, const nghttp2_priority_spec &pri_spec, int level) : uri(uri), u(u), pri_spec(pri_spec), data_length(data_length), data_offset(0), response_len(0), inflater(nullptr), html_parser(nullptr), - data_prd(data_prd), stream_id(-1), status(0), level(level), - expect_final_response(false) { + data_prd(data_prd), header_buffer_size(0), stream_id(-1), status(0), + level(level), expect_final_response(false) { http2::init_hdidx(res_hdidx); http2::init_hdidx(req_hdidx); } @@ -1704,6 +1704,14 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame, break; } + if (req->header_buffer_size + namelen + valuelen > 64_k) { + nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, frame->hd.stream_id, + NGHTTP2_INTERNAL_ERROR); + return 0; + } + + req->header_buffer_size += namelen + valuelen; + auto token = http2::lookup_token(name, namelen); http2::index_header(req->res_hdidx, token, req->res_nva.size()); @@ -1719,6 +1727,15 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame, break; } + if (req->header_buffer_size + namelen + valuelen > 64_k) { + nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, + frame->push_promise.promised_stream_id, + NGHTTP2_INTERNAL_ERROR); + return 0; + } + + req->header_buffer_size += namelen + valuelen; + auto token = http2::lookup_token(name, namelen); http2::index_header(req->req_hdidx, token, req->req_nva.size()); @@ -1806,6 +1823,10 @@ int on_frame_recv_callback2(nghttp2_session *session, if (!req) { break; } + + // Reset for response header field reception + req->header_buffer_size = 0; + auto scheme = req->get_req_header(http2::HD__SCHEME); auto authority = req->get_req_header(http2::HD__AUTHORITY); auto path = req->get_req_header(http2::HD__PATH); diff --git a/src/nghttp.h b/src/nghttp.h index ffc07007..715a110e 100644 --- a/src/nghttp.h +++ b/src/nghttp.h @@ -150,6 +150,7 @@ struct Request { nghttp2_gzip *inflater; HtmlParser *html_parser; const nghttp2_data_provider *data_prd; + size_t header_buffer_size; int32_t stream_id; int status; // Recursion level: 0: first entity, 1: entity linked from first entity