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; size_t index = context->hd_table.len - 1;
nghttp2_hd_entry* ent = nghttp2_hd_ringbuf_get(&context->hd_table, index); nghttp2_hd_entry* ent = nghttp2_hd_ringbuf_get(&context->hd_table, index);
context->hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen); 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->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) { if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
/* Emit common header just before it slips away from the /* Emit common header just before it slips away from the
table. If we don't do this, we have to emit it in literal 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); free(ent);
} }
} }
if(context->role == NGHTTP2_HD_ROLE_DEFLATE) { while(context->deflate_hd_table_bufsize + room >
while(context->deflate_hd_table_bufsize + room > context->deflate_hd_table_bufsize_max
context->deflate_hd_table_bufsize_max && context->deflate_hd_tablelen > 0) {
&& context->deflate_hd_tablelen > 0) { size_t index = context->deflate_hd_tablelen - 1;
size_t index = context->deflate_hd_tablelen - 1; nghttp2_hd_entry *ent =
nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, index);
nghttp2_hd_ringbuf_get(&context->hd_table, index); context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen);
ent->nv.valuelen); --context->deflate_hd_tablelen;
--context->deflate_hd_tablelen; if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) { /* Just like a normal eviction, implicit header must be
/* Just like a normal eviction, implicit header must be emitted twice. */
emitted twice. */ rv = emit_implicit(buf_ptr, buflen_ptr, offset_ptr, index);
rv = emit_implicit(buf_ptr, buflen_ptr, offset_ptr, index); if(rv != 0) {
if(rv != 0) { return NULL;
return NULL;
}
ent->flags ^= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
} }
if(ent->flags & NGHTTP2_HD_FLAG_REFSET) { ent->flags ^= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
/* We need to drop entry from reference set. */ }
rv = emit_indexed_block(buf_ptr, buflen_ptr, offset_ptr, index); if(ent->flags & NGHTTP2_HD_FLAG_REFSET) {
if(rv != 0) { /* We need to drop entry from reference set. */
return NULL; rv = emit_indexed_block(buf_ptr, buflen_ptr, offset_ptr, index);
} if(rv != 0) {
ent->flags ^= NGHTTP2_HD_FLAG_REFSET; return NULL;
}
/* 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_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; context->hd_table_bufsize += room;
new_ent->flags |= NGHTTP2_HD_FLAG_REFSET; new_ent->flags |= NGHTTP2_HD_FLAG_REFSET;
nghttp2_hd_ringbuf_push_front(&context->hd_table, new_ent); nghttp2_hd_ringbuf_push_front(&context->hd_table, new_ent);
if(context->role == NGHTTP2_HD_ROLE_DEFLATE && if(room <= context->deflate_hd_table_bufsize_max) {
room <= context->deflate_hd_table_bufsize_max) {
context->deflate_hd_table_bufsize += room; context->deflate_hd_table_bufsize += room;
++context->deflate_hd_tablelen; ++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) static ssize_t find_in_hd_table(nghttp2_hd_context *context, nghttp2_nv *nv)
{ {
size_t i; size_t i;
size_t max = context->role == NGHTTP2_HD_ROLE_DEFLATE ? for(i = 0; i < context->deflate_hd_tablelen; ++i) {
context->deflate_hd_tablelen : context->hd_table.len;
for(i = 0; i < max; ++i) {
nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, i); nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, i);
if(nghttp2_nv_equal(&ent->nv, nv)) { if(nghttp2_nv_equal(&ent->nv, nv)) {
return i; return i;
@ -849,9 +844,7 @@ static ssize_t find_name_in_hd_table(nghttp2_hd_context *context,
nghttp2_nv *nv) nghttp2_nv *nv)
{ {
size_t i; size_t i;
size_t max = context->role == NGHTTP2_HD_ROLE_DEFLATE ? for(i = 0; i < context->deflate_hd_tablelen; ++i) {
context->deflate_hd_tablelen : context->hd_table.len;
for(i = 0; i < max; ++i) {
nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, i); nghttp2_hd_entry *ent = nghttp2_hd_ringbuf_get(&context->hd_table, i);
if(ent->nv.namelen == nv->namelen && if(ent->nv.namelen == nv->namelen &&
memcmp(ent->nv.name, nv->name, nv->namelen) == 0) { 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; return rv;
} }
context->hd_table_bufsize_max = hd_table_bufsize_max; 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 && while(context->hd_table_bufsize > context->hd_table_bufsize_max &&
context->hd_table.len > 0) { context->hd_table.len > 0) {
size_t index = context->hd_table.len - 1; size_t index = context->hd_table.len - 1;
nghttp2_hd_entry* ent = nghttp2_hd_ringbuf_get(&context->hd_table, index); nghttp2_hd_entry* ent = nghttp2_hd_ringbuf_get(&context->hd_table, index);
context->hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen); 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) {
if(context->hd_table_bufsize < context->deflate_hd_table_bufsize) { context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen,
context->deflate_hd_table_bufsize -= entry_room(ent->nv.namelen, ent->nv.valuelen);
ent->nv.valuelen); --context->deflate_hd_tablelen;
--context->deflate_hd_tablelen;
}
} }
nghttp2_hd_ringbuf_pop_back(&context->hd_table); nghttp2_hd_ringbuf_pop_back(&context->hd_table);
if(--ent->ref == 0) { if(--ent->ref == 0) {

View File

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