Merge branch 'weliu-master'
This commit is contained in:
commit
4f02b191d1
|
@ -4599,6 +4599,39 @@ NGHTTP2_EXTERN ssize_t
|
|||
nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
|
||||
size_t buflen, const nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||
* the |inlen| size of buf vector |bufsin|, each buf has length |buflen|.
|
||||
* |buflens| is a |inlen| size of array, which will be used to store the writen
|
||||
* size of each chunk. If one chunk is filled up, next chunk will be used.
|
||||
* If |bufsin| 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.
|
||||
*/
|
||||
NGHTTP2_EXTERN ssize_t
|
||||
nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, uint8_t *const *bufsin,
|
||||
size_t inlen, size_t buflen, size_t *const buflens,
|
||||
const nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
|
|
@ -223,13 +223,57 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, uint8_t *const *bufs_in,
|
||||
size_t in_len, size_t buf_len, nghttp2_mem *mem) {
|
||||
size_t i = 0;
|
||||
nghttp2_buf_chain *cur_chain;
|
||||
nghttp2_buf_chain *head_chain = NULL;
|
||||
nghttp2_buf_chain **dst_chain = &head_chain;
|
||||
|
||||
for (i = 0; i < in_len; ++i) {
|
||||
uint8_t *begin = bufs_in[i];
|
||||
|
||||
cur_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain));
|
||||
if (cur_chain == NULL) {
|
||||
while (head_chain) {
|
||||
nghttp2_buf_chain *tmp_chain = head_chain->next;
|
||||
nghttp2_mem_free(mem, head_chain);
|
||||
head_chain = tmp_chain;
|
||||
}
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
|
||||
cur_chain->next = NULL;
|
||||
nghttp2_buf_wrap_init(&cur_chain->buf, begin, buf_len);
|
||||
|
||||
*dst_chain = cur_chain;
|
||||
dst_chain = &cur_chain->next;
|
||||
}
|
||||
|
||||
bufs->mem = mem;
|
||||
bufs->offset = 0;
|
||||
|
||||
bufs->head = head_chain;
|
||||
bufs->cur = bufs->head;
|
||||
|
||||
bufs->chunk_length = buf_len;
|
||||
bufs->chunk_used = in_len;
|
||||
bufs->max_chunk = in_len;
|
||||
bufs->chunk_keep = in_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
|
||||
if (bufs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||
bufs->head = NULL;
|
||||
while (bufs->head) {
|
||||
nghttp2_buf_chain *tmp_chain = bufs->head->next;
|
||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||
bufs->head = tmp_chain;
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
||||
|
@ -256,6 +300,20 @@ size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
|
|||
return len;
|
||||
}
|
||||
|
||||
size_t nghttp2_bufs_len_vec(nghttp2_bufs *bufs, size_t *const buflens) {
|
||||
nghttp2_buf_chain *ci;
|
||||
size_t len, total_len = 0;
|
||||
int i = 0;
|
||||
|
||||
for (ci = bufs->head; ci; ci = ci->next) {
|
||||
len = nghttp2_buf_len(&ci->buf);
|
||||
total_len += len;
|
||||
buflens[i++] = len;
|
||||
}
|
||||
|
||||
return total_len;
|
||||
}
|
||||
|
||||
static size_t bufs_avail(nghttp2_bufs *bufs) {
|
||||
return nghttp2_buf_avail(&bufs->cur->buf) +
|
||||
(bufs->chunk_length - bufs->offset) *
|
||||
|
|
|
@ -197,7 +197,7 @@ 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
|
||||
* is fixed and no 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().
|
||||
*
|
||||
|
@ -210,6 +210,22 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
|||
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |bufs| using supplied |in_len| size of buf vector |bufs_in|,
|
||||
* each buf has length |buf_len|.
|
||||
* The buffer size is fixed and no extra chunk buffer is allocated.
|
||||
* In other words, max_chunk = chunk_keep = |in_len|. 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_init2(nghttp2_bufs *bufs, uint8_t *const *bufs_in,
|
||||
size_t in_len, size_t buf_len, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees any related resource to the |bufs|. This function does not
|
||||
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||
|
@ -381,8 +397,13 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
|||
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
||||
|
||||
/*
|
||||
* Returns the buffer length of |bufs|.
|
||||
* Returns the total buffer length of |bufs|.
|
||||
*/
|
||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Returns the total buffer length of |bufs|, and each buffer length in |buflens|.
|
||||
*/
|
||||
size_t nghttp2_bufs_len_vec(nghttp2_bufs *bufs, size_t *const buflens);
|
||||
|
||||
#endif /* NGHTTP2_BUF_H */
|
||||
|
|
|
@ -1503,6 +1503,41 @@ ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
|
|||
return (ssize_t)buflen;
|
||||
}
|
||||
|
||||
ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
|
||||
uint8_t *const *bufsin, size_t inlen,
|
||||
size_t buflen, size_t *const buflens,
|
||||
const nghttp2_nv *nv, size_t nvlen) {
|
||||
nghttp2_bufs bufs;
|
||||
int rv;
|
||||
nghttp2_mem *mem;
|
||||
|
||||
memset(buflens, 0, sizeof(size_t) * inlen);
|
||||
|
||||
mem = deflater->ctx.mem;
|
||||
|
||||
rv = nghttp2_bufs_wrap_init2(&bufs, bufsin, inlen, buflen, mem);
|
||||
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = nghttp2_hd_deflate_hd_bufs(deflater, &bufs, nv, nvlen);
|
||||
|
||||
buflen = nghttp2_bufs_len_vec(&bufs, buflens);
|
||||
|
||||
nghttp2_bufs_wrap_free(&bufs);
|
||||
|
||||
if (rv == NGHTTP2_ERR_BUFFER_ERROR) {
|
||||
return NGHTTP2_ERR_INSUFF_BUFSIZE;
|
||||
}
|
||||
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return (ssize_t)buflen;
|
||||
}
|
||||
|
||||
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater _U_,
|
||||
const nghttp2_nv *nva, size_t nvlen) {
|
||||
size_t n = 0;
|
||||
|
|
|
@ -383,6 +383,8 @@ int main(int argc _U_, char *argv[] _U_) {
|
|||
!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, "hd_deflate_hd_vec",
|
||||
test_nghttp2_hd_deflate_hd_vec) ||
|
||||
!CU_add_test(pSuite, "hd_decode_length", test_nghttp2_hd_decode_length) ||
|
||||
!CU_add_test(pSuite, "hd_huff_encode", test_nghttp2_hd_huff_encode) ||
|
||||
!CU_add_test(pSuite, "adjust_local_window_size",
|
||||
|
|
|
@ -1265,6 +1265,57 @@ void test_nghttp2_hd_public_api(void) {
|
|||
nghttp2_hd_deflate_del(deflater);
|
||||
}
|
||||
|
||||
void test_nghttp2_hd_deflate_hd_vec(void) {
|
||||
nghttp2_hd_deflater *deflater;
|
||||
nghttp2_hd_inflater *inflater;
|
||||
nghttp2_nv nva[] = {
|
||||
MAKE_NV(":method", "PUT"), MAKE_NV(":scheme", "https"),
|
||||
MAKE_NV(":authority", "localhost:3000"),
|
||||
MAKE_NV(":path", "/usr/foo/alpha/bravo"),
|
||||
MAKE_NV("content-type", "image/png"),
|
||||
MAKE_NV("content-length", "1000000007"),
|
||||
};
|
||||
uint8_t buf[4096];
|
||||
ssize_t blocklen;
|
||||
nghttp2_mem *mem;
|
||||
uint8_t *bufsin[2];
|
||||
size_t buflens[2] = {0};
|
||||
size_t buflen;
|
||||
nghttp2_bufs bufs;
|
||||
nva_out out;
|
||||
|
||||
mem = nghttp2_mem_default();
|
||||
|
||||
nva_out_init(&out);
|
||||
|
||||
nghttp2_hd_deflate_new(&deflater, 4096);
|
||||
nghttp2_hd_inflate_new(&inflater);
|
||||
|
||||
buflen = nghttp2_hd_deflate_bound(deflater, nva, ARRLEN(nva));
|
||||
|
||||
bufsin[0] = &buf[0];
|
||||
bufsin[1] = &buf[buflen / 2];
|
||||
|
||||
blocklen = nghttp2_hd_deflate_hd_vec(deflater, bufsin, ARRLEN(bufsin),
|
||||
buflen / 2, buflens, nva, ARRLEN(nva));
|
||||
|
||||
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_deflate_del(deflater);
|
||||
nva_out_reset(&out, mem);
|
||||
}
|
||||
|
||||
static size_t encode_length(uint8_t *buf, uint64_t n, size_t prefix) {
|
||||
size_t k = (size_t)((1 << prefix) - 1);
|
||||
size_t len = 0;
|
||||
|
|
|
@ -47,6 +47,7 @@ void test_nghttp2_hd_deflate_inflate(void);
|
|||
void test_nghttp2_hd_no_index(void);
|
||||
void test_nghttp2_hd_deflate_bound(void);
|
||||
void test_nghttp2_hd_public_api(void);
|
||||
void test_nghttp2_hd_deflate_hd_vec(void);
|
||||
void test_nghttp2_hd_decode_length(void);
|
||||
void test_nghttp2_hd_huff_encode(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue