Honor NGHTTP2_NV_FLAG_NO_INDEX in deflater and inflater
This commit is contained in:
parent
c55df4a30b
commit
7877b676e3
155
lib/nghttp2_hd.c
155
lib/nghttp2_hd.c
|
@ -352,6 +352,7 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater)
|
||||||
inflater->index = 0;
|
inflater->index = 0;
|
||||||
inflater->left = 0;
|
inflater->left = 0;
|
||||||
inflater->index_required = 0;
|
inflater->index_required = 0;
|
||||||
|
inflater->no_index = 0;
|
||||||
inflater->ent_name = NULL;
|
inflater->ent_name = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -543,11 +544,10 @@ static int nghttp2_hd_handle_buffer_error(int rv)
|
||||||
static int emit_clear_refset(nghttp2_bufs *bufs)
|
static int emit_clear_refset(nghttp2_bufs *bufs)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t sb[] = {0x80u, 0x80u};
|
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "deflatehd: emit clear refset\n"));
|
DEBUGF(fprintf(stderr, "deflatehd: emit clear refset\n"));
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, sb, sizeof(sb));
|
rv = nghttp2_bufs_addb(bufs, 0x30u);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return nghttp2_hd_handle_buffer_error(rv);
|
return nghttp2_hd_handle_buffer_error(rv);
|
||||||
}
|
}
|
||||||
|
@ -564,7 +564,7 @@ static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "deflatehd: emit table_size=%zu\n", table_size));
|
DEBUGF(fprintf(stderr, "deflatehd: emit table_size=%zu\n", table_size));
|
||||||
|
|
||||||
blocklen = 1 + count_encoded_length(table_size, 7);
|
blocklen = count_encoded_length(table_size, 4);
|
||||||
|
|
||||||
if(sizeof(sb) < blocklen) {
|
if(sizeof(sb) < blocklen) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
@ -572,9 +572,9 @@ static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
|
||||||
|
|
||||||
bufp = sb;
|
bufp = sb;
|
||||||
|
|
||||||
*bufp++ = 0x80u;
|
*bufp = 0x20u;
|
||||||
*bufp = 0;
|
|
||||||
encode_length(bufp, table_size, 7);
|
encode_length(bufp, table_size, 4);
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, sb, blocklen);
|
rv = nghttp2_bufs_add(bufs, sb, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
|
@ -652,8 +652,21 @@ static int emit_string(nghttp2_bufs *bufs,
|
||||||
return nghttp2_hd_handle_buffer_error(rv);
|
return nghttp2_hd_handle_buffer_error(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t pack_first_byte(int inc_indexing, int no_index)
|
||||||
|
{
|
||||||
|
if(inc_indexing) {
|
||||||
|
return 0x40u;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(no_index) {
|
||||||
|
return 0x10u;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
static int emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
const uint8_t *value, size_t valuelen,
|
nghttp2_nv *nv,
|
||||||
int inc_indexing)
|
int inc_indexing)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -662,18 +675,28 @@ static int emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
size_t blocklen;
|
size_t blocklen;
|
||||||
int huffman;
|
int huffman;
|
||||||
uint8_t sb[16];
|
uint8_t sb[16];
|
||||||
|
size_t prefixlen;
|
||||||
|
int no_index;
|
||||||
|
|
||||||
|
no_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) != 0;
|
||||||
|
|
||||||
|
if(inc_indexing) {
|
||||||
|
prefixlen = 6;
|
||||||
|
} else {
|
||||||
|
prefixlen = 4;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr,
|
DEBUGF(fprintf(stderr,
|
||||||
"deflatehd: emit indname index=%zu, valuelen=%zu, "
|
"deflatehd: emit indname index=%zu, valuelen=%u, "
|
||||||
"indexing=%d\n",
|
"indexing=%d, no_index=%d\n",
|
||||||
index, valuelen, inc_indexing));
|
index, nv->valuelen, inc_indexing, no_index));
|
||||||
|
|
||||||
encvallen = nghttp2_hd_huff_encode_count(value, valuelen);
|
encvallen = nghttp2_hd_huff_encode_count(nv->value, nv->valuelen);
|
||||||
blocklen = count_encoded_length(index + 1, 6);
|
blocklen = count_encoded_length(index + 1, prefixlen);
|
||||||
huffman = encvallen < valuelen;
|
huffman = encvallen < nv->valuelen;
|
||||||
|
|
||||||
if(!huffman) {
|
if(!huffman) {
|
||||||
encvallen = valuelen;
|
encvallen = nv->valuelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sizeof(sb) < blocklen) {
|
if(sizeof(sb) < blocklen) {
|
||||||
|
@ -682,15 +705,16 @@ static int emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
|
|
||||||
bufp = sb;
|
bufp = sb;
|
||||||
|
|
||||||
*bufp = inc_indexing ? 0 : 0x40u;
|
*bufp = pack_first_byte(inc_indexing, no_index);
|
||||||
bufp += encode_length(bufp, index + 1, 6);
|
|
||||||
|
bufp += encode_length(bufp, index + 1, prefixlen);
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, sb, blocklen);
|
rv = nghttp2_bufs_add(bufs, sb, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return nghttp2_hd_handle_buffer_error(rv);
|
return nghttp2_hd_handle_buffer_error(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = emit_string(bufs, encvallen, huffman, value, valuelen);
|
rv = emit_string(bufs, encvallen, huffman, nv->value, nv->valuelen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -706,11 +730,14 @@ static int emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||||
size_t encvallen;
|
size_t encvallen;
|
||||||
int name_huffman;
|
int name_huffman;
|
||||||
int value_huffman;
|
int value_huffman;
|
||||||
|
int no_index;
|
||||||
|
|
||||||
|
no_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) != 0;
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr,
|
DEBUGF(fprintf(stderr,
|
||||||
"deflatehd: emit newname namelen=%u, valuelen=%u, "
|
"deflatehd: emit newname namelen=%u, valuelen=%u, "
|
||||||
"indexing=%d\n",
|
"indexing=%d, no_index=%d\n",
|
||||||
nv->namelen, nv->valuelen, inc_indexing));
|
nv->namelen, nv->valuelen, inc_indexing, no_index));
|
||||||
|
|
||||||
encnamelen = nghttp2_hd_huff_encode_count(nv->name, nv->namelen);
|
encnamelen = nghttp2_hd_huff_encode_count(nv->name, nv->namelen);
|
||||||
encvallen = nghttp2_hd_huff_encode_count(nv->value, nv->valuelen);
|
encvallen = nghttp2_hd_huff_encode_count(nv->value, nv->valuelen);
|
||||||
|
@ -724,7 +751,7 @@ static int emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||||
encvallen = nv->valuelen;
|
encvallen = nv->valuelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_bufs_addb(bufs, inc_indexing ? 0 : 0x40u);
|
rv = nghttp2_bufs_addb(bufs, pack_first_byte(inc_indexing, no_index));
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return nghttp2_hd_handle_buffer_error(rv);
|
return nghttp2_hd_handle_buffer_error(rv);
|
||||||
}
|
}
|
||||||
|
@ -849,7 +876,9 @@ static search_result search_hd_table(nghttp2_hd_context *context,
|
||||||
uint32_t name_hash = hash(nv->name, nv->namelen);
|
uint32_t name_hash = hash(nv->name, nv->namelen);
|
||||||
uint32_t value_hash = hash(nv->value, nv->valuelen);
|
uint32_t value_hash = hash(nv->value, nv->valuelen);
|
||||||
ssize_t left = -1, right = STATIC_TABLE_LENGTH;
|
ssize_t left = -1, right = STATIC_TABLE_LENGTH;
|
||||||
|
int use_index = (nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) == 0;
|
||||||
|
|
||||||
|
if(use_index) {
|
||||||
for(i = 0; i < context->hd_table.len; ++i) {
|
for(i = 0; i < context->hd_table.len; ++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->name_hash == name_hash && name_eq(&ent->nv, nv)) {
|
if(ent->name_hash == name_hash && name_eq(&ent->nv, nv)) {
|
||||||
|
@ -863,6 +892,7 @@ static search_result search_hd_table(nghttp2_hd_context *context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while(right - left > 1) {
|
while(right - left > 1) {
|
||||||
ssize_t mid = (left + right) / 2;
|
ssize_t mid = (left + right) / 2;
|
||||||
|
@ -873,6 +903,7 @@ static search_result search_hd_table(nghttp2_hd_context *context,
|
||||||
right = mid;
|
right = mid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = right; i < STATIC_TABLE_LENGTH; ++i) {
|
for(i = right; i < STATIC_TABLE_LENGTH; ++i) {
|
||||||
nghttp2_hd_entry *ent = &static_table[i].ent;
|
nghttp2_hd_entry *ent = &static_table[i].ent;
|
||||||
if(ent->name_hash != name_hash) {
|
if(ent->name_hash != name_hash) {
|
||||||
|
@ -882,7 +913,8 @@ static search_result search_hd_table(nghttp2_hd_context *context,
|
||||||
if(res.index == -1) {
|
if(res.index == -1) {
|
||||||
res.index = context->hd_table.len + static_table[i].index;
|
res.index = context->hd_table.len + static_table[i].index;
|
||||||
}
|
}
|
||||||
if(ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
|
if(use_index &&
|
||||||
|
ent->value_hash == value_hash && value_eq(&ent->nv, nv)) {
|
||||||
res.index = context->hd_table.len + static_table[i].index;
|
res.index = context->hd_table.len + static_table[i].index;
|
||||||
res.name_value_match = 1;
|
res.name_value_match = 1;
|
||||||
return res;
|
return res;
|
||||||
|
@ -985,7 +1017,8 @@ nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
|
||||||
static int hd_deflate_should_indexing(nghttp2_hd_deflater *deflater,
|
static int hd_deflate_should_indexing(nghttp2_hd_deflater *deflater,
|
||||||
const nghttp2_nv *nv)
|
const nghttp2_nv *nv)
|
||||||
{
|
{
|
||||||
if(entry_room(nv->namelen, nv->valuelen) >
|
if((nv->flags & NGHTTP2_NV_FLAG_NO_INDEX) ||
|
||||||
|
entry_room(nv->namelen, nv->valuelen) >
|
||||||
deflater->ctx.hd_table_bufsize_max * 3 / 4) {
|
deflater->ctx.hd_table_bufsize_max * 3 / 4) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1123,7 +1156,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
|
||||||
if(index == -1) {
|
if(index == -1) {
|
||||||
rv = emit_newname_block(bufs, nv, incidx);
|
rv = emit_newname_block(bufs, nv, incidx);
|
||||||
} else {
|
} else {
|
||||||
rv = emit_indname_block(bufs, index, nv->value, nv->valuelen, incidx);
|
rv = emit_indname_block(bufs, index, nv, incidx);
|
||||||
}
|
}
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -1407,8 +1440,11 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
|
||||||
return NGHTTP2_ERR_NOMEM;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set NGHTTP2_NV_FLAG_NO_INDEX if never indexing repr is used */
|
if(inflater->no_index) {
|
||||||
|
nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
|
||||||
|
} else {
|
||||||
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
if(inflater->index_required) {
|
if(inflater->index_required) {
|
||||||
nghttp2_hd_entry *new_ent;
|
nghttp2_hd_entry *new_ent;
|
||||||
|
@ -1463,8 +1499,11 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
|
||||||
return NGHTTP2_ERR_NOMEM;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set NGHTTP2_NV_FLAG_NO_INDEX if never indexing repr is used */
|
if(inflater->no_index) {
|
||||||
|
nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
|
||||||
|
} else {
|
||||||
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
nv.name = inflater->ent_name->nv.name;
|
nv.name = inflater->ent_name->nv.name;
|
||||||
nv.namelen = inflater->ent_name->nv.namelen;
|
nv.namelen = inflater->ent_name->nv.namelen;
|
||||||
|
@ -1533,17 +1572,26 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
for(; in != last;) {
|
for(; in != last;) {
|
||||||
switch(inflater->state) {
|
switch(inflater->state) {
|
||||||
case NGHTTP2_HD_STATE_OPCODE:
|
case NGHTTP2_HD_STATE_OPCODE:
|
||||||
if(*in == 0x80u) {
|
if((*in & 0xf0u) == 0x20u) {
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: encoding context update\n"));
|
DEBUGF(fprintf(stderr, "inflatehd: header table size change\n"));
|
||||||
inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
|
inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
|
||||||
inflater->state = NGHTTP2_HD_STATE_CONTEXT_UPDATE;
|
inflater->state = NGHTTP2_HD_STATE_READ_TABLE_SIZE;
|
||||||
|
} else if((*in & 0xf0u) == 0x30u) {
|
||||||
|
if(*in != 0x30u) {
|
||||||
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUGF(fprintf(stderr, "inflatehd: clearing reference set\n"));
|
||||||
|
inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
|
||||||
|
inflater->state = NGHTTP2_HD_STATE_CLEAR_REFSET;
|
||||||
++in;
|
++in;
|
||||||
} else if(*in & 0x80u) {
|
} else if(*in & 0x80u) {
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: indexed repr\n"));
|
DEBUGF(fprintf(stderr, "inflatehd: indexed repr\n"));
|
||||||
inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
|
inflater->opcode = NGHTTP2_HD_OPCODE_INDEXED;
|
||||||
inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
|
inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
|
||||||
} else {
|
} else {
|
||||||
if(*in == 0x40 || *in == 0) {
|
if(*in == 0x40u || *in == 0 || *in == 0x10u) {
|
||||||
DEBUGF(fprintf(stderr,
|
DEBUGF(fprintf(stderr,
|
||||||
"inflatehd: literal header repr - new name\n"));
|
"inflatehd: literal header repr - new name\n"));
|
||||||
inflater->opcode = NGHTTP2_HD_OPCODE_NEWNAME;
|
inflater->opcode = NGHTTP2_HD_OPCODE_NEWNAME;
|
||||||
|
@ -1554,34 +1602,26 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
inflater->opcode = NGHTTP2_HD_OPCODE_INDNAME;
|
inflater->opcode = NGHTTP2_HD_OPCODE_INDNAME;
|
||||||
inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
|
inflater->state = NGHTTP2_HD_STATE_READ_INDEX;
|
||||||
}
|
}
|
||||||
inflater->index_required = (*in & 0x40) == 0;
|
inflater->index_required = (*in & 0x40) != 0;
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: indexing required=%d\n",
|
inflater->no_index = (*in & 0x10u) != 0;
|
||||||
inflater->index_required != 0));
|
DEBUGF(fprintf(stderr,
|
||||||
|
"inflatehd: indexing required=%d, no_index=%d\n",
|
||||||
|
inflater->index_required,
|
||||||
|
inflater->no_index));
|
||||||
if(inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
|
if(inflater->opcode == NGHTTP2_HD_OPCODE_NEWNAME) {
|
||||||
++in;
|
++in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inflater->left = 0;
|
inflater->left = 0;
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_HD_STATE_CONTEXT_UPDATE:
|
case NGHTTP2_HD_STATE_CLEAR_REFSET:
|
||||||
if(*in & 0x80u) {
|
|
||||||
if(*in != 0x80u) {
|
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
++in;
|
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: clearing reference set\n"));
|
|
||||||
clear_refset(&inflater->ctx);
|
clear_refset(&inflater->ctx);
|
||||||
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Header table size change */
|
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: header table size change\n"));
|
|
||||||
inflater->state = NGHTTP2_HD_STATE_READ_TABLE_SIZE;
|
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_HD_STATE_READ_TABLE_SIZE:
|
case NGHTTP2_HD_STATE_READ_TABLE_SIZE:
|
||||||
rfin = 0;
|
rfin = 0;
|
||||||
rv = hd_inflate_read_len(inflater, &rfin, in, last, 7,
|
rv = hd_inflate_read_len(inflater, &rfin, in, last, 4,
|
||||||
inflater->settings_hd_table_bufsize_max);
|
inflater->settings_hd_table_bufsize_max);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1595,11 +1635,19 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
hd_context_shrink_table_size(&inflater->ctx);
|
hd_context_shrink_table_size(&inflater->ctx);
|
||||||
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_HD_STATE_READ_INDEX:
|
case NGHTTP2_HD_STATE_READ_INDEX: {
|
||||||
|
size_t prefixlen;
|
||||||
|
|
||||||
|
if(inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED) {
|
||||||
|
prefixlen = 7;
|
||||||
|
} else if(inflater->index_required) {
|
||||||
|
prefixlen = 6;
|
||||||
|
} else {
|
||||||
|
prefixlen = 4;
|
||||||
|
}
|
||||||
|
|
||||||
rfin = 0;
|
rfin = 0;
|
||||||
rv = hd_inflate_read_len(inflater, &rfin, in, last,
|
rv = hd_inflate_read_len(inflater, &rfin, in, last, prefixlen,
|
||||||
inflater->opcode == NGHTTP2_HD_OPCODE_INDEXED ?
|
|
||||||
7 : 6,
|
|
||||||
get_max_index(&inflater->ctx) + 1);
|
get_max_index(&inflater->ctx) + 1);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1632,6 +1680,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
|
inflater->state = NGHTTP2_HD_STATE_CHECK_VALUELEN;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN:
|
case NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN:
|
||||||
hd_inflate_set_huffman_encoded(inflater, in);
|
hd_inflate_set_huffman_encoded(inflater, in);
|
||||||
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN;
|
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN;
|
||||||
|
@ -1871,10 +1920,10 @@ int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater)
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
const uint8_t *value, size_t valuelen,
|
nghttp2_nv *nv, int inc_indexing)
|
||||||
int inc_indexing)
|
|
||||||
{
|
{
|
||||||
return emit_indname_block(bufs, index, value, valuelen, inc_indexing);
|
|
||||||
|
return emit_indname_block(bufs, index, nv, inc_indexing);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||||
|
|
|
@ -103,7 +103,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NGHTTP2_HD_STATE_OPCODE,
|
NGHTTP2_HD_STATE_OPCODE,
|
||||||
NGHTTP2_HD_STATE_CONTEXT_UPDATE,
|
NGHTTP2_HD_STATE_CLEAR_REFSET,
|
||||||
NGHTTP2_HD_STATE_READ_TABLE_SIZE,
|
NGHTTP2_HD_STATE_READ_TABLE_SIZE,
|
||||||
NGHTTP2_HD_STATE_READ_INDEX,
|
NGHTTP2_HD_STATE_READ_INDEX,
|
||||||
NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
|
NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
|
||||||
|
@ -177,6 +177,9 @@ typedef struct {
|
||||||
uint8_t huffman_encoded;
|
uint8_t huffman_encoded;
|
||||||
/* nonzero if deflater requires that current entry is indexed */
|
/* nonzero if deflater requires that current entry is indexed */
|
||||||
uint8_t index_required;
|
uint8_t index_required;
|
||||||
|
/* nonzero if deflater requires that current entry must not be
|
||||||
|
indexed */
|
||||||
|
uint8_t no_index;
|
||||||
} nghttp2_hd_inflater;
|
} nghttp2_hd_inflater;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -370,8 +373,7 @@ int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater);
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
const uint8_t *value, size_t valuelen,
|
nghttp2_nv *nv, int inc_indexing);
|
||||||
int inc_indexing);
|
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||||
|
|
|
@ -274,6 +274,7 @@ int main(int argc, char* argv[])
|
||||||
test_nghttp2_hd_change_table_size) ||
|
test_nghttp2_hd_change_table_size) ||
|
||||||
!CU_add_test(pSuite, "hd_deflate_inflate",
|
!CU_add_test(pSuite, "hd_deflate_inflate",
|
||||||
test_nghttp2_hd_deflate_inflate) ||
|
test_nghttp2_hd_deflate_inflate) ||
|
||||||
|
!CU_add_test(pSuite, "hd_no_index", test_nghttp2_hd_no_index) ||
|
||||||
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
|
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
|
||||||
!CU_add_test(pSuite, "adjust_local_window_size",
|
!CU_add_test(pSuite, "adjust_local_window_size",
|
||||||
test_nghttp2_adjust_local_window_size) ||
|
test_nghttp2_adjust_local_window_size) ||
|
||||||
|
|
|
@ -41,6 +41,8 @@ static nghttp2_nv make_nv(const char *name, const char *value)
|
||||||
nv.value = (uint8_t*)value;
|
nv.value = (uint8_t*)value;
|
||||||
nv.namelen = strlen(name);
|
nv.namelen = strlen(name);
|
||||||
nv.valuelen = strlen(value);
|
nv.valuelen = strlen(value);
|
||||||
|
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
|
|
||||||
return nv;
|
return nv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +225,7 @@ void test_nghttp2_frame_pack_headers_frame_too_large(void)
|
||||||
big_hds[i].value[big_vallen] = '\0';
|
big_hds[i].value[big_vallen] = '\0';
|
||||||
big_hds[i].namelen = strlen((char*)big_hds[i].name);
|
big_hds[i].namelen = strlen((char*)big_hds[i].name);
|
||||||
big_hds[i].valuelen = big_vallen;
|
big_hds[i].valuelen = big_vallen;
|
||||||
|
big_hds[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pri_spec.pri_type = NGHTTP2_PRIORITY_TYPE_NONE;
|
pri_spec.pri_type = NGHTTP2_PRIORITY_TYPE_NONE;
|
||||||
|
|
|
@ -329,9 +329,7 @@ void test_nghttp2_hd_inflate_indname_noinc(void)
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
for(i = 0; i < ARRLEN(nv); ++i) {
|
for(i = 0; i < ARRLEN(nv); ++i) {
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 56,
|
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 56, &nv[i], 0));
|
||||||
nv[i].value, nv[i].valuelen,
|
|
||||||
0));
|
|
||||||
|
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
|
@ -363,8 +361,7 @@ void test_nghttp2_hd_inflate_indname_inc(void)
|
||||||
nva_out_init(&out);
|
nva_out_init(&out);
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 56,
|
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 56, &nv, 1));
|
||||||
nv.value, nv.valuelen, 1));
|
|
||||||
|
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
|
@ -390,6 +387,7 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void)
|
||||||
ssize_t blocklen;
|
ssize_t blocklen;
|
||||||
uint8_t value[1024];
|
uint8_t value[1024];
|
||||||
nva_out out;
|
nva_out out;
|
||||||
|
nghttp2_nv nv;
|
||||||
|
|
||||||
frame_pack_bufs_init(&bufs);
|
frame_pack_bufs_init(&bufs);
|
||||||
|
|
||||||
|
@ -397,14 +395,15 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void)
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
memset(value, '0', sizeof(value));
|
memset(value, '0', sizeof(value));
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 13,
|
nv.value = value;
|
||||||
value, sizeof(value), 1));
|
nv.valuelen = sizeof(value);
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 14,
|
|
||||||
value, sizeof(value), 1));
|
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 15,
|
|
||||||
value, sizeof(value), 1));
|
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 13, &nv, 1));
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 16,
|
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 14, &nv, 1));
|
||||||
value, sizeof(value), 1));
|
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 15, &nv, 1));
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_emit_indname_block(&bufs, 16, &nv, 1));
|
||||||
|
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
|
@ -520,6 +519,8 @@ void test_nghttp2_hd_inflate_clearall_inc(void)
|
||||||
nv.value = value;
|
nv.value = value;
|
||||||
nv.valuelen = sizeof(value);
|
nv.valuelen = sizeof(value);
|
||||||
|
|
||||||
|
nv.flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
|
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
CU_ASSERT(0 == nghttp2_hd_emit_newname_block(&bufs, &nv, 1));
|
CU_ASSERT(0 == nghttp2_hd_emit_newname_block(&bufs, &nv, 1));
|
||||||
|
@ -991,3 +992,54 @@ void test_nghttp2_hd_deflate_inflate(void)
|
||||||
nghttp2_hd_inflate_free(&inflater);
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
nghttp2_hd_deflate_free(&deflater);
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_hd_no_index(void)
|
||||||
|
{
|
||||||
|
nghttp2_hd_deflater deflater;
|
||||||
|
nghttp2_hd_inflater inflater;
|
||||||
|
nghttp2_bufs bufs;
|
||||||
|
ssize_t blocklen;
|
||||||
|
nghttp2_nv nva[] = {
|
||||||
|
MAKE_NV(":method", "GET"),
|
||||||
|
MAKE_NV(":method", "POST"),
|
||||||
|
MAKE_NV(":path", "/foo"),
|
||||||
|
MAKE_NV("version", "HTTP/1.1"),
|
||||||
|
MAKE_NV(":method", "GET"),
|
||||||
|
};
|
||||||
|
size_t i;
|
||||||
|
nva_out out;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
/* 1st :method: GET can be indexable, last one is not */
|
||||||
|
for(i = 1; i < ARRLEN(nva); ++i) {
|
||||||
|
nva[i].flags = NGHTTP2_NV_FLAG_NO_INDEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_pack_bufs_init(&bufs);
|
||||||
|
|
||||||
|
nva_out_init(&out);
|
||||||
|
|
||||||
|
nghttp2_hd_deflate_init(&deflater);
|
||||||
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
|
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, ARRLEN(nva));
|
||||||
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
|
CU_ASSERT(0 == rv);
|
||||||
|
CU_ASSERT(blocklen > 0);
|
||||||
|
CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0));
|
||||||
|
|
||||||
|
CU_ASSERT(ARRLEN(nva) == out.nvlen);
|
||||||
|
assert_nv_equal(nva, out.nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
CU_ASSERT(out.nva[0].flags == NGHTTP2_NV_FLAG_NONE);
|
||||||
|
for(i = 1; i < ARRLEN(nva); ++i) {
|
||||||
|
CU_ASSERT(out.nva[i].flags == NGHTTP2_NV_FLAG_NO_INDEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
nva_out_reset(&out);
|
||||||
|
|
||||||
|
nghttp2_bufs_free(&bufs);
|
||||||
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
|
}
|
||||||
|
|
|
@ -38,5 +38,6 @@ void test_nghttp2_hd_inflate_clearall_inc(void);
|
||||||
void test_nghttp2_hd_inflate_zero_length_huffman(void);
|
void test_nghttp2_hd_inflate_zero_length_huffman(void);
|
||||||
void test_nghttp2_hd_change_table_size(void);
|
void test_nghttp2_hd_change_table_size(void);
|
||||||
void test_nghttp2_hd_deflate_inflate(void);
|
void test_nghttp2_hd_deflate_inflate(void);
|
||||||
|
void test_nghttp2_hd_no_index(void);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_TEST_H */
|
#endif /* NGHTTP2_HD_TEST_H */
|
||||||
|
|
|
@ -2347,6 +2347,7 @@ void test_nghttp2_session_send_headers_header_comp_error(void)
|
||||||
memset(nv[i].value, '0'+i, vallen);
|
memset(nv[i].value, '0'+i, vallen);
|
||||||
nv[i].value[vallen] = '\0';
|
nv[i].value[vallen] = '\0';
|
||||||
nv[i].valuelen = vallen;
|
nv[i].valuelen = vallen;
|
||||||
|
nv[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||||
|
@ -4665,6 +4666,7 @@ void test_nghttp2_session_pack_headers_with_padding(void)
|
||||||
nva[i].namelen = 5;
|
nva[i].namelen = 5;
|
||||||
nva[i].value = (uint8_t*)"/";
|
nva[i].value = (uint8_t*)"/";
|
||||||
nva[i].valuelen = 1;
|
nva[i].valuelen = 1;
|
||||||
|
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
@ -4729,6 +4731,7 @@ void test_nghttp2_session_pack_headers_with_padding2(void)
|
||||||
nva[i].namelen = 5;
|
nva[i].namelen = 5;
|
||||||
nva[i].value = (uint8_t*)"/";
|
nva[i].value = (uint8_t*)"/";
|
||||||
nva[i].valuelen = 1;
|
nva[i].valuelen = 1;
|
||||||
|
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
@ -4777,6 +4780,7 @@ void test_nghttp2_session_pack_headers_with_padding3(void)
|
||||||
nva[i].namelen = 5;
|
nva[i].namelen = 5;
|
||||||
nva[i].value = (uint8_t*)"/";
|
nva[i].value = (uint8_t*)"/";
|
||||||
nva[i].valuelen = 1;
|
nva[i].valuelen = 1;
|
||||||
|
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
|
@ -4817,12 +4821,7 @@ void test_nghttp2_session_pack_headers_with_padding4(void)
|
||||||
accumulator acc;
|
accumulator acc;
|
||||||
my_user_data ud;
|
my_user_data ud;
|
||||||
nghttp2_session_callbacks callbacks;
|
nghttp2_session_callbacks callbacks;
|
||||||
nghttp2_nv nva[1];
|
nghttp2_nv nv = MAKE_NV(":path", "/");
|
||||||
|
|
||||||
nva[0].name = (uint8_t*)":path";
|
|
||||||
nva[0].namelen = 5;
|
|
||||||
nva[0].value = (uint8_t*)"/";
|
|
||||||
nva[0].valuelen = 1;
|
|
||||||
|
|
||||||
memset(&callbacks, 0, sizeof(callbacks));
|
memset(&callbacks, 0, sizeof(callbacks));
|
||||||
callbacks.send_callback = accumulator_send_callback;
|
callbacks.send_callback = accumulator_send_callback;
|
||||||
|
@ -4841,7 +4840,7 @@ void test_nghttp2_session_pack_headers_with_padding4(void)
|
||||||
|
|
||||||
CU_ASSERT(0 ==
|
CU_ASSERT(0 ==
|
||||||
nghttp2_submit_request(session, NULL,
|
nghttp2_submit_request(session, NULL,
|
||||||
nva, ARRLEN(nva), NULL, NULL));
|
&nv, 1, NULL, NULL));
|
||||||
CU_ASSERT(0 == nghttp2_session_send(session));
|
CU_ASSERT(0 == nghttp2_session_send(session));
|
||||||
|
|
||||||
CU_ASSERT(acc.length < NGHTTP2_MAX_PAYLOADLEN);
|
CU_ASSERT(acc.length < NGHTTP2_MAX_PAYLOADLEN);
|
||||||
|
|
|
@ -161,6 +161,9 @@ void add_out(nva_out *out, nghttp2_nv *nv)
|
||||||
}
|
}
|
||||||
onv->namelen = nv->namelen;
|
onv->namelen = nv->namelen;
|
||||||
onv->valuelen = nv->valuelen;
|
onv->valuelen = nv->valuelen;
|
||||||
|
|
||||||
|
onv->flags = nv->flags;
|
||||||
|
|
||||||
++out->nvlen;
|
++out->nvlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue