nghttp2_hd: Enlarge buffers used in inflation process dynamically
This commit is contained in:
parent
e14baf134c
commit
8915e91b17
110
lib/nghttp2_hd.c
110
lib/nghttp2_hd.c
|
@ -262,31 +262,11 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->emit_set = NULL;
|
|
||||||
context->buf_track = NULL;
|
|
||||||
|
|
||||||
if(role == NGHTTP2_HD_ROLE_INFLATE) {
|
|
||||||
context->emit_set = malloc(sizeof(nghttp2_hd_entry*)*
|
|
||||||
NGHTTP2_INITIAL_EMIT_SET_SIZE);
|
|
||||||
if(context->emit_set == NULL) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
memset(context->emit_set, 0, sizeof(nghttp2_hd_entry*)*
|
|
||||||
NGHTTP2_INITIAL_EMIT_SET_SIZE);
|
|
||||||
context->emit_set_capacity = NGHTTP2_INITIAL_EMIT_SET_SIZE;
|
|
||||||
|
|
||||||
context->buf_track = malloc(sizeof(uint8_t*)*
|
|
||||||
NGHTTP2_INITIAL_BUF_TRACK_SIZE);
|
|
||||||
if(context->buf_track == NULL) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
context->buf_track_capacity = NGHTTP2_INITIAL_BUF_TRACK_SIZE;
|
|
||||||
} else {
|
|
||||||
context->emit_set = NULL;
|
context->emit_set = NULL;
|
||||||
context->emit_set_capacity = 0;
|
context->emit_set_capacity = 0;
|
||||||
context->buf_track = NULL;
|
context->buf_track = NULL;
|
||||||
context->buf_track_capacity = 0;
|
context->buf_track_capacity = 0;
|
||||||
}
|
|
||||||
context->deflate_hd_table_bufsize_max = deflate_hd_table_bufsize_max;
|
context->deflate_hd_table_bufsize_max = deflate_hd_table_bufsize_max;
|
||||||
context->deflate_hd_table_bufsize = 0;
|
context->deflate_hd_table_bufsize = 0;
|
||||||
context->deflate_hd_tablelen = 0;
|
context->deflate_hd_tablelen = 0;
|
||||||
|
@ -294,11 +274,6 @@ static int nghttp2_hd_context_init(nghttp2_hd_context *context,
|
||||||
context->buf_tracklen = 0;
|
context->buf_tracklen = 0;
|
||||||
context->hd_table_bufsize = 0;
|
context->hd_table_bufsize = 0;
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
|
||||||
free(context->buf_track);
|
|
||||||
free(context->emit_set);
|
|
||||||
nghttp2_hd_ringbuf_free(&context->hd_table);
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -359,19 +334,63 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensures that buffer size is at least |reqmemb| * |size| bytes. The
|
||||||
|
* currnet buffer size is given in the |nmemb| * |size|. If the
|
||||||
|
* requested buffer size is strictly larger than |maxmemb| * |size|,
|
||||||
|
* returns NGHTTP2_ERR_HEADER_COMP. If the |nmemb| is 0, the |inimemb|
|
||||||
|
* is used as initial value and doubles it until it is greater than or
|
||||||
|
* equal to the requested buffer size.
|
||||||
|
*
|
||||||
|
* This function returns the new number of members after buffer
|
||||||
|
* expansion. If no expansion is required, |nmemb| is returned.
|
||||||
|
*/
|
||||||
|
static ssize_t ensure_buffer(void **buf_ptr,
|
||||||
|
size_t size,
|
||||||
|
size_t nmemb,
|
||||||
|
size_t reqmemb,
|
||||||
|
size_t maxmemb,
|
||||||
|
size_t inimemb)
|
||||||
|
{
|
||||||
|
size_t new_nmemb;
|
||||||
|
void *new_buf;
|
||||||
|
assert(inimemb >= 2);
|
||||||
|
if(nmemb >= reqmemb) {
|
||||||
|
return nmemb;
|
||||||
|
}
|
||||||
|
if(reqmemb > maxmemb) {
|
||||||
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
|
}
|
||||||
|
if(nmemb == 0) {
|
||||||
|
new_nmemb = inimemb;
|
||||||
|
} else {
|
||||||
|
new_nmemb = nmemb;
|
||||||
|
for(; new_nmemb < reqmemb; new_nmemb *= 2);
|
||||||
|
}
|
||||||
|
new_buf = realloc(*buf_ptr, new_nmemb * size);
|
||||||
|
if(new_buf == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
*buf_ptr = new_buf;
|
||||||
|
return new_nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
static int add_nva(nghttp2_nva_out *nva_out_ptr,
|
static int add_nva(nghttp2_nva_out *nva_out_ptr,
|
||||||
uint8_t *name, uint16_t namelen,
|
uint8_t *name, uint16_t namelen,
|
||||||
uint8_t *value, uint16_t valuelen)
|
uint8_t *value, uint16_t valuelen)
|
||||||
{
|
{
|
||||||
nghttp2_nv *nv;
|
nghttp2_nv *nv;
|
||||||
if(nva_out_ptr->nvacap == nva_out_ptr->nvlen) {
|
if(nva_out_ptr->nvacap == nva_out_ptr->nvlen) {
|
||||||
size_t newcap = nva_out_ptr->nvacap == 0 ? 16 : nva_out_ptr->nvacap * 2;
|
ssize_t new_cap = ensure_buffer((void**)&nva_out_ptr->nva,
|
||||||
nghttp2_nv *new_nva = realloc(nva_out_ptr->nva, sizeof(nghttp2_nv)*newcap);
|
sizeof(nghttp2_nv),
|
||||||
if(new_nva == NULL) {
|
nva_out_ptr->nvacap,
|
||||||
return NGHTTP2_ERR_NOMEM;
|
nva_out_ptr->nvlen + 1,
|
||||||
|
NGHTTP2_MAX_NVA_LENGTH,
|
||||||
|
NGHTTP2_INITIAL_NVA_LENGTH);
|
||||||
|
if(new_cap == -1) {
|
||||||
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
nva_out_ptr->nva = new_nva;
|
nva_out_ptr->nvacap = new_cap;
|
||||||
nva_out_ptr->nvacap = newcap;
|
|
||||||
}
|
}
|
||||||
nv = &nva_out_ptr->nva[nva_out_ptr->nvlen++];
|
nv = &nva_out_ptr->nva[nva_out_ptr->nvlen++];
|
||||||
nv->name = name;
|
nv->name = name;
|
||||||
|
@ -384,8 +403,17 @@ static int add_nva(nghttp2_nva_out *nva_out_ptr,
|
||||||
static int track_decode_buf(nghttp2_hd_context *context, uint8_t *buf)
|
static int track_decode_buf(nghttp2_hd_context *context, uint8_t *buf)
|
||||||
{
|
{
|
||||||
if(context->buf_tracklen == context->buf_track_capacity) {
|
if(context->buf_tracklen == context->buf_track_capacity) {
|
||||||
|
ssize_t new_cap = ensure_buffer((void**)&context->buf_track,
|
||||||
|
sizeof(uint8_t*),
|
||||||
|
context->buf_track_capacity,
|
||||||
|
context->buf_tracklen + 1,
|
||||||
|
NGHTTP2_MAX_BUF_TRACK_LENGTH,
|
||||||
|
NGHTTP2_INITIAL_BUF_TRACK_LENGTH);
|
||||||
|
if(new_cap == -1) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
|
context->buf_track_capacity = new_cap;
|
||||||
|
}
|
||||||
context->buf_track[context->buf_tracklen++] = buf;
|
context->buf_track[context->buf_tracklen++] = buf;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -394,8 +422,17 @@ static int track_decode_buf2(nghttp2_hd_context *context,
|
||||||
uint8_t *buf1, uint8_t *buf2)
|
uint8_t *buf1, uint8_t *buf2)
|
||||||
{
|
{
|
||||||
if(context->buf_tracklen + 2 > context->buf_track_capacity) {
|
if(context->buf_tracklen + 2 > context->buf_track_capacity) {
|
||||||
|
ssize_t new_cap = ensure_buffer((void**)&context->buf_track,
|
||||||
|
sizeof(uint8_t*),
|
||||||
|
context->buf_track_capacity,
|
||||||
|
context->buf_tracklen + 2,
|
||||||
|
NGHTTP2_MAX_BUF_TRACK_LENGTH,
|
||||||
|
NGHTTP2_INITIAL_BUF_TRACK_LENGTH);
|
||||||
|
if(new_cap == -1) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
|
context->buf_track_capacity = new_cap;
|
||||||
|
}
|
||||||
context->buf_track[context->buf_tracklen++] = buf1;
|
context->buf_track[context->buf_tracklen++] = buf1;
|
||||||
context->buf_track[context->buf_tracklen++] = buf2;
|
context->buf_track[context->buf_tracklen++] = buf2;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -404,8 +441,17 @@ static int track_decode_buf2(nghttp2_hd_context *context,
|
||||||
static int add_emit_set(nghttp2_hd_context *context, nghttp2_hd_entry *ent)
|
static int add_emit_set(nghttp2_hd_context *context, nghttp2_hd_entry *ent)
|
||||||
{
|
{
|
||||||
if(context->emit_setlen == context->emit_set_capacity) {
|
if(context->emit_setlen == context->emit_set_capacity) {
|
||||||
|
ssize_t new_cap = ensure_buffer((void**)&context->emit_set,
|
||||||
|
sizeof(nghttp2_hd_entry*),
|
||||||
|
context->emit_set_capacity,
|
||||||
|
context->emit_setlen + 1,
|
||||||
|
NGHTTP2_MAX_EMIT_SET_LENGTH,
|
||||||
|
NGHTTP2_INITIAL_EMIT_SET_LENGTH);
|
||||||
|
if(new_cap == -1) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
|
context->emit_set_capacity = new_cap;
|
||||||
|
}
|
||||||
context->emit_set[context->emit_setlen++] = ent;
|
context->emit_set[context->emit_setlen++] = ent;
|
||||||
++ent->ref;
|
++ent->ref;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -31,8 +31,14 @@
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#define NGHTTP2_INITIAL_EMIT_SET_SIZE 128
|
#define NGHTTP2_MAX_EMIT_SET_LENGTH 256
|
||||||
#define NGHTTP2_INITIAL_BUF_TRACK_SIZE 128
|
#define NGHTTP2_INITIAL_EMIT_SET_LENGTH 32
|
||||||
|
|
||||||
|
#define NGHTTP2_MAX_BUF_TRACK_LENGTH 256
|
||||||
|
#define NGHTTP2_INITIAL_BUF_TRACK_LENGTH 32
|
||||||
|
|
||||||
|
#define NGHTTP2_MAX_NVA_LENGTH 256
|
||||||
|
#define NGHTTP2_INITIAL_NVA_LENGTH 32
|
||||||
|
|
||||||
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE (1 << 12)
|
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE (1 << 12)
|
||||||
#define NGHTTP2_HD_MAX_ENTRY_SIZE 3072
|
#define NGHTTP2_HD_MAX_ENTRY_SIZE 3072
|
||||||
|
|
Loading…
Reference in New Issue