Allocate field name and value in the same buffer if indname to dynamic table
This commit is contained in:
parent
c41f413978
commit
02468b1ca1
|
@ -432,6 +432,24 @@ ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
|
||||||
return (ssize_t)len;
|
return (ssize_t)len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) {
|
||||||
|
size_t len;
|
||||||
|
nghttp2_buf_chain *chain;
|
||||||
|
nghttp2_buf *buf;
|
||||||
|
nghttp2_buf resbuf;
|
||||||
|
|
||||||
|
len = nghttp2_bufs_len(bufs);
|
||||||
|
|
||||||
|
nghttp2_buf_wrap_init(&resbuf, out, len);
|
||||||
|
|
||||||
|
for (chain = bufs->head; chain; chain = chain->next) {
|
||||||
|
buf = &chain->buf;
|
||||||
|
resbuf.last = nghttp2_cpymem(resbuf.last, buf->pos, nghttp2_buf_len(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
void nghttp2_bufs_reset(nghttp2_bufs *bufs) {
|
void nghttp2_bufs_reset(nghttp2_bufs *bufs) {
|
||||||
nghttp2_buf_chain *chain, *ci;
|
nghttp2_buf_chain *chain, *ci;
|
||||||
size_t k;
|
size_t k;
|
||||||
|
|
|
@ -324,6 +324,17 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
|
||||||
*/
|
*/
|
||||||
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
|
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copies all data stored in |bufs| to |out|. This function assumes
|
||||||
|
* that the buffer space pointed by |out| has at least
|
||||||
|
* nghttp2_bufs(bufs) bytes.
|
||||||
|
*
|
||||||
|
* The contents of |bufs| is left unchanged.
|
||||||
|
*
|
||||||
|
* This function returns the length of copied data.
|
||||||
|
*/
|
||||||
|
size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resets |bufs| and makes the buffers empty.
|
* Resets |bufs| and makes the buffers empty.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1730,6 +1730,42 @@ static int hd_inflate_remove_bufs(nghttp2_hd_inflater *inflater, nghttp2_nv *nv,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hd_inflate_remove_bufs_with_name(nghttp2_hd_inflater *inflater,
|
||||||
|
nghttp2_nv *nv,
|
||||||
|
nghttp2_hd_entry *ent_name) {
|
||||||
|
size_t rv;
|
||||||
|
size_t buflen;
|
||||||
|
uint8_t *buf;
|
||||||
|
nghttp2_mem *mem;
|
||||||
|
|
||||||
|
mem = inflater->ctx.mem;
|
||||||
|
|
||||||
|
/* Allocate buffer including name in ent_name, plus terminating
|
||||||
|
NULL. */
|
||||||
|
buflen = ent_name->nv.namelen + 1 + nghttp2_bufs_len(&inflater->nvbufs);
|
||||||
|
|
||||||
|
buf = nghttp2_mem_malloc(mem, buflen);
|
||||||
|
if (buf == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy including terminal NULL */
|
||||||
|
memcpy(buf, ent_name->nv.name, ent_name->nv.namelen + 1);
|
||||||
|
rv = nghttp2_bufs_remove_copy(&inflater->nvbufs,
|
||||||
|
buf + ent_name->nv.namelen + 1);
|
||||||
|
assert(ent_name->nv.namelen + 1 + rv == buflen);
|
||||||
|
|
||||||
|
nghttp2_bufs_reset(&inflater->nvbufs);
|
||||||
|
|
||||||
|
nv->name = buf;
|
||||||
|
nv->namelen = ent_name->nv.namelen;
|
||||||
|
|
||||||
|
nv->value = buf + nv->namelen + 1;
|
||||||
|
nv->valuelen = buflen - nv->namelen - 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finalize literal header representation - new name- reception. If
|
* Finalize literal header representation - new name- reception. If
|
||||||
* header is emitted, |*nv_out| is filled with that value and 0 is
|
* header is emitted, |*nv_out| is filled with that value and 0 is
|
||||||
|
@ -1813,11 +1849,6 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
|
||||||
|
|
||||||
mem = inflater->ctx.mem;
|
mem = inflater->ctx.mem;
|
||||||
|
|
||||||
rv = hd_inflate_remove_bufs(inflater, &nv, 1 /* value only */);
|
|
||||||
if (rv != 0) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inflater->no_index) {
|
if (inflater->no_index) {
|
||||||
nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
|
nv.flags = NGHTTP2_NV_FLAG_NO_INDEX;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1826,31 +1857,33 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
|
||||||
|
|
||||||
ent_name = nghttp2_hd_table_get(&inflater->ctx, inflater->index);
|
ent_name = nghttp2_hd_table_get(&inflater->ctx, inflater->index);
|
||||||
|
|
||||||
nv.name = ent_name->nv.name;
|
|
||||||
nv.namelen = ent_name->nv.namelen;
|
|
||||||
|
|
||||||
if (inflater->index_required) {
|
if (inflater->index_required) {
|
||||||
nghttp2_hd_entry *new_ent;
|
nghttp2_hd_entry *new_ent;
|
||||||
uint8_t ent_flags;
|
uint8_t ent_flags;
|
||||||
int static_name;
|
|
||||||
|
|
||||||
ent_flags = NGHTTP2_HD_FLAG_VALUE_ALLOC | NGHTTP2_HD_FLAG_VALUE_GIFT;
|
if (inflater->index < NGHTTP2_STATIC_TABLE_LENGTH) {
|
||||||
static_name = inflater->index < NGHTTP2_STATIC_TABLE_LENGTH;
|
/* We don't copy name in static table */
|
||||||
|
rv = hd_inflate_remove_bufs(inflater, &nv, 1 /* value only */);
|
||||||
|
if (rv != 0) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
nv.name = ent_name->nv.name;
|
||||||
|
nv.namelen = ent_name->nv.namelen;
|
||||||
|
|
||||||
if (!static_name) {
|
ent_flags = NGHTTP2_HD_FLAG_VALUE_ALLOC | NGHTTP2_HD_FLAG_VALUE_GIFT;
|
||||||
ent_flags |= NGHTTP2_HD_FLAG_NAME_ALLOC;
|
} else {
|
||||||
/* For entry in static table, we must not touch ref, because it
|
rv = hd_inflate_remove_bufs_with_name(inflater, &nv, ent_name);
|
||||||
is shared by threads */
|
if (rv != 0) {
|
||||||
++ent_name->ref;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
/* nv->name and nv->value are in the same buffer. */
|
||||||
|
ent_flags = NGHTTP2_HD_FLAG_NAME_ALLOC | NGHTTP2_HD_FLAG_NAME_GIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_ent = add_hd_table_incremental(&inflater->ctx, &nv, ent_name->token,
|
new_ent = add_hd_table_incremental(&inflater->ctx, &nv, ent_name->token,
|
||||||
ent_flags);
|
ent_flags);
|
||||||
|
|
||||||
if (!static_name && --ent_name->ref == 0) {
|
/* At this point, ent_name might be deleted. */
|
||||||
nghttp2_hd_entry_free(ent_name, mem);
|
|
||||||
nghttp2_mem_free(mem, ent_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_ent) {
|
if (new_ent) {
|
||||||
emit_indexed_header(nv_out, token_out, new_ent);
|
emit_indexed_header(nv_out, token_out, new_ent);
|
||||||
|
@ -1865,6 +1898,14 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
|
||||||
return NGHTTP2_ERR_NOMEM;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv = hd_inflate_remove_bufs(inflater, &nv, 1 /* value only */);
|
||||||
|
if (rv != 0) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
nv.name = ent_name->nv.name;
|
||||||
|
nv.namelen = ent_name->nv.namelen;
|
||||||
|
|
||||||
emit_literal_header(nv_out, token_out, &nv);
|
emit_literal_header(nv_out, token_out, &nv);
|
||||||
|
|
||||||
if (nv.value != inflater->nvbufs.head->buf.pos) {
|
if (nv.value != inflater->nvbufs.head->buf.pos) {
|
||||||
|
|
Loading…
Reference in New Issue