Don't substitute if same indexed header field name is already in working set

This commit is contained in:
Tatsuhiro Tsujikawa 2013-07-23 02:52:08 +09:00
parent cca1d19d3d
commit 3c9e31da87
2 changed files with 45 additions and 2 deletions

View File

@ -766,10 +766,17 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
/* Check name exists in hd_table */
ent = find_name_in_hd_table(deflater, &nv[i]);
if(ent) {
/* As long as no eviction kicked in, perform substitution */
if(require_eviction_on_subst(deflater, &nv[i], ent)) {
/* As long as no eviction kicked in and the same header
field name is not indexed and added, perform
substitution. Since we never evict anything, searching
ent->index in working set is safe. */
if(require_eviction_on_subst(deflater, &nv[i], ent) ||
find_in_workingset_by_index(deflater, ent->index)) {
rv = emit_indname_block(buf_ptr, buflen_ptr, &offset, ent,
nv[i].value, nv[i].valuelen, 0);
if(rv < 0) {
return rv;
}
} else {
nghttp2_hd_entry *new_ent;
/* No need to increment ent->ref here */

View File

@ -51,6 +51,12 @@ void test_nghttp2_hd_deflate(void)
MAKE_NV("hello", "world")};
nghttp2_nv nva2[] = {MAKE_NV(":path", "/script.js"),
MAKE_NV(":scheme", "https")};
nghttp2_nv nva3[] = {MAKE_NV(":path", "/style.css"),
MAKE_NV("cookie", "k1=v1"),
MAKE_NV("cookie", "k2=v2")};
nghttp2_nv nva4[] = {MAKE_NV(":path", "/style.css"),
MAKE_NV("cookie", "k1=v1"),
MAKE_NV("cookie", "k1=v1")};
size_t nv_offset = 12;
uint8_t *buf = NULL;
size_t buflen = 0;
@ -89,6 +95,36 @@ void test_nghttp2_hd_deflate(void)
nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater);
/* Third headers, including same header field name, but value is not
the same. */
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva3,
sizeof(nva3)/sizeof(nghttp2_nv));
CU_ASSERT(blocklen > 0);
nghttp2_hd_end_headers(&deflater);
CU_ASSERT(3 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
blocklen));
assert_nv_equal(nva3, resnva, 3);
nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater);
/* Fourth headers, including duplicate header fields. We don't
encode duplicates. Only first one is encoded. */
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva4,
sizeof(nva4)/sizeof(nghttp2_nv));
CU_ASSERT(blocklen == 0);
nghttp2_hd_end_headers(&deflater);
CU_ASSERT(2 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
blocklen));
assert_nv_equal(nva4, resnva, 2);
nghttp2_nv_array_del(resnva);
nghttp2_hd_end_headers(&inflater);
free(buf);
nghttp2_hd_inflate_free(&inflater);
nghttp2_hd_deflate_free(&deflater);