Fix header compression bug
This commit is contained in:
parent
48d7453a21
commit
e496800cb7
135
lib/nghttp2_hd.c
135
lib/nghttp2_hd.c
|
@ -175,6 +175,7 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char **ini_table;
|
const char **ini_table;
|
||||||
|
context->bad = 0;
|
||||||
context->hd_table = malloc(sizeof(nghttp2_hd_entry*)*
|
context->hd_table = malloc(sizeof(nghttp2_hd_entry*)*
|
||||||
NGHTTP2_INITIAL_HD_TABLE_SIZE);
|
NGHTTP2_INITIAL_HD_TABLE_SIZE);
|
||||||
memset(context->hd_table, 0, sizeof(nghttp2_hd_entry*)*
|
memset(context->hd_table, 0, sizeof(nghttp2_hd_entry*)*
|
||||||
|
@ -227,15 +228,15 @@ static void nghttp2_hd_context_free(nghttp2_hd_context *context)
|
||||||
nghttp2_hd_ws_entry *ent = &context->ws[i];
|
nghttp2_hd_ws_entry *ent = &context->ws[i];
|
||||||
switch(ent->cat) {
|
switch(ent->cat) {
|
||||||
case NGHTTP2_HD_CAT_INDEXED:
|
case NGHTTP2_HD_CAT_INDEXED:
|
||||||
--ent->indexed.entry->ref;
|
if(--ent->indexed.entry->ref == 0) {
|
||||||
if(ent->indexed.entry->ref == 0) {
|
|
||||||
nghttp2_hd_entry_free(ent->indexed.entry);
|
nghttp2_hd_entry_free(ent->indexed.entry);
|
||||||
|
free(ent->indexed.entry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_HD_CAT_INDNAME:
|
case NGHTTP2_HD_CAT_INDNAME:
|
||||||
--ent->indname.entry->ref;
|
if(--ent->indname.entry->ref == 0) {
|
||||||
if(ent->indname.entry->ref == 0) {
|
|
||||||
nghttp2_hd_entry_free(ent->indname.entry);
|
nghttp2_hd_entry_free(ent->indname.entry);
|
||||||
|
free(ent->indname.entry);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -244,9 +245,9 @@ static void nghttp2_hd_context_free(nghttp2_hd_context *context)
|
||||||
}
|
}
|
||||||
for(i = 0; i < context->refsetlen; ++i) {
|
for(i = 0; i < context->refsetlen; ++i) {
|
||||||
nghttp2_hd_entry *ent = context->refset[i];
|
nghttp2_hd_entry *ent = context->refset[i];
|
||||||
--ent->ref;
|
if(--ent->ref == 0) {
|
||||||
if(ent->ref == 0) {
|
|
||||||
nghttp2_hd_entry_free(ent);
|
nghttp2_hd_entry_free(ent);
|
||||||
|
free(ent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(i = 0; i < context->hd_tablelen; ++i) {
|
for(i = 0; i < context->hd_tablelen; ++i) {
|
||||||
|
@ -677,7 +678,7 @@ static int emit_subst_indname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t *bufp;
|
uint8_t *bufp;
|
||||||
size_t blocklen = count_encoded_length(ent->index + 1, 5) +
|
size_t blocklen = count_encoded_length(ent->index + 1, 6) +
|
||||||
count_encoded_length(index, 8) +
|
count_encoded_length(index, 8) +
|
||||||
count_encoded_length(valuelen, 8) + valuelen;
|
count_encoded_length(valuelen, 8) + valuelen;
|
||||||
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, blocklen);
|
||||||
|
@ -685,7 +686,7 @@ static int emit_subst_indname_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
bufp = *buf_ptr + *offset_ptr;
|
bufp = *buf_ptr + *offset_ptr;
|
||||||
bufp += encode_length(bufp, ent->index + 1, 5);
|
bufp += encode_length(bufp, ent->index + 1, 6);
|
||||||
bufp += encode_length(bufp, index, 8);
|
bufp += encode_length(bufp, index, 8);
|
||||||
bufp += encode_length(bufp, valuelen, 8);
|
bufp += encode_length(bufp, valuelen, 8);
|
||||||
memcpy(bufp, value, valuelen);
|
memcpy(bufp, value, valuelen);
|
||||||
|
@ -748,7 +749,10 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
nghttp2_nv *nv, size_t nvlen)
|
nghttp2_nv *nv, size_t nvlen)
|
||||||
{
|
{
|
||||||
size_t i, offset;
|
size_t i, offset;
|
||||||
int rv;
|
int rv = 0;
|
||||||
|
if(deflater->bad) {
|
||||||
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
}
|
||||||
create_workingset(deflater);
|
create_workingset(deflater);
|
||||||
offset = nv_offset;
|
offset = nv_offset;
|
||||||
for(i = 0; i < nvlen; ++i) {
|
for(i = 0; i < nvlen; ++i) {
|
||||||
|
@ -765,11 +769,11 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
/* If nv[i] is found in hd_table, use Indexed Header repr */
|
/* If nv[i] is found in hd_table, use Indexed Header repr */
|
||||||
rv = add_workingset(deflater, ent);
|
rv = add_workingset(deflater, ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
rv = emit_indexed_block(buf_ptr, buflen_ptr, &offset, ent);
|
rv = emit_indexed_block(buf_ptr, buflen_ptr, &offset, ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Check name exists in hd_table */
|
/* Check name exists in hd_table */
|
||||||
|
@ -784,31 +788,32 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
rv = emit_indname_block(buf_ptr, buflen_ptr, &offset, ent,
|
rv = emit_indname_block(buf_ptr, buflen_ptr, &offset, ent,
|
||||||
nv[i].value, nv[i].valuelen, 0);
|
nv[i].value, nv[i].valuelen, 0);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nghttp2_hd_entry *new_ent;
|
nghttp2_hd_entry *new_ent;
|
||||||
/* No need to increment ent->ref here */
|
/* No need to increment ent->ref here */
|
||||||
new_ent = add_hd_table_subst(deflater, &nv[i], ent->index);
|
new_ent = add_hd_table_subst(deflater, &nv[i], ent->index);
|
||||||
if(!new_ent) {
|
if(!new_ent) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
rv = add_workingset(deflater, new_ent);
|
rv = add_workingset(deflater, new_ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
rv = emit_subst_indname_block(buf_ptr, buflen_ptr, &offset,
|
rv = emit_subst_indname_block(buf_ptr, buflen_ptr, &offset,
|
||||||
new_ent,
|
new_ent,
|
||||||
nv[i].value, nv[i].valuelen,
|
nv[i].value, nv[i].valuelen,
|
||||||
new_ent->index);
|
new_ent->index);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rv = emit_newname_block(buf_ptr, buflen_ptr, &offset, &nv[i], 0);
|
rv = emit_newname_block(buf_ptr, buflen_ptr, &offset, &nv[i], 0);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -821,11 +826,14 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
rv = emit_indexed_block(buf_ptr, buflen_ptr, &offset,
|
rv = emit_indexed_block(buf_ptr, buflen_ptr, &offset,
|
||||||
ws_ent->indexed.entry);
|
ws_ent->indexed.entry);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return offset - nv_offset;
|
return offset - nv_offset;
|
||||||
|
fail:
|
||||||
|
deflater->bad = 1;
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t build_nv_array(nghttp2_hd_context *inflater,
|
static ssize_t build_nv_array(nghttp2_hd_context *inflater,
|
||||||
|
@ -875,8 +883,11 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
nghttp2_nv **nva_ptr,
|
nghttp2_nv **nva_ptr,
|
||||||
uint8_t *in, size_t inlen)
|
uint8_t *in, size_t inlen)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv = 0;
|
||||||
uint8_t *last = in + inlen;
|
uint8_t *last = in + inlen;
|
||||||
|
if(inflater->bad) {
|
||||||
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
}
|
||||||
create_workingset(inflater);
|
create_workingset(inflater);
|
||||||
for(; in != last;) {
|
for(; in != last;) {
|
||||||
uint8_t c = *in;
|
uint8_t c = *in;
|
||||||
|
@ -886,13 +897,13 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
ssize_t index;
|
ssize_t index;
|
||||||
in = decode_length(&index, in, last, 7);
|
in = decode_length(&index, in, last, 7);
|
||||||
if(index < 0) {
|
if(index < 0) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
ws_ent = find_in_workingset_by_index(inflater, index);
|
ws_ent = find_in_workingset_by_index(inflater, index);
|
||||||
if(ws_ent) {
|
if(ws_ent) {
|
||||||
assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED);
|
assert(ws_ent->cat == NGHTTP2_HD_CAT_INDEXED);
|
||||||
--ws_ent->indexed.entry->ref;
|
if(--ws_ent->indexed.entry->ref == 0) {
|
||||||
if(ws_ent->indexed.entry->ref == 0) {
|
|
||||||
nghttp2_hd_entry_free(ws_ent->indexed.entry);
|
nghttp2_hd_entry_free(ws_ent->indexed.entry);
|
||||||
free(ws_ent->indexed.entry);
|
free(ws_ent->indexed.entry);
|
||||||
}
|
}
|
||||||
|
@ -900,12 +911,13 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
} else {
|
} else {
|
||||||
nghttp2_hd_entry *ent;
|
nghttp2_hd_entry *ent;
|
||||||
if(inflater->hd_tablelen <= index) {
|
if(inflater->hd_tablelen <= index) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
ent = inflater->hd_table[index];
|
ent = inflater->hd_table[index];
|
||||||
rv = add_workingset(inflater, ent);
|
rv = add_workingset(inflater, ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(c == 0x60u || c == 0x40u) {
|
} else if(c == 0x60u || c == 0x40u) {
|
||||||
|
@ -914,17 +926,20 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
nghttp2_nv nv;
|
nghttp2_nv nv;
|
||||||
ssize_t namelen, valuelen;
|
ssize_t namelen, valuelen;
|
||||||
if(++in == last) {
|
if(++in == last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
in = decode_length(&namelen, in, last, 8);
|
in = decode_length(&namelen, in, last, 8);
|
||||||
if(namelen < 0 || in + namelen > last) {
|
if(namelen < 0 || in + namelen > last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
nv.name = in;
|
nv.name = in;
|
||||||
in += namelen;
|
in += namelen;
|
||||||
in = decode_length(&valuelen, in, last, 8);
|
in = decode_length(&valuelen, in, last, 8);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
nv.namelen = namelen;
|
nv.namelen = namelen;
|
||||||
nv.value = in;
|
nv.value = in;
|
||||||
|
@ -938,11 +953,12 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
if(ent) {
|
if(ent) {
|
||||||
rv = add_workingset(inflater, ent);
|
rv = add_workingset(inflater, ent);
|
||||||
} else {
|
} else {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else if((c & 0x60u) == 0x60u || (c & 0x40) == 0x40u) {
|
} else if((c & 0x60u) == 0x60u || (c & 0x40) == 0x40u) {
|
||||||
/* Literal Header without Indexing - indexed name or Literal
|
/* Literal Header without Indexing - indexed name or Literal
|
||||||
|
@ -953,16 +969,19 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
ssize_t index;
|
ssize_t index;
|
||||||
in = decode_length(&index, in, last, 5);
|
in = decode_length(&index, in, last, 5);
|
||||||
if(index < 0) {
|
if(index < 0) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
--index;
|
--index;
|
||||||
if(inflater->hd_tablelen <= index) {
|
if(inflater->hd_tablelen <= index) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
ent = inflater->hd_table[index];
|
ent = inflater->hd_table[index];
|
||||||
in = decode_length(&valuelen, in , last, 8);
|
in = decode_length(&valuelen, in , last, 8);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
value = in;
|
value = in;
|
||||||
in += valuelen;
|
in += valuelen;
|
||||||
|
@ -984,11 +1003,12 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
if(new_ent) {
|
if(new_ent) {
|
||||||
rv = add_workingset(inflater, new_ent);
|
rv = add_workingset(inflater, new_ent);
|
||||||
} else {
|
} else {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else if(c == 0) {
|
} else if(c == 0) {
|
||||||
/* Literal Header with substitution indexing - new name */
|
/* Literal Header with substitution indexing - new name */
|
||||||
|
@ -996,21 +1016,25 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
nghttp2_nv nv;
|
nghttp2_nv nv;
|
||||||
ssize_t namelen, valuelen, subindex;
|
ssize_t namelen, valuelen, subindex;
|
||||||
if(++in == last) {
|
if(++in == last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
in = decode_length(&namelen, in, last, 8);
|
in = decode_length(&namelen, in, last, 8);
|
||||||
if(namelen < 0 || in + namelen > last) {
|
if(namelen < 0 || in + namelen > last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
nv.name = in;
|
nv.name = in;
|
||||||
in += namelen;
|
in += namelen;
|
||||||
in = decode_length(&subindex, in, last, 8);
|
in = decode_length(&subindex, in, last, 8);
|
||||||
if(subindex < 0) {
|
if(subindex < 0) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
in = decode_length(&valuelen, in, last, 8);
|
in = decode_length(&valuelen, in, last, 8);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
nv.value = in;
|
nv.value = in;
|
||||||
nv.namelen = namelen;
|
nv.namelen = namelen;
|
||||||
|
@ -1021,10 +1045,11 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
if(new_ent) {
|
if(new_ent) {
|
||||||
rv = add_workingset(inflater, new_ent);
|
rv = add_workingset(inflater, new_ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Literal Header with substitution indexing - indexed name */
|
/* Literal Header with substitution indexing - indexed name */
|
||||||
|
@ -1034,20 +1059,24 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
nghttp2_nv nv;
|
nghttp2_nv nv;
|
||||||
in = decode_length(&index, in, last, 6);
|
in = decode_length(&index, in, last, 6);
|
||||||
if(index < 0) {
|
if(index < 0) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
--index;
|
--index;
|
||||||
if(inflater->hd_tablelen <= index) {
|
if(inflater->hd_tablelen <= index) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
ent = inflater->hd_table[index];
|
ent = inflater->hd_table[index];
|
||||||
in = decode_length(&subindex, in, last, 8);
|
in = decode_length(&subindex, in, last, 8);
|
||||||
if(subindex < 0) {
|
if(subindex < 0) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
in = decode_length(&valuelen, in, last, 8);
|
in = decode_length(&valuelen, in, last, 8);
|
||||||
if(valuelen < 0 || in + valuelen > last) {
|
if(valuelen < 0 || in + valuelen > last) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
++ent->ref;
|
++ent->ref;
|
||||||
nv.name = ent->nv.name;
|
nv.name = ent->nv.name;
|
||||||
|
@ -1063,14 +1092,18 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
if(new_ent) {
|
if(new_ent) {
|
||||||
rv = add_workingset(inflater, new_ent);
|
rv = add_workingset(inflater, new_ent);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
return rv;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return build_nv_array(inflater, nva_ptr);
|
return build_nv_array(inflater, nva_ptr);
|
||||||
|
fail:
|
||||||
|
inflater->bad = 1;
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_end_headers(nghttp2_hd_context *context)
|
int nghttp2_hd_end_headers(nghttp2_hd_context *context)
|
||||||
|
@ -1081,19 +1114,17 @@ int nghttp2_hd_end_headers(nghttp2_hd_context *context)
|
||||||
nghttp2_hd_ws_entry *ws_ent = &context->ws[i];
|
nghttp2_hd_ws_entry *ws_ent = &context->ws[i];
|
||||||
switch(ws_ent->cat) {
|
switch(ws_ent->cat) {
|
||||||
case NGHTTP2_HD_CAT_INDEXED:
|
case NGHTTP2_HD_CAT_INDEXED:
|
||||||
if(ws_ent->indexed.checked == 0 || ws_ent->indexed.entry->ref == 1) {
|
if(ws_ent->indexed.checked) {
|
||||||
--ws_ent->indexed.entry->ref;
|
context->refset[context->refsetlen++] = ws_ent->indexed.entry;
|
||||||
if(ws_ent->indexed.entry->ref == 0) {
|
} else {
|
||||||
|
if(--ws_ent->indexed.entry->ref == 0) {
|
||||||
nghttp2_hd_entry_free(ws_ent->indexed.entry);
|
nghttp2_hd_entry_free(ws_ent->indexed.entry);
|
||||||
free(ws_ent->indexed.entry);
|
free(ws_ent->indexed.entry);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
context->refset[context->refsetlen++] = ws_ent->indexed.entry;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_HD_CAT_INDNAME:
|
case NGHTTP2_HD_CAT_INDNAME:
|
||||||
--ws_ent->indname.entry->ref;
|
if(--ws_ent->indname.entry->ref == 0) {
|
||||||
if(ws_ent->indname.entry->ref == 0) {
|
|
||||||
nghttp2_hd_entry_free(ws_ent->indname.entry);
|
nghttp2_hd_entry_free(ws_ent->indname.entry);
|
||||||
free(ws_ent->indname.entry);
|
free(ws_ent->indname.entry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,6 +113,10 @@ typedef struct {
|
||||||
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. */
|
||||||
uint16_t hd_table_bufsize;
|
uint16_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;
|
||||||
} nghttp2_hd_context;
|
} nghttp2_hd_context;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -51,9 +51,9 @@ void test_nghttp2_hd_deflate(void)
|
||||||
MAKE_NV("hello", "world")};
|
MAKE_NV("hello", "world")};
|
||||||
nghttp2_nv nva2[] = {MAKE_NV(":path", "/script.js"),
|
nghttp2_nv nva2[] = {MAKE_NV(":path", "/script.js"),
|
||||||
MAKE_NV(":scheme", "https")};
|
MAKE_NV(":scheme", "https")};
|
||||||
nghttp2_nv nva3[] = {MAKE_NV(":path", "/style.css"),
|
nghttp2_nv nva3[] = {MAKE_NV("cookie", "k1=v1"),
|
||||||
MAKE_NV("cookie", "k1=v1"),
|
MAKE_NV("cookie", "k2=v2"),
|
||||||
MAKE_NV("cookie", "k2=v2")};
|
MAKE_NV("via", "proxy")};
|
||||||
nghttp2_nv nva4[] = {MAKE_NV(":path", "/style.css"),
|
nghttp2_nv nva4[] = {MAKE_NV(":path", "/style.css"),
|
||||||
MAKE_NV("cookie", "k1=v1"),
|
MAKE_NV("cookie", "k1=v1"),
|
||||||
MAKE_NV("cookie", "k1=v1")};
|
MAKE_NV("cookie", "k1=v1")};
|
||||||
|
@ -116,7 +116,7 @@ void test_nghttp2_hd_deflate(void)
|
||||||
encode duplicates. Only first one is encoded. */
|
encode duplicates. Only first one is encoded. */
|
||||||
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva4,
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, nv_offset, nva4,
|
||||||
sizeof(nva4)/sizeof(nghttp2_nv));
|
sizeof(nva4)/sizeof(nghttp2_nv));
|
||||||
CU_ASSERT(blocklen == 0);
|
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