deps: update nghttp2 to 1.69.0

PR-URL: https://github.com/nodejs/node/pull/62891
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Node.js GitHub Bot committed 2026-04-29 12:30:00 +00:00
1 parent 61db2609e3
commit 5320a1b96f
20 files changed
+4558 -4323

No files matched your search

+1 -1
View File
@@ -51,7 +51,7 @@ set(NGHTTP2_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(NGHTTP2_VERSION_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(NGHTTP2_PROJECT_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
set(NGHTTP2_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(NGHTTP2_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(NGHTTP2_CONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
set(NGHTTP2_NAMESPACE "${PROJECT_NAME}::")
set(NGHTTP2_VERSION ${PROJECT_VERSION})
+1 -1
View File
@@ -3252,7 +3252,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
* regenerated per second. When a suspicious activity is detected,
* some amount of tokens are consumed. If there is no token
* available, GOAWAY is sent to tear down the connection. |burst| and
* |rate| default to 1000 and 33 respectively.
* |rate| default to 10000 and 330 respectively.
*/
NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
uint64_t burst,
+2 -2
View File
@@ -29,7 +29,7 @@
* @macro
* Version number of the nghttp2 library release
*/
#define NGHTTP2_VERSION "1.68.0"
#define NGHTTP2_VERSION "1.69.0"
/**
* @macro
@@ -37,6 +37,6 @@
* release. This is a 24 bit number with 8 bits for major number, 8 bits
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
*/
#define NGHTTP2_VERSION_NUM 0x014400
#define NGHTTP2_VERSION_NUM 0x014500
#endif /* NGHTTP2VER_H */
+3 -1
View File
@@ -26,6 +26,8 @@
#include <string.h>
#include "nghttp2_helper.h"
static int select_alpn(const unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen,
const char *key, unsigned int keylen) {
@@ -41,7 +43,7 @@ static int select_alpn(const unsigned char **out, unsigned char *outlen,
}
#define NGHTTP2_HTTP_1_1_ALPN "\x8http/1.1"
#define NGHTTP2_HTTP_1_1_ALPN_LEN (sizeof(NGHTTP2_HTTP_1_1_ALPN) - 1)
#define NGHTTP2_HTTP_1_1_ALPN_LEN nghttp2_strlen_lit(NGHTTP2_HTTP_1_1_ALPN)
int nghttp2_select_next_protocol(unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen) {
+10
View File
@@ -750,6 +750,16 @@ void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
uint8_t *p;
altsvc = frame->payload;
if (payloadlen == 0) {
altsvc->origin = NULL;
altsvc->origin_len = 0;
altsvc->field_value = NULL;
altsvc->field_value_len = 0;
return;
}
p = payload;
altsvc->origin = p;
-3
View File
@@ -34,10 +34,7 @@
#include "nghttp2_buf.h"
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
/* The number of bytes of frame header. */
#define NGHTTP2_FRAME_HDLEN 9
+10 -7
View File
@@ -35,9 +35,10 @@
/* Make scalar initialization form of nghttp2_hd_entry */
#define MAKE_STATIC_ENT(N, V, T, H) \
{ \
{NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \
{NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \
{(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \
{NULL, NULL, (uint8_t *)(N), nghttp2_strlen_lit((N)), -1}, \
{NULL, NULL, (uint8_t *)(V), nghttp2_strlen_lit((V)), -1}, \
{(uint8_t *)(N), (uint8_t *)(V), nghttp2_strlen_lit((N)), \
nghttp2_strlen_lit((V)), 0}, \
T, \
H, \
}
@@ -2058,8 +2059,9 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF;
rv =
nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, mem);
rv = nghttp2_rcbuf_new(
&inflater->namercbuf,
nghttp2_huff_estimate_decode_length(inflater->left) + 1, mem);
} else {
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME;
rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem);
@@ -2143,8 +2145,9 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF;
rv =
nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem);
rv = nghttp2_rcbuf_new(
&inflater->valuercbuf,
nghttp2_huff_estimate_decode_length(inflater->left) + 1, mem);
} else {
inflater->state = NGHTTP2_HD_STATE_READ_VALUE;
+12 -11
View File
@@ -104,15 +104,15 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
}
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
ctx->fstate = 0;
ctx->flags = NGHTTP2_HUFF_ACCEPTED;
}
nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final) {
const uint8_t *end = src + srclen;
nghttp2_huff_decode node = {ctx->fstate, 0};
const nghttp2_huff_decode *t = &node;
nghttp2_huff_decode t = {ctx->fstate, ctx->flags, 0};
uint8_t c;
/* We use the decoding algorithm described in
@@ -121,20 +121,21 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
- https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
for (; src != end;) {
c = *src++;
t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
t = huff_decode_table[t.fstate][c >> 4];
if (t.flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t.sym;
}
t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
t = huff_decode_table[t.fstate][c & 0xf];
if (t.flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t.sym;
}
}
ctx->fstate = t->fstate;
ctx->fstate = t.fstate;
ctx->flags = t.flags;
if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) {
if (final && !(ctx->flags & NGHTTP2_HUFF_ACCEPTED)) {
return NGHTTP2_ERR_HEADER_COMP;
}
+12 -2
View File
@@ -34,9 +34,9 @@
typedef enum {
/* FSA accepts this state as the end of huffman encoding
sequence. */
NGHTTP2_HUFF_ACCEPTED = 1 << 14,
NGHTTP2_HUFF_ACCEPTED = 1,
/* This state emits symbol */
NGHTTP2_HUFF_SYM = 1 << 15,
NGHTTP2_HUFF_SYM = 1 << 1,
} nghttp2_huff_decode_flag;
typedef struct {
@@ -48,6 +48,7 @@ typedef struct {
a special node and it is a terminal state that means decoding
failed. */
uint16_t fstate;
uint8_t flags;
/* symbol if NGHTTP2_HUFF_SYM flag set */
uint8_t sym;
} nghttp2_huff_decode;
@@ -57,6 +58,7 @@ typedef nghttp2_huff_decode huff_decode_table_type[16];
typedef struct {
/* fstate is the current huffman decoding state. */
uint16_t fstate;
uint8_t flags;
} nghttp2_hd_huff_decode_context;
typedef struct {
@@ -69,4 +71,12 @@ typedef struct {
extern const nghttp2_huff_sym huff_sym_table[];
extern const nghttp2_huff_decode huff_decode_table[][16];
/*
* nghttp2_huff_estimate_decode_length returns the estimated decoded
* length of the huffman encoded string of length |len|.
*/
static inline size_t nghttp2_huff_estimate_decode_length(size_t len) {
return len * 8 / 5;
}
#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */
+4112 -4112
View File
File diff suppressed because it is too large. Load diff
+9 -1
View File
@@ -61,7 +61,15 @@ nghttp2_min_def(uint32, uint32_t)
nghttp2_min_def(uint64, uint64_t)
nghttp2_min_def(size, size_t)
#define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0)
/*
* nghttp2_strlen_lit returns the length of string literal |S|. This
* macro assumes |S| is NULL-terminated string literal. It must not
* be used with pointers.
*/
#define nghttp2_strlen_lit(S) (sizeof(S) - 1)
#define lstreq(A, B, N) \
(nghttp2_strlen_lit((A)) == (N) && memcmp((A), (B), (N)) == 0)
#define nghttp2_struct_of(ptr, type, member) \
((type *)(void *)((char *)(ptr) - offsetof(type, member)))
+2 -1
View File
@@ -49,7 +49,8 @@ static int memieq(const void *a, const void *b, size_t n) {
return 1;
}
#define lstrieq(A, B, N) ((sizeof((A)) - 1) == (N) && memieq((A), (B), (N)))
#define lstrieq(A, B, N) \
(nghttp2_strlen_lit((A)) == (N) && memieq((A), (B), (N)))
static int64_t parse_uint(const uint8_t *s, size_t len) {
int64_t n = 0;
+5 -2
View File
@@ -39,7 +39,6 @@ typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
/* Internal error code. They must be in the range [-499, -100],
inclusive. */
typedef enum {
NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
NGHTTP2_ERR_IGN_PAYLOAD = -104,
/*
@@ -52,7 +51,11 @@ typedef enum {
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
* nghttp2_on_invalid_header_callback.
*/
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106,
/*
* Cancel pushed stream.
*/
NGHTTP2_ERR_PUSH_CANCEL = -107,
} nghttp2_internal_error;
#endif /* !defined(NGHTTP2_INT_H) */
+158 -109
View File
@@ -33,12 +33,11 @@
#define NGHTTP2_INITIAL_HASHBITS 4
void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem) {
map->mem = mem;
map->hashbits = 0;
map->table = NULL;
map->seed = seed;
map->size = 0;
void nghttp2_map_init(nghttp2_map *map, uint64_t seed, nghttp2_mem *mem) {
*map = (nghttp2_map){
.mem = mem,
.seed = seed,
};
}
void nghttp2_map_free(nghttp2_map *map) {
@@ -46,30 +45,27 @@ void nghttp2_map_free(nghttp2_map *map) {
return;
}
nghttp2_mem_free(map->mem, map->table);
nghttp2_mem_free(map->mem, map->keys);
}
int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
int rv;
size_t i;
nghttp2_map_bucket *bkt;
size_t tablelen;
if (map->size == 0) {
return 0;
}
tablelen = 1u << map->hashbits;
tablelen = (size_t)1 << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
if (map->psl[i] == 0) {
continue;
}
rv = func(bkt->data, ptr);
rv = func(map->data[i], ptr);
if (rv != 0) {
return rv;
}
@@ -78,175 +74,230 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
return 0;
}
static size_t map_hash(const nghttp2_map *map, nghttp2_map_key_type key) {
/* hasher from
https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
We do not perform finalization here because we use top bits
anyway. */
uint32_t h = ((uint32_t)key + map->seed) * 0x93d765dd;
return (size_t)((h * 2654435769u) >> (32 - map->hashbits));
}
/* Hasher from
https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
to maximize the output's sensitivity to all input bits. */
#define NGHTTP2_MAP_HASHER 0xf1357aea2e62a9c5ull
/* 64-bit Fibonacci hashing constant, Golden Ratio constant, to get
the high bits with the good distribution. */
#define NGHTTP2_MAP_FIBO 0x9e3779b97f4a7c15ull
static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) {
nghttp2_map_bucket c = *a;
static size_t map_index(const nghttp2_map *map, nghttp2_map_key_type key32) {
uint64_t key = (uint64_t)key32;
*a = *b;
*b = c;
key += map->seed;
key *= NGHTTP2_MAP_HASHER;
return (size_t)((key * NGHTTP2_MAP_FIBO) >> (64 - map->hashbits));
}
#ifndef WIN32
void nghttp2_map_print_distance(const nghttp2_map *map) {
size_t i;
size_t idx;
nghttp2_map_bucket *bkt;
size_t tablelen;
if (map->size == 0) {
return;
}
tablelen = 1u << map->hashbits;
tablelen = (size_t)1 << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
if (map->psl[i] == 0) {
fprintf(stderr, "@%zu <EMPTY>\n", i);
continue;
}
idx = map_hash(map, bkt->key);
fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i,
map_hash(map, bkt->key), bkt->key, idx, bkt->psl);
idx = map_index(map, map->keys[i]);
fprintf(stderr, "@%zu key=%d base=%zu distance=%u\n", i, map->keys[i], idx,
map->psl[i] - 1);
}
}
#endif /* !defined(WIN32) */
static int map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
size_t idx = map_hash(map, key);
nghttp2_map_bucket b = {
.key = key,
.data = data,
};
nghttp2_map_bucket *bkt;
size_t mask = (1u << map->hashbits) - 1;
static void map_set_entry(nghttp2_map *map, size_t idx,
nghttp2_map_key_type key, void *data, size_t psl) {
map->keys[idx] = key;
map->data[idx] = data;
map->psl[idx] = (uint8_t)psl;
}
#define NGHTTP2_SWAP(TYPE, A, B) \
do { \
TYPE t = (TYPE) * (A); \
\
*(A) = *(B); \
*(B) = t; \
} while (0)
/*
* map_insert inserts |key| and |data| to |map|, and returns the index
* where the pair is stored if it succeeds. Otherwise, it returns one
* of the following negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The another data associated to |key| is already present.
*/
static nghttp2_ssize map_insert(nghttp2_map *map, nghttp2_map_key_type key,
void *data) {
size_t idx = map_index(map, key);
size_t mask = ((size_t)1 << map->hashbits) - 1;
size_t psl = 1;
size_t kpsl;
for (;;) {
bkt = &map->table[idx];
kpsl = map->psl[idx];
if (bkt->data == NULL) {
*bkt = b;
if (kpsl == 0) {
map_set_entry(map, idx, key, data, psl);
++map->size;
return 0;
return (nghttp2_ssize)idx;
}
if (b.psl > bkt->psl) {
map_bucket_swap(bkt, &b);
} else if (bkt->key == key) {
/* TODO This check is just a waste after first swap or if this
function is called from map_resize. That said, there is no
difference with or without this conditional in performance
wise. */
if (psl > kpsl) {
NGHTTP2_SWAP(nghttp2_map_key_type, &key, &map->keys[idx]);
NGHTTP2_SWAP(void *, &data, &map->data[idx]);
NGHTTP2_SWAP(uint8_t, &psl, &map->psl[idx]);
} else if (map->keys[idx] == key) {
/* This check ensures that no duplicate keys are inserted. But
it is just a waste after first swap or if this function is
called from map_resize. That said, there is no difference
with or without this conditional in performance wise. */
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
++b.psl;
++psl;
idx = (idx + 1) & mask;
}
}
/* NGHTTP2_MAP_MAX_HASHBITS is the maximum number of bits used for
hash table. The theoretical limit of the maximum number of keys
that can be stored is 1 << NGHTTP2_MAP_MAX_HASHBITS. */
#define NGHTTP2_MAP_MAX_HASHBITS (sizeof(size_t) * 8 - 1)
static int map_resize(nghttp2_map *map, size_t new_hashbits) {
size_t i;
nghttp2_map_bucket *bkt;
size_t tablelen;
int rv;
nghttp2_ssize idx;
nghttp2_map new_map = {
.table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
sizeof(nghttp2_map_bucket)),
.mem = map->mem,
.seed = map->seed,
.hashbits = new_hashbits,
};
(void)rv;
void *buf;
(void)idx;
if (new_map.table == NULL) {
if (new_hashbits > NGHTTP2_MAP_MAX_HASHBITS) {
return NGHTTP2_ERR_NOMEM;
}
tablelen = (size_t)1 << new_hashbits;
buf = nghttp2_mem_calloc(map->mem, tablelen,
sizeof(nghttp2_map_key_type) + sizeof(void *) +
sizeof(uint8_t));
if (buf == NULL) {
return NGHTTP2_ERR_NOMEM;
}
new_map.keys = buf;
new_map.data =
(void *)((uint8_t *)new_map.keys + tablelen * sizeof(nghttp2_map_key_type));
new_map.psl = (uint8_t *)new_map.data + tablelen * sizeof(void *);
if (map->size) {
tablelen = 1u << map->hashbits;
tablelen = (size_t)1 << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
if (map->psl[i] == 0) {
continue;
}
rv = map_insert(&new_map, bkt->key, bkt->data);
idx = map_insert(&new_map, map->keys[i], map->data[i]);
assert(0 == rv);
/* map_insert must not fail because all keys are unique during
resize. */
assert(idx >= 0);
}
}
nghttp2_mem_free(map->mem, map->table);
map->table = new_map.table;
nghttp2_mem_free(map->mem, map->keys);
map->keys = new_map.keys;
map->data = new_map.data;
map->psl = new_map.psl;
map->hashbits = new_hashbits;
return 0;
}
/* NGHTTP2_MAX_PSL_RESIZE_THRESH is the maximum psl threshold. If
reached, resize the table. */
#define NGHTTP2_MAX_PSL_RESIZE_THRESH 128
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
int rv;
size_t tablelen;
nghttp2_ssize idx;
assert(data);
/* Load factor is 7/8 */
/* Under the very initial condition, that is map->size == 0 and
map->hashbits == 0, 8 > 7 still holds nicely. */
if ((map->size + 1) * 8 > (1u << map->hashbits) * 7) {
if (map->hashbits) {
rv = map_resize(map, map->hashbits + 1);
if (rv != 0) {
return rv;
}
} else {
rv = map_resize(map, NGHTTP2_INITIAL_HASHBITS);
if (rv != 0) {
return rv;
}
/* tablelen is incorrect if map->hashbits == 0 which leads to
tablelen = 1, but it is only used to check the load factor, and
it works in this special case. */
tablelen = (size_t)1 << map->hashbits;
/* Load factor is 7 / 8. Because tablelen is power of 2, (tablelen
- (tablelen >> 3)) computes tablelen * 7 / 8. */
if (map->size + 1 >= (tablelen - (tablelen >> 3))) {
rv = map_resize(map, map->hashbits ? map->hashbits + 1
: NGHTTP2_INITIAL_HASHBITS);
if (rv != 0) {
return rv;
}
idx = map_insert(map, key, data);
if (idx < 0) {
return (int)idx;
}
return 0;
}
rv = map_insert(map, key, data);
if (rv != 0) {
return rv;
idx = map_insert(map, key, data);
if (idx < 0) {
return (int)idx;
}
return 0;
/* Resize if psl reaches really large value which is almost
improbable, but just in case. */
if (map->psl[idx] - 1 < NGHTTP2_MAX_PSL_RESIZE_THRESH) {
return 0;
}
return map_resize(map, map->hashbits + 1);
}
void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
size_t idx;
nghttp2_map_bucket *bkt;
size_t psl = 0;
size_t psl = 1;
size_t mask;
if (map->size == 0) {
return NULL;
}
idx = map_hash(map, key);
mask = (1u << map->hashbits) - 1;
idx = map_index(map, key);
mask = ((size_t)1 << map->hashbits) - 1;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL || psl > bkt->psl) {
if (psl > map->psl[idx]) {
return NULL;
}
if (bkt->key == key) {
return bkt->data;
if (map->keys[idx] == key) {
return map->data[idx];
}
++psl;
@@ -256,38 +307,36 @@ void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
size_t idx;
nghttp2_map_bucket *b, *bkt;
size_t psl = 0;
size_t dest;
size_t psl = 1, kpsl;
size_t mask;
if (map->size == 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
idx = map_hash(map, key);
mask = (1u << map->hashbits) - 1;
idx = map_index(map, key);
mask = ((size_t)1 << map->hashbits) - 1;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL || psl > bkt->psl) {
if (psl > map->psl[idx]) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (bkt->key == key) {
b = bkt;
if (map->keys[idx] == key) {
dest = idx;
idx = (idx + 1) & mask;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL || bkt->psl == 0) {
b->data = NULL;
kpsl = map->psl[idx];
if (kpsl <= 1) {
map->psl[dest] = 0;
break;
}
--bkt->psl;
*b = *bkt;
b = bkt;
map_set_entry(map, dest, map->keys[idx], map->data[idx], kpsl - 1);
dest = idx;
idx = (idx + 1) & mask;
}
@@ -307,7 +356,7 @@ void nghttp2_map_clear(nghttp2_map *map) {
return;
}
memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits));
memset(map->psl, 0, sizeof(*map->psl) * ((size_t)1 << map->hashbits));
map->size = 0;
}
+8 -9
View File
@@ -38,16 +38,15 @@
typedef int32_t nghttp2_map_key_type;
typedef struct nghttp2_map_bucket {
uint32_t psl;
nghttp2_map_key_type key;
void *data;
} nghttp2_map_bucket;
typedef struct nghttp2_map {
nghttp2_map_bucket *table;
nghttp2_map_key_type *keys;
void **data;
/* psl is the Probe Sequence Length. 0 has special meaning that the
element is not stored at i-th position if psl[i] == 0. Because
of this, the actual psl value is psl[i] - 1 if psl[i] > 0. */
uint8_t *psl;
nghttp2_mem *mem;
uint32_t seed;
uint64_t seed;
size_t size;
size_t hashbits;
} nghttp2_map;
@@ -55,7 +54,7 @@ typedef struct nghttp2_map {
/*
* nghttp2_map_init initializes the map |map|.
*/
void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem);
void nghttp2_map_init(nghttp2_map *map, uint64_t seed, nghttp2_mem *mem);
/*
* nghttp2_map_free deallocates any resources allocated for |map|.
+12
View File
@@ -53,6 +53,18 @@ nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw,
return dpw;
}
int nghttp2_data_provider_wrap_contains_read_callback(
const nghttp2_data_provider_wrap *dpw) {
switch (dpw->version) {
case NGHTTP2_DATA_PROVIDER_V1:
return dpw->data_prd.v1.read_callback != NULL;
case NGHTTP2_DATA_PROVIDER_V2:
return dpw->data_prd.v2.read_callback != NULL;
default:
return 0;
}
}
void nghttp2_outbound_item_init(nghttp2_outbound_item *item) {
item->cycle = 0;
item->qnext = NULL;
+12 -4
View File
@@ -39,10 +39,6 @@
typedef struct nghttp2_data_provider_wrap {
int version;
union {
struct {
nghttp2_data_source source;
void *read_callback;
};
nghttp2_data_provider v1;
nghttp2_data_provider2 v2;
} data_prd;
@@ -56,6 +52,11 @@ nghttp2_data_provider_wrap *
nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw,
const nghttp2_data_provider2 *data_prd);
/* nghttp2_data_provider_wrap_contains_read_callback returns nonzero
if |dpw| contains read_callback in either version. */
int nghttp2_data_provider_wrap_contains_read_callback(
const nghttp2_data_provider_wrap *dpw);
/* struct used for HEADERS and PUSH_PROMISE frame */
typedef struct {
nghttp2_data_provider_wrap dpw;
@@ -110,6 +111,12 @@ typedef struct {
uint8_t flags;
} nghttp2_goaway_aux_data;
typedef struct {
/* nonzero if RST_STREAM should be sent even if stream is not
found. */
uint8_t continue_without_stream;
} nghttp2_rst_stream_aux_data;
/* struct used for extension frame */
typedef struct {
/* nonzero if this extension frame is serialized by library
@@ -122,6 +129,7 @@ typedef union {
nghttp2_data_aux_data data;
nghttp2_headers_aux_data headers;
nghttp2_goaway_aux_data goaway;
nghttp2_rst_stream_aux_data rst_stream;
nghttp2_ext_aux_data ext;
} nghttp2_aux_data;
+184 -52
View File
@@ -438,7 +438,7 @@ static int session_new(nghttp2_session **session_ptr,
size_t max_deflate_dynamic_table_size =
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
size_t i;
uint32_t map_seed;
uint64_t map_seed;
if (mem == NULL) {
mem = nghttp2_mem_default();
@@ -1051,7 +1051,6 @@ int nghttp2_session_add_item(nghttp2_session *session,
nghttp2_outbound_queue_push(&session->ob_syn, item);
item->queued = 1;
return 0;
;
}
nghttp2_outbound_queue_push(&session->ob_reg, item);
@@ -1189,6 +1188,10 @@ int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
frame = &item->frame;
nghttp2_frame_rst_stream_init(&frame->rst_stream, stream_id, error_code);
item->aux_data.rst_stream.continue_without_stream =
(uint8_t)(continue_without_stream != 0);
rv = nghttp2_session_add_item(session, item);
if (rv != 0) {
nghttp2_frame_rst_stream_free(&frame->rst_stream);
@@ -2141,6 +2144,12 @@ static int session_prep_frame(nghttp2_session *session,
if (session_is_closing(session)) {
return NGHTTP2_ERR_SESSION_CLOSING;
}
if (!item->aux_data.rst_stream.continue_without_stream &&
!nghttp2_session_get_stream(session, frame->rst_stream.hd.stream_id)) {
return NGHTTP2_ERR_STREAM_CLOSED;
}
nghttp2_frame_pack_rst_stream(&session->aob.framebufs, &frame->rst_stream);
return 0;
case NGHTTP2_SETTINGS: {
@@ -2584,7 +2593,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
}
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data = &item->aux_data.headers;
if (aux_data->dpw.data_prd.read_callback) {
if (nghttp2_data_provider_wrap_contains_read_callback(&aux_data->dpw)) {
/* nghttp2_submit_data_shared() makes a copy of
aux_data->dpw */
rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM,
@@ -2615,7 +2624,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
}
/* We assume aux_data is a pointer to nghttp2_headers_aux_data */
aux_data = &item->aux_data.headers;
if (aux_data->dpw.data_prd.read_callback) {
if (nghttp2_data_provider_wrap_contains_read_callback(&aux_data->dpw)) {
rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM,
frame->hd.stream_id, &aux_data->dpw);
if (nghttp2_is_fatal(rv)) {
@@ -2795,7 +2804,10 @@ static int session_call_send_data(nghttp2_session *session,
aux_data = &item->aux_data.data;
rv = session->callbacks.send_data_callback(session, frame, buf->pos, length,
&aux_data->dpw.data_prd.source,
/* This is fine because
of Common Initial
Sequence rule. */
&aux_data->dpw.data_prd.v2.source,
session->user_data);
switch (rv) {
@@ -2853,8 +2865,12 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session,
nghttp2_frame *frame = &item->frame;
/* The library is responsible for the transmission of
WINDOW_UPDATE frame, so we don't call error callback for
it. */
it. As for RST_STREAM, if it is not sent due to missing
stream, we also do not call error callback because it may
cause a lot of noises.*/
if (frame->hd.type != NGHTTP2_WINDOW_UPDATE &&
(frame->hd.type != NGHTTP2_RST_STREAM ||
rv != NGHTTP2_ERR_STREAM_CLOSED) &&
session->callbacks.on_frame_not_send_callback(
session, frame, rv, session->user_data) != 0) {
nghttp2_outbound_item_free(item, mem);
@@ -3272,7 +3288,9 @@ static int session_call_on_invalid_header(nghttp2_session *session,
session, frame, nv->name->base, nv->name->len, nv->value->base,
nv->value->len, nv->flags, session->user_data);
} else {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
/* If both callbacks are not set, the invalid field nv is
ignored. */
return 0;
}
if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -3357,6 +3375,10 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) {
case NGHTTP2_ERR_HTTP_HEADER:
case NGHTTP2_ERR_HTTP_MESSAGING:
return NGHTTP2_PROTOCOL_ERROR;
case NGHTTP2_ERR_INTERNAL:
return NGHTTP2_INTERNAL_ERROR;
case NGHTTP2_ERR_PUSH_CANCEL:
return NGHTTP2_CANCEL;
default:
return NGHTTP2_INTERNAL_ERROR;
}
@@ -3408,7 +3430,7 @@ static int session_handle_invalid_stream2(nghttp2_session *session,
if (rv != 0) {
return rv;
}
if (session->callbacks.on_invalid_frame_recv_callback) {
if (frame && session->callbacks.on_invalid_frame_recv_callback) {
if (session->callbacks.on_invalid_frame_recv_callback(
session, frame, lib_error_code, session->user_data) != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -3495,6 +3517,7 @@ static int session_inflate_handle_invalid_connection(nghttp2_session *session,
static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
size_t *readlen_ptr, uint8_t *in, size_t inlen,
int final, int call_header_cb) {
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_ssize proclen;
int rv;
int inflate_flags;
@@ -3563,7 +3586,29 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
rv2 = session_call_on_invalid_header(session, frame, &nv);
if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = NGHTTP2_ERR_HTTP_HEADER;
DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base);
rv = session_call_error_callback(
session, NGHTTP2_ERR_HTTP_HEADER,
"Invalid HTTP header field was received: frame type: "
"%u, stream: %d, name: [%.*s], value: [%.*s]",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = session_handle_invalid_stream2(
session, subject_stream->stream_id, frame,
NGHTTP2_ERR_HTTP_HEADER);
if (nghttp2_is_fatal(rv)) {
return rv;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
} else {
if (rv2 != 0) {
return rv2;
@@ -3609,6 +3654,16 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return 0;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
}
@@ -3678,6 +3733,7 @@ static int session_end_stream_headers_received(nghttp2_session *session,
static int session_after_header_block_received(nghttp2_session *session) {
int rv = 0;
nghttp2_frame *frame = &session->iframe.frame;
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_stream *stream;
/* We don't call on_frame_recv_callback if stream has been closed
@@ -3736,12 +3792,22 @@ static int session_after_header_block_received(nghttp2_session *session) {
return rv;
}
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return 0;
}
if (frame->hd.type == NGHTTP2_HEADERS &&
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
/* Don't call nghttp2_session_close_stream_if_shut_rdwr
because RST_STREAM has been submitted. */
}
return 0;
}
}
@@ -4078,8 +4144,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
rv = nghttp2_stream_update_remote_initial_window_size(
stream, arg->new_window_size, arg->old_window_size);
if (rv != 0) {
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
return NGHTTP2_ERR_FLOW_CONTROL;
}
/* If window size gets positive, push deferred DATA frame to
@@ -4105,6 +4170,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FLOW_CONTROL
* Window size gets out of range.
*/
static int
session_update_remote_initial_window_size(nghttp2_session *session,
@@ -4128,8 +4195,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
rv = nghttp2_stream_update_local_initial_window_size(
stream, arg->new_window_size, arg->old_window_size);
if (rv != 0) {
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
return NGHTTP2_ERR_FLOW_CONTROL;
}
if (stream->window_update_queued) {
@@ -4163,6 +4229,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FLOW_CONTROL
* Window size gets out of range.
*/
static int
session_update_local_initial_window_size(nghttp2_session *session,
@@ -4549,9 +4617,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
session->max_incoming_reserved_streams) {
/* Currently, client does not retain closed stream, so we don't
check NGHTTP2_SHUT_RD condition here. */
rv = nghttp2_session_add_rst_stream(
session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL);
rv = session_handle_invalid_stream2(session,
frame->push_promise.promised_stream_id,
NULL, NGHTTP2_ERR_PUSH_CANCEL);
if (rv != 0) {
return rv;
}
@@ -4708,8 +4776,9 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
}
if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
stream->remote_window_size) {
return session_handle_invalid_stream(session, frame,
NGHTTP2_ERR_FLOW_CONTROL);
return session_handle_invalid_connection(
session, frame, NGHTTP2_ERR_FLOW_CONTROL,
"WINDOW_UPDATE: window size overflow");
}
stream->remote_window_size += frame->window_update.window_size_increment;
@@ -4925,6 +4994,7 @@ int nghttp2_session_on_data_received(nghttp2_session *session,
nghttp2_frame *frame) {
int rv = 0;
nghttp2_stream *stream;
nghttp2_inbound_frame *iframe = &session->iframe;
/* We don't call on_frame_recv_callback if stream has been closed
already or being closed. */
@@ -4939,15 +5009,26 @@ int nghttp2_session_on_data_received(nghttp2_session *session,
if (session_enforce_http_messaging(session) &&
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
if (nghttp2_http_on_remote_end_stream(stream) != 0) {
rv = nghttp2_session_add_rst_stream(session, stream->stream_id,
NGHTTP2_PROTOCOL_ERROR);
rv = session_handle_invalid_stream2(session, stream->stream_id, frame,
NGHTTP2_ERR_HTTP_MESSAGING);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return 0;
}
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
/* Don't call nghttp2_session_close_stream_if_shut_rdwr because
RST_STREAM has been submitted. */
return 0;
}
}
@@ -5006,8 +5087,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
stream->local_window_size);
if (rv != 0) {
return nghttp2_session_add_rst_stream(session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
return nghttp2_session_terminate_session(session,
NGHTTP2_FLOW_CONTROL_ERROR);
}
/* We don't have to send WINDOW_UPDATE if the data received is the
last chunk in the incoming stream. */
@@ -5469,6 +5550,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
busy = 1;
rv = session_on_data_received_fail_fast(session);
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
@@ -5476,23 +5561,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
DEBUGF("recv: DATA not allowed stream_id=%d\n",
iframe->frame.hd.stream_id);
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
iframe->state = NGHTTP2_IB_IGN_DATA;
break;
}
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
if (rv < 0) {
rv = nghttp2_session_terminate_session_with_reason(
@@ -5576,6 +5648,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
on_begin_frame_called = 1;
rv = session_process_headers_frame(session);
@@ -5590,8 +5666,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6044,6 +6120,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
}
@@ -6107,8 +6187,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6191,9 +6271,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.push_promise.promised_stream_id,
NGHTTP2_INTERNAL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.push_promise.promised_stream_id, NULL,
NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6296,6 +6376,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
break;
@@ -6371,12 +6455,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
iframe->payloadleft -= hd_proclen;
/* Use promised stream ID for PUSH_PROMISE */
rv = nghttp2_session_add_rst_stream(
rv = session_handle_invalid_stream2(
session,
iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
? iframe->frame.push_promise.promised_stream_id
: iframe->frame.hd.stream_id,
NGHTTP2_INTERNAL_ERROR);
NULL, NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6423,6 +6507,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
session_inbound_frame_reset(session);
@@ -6598,6 +6686,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
} else {
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
}
@@ -6648,6 +6740,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
busy = 1;
@@ -6720,6 +6816,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
data_readlen =
inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen);
@@ -6763,13 +6863,25 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
}
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.hd.stream_id, &iframe->frame,
NGHTTP2_ERR_PROTO);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_DATA;
break;
}
}
@@ -6777,13 +6889,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
rv = session->callbacks.on_data_chunk_recv_callback(
session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
in - readlen, (size_t)data_readlen, session->user_data);
if (rv == NGHTTP2_ERR_PAUSE) {
return (nghttp2_ssize)(in - first);
}
if (nghttp2_is_fatal(rv)) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
if (rv == NGHTTP2_ERR_PAUSE) {
return (nghttp2_ssize)(in - first);
}
}
}
}
@@ -6797,6 +6913,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
break;
@@ -6863,6 +6983,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
if (rv != 0) {
busy = 1;
@@ -6881,6 +7005,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
break;
@@ -6909,6 +7037,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
break;
@@ -7372,13 +7504,13 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
case NGHTTP2_DATA_PROVIDER_V1:
payloadlen = (nghttp2_ssize)aux_data->dpw.data_prd.v1.read_callback(
session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
&aux_data->dpw.data_prd.source, session->user_data);
&aux_data->dpw.data_prd.v1.source, session->user_data);
break;
case NGHTTP2_DATA_PROVIDER_V2:
payloadlen = aux_data->dpw.data_prd.v2.read_callback(
session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
&aux_data->dpw.data_prd.source, session->user_data);
&aux_data->dpw.data_prd.v2.source, session->user_data);
break;
default:
+2 -2
View File
@@ -107,8 +107,8 @@ typedef struct {
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
/* The default values for glitch rate limiter. */
#define NGHTTP2_DEFAULT_GLITCH_BURST 1000
#define NGHTTP2_DEFAULT_GLITCH_RATE 33
#define NGHTTP2_DEFAULT_GLITCH_BURST 10000
#define NGHTTP2_DEFAULT_GLITCH_RATE 330
/* The default max number of CONTINUATION frames following an incoming
HEADER frame. */
+3 -3
View File
@@ -57,7 +57,7 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
nghttp2_outbound_item_init(item);
if (dpw != NULL && dpw->data_prd.read_callback != NULL) {
if (dpw != NULL && nghttp2_data_provider_wrap_contains_read_callback(dpw)) {
item->aux_data.headers.dpw = *dpw;
}
@@ -649,7 +649,7 @@ fail_item_malloc:
static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) {
uint8_t flags = NGHTTP2_FLAG_NONE;
if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
if (dpw == NULL || !nghttp2_data_provider_wrap_contains_read_callback(dpw)) {
flags |= NGHTTP2_FLAG_END_STREAM;
}
@@ -700,7 +700,7 @@ int32_t nghttp2_submit_request2(nghttp2_session *session,
static uint8_t set_response_flags(const nghttp2_data_provider_wrap *dpw) {
uint8_t flags = NGHTTP2_FLAG_NONE;
if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
if (dpw == NULL || !nghttp2_data_provider_wrap_contains_read_callback(dpw)) {
flags |= NGHTTP2_FLAG_END_STREAM;
}
return flags;