nghttp2_hd: Clear reference set with index 0
This commit is contained in:
parent
5696a65c5e
commit
3d863ed254
|
@ -366,7 +366,8 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nghttp2_hd_deflate_init2(&deflater, config.side, config.deflate_table_size);
|
nghttp2_hd_deflate_init2(&deflater, config.side, config.deflate_table_size,
|
||||||
|
0);
|
||||||
nghttp2_hd_change_table_size(&deflater, config.table_size);
|
nghttp2_hd_change_table_size(&deflater, config.table_size);
|
||||||
if(config.http1text) {
|
if(config.http1text) {
|
||||||
perform_from_http1text(&deflater);
|
perform_from_http1text(&deflater);
|
||||||
|
|
|
@ -246,12 +246,14 @@ static void nghttp2_hd_ringbuf_pop_back(nghttp2_hd_ringbuf *ringbuf)
|
||||||
static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
nghttp2_hd_role role,
|
nghttp2_hd_role role,
|
||||||
nghttp2_hd_side side,
|
nghttp2_hd_side side,
|
||||||
size_t deflate_hd_table_bufsize_max)
|
size_t deflate_hd_table_bufsize_max,
|
||||||
|
uint8_t no_refset)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
context->role = role;
|
context->role = role;
|
||||||
context->side = side;
|
context->side = side;
|
||||||
context->bad = 0;
|
context->bad = 0;
|
||||||
|
context->no_refset = no_refset;
|
||||||
context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
|
context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
|
||||||
rv = nghttp2_hd_ringbuf_init
|
rv = nghttp2_hd_ringbuf_init
|
||||||
(&context->hd_table,
|
(&context->hd_table,
|
||||||
|
@ -302,20 +304,24 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
int nghttp2_hd_deflate_init(nghttp2_hd_context *deflater, nghttp2_hd_side side)
|
int nghttp2_hd_deflate_init(nghttp2_hd_context *deflater, nghttp2_hd_side side)
|
||||||
{
|
{
|
||||||
return nghttp2_hd_context_init(deflater, NGHTTP2_HD_ROLE_DEFLATE, side,
|
return nghttp2_hd_context_init(deflater, NGHTTP2_HD_ROLE_DEFLATE, side,
|
||||||
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE);
|
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater,
|
int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater,
|
||||||
nghttp2_hd_side side,
|
nghttp2_hd_side side,
|
||||||
size_t deflate_hd_table_bufsize_max)
|
size_t deflate_hd_table_bufsize_max,
|
||||||
|
uint8_t no_refset)
|
||||||
{
|
{
|
||||||
return nghttp2_hd_context_init(deflater, NGHTTP2_HD_ROLE_DEFLATE, side,
|
return nghttp2_hd_context_init(deflater, NGHTTP2_HD_ROLE_DEFLATE, side,
|
||||||
deflate_hd_table_bufsize_max);
|
deflate_hd_table_bufsize_max,
|
||||||
|
no_refset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_inflate_init(nghttp2_hd_context *inflater, nghttp2_hd_side side)
|
int nghttp2_hd_inflate_init(nghttp2_hd_context *inflater, nghttp2_hd_side side)
|
||||||
{
|
{
|
||||||
return nghttp2_hd_context_init(inflater, NGHTTP2_HD_ROLE_INFLATE, side, 0);
|
return nghttp2_hd_context_init(inflater, NGHTTP2_HD_ROLE_INFLATE, side, 0,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nghttp2_hd_context_free(nghttp2_hd_context *context)
|
static void nghttp2_hd_context_free(nghttp2_hd_context *context)
|
||||||
|
@ -574,6 +580,19 @@ static uint8_t* decode_length(ssize_t *res, uint8_t *in, uint8_t *last,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int emit_indexed0(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
|
size_t *offset_ptr)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
rv = ensure_write_buffer(buf_ptr, buflen_ptr, *offset_ptr, 1);
|
||||||
|
if(rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
*(*buf_ptr + *offset_ptr) = 0x80u;
|
||||||
|
++*offset_ptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int emit_indexed_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
static int emit_indexed_block(uint8_t **buf_ptr, size_t *buflen_ptr,
|
||||||
size_t *offset_ptr, size_t index)
|
size_t *offset_ptr, size_t index)
|
||||||
{
|
{
|
||||||
|
@ -894,6 +913,15 @@ int nghttp2_hd_change_table_size(nghttp2_hd_context *context,
|
||||||
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 = nghttp2_hd_ringbuf_get(&context->hd_table, i);
|
||||||
|
ent->flags &= ~NGHTTP2_HD_FLAG_REFSET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int check_index_range(nghttp2_hd_context *context, size_t index)
|
static int check_index_range(nghttp2_hd_context *context, size_t index)
|
||||||
{
|
{
|
||||||
return index < context->hd_table.len + STATIC_TABLE_LENGTH;
|
return index < context->hd_table.len + STATIC_TABLE_LENGTH;
|
||||||
|
@ -1066,6 +1094,13 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_context *deflater,
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
offset = nv_offset;
|
offset = nv_offset;
|
||||||
|
if(deflater->no_refset) {
|
||||||
|
rv = emit_indexed0(buf_ptr, buflen_ptr, &offset);
|
||||||
|
if(rv != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
clear_refset(deflater);
|
||||||
|
}
|
||||||
for(i = 0; i < nvlen; ++i) {
|
for(i = 0; i < nvlen; ++i) {
|
||||||
rv = deflate_nv(deflater, buf_ptr, buflen_ptr, &offset, &nv[i]);
|
rv = deflate_nv(deflater, buf_ptr, buflen_ptr, &offset, &nv[i]);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
|
@ -1136,10 +1171,14 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_context *inflater,
|
||||||
ssize_t index;
|
ssize_t index;
|
||||||
nghttp2_hd_entry *ent;
|
nghttp2_hd_entry *ent;
|
||||||
in = decode_length(&index, in, last, 7);
|
in = decode_length(&index, in, last, 7);
|
||||||
if(index <= 0) {
|
if(index < 0) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if(index == 0) {
|
||||||
|
clear_refset(inflater);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
--index;
|
--index;
|
||||||
if(!check_index_range(inflater, index)) {
|
if(!check_index_range(inflater, index)) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
|
|
@ -123,6 +123,9 @@ typedef struct {
|
||||||
further invocation of inflate/deflate will fail with
|
further invocation of inflate/deflate will fail with
|
||||||
NGHTTP2_ERR_HEADER_COMP. */
|
NGHTTP2_ERR_HEADER_COMP. */
|
||||||
uint8_t bad;
|
uint8_t bad;
|
||||||
|
/* Set to this nonzero to clear reference set on each deflation each
|
||||||
|
time. */
|
||||||
|
uint8_t no_refset;
|
||||||
/* Role of this context; deflate or infalte */
|
/* Role of this context; deflate or infalte */
|
||||||
nghttp2_hd_role role;
|
nghttp2_hd_role role;
|
||||||
/* NGHTTP2_HD_SIDE_REQUEST for processing request, otherwise
|
/* NGHTTP2_HD_SIDE_REQUEST for processing request, otherwise
|
||||||
|
@ -179,6 +182,9 @@ int nghttp2_hd_deflate_init(nghttp2_hd_context *deflater,
|
||||||
* for header table even if the larger value is specified later in
|
* for header table even if the larger value is specified later in
|
||||||
* nghttp2_hd_change_table_size().
|
* nghttp2_hd_change_table_size().
|
||||||
*
|
*
|
||||||
|
* If nonzero is given in the |no_refset|, the encoder first clears
|
||||||
|
* the reference set each time on deflation.
|
||||||
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
*
|
*
|
||||||
|
@ -187,7 +193,8 @@ int nghttp2_hd_deflate_init(nghttp2_hd_context *deflater,
|
||||||
*/
|
*/
|
||||||
int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater,
|
int nghttp2_hd_deflate_init2(nghttp2_hd_context *deflater,
|
||||||
nghttp2_hd_side side,
|
nghttp2_hd_side side,
|
||||||
size_t deflate_hd_table_bufsize_max);
|
size_t deflate_hd_table_bufsize_max,
|
||||||
|
uint8_t no_refset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes |inflater| for inflating name/values pairs.
|
* Initializes |inflater| for inflating name/values pairs.
|
||||||
|
|
|
@ -233,6 +233,8 @@ int main(int argc, char* argv[])
|
||||||
test_nghttp2_hd_deflate_common_header_eviction) ||
|
test_nghttp2_hd_deflate_common_header_eviction) ||
|
||||||
!CU_add_test(pSuite, "hd_deflate_deflate_buffer",
|
!CU_add_test(pSuite, "hd_deflate_deflate_buffer",
|
||||||
test_nghttp2_hd_deflate_deflate_buffer) ||
|
test_nghttp2_hd_deflate_deflate_buffer) ||
|
||||||
|
!CU_add_test(pSuite, "hd_deflate_clear_refset",
|
||||||
|
test_nghttp2_hd_deflate_clear_refset) ||
|
||||||
!CU_add_test(pSuite, "hd_inflate_indname_noinc",
|
!CU_add_test(pSuite, "hd_inflate_indname_noinc",
|
||||||
test_nghttp2_hd_inflate_indname_noinc) ||
|
test_nghttp2_hd_inflate_indname_noinc) ||
|
||||||
!CU_add_test(pSuite, "hd_inflate_indname_inc",
|
!CU_add_test(pSuite, "hd_inflate_indname_inc",
|
||||||
|
|
|
@ -278,7 +278,7 @@ void test_nghttp2_hd_deflate_deflate_buffer(void)
|
||||||
/* Check the case where entry from static table is inserted to
|
/* Check the case where entry from static table is inserted to
|
||||||
dynamic header table. And it is out of deflate header table
|
dynamic header table. And it is out of deflate header table
|
||||||
size. */
|
size. */
|
||||||
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST, 32);
|
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST, 32, 0);
|
||||||
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_REQUEST);
|
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_REQUEST);
|
||||||
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
||||||
nva4, ARRLEN(nva4));
|
nva4, ARRLEN(nva4));
|
||||||
|
@ -310,8 +310,7 @@ void test_nghttp2_hd_deflate_deflate_buffer(void)
|
||||||
nghttp2_hd_inflate_free(&inflater);
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
|
|
||||||
/* 156 buffer size can hold all headers in deflate region */
|
/* 156 buffer size can hold all headers in deflate region */
|
||||||
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST,
|
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST, 156, 0);
|
||||||
156);
|
|
||||||
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
||||||
nva1, ARRLEN(nva1));
|
nva1, ARRLEN(nva1));
|
||||||
CU_ASSERT(blocklen > 0);
|
CU_ASSERT(blocklen > 0);
|
||||||
|
@ -345,8 +344,7 @@ void test_nghttp2_hd_deflate_deflate_buffer(void)
|
||||||
nghttp2_hd_deflate_free(&deflater);
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
|
|
||||||
/* Check more complex use case */
|
/* Check more complex use case */
|
||||||
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST,
|
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST, 155, 0);
|
||||||
155);
|
|
||||||
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_REQUEST);
|
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_REQUEST);
|
||||||
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
||||||
nva1, ARRLEN(nva1));
|
nva1, ARRLEN(nva1));
|
||||||
|
@ -439,6 +437,43 @@ void test_nghttp2_hd_deflate_deflate_buffer(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_hd_deflate_clear_refset(void)
|
||||||
|
{
|
||||||
|
nghttp2_hd_context deflater, inflater;
|
||||||
|
uint8_t *buf = NULL;
|
||||||
|
size_t buflen = 0;
|
||||||
|
ssize_t blocklen;
|
||||||
|
nghttp2_nv nv[] = {
|
||||||
|
MAKE_NV(":path", "/"),
|
||||||
|
MAKE_NV(":scheme", "http")
|
||||||
|
};
|
||||||
|
nghttp2_nv *resnva;
|
||||||
|
ssize_t nvlen;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
nghttp2_hd_deflate_init2(&deflater, NGHTTP2_HD_SIDE_REQUEST,
|
||||||
|
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, 1);
|
||||||
|
nghttp2_hd_inflate_init(&inflater, NGHTTP2_HD_SIDE_REQUEST);
|
||||||
|
|
||||||
|
for(i = 0; i < 2; ++i) {
|
||||||
|
blocklen = nghttp2_hd_deflate_hd(&deflater, &buf, &buflen, 0,
|
||||||
|
nv, ARRLEN(nv));
|
||||||
|
CU_ASSERT(blocklen > 1);
|
||||||
|
|
||||||
|
nvlen = nghttp2_hd_inflate_hd(&inflater, &resnva, buf, blocklen);
|
||||||
|
CU_ASSERT(ARRLEN(nv) == nvlen);
|
||||||
|
nghttp2_nv_array_sort(resnva, ARRLEN(nv));
|
||||||
|
assert_nv_equal(nv, resnva, ARRLEN(nv));
|
||||||
|
|
||||||
|
nghttp2_hd_end_headers(&inflater);
|
||||||
|
nghttp2_nv_array_del(resnva);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
nghttp2_hd_inflate_free(&inflater);
|
||||||
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
|
}
|
||||||
|
|
||||||
void test_nghttp2_hd_inflate_indname_noinc(void)
|
void test_nghttp2_hd_inflate_indname_noinc(void)
|
||||||
{
|
{
|
||||||
nghttp2_hd_context inflater;
|
nghttp2_hd_context inflater;
|
||||||
|
|
|
@ -29,6 +29,7 @@ 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_common_header_eviction(void);
|
||||||
void test_nghttp2_hd_deflate_deflate_buffer(void);
|
void test_nghttp2_hd_deflate_deflate_buffer(void);
|
||||||
|
void test_nghttp2_hd_deflate_clear_refset(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);
|
||||||
void test_nghttp2_hd_inflate_indname_inc_eviction(void);
|
void test_nghttp2_hd_inflate_indname_inc_eviction(void);
|
||||||
|
|
Loading…
Reference in New Issue