diff --git a/lib/nghttp2_hd.c b/lib/nghttp2_hd.c index 9a3d8262..4f34652f 100644 --- a/lib/nghttp2_hd.c +++ b/lib/nghttp2_hd.c @@ -218,15 +218,15 @@ static void nghttp2_hd_context_free(nghttp2_hd_context *context) nghttp2_hd_ws_entry *ent = &context->ws[i]; switch(ent->cat) { case NGHTTP2_HD_CAT_INDEXED: - --ent->entry->ref; - if(ent->entry->ref == 0) { - nghttp2_hd_entry_free(ent->entry); + --ent->indexed.entry->ref; + if(ent->indexed.entry->ref == 0) { + nghttp2_hd_entry_free(ent->indexed.entry); } break; - case NGHTTP2_HD_CAT_LITERAL_IDXNAME: - --ent->entv.entry->ref; - if(ent->entv.entry->ref == 0) { - nghttp2_hd_entry_free(ent->entv.entry); + case NGHTTP2_HD_CAT_INDNAME: + --ent->indname.entry->ref; + if(ent->indname.entry->ref == 0) { + nghttp2_hd_entry_free(ent->indname.entry); } break; default: @@ -384,13 +384,13 @@ static int add_workingset(nghttp2_hd_context *context, nghttp2_hd_entry *ent) } ws_ent = &context->ws[context->wslen++]; ws_ent->cat = NGHTTP2_HD_CAT_INDEXED; - ws_ent->entry = ent; - ws_ent->checked = 1; + ws_ent->indexed.entry = ent; + ws_ent->indexed.checked = 1; ++ent->ref; return 0; } -static int add_workingset_literal(nghttp2_hd_context *context, +static int add_workingset_newname(nghttp2_hd_context *context, nghttp2_nv *nv) { nghttp2_hd_ws_entry *ws_ent; @@ -398,12 +398,12 @@ static int add_workingset_literal(nghttp2_hd_context *context, return NGHTTP2_ERR_HEADER_COMP; } ws_ent = &context->ws[context->wslen++]; - ws_ent->cat = NGHTTP2_HD_CAT_LITERAL; - ws_ent->nv = *nv; + ws_ent->cat = NGHTTP2_HD_CAT_NEWNAME; + ws_ent->newname.nv = *nv; return 0; } -static int add_workingset_literal_indname(nghttp2_hd_context *context, +static int add_workingset_indname(nghttp2_hd_context *context, nghttp2_hd_entry *ent, uint8_t *value, size_t valuelen) { @@ -412,11 +412,11 @@ static int add_workingset_literal_indname(nghttp2_hd_context *context, return NGHTTP2_ERR_HEADER_COMP; } ws_ent = &context->ws[context->wslen++]; - ws_ent->cat = NGHTTP2_HD_CAT_LITERAL_IDXNAME; - ws_ent->entv.entry = ent; + ws_ent->cat = NGHTTP2_HD_CAT_INDNAME; + ws_ent->indname.entry = ent; ++ent->ref; - ws_ent->entv.value = value; - ws_ent->entv.valuelen = valuelen; + ws_ent->indname.value = value; + ws_ent->indname.valuelen = valuelen; return 0; } @@ -428,20 +428,20 @@ static nghttp2_hd_ws_entry* find_in_workingset(nghttp2_hd_context *context, nghttp2_hd_ws_entry *ent = &context->ws[i]; switch(ent->cat) { case NGHTTP2_HD_CAT_INDEXED: - if(nghttp2_nv_equal(&ent->entry->nv, nv)) { + if(nghttp2_nv_equal(&ent->indexed.entry->nv, nv)) { return ent; } break; - case NGHTTP2_HD_CAT_LITERAL_IDXNAME: - if(ent->entv.entry->nv.namelen == nv->namelen && - ent->entv.valuelen == nv->valuelen && - memcmp(ent->entv.entry->nv.name, nv->name, nv->namelen) == 0 && - memcmp(ent->entv.value, nv->value, nv->valuelen) == 0) { + case NGHTTP2_HD_CAT_INDNAME: + if(ent->indname.entry->nv.namelen == nv->namelen && + ent->indname.valuelen == nv->valuelen && + memcmp(ent->indname.entry->nv.name, nv->name, nv->namelen) == 0 && + memcmp(ent->indname.value, nv->value, nv->valuelen) == 0) { return ent; } break; - case NGHTTP2_HD_CAT_LITERAL: - if(nghttp2_nv_equal(&ent->nv, nv)) { + case NGHTTP2_HD_CAT_NEWNAME: + if(nghttp2_nv_equal(&ent->newname.nv, nv)) { return ent; } default: @@ -459,7 +459,7 @@ static nghttp2_hd_ws_entry* find_in_workingset_by_index nghttp2_hd_ws_entry *ent = &context->ws[i]; /* Compare against *frozen* index, not the current header table index. */ - if(ent->cat == NGHTTP2_HD_CAT_INDEXED && ent->index == index) { + if(ent->cat == NGHTTP2_HD_CAT_INDEXED && ent->indexed.index == index) { return ent; } } @@ -712,9 +712,9 @@ static void create_workingset(nghttp2_hd_context *context) for(i = 0; i < context->refsetlen; ++i) { nghttp2_hd_ws_entry *ent = &context->ws[i]; ent->cat = NGHTTP2_HD_CAT_INDEXED; - ent->entry = context->refset[i]; - ent->index = ent->entry->index; - ent->checked = 0; + ent->indexed.entry = context->refset[i]; + ent->indexed.index = ent->indexed.entry->index; + ent->indexed.checked = 0; context->refset[i] = NULL; } context->wslen = context->refsetlen; @@ -734,7 +734,9 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater, nghttp2_hd_ws_entry *ws_ent; ws_ent = find_in_workingset(deflater, &nv[i]); if(ws_ent) { - ws_ent->checked = 1; + if(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED) { + ws_ent->indexed.checked = 1; + } } else { nghttp2_hd_entry *ent; ent = find_in_hd_table(deflater, &nv[i]); @@ -768,9 +770,10 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater, } for(i = 0; i < deflater->wslen; ++i) { nghttp2_hd_ws_entry *ws_ent = &deflater->ws[i]; - if(!ws_ent->checked) { - assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED); - rv = emit_index_block(buf_ptr, buflen_ptr, &offset, ws_ent->entry); + if(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED && + !ws_ent->indexed.checked) { + rv = emit_index_block(buf_ptr, buflen_ptr, &offset, + ws_ent->indexed.entry); if(rv < 0) { return rv; } @@ -799,19 +802,19 @@ static ssize_t build_nv_array(nghttp2_hd_context *inflater, nghttp2_hd_ws_entry *ent = &inflater->ws[i]; switch(ent->cat) { case NGHTTP2_HD_CAT_INDEXED: - *nv = ent->entry->nv; - ent->checked = 1; + *nv = ent->indexed.entry->nv; + ent->indexed.checked = 1; ++nv; break; - case NGHTTP2_HD_CAT_LITERAL_IDXNAME: - nv->name = ent->entv.entry->nv.name; - nv->namelen = ent->entv.entry->nv.namelen; - nv->value = ent->entv.value; - nv->valuelen = ent->entv.valuelen; + case NGHTTP2_HD_CAT_INDNAME: + nv->name = ent->indname.entry->nv.name; + nv->namelen = ent->indname.entry->nv.namelen; + nv->value = ent->indname.value; + nv->valuelen = ent->indname.valuelen; ++nv; break; - case NGHTTP2_HD_CAT_LITERAL: - *nv = ent->nv; + case NGHTTP2_HD_CAT_NEWNAME: + *nv = ent->newname.nv; ++nv; break; default: @@ -842,10 +845,10 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater, ws_ent = find_in_workingset_by_index(inflater, index); if(ws_ent) { assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED); - --ws_ent->entry->ref; - if(ws_ent->entry->ref == 0) { - nghttp2_hd_entry_free(ws_ent->entry); - free(ws_ent->entry); + --ws_ent->indexed.entry->ref; + if(ws_ent->indexed.entry->ref == 0) { + nghttp2_hd_entry_free(ws_ent->indexed.entry); + free(ws_ent->indexed.entry); } ws_ent->cat = NGHTTP2_HD_CAT_NONE; } else { @@ -883,7 +886,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater, in += valuelen; nghttp2_downcase(nv.name, nv.namelen); if(c == 0x60u) { - rv = add_workingset_literal(inflater, &nv); + rv = add_workingset_newname(inflater, &nv); } else { nghttp2_hd_entry *ent = add_hd_table_incremental(inflater, &nv); if(ent) { @@ -918,7 +921,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater, value = in; in += valuelen; if((c & 0x60u) == 0x60u) { - rv = add_workingset_literal_indname(inflater, ent, value, valuelen); + rv = add_workingset_indname(inflater, ent, value, valuelen); } else { nghttp2_nv nv; nghttp2_hd_entry *new_ent; @@ -1032,21 +1035,21 @@ int nghttp2_hd_end_headers(nghttp2_hd_context *context) nghttp2_hd_ws_entry *ws_ent = &context->ws[i]; switch(ws_ent->cat) { case NGHTTP2_HD_CAT_INDEXED: - if(ws_ent->checked == 0 || ws_ent->entry->ref == 1) { - --ws_ent->entry->ref; - if(ws_ent->entry->ref == 0) { - nghttp2_hd_entry_free(ws_ent->entry); - free(ws_ent->entry); + if(ws_ent->indexed.checked == 0 || ws_ent->indexed.entry->ref == 1) { + --ws_ent->indexed.entry->ref; + if(ws_ent->indexed.entry->ref == 0) { + nghttp2_hd_entry_free(ws_ent->indexed.entry); + free(ws_ent->indexed.entry); } } else { - context->refset[context->refsetlen++] = ws_ent->entry; + context->refset[context->refsetlen++] = ws_ent->indexed.entry; } break; - case NGHTTP2_HD_CAT_LITERAL_IDXNAME: - --ws_ent->entv.entry->ref; - if(ws_ent->entv.entry->ref == 0) { - nghttp2_hd_entry_free(ws_ent->entv.entry); - free(ws_ent->entv.entry); + case NGHTTP2_HD_CAT_INDNAME: + --ws_ent->indname.entry->ref; + if(ws_ent->indname.entry->ref == 0) { + nghttp2_hd_entry_free(ws_ent->indname.entry); + free(ws_ent->indname.entry); } break; default: diff --git a/lib/nghttp2_hd.h b/lib/nghttp2_hd.h index 0b0de73f..f277cb40 100644 --- a/lib/nghttp2_hd.h +++ b/lib/nghttp2_hd.h @@ -63,28 +63,31 @@ typedef struct { typedef enum { NGHTTP2_HD_CAT_NONE, NGHTTP2_HD_CAT_INDEXED, - NGHTTP2_HD_CAT_LITERAL_IDXNAME, - NGHTTP2_HD_CAT_LITERAL + NGHTTP2_HD_CAT_INDNAME, + NGHTTP2_HD_CAT_NEWNAME } nghttp2_hd_entry_cat; typedef struct nghttp2_hd_ws_entry { nghttp2_hd_entry_cat cat; union { /* For NGHTTP2_HD_CAT_INDEXED */ - nghttp2_hd_entry *entry; - /* For NGHTTP2_HD_CAT_LITERAL */ - nghttp2_nv nv; - /* For NGHTTP2_HD_CAT_LITERAL_IDXNAME */ + struct { + nghttp2_hd_entry *entry; + uint8_t index; + uint8_t checked; + } indexed; + /* For NGHTTP2_HD_CAT_NEWNAME */ + struct { + nghttp2_nv nv; + } newname; + /* For NGHTTP2_HD_CAT_LITERAL_INDNAME */ struct { /* The entry in header table the name stored */ nghttp2_hd_entry *entry; uint8_t *value; uint16_t valuelen; - } entv; + } indname; }; - /* TODO Only usable with NGHTTP2_HD_CAT_INDEXED */ - uint8_t index; - uint8_t checked; } nghttp2_hd_ws_entry; typedef struct {