Use substitution as long as no eviction is required
This commit is contained in:
parent
aa87130711
commit
e92b74d66e
|
@ -722,6 +722,14 @@ static void create_workingset(nghttp2_hd_context *context)
|
||||||
context->refsetlen = 0;
|
context->refsetlen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int require_eviction_on_subst(nghttp2_hd_context *context,
|
||||||
|
nghttp2_nv *nv,
|
||||||
|
nghttp2_hd_entry *ent)
|
||||||
|
{
|
||||||
|
return context->capacity - entry_room(ent->nv.namelen, ent->nv.valuelen) +
|
||||||
|
entry_room(nv->namelen, nv->valuelen) > NGHTTP2_MAX_HD_TABLE_CAPACITY;
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
uint8_t **buf_ptr, size_t *buflen_ptr,
|
uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
size_t nv_offset,
|
size_t nv_offset,
|
||||||
|
@ -755,11 +763,29 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
/* Check name exists in hd_table */
|
/* Check name exists in hd_table */
|
||||||
ent = find_name_in_hd_table(deflater, &nv[i]);
|
ent = find_name_in_hd_table(deflater, &nv[i]);
|
||||||
if(ent) {
|
if(ent) {
|
||||||
|
/* As long as no eviction kicked in, perform substitution */
|
||||||
|
if(require_eviction_on_subst(deflater, &nv[i], ent)) {
|
||||||
rv = emit_literal_indname_block(buf_ptr, buflen_ptr, &offset, ent,
|
rv = emit_literal_indname_block(buf_ptr, buflen_ptr, &offset, ent,
|
||||||
nv[i].value, nv[i].valuelen, 0);
|
nv[i].value, nv[i].valuelen, 0);
|
||||||
|
} else {
|
||||||
|
nghttp2_hd_entry *new_ent;
|
||||||
|
/* No need to increment ent->ref here */
|
||||||
|
new_ent = add_hd_table_subst(deflater, &nv[i], ent->index);
|
||||||
|
if(!new_ent) {
|
||||||
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
}
|
||||||
|
rv = add_workingset(deflater, new_ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
rv = emit_subst_indname_block(buf_ptr, buflen_ptr, &offset,
|
||||||
|
new_ent,
|
||||||
|
nv[i].value, nv[i].valuelen,
|
||||||
|
new_ent->index);
|
||||||
|
if(rv < 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rv = emit_literal_block(buf_ptr, buflen_ptr, &offset, &nv[i], 0);
|
rv = emit_literal_block(buf_ptr, buflen_ptr, &offset, &nv[i], 0);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ void test_nghttp2_hd_deflate(void)
|
||||||
|
|
||||||
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva1,
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva1,
|
||||||
sizeof(nva1)/sizeof(nghttp2_nv));
|
sizeof(nva1)/sizeof(nghttp2_nv));
|
||||||
CU_ASSERT((1+1+22)+(1)+(1+1+5+1+5) == blocklen);
|
CU_ASSERT(blocklen > 0);
|
||||||
nghttp2_hd_end_headers(&deflater);
|
nghttp2_hd_end_headers(&deflater);
|
||||||
|
|
||||||
CU_ASSERT(3 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
|
CU_ASSERT(3 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
|
||||||
|
@ -73,12 +73,12 @@ void test_nghttp2_hd_deflate(void)
|
||||||
nghttp2_nv_array_del(resnva);
|
nghttp2_nv_array_del(resnva);
|
||||||
nghttp2_hd_end_headers(&inflater);
|
nghttp2_hd_end_headers(&inflater);
|
||||||
|
|
||||||
CU_ASSERT(1 == inflater.refsetlen);
|
CU_ASSERT(2 == inflater.refsetlen);
|
||||||
|
|
||||||
/* Second headers */
|
/* Second headers */
|
||||||
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva2,
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva2,
|
||||||
sizeof(nva2)/sizeof(nghttp2_nv));
|
sizeof(nva2)/sizeof(nghttp2_nv));
|
||||||
CU_ASSERT((1+1+10) == blocklen);
|
CU_ASSERT(blocklen > 0);
|
||||||
nghttp2_hd_end_headers(&deflater);
|
nghttp2_hd_end_headers(&deflater);
|
||||||
|
|
||||||
CU_ASSERT(2 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
|
CU_ASSERT(2 == nghttp2_hd_inflate_hd(&inflater, &resnva, buf + nv_offset,
|
||||||
|
|
Loading…
Reference in New Issue