Commit e5abc475 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

Don't send more than NGHTTP2_MAX_HEADERSLEN bytes header block

parent 593485c6
...@@ -1455,6 +1455,14 @@ static int session_headers_add_pad(nghttp2_session *session, ...@@ -1455,6 +1455,14 @@ static int session_headers_add_pad(nghttp2_session *session,
return 0; 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. * This function serializes frame for transmission.
* *
...@@ -1473,9 +1481,18 @@ static int session_prep_frame(nghttp2_session *session, ...@@ -1473,9 +1481,18 @@ static int session_prep_frame(nghttp2_session *session,
switch(frame->hd.type) { switch(frame->hd.type) {
case NGHTTP2_HEADERS: { case NGHTTP2_HEADERS: {
nghttp2_headers_aux_data *aux_data; nghttp2_headers_aux_data *aux_data;
size_t estimated_payloadlen;
aux_data = (nghttp2_headers_aux_data*)item->aux_data; 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) { if(frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
nghttp2_stream *stream; nghttp2_stream *stream;
...@@ -1589,9 +1606,17 @@ static int session_prep_frame(nghttp2_session *session, ...@@ -1589,9 +1606,17 @@ static int session_prep_frame(nghttp2_session *session,
nghttp2_stream *stream; nghttp2_stream *stream;
nghttp2_headers_aux_data *aux_data; nghttp2_headers_aux_data *aux_data;
nghttp2_priority_spec pri_spec; nghttp2_priority_spec pri_spec;
size_t estimated_payloadlen;
aux_data = (nghttp2_headers_aux_data*)item->aux_data; 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); rv = session_predicate_push_promise_send(session, frame->hd.stream_id);
if(rv != 0) { if(rv != 0) {
return rv; return rv;
......
...@@ -124,8 +124,8 @@ int main(int argc, char* argv[]) ...@@ -124,8 +124,8 @@ int main(int argc, char* argv[])
test_nghttp2_session_send_headers_start_stream) || test_nghttp2_session_send_headers_start_stream) ||
!CU_add_test(pSuite, "session_send_headers_reply", !CU_add_test(pSuite, "session_send_headers_reply",
test_nghttp2_session_send_headers_reply) || test_nghttp2_session_send_headers_reply) ||
!CU_add_test(pSuite, "session_send_headers_header_comp_error", !CU_add_test(pSuite, "session_send_headers_frame_size_error",
test_nghttp2_session_send_headers_header_comp_error) || test_nghttp2_session_send_headers_frame_size_error) ||
!CU_add_test(pSuite, "session_send_headers_push_reply", !CU_add_test(pSuite, "session_send_headers_push_reply",
test_nghttp2_session_send_headers_push_reply) || test_nghttp2_session_send_headers_push_reply) ||
!CU_add_test(pSuite, "session_send_rst_stream", !CU_add_test(pSuite, "session_send_rst_stream",
......
...@@ -2383,7 +2383,7 @@ void test_nghttp2_session_send_headers_reply(void) ...@@ -2383,7 +2383,7 @@ void test_nghttp2_session_send_headers_reply(void)
nghttp2_session_del(session); 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 *session;
nghttp2_session_callbacks callbacks; nghttp2_session_callbacks callbacks;
...@@ -2394,6 +2394,7 @@ void test_nghttp2_session_send_headers_header_comp_error(void) ...@@ -2394,6 +2394,7 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
nghttp2_nv nv[28]; nghttp2_nv nv[28];
size_t nnv = ARRLEN(nv); size_t nnv = ARRLEN(nv);
size_t i; size_t i;
my_user_data ud;
for(i = 0; i < nnv; ++i) { for(i = 0; i < nnv; ++i) {
nv[i].name = (uint8_t*)"header"; nv[i].name = (uint8_t*)"header";
...@@ -2407,8 +2408,9 @@ void test_nghttp2_session_send_headers_header_comp_error(void) ...@@ -2407,8 +2408,9 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
callbacks.send_callback = null_send_callback; 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; nvlen = nnv;
nghttp2_nv_array_copy(&nva, nv, nvlen); nghttp2_nv_array_copy(&nva, nv, nvlen);
...@@ -2419,10 +2421,14 @@ void test_nghttp2_session_send_headers_header_comp_error(void) ...@@ -2419,10 +2421,14 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
session->next_stream_id += 2; session->next_stream_id += 2;
nghttp2_session_add_frame(session, NGHTTP2_CAT_CTRL, frame, NULL); 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(0 == nghttp2_session_send(session));
CU_ASSERT(session->goaway_flags & CU_ASSERT(1 == ud.frame_not_send_cb_called);
(NGHTTP2_GOAWAY_SEND | NGHTTP2_GOAWAY_FAIL_ON_SEND)); 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) { for(i = 0; i < nnv; ++i) {
free(nv[i].value); free(nv[i].value);
......
...@@ -52,7 +52,7 @@ void test_nghttp2_session_on_window_update_received(void); ...@@ -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_on_data_received(void);
void test_nghttp2_session_send_headers_start_stream(void); void test_nghttp2_session_send_headers_start_stream(void);
void test_nghttp2_session_send_headers_reply(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_headers_push_reply(void);
void test_nghttp2_session_send_rst_stream(void); void test_nghttp2_session_send_rst_stream(void);
void test_nghttp2_session_send_push_promise(void); void test_nghttp2_session_send_push_promise(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment