Add test for nghttp2_frame_pack_headers with padding

This commit is contained in:
Tatsuhiro Tsujikawa 2014-02-09 15:16:58 +09:00
parent 1db2195389
commit 945c57c335
6 changed files with 154 additions and 10 deletions

View File

@ -201,6 +201,8 @@ int main(int argc, char* argv[])
test_nghttp2_frame_pack_headers) || test_nghttp2_frame_pack_headers) ||
!CU_add_test(pSuite, "frame_pack_headers_frame_too_large", !CU_add_test(pSuite, "frame_pack_headers_frame_too_large",
test_nghttp2_frame_pack_headers_frame_too_large) || test_nghttp2_frame_pack_headers_frame_too_large) ||
!CU_add_test(pSuite, "frame_pack_headers_with_padding",
test_nghttp2_frame_pack_headers_with_padding) ||
!CU_add_test(pSuite, "frame_pack_priority", !CU_add_test(pSuite, "frame_pack_priority",
test_nghttp2_frame_pack_priority) || test_nghttp2_frame_pack_priority) ||
!CU_add_test(pSuite, "frame_pack_rst_stream", !CU_add_test(pSuite, "frame_pack_rst_stream",

View File

@ -184,6 +184,134 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void)
nghttp2_hd_deflate_free(&deflater); nghttp2_hd_deflate_free(&deflater);
} }
void test_nghttp2_frame_pack_headers_with_padding(void)
{
nghttp2_hd_deflater deflater;
nghttp2_hd_inflater inflater;
nghttp2_headers frame, oframe;
uint8_t *buf = NULL;
size_t buflen = 0;
size_t bufoff;
ssize_t framelen;
nghttp2_nv *nva;
ssize_t nvlen;
nva_out out;
size_t trail_padlen;
size_t header_blocklen;
nva_out_init(&out);
nghttp2_hd_deflate_init(&deflater, NGHTTP2_HD_SIDE_REQUEST);
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_REQUEST);
/* Payload length is 0, so no padding */
nghttp2_frame_headers_init(&frame,
NGHTTP2_FLAG_END_STREAM|NGHTTP2_FLAG_END_HEADERS,
1000000007, NGHTTP2_PRI_DEFAULT, NULL, 0);
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 128);
CU_ASSERT(2 == bufoff);
CU_ASSERT((ssize_t)bufoff + NGHTTP2_FRAME_HEAD_LENGTH == framelen);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf + bufoff,
framelen - bufoff));
check_frame_header(framelen - bufoff - NGHTTP2_FRAME_HEAD_LENGTH,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS,
1000000007, &oframe.hd);
CU_ASSERT(NGHTTP2_PRI_DEFAULT == oframe.pri);
nghttp2_frame_headers_free(&oframe);
/* Include priroty */
frame.hd.flags |= NGHTTP2_FLAG_PRIORITY;
frame.pri = 1000000009;
bufoff = 0;
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 128);
CU_ASSERT(1 == bufoff);
CU_ASSERT((ssize_t)bufoff + NGHTTP2_FRAME_HEAD_LENGTH + 128 == framelen);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf + bufoff,
framelen - bufoff));
check_frame_header(framelen - bufoff - NGHTTP2_FRAME_HEAD_LENGTH,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY | NGHTTP2_FLAG_PAD_LOW,
1000000007, &oframe.hd);
CU_ASSERT(1000000009 == oframe.pri);
nghttp2_frame_headers_free(&oframe);
/* padding more than 256 */
bufoff = 0;
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 512);
CU_ASSERT(0 == bufoff);
CU_ASSERT(NGHTTP2_FRAME_HEAD_LENGTH + 512 == framelen);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf + bufoff,
framelen - bufoff));
check_frame_header(framelen - bufoff - NGHTTP2_FRAME_HEAD_LENGTH,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY |
NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW,
1000000007, &oframe.hd);
CU_ASSERT(1000000009 == oframe.pri);
nghttp2_frame_headers_free(&oframe);
/* Include priority + headers */
nva = headers();
nvlen = HEADERS_LENGTH;
frame.nva = nva;
frame.nvlen = nvlen;
bufoff = 0;
framelen = nghttp2_frame_pack_headers(&buf, &buflen, &bufoff, &frame,
&deflater, 512);
CU_ASSERT(0 == bufoff);
CU_ASSERT(NGHTTP2_FRAME_HEAD_LENGTH + 512 == framelen);
CU_ASSERT(0 == unpack_frame((nghttp2_frame*)&oframe, buf + bufoff,
framelen - bufoff));
check_frame_header(framelen - bufoff - NGHTTP2_FRAME_HEAD_LENGTH,
NGHTTP2_HEADERS,
NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
NGHTTP2_FLAG_PRIORITY |
NGHTTP2_FLAG_PAD_HIGH | NGHTTP2_FLAG_PAD_LOW,
1000000007, &oframe.hd);
CU_ASSERT(1000000009 == oframe.pri);
trail_padlen = (buf[NGHTTP2_FRAME_HEAD_LENGTH] << 8) |
buf[NGHTTP2_FRAME_HEAD_LENGTH + 1];
header_blocklen = framelen - NGHTTP2_FRAME_HEAD_LENGTH - 2 - 4
- trail_padlen;
CU_ASSERT((ssize_t)header_blocklen ==
inflate_hd(&inflater, &out,
buf + NGHTTP2_FRAME_HEAD_LENGTH + 2 + 4,
header_blocklen));
CU_ASSERT(nvlen == (ssize_t)out.nvlen);
assert_nv_equal(nva, out.nva, nvlen);
nghttp2_frame_headers_free(&oframe);
nva_out_reset(&out);
free(buf);
nghttp2_frame_headers_free(&frame);
nghttp2_hd_inflate_free(&inflater);
nghttp2_hd_deflate_free(&deflater);
}
void test_nghttp2_frame_pack_priority(void) void test_nghttp2_frame_pack_priority(void)
{ {
nghttp2_priority frame, oframe; nghttp2_priority frame, oframe;

View File

@ -27,6 +27,7 @@
void test_nghttp2_frame_pack_headers(void); void test_nghttp2_frame_pack_headers(void);
void test_nghttp2_frame_pack_headers_frame_too_large(void); void test_nghttp2_frame_pack_headers_frame_too_large(void);
void test_nghttp2_frame_pack_headers_with_padding(void);
void test_nghttp2_frame_pack_priority(void); void test_nghttp2_frame_pack_priority(void);
void test_nghttp2_frame_pack_rst_stream(void); void test_nghttp2_frame_pack_rst_stream(void);
void test_nghttp2_frame_pack_settings(void); void test_nghttp2_frame_pack_settings(void);

View File

@ -35,15 +35,6 @@
#define GET_TABLE_ENT(context, index) nghttp2_hd_table_get(context, index) #define GET_TABLE_ENT(context, index) nghttp2_hd_table_get(context, index)
static void assert_nv_equal(nghttp2_nv *a, nghttp2_nv *b, size_t len)
{
size_t i;
nghttp2_nv_array_sort(b, len);
for(i = 0; i < len; ++i, ++a, ++b) {
CU_ASSERT(nghttp2_nv_equal(a, b));
}
}
void test_nghttp2_hd_deflate(void) void test_nghttp2_hd_deflate(void)
{ {
nghttp2_hd_deflater deflater; nghttp2_hd_deflater deflater;

View File

@ -33,11 +33,15 @@ int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len)
ssize_t rv = 0; ssize_t rv = 0;
const uint8_t *payload = in + NGHTTP2_FRAME_HEAD_LENGTH; const uint8_t *payload = in + NGHTTP2_FRAME_HEAD_LENGTH;
size_t payloadlen = len - NGHTTP2_FRAME_HEAD_LENGTH; size_t payloadlen = len - NGHTTP2_FRAME_HEAD_LENGTH;
size_t payloadoff;
nghttp2_frame_unpack_frame_hd(&frame->hd, in); nghttp2_frame_unpack_frame_hd(&frame->hd, in);
switch(frame->hd.type) { switch(frame->hd.type) {
case NGHTTP2_HEADERS: case NGHTTP2_HEADERS:
payloadoff = ((frame->hd.flags & NGHTTP2_FLAG_PAD_HIGH) > 0) +
((frame->hd.flags & NGHTTP2_FLAG_PAD_LOW) > 0);
rv = nghttp2_frame_unpack_headers_payload rv = nghttp2_frame_unpack_headers_payload
(&frame->headers, payload, payloadlen); (&frame->headers, payload + payloadoff, payloadlen - payloadoff);
break; break;
case NGHTTP2_PRIORITY: case NGHTTP2_PRIORITY:
nghttp2_frame_unpack_priority_payload nghttp2_frame_unpack_priority_payload

View File

@ -37,6 +37,24 @@
{ (uint8_t*)NAME, (uint8_t*)VALUE, strlen(NAME), strlen(VALUE) } { (uint8_t*)NAME, (uint8_t*)VALUE, strlen(NAME), strlen(VALUE) }
#define ARRLEN(ARR) (sizeof(ARR)/sizeof(ARR[0])) #define ARRLEN(ARR) (sizeof(ARR)/sizeof(ARR[0]))
#define assert_nv_equal(A, B, len) \
do { \
size_t alloclen = sizeof(nghttp2_nv) * len; \
nghttp2_nv *sa = A, *sb = B; \
nghttp2_nv *a = malloc(alloclen); \
nghttp2_nv *b = malloc(alloclen); \
ssize_t i_; \
memcpy(a, sa, alloclen); \
memcpy(b, sb, alloclen); \
nghttp2_nv_array_sort(a, len); \
nghttp2_nv_array_sort(b, len); \
for(i_ = 0; i_ < (ssize_t)len; ++i_) { \
CU_ASSERT(nghttp2_nv_equal(&a[i_], &b[i_])); \
} \
free(b); \
free(a); \
} while(0);
int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len); int unpack_frame(nghttp2_frame *frame, const uint8_t *in, size_t len);
int strmemeq(const char *a, const uint8_t *b, size_t bn); int strmemeq(const char *a, const uint8_t *b, size_t bn);