Don't send more than NGHTTP2_MAX_HEADERSLEN bytes header block

This commit is contained in:
Tatsuhiro Tsujikawa 2014-07-02 22:45:38 +09:00
parent 593485c652
commit e5abc475f1
4 changed files with 38 additions and 7 deletions

View File

@ -1455,6 +1455,14 @@ static int session_headers_add_pad(nghttp2_session *session,
return 0;
}
static size_t session_estimate_headers_payload
(nghttp2_session *session, const nghttp2_nv *nva, size_t nvlen,
size_t additional)
{
return nghttp2_hd_deflate_bound
(&session->hd_deflater, nva, nvlen) + additional;
}
/*
* This function serializes frame for transmission.
*
@ -1473,9 +1481,18 @@ static int session_prep_frame(nghttp2_session *session,
switch(frame->hd.type) {
case NGHTTP2_HEADERS: {
nghttp2_headers_aux_data *aux_data;
size_t estimated_payloadlen;
aux_data = (nghttp2_headers_aux_data*)item->aux_data;
estimated_payloadlen = session_estimate_headers_payload
(session, frame->headers.nva, frame->headers.nvlen,
NGHTTP2_PRIORITY_SPECLEN);
if(estimated_payloadlen > NGHTTP2_MAX_HEADERSLEN) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}
if(frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
nghttp2_stream *stream;
@ -1589,9 +1606,17 @@ static int session_prep_frame(nghttp2_session *session,
nghttp2_stream *stream;
nghttp2_headers_aux_data *aux_data;
nghttp2_priority_spec pri_spec;
size_t estimated_payloadlen;
aux_data = (nghttp2_headers_aux_data*)item->aux_data;
estimated_payloadlen = session_estimate_headers_payload
(session, frame->push_promise.nva, frame->push_promise.nvlen, 0);
if(estimated_payloadlen > NGHTTP2_MAX_HEADERSLEN) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}
rv = session_predicate_push_promise_send(session, frame->hd.stream_id);
if(rv != 0) {
return rv;

View File

@ -124,8 +124,8 @@ int main(int argc, char* argv[])
test_nghttp2_session_send_headers_start_stream) ||
!CU_add_test(pSuite, "session_send_headers_reply",
test_nghttp2_session_send_headers_reply) ||
!CU_add_test(pSuite, "session_send_headers_header_comp_error",
test_nghttp2_session_send_headers_header_comp_error) ||
!CU_add_test(pSuite, "session_send_headers_frame_size_error",
test_nghttp2_session_send_headers_frame_size_error) ||
!CU_add_test(pSuite, "session_send_headers_push_reply",
test_nghttp2_session_send_headers_push_reply) ||
!CU_add_test(pSuite, "session_send_rst_stream",

View File

@ -2383,7 +2383,7 @@ void test_nghttp2_session_send_headers_reply(void)
nghttp2_session_del(session);
}
void test_nghttp2_session_send_headers_header_comp_error(void)
void test_nghttp2_session_send_headers_frame_size_error(void)
{
nghttp2_session *session;
nghttp2_session_callbacks callbacks;
@ -2394,6 +2394,7 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
nghttp2_nv nv[28];
size_t nnv = ARRLEN(nv);
size_t i;
my_user_data ud;
for(i = 0; i < nnv; ++i) {
nv[i].name = (uint8_t*)"header";
@ -2407,8 +2408,9 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback;
callbacks.on_frame_not_send_callback = on_frame_not_send_callback;
nghttp2_session_client_new(&session, &callbacks, NULL);
nghttp2_session_client_new(&session, &callbacks, &ud);
nvlen = nnv;
nghttp2_nv_array_copy(&nva, nv, nvlen);
@ -2419,10 +2421,14 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
session->next_stream_id += 2;
nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL);
ud.frame_not_send_cb_called = 0;
CU_ASSERT(0 == nghttp2_session_send(session));
CU_ASSERT(session->goaway_flags &
(NGHTTP2_GOAWAY_SEND | NGHTTP2_GOAWAY_FAIL_ON_SEND));
CU_ASSERT(1 == ud.frame_not_send_cb_called);
CU_ASSERT(NGHTTP2_HEADERS == ud.not_sent_frame_type);
CU_ASSERT(NGHTTP2_ERR_FRAME_SIZE_ERROR == ud.not_sent_error);
for(i = 0; i < nnv; ++i) {
free(nv[i].value);

View File

@ -52,7 +52,7 @@ void test_nghttp2_session_on_window_update_received(void);
void test_nghttp2_session_on_data_received(void);
void test_nghttp2_session_send_headers_start_stream(void);
void test_nghttp2_session_send_headers_reply(void);
void test_nghttp2_session_send_headers_header_comp_error(void);
void test_nghttp2_session_send_headers_frame_size_error(void);
void test_nghttp2_session_send_headers_push_reply(void);
void test_nghttp2_session_send_rst_stream(void);
void test_nghttp2_session_send_push_promise(void);