nghttp2_hd: Use defalte_hd_table_bufsize for decoder as well

This commit is contained in:
Tatsuhiro Tsujikawa 2013-10-31 01:51:16 +09:00
parent c8a9f8d312
commit b0f76773e1
2 changed files with 58 additions and 64 deletions

View File

@ -708,12 +708,12 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
size_t index = context->hd_table.len - 1;
nghttp2_hd_entry* ent = nghttp2_hd_ringbuf_get(&context->hd_table, index);
context->hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen);
if(context->hd_table_bufsize < context->deflate_hd_table_bufsize) {
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
ent->nv.valuelen);
--context->deflate_hd_tablelen;
}
if(context->role == NGHTTP2_HD_ROLE_DEFLATE) {
if(context->hd_table_bufsize < context->deflate_hd_table_bufsize) {
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
ent->nv.valuelen);
--context->deflate_hd_tablelen;
}
if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
/* Emit common header just before it slips away from the
table. If we don't do this, we have to emit it in literal
@ -730,45 +730,43 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
free(ent);
}
}
if(context->role == NGHTTP2_HD_ROLE_DEFLATE) {
while(context->deflate_hd_table_bufsize + room >
context->deflate_hd_table_bufsize_max
&& context->deflate_hd_tablelen > 0) {
size_t index = context->deflate_hd_tablelen - 1;
nghttp2_hd_entry *ent =
nghttp2_hd_ringbuf_get(&context->hd_table, index);
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
ent->nv.valuelen);
--context->deflate_hd_tablelen;
if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
/* Just like a normal eviction, implicit header must be
emitted twice. */
rv = emit_implicit(buf_ptr, buflen_ptr, offset_ptr, index);
if(rv != 0) {
return NULL;
}
ent->flags ^= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
while(context->deflate_hd_table_bufsize + room >
context->deflate_hd_table_bufsize_max
&& context->deflate_hd_tablelen > 0) {
size_t index = context->deflate_hd_tablelen - 1;
nghttp2_hd_entry *ent =
nghttp2_hd_ringbuf_get(&context->hd_table, index);
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
ent->nv.valuelen);
--context->deflate_hd_tablelen;
if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
/* Just like a normal eviction, implicit header must be
emitted twice. */
rv = emit_implicit(buf_ptr, buflen_ptr, offset_ptr, index);
if(rv != 0) {
return NULL;
}
if(ent->flags & NGHTTP2_HD_FLAG_REFSET) {
/* We need to drop entry from reference set. */
rv = emit_indexed_block(buf_ptr, buflen_ptr, offset_ptr, index);
if(rv != 0) {
return NULL;
}
ent->flags ^= NGHTTP2_HD_FLAG_REFSET;
}
/* Release memory. We don't remove entry from the header table
at this moment. */
if(ent->flags & NGHTTP2_HD_FLAG_NAME_ALLOC) {
free(ent->nv.name);
ent->nv.name = NULL;
ent->flags ^= NGHTTP2_HD_FLAG_NAME_ALLOC;
}
if(ent->flags & NGHTTP2_HD_FLAG_VALUE_ALLOC) {
free(ent->nv.value);
ent->nv.value = NULL;
ent->flags ^= NGHTTP2_HD_FLAG_VALUE_ALLOC;
ent->flags ^= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
}
if(ent->flags & NGHTTP2_HD_FLAG_REFSET) {
/* We need to drop entry from reference set. */
rv = emit_indexed_block(buf_ptr, buflen_ptr, offset_ptr, index);
if(rv != 0) {
return NULL;
}
ent->flags ^= NGHTTP2_HD_FLAG_REFSET;
}
/* Release memory. We don't remove entry from the header table
at this moment. */
if(ent->flags & NGHTTP2_HD_FLAG_NAME_ALLOC) {
free(ent->nv.name);
ent->nv.name = NULL;
ent->flags ^= NGHTTP2_HD_FLAG_NAME_ALLOC;
}
if(ent->flags & NGHTTP2_HD_FLAG_VALUE_ALLOC) {
free(ent->nv.value);
ent->nv.value = NULL;
ent->flags ^= NGHTTP2_HD_FLAG_VALUE_ALLOC;
}
}
@ -816,8 +814,7 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
context->hd_table_bufsize += room;
new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
nghttp2_hd_ringbuf_push_front(&context->hd_table, new_ent);
if(context->role == NGHTTP2_HD_ROLE_DEFLATE &&
room <= context->deflate_hd_table_bufsize_max) {
if(room <= context->deflate_hd_table_bufsize_max) {
context->deflate_hd_table_bufsize += room;
++context->deflate_hd_tablelen;
}
@ -828,9 +825,7 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
static ssize_t find_in_hd_table(nghttp2_hd_context *context, nghttp2_nv *nv)
{
size_t i;
size_t max = context->role == NGHTTP2_HD_ROLE_DEFLATE ?
context->deflate_hd_tablelen : context->hd_table.len;
for(i = 0; i < max; ++i) {
for(i = 0; i < context->deflate_hd_tablelen; ++i) {
nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, i);
if(nghttp2_nv_equal(&ent->nv, nv)) {
return i;
@ -849,9 +844,7 @@ static ssize_t find_name_in_hd_table(nghttp2_hd_context *context,
nghttp2_nv *nv)
{
size_t i;
size_t max = context->role == NGHTTP2_HD_ROLE_DEFLATE ?
context->deflate_hd_tablelen : context->hd_table.len;
for(i = 0; i < max; ++i) {
for(i = 0; i < context->deflate_hd_tablelen; ++i) {
nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, i);
if(ent->nv.namelen == nv->namelen &&
memcmp(ent->nv.name, nv->name, nv->namelen) == 0) {
@ -878,17 +871,18 @@ int nghttp2_hd_change_table_size(nghttp2_hd_context *context,
return rv;
}
context->hd_table_bufsize_max = hd_table_bufsize_max;
if(context->role == NGHTTP2_HD_ROLE_INFLATE) {
context->deflate_hd_table_bufsize_max = hd_table_bufsize_max;
}
while(context->hd_table_bufsize > context->hd_table_bufsize_max &&
context->hd_table.len > 0) {
size_t index = context->hd_table.len - 1;
nghttp2_hd_entry* ent = nghttp2_hd_ringbuf_get(&context->hd_table, index);
context->hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen);
if(context->role == NGHTTP2_HD_ROLE_DEFLATE) {
if(context->hd_table_bufsize < context->deflate_hd_table_bufsize) {
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
ent->nv.valuelen);
--context->deflate_hd_tablelen;
}
if(context->hd_table_bufsize < context->deflate_hd_table_bufsize) {
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
ent->nv.valuelen);
--context->deflate_hd_tablelen;
}
nghttp2_hd_ringbuf_pop_back(&context->hd_table);
if(--ent->ref == 0) {

View File

@ -93,18 +93,22 @@ typedef struct {
/* The header table size for decoding. If the context is initialized
as encoder, this value is advertised by remote endpoint
decoder. */
size_t hd_table_bufsize;
/* If inflate/deflate error occurred, this value is set to 1 and
further invocation of inflate/deflate will fail with
NGHTTP2_ERR_HEADER_COMP. */
size_t hd_table_bufsize_max;
/* The current effective header table size for encoding. This value
is meaningful iff this context is initialized as
encoder. |deflate_hd_table_bufsize| <= |hd_table_bufsize| must be
is always equal to |hd_table_bufsize| on decoder
context. |deflate_hd_table_bufsize| <= |hd_table_bufsize| must be
hold. */
size_t deflate_hd_table_bufsize;
/* The maximum effective header table for encoding. Although header
table size is bounded by |hd_table_bufsize_max|, the encoder can
use smaller buffer by not retaining the header name/values beyond
the |deflate_hd_table_bufsize_max| and not referencing those
entries. This value is meaningful iff this context is initialized
as encoder. */
entries. This value is always equal to |hd_table_bufsize_max| on
decoder context. */
size_t deflate_hd_table_bufsize_max;
/* The number of effective entry in |hd_table|. */
size_t deflate_hd_tablelen;
@ -118,10 +122,6 @@ typedef struct {
/* Abstract buffer size of hd_table as described in the spec. This
is the sum of length of name/value in hd_table +
NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
size_t hd_table_bufsize;
/* If inflate/deflate error occurred, this value is set to 1 and
further invocation of inflate/deflate will fail with
NGHTTP2_ERR_HEADER_COMP. */
uint8_t bad;
/* Role of this context; deflate or infalte */
nghttp2_hd_role role;