Fix premature header block is not treated as connection error

This commit is contained in:
Tatsuhiro Tsujikawa 2014-02-11 16:00:59 +09:00
parent cbbecfeb41
commit cacf4ecf26
4 changed files with 55 additions and 0 deletions

View File

@ -1642,6 +1642,10 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
}
assert(in == last);
if(in_final) {
if(inflater->state != NGHTTP2_HD_STATE_OPCODE) {
rv = NGHTTP2_ERR_HEADER_COMP;
goto fail;
}
for(; inflater->end_headers_index < inflater->ctx.hd_table.len;
++inflater->end_headers_index) {
nghttp2_hd_entry *ent;

View File

@ -85,6 +85,8 @@ int main(int argc, char* argv[])
test_nghttp2_session_recv_data) ||
!CU_add_test(pSuite, "session_recv_continuation",
test_nghttp2_session_recv_continuation) ||
!CU_add_test(pSuite, "session_recv_premature_headers",
test_nghttp2_session_recv_premature_headers) ||
!CU_add_test(pSuite, "session_continue", test_nghttp2_session_continue) ||
!CU_add_test(pSuite, "session_add_frame",
test_nghttp2_session_add_frame) ||

View File

@ -760,6 +760,54 @@ void test_nghttp2_session_recv_continuation(void)
nghttp2_session_del(session);
}
void test_nghttp2_session_recv_premature_headers(void)
{
nghttp2_session *session;
nghttp2_session_callbacks callbacks;
const nghttp2_nv nv1[] = {
MAKE_NV("method", "GET"),
MAKE_NV("path", "/")
};
nghttp2_nv *nva;
size_t nvlen;
nghttp2_frame frame;
uint8_t *framedata = NULL;
size_t framedatacap = 0;
size_t framedatalen;
ssize_t rv;
my_user_data ud;
nghttp2_hd_deflater deflater;
nghttp2_outbound_item *item;
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
nghttp2_session_server_new(&session, &callbacks, &ud);
nghttp2_hd_deflate_init(&deflater, NGHTTP2_HD_SIDE_REQUEST);
nvlen = nghttp2_nv_array_copy(&nva, nv1, ARRLEN(nv1));
nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS,
1, NGHTTP2_PRI_DEFAULT, nva, nvlen);
framedatalen = nghttp2_frame_pack_headers(&framedata, &framedatacap,
&frame.headers,
&deflater);
nghttp2_frame_headers_free(&frame.headers);
/* Intentionally feed payload cutting last 1 byte off */
nghttp2_put_uint16be(framedata, frame.hd.length - 1);
rv = nghttp2_session_mem_recv(session, framedata, framedatalen - 1);
CU_ASSERT((ssize_t)framedatalen - 1 == rv);
item = nghttp2_session_get_next_ob_item(session);
CU_ASSERT(NULL != item);
CU_ASSERT(NGHTTP2_GOAWAY == OB_CTRL_TYPE(item));
CU_ASSERT(NGHTTP2_COMPRESSION_ERROR == OB_CTRL(item)->goaway.error_code);
free(framedata);
nghttp2_hd_deflate_free(&deflater);
nghttp2_session_del(session);
}
void test_nghttp2_session_continue(void)
{
nghttp2_session *session;

View File

@ -31,6 +31,7 @@ void test_nghttp2_session_recv_invalid_frame(void);
void test_nghttp2_session_recv_eof(void);
void test_nghttp2_session_recv_data(void);
void test_nghttp2_session_recv_continuation(void);
void test_nghttp2_session_recv_premature_headers(void);
void test_nghttp2_session_continue(void);
void test_nghttp2_session_add_frame(void);
void test_nghttp2_session_on_request_headers_received(void);