Allow nonuniform buffer size in nghttp2_hd_deflate_hd_vec()
This commit is contained in:
parent
b8883101d3
commit
d0fea96e69
|
@ -4604,14 +4604,12 @@ nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
|
||||||
*
|
*
|
||||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||||
* the |veclen| size of buf vector |vec|. The each size of buffer
|
* the |veclen| size of buf vector |vec|. The each size of buffer
|
||||||
* must be set in len field of :type:`nghttp2_vec`, and this function
|
* must be set in len field of :type:`nghttp2_vec`. If and only if
|
||||||
* assumes all buffer size is equal. The application is responsible
|
* one chunk is filled up completely, next chunk will be used. If
|
||||||
* to make sure that this assumption holds. If one chunk is filled
|
* |vec| is not large enough to store the deflated header block, this
|
||||||
* up, next chunk will be used. If |vec| is not large enough to store
|
* function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
|
||||||
* the deflated header block, this function fails with
|
* should use `nghttp2_hd_deflate_bound()` to know the upper bound of
|
||||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller should use
|
* buffer size required to deflate given header name/value pairs.
|
||||||
* `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
|
* Once this function fails, subsequent call of this function always
|
||||||
* returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
|
* returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
|
||||||
|
@ -4627,8 +4625,6 @@ nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
|
||||||
* Deflation process has failed.
|
* Deflation process has failed.
|
||||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||||
* The provided |buflen| size is too small to hold the output.
|
* The provided |buflen| size is too small to hold the output.
|
||||||
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
|
|
||||||
* The size of each buffer in |nva| is not the same.
|
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN ssize_t
|
NGHTTP2_EXTERN ssize_t
|
||||||
nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, const nghttp2_vec *vec,
|
nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, const nghttp2_vec *vec,
|
||||||
|
|
|
@ -224,13 +224,13 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||||
size_t veclen, size_t chunklen, nghttp2_mem *mem) {
|
size_t veclen, nghttp2_mem *mem) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
nghttp2_buf_chain *cur_chain;
|
nghttp2_buf_chain *cur_chain;
|
||||||
nghttp2_buf_chain *head_chain;
|
nghttp2_buf_chain *head_chain;
|
||||||
nghttp2_buf_chain **dst_chain = &head_chain;
|
nghttp2_buf_chain **dst_chain = &head_chain;
|
||||||
|
|
||||||
if (veclen == 0 || chunklen == 0) {
|
if (veclen == 0) {
|
||||||
return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
|
return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,8 @@ int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||||
bufs->head = head_chain;
|
bufs->head = head_chain;
|
||||||
bufs->cur = bufs->head;
|
bufs->cur = bufs->head;
|
||||||
|
|
||||||
bufs->chunk_length = chunklen;
|
/* We don't use chunk_length since no allocation is expected. */
|
||||||
|
bufs->chunk_length = 0;
|
||||||
bufs->chunk_used = veclen;
|
bufs->chunk_used = veclen;
|
||||||
bufs->max_chunk = veclen;
|
bufs->max_chunk = veclen;
|
||||||
bufs->chunk_keep = veclen;
|
bufs->chunk_keep = veclen;
|
||||||
|
|
|
@ -212,10 +212,10 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes |bufs| using supplied |veclen| size of buf vector
|
* Initializes |bufs| using supplied |veclen| size of buf vector
|
||||||
* |vec|, assuming that each buffer has length |chunklen|. The buffer
|
* |vec|. The number of buffers is fixed and no extra chunk buffer is
|
||||||
* size is fixed and no extra chunk buffer is allocated. In other
|
* allocated. In other words, max_chunk = chunk_keep = |in_len|. To
|
||||||
* words, max_chunk = chunk_keep = |in_len|. To free the resource
|
* free the resource allocated for |bufs|, use
|
||||||
* allocated for |bufs|, use nghttp2_bufs_wrap_free().
|
* nghttp2_bufs_wrap_free().
|
||||||
*
|
*
|
||||||
* 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:
|
||||||
|
@ -224,7 +224,7 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||||
size_t veclen, size_t chunklen, nghttp2_mem *mem);
|
size_t veclen, nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frees any related resource to the |bufs|. This function does not
|
* Frees any related resource to the |bufs|. This function does not
|
||||||
|
|
|
@ -1509,25 +1509,11 @@ ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
|
||||||
nghttp2_bufs bufs;
|
nghttp2_bufs bufs;
|
||||||
int rv;
|
int rv;
|
||||||
nghttp2_mem *mem;
|
nghttp2_mem *mem;
|
||||||
size_t i;
|
|
||||||
size_t buflen;
|
size_t buflen;
|
||||||
size_t chunklen;
|
|
||||||
|
|
||||||
if (veclen == 0) {
|
|
||||||
chunklen = 0;
|
|
||||||
} else {
|
|
||||||
for (i = 1; i < veclen; ++i) {
|
|
||||||
if (vec[0].len != vec[i].len) {
|
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chunklen = vec[0].len;
|
|
||||||
}
|
|
||||||
|
|
||||||
mem = deflater->ctx.mem;
|
mem = deflater->ctx.mem;
|
||||||
|
|
||||||
rv = nghttp2_bufs_wrap_init2(&bufs, vec, veclen, chunklen, mem);
|
rv = nghttp2_bufs_wrap_init2(&bufs, vec, veclen, mem);
|
||||||
|
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -1352,14 +1352,24 @@ void test_nghttp2_hd_deflate_hd_vec(void) {
|
||||||
vec[0].base = &buf[0];
|
vec[0].base = &buf[0];
|
||||||
vec[0].len = buflen / 2;
|
vec[0].len = buflen / 2;
|
||||||
vec[1].base = &buf[buflen / 2];
|
vec[1].base = &buf[buflen / 2];
|
||||||
vec[1].len = (buflen / 2) - 1;
|
vec[1].len = (buflen / 2) + 1;
|
||||||
|
|
||||||
blocklen = nghttp2_hd_deflate_hd_vec(deflater, vec, 2, nva, ARRLEN(nva));
|
blocklen = nghttp2_hd_deflate_hd_vec(deflater, vec, 2, nva, ARRLEN(nva));
|
||||||
|
|
||||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT == blocklen);
|
CU_ASSERT(blocklen > 0);
|
||||||
|
|
||||||
|
nghttp2_bufs_wrap_init(&bufs, buf, (size_t)blocklen, mem);
|
||||||
|
bufs.head->buf.last += blocklen;
|
||||||
|
|
||||||
|
CU_ASSERT(blocklen == inflate_hd(inflater, &out, &bufs, 0, mem));
|
||||||
|
CU_ASSERT(ARRLEN(nva) == out.nvlen);
|
||||||
|
assert_nv_equal(nva, out.nva, ARRLEN(nva), mem);
|
||||||
|
|
||||||
|
nghttp2_bufs_wrap_free(&bufs);
|
||||||
|
|
||||||
nghttp2_hd_inflate_del(inflater);
|
nghttp2_hd_inflate_del(inflater);
|
||||||
nghttp2_hd_deflate_del(deflater);
|
nghttp2_hd_deflate_del(deflater);
|
||||||
|
nva_out_reset(&out, mem);
|
||||||
|
|
||||||
/* check the case where chunk size is 1 */
|
/* check the case where chunk size is 1 */
|
||||||
nghttp2_hd_deflate_new(&deflater, 4096);
|
nghttp2_hd_deflate_new(&deflater, 4096);
|
||||||
|
|
Loading…
Reference in New Issue