Add HPACK deflation API
This commit is contained in:
parent
03e2dabea9
commit
7b9a8acc22
|
@ -2716,6 +2716,117 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len);
|
||||||
|
|
||||||
/* HPACK API */
|
/* HPACK API */
|
||||||
|
|
||||||
|
struct nghttp2_hd_deflater;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct
|
||||||
|
*
|
||||||
|
* HPACK deflater object.
|
||||||
|
*/
|
||||||
|
typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* Initializes |*deflater_ptr| for deflating name/values pairs.
|
||||||
|
*
|
||||||
|
* The |deflate_hd_table_bufsize_max| is the upper bound of header
|
||||||
|
* table size the deflater will use.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||||
|
* Out of memory.
|
||||||
|
*/
|
||||||
|
int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||||
|
size_t deflate_hd_table_bufsize_max);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* Deallocates any resources allocated for |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
|
||||||
|
*
|
||||||
|
* Changes header table size of the |deflater| to
|
||||||
|
* |settings_hd_table_bufsize_max| bytes. This may trigger eviction
|
||||||
|
* in the dynamic table.
|
||||||
|
*
|
||||||
|
* The |settings_hd_table_bufsize_max| should be the value received in
|
||||||
|
* SETTINGS_HEADER_TABLE_SIZE.
|
||||||
|
*
|
||||||
|
* The deflater never uses more memory than
|
||||||
|
* ``deflate_hd_table_bufsize_max`` bytes specified in
|
||||||
|
* `nghttp2_hd_deflate_new()`. Therefore, if
|
||||||
|
* |settings_hd_table_bufsize_max| > ``deflate_hd_table_bufsize_max``,
|
||||||
|
* resulting maximum table size becomes
|
||||||
|
* ``deflate_hd_table_bufsize_max``.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||||
|
* Out of memory.
|
||||||
|
*/
|
||||||
|
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||||
|
size_t settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||||
|
* the |buf| of length |buflen|.
|
||||||
|
*
|
||||||
|
* If |buf| is not large enough to store the deflated header block,
|
||||||
|
* this function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The
|
||||||
|
* caller should use `nghttp2_hd_deflate_bound()` to know the upper
|
||||||
|
* bound of buffer size required to deflate given header name/value
|
||||||
|
* pairs.
|
||||||
|
*
|
||||||
|
* Once this function fails, subsequent call of this function always
|
||||||
|
* returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
|
||||||
|
*
|
||||||
|
* After this function returns, it is safe to delete the |nva|.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||||
|
* Out of memory.
|
||||||
|
* :enum:`NGHTTP2_ERR_HEADER_COMP`
|
||||||
|
* Deflation process has failed.
|
||||||
|
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||||
|
* The provided |buflen| size is too small to hold the output.
|
||||||
|
*/
|
||||||
|
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
||||||
|
uint8_t *buf, size_t buflen,
|
||||||
|
nghttp2_nv *nva, size_t nvlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* Returns an upper bound on the compressed size after deflation of
|
||||||
|
* |nva| of length |nvlen|.
|
||||||
|
*/
|
||||||
|
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
|
||||||
|
const nghttp2_nv *nva, size_t nvlen);
|
||||||
|
|
||||||
struct nghttp2_hd_inflater;
|
struct nghttp2_hd_inflater;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -177,6 +177,37 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len)
|
||||||
|
{
|
||||||
|
nghttp2_buf_chain *chain;
|
||||||
|
|
||||||
|
chain = malloc(sizeof(nghttp2_buf_chain));
|
||||||
|
if(chain == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
chain->next = NULL;
|
||||||
|
|
||||||
|
nghttp2_buf_wrap_init(&chain->buf, begin, len);
|
||||||
|
|
||||||
|
bufs->offset = 0;
|
||||||
|
|
||||||
|
bufs->head = chain;
|
||||||
|
bufs->cur = bufs->head;
|
||||||
|
|
||||||
|
bufs->chunk_length = len;
|
||||||
|
bufs->chunk_used = 1;
|
||||||
|
bufs->max_chunk = 1;
|
||||||
|
bufs->chunk_keep = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs)
|
||||||
|
{
|
||||||
|
free(bufs->head);
|
||||||
|
}
|
||||||
|
|
||||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs)
|
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs)
|
||||||
{
|
{
|
||||||
nghttp2_buf_chain *ci;
|
nghttp2_buf_chain *ci;
|
||||||
|
|
|
@ -207,6 +207,27 @@ int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
|
||||||
*/
|
*/
|
||||||
void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
||||||
|
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
||||||
|
* is fixed and no allocate extra chunk buffer is allocated. In other
|
||||||
|
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
||||||
|
* for |bufs|, use nghttp2_bufs_wrap_free().
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory.
|
||||||
|
*/
|
||||||
|
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frees any related resource to the |bufs|. This function does not
|
||||||
|
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||||
|
*/
|
||||||
|
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Appends the |data| of length |len| to the |bufs|. The write starts
|
* Appends the |data| of length |len| to the |bufs|. The write starts
|
||||||
* at bufs->cur->buf.last. A new buffers will be allocated to store
|
* at bufs->cur->buf.last. A new buffers will be allocated to store
|
||||||
|
|
|
@ -364,7 +364,7 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs,
|
||||||
buf->last = buf->pos;
|
buf->last = buf->pos;
|
||||||
|
|
||||||
/* This call will adjust buf->last to the correct position */
|
/* This call will adjust buf->last to the correct position */
|
||||||
rv = nghttp2_hd_deflate_hd(deflater, bufs, frame->nva, frame->nvlen);
|
rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, frame->nva, frame->nvlen);
|
||||||
|
|
||||||
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
@ -595,7 +595,7 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
|
||||||
buf->last = buf->pos;
|
buf->last = buf->pos;
|
||||||
|
|
||||||
/* This call will adjust buf->last to the correct position */
|
/* This call will adjust buf->last to the correct position */
|
||||||
rv = nghttp2_hd_deflate_hd(deflater, bufs, frame->nva, frame->nvlen);
|
rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, frame->nva, frame->nvlen);
|
||||||
|
|
||||||
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
||||||
rv = NGHTTP2_ERR_HEADER_COMP;
|
rv = NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
|
|
@ -1203,9 +1203,9 @@ static int deflate_post_process_hd_entry(nghttp2_hd_entry *ent,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||||
nghttp2_bufs *bufs,
|
nghttp2_bufs *bufs,
|
||||||
nghttp2_nv *nv, size_t nvlen)
|
nghttp2_nv *nv, size_t nvlen)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
|
@ -1259,6 +1259,87 @@ int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
||||||
|
uint8_t *buf, size_t buflen,
|
||||||
|
nghttp2_nv *nv, size_t nvlen)
|
||||||
|
{
|
||||||
|
nghttp2_bufs bufs;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = nghttp2_bufs_wrap_init(&bufs, buf, buflen);
|
||||||
|
|
||||||
|
if(rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen);
|
||||||
|
|
||||||
|
buflen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
|
nghttp2_bufs_wrap_free(&bufs);
|
||||||
|
|
||||||
|
if(rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
||||||
|
return NGHTTP2_ERR_INSUFF_BUFSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buflen;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
|
||||||
|
const nghttp2_nv *nva, size_t nvlen)
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Possible Reference Set Emptying */
|
||||||
|
n = 1;
|
||||||
|
|
||||||
|
/* Possible Maximum Header Table Size Change. Encoding (1u << 31) -
|
||||||
|
1 using 4 bit prefix requires 6 bytes. */
|
||||||
|
n += 6;
|
||||||
|
|
||||||
|
/* Use Literal Header Field without indexing - New Name, since it is
|
||||||
|
most space consuming format. Also we choose the less one between
|
||||||
|
non-huffman and huffman, so using literal byte count is
|
||||||
|
sufficient for upper bound.
|
||||||
|
|
||||||
|
Encoding (1u << 31) - 1 using 7 bit prefix requires 6 bytes. We
|
||||||
|
need 2 of this for |nvlen| header fields. */
|
||||||
|
n += 6 * 2 * nvlen;
|
||||||
|
|
||||||
|
for(i = 0; i < nvlen; ++i) {
|
||||||
|
n += nva[i].namelen + nva[i].valuelen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add possible reference set toggle off */
|
||||||
|
n += deflater->ctx.hd_table.len;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||||
|
size_t deflate_hd_table_bufsize_max)
|
||||||
|
{
|
||||||
|
*deflater_ptr = malloc(sizeof(nghttp2_hd_deflater));
|
||||||
|
|
||||||
|
if(*deflater_ptr == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nghttp2_hd_deflate_init2(*deflater_ptr, deflate_hd_table_bufsize_max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater)
|
||||||
|
{
|
||||||
|
nghttp2_hd_deflate_free(deflater);
|
||||||
|
|
||||||
|
free(deflater);
|
||||||
|
}
|
||||||
|
|
||||||
static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater,
|
static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater,
|
||||||
const uint8_t *in)
|
const uint8_t *in)
|
||||||
{
|
{
|
||||||
|
|
|
@ -132,7 +132,7 @@ typedef struct {
|
||||||
uint8_t bad;
|
uint8_t bad;
|
||||||
} nghttp2_hd_context;
|
} nghttp2_hd_context;
|
||||||
|
|
||||||
typedef struct {
|
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;
|
||||||
|
@ -142,7 +142,7 @@ typedef struct {
|
||||||
/* 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;
|
||||||
} nghttp2_hd_deflater;
|
};
|
||||||
|
|
||||||
struct nghttp2_hd_inflater {
|
struct nghttp2_hd_inflater {
|
||||||
nghttp2_hd_context ctx;
|
nghttp2_hd_context ctx;
|
||||||
|
@ -240,31 +240,6 @@ int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
*/
|
*/
|
||||||
void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
|
void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets the availability of reference set in the |deflater|. If
|
|
||||||
* |no_refset| is nonzero, the deflater will first emit index=0 in the
|
|
||||||
* each 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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Changes header table size of the |deflater|. This may trigger
|
|
||||||
* eviction in the dynamic table.
|
|
||||||
*
|
|
||||||
* The |settings_hd_table_bufsize_max| should be the value received in
|
|
||||||
* SETTINGS_HEADER_TABLE_SIZE.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
*/
|
|
||||||
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
|
||||||
size_t settings_hd_table_bufsize_max);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||||
* the |bufs|.
|
* the |bufs|.
|
||||||
|
@ -285,9 +260,9 @@ int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||||
* NGHTTP2_ERR_BUFFER_ERROR
|
* NGHTTP2_ERR_BUFFER_ERROR
|
||||||
* Out of buffer space.
|
* Out of buffer space.
|
||||||
*/
|
*/
|
||||||
int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||||
nghttp2_bufs *bufs,
|
nghttp2_bufs *bufs,
|
||||||
nghttp2_nv *nva, size_t nvlen);
|
nghttp2_nv *nva, size_t nvlen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes |inflater| for inflating name/values pairs.
|
* Initializes |inflater| for inflating name/values pairs.
|
||||||
|
|
|
@ -247,6 +247,11 @@ cdef extern from 'nghttp2/nghttp2.h':
|
||||||
|
|
||||||
const char* nghttp2_strerror(int lib_error_code)
|
const char* nghttp2_strerror(int lib_error_code)
|
||||||
|
|
||||||
|
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,
|
||||||
|
size_t hd_table_bufsize_max)
|
||||||
|
|
||||||
int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
||||||
size_t hd_table_bufsize_max)
|
size_t hd_table_bufsize_max)
|
||||||
|
@ -302,15 +307,9 @@ cdef extern from 'nghttp2_hd.h':
|
||||||
|
|
||||||
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater)
|
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater)
|
||||||
|
|
||||||
void nghttp2_hd_deflate_set_no_refset(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||||
uint8_t no_refset)
|
nghttp2_bufs *bufs,
|
||||||
|
nghttp2_nv *nva, size_t nvlen)
|
||||||
int nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
|
||||||
size_t hd_table_bufsize_max)
|
|
||||||
|
|
||||||
int nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
|
||||||
nghttp2_bufs *bufs,
|
|
||||||
nghttp2_nv *nva, size_t nvlen)
|
|
||||||
|
|
||||||
nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
|
nghttp2_hd_entry* nghttp2_hd_table_get(nghttp2_hd_context *context,
|
||||||
size_t index)
|
size_t index)
|
||||||
|
|
|
@ -122,8 +122,8 @@ cdef class HDDeflater:
|
||||||
|
|
||||||
cnghttp2.nghttp2_bufs_init(&bufs, 4096, 16)
|
cnghttp2.nghttp2_bufs_init(&bufs, 4096, 16)
|
||||||
|
|
||||||
rv = cnghttp2.nghttp2_hd_deflate_hd(&self._deflater, &bufs,
|
rv = cnghttp2.nghttp2_hd_deflate_hd_bufs(&self._deflater, &bufs,
|
||||||
nva, len(headers))
|
nva, len(headers))
|
||||||
free(nva)
|
free(nva)
|
||||||
|
|
||||||
if rv < 0:
|
if rv < 0:
|
||||||
|
|
|
@ -130,8 +130,8 @@ static void deflate_hd(nghttp2_hd_deflater *deflater,
|
||||||
|
|
||||||
nghttp2_bufs_init2(&bufs, 4096, 16, 0);
|
nghttp2_bufs_init2(&bufs, 4096, 16, 0);
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(deflater, &bufs,
|
rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs,
|
||||||
(nghttp2_nv*)nva.data(), nva.size());
|
(nghttp2_nv*)nva.data(), nva.size());
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
fprintf(stderr, "deflate failed with error code %zd at %d\n", rv, seq);
|
fprintf(stderr, "deflate failed with error code %zd at %d\n", rv, seq);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
|
@ -453,7 +453,7 @@ static int deflate_inflate(nghttp2_hd_deflater *deflater,
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(deflater, bufs, nva, nvlen);
|
rv = nghttp2_hd_deflate_hd_bufs(deflater, bufs, nva, nvlen);
|
||||||
|
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -278,6 +278,9 @@ int main(int argc, char* argv[])
|
||||||
!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, "hd_no_index", test_nghttp2_hd_no_index) ||
|
||||||
|
!CU_add_test(pSuite, "hd_deflate_bound",
|
||||||
|
test_nghttp2_hd_deflate_bound) ||
|
||||||
|
!CU_add_test(pSuite, "hd_public_api", test_nghttp2_hd_public_api) ||
|
||||||
!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) ||
|
||||||
!CU_add_test(pSuite, "check_header_name",
|
!CU_add_test(pSuite, "check_header_name",
|
||||||
|
|
|
@ -63,7 +63,7 @@ void test_nghttp2_hd_deflate(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));
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&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);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -77,7 +77,7 @@ void test_nghttp2_hd_deflate(void)
|
||||||
nghttp2_bufs_reset(&bufs);
|
nghttp2_bufs_reset(&bufs);
|
||||||
|
|
||||||
/* Second headers */
|
/* Second headers */
|
||||||
rv = nghttp2_hd_deflate_hd(&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);
|
||||||
|
@ -92,7 +92,7 @@ void test_nghttp2_hd_deflate(void)
|
||||||
|
|
||||||
/* Third headers, including same header field name, but value is not
|
/* Third headers, including same header field name, but value is not
|
||||||
the same. */
|
the same. */
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva3, ARRLEN(nva3));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva3, ARRLEN(nva3));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -106,7 +106,7 @@ void test_nghttp2_hd_deflate(void)
|
||||||
nghttp2_bufs_reset(&bufs);
|
nghttp2_bufs_reset(&bufs);
|
||||||
|
|
||||||
/* Fourth headers, including duplicate header fields. */
|
/* Fourth headers, including duplicate header fields. */
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva4, ARRLEN(nva4));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva4, ARRLEN(nva4));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -120,7 +120,7 @@ void test_nghttp2_hd_deflate(void)
|
||||||
nghttp2_bufs_reset(&bufs);
|
nghttp2_bufs_reset(&bufs);
|
||||||
|
|
||||||
/* Fifth headers includes empty value */
|
/* Fifth headers includes empty value */
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva5, ARRLEN(nva5));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva5, ARRLEN(nva5));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -161,7 +161,7 @@ void test_nghttp2_hd_deflate_same_indexed_repr(void)
|
||||||
|
|
||||||
/* Encode 2 same headers. cookie:alpha is not in the reference set,
|
/* Encode 2 same headers. cookie:alpha is not in the reference set,
|
||||||
so first emit literal repr and then 2 emits of indexed repr. */
|
so first emit literal repr and then 2 emits of indexed repr. */
|
||||||
rv = nghttp2_hd_deflate_hd(&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);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -176,7 +176,7 @@ void test_nghttp2_hd_deflate_same_indexed_repr(void)
|
||||||
|
|
||||||
/* Encode 3 same headers. This time, cookie:alpha is in the
|
/* Encode 3 same headers. This time, cookie:alpha is in the
|
||||||
reference set, so the encoder emits indexed repr 6 times */
|
reference set, so the encoder emits indexed repr 6 times */
|
||||||
rv = nghttp2_hd_deflate_hd(&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);
|
||||||
|
@ -225,7 +225,7 @@ void test_nghttp2_hd_deflate_common_header_eviction(void)
|
||||||
|
|
||||||
/* First emit "h1: ..." to put it in the reference set (index
|
/* First emit "h1: ..." to put it in the reference set (index
|
||||||
= 0). */
|
= 0). */
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 1);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 1);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -241,7 +241,7 @@ void test_nghttp2_hd_deflate_common_header_eviction(void)
|
||||||
|
|
||||||
/* Encode with second header */
|
/* Encode with second header */
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -290,7 +290,7 @@ void test_nghttp2_hd_deflate_clear_refset(void)
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
for(i = 0; i < 2; ++i) {
|
for(i = 0; i < 2; ++i) {
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nv, ARRLEN(nv));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nv, ARRLEN(nv));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -671,7 +671,7 @@ void test_nghttp2_hd_change_table_size(void)
|
||||||
CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max);
|
CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
/* This will emit encoding context update with header table size 4096 */
|
/* This will emit encoding context update with header table size 4096 */
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -698,7 +698,7 @@ void test_nghttp2_hd_change_table_size(void)
|
||||||
CU_ASSERT(1024 == inflater.ctx.hd_table_bufsize_max);
|
CU_ASSERT(1024 == inflater.ctx.hd_table_bufsize_max);
|
||||||
CU_ASSERT(1024 == inflater.settings_hd_table_bufsize_max);
|
CU_ASSERT(1024 == inflater.settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -727,7 +727,7 @@ void test_nghttp2_hd_change_table_size(void)
|
||||||
CU_ASSERT(0 == inflater.ctx.hd_table_bufsize_max);
|
CU_ASSERT(0 == inflater.ctx.hd_table_bufsize_max);
|
||||||
CU_ASSERT(0 == inflater.settings_hd_table_bufsize_max);
|
CU_ASSERT(0 == inflater.settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -764,7 +764,7 @@ void test_nghttp2_hd_change_table_size(void)
|
||||||
CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max);
|
CU_ASSERT(8000 == inflater.ctx.hd_table_bufsize_max);
|
||||||
CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max);
|
CU_ASSERT(8000 == inflater.settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -790,7 +790,7 @@ void test_nghttp2_hd_change_table_size(void)
|
||||||
CU_ASSERT(16383 == inflater.ctx.hd_table_bufsize_max);
|
CU_ASSERT(16383 == inflater.ctx.hd_table_bufsize_max);
|
||||||
CU_ASSERT(16383 == inflater.settings_hd_table_bufsize_max);
|
CU_ASSERT(16383 == inflater.settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -827,7 +827,7 @@ void test_nghttp2_hd_change_table_size(void)
|
||||||
CU_ASSERT(1024 == deflater.ctx.hd_table_bufsize_max);
|
CU_ASSERT(1024 == deflater.ctx.hd_table_bufsize_max);
|
||||||
|
|
||||||
/* This emits context update with buffer size 1024 */
|
/* This emits context update with buffer size 1024 */
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, 2);
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, 2);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -860,7 +860,7 @@ static void check_deflate_inflate(nghttp2_hd_deflater *deflater,
|
||||||
frame_pack_bufs_init(&bufs);
|
frame_pack_bufs_init(&bufs);
|
||||||
|
|
||||||
nva_out_init(&out);
|
nva_out_init(&out);
|
||||||
rv = nghttp2_hd_deflate_hd(deflater, &bufs, nva, nvlen);
|
rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nva, nvlen);
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -1061,7 +1061,7 @@ void test_nghttp2_hd_no_index(void)
|
||||||
nghttp2_hd_deflate_init(&deflater);
|
nghttp2_hd_deflate_init(&deflater);
|
||||||
nghttp2_hd_inflate_init(&inflater);
|
nghttp2_hd_inflate_init(&inflater);
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_hd(&deflater, &bufs, nva, ARRLEN(nva));
|
rv = nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, ARRLEN(nva));
|
||||||
blocklen = nghttp2_bufs_len(&bufs);
|
blocklen = nghttp2_bufs_len(&bufs);
|
||||||
|
|
||||||
CU_ASSERT(0 == rv);
|
CU_ASSERT(0 == rv);
|
||||||
|
@ -1082,3 +1082,80 @@ void test_nghttp2_hd_no_index(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_deflate_bound(void)
|
||||||
|
{
|
||||||
|
nghttp2_hd_deflater deflater;
|
||||||
|
nghttp2_nv nva[] = {
|
||||||
|
MAKE_NV(":method", "GET"),
|
||||||
|
MAKE_NV("alpha", "bravo")
|
||||||
|
};
|
||||||
|
nghttp2_bufs bufs;
|
||||||
|
size_t bound, bound2;
|
||||||
|
|
||||||
|
frame_pack_bufs_init(&bufs);
|
||||||
|
|
||||||
|
nghttp2_hd_deflate_init(&deflater);
|
||||||
|
|
||||||
|
bound = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
CU_ASSERT(1 + 6 + 6 * 2 * 2 +
|
||||||
|
nva[0].namelen + nva[0].valuelen +
|
||||||
|
nva[1].namelen + nva[1].valuelen
|
||||||
|
== bound);
|
||||||
|
|
||||||
|
nghttp2_hd_deflate_hd_bufs(&deflater, &bufs, nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
CU_ASSERT(bound > (size_t)nghttp2_bufs_len(&bufs));
|
||||||
|
|
||||||
|
bound2 = nghttp2_hd_deflate_bound(&deflater, nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
CU_ASSERT(bound + 2 == bound2);
|
||||||
|
|
||||||
|
nghttp2_bufs_free(&bufs);
|
||||||
|
nghttp2_hd_deflate_free(&deflater);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_nghttp2_hd_public_api(void)
|
||||||
|
{
|
||||||
|
nghttp2_hd_deflater *deflater;
|
||||||
|
nghttp2_hd_inflater *inflater;
|
||||||
|
nghttp2_nv nva[] = {
|
||||||
|
MAKE_NV("alpha", "bravo"),
|
||||||
|
MAKE_NV("charlie", "delta")
|
||||||
|
};
|
||||||
|
uint8_t buf[4096];
|
||||||
|
size_t buflen;
|
||||||
|
ssize_t blocklen;
|
||||||
|
nghttp2_bufs bufs;
|
||||||
|
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_deflate_new(&deflater, 4096));
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_inflate_new(&inflater));
|
||||||
|
|
||||||
|
buflen = nghttp2_hd_deflate_bound(deflater, nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
blocklen = nghttp2_hd_deflate_hd(deflater, buf, buflen, nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
CU_ASSERT(blocklen > 0);
|
||||||
|
|
||||||
|
nghttp2_bufs_wrap_init(&bufs, buf, blocklen);
|
||||||
|
bufs.head->buf.last += blocklen;
|
||||||
|
|
||||||
|
CU_ASSERT(blocklen == inflate_hd(inflater, NULL, &bufs, 0));
|
||||||
|
|
||||||
|
nghttp2_bufs_wrap_free(&bufs);
|
||||||
|
|
||||||
|
nghttp2_hd_inflate_del(inflater);
|
||||||
|
nghttp2_hd_deflate_del(deflater);
|
||||||
|
|
||||||
|
/* See NGHTTP2_ERR_INSUFF_BUFSIZE */
|
||||||
|
CU_ASSERT(0 == nghttp2_hd_deflate_new(&deflater, 4096));
|
||||||
|
|
||||||
|
blocklen = nghttp2_hd_deflate_hd(deflater, buf, blocklen - 1,
|
||||||
|
nva, ARRLEN(nva));
|
||||||
|
|
||||||
|
CU_ASSERT(NGHTTP2_ERR_INSUFF_BUFSIZE == blocklen);
|
||||||
|
|
||||||
|
nghttp2_hd_deflate_del(deflater);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,5 +40,7 @@ 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);
|
void test_nghttp2_hd_no_index(void);
|
||||||
|
void test_nghttp2_hd_deflate_bound(void);
|
||||||
|
void test_nghttp2_hd_public_api(void);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_TEST_H */
|
#endif /* NGHTTP2_HD_TEST_H */
|
||||||
|
|
Loading…
Reference in New Issue