From 73563de8d46f6b69dfa6d78431538d82237fc858 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 6 Aug 2013 21:57:26 +0900 Subject: [PATCH] Specify max length for header value and header block The max length of header block is not used right now. It will be used when header continuation is implemented. --- lib/nghttp2_frame.c | 2 +- lib/nghttp2_frame.h | 10 ++++++++++ tests/nghttp2_frame_test.c | 23 ++++++++++++++++------- tests/nghttp2_session_test.c | 23 +++++++++++++++-------- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/lib/nghttp2_frame.c b/lib/nghttp2_frame.c index 7f476d93..a2462d98 100644 --- a/lib/nghttp2_frame.c +++ b/lib/nghttp2_frame.c @@ -794,7 +794,7 @@ ssize_t nghttp2_nv_array_from_cstr(nghttp2_nv **nva_ptr, const char **nv) nghttp2_nv *p; for(i = 0; nv[i]; ++i) { size_t len = strlen(nv[i]); - if(len > (1 << 16) - 1) { + if(len > NGHTTP2_MAX_HD_VALUE_LENGTH) { return NGHTTP2_ERR_INVALID_ARGUMENT; } buflen += len; diff --git a/lib/nghttp2_frame.h b/lib/nghttp2_frame.h index 76beb29a..dfb5acc0 100644 --- a/lib/nghttp2_frame.h +++ b/lib/nghttp2_frame.h @@ -33,8 +33,18 @@ #include "nghttp2_hd.h" #include "nghttp2_buffer.h" +/* The maximum payload length of a frame */ +/* TODO The spec says the max payload length in HTTP is ((1 << 14) - + 1) */ #define NGHTTP2_MAX_FRAME_SIZE ((1 << 16) - 1) +/* The maximum header block length. This is not specified by the + spec. We just chose the arbitrary size */ +#define NGHTTP2_MAX_HD_BLOCK_LENGTH ((1 << 16) - 1) +/* The maximum value length of name/value pair. This is not specified + by the spec. We just chose the arbitrary size */ +#define NGHTTP2_MAX_HD_VALUE_LENGTH ((1 << 13) - 1) + #define NGHTTP2_STREAM_ID_MASK 0x7fffffff #define NGHTTP2_PRIORITY_MASK 0x7fffffff #define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK 0x7fffffff diff --git a/tests/nghttp2_frame_test.c b/tests/nghttp2_frame_test.c index 6839f0b3..6085a9c5 100644 --- a/tests/nghttp2_frame_test.c +++ b/tests/nghttp2_frame_test.c @@ -168,13 +168,20 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void) ssize_t framelen; nghttp2_nv *nva; ssize_t nvlen; - size_t big_vallen = (1 << 16) - 1; - char *big_val = malloc(big_vallen + 1); - const char *big_hds[] = { "header", big_val, NULL }; + size_t big_vallen = NGHTTP2_MAX_HD_VALUE_LENGTH; + char *big_hds[17]; + size_t big_hdslen = sizeof(big_hds)/sizeof(big_hds[0]); + size_t i; - memset(big_val, '0', big_vallen); - big_val[big_vallen] = '\0'; - nvlen = nghttp2_nv_array_from_cstr(&nva, big_hds); + for(i = 0; i < big_hdslen; i += 2) { + big_hds[i] = (char*)"header"; + big_hds[i+1] = malloc(big_vallen+1); + memset(big_hds[i+1], '0'+i, big_vallen); + big_hds[i+1][big_vallen] = '\0'; + } + big_hds[big_hdslen - 1] = NULL; + + nvlen = nghttp2_nv_array_from_cstr(&nva, (const char**)big_hds); nghttp2_hd_deflate_init(&deflater, NGHTTP2_HD_SIDE_CLIENT); nghttp2_frame_headers_init(&frame, NGHTTP2_FLAG_END_STREAM, 1000000007, 0, nva, nvlen); @@ -183,7 +190,9 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void) nghttp2_frame_headers_free(&frame); free(buf); - free(big_val); + for(i = 0; i < big_hdslen; i += 2) { + free(big_hds[i+1]); + } nghttp2_hd_deflate_free(&deflater); } diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c index cd0e43f6..e6014894 100644 --- a/tests/nghttp2_session_test.c +++ b/tests/nghttp2_session_test.c @@ -1278,22 +1278,27 @@ void test_nghttp2_session_send_headers_header_comp_error(void) { nghttp2_session *session; nghttp2_session_callbacks callbacks; - const char *nv[] = { ":path", NULL, NULL }; - size_t valuelen = 64*1024-1; - char *value = malloc(valuelen+1); nghttp2_frame *frame = malloc(sizeof(nghttp2_frame)); nghttp2_nv *nva; ssize_t nvlen; + size_t vallen = NGHTTP2_MAX_HD_VALUE_LENGTH; + char *nv[17]; + size_t nnv = sizeof(nv)/sizeof(nv[0]); + size_t i; - memset(value, '0', valuelen); - value[valuelen] = '\0'; - nv[1] = value; + for(i = 0; i < nnv; i += 2) { + nv[i] = (char*)"header"; + nv[i+1] = malloc(vallen+1); + memset(nv[i+1], '0'+i, vallen); + nv[i+1][vallen] = '\0'; + } + nv[nnv - 1] = NULL; memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); callbacks.send_callback = null_send_callback; nghttp2_session_client_new(&session, &callbacks, NULL); - nvlen = nghttp2_nv_array_from_cstr(&nva, nv); + nvlen = nghttp2_nv_array_from_cstr(&nva, (const char**)nv); nghttp2_frame_headers_init(&frame->headers, NGHTTP2_FLAG_END_HEADERS, -1, NGHTTP2_PRI_DEFAULT, nva, nvlen); @@ -1304,7 +1309,9 @@ void test_nghttp2_session_send_headers_header_comp_error(void) CU_ASSERT(session->goaway_flags & (NGHTTP2_GOAWAY_SEND | NGHTTP2_GOAWAY_FAIL_ON_SEND)); - free(value); + for(i = 0; i < nnv; i += 2) { + free(nv[i+1]); + } nghttp2_session_del(session); }