void test_nghttp2_hd_deflate_same_indexed_repr(void) { nghttp2_hd_deflater deflater; nghttp2_hd_inflater inflater; nghttp2_nv nva1[] = {MAKE_NV("cookie", "alpha"), MAKE_NV("cookie", "alpha")}; nghttp2_nv nva2[] = {MAKE_NV("cookie", "alpha"), MAKE_NV("cookie", "alpha"), MAKE_NV("cookie", "alpha")}; nghttp2_bufs bufs; ssize_t blocklen; nva_out out; int rv; nghttp2_mem *mem; mem = nghttp2_mem_default(); frame_pack_bufs_init(&bufs); nva_out_init(&out); CU_ASSERT(0 == nghttp2_hd_deflate_init(&deflater, mem)); CU_ASSERT(0 == nghttp2_hd_inflate_init(&inflater, mem)); /* Encode 2 same headers. Emit 1 literal reprs and 1 index repr. */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva1, ARRLEN(nva1)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == out.nvlen); assert_nv_equal(nva1, out.nva, 2, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Encode 3 same headers. This time, emits 3 index reprs. */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva2, ARRLEN(nva2)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen == 3); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(3 == out.nvlen); assert_nv_equal(nva2, out.nva, 3, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Cleanup */ nghttp2_bufs_free(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); }
static void check_deflate_inflate(nghttp2_hd_deflater *deflater, nghttp2_hd_inflater *inflater, nghttp2_nv *nva, size_t nvlen, nghttp2_mem *mem) { nghttp2_bufs bufs; ssize_t blocklen; nva_out out; int rv; frame_pack_bufs_init(&bufs); nva_out_init(&out); rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nva, nvlen); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen >= 0); CU_ASSERT(blocklen == inflate_hd(inflater, &out, &bufs, 0, mem)); CU_ASSERT(nvlen == out.nvlen); assert_nv_equal(nva, out.nva, nvlen, mem); nva_out_reset(&out, mem); nghttp2_bufs_free(&bufs); }
void test_nghttp2_hd_deflate_bound(void) { nghttp2_hd_deflater deflater; nghttp2_nv nva[] = {MAKE_NV(":method", "GET"), MAKE_NV("alpha", "bravo")}; nghttp2_bufs bufs; size_t bound, bound2; nghttp2_mem *mem; mem = nghttp2_mem_default(); frame_pack_bufs_init(&bufs); nghttp2_hd_deflate_init(&deflater, mem); bound = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva)); CU_ASSERT(12 + 6 * 2 * 2 + nva[0].namelen + nva[0].valuelen + nva[1].namelen + nva[1].valuelen == bound); nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, ARRLEN(nva)); CU_ASSERT(bound > (size_t)nghttp2_bufs_len(&bufs)); bound2 = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva)); CU_ASSERT(bound == bound2); nghttp2_bufs_free(&bufs); nghttp2_hd_deflate_free(&deflater); }
void test_nghttp2_hd_ringbuf_reserve(void) { nghttp2_hd_deflater deflater; nghttp2_hd_inflater inflater; nghttp2_nv nv; nghttp2_bufs bufs; nva_out out; int i; ssize_t rv; ssize_t blocklen; nghttp2_mem *mem; mem = nghttp2_mem_default(); frame_pack_bufs_init(&bufs); nva_out_init(&out); nv.flags = NGHTTP2_NV_FLAG_NONE; nv.name = (uint8_t *)"a"; nv.namelen = strlen((const char *)nv.name); nv.valuelen = 4; nv.value = mem->malloc(nv.valuelen + 1, NULL); memset(nv.value, 0, nv.valuelen); nghttp2_hd_deflate_init2(&deflater, 8000, mem); nghttp2_hd_inflate_init(&inflater, mem); nghttp2_hd_inflate_change_table_size(&inflater, 8000); nghttp2_hd_deflate_change_table_size(&deflater, 8000); for (i = 0; i < 150; ++i) { memcpy(nv.value, &i, sizeof(i)); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, &nv, 1); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(1 == out.nvlen); assert_nv_equal(&nv, out.nva, 1, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); } nghttp2_bufs_free(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); mem->free(nv.value, NULL); }
void test_nghttp2_hd_no_index(void) { nghttp2_hd_deflater deflater; nghttp2_hd_inflater inflater; nghttp2_bufs bufs; ssize_t blocklen; nghttp2_nv nva[] = { MAKE_NV(":method", "GET"), MAKE_NV(":method", "POST"), MAKE_NV(":path", "/foo"), MAKE_NV("version", "HTTP/1.1"), MAKE_NV(":method", "GET"), }; size_t i; nva_out out; int rv; nghttp2_mem *mem; mem = nghttp2_mem_default(); /* 1st :method: GET can be indexable, last one is not */ for (i = 1; i < ARRLEN(nva); ++i) { nva[i].flags = NGHTTP2_NV_FLAG_NO_INDEX; } frame_pack_bufs_init(&bufs); nva_out_init(&out); nghttp2_hd_deflate_init(&deflater, mem); nghttp2_hd_inflate_init(&inflater, mem); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, ARRLEN(nva)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(ARRLEN(nva) == out.nvlen); assert_nv_equal(nva, out.nva, ARRLEN(nva), mem); CU_ASSERT(out.nva[0].flags == NGHTTP2_NV_FLAG_NONE); for (i = 1; i < ARRLEN(nva); ++i) { CU_ASSERT(out.nva[i].flags == NGHTTP2_NV_FLAG_NO_INDEX); } nva_out_reset(&out, mem); nghttp2_bufs_free(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); }
static int deflate_inflate(nghttp2_hd_deflater *deflater, nghttp2_hd_inflater *inflater, nghttp2_bufs *bufs, nghttp2_nv *nva, size_t nvlen, nghttp2_mem *mem) { int rv; rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, nva, nvlen); if (rv != 0) { return rv; } rv = (int)inflate_hd(inflater, NULL, bufs, 0, mem); if (rv < 0) { return rv; } nghttp2_bufs_reset(bufs); return 0; }
void test_nghttp2_hd_change_table_size(void) { nghttp2_hd_deflater deflater; nghttp2_hd_inflater inflater; nghttp2_nv nva[] = {MAKE_NV("alpha", "bravo"), MAKE_NV("charlie", "delta")}; nghttp2_nv nva2[] = {MAKE_NV(":path", "/")}; nghttp2_bufs bufs; ssize_t rv; nva_out out; ssize_t blocklen; nghttp2_mem *mem; mem = nghttp2_mem_default(); frame_pack_bufs_init(&bufs); nva_out_init(&out); nghttp2_hd_deflate_init(&deflater, mem); nghttp2_hd_inflate_init(&inflater, mem); /* inflater changes notifies 8000 max header table size */ CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 8000)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 8000)); CU_ASSERT(4096 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max); /* This will emit encoding context update with header table size 4096 */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(2 == deflater.ctx.hd_table.len); CU_ASSERT(4096 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == inflater.ctx.hd_table.len); CU_ASSERT(4096 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* inflater changes header table size to 1024 */ CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 1024)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 1024)); CU_ASSERT(1024 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(1024 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(1024 == inflater.settings_hd_table_bufsize_max); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(2 == deflater.ctx.hd_table.len); CU_ASSERT(1024 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == inflater.ctx.hd_table.len); CU_ASSERT(1024 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(1024 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* inflater changes header table size to 0 */ CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 0)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 0)); CU_ASSERT(0 == deflater.ctx.hd_table.len); CU_ASSERT(0 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(0 == inflater.ctx.hd_table.len); CU_ASSERT(0 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(0 == inflater.settings_hd_table_bufsize_max); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(0 == deflater.ctx.hd_table.len); CU_ASSERT(0 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(0 == inflater.ctx.hd_table.len); CU_ASSERT(0 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(0 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); nghttp2_bufs_free(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); /* Check table buffer is expanded */ frame_pack_bufs_init(&bufs); nghttp2_hd_deflate_init2(&deflater, 8192, mem); nghttp2_hd_inflate_init(&inflater, mem); /* First inflater changes header table size to 8000 */ CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 8000)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 8000)); CU_ASSERT(8000 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(2 == deflater.ctx.hd_table.len); CU_ASSERT(8000 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == inflater.ctx.hd_table.len); CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 16383)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 16383)); CU_ASSERT(8192 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(16383 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(16383 == inflater.settings_hd_table_bufsize_max); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(2 == deflater.ctx.hd_table.len); CU_ASSERT(8192 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == inflater.ctx.hd_table.len); CU_ASSERT(8192 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(16383 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Lastly, check the error condition */ rv = nghttp2_hd_emit_table_size(&bufs, 25600); CU_ASSERT(rv == 0); CU_ASSERT(NGHTTP2_ERR_HEADER_COMP == inflate_hd(&inflater, &out, &bufs, 0, mem)); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); /* Check that encoder can handle the case where its allowable buffer size is less than default size, 4096 */ nghttp2_hd_deflate_init2(&deflater, 1024, mem); nghttp2_hd_inflate_init(&inflater, mem); CU_ASSERT(1024 == deflater.ctx.hd_table_bufsize_max); /* This emits context update with buffer size 1024 */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(2 == deflater.ctx.hd_table.len); CU_ASSERT(1024 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == inflater.ctx.hd_table.len); CU_ASSERT(1024 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(4096 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); /* Check that table size UINT32_MAX can be received */ nghttp2_hd_deflate_init2(&deflater, UINT32_MAX, mem); nghttp2_hd_inflate_init(&inflater, mem); CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, UINT32_MAX)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, UINT32_MAX)); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(UINT32_MAX == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(UINT32_MAX == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(UINT32_MAX == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); /* Check that context update emitted twice */ nghttp2_hd_deflate_init2(&deflater, 4096, mem); nghttp2_hd_inflate_init(&inflater, mem); CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 0)); CU_ASSERT(0 == nghttp2_hd_inflate_change_table_size(&inflater, 3000)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 0)); CU_ASSERT(0 == nghttp2_hd_deflate_change_table_size(&deflater, 3000)); CU_ASSERT(0 == deflater.min_hd_table_bufsize_max); CU_ASSERT(3000 == deflater.ctx.hd_table_bufsize_max); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva2, 1); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(3 < blocklen); CU_ASSERT(3000 == deflater.ctx.hd_table_bufsize_max); CU_ASSERT(UINT32_MAX == deflater.min_hd_table_bufsize_max); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(3000 == inflater.ctx.hd_table_bufsize_max); CU_ASSERT(3000 == inflater.settings_hd_table_bufsize_max); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); nghttp2_bufs_free(&bufs); }
void test_nghttp2_hd_deflate(void) { nghttp2_hd_deflater deflater; nghttp2_hd_inflater inflater; nghttp2_nv nva1[] = {MAKE_NV(":path", "/my-example/index.html"), MAKE_NV(":scheme", "https"), MAKE_NV("hello", "world")}; nghttp2_nv nva2[] = {MAKE_NV(":path", "/script.js"), MAKE_NV(":scheme", "https")}; nghttp2_nv nva3[] = {MAKE_NV("cookie", "k1=v1"), MAKE_NV("cookie", "k2=v2"), MAKE_NV("via", "proxy")}; nghttp2_nv nva4[] = {MAKE_NV(":path", "/style.css"), MAKE_NV("cookie", "k1=v1"), MAKE_NV("cookie", "k1=v1")}; nghttp2_nv nva5[] = {MAKE_NV(":path", "/style.css"), MAKE_NV("x-nghttp2", "")}; nghttp2_bufs bufs; ssize_t blocklen; nva_out out; int rv; nghttp2_mem *mem; mem = nghttp2_mem_default(); frame_pack_bufs_init(&bufs); nva_out_init(&out); CU_ASSERT(0 == nghttp2_hd_deflate_init(&deflater, mem)); CU_ASSERT(0 == nghttp2_hd_inflate_init(&inflater, mem)); rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva1, ARRLEN(nva1)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(3 == out.nvlen); assert_nv_equal(nva1, out.nva, 3, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Second headers */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva2, ARRLEN(nva2)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == out.nvlen); assert_nv_equal(nva2, out.nva, 2, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Third headers, including same header field name, but value is not the same. */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva3, ARRLEN(nva3)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(3 == out.nvlen); assert_nv_equal(nva3, out.nva, 3, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Fourth headers, including duplicate header fields. */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva4, ARRLEN(nva4)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(3 == out.nvlen); assert_nv_equal(nva4, out.nva, 3, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Fifth headers includes empty value */ rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva5, ARRLEN(nva5)); blocklen = nghttp2_bufs_len(&bufs); CU_ASSERT(0 == rv); CU_ASSERT(blocklen > 0); CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0, mem)); CU_ASSERT(2 == out.nvlen); assert_nv_equal(nva5, out.nva, 2, mem); nva_out_reset(&out, mem); nghttp2_bufs_reset(&bufs); /* Cleanup */ nghttp2_bufs_free(&bufs); nghttp2_hd_inflate_free(&inflater); nghttp2_hd_deflate_free(&deflater); }