Remove HPACK reference set
This commit is contained in:
parent
63398f30dd
commit
38bfbffb1b
|
@ -2819,18 +2819,6 @@ int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||||
*/
|
*/
|
||||||
void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Sets the availability of reference set in the |deflater|. If
|
|
||||||
* |no_refset| is nonzero, the deflater will first emit "Reference Set
|
|
||||||
* Emptying" in the each subsequent invocation of
|
|
||||||
* `nghttp2_hd_deflate_hd()` to clear up reference set. By default,
|
|
||||||
* the deflater uses reference set.
|
|
||||||
*/
|
|
||||||
void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
|
|
||||||
uint8_t no_refset);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
|
|
218
lib/nghttp2_hd.c
218
lib/nghttp2_hd.c
|
@ -318,7 +318,6 @@ int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
deflater->no_refset = 0;
|
|
||||||
|
|
||||||
if(deflate_hd_table_bufsize_max < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) {
|
if(deflate_hd_table_bufsize_max < NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE) {
|
||||||
deflater->notify_table_size_change = 1;
|
deflater->notify_table_size_change = 1;
|
||||||
|
@ -346,7 +345,6 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater)
|
||||||
|
|
||||||
inflater->ent_keep = NULL;
|
inflater->ent_keep = NULL;
|
||||||
inflater->nv_keep = NULL;
|
inflater->nv_keep = NULL;
|
||||||
inflater->end_headers_index = 0;
|
|
||||||
|
|
||||||
inflater->opcode = NGHTTP2_HD_OPCODE_NONE;
|
inflater->opcode = NGHTTP2_HD_OPCODE_NONE;
|
||||||
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
||||||
|
@ -400,12 +398,6 @@ void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater)
|
||||||
hd_context_free(&inflater->ctx);
|
hd_context_free(&inflater->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
|
|
||||||
uint8_t no_refset)
|
|
||||||
{
|
|
||||||
deflater->no_refset = no_refset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t entry_room(size_t namelen, size_t valuelen)
|
static size_t entry_room(size_t namelen, size_t valuelen)
|
||||||
{
|
{
|
||||||
return NGHTTP2_HD_ENTRY_OVERHEAD + namelen + valuelen;
|
return NGHTTP2_HD_ENTRY_OVERHEAD + namelen + valuelen;
|
||||||
|
@ -418,10 +410,8 @@ static int emit_indexed_header(nghttp2_nv *nv_out, nghttp2_hd_entry *ent)
|
||||||
DEBUGF(fprintf(stderr, ": "));
|
DEBUGF(fprintf(stderr, ": "));
|
||||||
DEBUGF(fwrite(ent->nv.value, ent->nv.valuelen, 1, stderr));
|
DEBUGF(fwrite(ent->nv.value, ent->nv.valuelen, 1, stderr));
|
||||||
DEBUGF(fprintf(stderr, "\n"));
|
DEBUGF(fprintf(stderr, "\n"));
|
||||||
/* ent->ref may be 0. This happens if the careless stupid encoder
|
/* ent->ref may be 0. This happens if the encoder emits literal
|
||||||
emits literal block larger than header table capacity with
|
block larger than header table capacity with indexing. */
|
||||||
indexing. */
|
|
||||||
ent->flags |= NGHTTP2_HD_FLAG_EMIT;
|
|
||||||
*nv_out = ent->nv;
|
*nv_out = ent->nv;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -561,20 +551,6 @@ static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *final,
|
||||||
return in + 1 - start;
|
return in + 1 - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int emit_clear_refset(nghttp2_bufs *bufs)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "deflatehd: emit clear refset\n"));
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_addb(bufs, 0x30u);
|
|
||||||
if(rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
|
static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -584,7 +560,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 = count_encoded_length(table_size, 4);
|
blocklen = count_encoded_length(table_size, 5);
|
||||||
|
|
||||||
if(sizeof(sb) < blocklen) {
|
if(sizeof(sb) < blocklen) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
@ -594,7 +570,7 @@ static int emit_table_size(nghttp2_bufs *bufs, size_t table_size)
|
||||||
|
|
||||||
*bufp = 0x20u;
|
*bufp = 0x20u;
|
||||||
|
|
||||||
encode_length(bufp, table_size, 4);
|
encode_length(bufp, table_size, 5);
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, sb, blocklen);
|
rv = nghttp2_bufs_add(bufs, sb, blocklen);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
|
@ -789,23 +765,6 @@ static int emit_newname_block(nghttp2_bufs *bufs, const nghttp2_nv *nv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Emit common header with |index| by toggle off and on (thus 2
|
|
||||||
* indexed representation emissions).
|
|
||||||
*/
|
|
||||||
static int emit_implicit(nghttp2_bufs *bufs, size_t idx)
|
|
||||||
{
|
|
||||||
int i, rv;
|
|
||||||
|
|
||||||
for(i = 0; i < 2; ++i) {
|
|
||||||
rv = emit_indexed_block(bufs, idx);
|
|
||||||
if(rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
|
static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
|
||||||
nghttp2_bufs *bufs,
|
nghttp2_bufs *bufs,
|
||||||
const nghttp2_nv *nv,
|
const nghttp2_nv *nv,
|
||||||
|
@ -824,17 +783,7 @@ static nghttp2_hd_entry* add_hd_table_incremental(nghttp2_hd_context *context,
|
||||||
nghttp2_hd_entry* ent = hd_ringbuf_get(&context->hd_table, idx);
|
nghttp2_hd_entry* ent = hd_ringbuf_get(&context->hd_table, idx);
|
||||||
|
|
||||||
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(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
|
|
||||||
representation which hurts compression. */
|
|
||||||
rv = emit_implicit(bufs, idx);
|
|
||||||
if(rv != 0) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUGF(fprintf(stderr, "hpack: remove item from header table: "));
|
DEBUGF(fprintf(stderr, "hpack: remove item from header table: "));
|
||||||
DEBUGF(fwrite(ent->nv.name, ent->nv.namelen, 1, stderr));
|
DEBUGF(fwrite(ent->nv.name, ent->nv.namelen, 1, stderr));
|
||||||
DEBUGF(fprintf(stderr, ": "));
|
DEBUGF(fprintf(stderr, ": "));
|
||||||
|
@ -882,8 +831,6 @@ 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;
|
|
||||||
}
|
}
|
||||||
return new_ent;
|
return new_ent;
|
||||||
}
|
}
|
||||||
|
@ -987,15 +934,6 @@ int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_refset(nghttp2_hd_context *context)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
for(i = 0; i < context->hd_table.len; ++i) {
|
|
||||||
nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, i);
|
|
||||||
ent->flags &= ~NGHTTP2_HD_FLAG_REFSET;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INDEX_RANGE_VALID(context, idx) \
|
#define INDEX_RANGE_VALID(context, idx) \
|
||||||
((idx) < (context)->hd_table.len + STATIC_TABLE_LENGTH)
|
((idx) < (context)->hd_table.len + STATIC_TABLE_LENGTH)
|
||||||
|
|
||||||
|
@ -1063,9 +1001,6 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
|
||||||
if(idx >= deflater->ctx.hd_table.len) {
|
if(idx >= deflater->ctx.hd_table.len) {
|
||||||
nghttp2_hd_entry *new_ent;
|
nghttp2_hd_entry *new_ent;
|
||||||
|
|
||||||
/* It is important to first add entry to the header table and
|
|
||||||
let eviction go. If NGHTTP2_HD_FLAG_IMPLICIT_EMIT entry is
|
|
||||||
evicted, it must be emitted before the |nv|. */
|
|
||||||
new_ent = add_hd_table_incremental(&deflater->ctx, bufs, &ent->nv,
|
new_ent = add_hd_table_incremental(&deflater->ctx, bufs, &ent->nv,
|
||||||
NGHTTP2_HD_FLAG_NONE);
|
NGHTTP2_HD_FLAG_NONE);
|
||||||
if(!new_ent) {
|
if(!new_ent) {
|
||||||
|
@ -1075,51 +1010,15 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
|
||||||
nghttp2_hd_entry_free(new_ent);
|
nghttp2_hd_entry_free(new_ent);
|
||||||
free(new_ent);
|
free(new_ent);
|
||||||
new_ent = NULL;
|
new_ent = NULL;
|
||||||
} else {
|
|
||||||
/* new_ent->ref > 0 means that new_ent is in the reference
|
|
||||||
set */
|
|
||||||
new_ent->flags |= NGHTTP2_HD_FLAG_EMIT;
|
|
||||||
}
|
}
|
||||||
rv = emit_indexed_block(bufs, idx);
|
rv = emit_indexed_block(bufs, idx);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
} else if((ent->flags & NGHTTP2_HD_FLAG_REFSET) == 0) {
|
|
||||||
ent->flags |= NGHTTP2_HD_FLAG_REFSET | NGHTTP2_HD_FLAG_EMIT;
|
|
||||||
rv = emit_indexed_block(bufs, idx);
|
|
||||||
if(rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
int num_emits = 0;
|
rv = emit_indexed_block(bufs, idx);
|
||||||
if(ent->flags & NGHTTP2_HD_FLAG_EMIT) {
|
if(rv != 0) {
|
||||||
/* occurrences of the same indexed representation. Emit index
|
return rv;
|
||||||
twice. */
|
|
||||||
num_emits = 2;
|
|
||||||
} else if(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) {
|
|
||||||
/* ent was implicitly emitted because it is the common
|
|
||||||
header field. To support occurrences of the same indexed
|
|
||||||
representation, we have to emit 4 times. This is because
|
|
||||||
"implicitly emitted" means actually not emitted at
|
|
||||||
all. So first 2 emits performs 1st header appears in the
|
|
||||||
reference set. And another 2 emits are done for 2nd
|
|
||||||
(current) header. */
|
|
||||||
ent->flags ^= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
|
|
||||||
ent->flags |= NGHTTP2_HD_FLAG_EMIT;
|
|
||||||
num_emits = 4;
|
|
||||||
} else {
|
|
||||||
/* This is common header and not emitted in the current
|
|
||||||
run. Just mark IMPLICIT_EMIT, in the hope that we are not
|
|
||||||
required to emit anything for this. We will emit toggle
|
|
||||||
off/on for this entry if it is removed from the header
|
|
||||||
table. */
|
|
||||||
ent->flags |= NGHTTP2_HD_FLAG_IMPLICIT_EMIT;
|
|
||||||
}
|
|
||||||
for(; num_emits > 0; --num_emits) {
|
|
||||||
rv = emit_indexed_block(bufs, idx);
|
|
||||||
if(rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1150,10 +1049,6 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
|
||||||
if(new_ent->ref == 0) {
|
if(new_ent->ref == 0) {
|
||||||
nghttp2_hd_entry_free(new_ent);
|
nghttp2_hd_entry_free(new_ent);
|
||||||
free(new_ent);
|
free(new_ent);
|
||||||
} else {
|
|
||||||
/* new_ent->ref > 0 means that new_ent is in the reference
|
|
||||||
set. */
|
|
||||||
new_ent->flags |= NGHTTP2_HD_FLAG_EMIT;
|
|
||||||
}
|
}
|
||||||
incidx = 1;
|
incidx = 1;
|
||||||
}
|
}
|
||||||
|
@ -1169,30 +1064,6 @@ static int deflate_nv(nghttp2_hd_deflater *deflater,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int deflate_post_process_hd_entry(nghttp2_hd_entry *ent,
|
|
||||||
size_t idx,
|
|
||||||
nghttp2_bufs *bufs)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if((ent->flags & NGHTTP2_HD_FLAG_REFSET) &&
|
|
||||||
(ent->flags & NGHTTP2_HD_FLAG_IMPLICIT_EMIT) == 0 &&
|
|
||||||
(ent->flags & NGHTTP2_HD_FLAG_EMIT) == 0) {
|
|
||||||
/* This entry is not present in the current header set and must
|
|
||||||
be removed. */
|
|
||||||
ent->flags ^= NGHTTP2_HD_FLAG_REFSET;
|
|
||||||
|
|
||||||
rv = emit_indexed_block(bufs, idx);
|
|
||||||
if(rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ent->flags &= ~(NGHTTP2_HD_FLAG_EMIT | NGHTTP2_HD_FLAG_IMPLICIT_EMIT);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||||
nghttp2_bufs *bufs,
|
nghttp2_bufs *bufs,
|
||||||
const nghttp2_nv *nv, size_t nvlen)
|
const nghttp2_nv *nv, size_t nvlen)
|
||||||
|
@ -1215,13 +1086,6 @@ int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(deflater->no_refset) {
|
|
||||||
rv = emit_clear_refset(bufs);
|
|
||||||
if(rv != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
clear_refset(&deflater->ctx);
|
|
||||||
}
|
|
||||||
for(i = 0; i < nvlen; ++i) {
|
for(i = 0; i < nvlen; ++i) {
|
||||||
rv = deflate_nv(deflater, bufs, &nv[i]);
|
rv = deflate_nv(deflater, bufs, &nv[i]);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
|
@ -1232,15 +1096,6 @@ int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||||
DEBUGF(fprintf(stderr,
|
DEBUGF(fprintf(stderr,
|
||||||
"deflatehd: all input name/value pairs were deflated\n"));
|
"deflatehd: all input name/value pairs were deflated\n"));
|
||||||
|
|
||||||
for(i = 0; i < deflater->ctx.hd_table.len; ++i) {
|
|
||||||
nghttp2_hd_entry *ent = hd_ringbuf_get(&deflater->ctx.hd_table, i);
|
|
||||||
|
|
||||||
rv = deflate_post_process_hd_entry(ent, i, bufs);
|
|
||||||
if(rv != 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
DEBUGF(fprintf(stderr, "deflatehd: error return %d\n", rv));
|
DEBUGF(fprintf(stderr, "deflatehd: error return %d\n", rv));
|
||||||
|
@ -1282,12 +1137,9 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
||||||
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
|
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
|
||||||
const nghttp2_nv *nva, size_t nvlen)
|
const nghttp2_nv *nva, size_t nvlen)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* Possible Reference Set Emptying */
|
|
||||||
n = 1;
|
|
||||||
|
|
||||||
/* Possible Maximum Header Table Size Change. Encoding (1u << 31) -
|
/* Possible Maximum Header Table Size Change. Encoding (1u << 31) -
|
||||||
1 using 4 bit prefix requires 6 bytes. */
|
1 using 4 bit prefix requires 6 bytes. */
|
||||||
n += 6;
|
n += 6;
|
||||||
|
@ -1305,9 +1157,6 @@ size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
|
||||||
n += nva[i].namelen + nva[i].valuelen;
|
n += nva[i].namelen + nva[i].valuelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add possible reference set toggle off */
|
|
||||||
n += deflater->ctx.hd_table.len;
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1483,17 +1332,10 @@ static int hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
|
||||||
inflater->ent_keep = new_ent;
|
inflater->ent_keep = new_ent;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ent->flags ^= NGHTTP2_HD_FLAG_REFSET;
|
|
||||||
if(ent->flags & NGHTTP2_HD_FLAG_REFSET) {
|
emit_indexed_header(nv_out, ent);
|
||||||
emit_indexed_header(nv_out, ent);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: toggle off item: "));
|
|
||||||
DEBUGF(fwrite(ent->nv.name, ent->nv.namelen, 1, stderr));
|
|
||||||
DEBUGF(fprintf(stderr, ": "));
|
|
||||||
DEBUGF(fwrite(ent->nv.value, ent->nv.valuelen, 1, stderr));
|
|
||||||
DEBUGF(fprintf(stderr, "\n"));
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hd_inflate_remove_bufs(nghttp2_hd_inflater *inflater,
|
static int hd_inflate_remove_bufs(nghttp2_hd_inflater *inflater,
|
||||||
|
@ -1678,20 +1520,10 @@ 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 & 0xf0u) == 0x20u) {
|
if((*in & 0xe0u) == 0x20u) {
|
||||||
DEBUGF(fprintf(stderr, "inflatehd: header table size change\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_READ_TABLE_SIZE;
|
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;
|
|
||||||
} 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;
|
||||||
|
@ -1720,15 +1552,10 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
}
|
}
|
||||||
inflater->left = 0;
|
inflater->left = 0;
|
||||||
inflater->shift = 0;
|
inflater->shift = 0;
|
||||||
break;
|
|
||||||
case NGHTTP2_HD_STATE_CLEAR_REFSET:
|
|
||||||
clear_refset(&inflater->ctx);
|
|
||||||
inflater->state = NGHTTP2_HD_STATE_OPCODE;
|
|
||||||
|
|
||||||
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, 4,
|
rv = hd_inflate_read_len(inflater, &rfin, in, last, 5,
|
||||||
inflater->settings_hd_table_bufsize_max);
|
inflater->settings_hd_table_bufsize_max);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -1995,20 +1822,6 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
for(; inflater->end_headers_index < inflater->ctx.hd_table.len;
|
|
||||||
++inflater->end_headers_index) {
|
|
||||||
nghttp2_hd_entry *ent;
|
|
||||||
ent = hd_ringbuf_get(&inflater->ctx.hd_table,
|
|
||||||
inflater->end_headers_index);
|
|
||||||
|
|
||||||
if((ent->flags & NGHTTP2_HD_FLAG_REFSET) &&
|
|
||||||
(ent->flags & NGHTTP2_HD_FLAG_EMIT) == 0) {
|
|
||||||
emit_indexed_header(nv_out, ent);
|
|
||||||
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
|
|
||||||
return (ssize_t)(in - first);
|
|
||||||
}
|
|
||||||
ent->flags &= ~NGHTTP2_HD_FLAG_EMIT;
|
|
||||||
}
|
|
||||||
*inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
|
*inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
|
||||||
}
|
}
|
||||||
return (ssize_t)(in - first);
|
return (ssize_t)(in - first);
|
||||||
|
@ -2033,7 +1846,6 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater)
|
int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater)
|
||||||
{
|
{
|
||||||
hd_inflate_keep_free(inflater);
|
hd_inflate_keep_free(inflater);
|
||||||
inflater->end_headers_index = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,18 +58,12 @@ typedef enum {
|
||||||
NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
|
NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
|
||||||
/* Indicates value was dynamically allocated and must be freed */
|
/* Indicates value was dynamically allocated and must be freed */
|
||||||
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
|
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
|
||||||
/* Indicates that the entry is in the reference set */
|
|
||||||
NGHTTP2_HD_FLAG_REFSET = 1 << 2,
|
|
||||||
/* Indicates that the entry is emitted in the current header
|
|
||||||
processing. */
|
|
||||||
NGHTTP2_HD_FLAG_EMIT = 1 << 3,
|
|
||||||
NGHTTP2_HD_FLAG_IMPLICIT_EMIT = 1 << 4,
|
|
||||||
/* Indicates that the name was gifted to the entry and no copying
|
/* Indicates that the name was gifted to the entry and no copying
|
||||||
necessary. */
|
necessary. */
|
||||||
NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 5,
|
NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 2,
|
||||||
/* Indicates that the value was gifted to the entry and no copying
|
/* Indicates that the value was gifted to the entry and no copying
|
||||||
necessary. */
|
necessary. */
|
||||||
NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 6
|
NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 3
|
||||||
} nghttp2_hd_flags;
|
} nghttp2_hd_flags;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -97,7 +91,6 @@ typedef enum {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NGHTTP2_HD_STATE_OPCODE,
|
NGHTTP2_HD_STATE_OPCODE,
|
||||||
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,
|
||||||
|
@ -131,9 +124,6 @@ struct nghttp2_hd_deflater {
|
||||||
nghttp2_hd_context ctx;
|
nghttp2_hd_context ctx;
|
||||||
/* The upper limit of the header table size the deflater accepts. */
|
/* The upper limit of the header table size the deflater accepts. */
|
||||||
size_t deflate_hd_table_bufsize_max;
|
size_t deflate_hd_table_bufsize_max;
|
||||||
/* Set to this nonzero to clear reference set on each deflation each
|
|
||||||
time. */
|
|
||||||
uint8_t no_refset;
|
|
||||||
/* If nonzero, send header table size using encoding context update
|
/* If nonzero, send header table size using encoding context update
|
||||||
in the next deflate process */
|
in the next deflate process */
|
||||||
uint8_t notify_table_size_change;
|
uint8_t notify_table_size_change;
|
||||||
|
@ -159,9 +149,6 @@ struct nghttp2_hd_inflater {
|
||||||
size_t left;
|
size_t left;
|
||||||
/* The index in indexed repr or indexed name */
|
/* The index in indexed repr or indexed name */
|
||||||
size_t index;
|
size_t index;
|
||||||
/* The index of header table to toggle off the entry from reference
|
|
||||||
set at the end of decompression. */
|
|
||||||
size_t end_headers_index;
|
|
||||||
/* The length of new name encoded in literal. For huffman encoded
|
/* The length of new name encoded in literal. For huffman encoded
|
||||||
string, this is the length after it is decoded. */
|
string, this is the length after it is decoded. */
|
||||||
size_t newnamelen;
|
size_t newnamelen;
|
||||||
|
|
|
@ -252,9 +252,6 @@ cdef extern from 'nghttp2/nghttp2.h':
|
||||||
|
|
||||||
void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater)
|
void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater)
|
||||||
|
|
||||||
void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
|
|
||||||
uint8_t no_refset)
|
|
||||||
|
|
||||||
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||||
size_t hd_table_bufsize_max)
|
size_t hd_table_bufsize_max)
|
||||||
|
|
||||||
|
@ -291,9 +288,6 @@ cdef extern from 'nghttp2_hd.h':
|
||||||
# This is macro
|
# This is macro
|
||||||
int NGHTTP2_HD_ENTRY_OVERHEAD
|
int NGHTTP2_HD_ENTRY_OVERHEAD
|
||||||
|
|
||||||
ctypedef enum nghttp2_hd_flags:
|
|
||||||
NGHTTP2_HD_FLAG_REFSET
|
|
||||||
|
|
||||||
ctypedef enum nghttp2_hd_inflate_flag:
|
ctypedef enum nghttp2_hd_inflate_flag:
|
||||||
NGHTTP2_HD_INFLATE_EMIT
|
NGHTTP2_HD_INFLATE_EMIT
|
||||||
NGHTTP2_HD_INFLATE_FINAL
|
NGHTTP2_HD_INFLATE_FINAL
|
||||||
|
|
|
@ -33,12 +33,11 @@ HD_ENTRY_OVERHEAD = cnghttp2.NGHTTP2_HD_ENTRY_OVERHEAD
|
||||||
|
|
||||||
class HDTableEntry:
|
class HDTableEntry:
|
||||||
|
|
||||||
def __init__(self, name, namelen, value, valuelen, ref):
|
def __init__(self, name, namelen, value, valuelen):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.namelen = namelen
|
self.namelen = namelen
|
||||||
self.value = value
|
self.value = value
|
||||||
self.valuelen = valuelen
|
self.valuelen = valuelen
|
||||||
self.ref = ref
|
|
||||||
|
|
||||||
def space(self):
|
def space(self):
|
||||||
return self.namelen + self.valuelen + HD_ENTRY_OVERHEAD
|
return self.namelen + self.valuelen + HD_ENTRY_OVERHEAD
|
||||||
|
@ -52,8 +51,7 @@ cdef _get_hd_table(cnghttp2.nghttp2_hd_context *ctx):
|
||||||
k = _get_pybytes(entry.nv.name, entry.nv.namelen)
|
k = _get_pybytes(entry.nv.name, entry.nv.namelen)
|
||||||
v = _get_pybytes(entry.nv.value, entry.nv.valuelen)
|
v = _get_pybytes(entry.nv.value, entry.nv.valuelen)
|
||||||
res.append(HDTableEntry(k, entry.nv.namelen,
|
res.append(HDTableEntry(k, entry.nv.namelen,
|
||||||
v, entry.nv.valuelen,
|
v, entry.nv.valuelen))
|
||||||
(entry.flags & cnghttp2.NGHTTP2_HD_FLAG_REFSET) != 0))
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
cdef _get_pybytes(uint8_t *b, uint16_t blen):
|
cdef _get_pybytes(uint8_t *b, uint16_t blen):
|
||||||
|
@ -143,15 +141,6 @@ cdef class HDDeflater:
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def set_no_refset(self, no_refset):
|
|
||||||
'''Tells the compressor not to use reference set if |no_refset| is
|
|
||||||
nonzero. If |no_refset| is nonzero, on each invocation of
|
|
||||||
deflate(), compressor first emits index=0 to clear up
|
|
||||||
reference set.
|
|
||||||
|
|
||||||
'''
|
|
||||||
cnghttp2.nghttp2_hd_deflate_set_no_refset(self._deflater, no_refset)
|
|
||||||
|
|
||||||
def change_table_size(self, hd_table_bufsize_max):
|
def change_table_size(self, hd_table_bufsize_max):
|
||||||
'''Changes header table size to |hd_table_bufsize_max| byte.
|
'''Changes header table size to |hd_table_bufsize_max| byte.
|
||||||
|
|
||||||
|
@ -243,16 +232,14 @@ def print_hd_table(hdtable):
|
||||||
function does not work if header name/value cannot be decoded using
|
function does not work if header name/value cannot be decoded using
|
||||||
UTF-8 encoding.
|
UTF-8 encoding.
|
||||||
|
|
||||||
s=N means the entry occupies N bytes in header table. if r=y, then
|
s=N means the entry occupies N bytes in header table.
|
||||||
the entry is in the reference set.
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
idx = 0
|
idx = 0
|
||||||
for entry in hdtable:
|
for entry in hdtable:
|
||||||
idx += 1
|
idx += 1
|
||||||
print('[{}] (s={}) (r={}) {}: {}'\
|
print('[{}] (s={}) {}: {}'\
|
||||||
.format(idx, entry.space(),
|
.format(idx, entry.space(),
|
||||||
'y' if entry.ref else 'n',
|
|
||||||
entry.name.decode('utf-8'),
|
entry.name.decode('utf-8'),
|
||||||
entry.value.decode('utf-8')))
|
entry.value.decode('utf-8')))
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,6 @@ json_t* dump_header_table(nghttp2_hd_context *context)
|
||||||
json_object_set_new(outent, "index", json_integer(i + 1));
|
json_object_set_new(outent, "index", json_integer(i + 1));
|
||||||
dump_val(outent, "name", ent->nv.name, ent->nv.namelen);
|
dump_val(outent, "name", ent->nv.name, ent->nv.namelen);
|
||||||
dump_val(outent, "value", ent->nv.value, ent->nv.valuelen);
|
dump_val(outent, "value", ent->nv.value, ent->nv.valuelen);
|
||||||
json_object_set_new(outent, "referenced",
|
|
||||||
json_boolean(ent->flags & NGHTTP2_HD_FLAG_REFSET));
|
|
||||||
json_object_set_new(outent, "size",
|
json_object_set_new(outent, "size",
|
||||||
json_integer(ent->nv.namelen + ent->nv.valuelen +
|
json_integer(ent->nv.namelen + ent->nv.valuelen +
|
||||||
NGHTTP2_HD_ENTRY_OVERHEAD));
|
NGHTTP2_HD_ENTRY_OVERHEAD));
|
||||||
|
|
|
@ -53,7 +53,6 @@ typedef struct {
|
||||||
size_t deflate_table_size;
|
size_t deflate_table_size;
|
||||||
int http1text;
|
int http1text;
|
||||||
int dump_header_table;
|
int dump_header_table;
|
||||||
int no_refset;
|
|
||||||
} deflate_config;
|
} deflate_config;
|
||||||
|
|
||||||
static deflate_config config;
|
static deflate_config config;
|
||||||
|
@ -198,7 +197,6 @@ static int deflate_hd_json(json_t *obj, nghttp2_hd_deflater *deflater, int seq)
|
||||||
static void init_deflater(nghttp2_hd_deflater *deflater)
|
static void init_deflater(nghttp2_hd_deflater *deflater)
|
||||||
{
|
{
|
||||||
nghttp2_hd_deflate_init2(deflater, config.deflate_table_size);
|
nghttp2_hd_deflate_init2(deflater, config.deflate_table_size);
|
||||||
nghttp2_hd_deflate_set_no_refset(deflater, config.no_refset);
|
|
||||||
nghttp2_hd_deflate_change_table_size(deflater, config.table_size);
|
nghttp2_hd_deflate_change_table_size(deflater, config.table_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,8 +385,7 @@ OPTIONS:
|
||||||
buffer.
|
buffer.
|
||||||
Default: 4096
|
Default: 4096
|
||||||
-d, --dump-header-table
|
-d, --dump-header-table
|
||||||
Output dynamic header table.
|
Output dynamic header table.)"
|
||||||
-c, --no-refset Don't use reference set.)"
|
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +394,6 @@ static struct option long_options[] = {
|
||||||
{"table-size", required_argument, nullptr, 's'},
|
{"table-size", required_argument, nullptr, 's'},
|
||||||
{"deflate-table-size", required_argument, nullptr, 'S'},
|
{"deflate-table-size", required_argument, nullptr, 'S'},
|
||||||
{"dump-header-table", no_argument, nullptr, 'd'},
|
{"dump-header-table", no_argument, nullptr, 'd'},
|
||||||
{"no-refset", no_argument, nullptr, 'c'},
|
|
||||||
{nullptr, 0, nullptr, 0 }
|
{nullptr, 0, nullptr, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -409,10 +405,9 @@ int main(int argc, char **argv)
|
||||||
config.deflate_table_size = NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
|
config.deflate_table_size = NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
|
||||||
config.http1text = 0;
|
config.http1text = 0;
|
||||||
config.dump_header_table = 0;
|
config.dump_header_table = 0;
|
||||||
config.no_refset = 0;
|
|
||||||
while(1) {
|
while(1) {
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
int c = getopt_long(argc, argv, "S:cdhs:t", long_options, &option_index);
|
int c = getopt_long(argc, argv, "S:dhs:t", long_options, &option_index);
|
||||||
if(c == -1) {
|
if(c == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -446,10 +441,6 @@ int main(int argc, char **argv)
|
||||||
// --dump-header-table
|
// --dump-header-table
|
||||||
config.dump_header_table = 1;
|
config.dump_header_table = 1;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
|
||||||
// --no-refset
|
|
||||||
config.no_refset = 1;
|
|
||||||
break;
|
|
||||||
case '?':
|
case '?':
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -255,10 +255,6 @@ int main(int argc, char* argv[])
|
||||||
!CU_add_test(pSuite, "hd_deflate", test_nghttp2_hd_deflate) ||
|
!CU_add_test(pSuite, "hd_deflate", test_nghttp2_hd_deflate) ||
|
||||||
!CU_add_test(pSuite, "hd_deflate_same_indexed_repr",
|
!CU_add_test(pSuite, "hd_deflate_same_indexed_repr",
|
||||||
test_nghttp2_hd_deflate_same_indexed_repr) ||
|
test_nghttp2_hd_deflate_same_indexed_repr) ||
|
||||||
!CU_add_test(pSuite, "hd_deflate_common_header_eviction",
|
|
||||||
test_nghttp2_hd_deflate_common_header_eviction) ||
|
|
||||||
!CU_add_test(pSuite, "hd_deflate_clear_refset",
|
|
||||||
test_nghttp2_hd_deflate_clear_refset) ||
|
|
||||||
!CU_add_test(pSuite, "hd_inflate_indexed",
|
!CU_add_test(pSuite, "hd_inflate_indexed",
|
||||||
test_nghttp2_hd_inflate_indexed) ||
|
test_nghttp2_hd_inflate_indexed) ||
|
||||||
!CU_add_test(pSuite, "hd_inflate_indname_noinc",
|
!CU_add_test(pSuite, "hd_inflate_indname_noinc",
|
||||||
|
|
|
@ -159,8 +159,7 @@ void test_nghttp2_hd_deflate_same_indexed_repr(void)
|
||||||
CU_ASSERT(0 == nghttp2_hd_deflate_init(&deflater));
|
CU_ASSERT(0 == nghttp2_hd_deflate_init(&deflater));
|
||||||
CU_ASSERT(0 == nghttp2_hd_inflate_init(&inflater));
|
CU_ASSERT(0 == nghttp2_hd_inflate_init(&inflater));
|
||||||
|
|
||||||
/* Encode 2 same headers. cookie:alpha is not in the reference set,
|
/* Encode 2 same headers. Emit 1 literal reprs and 1 index repr. */
|
||||||
so first emit literal repr and then 2 emits of indexed repr. */
|
|
||||||
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva1, ARRLEN(nva1));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva1, ARRLEN(nva1));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
|
@ -174,13 +173,12 @@ void test_nghttp2_hd_deflate_same_indexed_repr(void)
|
||||||
nva_out_reset(&out);
|
nva_out_reset(&out);
|
||||||
nghttp2_bufs_reset(&bufs);
|
nghttp2_bufs_reset(&bufs);
|
||||||
|
|
||||||
/* Encode 3 same headers. This time, cookie:alpha is in the
|
/* Encode 3 same headers. This time, emits 3 index reprs. */
|
||||||
reference set, so the encoder emits indexed repr 6 times */
|
|
||||||
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva2, ARRLEN(nva2));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva2, ARRLEN(nva2));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
CU_ASSERT(blocklen == 6);
|
CU_ASSERT(blocklen == 3);
|
||||||
CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0));
|
CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0));
|
||||||
|
|
||||||
CU_ASSERT(3 == out.nvlen);
|
CU_ASSERT(3 == out.nvlen);
|
||||||
|
@ -195,120 +193,6 @@ void test_nghttp2_hd_deflate_same_indexed_repr(void)
|
||||||
nghttp2_hd_deflate_free(&deflater);
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_nghttp2_hd_deflate_common_header_eviction(void)
|
|
||||||
{
|
|
||||||
nghttp2_hd_deflater deflater;
|
|
||||||
nghttp2_hd_inflater inflater;
|
|
||||||
nghttp2_nv nva[] = {MAKE_NV("h1", ""),
|
|
||||||
MAKE_NV("h2", "")};
|
|
||||||
nghttp2_bufs bufs;
|
|
||||||
ssize_t blocklen;
|
|
||||||
/* Default header table capacity is 4096. Adding 2 byte header name
|
|
||||||
and 4060 byte value, which is 4094 bytes including overhead, to
|
|
||||||
the table evicts first entry. */
|
|
||||||
uint8_t value[3038];
|
|
||||||
nva_out out;
|
|
||||||
size_t i;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
frame_pack_bufs_init(&bufs);
|
|
||||||
|
|
||||||
nva_out_init(&out);
|
|
||||||
memset(value, '0', sizeof(value));
|
|
||||||
for(i = 0; i < 2; ++i) {
|
|
||||||
nva[i].value = value;
|
|
||||||
nva[i].valuelen = sizeof(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_hd_deflate_init(&deflater);
|
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
|
||||||
|
|
||||||
/* First emit "h1: ..." to put it in the reference set (index
|
|
||||||
= 0). */
|
|
||||||
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 1);
|
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
|
||||||
CU_ASSERT(blocklen > 0);
|
|
||||||
CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0));
|
|
||||||
|
|
||||||
CU_ASSERT(1 == out.nvlen);
|
|
||||||
nghttp2_nv_array_sort(nva, 1);
|
|
||||||
assert_nv_equal(nva, out.nva, 1);
|
|
||||||
|
|
||||||
nva_out_reset(&out);
|
|
||||||
nghttp2_bufs_reset(&bufs);
|
|
||||||
|
|
||||||
/* Encode with second header */
|
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
|
||||||
CU_ASSERT(blocklen > 0);
|
|
||||||
|
|
||||||
/* Check common header "h1: ...:, which is removed from the
|
|
||||||
header table because of eviction, is still emitted by the
|
|
||||||
inflater */
|
|
||||||
CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0));
|
|
||||||
|
|
||||||
CU_ASSERT(2 == out.nvlen);
|
|
||||||
nghttp2_nv_array_sort(nva, 2);
|
|
||||||
assert_nv_equal(nva, out.nva, 2);
|
|
||||||
|
|
||||||
nva_out_reset(&out);
|
|
||||||
nghttp2_bufs_reset(&bufs);
|
|
||||||
|
|
||||||
CU_ASSERT(1 == deflater.ctx.hd_table.len);
|
|
||||||
CU_ASSERT(1 == inflater.ctx.hd_table.len);
|
|
||||||
|
|
||||||
nghttp2_bufs_free(&bufs);
|
|
||||||
nghttp2_hd_inflate_free(&inflater);
|
|
||||||
nghttp2_hd_deflate_free(&deflater);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_nghttp2_hd_deflate_clear_refset(void)
|
|
||||||
{
|
|
||||||
nghttp2_hd_deflater deflater;
|
|
||||||
nghttp2_hd_inflater inflater;
|
|
||||||
nghttp2_bufs bufs;
|
|
||||||
ssize_t blocklen;
|
|
||||||
nghttp2_nv nv[] = {
|
|
||||||
MAKE_NV(":path", "/"),
|
|
||||||
MAKE_NV(":scheme", "http")
|
|
||||||
};
|
|
||||||
size_t i;
|
|
||||||
nva_out out;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
frame_pack_bufs_init(&bufs);
|
|
||||||
|
|
||||||
nva_out_init(&out);
|
|
||||||
nghttp2_hd_deflate_init2(&deflater,
|
|
||||||
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE);
|
|
||||||
nghttp2_hd_deflate_set_no_refset(&deflater, 1);
|
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
|
||||||
|
|
||||||
for(i = 0; i < 2; ++i) {
|
|
||||||
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nv, ARRLEN(nv));
|
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
|
||||||
CU_ASSERT(blocklen > 1);
|
|
||||||
CU_ASSERT(blocklen == inflate_hd(&inflater, &out, &bufs, 0));
|
|
||||||
|
|
||||||
CU_ASSERT(ARRLEN(nv) == out.nvlen);
|
|
||||||
assert_nv_equal(nv, out.nva, ARRLEN(nv));
|
|
||||||
|
|
||||||
nva_out_reset(&out);
|
|
||||||
nghttp2_bufs_reset(&bufs);
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_bufs_free(&bufs);
|
|
||||||
nghttp2_hd_inflate_free(&inflater);
|
|
||||||
nghttp2_hd_deflate_free(&deflater);
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_nghttp2_hd_inflate_indexed(void)
|
void test_nghttp2_hd_inflate_indexed(void)
|
||||||
{
|
{
|
||||||
nghttp2_hd_inflater inflater;
|
nghttp2_hd_inflater inflater;
|
||||||
|
@ -459,7 +343,6 @@ void test_nghttp2_hd_inflate_indname_inc_eviction(void)
|
||||||
nghttp2_bufs_reset(&bufs);
|
nghttp2_bufs_reset(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(3 == inflater.ctx.hd_table.len);
|
CU_ASSERT(3 == inflater.ctx.hd_table.len);
|
||||||
CU_ASSERT(GET_TABLE_ENT(&inflater.ctx, 0)->flags & NGHTTP2_HD_FLAG_REFSET);
|
|
||||||
|
|
||||||
nghttp2_bufs_free(&bufs);
|
nghttp2_bufs_free(&bufs);
|
||||||
nghttp2_hd_inflate_free(&inflater);
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
|
@ -1163,7 +1046,7 @@ void test_nghttp2_hd_deflate_bound(void)
|
||||||
|
|
||||||
bound = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva));
|
bound = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva));
|
||||||
|
|
||||||
CU_ASSERT(1 + 6 + 6 * 2 * 2 +
|
CU_ASSERT(6 + 6 * 2 * 2 +
|
||||||
nva[0].namelen + nva[0].valuelen +
|
nva[0].namelen + nva[0].valuelen +
|
||||||
nva[1].namelen + nva[1].valuelen
|
nva[1].namelen + nva[1].valuelen
|
||||||
== bound);
|
== bound);
|
||||||
|
@ -1174,7 +1057,7 @@ void test_nghttp2_hd_deflate_bound(void)
|
||||||
|
|
||||||
bound2 = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva));
|
bound2 = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva));
|
||||||
|
|
||||||
CU_ASSERT(bound + 2 == bound2);
|
CU_ASSERT(bound == bound2);
|
||||||
|
|
||||||
nghttp2_bufs_free(&bufs);
|
nghttp2_bufs_free(&bufs);
|
||||||
nghttp2_hd_deflate_free(&deflater);
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
|
|
||||||
void test_nghttp2_hd_deflate(void);
|
void test_nghttp2_hd_deflate(void);
|
||||||
void test_nghttp2_hd_deflate_same_indexed_repr(void);
|
void test_nghttp2_hd_deflate_same_indexed_repr(void);
|
||||||
void test_nghttp2_hd_deflate_common_header_eviction(void);
|
|
||||||
void test_nghttp2_hd_deflate_clear_refset(void);
|
|
||||||
void test_nghttp2_hd_inflate_indexed(void);
|
void test_nghttp2_hd_inflate_indexed(void);
|
||||||
void test_nghttp2_hd_inflate_indname_noinc(void);
|
void test_nghttp2_hd_inflate_indname_noinc(void);
|
||||||
void test_nghttp2_hd_inflate_indname_inc(void);
|
void test_nghttp2_hd_inflate_indname_inc(void);
|
||||||
|
|
|
@ -927,7 +927,7 @@ void test_nghttp2_session_recv_headers_with_priority(void)
|
||||||
rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater);
|
rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
CU_ASSERT(NGHTTP2_FRAME_HDLEN + 5 == nghttp2_bufs_len(&bufs));
|
CU_ASSERT(NGHTTP2_FRAME_HDLEN + 5 + 2 == nghttp2_bufs_len(&bufs));
|
||||||
|
|
||||||
nghttp2_frame_headers_free(&frame.headers);
|
nghttp2_frame_headers_free(&frame.headers);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue