nghttpx: Limit the number of receiving headers

This commit is contained in:
Tatsuhiro Tsujikawa 2014-01-27 00:44:08 +09:00
parent bf99da4ffb
commit fbffd2c923
5 changed files with 39 additions and 0 deletions

View File

@ -730,6 +730,21 @@ int check_nv(const uint8_t *name, size_t namelen,
return 1; return 1;
} }
int handle_too_many_headers(nghttp2_session *session, int32_t stream_id)
{
int rv;
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, stream_id,
NGHTTP2_INTERNAL_ERROR);
if(nghttp2_is_fatal(rv)) {
return rv;
}
rv = nghttp2_session_terminate_session(session, NGHTTP2_INTERNAL_ERROR);
if(nghttp2_is_fatal(rv)) {
return rv;
}
return 0;
}
} // namespace http2 } // namespace http2
} // namespace nghttp2 } // namespace nghttp2

View File

@ -221,6 +221,10 @@ int check_header_value(const uint8_t* value, size_t len);
int check_nv(const uint8_t *name, size_t namelen, int check_nv(const uint8_t *name, size_t namelen,
const uint8_t *value, size_t valuelen); const uint8_t *value, size_t valuelen);
// Handles the situation that incoming headers are too many. It is
// dealt with by issuing RST_STREAM and GOAWAY.
int handle_too_many_headers(nghttp2_session *session, int32_t stream_id);
} // namespace http2 } // namespace http2
} // namespace nghttp2 } // namespace nghttp2

View File

@ -199,6 +199,10 @@ public:
// Change the priority of downstream // Change the priority of downstream
int change_priority(int32_t pri); int change_priority(int32_t pri);
// Maximum number of headers per HEADERS frame, including its
// following CONTINUATIONs.
static const size_t MAX_HEADERS = 128;
private: private:
Headers request_headers_; Headers request_headers_;
Headers response_headers_; Headers response_headers_;

View File

@ -804,6 +804,7 @@ int on_header_callback(nghttp2_session *session,
const uint8_t *value, size_t valuelen, const uint8_t *value, size_t valuelen,
void *user_data) void *user_data)
{ {
int rv;
if(frame->hd.type != NGHTTP2_HEADERS || if(frame->hd.type != NGHTTP2_HEADERS ||
frame->headers.cat != NGHTTP2_HCAT_RESPONSE) { frame->headers.cat != NGHTTP2_HCAT_RESPONSE) {
return 0; return 0;
@ -817,6 +818,13 @@ int on_header_callback(nghttp2_session *session,
if(!downstream) { if(!downstream) {
return 0; return 0;
} }
if(downstream->get_request_headers().size() >= Downstream::MAX_HEADERS) {
rv = http2::handle_too_many_headers(session, frame->hd.stream_id);
if(nghttp2_is_fatal(rv)) {
return rv;
}
return 0;
}
if(!http2::check_nv(name, namelen, value, valuelen)) { if(!http2::check_nv(name, namelen, value, valuelen)) {
return 0; return 0;
} }

View File

@ -205,6 +205,7 @@ int on_header_callback(nghttp2_session *session,
const uint8_t *value, size_t valuelen, const uint8_t *value, size_t valuelen,
void *user_data) void *user_data)
{ {
int rv;
if(frame->hd.type != NGHTTP2_HEADERS || if(frame->hd.type != NGHTTP2_HEADERS ||
frame->headers.cat != NGHTTP2_HCAT_REQUEST) { frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
return 0; return 0;
@ -214,6 +215,13 @@ int on_header_callback(nghttp2_session *session,
if(!downstream) { if(!downstream) {
return 0; return 0;
} }
if(downstream->get_request_headers().size() >= Downstream::MAX_HEADERS) {
rv = http2::handle_too_many_headers(session, frame->hd.stream_id);
if(nghttp2_is_fatal(rv)) {
return rv;
}
return 0;
}
if(!http2::check_nv(name, namelen, value, valuelen)) { if(!http2::check_nv(name, namelen, value, valuelen)) {
return 0; return 0;
} }