mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
deps: update nghttp3 to 1.11.0
Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: https://github.com/nodejs/node/pull/59249 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
dceb1fca40
commit
ebfc28a037
36 changed files with 1649 additions and 2300 deletions
117
deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h
vendored
117
deps/ngtcp2/nghttp3/lib/includes/nghttp3/nghttp3.h
vendored
|
@ -1116,11 +1116,43 @@ typedef struct nghttp3_qpack_encoder nghttp3_qpack_encoder;
|
|||
*
|
||||
* :macro:`NGHTTP3_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
*
|
||||
* See also `nghttp3_qpack_encoder_new2`. This function calls
|
||||
* `nghttp3_qpack_encoder_new2` with the given parameters and 0 as
|
||||
* seed.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `nghttp3_qpack_encoder_new2` initializes QPACK encoder. |pencoder|
|
||||
* must be non-NULL pointer. |hard_max_dtable_capacity| is the upper
|
||||
* bound of the dynamic table capacity. |seed| must be unpredictable
|
||||
* value, and is used to seed the internal data structure. |mem| is a
|
||||
* memory allocator. This function allocates memory for
|
||||
* :type:`nghttp3_qpack_encoder` itself, and assigns its pointer to
|
||||
* |*pencoder| if it succeeds.
|
||||
*
|
||||
* The maximum dynamic table capacity is still 0. In order to change
|
||||
* the maximum dynamic table capacity, call
|
||||
* `nghttp3_qpack_encoder_set_max_dtable_capacity`.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`NGHTTP3_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
*
|
||||
* This function is available since v1.11.0.
|
||||
*/
|
||||
NGHTTP3_EXTERN int nghttp3_qpack_encoder_new2(nghttp3_qpack_encoder **pencoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
uint64_t seed,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
@ -1605,7 +1637,8 @@ NGHTTP3_EXTERN void nghttp3_set_debug_vprintf_callback(
|
|||
typedef struct nghttp3_conn nghttp3_conn;
|
||||
|
||||
#define NGHTTP3_SETTINGS_V1 1
|
||||
#define NGHTTP3_SETTINGS_VERSION NGHTTP3_SETTINGS_V1
|
||||
#define NGHTTP3_SETTINGS_V2 2
|
||||
#define NGHTTP3_SETTINGS_VERSION NGHTTP3_SETTINGS_V2
|
||||
|
||||
/**
|
||||
* @struct
|
||||
|
@ -1652,6 +1685,21 @@ typedef struct nghttp3_settings {
|
|||
* Datagrams (see :rfc:`9297`).
|
||||
*/
|
||||
uint8_t h3_datagram;
|
||||
/* The following fields have been added since NGHTTP3_SETTINGS_V2. */
|
||||
/**
|
||||
* :member:`origin_list`, if set, must contain a serialized HTTP/3
|
||||
* ORIGIN frame (see :rfc:`9412`) payload. The ORIGIN frame payload
|
||||
* is a sequence of zero or more of a length prefixed byte string.
|
||||
* The length is encoded in 2 bytes in network byte order. If
|
||||
* :member:`origin_list->len <nghttp3_vec.len>` is zero, an empty
|
||||
* ORIGIN frame is sent. An application must keep the buffer
|
||||
* pointed by :member:`origin_list->base <nghttp3_vec.base>` alive
|
||||
* until the :type:`nghttp3_conn` to which this field was passed is
|
||||
* freed by `nghttp3_conn_del`. The object pointed to by this field
|
||||
* is copied internally, and does not need to be kept alive. Only
|
||||
* server uses this field. This field is available since v1.11.0.
|
||||
*/
|
||||
const nghttp3_vec *origin_list;
|
||||
} nghttp3_settings;
|
||||
|
||||
/**
|
||||
|
@ -1891,8 +1939,47 @@ typedef int (*nghttp3_recv_settings)(nghttp3_conn *conn,
|
|||
const nghttp3_settings *settings,
|
||||
void *conn_user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* :type:`nghttp3_recv_origin` is a callback function which is invoked
|
||||
* when a single origin in ORIGIN frame is received. |origin| is a
|
||||
* received origin of length |originlen|. |originlen| never be 0.
|
||||
*
|
||||
* The implementation of this callback must return 0 if it succeeds.
|
||||
* Returning :macro:`NGHTTP3_ERR_CALLBACK_FAILURE` will return to the
|
||||
* caller immediately. Any values other than 0 is treated as
|
||||
* :macro:`NGHTTP3_ERR_CALLBACK_FAILURE`.
|
||||
*/
|
||||
typedef int (*nghttp3_recv_origin)(nghttp3_conn *conn, const uint8_t *origin,
|
||||
size_t originlen, void *conn_user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* :type:`nghttp3_end_origin` is a callback function which is invoked
|
||||
* when an ORIGIN frame has been completely processed.
|
||||
*
|
||||
* The implementation of this callback must return 0 if it succeeds.
|
||||
* Returning :macro:`NGHTTP3_ERR_CALLBACK_FAILURE` will return to the
|
||||
* caller immediately. Any values other than 0 is treated as
|
||||
* :macro:`NGHTTP3_ERR_CALLBACK_FAILURE`.
|
||||
*/
|
||||
typedef int (*nghttp3_end_origin)(nghttp3_conn *conn, void *conn_user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* :type:`nghttp3_rand` is a callback function which is invoked when
|
||||
* unpredictable data of |destlen| bytes are needed. The
|
||||
* implementation must write unpredictable data of |destlen| bytes
|
||||
* into the buffer pointed by |dest|.
|
||||
*/
|
||||
typedef void (*nghttp3_rand)(uint8_t *dest, size_t destlen);
|
||||
|
||||
#define NGHTTP3_CALLBACKS_V1 1
|
||||
#define NGHTTP3_CALLBACKS_VERSION NGHTTP3_CALLBACKS_V1
|
||||
#define NGHTTP3_CALLBACKS_V2 2
|
||||
#define NGHTTP3_CALLBACKS_VERSION NGHTTP3_CALLBACKS_V2
|
||||
|
||||
/**
|
||||
* @struct
|
||||
|
@ -1986,6 +2073,28 @@ typedef struct nghttp3_callbacks {
|
|||
* when SETTINGS frame is received.
|
||||
*/
|
||||
nghttp3_recv_settings recv_settings;
|
||||
/* The following fields have been added since NGHTTP3_CALLBACKS_V2. */
|
||||
/**
|
||||
* :member:`recv_origin` is a callback function which is invoked
|
||||
* when a single origin in an ORIGIN frame is received. This field
|
||||
* is available since v1.11.0.
|
||||
*/
|
||||
nghttp3_recv_origin recv_origin;
|
||||
/**
|
||||
* :member:`end_origin` is a callback function which is invoked when
|
||||
* an ORIGIN frame has been completely processed. This field is
|
||||
* available since v1.11.0.
|
||||
*/
|
||||
nghttp3_end_origin end_origin;
|
||||
/**
|
||||
* :member:`rand` is a callback function which is invoked when
|
||||
* unpredictable data are needed. Although this field is optional
|
||||
* due to the backward compatibility, it is recommended to specify
|
||||
* this field to harden the runtime behavior against suspicious
|
||||
* activities of a remote endpoint. This field is available since
|
||||
* v1.11.0.
|
||||
*/
|
||||
nghttp3_rand rand;
|
||||
} nghttp3_callbacks;
|
||||
|
||||
/**
|
||||
|
@ -2106,7 +2215,7 @@ NGHTTP3_EXTERN int nghttp3_conn_bind_qpack_streams(nghttp3_conn *conn,
|
|||
* control credit (both stream and connection) of underlying QUIC
|
||||
* connection by that amount. It does not include the amount of data
|
||||
* carried by DATA frame which contains application data (excluding
|
||||
* any control or QPACK unidirectional streams) . See
|
||||
* any control or QPACK unidirectional streams). See
|
||||
* :type:`nghttp3_recv_data` to handle those bytes. If |fin| is
|
||||
* nonzero, this is the last data from remote endpoint in this stream.
|
||||
*
|
||||
|
@ -2480,8 +2589,6 @@ typedef struct nghttp3_data_reader {
|
|||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`NGHTTP3_ERR_INVALID_ARGUMENT`
|
||||
* |stream_id| identifies unidirectional stream.
|
||||
* :macro:`NGHTTP3_ERR_CONN_CLOSING`
|
||||
* Connection is shutting down, and no new stream is allowed.
|
||||
* :macro:`NGHTTP3_ERR_STREAM_IN_USE`
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
*
|
||||
* Version number of the nghttp3 library release.
|
||||
*/
|
||||
#define NGHTTP3_VERSION "1.6.0"
|
||||
#define NGHTTP3_VERSION "1.11.0"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
|
@ -41,6 +41,6 @@
|
|||
* number, 8 bits for minor and 8 bits for patch. Version 1.2.3
|
||||
* becomes 0x010203.
|
||||
*/
|
||||
#define NGHTTP3_VERSION_NUM 0x010600
|
||||
#define NGHTTP3_VERSION_NUM 0x010b00
|
||||
|
||||
#endif /* !defined(NGHTTP3_VERSION_H) */
|
||||
|
|
12
deps/ngtcp2/nghttp3/lib/nghttp3_buf.c
vendored
12
deps/ngtcp2/nghttp3/lib/nghttp3_buf.c
vendored
|
@ -50,6 +50,10 @@ size_t nghttp3_buf_cap(const nghttp3_buf *buf) {
|
|||
return (size_t)(buf->end - buf->begin);
|
||||
}
|
||||
|
||||
size_t nghttp3_buf_offset(const nghttp3_buf *buf) {
|
||||
return (size_t)(buf->pos - buf->begin);
|
||||
}
|
||||
|
||||
void nghttp3_buf_reset(nghttp3_buf *buf) { buf->pos = buf->last = buf->begin; }
|
||||
|
||||
int nghttp3_buf_reserve(nghttp3_buf *buf, size_t size, const nghttp3_mem *mem) {
|
||||
|
@ -87,4 +91,12 @@ void nghttp3_typed_buf_init(nghttp3_typed_buf *tbuf, const nghttp3_buf *buf,
|
|||
nghttp3_buf_type type) {
|
||||
tbuf->buf = *buf;
|
||||
tbuf->type = type;
|
||||
tbuf->buf.begin = tbuf->buf.pos;
|
||||
}
|
||||
|
||||
void nghttp3_typed_buf_shared_init(nghttp3_typed_buf *tbuf,
|
||||
const nghttp3_buf *chunk) {
|
||||
tbuf->buf = *chunk;
|
||||
tbuf->type = NGHTTP3_BUF_TYPE_SHARED;
|
||||
tbuf->buf.begin = tbuf->buf.pos = tbuf->buf.last;
|
||||
}
|
||||
|
|
19
deps/ngtcp2/nghttp3/lib/nghttp3_buf.h
vendored
19
deps/ngtcp2/nghttp3/lib/nghttp3_buf.h
vendored
|
@ -42,6 +42,12 @@ void nghttp3_buf_wrap_init(nghttp3_buf *buf, uint8_t *src, size_t len);
|
|||
*/
|
||||
size_t nghttp3_buf_cap(const nghttp3_buf *buf);
|
||||
|
||||
/*
|
||||
* nghttp3_buf_offset returns the distance from tbuf->begin to
|
||||
* tbuf->pos. In other words, it returns buf->pos - buf->begin.
|
||||
*/
|
||||
size_t nghttp3_buf_offset(const nghttp3_buf *buf);
|
||||
|
||||
int nghttp3_buf_reserve(nghttp3_buf *buf, size_t size, const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
|
@ -57,8 +63,12 @@ typedef enum nghttp3_buf_type {
|
|||
memory. */
|
||||
NGHTTP3_BUF_TYPE_SHARED,
|
||||
/* NGHTTP3_BUF_TYPE_ALIEN indicates that the buffer points to a
|
||||
memory which comes from outside of the library. */
|
||||
memory which comes from outside of the library. When
|
||||
acknowledged, acked_data callback is called. */
|
||||
NGHTTP3_BUF_TYPE_ALIEN,
|
||||
/* NGHTTP3_BUF_TYPE_ALIEN_NO_ACK is like NGHTTP3_BUF_TYPE_ALIEN, but
|
||||
acked_data callback is not called. */
|
||||
NGHTTP3_BUF_TYPE_ALIEN_NO_ACK,
|
||||
} nghttp3_buf_type;
|
||||
|
||||
typedef struct nghttp3_typed_buf {
|
||||
|
@ -69,6 +79,13 @@ typedef struct nghttp3_typed_buf {
|
|||
void nghttp3_typed_buf_init(nghttp3_typed_buf *tbuf, const nghttp3_buf *buf,
|
||||
nghttp3_buf_type type);
|
||||
|
||||
/*
|
||||
* nghttp3_typed_buf_shared_init initializes |tbuf| of type
|
||||
* NGHTTP3_BUF_TYPE_SHARED.
|
||||
*/
|
||||
void nghttp3_typed_buf_shared_init(nghttp3_typed_buf *tbuf,
|
||||
const nghttp3_buf *chunk);
|
||||
|
||||
void nghttp3_typed_buf_free(nghttp3_typed_buf *tbuf);
|
||||
|
||||
#endif /* !defined(NGHTTP3_BUF_H) */
|
||||
|
|
75
deps/ngtcp2/nghttp3/lib/nghttp3_callbacks.c
vendored
Normal file
75
deps/ngtcp2/nghttp3/lib/nghttp3_callbacks.c
vendored
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* nghttp3
|
||||
*
|
||||
* Copyright (c) 2025 nghttp3 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "nghttp3_callbacks.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "nghttp3_unreachable.h"
|
||||
|
||||
static void callbacks_copy(nghttp3_callbacks *dest,
|
||||
const nghttp3_callbacks *src,
|
||||
int callbacks_version) {
|
||||
assert(callbacks_version != NGHTTP3_CALLBACKS_VERSION);
|
||||
|
||||
memcpy(dest, src, nghttp3_callbackslen_version(callbacks_version));
|
||||
}
|
||||
|
||||
const nghttp3_callbacks *
|
||||
nghttp3_callbacks_convert_to_latest(nghttp3_callbacks *dest,
|
||||
int callbacks_version,
|
||||
const nghttp3_callbacks *src) {
|
||||
if (callbacks_version == NGHTTP3_CALLBACKS_VERSION) {
|
||||
return src;
|
||||
}
|
||||
|
||||
memset(dest, 0, sizeof(*dest));
|
||||
|
||||
callbacks_copy(dest, src, callbacks_version);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void nghttp3_callbacks_convert_to_old(int callbacks_version,
|
||||
nghttp3_callbacks *dest,
|
||||
const nghttp3_callbacks *src) {
|
||||
assert(callbacks_version != NGHTTP3_CALLBACKS_VERSION);
|
||||
|
||||
callbacks_copy(dest, src, callbacks_version);
|
||||
}
|
||||
|
||||
size_t nghttp3_callbackslen_version(int callbacks_version) {
|
||||
nghttp3_callbacks callbacks;
|
||||
|
||||
switch (callbacks_version) {
|
||||
case NGHTTP3_CALLBACKS_VERSION:
|
||||
return sizeof(callbacks);
|
||||
case NGHTTP3_CALLBACKS_V1:
|
||||
return offsetof(nghttp3_callbacks, recv_settings) +
|
||||
sizeof(callbacks.recv_settings);
|
||||
default:
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
}
|
74
deps/ngtcp2/nghttp3/lib/nghttp3_callbacks.h
vendored
Normal file
74
deps/ngtcp2/nghttp3/lib/nghttp3_callbacks.h
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* nghttp3
|
||||
*
|
||||
* Copyright (c) 2025 nghttp3 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP3_CALLBACKS_H
|
||||
#define NGHTTP3_CALLBACKS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
/*
|
||||
* nghttp3_callbacks_convert_to_latest converts |src| of version
|
||||
* |callbacks_version| to the latest version
|
||||
* NGHTTP3_CALLBACKS_VERSION.
|
||||
*
|
||||
* |dest| must point to the latest version. |src| may be the older
|
||||
* version, and if so, it may have fewer fields. Accessing those
|
||||
* fields causes undefined behavior.
|
||||
*
|
||||
* If |callbacks_version| == NGHTTP3_CALLBACKS_VERSION, no conversion
|
||||
* is made, and |src| is returned. Otherwise, first |dest| is
|
||||
* zero-initialized, and then all valid fields in |src| are copied
|
||||
* into |dest|. Finally, |dest| is returned.
|
||||
*/
|
||||
const nghttp3_callbacks *nghttp3_callbacks_convert_to_latest(
|
||||
nghttp3_callbacks *dest, int callbacks_version, const nghttp3_callbacks *src);
|
||||
|
||||
/*
|
||||
* nghttp3_callbacks_convert_to_old converts |src| of the latest
|
||||
* version to |dest| of version |callbacks_version|.
|
||||
*
|
||||
* |callbacks_version| must not be the latest version
|
||||
* NGHTTP3_CALLBACKS_VERSION.
|
||||
*
|
||||
* |dest| points to the older version, and it may have fewer fields.
|
||||
* Accessing those fields causes undefined behavior.
|
||||
*
|
||||
* This function copies all valid fields in version
|
||||
* |callbacks_version| from |src| to |dest|.
|
||||
*/
|
||||
void nghttp3_callbacks_convert_to_old(int callbacks_version,
|
||||
nghttp3_callbacks *dest,
|
||||
const nghttp3_callbacks *src);
|
||||
|
||||
/*
|
||||
* nghttp3_callbackslen_version returns the effective length of
|
||||
* nghttp3_callbacks at the version |callbacks_version|.
|
||||
*/
|
||||
size_t nghttp3_callbackslen_version(int callbacks_version);
|
||||
|
||||
#endif /* !defined(NGHTTP3_CALLBACKS_H) */
|
405
deps/ngtcp2/nghttp3/lib/nghttp3_conn.c
vendored
405
deps/ngtcp2/nghttp3/lib/nghttp3_conn.c
vendored
|
@ -34,12 +34,10 @@
|
|||
#include "nghttp3_conv.h"
|
||||
#include "nghttp3_http.h"
|
||||
#include "nghttp3_unreachable.h"
|
||||
#include "nghttp3_settings.h"
|
||||
#include "nghttp3_callbacks.h"
|
||||
|
||||
/* NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY is the upper bound of the
|
||||
dynamic table capacity that QPACK encoder is willing to use. */
|
||||
#define NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY 4096
|
||||
|
||||
nghttp3_objalloc_def(chunk, nghttp3_chunk, oplent);
|
||||
nghttp3_objalloc_def(chunk, nghttp3_chunk, oplent)
|
||||
|
||||
/*
|
||||
* conn_remote_stream_uni returns nonzero if |stream_id| is remote
|
||||
|
@ -207,6 +205,32 @@ static int conn_call_recv_settings(nghttp3_conn *conn) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int conn_call_recv_origin(nghttp3_conn *conn, const uint8_t *origin,
|
||||
size_t originlen) {
|
||||
if (!conn->callbacks.recv_origin) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (conn->callbacks.recv_origin(conn, origin, originlen, conn->user_data) !=
|
||||
0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int conn_call_end_origin(nghttp3_conn *conn) {
|
||||
if (!conn->callbacks.end_origin) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (conn->callbacks.end_origin(conn, conn->user_data) != 0) {
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ricnt_less(const nghttp3_pq_entry *lhsx,
|
||||
const nghttp3_pq_entry *rhsx) {
|
||||
nghttp3_stream *lhs =
|
||||
|
@ -233,11 +257,22 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version,
|
|||
const nghttp3_callbacks *callbacks, int settings_version,
|
||||
const nghttp3_settings *settings, const nghttp3_mem *mem,
|
||||
void *user_data) {
|
||||
int rv;
|
||||
nghttp3_conn *conn;
|
||||
nghttp3_settings settings_latest;
|
||||
nghttp3_callbacks callbacks_latest;
|
||||
uint64_t map_seed;
|
||||
size_t i;
|
||||
(void)callbacks_version;
|
||||
(void)settings_version;
|
||||
|
||||
settings = nghttp3_settings_convert_to_latest(&settings_latest,
|
||||
settings_version, settings);
|
||||
callbacks = nghttp3_callbacks_convert_to_latest(&callbacks_latest,
|
||||
callbacks_version, callbacks);
|
||||
|
||||
assert(settings->max_field_section_size <= NGHTTP3_VARINT_MAX);
|
||||
assert(settings->qpack_max_dtable_capacity <= NGHTTP3_VARINT_MAX);
|
||||
assert(settings->qpack_encoder_max_dtable_capacity <= NGHTTP3_VARINT_MAX);
|
||||
assert(settings->qpack_blocked_streams <= NGHTTP3_VARINT_MAX);
|
||||
|
||||
if (mem == NULL) {
|
||||
mem = nghttp3_mem_default();
|
||||
|
@ -252,20 +287,19 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version,
|
|||
NGHTTP3_STREAM_MIN_CHUNK_SIZE * 16, mem);
|
||||
nghttp3_objalloc_stream_init(&conn->stream_objalloc, 8, mem);
|
||||
|
||||
nghttp3_map_init(&conn->streams, mem);
|
||||
|
||||
rv =
|
||||
nghttp3_qpack_decoder_init(&conn->qdec, settings->qpack_max_dtable_capacity,
|
||||
settings->qpack_blocked_streams, mem);
|
||||
if (rv != 0) {
|
||||
goto qdec_init_fail;
|
||||
if (callbacks->rand) {
|
||||
callbacks->rand((uint8_t *)&map_seed, sizeof(map_seed));
|
||||
} else {
|
||||
map_seed = 0;
|
||||
}
|
||||
|
||||
rv = nghttp3_qpack_encoder_init(
|
||||
&conn->qenc, settings->qpack_encoder_max_dtable_capacity, mem);
|
||||
if (rv != 0) {
|
||||
goto qenc_init_fail;
|
||||
}
|
||||
nghttp3_map_init(&conn->streams, map_seed, mem);
|
||||
|
||||
nghttp3_qpack_decoder_init(&conn->qdec, settings->qpack_max_dtable_capacity,
|
||||
settings->qpack_blocked_streams, mem);
|
||||
|
||||
nghttp3_qpack_encoder_init(
|
||||
&conn->qenc, settings->qpack_encoder_max_dtable_capacity, ++map_seed, mem);
|
||||
|
||||
nghttp3_pq_init(&conn->qpack_blocked_streams, ricnt_less, mem);
|
||||
|
||||
|
@ -277,8 +311,14 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version,
|
|||
|
||||
conn->callbacks = *callbacks;
|
||||
conn->local.settings = *settings;
|
||||
if (!server) {
|
||||
if (server) {
|
||||
if (settings->origin_list) {
|
||||
conn->local.settings.origin_list = &conn->local.origin_list;
|
||||
conn->local.origin_list = *settings->origin_list;
|
||||
}
|
||||
} else {
|
||||
conn->local.settings.enable_connect_protocol = 0;
|
||||
conn->local.settings.origin_list = NULL;
|
||||
}
|
||||
nghttp3_settings_default(&conn->remote.settings);
|
||||
conn->mem = mem;
|
||||
|
@ -291,16 +331,6 @@ static int conn_new(nghttp3_conn **pconn, int server, int callbacks_version,
|
|||
*pconn = conn;
|
||||
|
||||
return 0;
|
||||
|
||||
qenc_init_fail:
|
||||
nghttp3_qpack_decoder_free(&conn->qdec);
|
||||
qdec_init_fail:
|
||||
nghttp3_map_free(&conn->streams);
|
||||
nghttp3_objalloc_free(&conn->stream_objalloc);
|
||||
nghttp3_objalloc_free(&conn->out_chunk_objalloc);
|
||||
nghttp3_mem_free(mem, conn);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int nghttp3_conn_client_new_versioned(nghttp3_conn **pconn,
|
||||
|
@ -374,6 +404,8 @@ void nghttp3_conn_del(nghttp3_conn *conn) {
|
|||
nghttp3_objalloc_free(&conn->stream_objalloc);
|
||||
nghttp3_objalloc_free(&conn->out_chunk_objalloc);
|
||||
|
||||
nghttp3_mem_free(conn->mem, conn->rx.originbuf);
|
||||
|
||||
nghttp3_mem_free(conn->mem, conn);
|
||||
}
|
||||
|
||||
|
@ -399,6 +431,9 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id,
|
|||
size_t bidi_nproc;
|
||||
int rv;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
stream = nghttp3_conn_find_stream(conn, stream_id);
|
||||
if (stream == NULL) {
|
||||
/* TODO Assert idtr */
|
||||
|
@ -434,6 +469,10 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id,
|
|||
return rv;
|
||||
}
|
||||
}
|
||||
} else if (!nghttp3_client_stream_uni(stream_id)) {
|
||||
/* server does not expect to receive new server initiated
|
||||
bidirectional or unidirectional stream from client. */
|
||||
return NGHTTP3_ERR_H3_STREAM_CREATION_ERROR;
|
||||
} else {
|
||||
/* unidirectional stream */
|
||||
if (srclen == 0 && fin) {
|
||||
|
@ -448,7 +487,7 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id,
|
|||
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL;
|
||||
stream->tx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL;
|
||||
} else if (nghttp3_stream_uni(stream_id)) {
|
||||
} else if (nghttp3_server_stream_uni(stream_id)) {
|
||||
if (srclen == 0 && fin) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -461,17 +500,16 @@ nghttp3_ssize nghttp3_conn_read_stream(nghttp3_conn *conn, int64_t stream_id,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_INITIAL;
|
||||
stream->tx.hstate = NGHTTP3_HTTP_STATE_RESP_INITIAL;
|
||||
} else {
|
||||
/* client doesn't expect to receive new bidirectional stream
|
||||
from server. */
|
||||
/* client doesn't expect to receive new bidirectional stream or
|
||||
client initiated unidirectional stream from server. */
|
||||
return NGHTTP3_ERR_H3_STREAM_CREATION_ERROR;
|
||||
}
|
||||
} else if (conn->server) {
|
||||
if (nghttp3_client_stream_bidi(stream_id)) {
|
||||
if (stream->rx.hstate == NGHTTP3_HTTP_STATE_NONE) {
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL;
|
||||
stream->tx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL;
|
||||
}
|
||||
}
|
||||
assert(nghttp3_client_stream_bidi(stream_id) ||
|
||||
nghttp3_client_stream_uni(stream_id));
|
||||
} else {
|
||||
assert(nghttp3_client_stream_bidi(stream_id) ||
|
||||
nghttp3_server_stream_uni(stream_id));
|
||||
}
|
||||
|
||||
if (srclen == 0 && !fin) {
|
||||
|
@ -608,6 +646,9 @@ nghttp3_ssize nghttp3_conn_read_uni(nghttp3_conn *conn, nghttp3_stream *stream,
|
|||
break;
|
||||
case NGHTTP3_STREAM_TYPE_UNKNOWN:
|
||||
nconsumed = (nghttp3_ssize)srclen;
|
||||
if (fin) {
|
||||
break;
|
||||
}
|
||||
|
||||
rv = conn_call_stop_sending(conn, stream, NGHTTP3_H3_STREAM_CREATION_ERROR);
|
||||
if (rv != 0) {
|
||||
|
@ -625,6 +666,11 @@ nghttp3_ssize nghttp3_conn_read_uni(nghttp3_conn *conn, nghttp3_stream *stream,
|
|||
return nread + nconsumed;
|
||||
}
|
||||
|
||||
static void conn_reset_rx_originlen(nghttp3_conn *conn) {
|
||||
conn->rx.originlen_offset = 0;
|
||||
conn->rx.originlen = 0;
|
||||
}
|
||||
|
||||
static int frame_fin(nghttp3_stream_read_state *rstate, size_t len) {
|
||||
return (int64_t)len >= rstate->left;
|
||||
}
|
||||
|
@ -661,11 +707,11 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
|||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
|
||||
rstate->fr.hd.type = rvint->acc;
|
||||
rstate->fr.type = rvint->acc;
|
||||
nghttp3_varint_read_state_reset(rvint);
|
||||
rstate->state = NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH;
|
||||
if (p == end) {
|
||||
break;
|
||||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
/* Fall through */
|
||||
case NGHTTP3_CTRL_STREAM_STATE_FRAME_LENGTH:
|
||||
|
@ -681,19 +727,19 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
|||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
|
||||
rstate->left = rstate->fr.hd.length = rvint->acc;
|
||||
rstate->left = rvint->acc;
|
||||
nghttp3_varint_read_state_reset(rvint);
|
||||
|
||||
if (!(conn->flags & NGHTTP3_CONN_FLAG_SETTINGS_RECVED)) {
|
||||
if (rstate->fr.hd.type != NGHTTP3_FRAME_SETTINGS) {
|
||||
if (rstate->fr.type != NGHTTP3_FRAME_SETTINGS) {
|
||||
return NGHTTP3_ERR_H3_MISSING_SETTINGS;
|
||||
}
|
||||
conn->flags |= NGHTTP3_CONN_FLAG_SETTINGS_RECVED;
|
||||
} else if (rstate->fr.hd.type == NGHTTP3_FRAME_SETTINGS) {
|
||||
} else if (rstate->fr.type == NGHTTP3_FRAME_SETTINGS) {
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
}
|
||||
|
||||
switch (rstate->fr.hd.type) {
|
||||
switch (rstate->fr.type) {
|
||||
case NGHTTP3_FRAME_SETTINGS:
|
||||
/* SETTINGS frame might be empty. */
|
||||
if (rstate->left == 0) {
|
||||
|
@ -734,6 +780,31 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
|||
case NGHTTP3_FRAME_PRIORITY_UPDATE_PUSH_ID:
|
||||
/* We do not support push */
|
||||
return NGHTTP3_ERR_H3_ID_ERROR;
|
||||
case NGHTTP3_FRAME_ORIGIN:
|
||||
if (conn->server ||
|
||||
(!conn->callbacks.recv_origin && !conn->callbacks.end_origin)) {
|
||||
busy = 1;
|
||||
rstate->state = NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME;
|
||||
break;
|
||||
}
|
||||
|
||||
/* ORIGIN frame might be empty */
|
||||
if (rstate->left == 0) {
|
||||
rv = conn_call_end_origin(conn);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
conn_reset_rx_originlen(conn);
|
||||
|
||||
rstate->state = NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ORIGIN_LEN;
|
||||
|
||||
break;
|
||||
case NGHTTP3_FRAME_CANCEL_PUSH: /* We do not support push */
|
||||
case NGHTTP3_FRAME_DATA:
|
||||
case NGHTTP3_FRAME_HEADERS:
|
||||
|
@ -971,8 +1042,14 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
|||
break;
|
||||
}
|
||||
|
||||
conn->rx.pri_fieldbuflen = 0;
|
||||
|
||||
rstate->state = NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE;
|
||||
|
||||
if (p == end) {
|
||||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
|
||||
/* Fall through */
|
||||
case NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE:
|
||||
/* We need to buffer Priority Field Value because it might be
|
||||
|
@ -1027,9 +1104,134 @@ nghttp3_ssize nghttp3_conn_read_control(nghttp3_conn *conn,
|
|||
return rv;
|
||||
}
|
||||
|
||||
conn->rx.pri_fieldbuflen = 0;
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ORIGIN_LEN:
|
||||
/* client side only */
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
for (;;) {
|
||||
nread = 0;
|
||||
|
||||
for (; conn->rx.originlen_offset < sizeof(conn->rx.originlen) &&
|
||||
(size_t)nread < len;
|
||||
++conn->rx.originlen_offset, ++nread) {
|
||||
conn->rx.originlen <<= 8;
|
||||
conn->rx.originlen += *p++;
|
||||
}
|
||||
|
||||
nconsumed += (size_t)nread;
|
||||
rstate->left -= nread;
|
||||
len -= (size_t)nread;
|
||||
|
||||
if (conn->rx.originlen_offset < sizeof(conn->rx.originlen)) {
|
||||
/* Needs another byte to parse Origin-Len */
|
||||
if (rstate->left == 0) {
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
|
||||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
|
||||
if (conn->rx.originlen == 0 || rstate->left < conn->rx.originlen) {
|
||||
/* While this seems OK in very loose RFC, allowing this
|
||||
sounds like an atack vector. */
|
||||
return NGHTTP3_ERR_H3_FRAME_ERROR;
|
||||
}
|
||||
|
||||
if (len < conn->rx.originlen) {
|
||||
/* ASCII-Origin does not fit into this buffer. Needs
|
||||
buffering. */
|
||||
if (conn->rx.originbuf == NULL) {
|
||||
conn->rx.originbuf = nghttp3_mem_malloc(conn->mem, UINT16_MAX);
|
||||
if (conn->rx.originbuf == NULL) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(conn->rx.originbuf, p, len);
|
||||
|
||||
/* No need to update p because we will return very soon. */
|
||||
nconsumed += len;
|
||||
rstate->left -= (int64_t)len;
|
||||
|
||||
conn->rx.originbuflen = len;
|
||||
|
||||
rstate->state = NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ASCII_ORIGIN;
|
||||
|
||||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
|
||||
rv = conn_call_recv_origin(conn, p, conn->rx.originlen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
p += conn->rx.originlen;
|
||||
nconsumed += conn->rx.originlen;
|
||||
rstate->left -= conn->rx.originlen;
|
||||
|
||||
if (rstate->left == 0) {
|
||||
rv = conn_call_end_origin(conn);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
len -= conn->rx.originlen;
|
||||
|
||||
conn_reset_rx_originlen(conn);
|
||||
|
||||
if (p == end) {
|
||||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ASCII_ORIGIN:
|
||||
/* client side only */
|
||||
len = nghttp3_min_size(conn->rx.originlen - conn->rx.originbuflen,
|
||||
(size_t)(end - p));
|
||||
|
||||
assert(len > 0);
|
||||
|
||||
memcpy(conn->rx.originbuf + conn->rx.originbuflen, p, len);
|
||||
|
||||
conn->rx.originbuflen += len;
|
||||
p += len;
|
||||
nconsumed += len;
|
||||
rstate->left -= (int64_t)len;
|
||||
|
||||
if (conn->rx.originbuflen < conn->rx.originlen) {
|
||||
return (nghttp3_ssize)nconsumed;
|
||||
}
|
||||
|
||||
rv = conn_call_recv_origin(conn, conn->rx.originbuf, conn->rx.originlen);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (rstate->left) {
|
||||
conn_reset_rx_originlen(conn);
|
||||
|
||||
rstate->state = NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ORIGIN_LEN;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
rv = conn_call_end_origin(conn);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
|
||||
break;
|
||||
case NGHTTP3_CTRL_STREAM_STATE_IGN_FRAME:
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
|
@ -1251,7 +1453,7 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
|||
goto almost_done;
|
||||
}
|
||||
|
||||
rstate->fr.hd.type = rvint->acc;
|
||||
rstate->fr.type = rvint->acc;
|
||||
nghttp3_varint_read_state_reset(rvint);
|
||||
rstate->state = NGHTTP3_REQ_STREAM_STATE_FRAME_LENGTH;
|
||||
if (p == end) {
|
||||
|
@ -1271,10 +1473,10 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
|||
goto almost_done;
|
||||
}
|
||||
|
||||
rstate->left = rstate->fr.hd.length = rvint->acc;
|
||||
rstate->left = rvint->acc;
|
||||
nghttp3_varint_read_state_reset(rvint);
|
||||
|
||||
switch (rstate->fr.hd.type) {
|
||||
switch (rstate->fr.type) {
|
||||
case NGHTTP3_FRAME_DATA:
|
||||
rv = nghttp3_stream_transit_rx_http_state(
|
||||
stream, NGHTTP3_HTTP_EVENT_DATA_BEGIN);
|
||||
|
@ -1374,10 +1576,6 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
|||
nread = nghttp3_conn_on_headers(conn, stream, p, len,
|
||||
(int64_t)len == rstate->left);
|
||||
if (nread < 0) {
|
||||
if (nread == NGHTTP3_ERR_MALFORMED_HTTP_HEADER) {
|
||||
goto http_header_error;
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
|
@ -1416,10 +1614,6 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
|||
}
|
||||
|
||||
if (rv != 0) {
|
||||
if (rv == NGHTTP3_ERR_MALFORMED_HTTP_HEADER) {
|
||||
goto http_header_error;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1458,24 +1652,6 @@ nghttp3_ssize nghttp3_conn_read_bidi(nghttp3_conn *conn, size_t *pnproc,
|
|||
|
||||
nghttp3_stream_read_state_reset(rstate);
|
||||
|
||||
break;
|
||||
|
||||
http_header_error:
|
||||
stream->flags |= NGHTTP3_STREAM_FLAG_HTTP_ERROR;
|
||||
|
||||
busy = 1;
|
||||
rstate->state = NGHTTP3_REQ_STREAM_STATE_IGN_REST;
|
||||
|
||||
rv = conn_call_stop_sending(conn, stream, NGHTTP3_H3_MESSAGE_ERROR);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = conn_call_reset_stream(conn, stream, NGHTTP3_H3_MESSAGE_ERROR);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
break;
|
||||
case NGHTTP3_REQ_STREAM_STATE_IGN_FRAME:
|
||||
len = (size_t)nghttp3_min_int64(rstate->left, (int64_t)(end - p));
|
||||
|
@ -1792,6 +1968,8 @@ conn_on_priority_update_stream(nghttp3_conn *conn,
|
|||
|
||||
stream->node.pri = fr->pri;
|
||||
stream->flags |= NGHTTP3_STREAM_FLAG_PRIORITY_UPDATE_RECVED;
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL;
|
||||
stream->tx.hstate = NGHTTP3_HTTP_STATE_REQ_INITIAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1808,7 +1986,7 @@ conn_on_priority_update_stream(nghttp3_conn *conn,
|
|||
int nghttp3_conn_on_priority_update(nghttp3_conn *conn,
|
||||
const nghttp3_frame_priority_update *fr) {
|
||||
assert(conn->server);
|
||||
assert(fr->hd.type == NGHTTP3_FRAME_PRIORITY_UPDATE);
|
||||
assert(fr->type == NGHTTP3_FRAME_PRIORITY_UPDATE);
|
||||
|
||||
return conn_on_priority_update_stream(conn, fr);
|
||||
}
|
||||
|
@ -1836,7 +2014,7 @@ int nghttp3_conn_create_stream(nghttp3_conn *conn, nghttp3_stream **pstream,
|
|||
nghttp3_stream *stream;
|
||||
int rv;
|
||||
nghttp3_stream_callbacks callbacks = {
|
||||
conn_stream_acked_data,
|
||||
.acked_data = conn_stream_acked_data,
|
||||
};
|
||||
|
||||
rv = nghttp3_stream_new(&stream, stream_id, &callbacks,
|
||||
|
@ -1874,6 +2052,8 @@ int nghttp3_conn_bind_control_stream(nghttp3_conn *conn, int64_t stream_id) {
|
|||
nghttp3_frame_entry frent;
|
||||
int rv;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
assert(!conn->server || nghttp3_server_stream_uni(stream_id));
|
||||
assert(conn->server || nghttp3_client_stream_uni(stream_id));
|
||||
|
||||
|
@ -1895,10 +2075,27 @@ int nghttp3_conn_bind_control_stream(nghttp3_conn *conn, int64_t stream_id) {
|
|||
return rv;
|
||||
}
|
||||
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_SETTINGS;
|
||||
frent.fr.type = NGHTTP3_FRAME_SETTINGS;
|
||||
frent.aux.settings.local_settings = &conn->local.settings;
|
||||
|
||||
return nghttp3_stream_frq_add(stream, &frent);
|
||||
rv = nghttp3_stream_frq_add(stream, &frent);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (conn->local.settings.origin_list) {
|
||||
assert(conn->server);
|
||||
|
||||
frent.fr.origin.type = NGHTTP3_FRAME_ORIGIN;
|
||||
frent.fr.origin.origin_list = *conn->local.settings.origin_list;
|
||||
|
||||
rv = nghttp3_stream_frq_add(stream, &frent);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nghttp3_conn_bind_qpack_streams(nghttp3_conn *conn, int64_t qenc_stream_id,
|
||||
|
@ -1906,6 +2103,10 @@ int nghttp3_conn_bind_qpack_streams(nghttp3_conn *conn, int64_t qenc_stream_id,
|
|||
nghttp3_stream *stream;
|
||||
int rv;
|
||||
|
||||
assert(qenc_stream_id >= 0);
|
||||
assert(qenc_stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
assert(qdec_stream_id >= 0);
|
||||
assert(qdec_stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
assert(!conn->server || nghttp3_server_stream_uni(qenc_stream_id));
|
||||
assert(!conn->server || nghttp3_server_stream_uni(qdec_stream_id));
|
||||
assert(conn->server || nghttp3_client_stream_uni(qenc_stream_id));
|
||||
|
@ -2118,14 +2319,14 @@ static int conn_submit_headers_data(nghttp3_conn *conn, nghttp3_stream *stream,
|
|||
const nghttp3_data_reader *dr) {
|
||||
int rv;
|
||||
nghttp3_nv *nnva;
|
||||
nghttp3_frame_entry frent = {0};
|
||||
nghttp3_frame_entry frent;
|
||||
|
||||
rv = nghttp3_nva_copy(&nnva, nva, nvlen, conn->mem);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_HEADERS;
|
||||
frent.fr.type = NGHTTP3_FRAME_HEADERS;
|
||||
frent.fr.headers.nva = nnva;
|
||||
frent.fr.headers.nvlen = nvlen;
|
||||
|
||||
|
@ -2136,7 +2337,7 @@ static int conn_submit_headers_data(nghttp3_conn *conn, nghttp3_stream *stream,
|
|||
}
|
||||
|
||||
if (dr) {
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_DATA;
|
||||
frent.fr.type = NGHTTP3_FRAME_DATA;
|
||||
frent.aux.data.dr = *dr;
|
||||
|
||||
rv = nghttp3_stream_frq_add(stream, &frent);
|
||||
|
@ -2194,13 +2395,11 @@ int nghttp3_conn_submit_request(nghttp3_conn *conn, int64_t stream_id,
|
|||
assert(!conn->server);
|
||||
assert(conn->tx.qenc);
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
assert(nghttp3_client_stream_bidi(stream_id));
|
||||
|
||||
/* TODO Should we check that stream_id is client stream_id? */
|
||||
/* TODO Check GOAWAY last stream ID */
|
||||
if (nghttp3_stream_uni(stream_id)) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (conn->flags & NGHTTP3_CONN_FLAG_GOAWAY_RECVED) {
|
||||
return NGHTTP3_ERR_CONN_CLOSING;
|
||||
|
@ -2288,12 +2487,12 @@ int nghttp3_conn_submit_trailers(nghttp3_conn *conn, int64_t stream_id,
|
|||
}
|
||||
|
||||
int nghttp3_conn_submit_shutdown_notice(nghttp3_conn *conn) {
|
||||
nghttp3_frame_entry frent = {0};
|
||||
nghttp3_frame_entry frent;
|
||||
int rv;
|
||||
|
||||
assert(conn->tx.ctrl);
|
||||
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_GOAWAY;
|
||||
frent.fr.type = NGHTTP3_FRAME_GOAWAY;
|
||||
frent.fr.goaway.id = conn->server ? NGHTTP3_SHUTDOWN_NOTICE_STREAM_ID
|
||||
: NGHTTP3_SHUTDOWN_NOTICE_PUSH_ID;
|
||||
|
||||
|
@ -2311,12 +2510,12 @@ int nghttp3_conn_submit_shutdown_notice(nghttp3_conn *conn) {
|
|||
}
|
||||
|
||||
int nghttp3_conn_shutdown(nghttp3_conn *conn) {
|
||||
nghttp3_frame_entry frent = {0};
|
||||
nghttp3_frame_entry frent;
|
||||
int rv;
|
||||
|
||||
assert(conn->tx.ctrl);
|
||||
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_GOAWAY;
|
||||
frent.fr.type = NGHTTP3_FRAME_GOAWAY;
|
||||
if (conn->server) {
|
||||
frent.fr.goaway.id =
|
||||
nghttp3_min_int64((1ll << 62) - 4, conn->rx.max_stream_id_bidi + 4);
|
||||
|
@ -2454,6 +2653,9 @@ int nghttp3_conn_close_stream(nghttp3_conn *conn, int64_t stream_id,
|
|||
int nghttp3_conn_shutdown_stream_read(nghttp3_conn *conn, int64_t stream_id) {
|
||||
nghttp3_stream *stream;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (!nghttp3_client_stream_bidi(stream_id)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -2515,6 +2717,9 @@ uint64_t nghttp3_conn_get_frame_payload_left(nghttp3_conn *conn,
|
|||
nghttp3_stream *stream;
|
||||
int uni = 0;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (!nghttp3_client_stream_bidi(stream_id)) {
|
||||
uni = conn_remote_stream_uni(conn, stream_id);
|
||||
if (!uni) {
|
||||
|
@ -2542,6 +2747,8 @@ int nghttp3_conn_get_stream_priority_versioned(nghttp3_conn *conn,
|
|||
(void)pri_version;
|
||||
|
||||
assert(conn->server);
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (!nghttp3_client_stream_bidi(stream_id)) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
|
@ -2562,10 +2769,12 @@ int nghttp3_conn_set_client_stream_priority(nghttp3_conn *conn,
|
|||
const uint8_t *data,
|
||||
size_t datalen) {
|
||||
nghttp3_stream *stream;
|
||||
nghttp3_frame_entry frent = {0};
|
||||
nghttp3_frame_entry frent;
|
||||
uint8_t *buf = NULL;
|
||||
|
||||
assert(!conn->server);
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (!nghttp3_client_stream_bidi(stream_id)) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
|
@ -2585,7 +2794,7 @@ int nghttp3_conn_set_client_stream_priority(nghttp3_conn *conn,
|
|||
memcpy(buf, data, datalen);
|
||||
}
|
||||
|
||||
frent.fr.hd.type = NGHTTP3_FRAME_PRIORITY_UPDATE;
|
||||
frent.fr.type = NGHTTP3_FRAME_PRIORITY_UPDATE;
|
||||
frent.fr.priority_update.pri_elem_id = stream_id;
|
||||
frent.fr.priority_update.data = buf;
|
||||
frent.fr.priority_update.datalen = datalen;
|
||||
|
@ -2603,6 +2812,8 @@ int nghttp3_conn_set_server_stream_priority_versioned(nghttp3_conn *conn,
|
|||
assert(conn->server);
|
||||
assert(pri->urgency < NGHTTP3_URGENCY_LEVELS);
|
||||
assert(pri->inc == 0 || pri->inc == 1);
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (!nghttp3_client_stream_bidi(stream_id)) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
|
@ -2626,13 +2837,3 @@ int nghttp3_conn_is_drained(nghttp3_conn *conn) {
|
|||
nghttp3_stream_outq_write_done(conn->tx.ctrl) &&
|
||||
nghttp3_ringbuf_len(&conn->tx.ctrl->frq) == 0;
|
||||
}
|
||||
|
||||
void nghttp3_settings_default_versioned(int settings_version,
|
||||
nghttp3_settings *settings) {
|
||||
(void)settings_version;
|
||||
|
||||
memset(settings, 0, sizeof(nghttp3_settings));
|
||||
settings->max_field_section_size = NGHTTP3_VARINT_MAX;
|
||||
settings->qpack_encoder_max_dtable_capacity =
|
||||
NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY;
|
||||
}
|
||||
|
|
45
deps/ngtcp2/nghttp3/lib/nghttp3_conn.h
vendored
45
deps/ngtcp2/nghttp3/lib/nghttp3_conn.h
vendored
|
@ -38,8 +38,6 @@
|
|||
#include "nghttp3_idtr.h"
|
||||
#include "nghttp3_gaptr.h"
|
||||
|
||||
#define NGHTTP3_VARINT_MAX ((1ull << 62) - 1)
|
||||
|
||||
/* NGHTTP3_QPACK_ENCODER_MAX_TABLE_CAPACITY is the maximum dynamic
|
||||
table size for QPACK encoder. */
|
||||
#define NGHTTP3_QPACK_ENCODER_MAX_TABLE_CAPACITY 16384
|
||||
|
@ -76,7 +74,7 @@ typedef struct nghttp3_chunk {
|
|||
nghttp3_opl_entry oplent;
|
||||
} nghttp3_chunk;
|
||||
|
||||
nghttp3_objalloc_decl(chunk, nghttp3_chunk, oplent);
|
||||
nghttp3_objalloc_decl(chunk, nghttp3_chunk, oplent)
|
||||
|
||||
struct nghttp3_conn {
|
||||
nghttp3_objalloc out_chunk_objalloc;
|
||||
|
@ -95,6 +93,11 @@ struct nghttp3_conn {
|
|||
uint16_t flags;
|
||||
|
||||
struct {
|
||||
/* origin_list contains the shallow copy of
|
||||
nghttp3_settings.origin_list passed from an application if this
|
||||
object is initialized as server. settings.origin_list may
|
||||
point to the address of this field. */
|
||||
nghttp3_vec origin_list;
|
||||
nghttp3_settings settings;
|
||||
struct {
|
||||
/* max_pushes is the number of push IDs that local endpoint can
|
||||
|
@ -125,12 +128,36 @@ struct nghttp3_conn {
|
|||
|
||||
int64_t max_stream_id_bidi;
|
||||
|
||||
/* pri_fieldbuf is a buffer to store incoming Priority Field Value
|
||||
in PRIORITY_UPDATE frame. */
|
||||
uint8_t pri_fieldbuf[8];
|
||||
/* pri_fieldlen is the number of bytes written into
|
||||
pri_fieldbuf. */
|
||||
size_t pri_fieldbuflen;
|
||||
union {
|
||||
struct {
|
||||
/* pri_fieldbuf is a buffer to store incoming Priority Field Value
|
||||
in PRIORITY_UPDATE frame. */
|
||||
uint8_t pri_fieldbuf[8];
|
||||
/* pri_fieldlen is the number of bytes written into
|
||||
pri_fieldbuf. */
|
||||
size_t pri_fieldbuflen;
|
||||
};
|
||||
/* ORIGIN frame */
|
||||
struct {
|
||||
/* originlen_offset is the offset to Origin-Len that is going
|
||||
to be added to originlen. If this value equals
|
||||
sizeof(originlen), Origin-Len is fully read, and the length
|
||||
of ASCII-Origin is determined. */
|
||||
size_t originlen_offset;
|
||||
/* originlen is Origin-Len of ASCII-Origin currently read. */
|
||||
uint16_t originlen;
|
||||
};
|
||||
};
|
||||
|
||||
/* originbuf points to the buffer that contains ASCII-Origin that
|
||||
is not fully available in a single input buffer. If it is
|
||||
fully available in the input buffer, it is emitted to an
|
||||
application without using this field. Otherwise, partial
|
||||
ASCII-Origin is copied to this field, and the complete
|
||||
ASCII-Origin is emitted when the assembly finishes. */
|
||||
uint8_t *originbuf;
|
||||
/* originbuflen is the length of bytes written to originbuf. */
|
||||
size_t originbuflen;
|
||||
} rx;
|
||||
|
||||
struct {
|
||||
|
|
2
deps/ngtcp2/nghttp3/lib/nghttp3_conv.c
vendored
2
deps/ngtcp2/nghttp3/lib/nghttp3_conv.c
vendored
|
@ -66,8 +66,6 @@ const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p) {
|
|||
}
|
||||
}
|
||||
|
||||
int64_t nghttp3_get_varint_fb(const uint8_t *p) { return *p & 0x3f; }
|
||||
|
||||
size_t nghttp3_get_varintlen(const uint8_t *p) {
|
||||
return (size_t)(1u << (*p >> 6));
|
||||
}
|
||||
|
|
8
deps/ngtcp2/nghttp3/lib/nghttp3_conv.h
vendored
8
deps/ngtcp2/nghttp3/lib/nghttp3_conv.h
vendored
|
@ -56,6 +56,8 @@
|
|||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
#define NGHTTP3_VARINT_MAX ((1ull << 62) - 1)
|
||||
|
||||
#if HAVE_DECL_BE64TOH
|
||||
# define nghttp3_ntohl64(N) be64toh(N)
|
||||
# define nghttp3_htonl64(N) htobe64(N)
|
||||
|
@ -135,12 +137,6 @@ STIN uint16_t ntohs(uint16_t netshort) {
|
|||
*/
|
||||
const uint8_t *nghttp3_get_varint(int64_t *dest, const uint8_t *p);
|
||||
|
||||
/*
|
||||
* nghttp3_get_varint_fb reads first byte of encoded variable-length
|
||||
* integer from |p|.
|
||||
*/
|
||||
int64_t nghttp3_get_varint_fb(const uint8_t *p);
|
||||
|
||||
/*
|
||||
* nghttp3_get_varintlen returns the required number of bytes to read
|
||||
* variable-length integer starting at |p|.
|
||||
|
|
50
deps/ngtcp2/nghttp3/lib/nghttp3_frame.c
vendored
50
deps/ngtcp2/nghttp3/lib/nghttp3_frame.c
vendored
|
@ -31,21 +31,22 @@
|
|||
#include "nghttp3_conv.h"
|
||||
#include "nghttp3_str.h"
|
||||
|
||||
uint8_t *nghttp3_frame_write_hd(uint8_t *p, const nghttp3_frame_hd *hd) {
|
||||
p = nghttp3_put_varint(p, hd->type);
|
||||
p = nghttp3_put_varint(p, hd->length);
|
||||
uint8_t *nghttp3_frame_write_hd(uint8_t *p, int64_t type, int64_t payloadlen) {
|
||||
p = nghttp3_put_varint(p, type);
|
||||
p = nghttp3_put_varint(p, payloadlen);
|
||||
return p;
|
||||
}
|
||||
|
||||
size_t nghttp3_frame_write_hd_len(const nghttp3_frame_hd *hd) {
|
||||
return nghttp3_put_varintlen(hd->type) + nghttp3_put_varintlen(hd->length);
|
||||
size_t nghttp3_frame_write_hd_len(int64_t type, int64_t payloadlen) {
|
||||
return nghttp3_put_varintlen(type) + nghttp3_put_varintlen(payloadlen);
|
||||
}
|
||||
|
||||
uint8_t *nghttp3_frame_write_settings(uint8_t *p,
|
||||
const nghttp3_frame_settings *fr) {
|
||||
const nghttp3_frame_settings *fr,
|
||||
int64_t payloadlen) {
|
||||
size_t i;
|
||||
|
||||
p = nghttp3_frame_write_hd(p, &fr->hd);
|
||||
p = nghttp3_frame_write_hd(p, fr->type, payloadlen);
|
||||
|
||||
for (i = 0; i < fr->niv; ++i) {
|
||||
p = nghttp3_put_varint(p, (int64_t)fr->iv[i].id);
|
||||
|
@ -71,9 +72,9 @@ size_t nghttp3_frame_write_settings_len(int64_t *ppayloadlen,
|
|||
nghttp3_put_varintlen((int64_t)payloadlen) + payloadlen;
|
||||
}
|
||||
|
||||
uint8_t *nghttp3_frame_write_goaway(uint8_t *p,
|
||||
const nghttp3_frame_goaway *fr) {
|
||||
p = nghttp3_frame_write_hd(p, &fr->hd);
|
||||
uint8_t *nghttp3_frame_write_goaway(uint8_t *p, const nghttp3_frame_goaway *fr,
|
||||
int64_t payloadlen) {
|
||||
p = nghttp3_frame_write_hd(p, fr->type, payloadlen);
|
||||
p = nghttp3_put_varint(p, fr->id);
|
||||
|
||||
return p;
|
||||
|
@ -89,10 +90,9 @@ size_t nghttp3_frame_write_goaway_len(int64_t *ppayloadlen,
|
|||
nghttp3_put_varintlen((int64_t)payloadlen) + payloadlen;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
nghttp3_frame_write_priority_update(uint8_t *p,
|
||||
const nghttp3_frame_priority_update *fr) {
|
||||
p = nghttp3_frame_write_hd(p, &fr->hd);
|
||||
uint8_t *nghttp3_frame_write_priority_update(
|
||||
uint8_t *p, const nghttp3_frame_priority_update *fr, int64_t payloadlen) {
|
||||
p = nghttp3_frame_write_hd(p, fr->type, payloadlen);
|
||||
p = nghttp3_put_varint(p, fr->pri_elem_id);
|
||||
if (fr->datalen) {
|
||||
p = nghttp3_cpymem(p, fr->data, fr->datalen);
|
||||
|
@ -107,7 +107,27 @@ size_t nghttp3_frame_write_priority_update_len(
|
|||
|
||||
*ppayloadlen = (int64_t)payloadlen;
|
||||
|
||||
return nghttp3_put_varintlen(fr->hd.type) +
|
||||
return nghttp3_put_varintlen(fr->type) +
|
||||
nghttp3_put_varintlen((int64_t)payloadlen) + payloadlen;
|
||||
}
|
||||
|
||||
uint8_t *nghttp3_frame_write_origin(uint8_t *p, const nghttp3_frame_origin *fr,
|
||||
int64_t payloadlen) {
|
||||
p = nghttp3_frame_write_hd(p, fr->type, payloadlen);
|
||||
if (fr->origin_list.len) {
|
||||
p = nghttp3_cpymem(p, fr->origin_list.base, fr->origin_list.len);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
size_t nghttp3_frame_write_origin_len(int64_t *ppayloadlen,
|
||||
const nghttp3_frame_origin *fr) {
|
||||
size_t payloadlen = fr->origin_list.len;
|
||||
|
||||
*ppayloadlen = (int64_t)payloadlen;
|
||||
|
||||
return nghttp3_put_varintlen(fr->type) +
|
||||
nghttp3_put_varintlen((int64_t)payloadlen) + payloadlen;
|
||||
}
|
||||
|
||||
|
|
89
deps/ngtcp2/nghttp3/lib/nghttp3_frame.h
vendored
89
deps/ngtcp2/nghttp3/lib/nghttp3_frame.h
vendored
|
@ -44,6 +44,8 @@
|
|||
/* PRIORITY_UPDATE: https://datatracker.ietf.org/doc/html/rfc9218 */
|
||||
#define NGHTTP3_FRAME_PRIORITY_UPDATE 0x0f0700
|
||||
#define NGHTTP3_FRAME_PRIORITY_UPDATE_PUSH_ID 0x0f0701
|
||||
/* ORIGIN: https://datatracker.ietf.org/doc/html/rfc9412 */
|
||||
#define NGHTTP3_FRAME_ORIGIN 0x0c
|
||||
|
||||
/* Frame types that are reserved for HTTP/2, and must not be used in
|
||||
HTTP/3. */
|
||||
|
@ -52,17 +54,12 @@
|
|||
#define NGHTTP3_H2_FRAME_WINDOW_UPDATE 0x08
|
||||
#define NGHTTP3_H2_FRAME_CONTINUATION 0x9
|
||||
|
||||
typedef struct nghttp3_frame_hd {
|
||||
int64_t type;
|
||||
int64_t length;
|
||||
} nghttp3_frame_hd;
|
||||
|
||||
typedef struct nghttp3_frame_data {
|
||||
nghttp3_frame_hd hd;
|
||||
int64_t type;
|
||||
} nghttp3_frame_data;
|
||||
|
||||
typedef struct nghttp3_frame_headers {
|
||||
nghttp3_frame_hd hd;
|
||||
int64_t type;
|
||||
nghttp3_nv *nva;
|
||||
size_t nvlen;
|
||||
} nghttp3_frame_headers;
|
||||
|
@ -84,20 +81,20 @@ typedef struct nghttp3_settings_entry {
|
|||
} nghttp3_settings_entry;
|
||||
|
||||
typedef struct nghttp3_frame_settings {
|
||||
nghttp3_frame_hd hd;
|
||||
int64_t type;
|
||||
size_t niv;
|
||||
nghttp3_settings_entry iv[1];
|
||||
} nghttp3_frame_settings;
|
||||
|
||||
typedef struct nghttp3_frame_goaway {
|
||||
nghttp3_frame_hd hd;
|
||||
int64_t type;
|
||||
int64_t id;
|
||||
} nghttp3_frame_goaway;
|
||||
|
||||
typedef struct nghttp3_frame_priority_update {
|
||||
nghttp3_frame_hd hd;
|
||||
/* pri_elem_id is stream ID if hd.type ==
|
||||
NGHTTP3_FRAME_PRIORITY_UPDATE. It is push ID if hd.type ==
|
||||
int64_t type;
|
||||
/* pri_elem_id is stream ID if type ==
|
||||
NGHTTP3_FRAME_PRIORITY_UPDATE. It is push ID if type ==
|
||||
NGHTTP3_FRAME_PRIORITY_UPDATE_PUSH_ID. It is undefined
|
||||
otherwise. */
|
||||
int64_t pri_elem_id;
|
||||
|
@ -114,42 +111,54 @@ typedef struct nghttp3_frame_priority_update {
|
|||
};
|
||||
} nghttp3_frame_priority_update;
|
||||
|
||||
typedef struct nghttp3_frame_origin {
|
||||
int64_t type;
|
||||
/* These fields are only used by server to send ORIGIN frame.
|
||||
Client never use them. */
|
||||
nghttp3_vec origin_list;
|
||||
} nghttp3_frame_origin;
|
||||
|
||||
typedef union nghttp3_frame {
|
||||
nghttp3_frame_hd hd;
|
||||
int64_t type;
|
||||
nghttp3_frame_data data;
|
||||
nghttp3_frame_headers headers;
|
||||
nghttp3_frame_settings settings;
|
||||
nghttp3_frame_goaway goaway;
|
||||
nghttp3_frame_priority_update priority_update;
|
||||
nghttp3_frame_origin origin;
|
||||
} nghttp3_frame;
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_hd writes frame header |hd| to |dest|. This
|
||||
* function assumes that |dest| has enough space to write |hd|.
|
||||
* nghttp3_frame_write_hd writes frame header consisting of |type| and
|
||||
* |payloadlen| to |dest|. This function assumes that |dest| has
|
||||
* enough space to write the frame header.
|
||||
*
|
||||
* This function returns |dest| plus the number of bytes written.
|
||||
*/
|
||||
uint8_t *nghttp3_frame_write_hd(uint8_t *dest, const nghttp3_frame_hd *hd);
|
||||
uint8_t *nghttp3_frame_write_hd(uint8_t *dest, int64_t type,
|
||||
int64_t payloadlen);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_hd_len returns the number of bytes required to
|
||||
* write |hd|. hd->length must be set.
|
||||
* write a frame header consisting of |type| and |payloadlen|.
|
||||
*/
|
||||
size_t nghttp3_frame_write_hd_len(const nghttp3_frame_hd *hd);
|
||||
size_t nghttp3_frame_write_hd_len(int64_t type, int64_t payloadlen);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_settings writes SETTINGS frame |fr| to |dest|.
|
||||
* This function assumes that |dest| has enough space to write |fr|.
|
||||
* |payloadlen| is the length of the frame payload.
|
||||
*
|
||||
* This function returns |dest| plus the number of bytes written.
|
||||
*/
|
||||
uint8_t *nghttp3_frame_write_settings(uint8_t *dest,
|
||||
const nghttp3_frame_settings *fr);
|
||||
const nghttp3_frame_settings *fr,
|
||||
int64_t payloadlen);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_settings_len returns the number of bytes
|
||||
* required to write |fr|. fr->hd.length is ignored. This function
|
||||
* stores payload length in |*ppayloadlen|.
|
||||
* required to write |fr|. This function stores the frame payload
|
||||
* length in |*ppayloadlen|.
|
||||
*/
|
||||
size_t nghttp3_frame_write_settings_len(int64_t *pppayloadlen,
|
||||
const nghttp3_frame_settings *fr);
|
||||
|
@ -157,16 +166,18 @@ size_t nghttp3_frame_write_settings_len(int64_t *pppayloadlen,
|
|||
/*
|
||||
* nghttp3_frame_write_goaway writes GOAWAY frame |fr| to |dest|.
|
||||
* This function assumes that |dest| has enough space to write |fr|.
|
||||
* |payloadlen| is the length of the frame payload.
|
||||
*
|
||||
* This function returns |dest| plus the number of bytes written.
|
||||
*/
|
||||
uint8_t *nghttp3_frame_write_goaway(uint8_t *dest,
|
||||
const nghttp3_frame_goaway *fr);
|
||||
const nghttp3_frame_goaway *fr,
|
||||
int64_t payloadlen);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_goaway_len returns the number of bytes required
|
||||
* to write |fr|. fr->hd.length is ignored. This function stores
|
||||
* payload length in |*ppayloadlen|.
|
||||
* to write |fr|. This function stores the frame payload length in
|
||||
* |*ppayloadlen|.
|
||||
*/
|
||||
size_t nghttp3_frame_write_goaway_len(int64_t *ppayloadlen,
|
||||
const nghttp3_frame_goaway *fr);
|
||||
|
@ -174,22 +185,40 @@ size_t nghttp3_frame_write_goaway_len(int64_t *ppayloadlen,
|
|||
/*
|
||||
* nghttp3_frame_write_priority_update writes PRIORITY_UPDATE frame
|
||||
* |fr| to |dest|. This function assumes that |dest| has enough space
|
||||
* to write |fr|.
|
||||
* to write |fr|. |payloadlen| is the length of the frame payload.
|
||||
*
|
||||
* This function returns |dest| plus the number of bytes written;
|
||||
*/
|
||||
uint8_t *
|
||||
nghttp3_frame_write_priority_update(uint8_t *dest,
|
||||
const nghttp3_frame_priority_update *fr);
|
||||
uint8_t *nghttp3_frame_write_priority_update(
|
||||
uint8_t *dest, const nghttp3_frame_priority_update *fr, int64_t payloadlen);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_priority_update_len returns the number of bytes
|
||||
* required to write |fr|. fr->hd.length is ignored. This function
|
||||
* stores payload length in |*ppayloadlen|.
|
||||
* required to write |fr|. This function stores the frame payload
|
||||
* length in |*ppayloadlen|.
|
||||
*/
|
||||
size_t nghttp3_frame_write_priority_update_len(
|
||||
int64_t *ppayloadlen, const nghttp3_frame_priority_update *fr);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_origin writes ORIGIN frame |fr| to |dest|.
|
||||
* This function assumes that |dest| has enough space to write |fr|.
|
||||
* |payloadlen| is the length of the frame payload.
|
||||
*
|
||||
* This function returns |dest| plus the number of bytes written;
|
||||
*/
|
||||
uint8_t *nghttp3_frame_write_origin(uint8_t *dest,
|
||||
const nghttp3_frame_origin *fr,
|
||||
int64_t payloadlen);
|
||||
|
||||
/*
|
||||
* nghttp3_frame_write_origin_len returns the number of bytes required
|
||||
* to write |fr|. This function stores the frame payload length in
|
||||
* |*ppayloadlen|.
|
||||
*/
|
||||
size_t nghttp3_frame_write_origin_len(int64_t *ppayloadlen,
|
||||
const nghttp3_frame_origin *fr);
|
||||
|
||||
/*
|
||||
* nghttp3_nva_copy copies name/value pairs from |nva|, which contains
|
||||
* |nvlen| pairs, to |*nva_ptr|, which is dynamically allocated so
|
||||
|
|
39
deps/ngtcp2/nghttp3/lib/nghttp3_gaptr.c
vendored
39
deps/ngtcp2/nghttp3/lib/nghttp3_gaptr.c
vendored
|
@ -29,14 +29,16 @@
|
|||
#include <assert.h>
|
||||
|
||||
void nghttp3_gaptr_init(nghttp3_gaptr *gaptr, const nghttp3_mem *mem) {
|
||||
nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar, sizeof(nghttp3_range),
|
||||
mem);
|
||||
nghttp3_ksl_init(&gaptr->gap, nghttp3_ksl_range_compar,
|
||||
nghttp3_ksl_range_search, sizeof(nghttp3_range), mem);
|
||||
|
||||
gaptr->mem = mem;
|
||||
}
|
||||
|
||||
static int gaptr_gap_init(nghttp3_gaptr *gaptr) {
|
||||
nghttp3_range range = {0, UINT64_MAX};
|
||||
nghttp3_range range = {
|
||||
.end = UINT64_MAX,
|
||||
};
|
||||
|
||||
return nghttp3_ksl_insert(&gaptr->gap, NULL, &range, NULL);
|
||||
}
|
||||
|
@ -52,7 +54,11 @@ void nghttp3_gaptr_free(nghttp3_gaptr *gaptr) {
|
|||
int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
uint64_t datalen) {
|
||||
int rv;
|
||||
nghttp3_range k, m, l, r, q = {offset, offset + datalen};
|
||||
nghttp3_range k, m, l, r;
|
||||
nghttp3_range q = {
|
||||
.begin = offset,
|
||||
.end = offset + datalen,
|
||||
};
|
||||
nghttp3_ksl_it it;
|
||||
|
||||
if (nghttp3_ksl_len(&gaptr->gap) == 0) {
|
||||
|
@ -62,8 +68,8 @@ int nghttp3_gaptr_push(nghttp3_gaptr *gaptr, uint64_t offset,
|
|||
}
|
||||
}
|
||||
|
||||
it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_compar);
|
||||
it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_search);
|
||||
|
||||
for (; !nghttp3_ksl_it_end(&it);) {
|
||||
k = *(nghttp3_range *)nghttp3_ksl_it_key(&it);
|
||||
|
@ -112,7 +118,10 @@ uint64_t nghttp3_gaptr_first_gap_offset(nghttp3_gaptr *gaptr) {
|
|||
|
||||
nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
|
||||
uint64_t offset) {
|
||||
nghttp3_range q = {offset, offset + 1};
|
||||
nghttp3_range q = {
|
||||
.begin = offset,
|
||||
.end = offset + 1,
|
||||
};
|
||||
nghttp3_ksl_it it;
|
||||
|
||||
if (nghttp3_ksl_len(&gaptr->gap) == 0) {
|
||||
|
@ -120,8 +129,8 @@ nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
|
|||
return r;
|
||||
}
|
||||
|
||||
it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_compar);
|
||||
it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_search);
|
||||
|
||||
assert(!nghttp3_ksl_it_end(&it));
|
||||
|
||||
|
@ -130,7 +139,10 @@ nghttp3_range nghttp3_gaptr_get_first_gap_after(nghttp3_gaptr *gaptr,
|
|||
|
||||
int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
|
||||
uint64_t datalen) {
|
||||
nghttp3_range q = {offset, offset + datalen};
|
||||
nghttp3_range q = {
|
||||
.begin = offset,
|
||||
.end = offset + datalen,
|
||||
};
|
||||
nghttp3_ksl_it it;
|
||||
nghttp3_range m;
|
||||
|
||||
|
@ -138,8 +150,11 @@ int nghttp3_gaptr_is_pushed(nghttp3_gaptr *gaptr, uint64_t offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
it = nghttp3_ksl_lower_bound_compar(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_compar);
|
||||
it = nghttp3_ksl_lower_bound_search(&gaptr->gap, &q,
|
||||
nghttp3_ksl_range_exclusive_search);
|
||||
|
||||
assert(!nghttp3_ksl_it_end(&it));
|
||||
|
||||
m = nghttp3_range_intersect(&q, (nghttp3_range *)nghttp3_ksl_it_key(&it));
|
||||
|
||||
return nghttp3_range_len(&m) == 0;
|
||||
|
|
32
deps/ngtcp2/nghttp3/lib/nghttp3_http.c
vendored
32
deps/ngtcp2/nghttp3/lib/nghttp3_http.c
vendored
|
@ -69,11 +69,11 @@ static int64_t parse_uint(const uint8_t *s, size_t len) {
|
|||
}
|
||||
for (i = 0; i < len; ++i) {
|
||||
if ('0' <= s[i] && s[i] <= '9') {
|
||||
if (n > INT64_MAX / 10) {
|
||||
if (n > (int64_t)NGHTTP3_MAX_VARINT / 10) {
|
||||
return -1;
|
||||
}
|
||||
n *= 10;
|
||||
if (n > INT64_MAX - (s[i] - '0')) {
|
||||
if (n > (int64_t)NGHTTP3_MAX_VARINT - (s[i] - '0')) {
|
||||
return -1;
|
||||
}
|
||||
n += s[i] - '0';
|
||||
|
@ -124,17 +124,17 @@ static int is_ws(uint8_t c) {
|
|||
int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value,
|
||||
size_t valuelen) {
|
||||
nghttp3_pri pri = *dest;
|
||||
sf_parser sfp;
|
||||
sf_vec key;
|
||||
sf_value val;
|
||||
sfparse_parser sfp;
|
||||
sfparse_vec key;
|
||||
sfparse_value val;
|
||||
int rv;
|
||||
|
||||
sf_parser_init(&sfp, value, valuelen);
|
||||
sfparse_parser_init(&sfp, value, valuelen);
|
||||
|
||||
for (;;) {
|
||||
rv = sf_parser_dict(&sfp, &key, &val);
|
||||
rv = sfparse_parser_dict(&sfp, &key, &val);
|
||||
if (rv != 0) {
|
||||
if (rv == SF_ERR_EOF) {
|
||||
if (rv == SFPARSE_ERR_EOF) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value,
|
|||
|
||||
switch (key.base[0]) {
|
||||
case 'i':
|
||||
if (val.type != SF_TYPE_BOOLEAN) {
|
||||
if (val.type != SFPARSE_TYPE_BOOLEAN) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,8 @@ int nghttp3_http_parse_priority(nghttp3_pri *dest, const uint8_t *value,
|
|||
|
||||
break;
|
||||
case 'u':
|
||||
if (val.type != SF_TYPE_INTEGER || val.integer < NGHTTP3_URGENCY_HIGH ||
|
||||
if (val.type != SFPARSE_TYPE_INTEGER ||
|
||||
val.integer < NGHTTP3_URGENCY_HIGH ||
|
||||
NGHTTP3_URGENCY_LOW < val.integer) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
@ -197,7 +198,7 @@ static char VALID_AUTHORITY_CHARS[] = {
|
|||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
|
||||
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
||||
0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
||||
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
||||
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
||||
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||
|
@ -548,6 +549,9 @@ static int http_request_on_header(nghttp3_http_state *http,
|
|||
break;
|
||||
case NGHTTP3_QPACK_TOKEN_PRIORITY:
|
||||
if (!nghttp3_check_header_value(nv->value->base, nv->value->len)) {
|
||||
http->flags &= ~NGHTTP3_HTTP_FLAG_PRIORITY;
|
||||
http->flags |= NGHTTP3_HTTP_FLAG_BAD_PRIORITY;
|
||||
|
||||
return NGHTTP3_ERR_REMOVE_HTTP_HEADER;
|
||||
}
|
||||
|
||||
|
@ -991,7 +995,11 @@ int nghttp3_check_header_value(const uint8_t *value, size_t len) {
|
|||
case 0:
|
||||
return 1;
|
||||
case 1:
|
||||
return !is_ws(*value);
|
||||
if (is_ws(*value)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if (is_ws(*value) || is_ws(*(value + len - 1))) {
|
||||
return 0;
|
||||
|
|
77
deps/ngtcp2/nghttp3/lib/nghttp3_ksl.c
vendored
77
deps/ngtcp2/nghttp3/lib/nghttp3_ksl.c
vendored
|
@ -34,9 +34,9 @@
|
|||
#include "nghttp3_mem.h"
|
||||
#include "nghttp3_range.h"
|
||||
|
||||
static nghttp3_ksl_blk null_blk = {{{NULL, NULL, 0, 0, {0}}}};
|
||||
static nghttp3_ksl_blk null_blk;
|
||||
|
||||
nghttp3_objalloc_def(ksl_blk, nghttp3_ksl_blk, oplent);
|
||||
nghttp3_objalloc_def(ksl_blk, nghttp3_ksl_blk, oplent)
|
||||
|
||||
static size_t ksl_nodelen(size_t keylen) {
|
||||
assert(keylen >= sizeof(uint64_t));
|
||||
|
@ -59,7 +59,8 @@ static void ksl_node_set_key(nghttp3_ksl *ksl, nghttp3_ksl_node *node,
|
|||
}
|
||||
|
||||
void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
|
||||
size_t keylen, const nghttp3_mem *mem) {
|
||||
nghttp3_ksl_search search, size_t keylen,
|
||||
const nghttp3_mem *mem) {
|
||||
size_t nodelen = ksl_nodelen(keylen);
|
||||
|
||||
nghttp3_objalloc_init(&ksl->blkalloc,
|
||||
|
@ -68,6 +69,7 @@ void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
|
|||
ksl->head = NULL;
|
||||
ksl->front = ksl->back = NULL;
|
||||
ksl->compar = compar;
|
||||
ksl->search = search;
|
||||
ksl->n = 0;
|
||||
ksl->keylen = keylen;
|
||||
ksl->nodelen = nodelen;
|
||||
|
@ -274,20 +276,6 @@ static void ksl_insert_node(nghttp3_ksl *ksl, nghttp3_ksl_blk *blk, size_t i,
|
|||
++blk->n;
|
||||
}
|
||||
|
||||
static size_t ksl_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar) {
|
||||
size_t i;
|
||||
nghttp3_ksl_node *node;
|
||||
|
||||
for (i = 0, node = (nghttp3_ksl_node *)(void *)blk->nodes;
|
||||
i < blk->n && compar((nghttp3_ksl_key *)node->key, key);
|
||||
++i, node = (nghttp3_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen))
|
||||
;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
||||
const nghttp3_ksl_key *key, void *data) {
|
||||
nghttp3_ksl_blk *blk;
|
||||
|
@ -312,7 +300,7 @@ int nghttp3_ksl_insert(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
|||
blk = ksl->head;
|
||||
|
||||
for (;;) {
|
||||
i = ksl_search(ksl, blk, key, ksl->compar);
|
||||
i = ksl->search(ksl, blk, key);
|
||||
|
||||
if (blk->leaf) {
|
||||
if (i < blk->n &&
|
||||
|
@ -571,7 +559,7 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
i = ksl_search(ksl, blk, key, ksl->compar);
|
||||
i = ksl->search(ksl, blk, key);
|
||||
|
||||
if (i == blk->n) {
|
||||
if (it) {
|
||||
|
@ -642,12 +630,12 @@ int nghttp3_ksl_remove(nghttp3_ksl *ksl, nghttp3_ksl_it *it,
|
|||
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key) {
|
||||
return nghttp3_ksl_lower_bound_compar(ksl, key, ksl->compar);
|
||||
return nghttp3_ksl_lower_bound_search(ksl, key, ksl->search);
|
||||
}
|
||||
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_search(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar) {
|
||||
nghttp3_ksl_search search) {
|
||||
nghttp3_ksl_blk *blk = ksl->head;
|
||||
nghttp3_ksl_it it;
|
||||
size_t i;
|
||||
|
@ -658,7 +646,7 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
i = ksl_search(ksl, blk, key, compar);
|
||||
i = search(ksl, blk, key);
|
||||
|
||||
if (blk->leaf) {
|
||||
if (i == blk->n && blk->next) {
|
||||
|
@ -702,7 +690,7 @@ void nghttp3_ksl_update_key(nghttp3_ksl *ksl, const nghttp3_ksl_key *old_key,
|
|||
assert(ksl->head);
|
||||
|
||||
for (;;) {
|
||||
i = ksl_search(ksl, blk, old_key, ksl->compar);
|
||||
i = ksl->search(ksl, blk, old_key);
|
||||
|
||||
assert(i < blk->n);
|
||||
node = nghttp3_ksl_nth_node(ksl, blk, i);
|
||||
|
@ -825,9 +813,50 @@ int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs,
|
|||
return a->begin < b->begin;
|
||||
}
|
||||
|
||||
nghttp3_ksl_search_def(range, nghttp3_ksl_range_compar)
|
||||
|
||||
size_t nghttp3_ksl_range_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key) {
|
||||
return ksl_range_search(ksl, blk, key);
|
||||
}
|
||||
|
||||
int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs) {
|
||||
const nghttp3_range *a = lhs, *b = rhs;
|
||||
return a->begin < b->begin && !(nghttp3_max_uint64(a->begin, b->begin) <
|
||||
nghttp3_min_uint64(a->end, b->end));
|
||||
}
|
||||
|
||||
nghttp3_ksl_search_def(range_exclusive, nghttp3_ksl_range_exclusive_compar)
|
||||
|
||||
size_t nghttp3_ksl_range_exclusive_search(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key) {
|
||||
return ksl_range_exclusive_search(ksl, blk, key);
|
||||
}
|
||||
|
||||
int nghttp3_ksl_uint64_less(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs) {
|
||||
return *(uint64_t *)lhs < *(uint64_t *)rhs;
|
||||
}
|
||||
|
||||
nghttp3_ksl_search_def(uint64_less, nghttp3_ksl_uint64_less)
|
||||
|
||||
size_t nghttp3_ksl_uint64_less_search(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key) {
|
||||
return ksl_uint64_less_search(ksl, blk, key);
|
||||
}
|
||||
|
||||
int nghttp3_ksl_int64_greater(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs) {
|
||||
return *(int64_t *)lhs > *(int64_t *)rhs;
|
||||
}
|
||||
|
||||
nghttp3_ksl_search_def(int64_greater, nghttp3_ksl_int64_greater)
|
||||
|
||||
size_t nghttp3_ksl_int64_greater_search(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key) {
|
||||
return ksl_int64_greater_search(ksl, blk, key);
|
||||
}
|
||||
|
|
141
deps/ngtcp2/nghttp3/lib/nghttp3_ksl.h
vendored
141
deps/ngtcp2/nghttp3/lib/nghttp3_ksl.h
vendored
|
@ -104,7 +104,7 @@ struct nghttp3_ksl_blk {
|
|||
};
|
||||
};
|
||||
|
||||
nghttp3_objalloc_decl(ksl_blk, nghttp3_ksl_blk, oplent);
|
||||
nghttp3_objalloc_decl(ksl_blk, nghttp3_ksl_blk, oplent)
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_compar is a function type which returns nonzero if key
|
||||
|
@ -115,6 +115,35 @@ typedef int (*nghttp3_ksl_compar)(const nghttp3_ksl_key *lhs,
|
|||
|
||||
typedef struct nghttp3_ksl nghttp3_ksl;
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_search is a function to search for the first element in
|
||||
* |blk|->nodes which is not ordered before |key|. It returns the
|
||||
* index of such element. It returns |blk|->n if there is no such
|
||||
* element.
|
||||
*/
|
||||
typedef size_t (*nghttp3_ksl_search)(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_search_def is a macro to implement nghttp3_ksl_search
|
||||
* with COMPAR which is supposed to be nghttp3_ksl_compar.
|
||||
*/
|
||||
#define nghttp3_ksl_search_def(NAME, COMPAR) \
|
||||
static size_t ksl_##NAME##_search(const nghttp3_ksl *ksl, \
|
||||
nghttp3_ksl_blk *blk, \
|
||||
const nghttp3_ksl_key *key) { \
|
||||
size_t i; \
|
||||
nghttp3_ksl_node *node; \
|
||||
\
|
||||
for (i = 0, node = (nghttp3_ksl_node *)(void *)blk->nodes; \
|
||||
i < blk->n && COMPAR((nghttp3_ksl_key *)node->key, key); ++i, \
|
||||
node = (nghttp3_ksl_node *)(void *)((uint8_t *)node + ksl->nodelen)) \
|
||||
; \
|
||||
\
|
||||
return i; \
|
||||
}
|
||||
|
||||
typedef struct nghttp3_ksl_it nghttp3_ksl_it;
|
||||
|
||||
/*
|
||||
|
@ -138,6 +167,7 @@ struct nghttp3_ksl {
|
|||
/* back points to the last leaf block. */
|
||||
nghttp3_ksl_blk *back;
|
||||
nghttp3_ksl_compar compar;
|
||||
nghttp3_ksl_search search;
|
||||
/* n is the number of elements stored. */
|
||||
size_t n;
|
||||
/* keylen is the size of key */
|
||||
|
@ -149,11 +179,13 @@ struct nghttp3_ksl {
|
|||
|
||||
/*
|
||||
* nghttp3_ksl_init initializes |ksl|. |compar| specifies compare
|
||||
* function. |keylen| is the length of key and must be at least
|
||||
* function. |search| is a search function which must use |compar|.
|
||||
* |keylen| is the length of key and must be at least
|
||||
* sizeof(uint64_t).
|
||||
*/
|
||||
void nghttp3_ksl_init(nghttp3_ksl *ksl, nghttp3_ksl_compar compar,
|
||||
size_t keylen, const nghttp3_mem *mem);
|
||||
nghttp3_ksl_search search, size_t keylen,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_free frees resources allocated for |ksl|. If |ksl| is
|
||||
|
@ -218,12 +250,12 @@ nghttp3_ksl_it nghttp3_ksl_lower_bound(const nghttp3_ksl *ksl,
|
|||
const nghttp3_ksl_key *key);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_lower_bound_compar works like nghttp3_ksl_lower_bound,
|
||||
* but it takes custom function |compar| to do lower bound search.
|
||||
* nghttp3_ksl_lower_bound_search works like nghttp3_ksl_lower_bound,
|
||||
* but it takes custom function |search| to do lower bound search.
|
||||
*/
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_compar(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_it nghttp3_ksl_lower_bound_search(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_key *key,
|
||||
nghttp3_ksl_compar compar);
|
||||
nghttp3_ksl_search search);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_update_key replaces the key of nodes which has
|
||||
|
@ -263,8 +295,11 @@ void nghttp3_ksl_clear(nghttp3_ksl *ksl);
|
|||
/*
|
||||
* nghttp3_ksl_nth_node returns the |n|th node under |blk|.
|
||||
*/
|
||||
#define nghttp3_ksl_nth_node(KSL, BLK, N) \
|
||||
((nghttp3_ksl_node *)(void *)((BLK)->nodes + (KSL)->nodelen * (N)))
|
||||
static inline nghttp3_ksl_node *nghttp3_ksl_nth_node(const nghttp3_ksl *ksl,
|
||||
const nghttp3_ksl_blk *blk,
|
||||
size_t n) {
|
||||
return (nghttp3_ksl_node *)(void *)(blk->nodes + ksl->nodelen * n);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
/*
|
||||
|
@ -286,18 +321,21 @@ void nghttp3_ksl_it_init(nghttp3_ksl_it *it, const nghttp3_ksl *ksl,
|
|||
* |it| points to. It is undefined to call this function when
|
||||
* nghttp3_ksl_it_end(it) returns nonzero.
|
||||
*/
|
||||
#define nghttp3_ksl_it_get(IT) \
|
||||
nghttp3_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->data
|
||||
static inline void *nghttp3_ksl_it_get(const nghttp3_ksl_it *it) {
|
||||
return nghttp3_ksl_nth_node(it->ksl, it->blk, it->i)->data;
|
||||
}
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_next advances the iterator by one. It is undefined
|
||||
* if this function is called when nghttp3_ksl_it_end(it) returns
|
||||
* nonzero.
|
||||
*/
|
||||
#define nghttp3_ksl_it_next(IT) \
|
||||
(++(IT)->i == (IT)->blk->n && (IT)->blk->next \
|
||||
? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \
|
||||
: 0)
|
||||
static inline void nghttp3_ksl_it_next(nghttp3_ksl_it *it) {
|
||||
if (++it->i == it->blk->n && it->blk->next) {
|
||||
it->blk = it->blk->next;
|
||||
it->i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_prev moves backward the iterator by one. It is
|
||||
|
@ -310,8 +348,9 @@ void nghttp3_ksl_it_prev(nghttp3_ksl_it *it);
|
|||
* nghttp3_ksl_it_end returns nonzero if |it| points to the one beyond
|
||||
* the last node.
|
||||
*/
|
||||
#define nghttp3_ksl_it_end(IT) \
|
||||
((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL)
|
||||
static inline int nghttp3_ksl_it_end(const nghttp3_ksl_it *it) {
|
||||
return it->blk->n == it->i && it->blk->next == NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_it_begin returns nonzero if |it| points to the first
|
||||
|
@ -325,27 +364,75 @@ int nghttp3_ksl_it_begin(const nghttp3_ksl_it *it);
|
|||
* It is undefined to call this function when nghttp3_ksl_it_end(it)
|
||||
* returns nonzero.
|
||||
*/
|
||||
#define nghttp3_ksl_it_key(IT) \
|
||||
((nghttp3_ksl_key *)nghttp3_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->key)
|
||||
static inline nghttp3_ksl_key *nghttp3_ksl_it_key(const nghttp3_ksl_it *it) {
|
||||
return (nghttp3_ksl_key *)nghttp3_ksl_nth_node(it->ksl, it->blk, it->i)->key;
|
||||
}
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_range_compar is an implementation of
|
||||
* nghttp3_ksl_compar. lhs->ptr and rhs->ptr must point to
|
||||
* nghttp3_range object and the function returns nonzero if (const
|
||||
* nghttp3_range *)(lhs->ptr)->begin < (const nghttp3_range
|
||||
* *)(rhs->ptr)->begin.
|
||||
* nghttp3_ksl_compar. |lhs| and |rhs| must point to nghttp3_range
|
||||
* object, and the function returns nonzero if ((const nghttp3_range
|
||||
* *)lhs)->begin < ((const nghttp3_range *)rhs)->begin.
|
||||
*/
|
||||
int nghttp3_ksl_range_compar(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_range_search is an implementation of nghttp3_ksl_search
|
||||
* that uses nghttp3_ksl_range_compar.
|
||||
*/
|
||||
size_t nghttp3_ksl_range_search(const nghttp3_ksl *ksl, nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_range_exclusive_compar is an implementation of
|
||||
* nghttp3_ksl_compar. lhs->ptr and rhs->ptr must point to
|
||||
* nghttp3_range object and the function returns nonzero if (const
|
||||
* nghttp3_range *)(lhs->ptr)->begin < (const nghttp3_range
|
||||
* *)(rhs->ptr)->begin and the 2 ranges do not intersect.
|
||||
* nghttp3_ksl_compar. |lhs| and |rhs| must point to nghttp3_range
|
||||
* object, and the function returns nonzero if ((const nghttp3_range
|
||||
* *)lhs)->begin < ((const nghttp3_range *)rhs)->begin, and the 2
|
||||
* ranges do not intersect.
|
||||
*/
|
||||
int nghttp3_ksl_range_exclusive_compar(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_range_exclusive_search is an implementation of
|
||||
* nghttp3_ksl_search that uses nghttp3_ksl_range_exclusive_compar.
|
||||
*/
|
||||
size_t nghttp3_ksl_range_exclusive_search(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_uint64_less is an implementation of nghttp3_ksl_compar.
|
||||
* |lhs| and |rhs| must point to uint64_t objects, and the function
|
||||
* returns nonzero if *(uint64_t *)|lhs| < *(uint64_t *)|rhs|.
|
||||
*/
|
||||
int nghttp3_ksl_uint64_less(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_uint64_less_search is an implementation of
|
||||
* nghttp3_ksl_search that uses nghttp3_ksl_uint64_less.
|
||||
*/
|
||||
size_t nghttp3_ksl_uint64_less_search(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_int64_greater is an implementation of
|
||||
* nghttp3_ksl_compar. |lhs| and |rhs| must point to int64_t objects,
|
||||
* and the function returns nonzero if *(int64_t *)|lhs| > *(int64_t
|
||||
* *)|rhs|.
|
||||
*/
|
||||
int nghttp3_ksl_int64_greater(const nghttp3_ksl_key *lhs,
|
||||
const nghttp3_ksl_key *rhs);
|
||||
|
||||
/*
|
||||
* nghttp3_ksl_int64_greater_search is an implementation of
|
||||
* nghttp3_ksl_search that uses nghttp3_ksl_int64_greater.
|
||||
*/
|
||||
size_t nghttp3_ksl_int64_greater_search(const nghttp3_ksl *ksl,
|
||||
nghttp3_ksl_blk *blk,
|
||||
const nghttp3_ksl_key *key);
|
||||
|
||||
#endif /* !defined(NGHTTP3_KSL_H) */
|
||||
|
|
36
deps/ngtcp2/nghttp3/lib/nghttp3_macro.h
vendored
36
deps/ngtcp2/nghttp3/lib/nghttp3_macro.h
vendored
|
@ -48,27 +48,27 @@
|
|||
#define nghttp3_max_def(SUFFIX, T) \
|
||||
static inline T nghttp3_max_##SUFFIX(T a, T b) { return a < b ? b : a; }
|
||||
|
||||
nghttp3_max_def(int8, int8_t);
|
||||
nghttp3_max_def(int16, int16_t);
|
||||
nghttp3_max_def(int32, int32_t);
|
||||
nghttp3_max_def(int64, int64_t);
|
||||
nghttp3_max_def(uint8, uint8_t);
|
||||
nghttp3_max_def(uint16, uint16_t);
|
||||
nghttp3_max_def(uint32, uint32_t);
|
||||
nghttp3_max_def(uint64, uint64_t);
|
||||
nghttp3_max_def(size, size_t);
|
||||
nghttp3_max_def(int8, int8_t)
|
||||
nghttp3_max_def(int16, int16_t)
|
||||
nghttp3_max_def(int32, int32_t)
|
||||
nghttp3_max_def(int64, int64_t)
|
||||
nghttp3_max_def(uint8, uint8_t)
|
||||
nghttp3_max_def(uint16, uint16_t)
|
||||
nghttp3_max_def(uint32, uint32_t)
|
||||
nghttp3_max_def(uint64, uint64_t)
|
||||
nghttp3_max_def(size, size_t)
|
||||
|
||||
#define nghttp3_min_def(SUFFIX, T) \
|
||||
static inline T nghttp3_min_##SUFFIX(T a, T b) { return a < b ? a : b; }
|
||||
|
||||
nghttp3_min_def(int8, int8_t);
|
||||
nghttp3_min_def(int16, int16_t);
|
||||
nghttp3_min_def(int32, int32_t);
|
||||
nghttp3_min_def(int64, int64_t);
|
||||
nghttp3_min_def(uint8, uint8_t);
|
||||
nghttp3_min_def(uint16, uint16_t);
|
||||
nghttp3_min_def(uint32, uint32_t);
|
||||
nghttp3_min_def(uint64, uint64_t);
|
||||
nghttp3_min_def(size, size_t);
|
||||
nghttp3_min_def(int8, int8_t)
|
||||
nghttp3_min_def(int16, int16_t)
|
||||
nghttp3_min_def(int32, int32_t)
|
||||
nghttp3_min_def(int64, int64_t)
|
||||
nghttp3_min_def(uint8, uint8_t)
|
||||
nghttp3_min_def(uint16, uint16_t)
|
||||
nghttp3_min_def(uint32, uint32_t)
|
||||
nghttp3_min_def(uint64, uint64_t)
|
||||
nghttp3_min_def(size, size_t)
|
||||
|
||||
#endif /* !defined(NGHTTP3_MACRO_H) */
|
||||
|
|
67
deps/ngtcp2/nghttp3/lib/nghttp3_map.c
vendored
67
deps/ngtcp2/nghttp3/lib/nghttp3_map.c
vendored
|
@ -32,12 +32,13 @@
|
|||
|
||||
#include "nghttp3_conv.h"
|
||||
|
||||
#define NGHTTP3_INITIAL_TABLE_LENBITS 4
|
||||
#define NGHTTP3_INITIAL_HASHBITS 4
|
||||
|
||||
void nghttp3_map_init(nghttp3_map *map, const nghttp3_mem *mem) {
|
||||
void nghttp3_map_init(nghttp3_map *map, uint64_t seed, const nghttp3_mem *mem) {
|
||||
map->mem = mem;
|
||||
map->hashbits = 0;
|
||||
map->table = NULL;
|
||||
map->seed = seed;
|
||||
map->size = 0;
|
||||
}
|
||||
|
||||
|
@ -78,8 +79,14 @@ int nghttp3_map_each(const nghttp3_map *map, int (*func)(void *data, void *ptr),
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t hash(nghttp3_map_key_type key, size_t bits) {
|
||||
return (size_t)((key * 11400714819323198485llu) >> (64 - bits));
|
||||
static size_t map_hash(const nghttp3_map *map, nghttp3_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. */
|
||||
key += map->seed;
|
||||
key *= 0xf1357aea2e62a9c5ull;
|
||||
return (size_t)((key * 11400714819323198485llu) >> (64 - map->hashbits));
|
||||
}
|
||||
|
||||
static void map_bucket_swap(nghttp3_map_bucket *a, nghttp3_map_bucket *b) {
|
||||
|
@ -110,24 +117,28 @@ void nghttp3_map_print_distance(const nghttp3_map *map) {
|
|||
continue;
|
||||
}
|
||||
|
||||
idx = hash(bkt->key, map->hashbits);
|
||||
idx = map_hash(map, bkt->key);
|
||||
fprintf(stderr, "@%zu hash=%zu key=%" PRIu64 " base=%zu distance=%u\n", i,
|
||||
hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl);
|
||||
map_hash(map, bkt->key), bkt->key, idx, bkt->psl);
|
||||
}
|
||||
}
|
||||
#endif /* !defined(WIN32) */
|
||||
|
||||
static int insert(nghttp3_map_bucket *table, size_t hashbits,
|
||||
nghttp3_map_key_type key, void *data) {
|
||||
size_t idx = hash(key, hashbits);
|
||||
nghttp3_map_bucket b = {0, key, data}, *bkt;
|
||||
size_t mask = (1u << hashbits) - 1;
|
||||
static int map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data) {
|
||||
size_t idx = map_hash(map, key);
|
||||
nghttp3_map_bucket b = {
|
||||
.key = key,
|
||||
.data = data,
|
||||
};
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
bkt = &table[idx];
|
||||
bkt = &map->table[idx];
|
||||
|
||||
if (bkt->data == NULL) {
|
||||
*bkt = b;
|
||||
++map->size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -148,15 +159,19 @@ static int insert(nghttp3_map_bucket *table, size_t hashbits,
|
|||
|
||||
static int map_resize(nghttp3_map *map, size_t new_hashbits) {
|
||||
size_t i;
|
||||
nghttp3_map_bucket *new_table;
|
||||
nghttp3_map_bucket *bkt;
|
||||
size_t tablelen;
|
||||
int rv;
|
||||
nghttp3_map new_map = {
|
||||
.table = nghttp3_mem_calloc(map->mem, 1u << new_hashbits,
|
||||
sizeof(nghttp3_map_bucket)),
|
||||
.mem = map->mem,
|
||||
.seed = map->seed,
|
||||
.hashbits = new_hashbits,
|
||||
};
|
||||
(void)rv;
|
||||
|
||||
new_table = nghttp3_mem_calloc(map->mem, 1u << new_hashbits,
|
||||
sizeof(nghttp3_map_bucket));
|
||||
if (new_table == NULL) {
|
||||
if (new_map.table == NULL) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
|
@ -169,15 +184,15 @@ static int map_resize(nghttp3_map *map, size_t new_hashbits) {
|
|||
continue;
|
||||
}
|
||||
|
||||
rv = insert(new_table, new_hashbits, bkt->key, bkt->data);
|
||||
rv = map_insert(&new_map, bkt->key, bkt->data);
|
||||
|
||||
assert(0 == rv);
|
||||
}
|
||||
}
|
||||
|
||||
nghttp3_mem_free(map->mem, map->table);
|
||||
map->table = new_map.table;
|
||||
map->hashbits = new_hashbits;
|
||||
map->table = new_table;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -187,30 +202,28 @@ int nghttp3_map_insert(nghttp3_map *map, nghttp3_map_key_type key, void *data) {
|
|||
|
||||
assert(data);
|
||||
|
||||
/* Load factor is 0.75 */
|
||||
/* Load factor is 7/8 */
|
||||
/* Under the very initial condition, that is map->size == 0 and
|
||||
map->hashbits == 0, 4 > 3 still holds nicely. */
|
||||
if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) {
|
||||
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, NGHTTP3_INITIAL_TABLE_LENBITS);
|
||||
rv = map_resize(map, NGHTTP3_INITIAL_HASHBITS);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = insert(map->table, map->hashbits, key, data);
|
||||
rv = map_insert(map, key, data);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
++map->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -224,7 +237,7 @@ void *nghttp3_map_find(const nghttp3_map *map, nghttp3_map_key_type key) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
idx = hash(key, map->hashbits);
|
||||
idx = map_hash(map, key);
|
||||
mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
|
@ -253,7 +266,7 @@ int nghttp3_map_remove(nghttp3_map *map, nghttp3_map_key_type key) {
|
|||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
idx = hash(key, map->hashbits);
|
||||
idx = map_hash(map, key);
|
||||
mask = (1u << map->hashbits) - 1;
|
||||
|
||||
for (;;) {
|
||||
|
|
3
deps/ngtcp2/nghttp3/lib/nghttp3_map.h
vendored
3
deps/ngtcp2/nghttp3/lib/nghttp3_map.h
vendored
|
@ -48,6 +48,7 @@ typedef struct nghttp3_map_bucket {
|
|||
typedef struct nghttp3_map {
|
||||
nghttp3_map_bucket *table;
|
||||
const nghttp3_mem *mem;
|
||||
uint64_t seed;
|
||||
size_t size;
|
||||
size_t hashbits;
|
||||
} nghttp3_map;
|
||||
|
@ -55,7 +56,7 @@ typedef struct nghttp3_map {
|
|||
/*
|
||||
* nghttp3_map_init initializes the map |map|.
|
||||
*/
|
||||
void nghttp3_map_init(nghttp3_map *map, const nghttp3_mem *mem);
|
||||
void nghttp3_map_init(nghttp3_map *map, uint64_t seed, const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* nghttp3_map_free deallocates any resources allocated for |map|.
|
||||
|
|
16
deps/ngtcp2/nghttp3/lib/nghttp3_pq.c
vendored
16
deps/ngtcp2/nghttp3/lib/nghttp3_pq.c
vendored
|
@ -164,20 +164,4 @@ int nghttp3_pq_empty(const nghttp3_pq *pq) { return pq->length == 0; }
|
|||
|
||||
size_t nghttp3_pq_size(const nghttp3_pq *pq) { return pq->length; }
|
||||
|
||||
int nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg) {
|
||||
size_t i;
|
||||
|
||||
if (pq->length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < pq->length; ++i) {
|
||||
if ((*fun)(pq->q[i], arg)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp3_pq_clear(nghttp3_pq *pq) { pq->length = 0; }
|
||||
|
|
11
deps/ngtcp2/nghttp3/lib/nghttp3_pq.h
vendored
11
deps/ngtcp2/nghttp3/lib/nghttp3_pq.h
vendored
|
@ -112,17 +112,6 @@ int nghttp3_pq_empty(const nghttp3_pq *pq);
|
|||
*/
|
||||
size_t nghttp3_pq_size(const nghttp3_pq *pq);
|
||||
|
||||
typedef int (*nghttp3_pq_item_cb)(nghttp3_pq_entry *item, void *arg);
|
||||
|
||||
/*
|
||||
* nghttp3_pq_each applies |fun| to each item in |pq|. The |arg| is
|
||||
* passed as arg parameter to callback function. This function must
|
||||
* not change the ordering key. If the return value from callback is
|
||||
* nonzero, this function returns 1 immediately without iterating
|
||||
* remaining items. Otherwise this function returns 0.
|
||||
*/
|
||||
int nghttp3_pq_each(const nghttp3_pq *pq, nghttp3_pq_item_cb fun, void *arg);
|
||||
|
||||
/*
|
||||
* nghttp3_pq_remove removes |item| from |pq|. |pq| must contain
|
||||
* |item| otherwise the behavior is undefined.
|
||||
|
|
202
deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c
vendored
202
deps/ngtcp2/nghttp3/lib/nghttp3_qpack.c
vendored
|
@ -41,7 +41,12 @@
|
|||
#define NGHTTP3_QPACK_MAX_QPACK_STREAMS 2000
|
||||
|
||||
/* Make scalar initialization form of nghttp3_qpack_static_entry */
|
||||
#define MAKE_STATIC_ENT(I, T, H) {I, T, H}
|
||||
#define MAKE_STATIC_ENT(I, T, H) \
|
||||
{ \
|
||||
.absidx = I, \
|
||||
.token = T, \
|
||||
.hash = H, \
|
||||
}
|
||||
|
||||
/* Generated by mkstatichdtbl.py */
|
||||
static nghttp3_qpack_static_entry token_stable[] = {
|
||||
|
@ -166,9 +171,19 @@ static nghttp3_qpack_static_entry token_stable[] = {
|
|||
/* Make scalar initialization form of nghttp3_qpack_static_entry */
|
||||
#define MAKE_STATIC_HD(N, V, T) \
|
||||
{ \
|
||||
{NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \
|
||||
{NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \
|
||||
T, \
|
||||
.name = \
|
||||
{ \
|
||||
.base = (uint8_t *)(N), \
|
||||
.len = sizeof((N)) - 1, \
|
||||
.ref = -1, \
|
||||
}, \
|
||||
.value = \
|
||||
{ \
|
||||
.base = (uint8_t *)(V), \
|
||||
.len = sizeof((V)) - 1, \
|
||||
.ref = -1, \
|
||||
}, \
|
||||
.token = T, \
|
||||
}
|
||||
|
||||
static nghttp3_qpack_static_header stable[] = {
|
||||
|
@ -828,29 +843,12 @@ static void encoder_qpack_map_find(nghttp3_qpack_encoder *encoder,
|
|||
* ctx->max_dtable_capacity and it is initialized to 0.
|
||||
* |hard_max_dtable_capacity| is the upper bound of
|
||||
* ctx->max_dtable_capacity.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
static int qpack_context_init(nghttp3_qpack_context *ctx,
|
||||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem) {
|
||||
int rv;
|
||||
size_t len = 4096 / NGHTTP3_QPACK_ENTRY_OVERHEAD;
|
||||
size_t len2;
|
||||
|
||||
for (len2 = 1; len2 < len; len2 <<= 1)
|
||||
;
|
||||
|
||||
rv = nghttp3_ringbuf_init(&ctx->dtable, len2, sizeof(nghttp3_qpack_entry *),
|
||||
mem);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
static void qpack_context_init(nghttp3_qpack_context *ctx,
|
||||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem) {
|
||||
nghttp3_ringbuf_init(&ctx->dtable, 0, sizeof(nghttp3_qpack_entry *), mem);
|
||||
|
||||
ctx->mem = mem;
|
||||
ctx->dtable_size = 0;
|
||||
|
@ -860,8 +858,6 @@ static int qpack_context_init(nghttp3_qpack_context *ctx,
|
|||
ctx->max_blocked_streams = max_blocked_streams;
|
||||
ctx->next_absidx = 0;
|
||||
ctx->bad = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qpack_context_free(nghttp3_qpack_context *ctx) {
|
||||
|
@ -898,19 +894,17 @@ static int max_cnt_greater(const nghttp3_ksl_key *lhs,
|
|||
return a->max_cnt > b->max_cnt || (a->max_cnt == b->max_cnt && a->id < b->id);
|
||||
}
|
||||
|
||||
int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
const nghttp3_mem *mem) {
|
||||
int rv;
|
||||
nghttp3_ksl_search_def(max_cnt_greater, max_cnt_greater)
|
||||
|
||||
rv = qpack_context_init(&encoder->ctx, hard_max_dtable_capacity, 0, mem);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
void nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
|
||||
size_t hard_max_dtable_capacity, uint64_t seed,
|
||||
const nghttp3_mem *mem) {
|
||||
qpack_context_init(&encoder->ctx, hard_max_dtable_capacity, 0, mem);
|
||||
|
||||
nghttp3_map_init(&encoder->streams, mem);
|
||||
nghttp3_map_init(&encoder->streams, seed, mem);
|
||||
|
||||
nghttp3_ksl_init(&encoder->blocked_streams, max_cnt_greater,
|
||||
ksl_max_cnt_greater_search,
|
||||
sizeof(nghttp3_blocked_streams_key), mem);
|
||||
|
||||
qpack_map_init(&encoder->dtable_map);
|
||||
|
@ -925,8 +919,6 @@ int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
|
|||
encoder->flags = NGHTTP3_QPACK_ENCODER_FLAG_NONE;
|
||||
|
||||
nghttp3_qpack_read_state_reset(&encoder->rstate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int map_stream_free(void *data, void *ptr) {
|
||||
|
@ -1149,6 +1141,9 @@ int nghttp3_qpack_encoder_encode(nghttp3_qpack_encoder *encoder,
|
|||
int blocked_stream;
|
||||
nghttp3_qpack_stream *stream;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (encoder->ctx.bad) {
|
||||
return NGHTTP3_ERR_QPACK_FATAL;
|
||||
}
|
||||
|
@ -1444,7 +1439,14 @@ int nghttp3_qpack_encoder_encode_nv(nghttp3_qpack_encoder *encoder,
|
|||
uint32_t hash = 0;
|
||||
int32_t token;
|
||||
nghttp3_qpack_indexing_mode indexing_mode;
|
||||
nghttp3_qpack_lookup_result sres = {-1, 0, -1}, dres = {-1, 0, -1};
|
||||
nghttp3_qpack_lookup_result sres = {
|
||||
.index = -1,
|
||||
.pb_index = -1,
|
||||
};
|
||||
nghttp3_qpack_lookup_result dres = {
|
||||
.index = -1,
|
||||
.pb_index = -1,
|
||||
};
|
||||
nghttp3_qpack_entry *new_ent = NULL;
|
||||
int static_entry;
|
||||
int just_index = 0;
|
||||
|
@ -1608,8 +1610,10 @@ int nghttp3_qpack_encoder_encode_nv(nghttp3_qpack_encoder *encoder,
|
|||
nghttp3_qpack_lookup_result
|
||||
nghttp3_qpack_lookup_stable(const nghttp3_nv *nv, int32_t token,
|
||||
nghttp3_qpack_indexing_mode indexing_mode) {
|
||||
nghttp3_qpack_lookup_result res = {(nghttp3_ssize)token_stable[token].absidx,
|
||||
0, -1};
|
||||
nghttp3_qpack_lookup_result res = {
|
||||
.index = (nghttp3_ssize)token_stable[token].absidx,
|
||||
.pb_index = -1,
|
||||
};
|
||||
nghttp3_qpack_static_entry *ent;
|
||||
nghttp3_qpack_static_header *hdr;
|
||||
size_t i;
|
||||
|
@ -1639,7 +1643,10 @@ nghttp3_qpack_lookup_result nghttp3_qpack_encoder_lookup_dtable(
|
|||
nghttp3_qpack_encoder *encoder, const nghttp3_nv *nv, int32_t token,
|
||||
uint32_t hash, nghttp3_qpack_indexing_mode indexing_mode, uint64_t krcnt,
|
||||
int allow_blocking) {
|
||||
nghttp3_qpack_lookup_result res = {-1, 0, -1};
|
||||
nghttp3_qpack_lookup_result res = {
|
||||
.index = -1,
|
||||
.pb_index = -1,
|
||||
};
|
||||
int exact_match = 0;
|
||||
nghttp3_qpack_entry *match, *pb_match;
|
||||
|
||||
|
@ -1694,7 +1701,6 @@ static int ref_max_cnt_greater(const nghttp3_pq_entry *lhsx,
|
|||
|
||||
int nghttp3_qpack_stream_new(nghttp3_qpack_stream **pstream, int64_t stream_id,
|
||||
const nghttp3_mem *mem) {
|
||||
int rv;
|
||||
nghttp3_qpack_stream *stream;
|
||||
|
||||
stream = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_stream));
|
||||
|
@ -1702,12 +1708,8 @@ int nghttp3_qpack_stream_new(nghttp3_qpack_stream **pstream, int64_t stream_id,
|
|||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
rv = nghttp3_ringbuf_init(&stream->refs, 4,
|
||||
sizeof(nghttp3_qpack_header_block_ref *), mem);
|
||||
if (rv != 0) {
|
||||
nghttp3_mem_free(mem, stream);
|
||||
return rv;
|
||||
}
|
||||
nghttp3_ringbuf_init(&stream->refs, 0,
|
||||
sizeof(nghttp3_qpack_header_block_ref *), mem);
|
||||
|
||||
nghttp3_pq_init(&stream->max_cnts, ref_max_cnt_greater, mem);
|
||||
|
||||
|
@ -1759,17 +1761,23 @@ int nghttp3_qpack_stream_add_ref(nghttp3_qpack_stream *stream,
|
|||
int rv;
|
||||
|
||||
if (nghttp3_ringbuf_full(&stream->refs)) {
|
||||
rv = nghttp3_ringbuf_reserve(&stream->refs,
|
||||
nghttp3_ringbuf_len(&stream->refs) * 2);
|
||||
rv = nghttp3_ringbuf_reserve(
|
||||
&stream->refs,
|
||||
nghttp3_max_size(4, nghttp3_ringbuf_len(&stream->refs) * 2));
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
rv = nghttp3_pq_push(&stream->max_cnts, &ref->max_cnts_pe);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
dest = nghttp3_ringbuf_push_back(&stream->refs);
|
||||
*dest = ref;
|
||||
|
||||
return nghttp3_pq_push(&stream->max_cnts, &ref->max_cnts_pe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp3_qpack_stream_pop_ref(nghttp3_qpack_stream *stream) {
|
||||
|
@ -1834,7 +1842,7 @@ static int qpack_encoder_write_indexed_name(nghttp3_qpack_encoder *encoder,
|
|||
int h = 0;
|
||||
|
||||
hlen = nghttp3_qpack_huffman_encode_count(nv->value, nv->valuelen);
|
||||
if (hlen * 4 < nv->valuelen * 3) {
|
||||
if (hlen < nv->valuelen) {
|
||||
h = 1;
|
||||
len += nghttp3_qpack_put_varint_len(hlen, 7) + hlen;
|
||||
} else {
|
||||
|
@ -1925,7 +1933,7 @@ static int qpack_encoder_write_literal(nghttp3_qpack_encoder *encoder,
|
|||
int nh = 0, vh = 0;
|
||||
|
||||
nhlen = nghttp3_qpack_huffman_encode_count(nv->name, nv->namelen);
|
||||
if (nhlen * 4 < nv->namelen * 3) {
|
||||
if (nhlen < nv->namelen) {
|
||||
nh = 1;
|
||||
len = nghttp3_qpack_put_varint_len(nhlen, prefix) + nhlen;
|
||||
} else {
|
||||
|
@ -1933,7 +1941,7 @@ static int qpack_encoder_write_literal(nghttp3_qpack_encoder *encoder,
|
|||
}
|
||||
|
||||
vhlen = nghttp3_qpack_huffman_encode_count(nv->value, nv->valuelen);
|
||||
if (vhlen * 4 < nv->valuelen * 3) {
|
||||
if (vhlen < nv->valuelen) {
|
||||
vh = 1;
|
||||
len += nghttp3_qpack_put_varint_len(vhlen, 7) + vhlen;
|
||||
} else {
|
||||
|
@ -2083,8 +2091,9 @@ int nghttp3_qpack_context_dtable_add(nghttp3_qpack_context *ctx,
|
|||
hash);
|
||||
|
||||
if (nghttp3_ringbuf_full(&ctx->dtable)) {
|
||||
rv = nghttp3_ringbuf_reserve(&ctx->dtable,
|
||||
nghttp3_ringbuf_len(&ctx->dtable) * 2);
|
||||
rv = nghttp3_ringbuf_reserve(
|
||||
&ctx->dtable,
|
||||
nghttp3_max_size(128, nghttp3_ringbuf_len(&ctx->dtable) * 2));
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
@ -2259,10 +2268,11 @@ void nghttp3_qpack_entry_free(nghttp3_qpack_entry *ent) {
|
|||
int nghttp3_qpack_encoder_block_stream(nghttp3_qpack_encoder *encoder,
|
||||
nghttp3_qpack_stream *stream) {
|
||||
nghttp3_blocked_streams_key bsk = {
|
||||
nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
|
||||
nghttp3_qpack_header_block_ref, max_cnts_pe)
|
||||
->max_cnt,
|
||||
(uint64_t)stream->stream_id};
|
||||
.max_cnt = nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
|
||||
nghttp3_qpack_header_block_ref, max_cnts_pe)
|
||||
->max_cnt,
|
||||
.id = (uint64_t)stream->stream_id,
|
||||
};
|
||||
|
||||
return nghttp3_ksl_insert(&encoder->blocked_streams, NULL, &bsk, stream);
|
||||
}
|
||||
|
@ -2270,10 +2280,11 @@ int nghttp3_qpack_encoder_block_stream(nghttp3_qpack_encoder *encoder,
|
|||
void nghttp3_qpack_encoder_unblock_stream(nghttp3_qpack_encoder *encoder,
|
||||
nghttp3_qpack_stream *stream) {
|
||||
nghttp3_blocked_streams_key bsk = {
|
||||
nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
|
||||
nghttp3_qpack_header_block_ref, max_cnts_pe)
|
||||
->max_cnt,
|
||||
(uint64_t)stream->stream_id};
|
||||
.max_cnt = nghttp3_struct_of(nghttp3_pq_top(&stream->max_cnts),
|
||||
nghttp3_qpack_header_block_ref, max_cnts_pe)
|
||||
->max_cnt,
|
||||
.id = (uint64_t)stream->stream_id,
|
||||
};
|
||||
nghttp3_ksl_it it;
|
||||
|
||||
/* This is purely debugging purpose only */
|
||||
|
@ -2287,7 +2298,9 @@ void nghttp3_qpack_encoder_unblock_stream(nghttp3_qpack_encoder *encoder,
|
|||
|
||||
void nghttp3_qpack_encoder_unblock(nghttp3_qpack_encoder *encoder,
|
||||
uint64_t max_cnt) {
|
||||
nghttp3_blocked_streams_key bsk = {max_cnt, 0};
|
||||
nghttp3_blocked_streams_key bsk = {
|
||||
.max_cnt = max_cnt,
|
||||
};
|
||||
nghttp3_ksl_it it;
|
||||
|
||||
it = nghttp3_ksl_lower_bound(&encoder->blocked_streams, &bsk);
|
||||
|
@ -2667,17 +2680,12 @@ void nghttp3_qpack_read_state_reset(nghttp3_qpack_read_state *rstate) {
|
|||
rstate->huffman_encoded = 0;
|
||||
}
|
||||
|
||||
int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem) {
|
||||
int rv;
|
||||
|
||||
rv = qpack_context_init(&decoder->ctx, hard_max_dtable_capacity,
|
||||
max_blocked_streams, mem);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
void nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem) {
|
||||
qpack_context_init(&decoder->ctx, hard_max_dtable_capacity,
|
||||
max_blocked_streams, mem);
|
||||
|
||||
decoder->state = NGHTTP3_QPACK_ES_STATE_OPCODE;
|
||||
decoder->opcode = 0;
|
||||
|
@ -2687,8 +2695,6 @@ int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder,
|
|||
|
||||
nghttp3_qpack_read_state_reset(&decoder->rstate);
|
||||
nghttp3_buf_init(&decoder->dbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp3_qpack_decoder_free(nghttp3_qpack_decoder *decoder) {
|
||||
|
@ -3171,6 +3177,7 @@ int nghttp3_qpack_decoder_dtable_static_add(nghttp3_qpack_decoder *decoder) {
|
|||
rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
|
||||
|
||||
nghttp3_rcbuf_decref(qnv.value);
|
||||
decoder->rstate.value = NULL;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -3197,6 +3204,7 @@ int nghttp3_qpack_decoder_dtable_dynamic_add(nghttp3_qpack_decoder *decoder) {
|
|||
rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
|
||||
|
||||
nghttp3_rcbuf_decref(qnv.value);
|
||||
decoder->rstate.value = NULL;
|
||||
nghttp3_rcbuf_decref(qnv.name);
|
||||
|
||||
return rv;
|
||||
|
@ -3250,7 +3258,9 @@ int nghttp3_qpack_decoder_dtable_literal_add(nghttp3_qpack_decoder *decoder) {
|
|||
rv = nghttp3_qpack_context_dtable_add(&decoder->ctx, &qnv, NULL, 0);
|
||||
|
||||
nghttp3_rcbuf_decref(qnv.value);
|
||||
decoder->rstate.value = NULL;
|
||||
nghttp3_rcbuf_decref(qnv.name);
|
||||
decoder->rstate.name = NULL;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -3818,6 +3828,9 @@ int nghttp3_qpack_decoder_cancel_stream(nghttp3_qpack_decoder *decoder,
|
|||
uint8_t *p;
|
||||
int rv;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
if (qpack_decoder_dbuf_overflow(decoder)) {
|
||||
return NGHTTP3_ERR_QPACK_FATAL;
|
||||
}
|
||||
|
@ -4059,10 +4072,9 @@ void nghttp3_qpack_decoder_emit_literal(nghttp3_qpack_decoder *decoder,
|
|||
sctx->rstate.value = NULL;
|
||||
}
|
||||
|
||||
int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
const nghttp3_mem *mem) {
|
||||
int rv;
|
||||
int nghttp3_qpack_encoder_new2(nghttp3_qpack_encoder **pencoder,
|
||||
size_t hard_max_dtable_capacity, uint64_t seed,
|
||||
const nghttp3_mem *mem) {
|
||||
nghttp3_qpack_encoder *p;
|
||||
|
||||
p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_encoder));
|
||||
|
@ -4070,16 +4082,19 @@ int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder,
|
|||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
rv = nghttp3_qpack_encoder_init(p, hard_max_dtable_capacity, mem);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
nghttp3_qpack_encoder_init(p, hard_max_dtable_capacity, seed, mem);
|
||||
|
||||
*pencoder = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nghttp3_qpack_encoder_new(nghttp3_qpack_encoder **pencoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
const nghttp3_mem *mem) {
|
||||
return nghttp3_qpack_encoder_new2(pencoder, hard_max_dtable_capacity, 0, mem);
|
||||
}
|
||||
|
||||
void nghttp3_qpack_encoder_del(nghttp3_qpack_encoder *encoder) {
|
||||
const nghttp3_mem *mem;
|
||||
|
||||
|
@ -4098,6 +4113,9 @@ int nghttp3_qpack_stream_context_new(nghttp3_qpack_stream_context **psctx,
|
|||
const nghttp3_mem *mem) {
|
||||
nghttp3_qpack_stream_context *p;
|
||||
|
||||
assert(stream_id >= 0);
|
||||
assert(stream_id <= (int64_t)NGHTTP3_MAX_VARINT);
|
||||
|
||||
p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_stream_context));
|
||||
if (p == NULL) {
|
||||
return NGHTTP3_ERR_NOMEM;
|
||||
|
@ -4127,7 +4145,6 @@ int nghttp3_qpack_decoder_new(nghttp3_qpack_decoder **pdecoder,
|
|||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem) {
|
||||
int rv;
|
||||
nghttp3_qpack_decoder *p;
|
||||
|
||||
p = nghttp3_mem_malloc(mem, sizeof(nghttp3_qpack_decoder));
|
||||
|
@ -4135,11 +4152,8 @@ int nghttp3_qpack_decoder_new(nghttp3_qpack_decoder **pdecoder,
|
|||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
rv = nghttp3_qpack_decoder_init(p, hard_max_dtable_capacity,
|
||||
max_blocked_streams, mem);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
nghttp3_qpack_decoder_init(p, hard_max_dtable_capacity, max_blocked_streams,
|
||||
mem);
|
||||
|
||||
*pdecoder = p;
|
||||
|
||||
|
|
29
deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h
vendored
29
deps/ngtcp2/nghttp3/lib/nghttp3_qpack.h
vendored
|
@ -269,17 +269,12 @@ struct nghttp3_qpack_encoder {
|
|||
/*
|
||||
* nghttp3_qpack_encoder_init initializes |encoder|.
|
||||
* |hard_max_dtable_capacity| is the upper bound of the dynamic table
|
||||
* capacity. |mem| is a memory allocator.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* capacity. |seed| is used to initialize nghttp3_map. |mem| is a
|
||||
* memory allocator.
|
||||
*/
|
||||
int nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
const nghttp3_mem *mem);
|
||||
void nghttp3_qpack_encoder_init(nghttp3_qpack_encoder *encoder,
|
||||
size_t hard_max_dtable_capacity, uint64_t seed,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_encoder_free frees memory allocated for |encoder|.
|
||||
|
@ -800,17 +795,11 @@ struct nghttp3_qpack_decoder {
|
|||
* |hard_max_dtable_capacity| is the upper bound of the dynamic table
|
||||
* capacity. |max_blocked_streams| is the maximum number of stream
|
||||
* which can be blocked. |mem| is a memory allocator.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP3_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem);
|
||||
void nghttp3_qpack_decoder_init(nghttp3_qpack_decoder *decoder,
|
||||
size_t hard_max_dtable_capacity,
|
||||
size_t max_blocked_streams,
|
||||
const nghttp3_mem *mem);
|
||||
|
||||
/*
|
||||
* nghttp3_qpack_decoder_free frees memory allocated for |decoder|.
|
||||
|
|
|
@ -88,7 +88,9 @@ nghttp3_qpack_huffman_decode(nghttp3_qpack_huffman_decode_context *ctx,
|
|||
int fin) {
|
||||
uint8_t *p = dest;
|
||||
const uint8_t *end = src + srclen;
|
||||
nghttp3_qpack_huffman_decode_node node = {ctx->fstate, 0};
|
||||
nghttp3_qpack_huffman_decode_node node = {
|
||||
.fstate = ctx->fstate,
|
||||
};
|
||||
const nghttp3_qpack_huffman_decode_node *t = &node;
|
||||
uint8_t c;
|
||||
|
||||
|
|
2
deps/ngtcp2/nghttp3/lib/nghttp3_range.c
vendored
2
deps/ngtcp2/nghttp3/lib/nghttp3_range.c
vendored
|
@ -33,7 +33,7 @@ void nghttp3_range_init(nghttp3_range *r, uint64_t begin, uint64_t end) {
|
|||
|
||||
nghttp3_range nghttp3_range_intersect(const nghttp3_range *a,
|
||||
const nghttp3_range *b) {
|
||||
nghttp3_range r = {0, 0};
|
||||
nghttp3_range r = {0};
|
||||
uint64_t begin = nghttp3_max_uint64(a->begin, b->begin);
|
||||
uint64_t end = nghttp3_min_uint64(a->end, b->end);
|
||||
|
||||
|
|
17
deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
vendored
17
deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.c
vendored
|
@ -33,18 +33,21 @@
|
|||
|
||||
#include "nghttp3_macro.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
static int ispow2(size_t n) {
|
||||
#if defined(_MSC_VER) && !defined(__clang__) && \
|
||||
(defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941))
|
||||
# if defined(DISABLE_POPCNT) || \
|
||||
(defined(_MSC_VER) && !defined(__clang__) && \
|
||||
(defined(_M_ARM) || (defined(_M_ARM64) && _MSC_VER < 1941)))
|
||||
return n && !(n & (n - 1));
|
||||
#elif defined(WIN32)
|
||||
# elif defined(WIN32)
|
||||
return 1 == __popcnt((unsigned int)n);
|
||||
#else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
||||
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
||||
# else /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
||||
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
||||
return 1 == __builtin_popcount((unsigned int)n);
|
||||
#endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
||||
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
||||
# endif /* !((defined(_MSC_VER) && !defined(__clang__) && (defined(_M_ARM) || \
|
||||
(defined(_M_ARM64) && _MSC_VER < 1941))) || defined(WIN32)) */
|
||||
}
|
||||
#endif /* !defined(NDEBUG) */
|
||||
|
||||
int nghttp3_ringbuf_init(nghttp3_ringbuf *rb, size_t nmemb, size_t size,
|
||||
const nghttp3_mem *mem) {
|
||||
|
|
4
deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.h
vendored
4
deps/ngtcp2/nghttp3/lib/nghttp3_ringbuf.h
vendored
|
@ -103,7 +103,9 @@ void nghttp3_ringbuf_resize(nghttp3_ringbuf *rb, size_t len);
|
|||
void *nghttp3_ringbuf_get(nghttp3_ringbuf *rb, size_t offset);
|
||||
|
||||
/* nghttp3_ringbuf_len returns the number of elements stored. */
|
||||
#define nghttp3_ringbuf_len(RB) ((RB)->len)
|
||||
static inline size_t nghttp3_ringbuf_len(const nghttp3_ringbuf *rb) {
|
||||
return rb->len;
|
||||
}
|
||||
|
||||
/* nghttp3_ringbuf_full returns nonzero if |rb| is full. */
|
||||
int nghttp3_ringbuf_full(nghttp3_ringbuf *rb);
|
||||
|
|
95
deps/ngtcp2/nghttp3/lib/nghttp3_settings.c
vendored
Normal file
95
deps/ngtcp2/nghttp3/lib/nghttp3_settings.c
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* nghttp3
|
||||
*
|
||||
* Copyright (c) 2025 nghttp3 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "nghttp3_settings.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "nghttp3_conv.h"
|
||||
#include "nghttp3_unreachable.h"
|
||||
|
||||
/* NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY is the upper bound of the
|
||||
dynamic table capacity that QPACK encoder is willing to use. */
|
||||
#define NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY 4096
|
||||
|
||||
void nghttp3_settings_default_versioned(int settings_version,
|
||||
nghttp3_settings *settings) {
|
||||
size_t len = nghttp3_settingslen_version(settings_version);
|
||||
|
||||
memset(settings, 0, len);
|
||||
|
||||
switch (settings_version) {
|
||||
case NGHTTP3_SETTINGS_VERSION:
|
||||
case NGHTTP3_SETTINGS_V1:
|
||||
settings->max_field_section_size = NGHTTP3_VARINT_MAX;
|
||||
settings->qpack_encoder_max_dtable_capacity =
|
||||
NGHTTP3_QPACK_ENCODER_MAX_DTABLE_CAPACITY;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void settings_copy(nghttp3_settings *dest, const nghttp3_settings *src,
|
||||
int settings_version) {
|
||||
assert(settings_version != NGHTTP3_SETTINGS_VERSION);
|
||||
|
||||
memcpy(dest, src, nghttp3_settingslen_version(settings_version));
|
||||
}
|
||||
|
||||
const nghttp3_settings *
|
||||
nghttp3_settings_convert_to_latest(nghttp3_settings *dest, int settings_version,
|
||||
const nghttp3_settings *src) {
|
||||
if (settings_version == NGHTTP3_SETTINGS_VERSION) {
|
||||
return src;
|
||||
}
|
||||
|
||||
nghttp3_settings_default(dest);
|
||||
|
||||
settings_copy(dest, src, settings_version);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void nghttp3_settings_convert_to_old(int settings_version,
|
||||
nghttp3_settings *dest,
|
||||
const nghttp3_settings *src) {
|
||||
assert(settings_version != NGHTTP3_SETTINGS_VERSION);
|
||||
|
||||
settings_copy(dest, src, settings_version);
|
||||
}
|
||||
|
||||
size_t nghttp3_settingslen_version(int settings_version) {
|
||||
nghttp3_settings settings;
|
||||
|
||||
switch (settings_version) {
|
||||
case NGHTTP3_SETTINGS_VERSION:
|
||||
return sizeof(settings);
|
||||
case NGHTTP3_SETTINGS_V1:
|
||||
return offsetof(nghttp3_settings, h3_datagram) +
|
||||
sizeof(settings.h3_datagram);
|
||||
default:
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
}
|
74
deps/ngtcp2/nghttp3/lib/nghttp3_settings.h
vendored
Normal file
74
deps/ngtcp2/nghttp3/lib/nghttp3_settings.h
vendored
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* nghttp3
|
||||
*
|
||||
* Copyright (c) 2025 nghttp3 contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP3_SETTINGS_H
|
||||
#define NGHTTP3_SETTINGS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* defined(HAVE_CONFIG_H) */
|
||||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
/*
|
||||
* nghttp3_settings_convert_to_latest converts |src| of version
|
||||
* |settings_version| to the latest version NGHTTP3_SETTINGS_VERSION.
|
||||
*
|
||||
* |dest| must point to the latest version. |src| may be the older
|
||||
* version, and if so, it may have fewer fields. Accessing those
|
||||
* fields causes undefined behavior.
|
||||
*
|
||||
* If |settings_version| == NGHTTP3_SETTINGS_VERSION, no conversion is
|
||||
* made, and |src| is returned. Otherwise, first |dest| is
|
||||
* initialized via nghttp3_settings_default, and then all valid fields
|
||||
* in |src| are copied into |dest|. Finally, |dest| is returned.
|
||||
*/
|
||||
const nghttp3_settings *
|
||||
nghttp3_settings_convert_to_latest(nghttp3_settings *dest, int settings_version,
|
||||
const nghttp3_settings *src);
|
||||
|
||||
/*
|
||||
* nghttp3_settings_convert_to_old converts |src| of the latest
|
||||
* version to |dest| of version |settings_version|.
|
||||
*
|
||||
* |settings_version| must not be the latest version
|
||||
* NGHTTP3_SETTINGS_VERSION.
|
||||
*
|
||||
* |dest| points to the older version, and it may have fewer fields.
|
||||
* Accessing those fields causes undefined behavior.
|
||||
*
|
||||
* This function copies all valid fields in version |settings_version|
|
||||
* from |src| to |dest|.
|
||||
*/
|
||||
void nghttp3_settings_convert_to_old(int settings_version,
|
||||
nghttp3_settings *dest,
|
||||
const nghttp3_settings *src);
|
||||
|
||||
/*
|
||||
* nghttp3_settingslen_version returns the effective length of
|
||||
* nghttp3_settings at the version |settings_version|.
|
||||
*/
|
||||
size_t nghttp3_settingslen_version(int settings_version);
|
||||
|
||||
#endif /* !defined(NGHTTP3_SETTINGS_H) */
|
310
deps/ngtcp2/nghttp3/lib/nghttp3_stream.c
vendored
310
deps/ngtcp2/nghttp3/lib/nghttp3_stream.c
vendored
|
@ -44,7 +44,7 @@
|
|||
/* NGHTTP3_MIN_RBLEN is the minimum length of nghttp3_ringbuf */
|
||||
#define NGHTTP3_MIN_RBLEN 4
|
||||
|
||||
nghttp3_objalloc_def(stream, nghttp3_stream, oplent);
|
||||
nghttp3_objalloc_def(stream, nghttp3_stream, oplent)
|
||||
|
||||
int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id,
|
||||
const nghttp3_stream_callbacks *callbacks,
|
||||
|
@ -57,10 +57,19 @@ int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id,
|
|||
return NGHTTP3_ERR_NOMEM;
|
||||
}
|
||||
|
||||
memset(stream, 0, sizeof(*stream));
|
||||
|
||||
stream->out_chunk_objalloc = out_chunk_objalloc;
|
||||
stream->stream_objalloc = stream_objalloc;
|
||||
*stream = (nghttp3_stream){
|
||||
.out_chunk_objalloc = out_chunk_objalloc,
|
||||
.stream_objalloc = stream_objalloc,
|
||||
.qpack_blocked_pe.index = NGHTTP3_PQ_BAD_INDEX,
|
||||
.mem = mem,
|
||||
.rx =
|
||||
{
|
||||
.http.status_code = -1,
|
||||
.http.content_length = -1,
|
||||
.http.pri.urgency = NGHTTP3_DEFAULT_URGENCY,
|
||||
},
|
||||
.error_code = NGHTTP3_H3_NO_ERROR,
|
||||
};
|
||||
|
||||
nghttp3_tnode_init(&stream->node, stream_id);
|
||||
|
||||
|
@ -71,13 +80,6 @@ int nghttp3_stream_new(nghttp3_stream **pstream, int64_t stream_id,
|
|||
|
||||
nghttp3_qpack_stream_context_init(&stream->qpack_sctx, stream_id, mem);
|
||||
|
||||
stream->qpack_blocked_pe.index = NGHTTP3_PQ_BAD_INDEX;
|
||||
stream->mem = mem;
|
||||
stream->rx.http.status_code = -1;
|
||||
stream->rx.http.content_length = -1;
|
||||
stream->rx.http.pri.urgency = NGHTTP3_DEFAULT_URGENCY;
|
||||
stream->error_code = NGHTTP3_H3_NO_ERROR;
|
||||
|
||||
if (callbacks) {
|
||||
stream->callbacks = *callbacks;
|
||||
}
|
||||
|
@ -140,7 +142,7 @@ static void delete_frq(nghttp3_ringbuf *frq, const nghttp3_mem *mem) {
|
|||
|
||||
for (i = 0; i < len; ++i) {
|
||||
frent = nghttp3_ringbuf_get(frq, i);
|
||||
switch (frent->fr.hd.type) {
|
||||
switch (frent->fr.type) {
|
||||
case NGHTTP3_FRAME_HEADERS:
|
||||
nghttp3_frame_headers_free(&frent->fr.headers, mem);
|
||||
break;
|
||||
|
@ -181,42 +183,45 @@ void nghttp3_stream_read_state_reset(nghttp3_stream_read_state *rstate) {
|
|||
nghttp3_ssize nghttp3_read_varint(nghttp3_varint_read_state *rvint,
|
||||
const uint8_t *begin, const uint8_t *end,
|
||||
int fin) {
|
||||
const uint8_t *orig_begin = begin;
|
||||
size_t len;
|
||||
size_t len, vlen;
|
||||
uint8_t *p;
|
||||
|
||||
assert(begin != end);
|
||||
|
||||
if (rvint->left == 0) {
|
||||
assert(rvint->acc == 0);
|
||||
|
||||
len = nghttp3_get_varintlen(begin);
|
||||
if (len <= (size_t)(end - begin)) {
|
||||
vlen = nghttp3_get_varintlen(begin);
|
||||
len = nghttp3_min_size(vlen, (size_t)(end - begin));
|
||||
if (vlen <= len) {
|
||||
nghttp3_get_varint(&rvint->acc, begin);
|
||||
return (nghttp3_ssize)len;
|
||||
return (nghttp3_ssize)vlen;
|
||||
}
|
||||
|
||||
if (fin) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
rvint->acc = nghttp3_get_varint_fb(begin++);
|
||||
rvint->left = len - 1;
|
||||
p = (uint8_t *)&rvint->acc + (sizeof(rvint->acc) - vlen);
|
||||
memcpy(p, begin, len);
|
||||
*p &= 0x3f;
|
||||
rvint->left = vlen - len;
|
||||
|
||||
return (nghttp3_ssize)len;
|
||||
}
|
||||
|
||||
len = nghttp3_min_size(rvint->left, (size_t)(end - begin));
|
||||
end = begin + len;
|
||||
|
||||
for (; begin != end;) {
|
||||
rvint->acc = (rvint->acc << 8) + *begin++;
|
||||
}
|
||||
|
||||
p = (uint8_t *)&rvint->acc + (sizeof(rvint->acc) - rvint->left);
|
||||
memcpy(p, begin, len);
|
||||
rvint->left -= len;
|
||||
|
||||
if (fin && rvint->left) {
|
||||
if (rvint->left == 0) {
|
||||
rvint->acc = (int64_t)nghttp3_ntohl64((uint64_t)rvint->acc);
|
||||
} else if (fin) {
|
||||
return NGHTTP3_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
return (nghttp3_ssize)(begin - orig_begin);
|
||||
return (nghttp3_ssize)len;
|
||||
}
|
||||
|
||||
int nghttp3_stream_frq_add(nghttp3_stream *stream,
|
||||
|
@ -250,7 +255,7 @@ int nghttp3_stream_fill_outq(nghttp3_stream *stream) {
|
|||
stream->unsent_bytes < NGHTTP3_MIN_UNSENT_BYTES;) {
|
||||
frent = nghttp3_ringbuf_get(frq, 0);
|
||||
|
||||
switch (frent->fr.hd.type) {
|
||||
switch (frent->fr.type) {
|
||||
case NGHTTP3_FRAME_SETTINGS:
|
||||
rv = nghttp3_stream_write_settings(stream, frent);
|
||||
if (rv != 0) {
|
||||
|
@ -290,6 +295,13 @@ int nghttp3_stream_fill_outq(nghttp3_stream *stream) {
|
|||
nghttp3_frame_priority_update_free(&frent->fr.priority_update,
|
||||
stream->mem);
|
||||
break;
|
||||
case NGHTTP3_FRAME_ORIGIN:
|
||||
rv = nghttp3_stream_write_origin(stream, frent);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
/* TODO Not implemented */
|
||||
break;
|
||||
|
@ -301,12 +313,6 @@ int nghttp3_stream_fill_outq(nghttp3_stream *stream) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void typed_buf_shared_init(nghttp3_typed_buf *tbuf,
|
||||
const nghttp3_buf *chunk) {
|
||||
nghttp3_typed_buf_init(tbuf, chunk, NGHTTP3_BUF_TYPE_SHARED);
|
||||
tbuf->buf.pos = tbuf->buf.last;
|
||||
}
|
||||
|
||||
int nghttp3_stream_write_stream_type(nghttp3_stream *stream) {
|
||||
size_t len = nghttp3_put_varintlen((int64_t)stream->type);
|
||||
nghttp3_buf *chunk;
|
||||
|
@ -319,7 +325,7 @@ int nghttp3_stream_write_stream_type(nghttp3_stream *stream) {
|
|||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_put_varint(chunk->last, (int64_t)stream->type);
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
@ -336,12 +342,17 @@ int nghttp3_stream_write_settings(nghttp3_stream *stream,
|
|||
struct {
|
||||
nghttp3_frame_settings settings;
|
||||
nghttp3_settings_entry iv[15];
|
||||
} fr;
|
||||
} fr = {
|
||||
.settings =
|
||||
{
|
||||
.type = NGHTTP3_FRAME_SETTINGS,
|
||||
.niv = 3,
|
||||
},
|
||||
};
|
||||
nghttp3_settings_entry *iv;
|
||||
nghttp3_settings *local_settings = frent->aux.settings.local_settings;
|
||||
int64_t payloadlen;
|
||||
|
||||
fr.settings.hd.type = NGHTTP3_FRAME_SETTINGS;
|
||||
fr.settings.niv = 3;
|
||||
iv = &fr.settings.iv[0];
|
||||
|
||||
iv[0].id = NGHTTP3_SETTINGS_ID_MAX_FIELD_SECTION_SIZE;
|
||||
|
@ -365,7 +376,7 @@ int nghttp3_stream_write_settings(nghttp3_stream *stream,
|
|||
++fr.settings.niv;
|
||||
}
|
||||
|
||||
len = nghttp3_frame_write_settings_len(&fr.settings.hd.length, &fr.settings);
|
||||
len = nghttp3_frame_write_settings_len(&payloadlen, &fr.settings);
|
||||
|
||||
rv = nghttp3_stream_ensure_chunk(stream, len);
|
||||
if (rv != 0) {
|
||||
|
@ -373,9 +384,10 @@ int nghttp3_stream_write_settings(nghttp3_stream *stream,
|
|||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_frame_write_settings(chunk->last, &fr.settings);
|
||||
chunk->last =
|
||||
nghttp3_frame_write_settings(chunk->last, &fr.settings, payloadlen);
|
||||
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
||||
|
@ -389,8 +401,9 @@ int nghttp3_stream_write_goaway(nghttp3_stream *stream,
|
|||
int rv;
|
||||
nghttp3_buf *chunk;
|
||||
nghttp3_typed_buf tbuf;
|
||||
int64_t payloadlen;
|
||||
|
||||
len = nghttp3_frame_write_goaway_len(&fr->hd.length, fr);
|
||||
len = nghttp3_frame_write_goaway_len(&payloadlen, fr);
|
||||
|
||||
rv = nghttp3_stream_ensure_chunk(stream, len);
|
||||
if (rv != 0) {
|
||||
|
@ -398,9 +411,9 @@ int nghttp3_stream_write_goaway(nghttp3_stream *stream,
|
|||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_frame_write_goaway(chunk->last, fr);
|
||||
chunk->last = nghttp3_frame_write_goaway(chunk->last, fr, payloadlen);
|
||||
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
||||
|
@ -414,8 +427,9 @@ int nghttp3_stream_write_priority_update(nghttp3_stream *stream,
|
|||
int rv;
|
||||
nghttp3_buf *chunk;
|
||||
nghttp3_typed_buf tbuf;
|
||||
int64_t payloadlen;
|
||||
|
||||
len = nghttp3_frame_write_priority_update_len(&fr->hd.length, fr);
|
||||
len = nghttp3_frame_write_priority_update_len(&payloadlen, fr);
|
||||
|
||||
rv = nghttp3_stream_ensure_chunk(stream, len);
|
||||
if (rv != 0) {
|
||||
|
@ -423,15 +437,55 @@ int nghttp3_stream_write_priority_update(nghttp3_stream *stream,
|
|||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_frame_write_priority_update(chunk->last, fr);
|
||||
chunk->last =
|
||||
nghttp3_frame_write_priority_update(chunk->last, fr, payloadlen);
|
||||
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
||||
return nghttp3_stream_outq_add(stream, &tbuf);
|
||||
}
|
||||
|
||||
int nghttp3_stream_write_origin(nghttp3_stream *stream,
|
||||
nghttp3_frame_entry *frent) {
|
||||
nghttp3_frame_origin *fr = &frent->fr.origin;
|
||||
nghttp3_buf *chunk;
|
||||
nghttp3_buf buf;
|
||||
nghttp3_typed_buf tbuf;
|
||||
int rv;
|
||||
|
||||
rv = nghttp3_stream_ensure_chunk(
|
||||
stream, nghttp3_frame_write_hd_len(fr->type, (int64_t)fr->origin_list.len));
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last =
|
||||
nghttp3_frame_write_hd(chunk->last, fr->type, (int64_t)fr->origin_list.len);
|
||||
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
||||
rv = nghttp3_stream_outq_add(stream, &tbuf);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (fr->origin_list.len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nghttp3_buf_wrap_init(&buf, (uint8_t *)fr->origin_list.base,
|
||||
fr->origin_list.len);
|
||||
buf.last = buf.end;
|
||||
nghttp3_typed_buf_init(&tbuf, &buf, NGHTTP3_BUF_TYPE_ALIEN_NO_ACK);
|
||||
|
||||
return nghttp3_stream_outq_add(stream, &tbuf);
|
||||
}
|
||||
|
||||
int nghttp3_stream_write_headers(nghttp3_stream *stream,
|
||||
nghttp3_frame_entry *frent) {
|
||||
nghttp3_frame_headers *fr = &frent->fr.headers;
|
||||
|
@ -455,26 +509,25 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
|||
size_t len;
|
||||
nghttp3_buf *chunk;
|
||||
nghttp3_typed_buf tbuf;
|
||||
nghttp3_frame_hd hd;
|
||||
uint8_t raw_pbuf[16];
|
||||
size_t pbuflen, rbuflen, ebuflen;
|
||||
int64_t payloadlen;
|
||||
|
||||
nghttp3_buf_wrap_init(&pbuf, raw_pbuf, sizeof(raw_pbuf));
|
||||
|
||||
rv = nghttp3_qpack_encoder_encode(qenc, &pbuf, rbuf, ebuf, stream->node.id,
|
||||
nva, nvlen);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
|
||||
pbuflen = nghttp3_buf_len(&pbuf);
|
||||
rbuflen = nghttp3_buf_len(rbuf);
|
||||
ebuflen = nghttp3_buf_len(ebuf);
|
||||
|
||||
hd.type = frame_type;
|
||||
hd.length = (int64_t)(pbuflen + rbuflen);
|
||||
payloadlen = (int64_t)(pbuflen + rbuflen);
|
||||
|
||||
len = nghttp3_frame_write_hd_len(&hd) + pbuflen;
|
||||
len = nghttp3_frame_write_hd_len(frame_type, payloadlen) + pbuflen;
|
||||
|
||||
if (rbuflen <= NGHTTP3_STREAM_MAX_COPY_THRES) {
|
||||
len += rbuflen;
|
||||
|
@ -482,13 +535,13 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
|||
|
||||
rv = nghttp3_stream_ensure_chunk(stream, len);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_frame_write_hd(chunk->last, &hd);
|
||||
chunk->last = nghttp3_frame_write_hd(chunk->last, frame_type, payloadlen);
|
||||
|
||||
chunk->last = nghttp3_cpymem(chunk->last, pbuf.pos, pbuflen);
|
||||
nghttp3_buf_init(&pbuf);
|
||||
|
@ -498,13 +551,13 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
|||
|
||||
rv = nghttp3_stream_outq_add(stream, &tbuf);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nghttp3_typed_buf_init(&tbuf, rbuf, NGHTTP3_BUF_TYPE_PRIVATE);
|
||||
rv = nghttp3_stream_outq_add(stream, &tbuf);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
nghttp3_buf_init(rbuf);
|
||||
} else if (rbuflen) {
|
||||
|
@ -513,7 +566,7 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
|||
|
||||
rv = nghttp3_stream_outq_add(stream, &tbuf);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
nghttp3_buf_reset(rbuf);
|
||||
}
|
||||
|
@ -532,18 +585,18 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
|||
|
||||
rv = nghttp3_stream_ensure_chunk(qenc_stream, ebuflen);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(qenc_stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_cpymem(chunk->last, ebuf->pos, ebuflen);
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
||||
rv = nghttp3_stream_outq_add(qenc_stream, &tbuf);
|
||||
if (rv != 0) {
|
||||
goto fail;
|
||||
return rv;
|
||||
}
|
||||
nghttp3_buf_reset(ebuf);
|
||||
}
|
||||
|
@ -553,10 +606,6 @@ int nghttp3_stream_write_header_block(nghttp3_stream *stream,
|
|||
assert(0 == nghttp3_buf_len(ebuf));
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof,
|
||||
|
@ -570,7 +619,6 @@ int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof,
|
|||
nghttp3_conn *conn = stream->conn;
|
||||
int64_t datalen;
|
||||
uint32_t flags = 0;
|
||||
nghttp3_frame_hd hd;
|
||||
nghttp3_vec vec[8];
|
||||
nghttp3_vec *v;
|
||||
nghttp3_ssize sveccnt;
|
||||
|
@ -624,10 +672,7 @@ int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof,
|
|||
}
|
||||
}
|
||||
|
||||
hd.type = NGHTTP3_FRAME_DATA;
|
||||
hd.length = datalen;
|
||||
|
||||
len = nghttp3_frame_write_hd_len(&hd);
|
||||
len = nghttp3_frame_write_hd_len(NGHTTP3_FRAME_DATA, datalen);
|
||||
|
||||
rv = nghttp3_stream_ensure_chunk(stream, len);
|
||||
if (rv != 0) {
|
||||
|
@ -635,9 +680,10 @@ int nghttp3_stream_write_data(nghttp3_stream *stream, int *peof,
|
|||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
chunk->last = nghttp3_frame_write_hd(chunk->last, &hd);
|
||||
chunk->last =
|
||||
nghttp3_frame_write_hd(chunk->last, NGHTTP3_FRAME_DATA, datalen);
|
||||
|
||||
tbuf.buf.last = chunk->last;
|
||||
|
||||
|
@ -690,7 +736,7 @@ int nghttp3_stream_write_qpack_decoder_stream(nghttp3_stream *stream) {
|
|||
}
|
||||
|
||||
chunk = nghttp3_stream_get_chunk(stream);
|
||||
typed_buf_shared_init(&tbuf, chunk);
|
||||
nghttp3_typed_buf_shared_init(&tbuf, chunk);
|
||||
|
||||
nghttp3_qpack_decoder_write_decoder(qdec, chunk);
|
||||
|
||||
|
@ -717,17 +763,16 @@ int nghttp3_stream_outq_add(nghttp3_stream *stream,
|
|||
if (len) {
|
||||
dest = nghttp3_ringbuf_get(outq, len - 1);
|
||||
if (dest->type == tbuf->type && dest->type == NGHTTP3_BUF_TYPE_SHARED &&
|
||||
dest->buf.begin == tbuf->buf.begin && dest->buf.last == tbuf->buf.pos) {
|
||||
dest->buf.end == tbuf->buf.end && dest->buf.last == tbuf->buf.pos) {
|
||||
/* If we have already written last entry, adjust outq_idx and
|
||||
offset so that this entry is eligible to send. */
|
||||
if (len == stream->outq_idx) {
|
||||
--stream->outq_idx;
|
||||
stream->outq_offset = nghttp3_buf_len(&dest->buf);
|
||||
}
|
||||
|
||||
dest->buf.last = tbuf->buf.last;
|
||||
/* TODO Is this required? */
|
||||
dest->buf.end = tbuf->buf.end;
|
||||
|
||||
assert(dest->buf.end == tbuf->buf.end);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -817,34 +862,24 @@ size_t nghttp3_stream_writev(nghttp3_stream *stream, int *pfin,
|
|||
nghttp3_ringbuf *outq = &stream->outq;
|
||||
size_t len = nghttp3_ringbuf_len(outq);
|
||||
size_t i = stream->outq_idx;
|
||||
uint64_t offset = stream->outq_offset;
|
||||
size_t buflen;
|
||||
nghttp3_vec *vbegin = vec, *vend = vec + veccnt;
|
||||
nghttp3_typed_buf *tbuf;
|
||||
|
||||
assert(veccnt > 0);
|
||||
|
||||
if (i < len) {
|
||||
for (; i < len && vec != vend; ++i) {
|
||||
tbuf = nghttp3_ringbuf_get(outq, i);
|
||||
buflen = nghttp3_buf_len(&tbuf->buf);
|
||||
|
||||
if (offset < buflen) {
|
||||
vec->base = tbuf->buf.pos + offset;
|
||||
vec->len = (size_t)(buflen - offset);
|
||||
++vec;
|
||||
} else {
|
||||
/* This is the only case that satisfies offset >= buflen */
|
||||
assert(0 == offset);
|
||||
assert(0 == buflen);
|
||||
if (buflen == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
++i;
|
||||
vec->base = tbuf->buf.pos;
|
||||
vec->len = buflen;
|
||||
|
||||
for (; i < len && vec != vend; ++i, ++vec) {
|
||||
tbuf = nghttp3_ringbuf_get(outq, i);
|
||||
vec->base = tbuf->buf.pos;
|
||||
vec->len = nghttp3_buf_len(&tbuf->buf);
|
||||
}
|
||||
++vec;
|
||||
}
|
||||
|
||||
/* TODO Rework this if we have finished implementing HTTP
|
||||
|
@ -859,26 +894,27 @@ void nghttp3_stream_add_outq_offset(nghttp3_stream *stream, size_t n) {
|
|||
nghttp3_ringbuf *outq = &stream->outq;
|
||||
size_t i;
|
||||
size_t len = nghttp3_ringbuf_len(outq);
|
||||
uint64_t offset = stream->outq_offset + n;
|
||||
size_t buflen;
|
||||
nghttp3_typed_buf *tbuf;
|
||||
|
||||
stream->unsent_bytes -= n;
|
||||
|
||||
for (i = stream->outq_idx; i < len; ++i) {
|
||||
tbuf = nghttp3_ringbuf_get(outq, i);
|
||||
buflen = nghttp3_buf_len(&tbuf->buf);
|
||||
if (offset >= buflen) {
|
||||
offset -= buflen;
|
||||
continue;
|
||||
if (n < buflen) {
|
||||
tbuf->buf.pos += n;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
tbuf->buf.pos = tbuf->buf.last;
|
||||
n -= buflen;
|
||||
}
|
||||
|
||||
assert(i < len || offset == 0);
|
||||
assert(i < len || n == 0);
|
||||
|
||||
stream->unsent_bytes -= n;
|
||||
stream->outq_idx = i;
|
||||
stream->outq_offset = offset;
|
||||
}
|
||||
|
||||
int nghttp3_stream_outq_write_done(nghttp3_stream *stream) {
|
||||
|
@ -898,13 +934,13 @@ static void stream_pop_outq_entry(nghttp3_stream *stream,
|
|||
nghttp3_buf_free(&tbuf->buf, stream->mem);
|
||||
break;
|
||||
case NGHTTP3_BUF_TYPE_ALIEN:
|
||||
case NGHTTP3_BUF_TYPE_ALIEN_NO_ACK:
|
||||
break;
|
||||
case NGHTTP3_BUF_TYPE_SHARED:
|
||||
assert(nghttp3_ringbuf_len(chunks));
|
||||
|
||||
chunk = nghttp3_ringbuf_get(chunks, 0);
|
||||
|
||||
assert(chunk->begin == tbuf->buf.begin);
|
||||
assert(chunk->end == tbuf->buf.end);
|
||||
|
||||
if (chunk->last == tbuf->buf.last) {
|
||||
|
@ -927,14 +963,13 @@ static void stream_pop_outq_entry(nghttp3_stream *stream,
|
|||
int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) {
|
||||
nghttp3_ringbuf *outq = &stream->outq;
|
||||
size_t buflen;
|
||||
size_t npopped = 0;
|
||||
uint64_t nack;
|
||||
nghttp3_typed_buf *tbuf;
|
||||
int rv;
|
||||
|
||||
for (; nghttp3_ringbuf_len(outq);) {
|
||||
tbuf = nghttp3_ringbuf_get(outq, 0);
|
||||
buflen = nghttp3_buf_len(&tbuf->buf);
|
||||
buflen = (size_t)(tbuf->buf.last - tbuf->buf.begin);
|
||||
|
||||
/* For NGHTTP3_BUF_TYPE_ALIEN, we never add 0 length buffer. */
|
||||
if (tbuf->type == NGHTTP3_BUF_TYPE_ALIEN && stream->ack_offset < offset &&
|
||||
|
@ -949,17 +984,13 @@ int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) {
|
|||
}
|
||||
}
|
||||
|
||||
if (offset >= stream->ack_base + buflen) {
|
||||
if (stream->outq_idx > 0 && offset >= stream->ack_base + buflen) {
|
||||
stream_pop_outq_entry(stream, tbuf);
|
||||
|
||||
stream->ack_base += buflen;
|
||||
stream->ack_offset = stream->ack_base;
|
||||
++npopped;
|
||||
|
||||
if (stream->outq_idx + 1 == npopped) {
|
||||
stream->outq_offset = 0;
|
||||
break;
|
||||
}
|
||||
--stream->outq_idx;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -967,13 +998,6 @@ int nghttp3_stream_update_ack_offset(nghttp3_stream *stream, uint64_t offset) {
|
|||
break;
|
||||
}
|
||||
|
||||
assert(stream->outq_idx + 1 >= npopped);
|
||||
if (stream->outq_idx >= npopped) {
|
||||
stream->outq_idx -= npopped;
|
||||
} else {
|
||||
stream->outq_idx = 0;
|
||||
}
|
||||
|
||||
stream->ack_offset = offset;
|
||||
|
||||
return 0;
|
||||
|
@ -1045,19 +1069,17 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
|
||||
switch (stream->rx.hstate) {
|
||||
case NGHTTP3_HTTP_STATE_NONE:
|
||||
return NGHTTP3_ERR_H3_INTERNAL_ERROR;
|
||||
nghttp3_unreachable();
|
||||
case NGHTTP3_HTTP_STATE_REQ_INITIAL:
|
||||
switch (event) {
|
||||
case NGHTTP3_HTTP_EVENT_HEADERS_BEGIN:
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN;
|
||||
return 0;
|
||||
default:
|
||||
if (event != NGHTTP3_HTTP_EVENT_HEADERS_BEGIN) {
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
}
|
||||
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN;
|
||||
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_REQ_HEADERS_BEGIN:
|
||||
if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
}
|
||||
assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event);
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_HEADERS_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_REQ_HEADERS_END:
|
||||
|
@ -1080,12 +1102,10 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_END;
|
||||
return 0;
|
||||
default:
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
case NGHTTP3_HTTP_STATE_REQ_DATA_BEGIN:
|
||||
if (event != NGHTTP3_HTTP_EVENT_DATA_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
}
|
||||
assert(NGHTTP3_HTTP_EVENT_DATA_END == event);
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_DATA_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_REQ_DATA_END:
|
||||
|
@ -1108,12 +1128,10 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_END;
|
||||
return 0;
|
||||
default:
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
case NGHTTP3_HTTP_STATE_REQ_TRAILERS_BEGIN:
|
||||
if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
}
|
||||
assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event);
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_TRAILERS_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_REQ_TRAILERS_END:
|
||||
|
@ -1129,7 +1147,7 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_REQ_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_REQ_END:
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
case NGHTTP3_HTTP_STATE_RESP_INITIAL:
|
||||
if (event != NGHTTP3_HTTP_EVENT_HEADERS_BEGIN) {
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
|
@ -1137,9 +1155,7 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_HEADERS_BEGIN;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_RESP_HEADERS_BEGIN:
|
||||
if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
}
|
||||
assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event);
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_HEADERS_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_RESP_HEADERS_END:
|
||||
|
@ -1169,12 +1185,10 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_END;
|
||||
return 0;
|
||||
default:
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
case NGHTTP3_HTTP_STATE_RESP_DATA_BEGIN:
|
||||
if (event != NGHTTP3_HTTP_EVENT_DATA_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
}
|
||||
assert(NGHTTP3_HTTP_EVENT_DATA_END == event);
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_DATA_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_RESP_DATA_END:
|
||||
|
@ -1197,17 +1211,15 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_END;
|
||||
return 0;
|
||||
default:
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
case NGHTTP3_HTTP_STATE_RESP_TRAILERS_BEGIN:
|
||||
if (event != NGHTTP3_HTTP_EVENT_HEADERS_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
}
|
||||
assert(NGHTTP3_HTTP_EVENT_HEADERS_END == event);
|
||||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_TRAILERS_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_RESP_TRAILERS_END:
|
||||
if (event != NGHTTP3_HTTP_EVENT_MSG_END) {
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
}
|
||||
rv = nghttp3_http_on_remote_end_stream(stream);
|
||||
if (rv != 0) {
|
||||
|
@ -1216,7 +1228,7 @@ int nghttp3_stream_transit_rx_http_state(nghttp3_stream *stream,
|
|||
stream->rx.hstate = NGHTTP3_HTTP_STATE_RESP_END;
|
||||
return 0;
|
||||
case NGHTTP3_HTTP_STATE_RESP_END:
|
||||
return NGHTTP3_ERR_MALFORMED_HTTP_MESSAGING;
|
||||
return NGHTTP3_ERR_H3_FRAME_UNEXPECTED;
|
||||
default:
|
||||
nghttp3_unreachable();
|
||||
}
|
||||
|
|
14
deps/ngtcp2/nghttp3/lib/nghttp3_stream.h
vendored
14
deps/ngtcp2/nghttp3/lib/nghttp3_stream.h
vendored
|
@ -69,6 +69,8 @@ typedef enum nghttp3_ctrl_stream_state {
|
|||
NGHTTP3_CTRL_STREAM_STATE_SETTINGS_VALUE,
|
||||
NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE_PRI_ELEM_ID,
|
||||
NGHTTP3_CTRL_STREAM_STATE_PRIORITY_UPDATE,
|
||||
NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ORIGIN_LEN,
|
||||
NGHTTP3_CTRL_STREAM_STATE_ORIGIN_ASCII_ORIGIN,
|
||||
} nghttp3_ctrl_stream_state;
|
||||
|
||||
typedef enum nghttp3_req_stream_state {
|
||||
|
@ -129,10 +131,6 @@ typedef struct nghttp3_stream_read_state {
|
|||
/* NGHTTP3_STREAM_FLAG_PRIORITY_UPDATE_RECVED indicates that server
|
||||
received PRIORITY_UPDATE frame for this stream. */
|
||||
#define NGHTTP3_STREAM_FLAG_PRIORITY_UPDATE_RECVED 0x0800u
|
||||
/* NGHTTP3_STREAM_FLAG_HTTP_ERROR indicates that
|
||||
NGHTTP3_ERR_MALFORMED_HTTP_HEADER error is encountered while
|
||||
processing incoming HTTP fields. */
|
||||
#define NGHTTP3_STREAM_FLAG_HTTP_ERROR 0x1000u
|
||||
|
||||
typedef enum nghttp3_stream_http_state {
|
||||
NGHTTP3_HTTP_STATE_NONE,
|
||||
|
@ -223,9 +221,6 @@ struct nghttp3_stream {
|
|||
uint64_t unsent_bytes;
|
||||
/* outq_idx is an index into outq where next write is made. */
|
||||
size_t outq_idx;
|
||||
/* outq_offset is write offset relative to the element at outq_idx
|
||||
in outq. */
|
||||
uint64_t outq_offset;
|
||||
/* ack_base is the number of bytes acknowledged by a remote
|
||||
endpoint where the first element in outq is positioned at. */
|
||||
uint64_t ack_base;
|
||||
|
@ -255,7 +250,7 @@ struct nghttp3_stream {
|
|||
};
|
||||
};
|
||||
|
||||
nghttp3_objalloc_decl(stream, nghttp3_stream, oplent);
|
||||
nghttp3_objalloc_decl(stream, nghttp3_stream, oplent)
|
||||
|
||||
typedef struct nghttp3_frame_entry {
|
||||
nghttp3_frame fr;
|
||||
|
@ -322,6 +317,9 @@ int nghttp3_stream_write_goaway(nghttp3_stream *stream,
|
|||
int nghttp3_stream_write_priority_update(nghttp3_stream *stream,
|
||||
nghttp3_frame_entry *frent);
|
||||
|
||||
int nghttp3_stream_write_origin(nghttp3_stream *stream,
|
||||
nghttp3_frame_entry *frent);
|
||||
|
||||
int nghttp3_stream_ensure_chunk(nghttp3_stream *stream, size_t need);
|
||||
|
||||
nghttp3_buf *nghttp3_stream_get_chunk(nghttp3_stream *stream);
|
||||
|
|
7
deps/ngtcp2/nghttp3/lib/nghttp3_version.c
vendored
7
deps/ngtcp2/nghttp3/lib/nghttp3_version.c
vendored
|
@ -28,8 +28,11 @@
|
|||
|
||||
#include <nghttp3/nghttp3.h>
|
||||
|
||||
static nghttp3_info version = {NGHTTP3_VERSION_AGE, NGHTTP3_VERSION_NUM,
|
||||
NGHTTP3_VERSION};
|
||||
static nghttp3_info version = {
|
||||
.age = NGHTTP3_VERSION_AGE,
|
||||
.version_num = NGHTTP3_VERSION_NUM,
|
||||
.version_str = NGHTTP3_VERSION,
|
||||
};
|
||||
|
||||
const nghttp3_info *nghttp3_version(int least_version) {
|
||||
if (least_version > NGHTTP3_VERSION_NUM) {
|
||||
|
|
22
deps/ngtcp2/nghttp3/lib/sfparse/COPYING
vendored
22
deps/ngtcp2/nghttp3/lib/sfparse/COPYING
vendored
|
@ -1,22 +0,0 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2023 sfparse contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1517
deps/ngtcp2/nghttp3/lib/sfparse/sfparse.c
vendored
1517
deps/ngtcp2/nghttp3/lib/sfparse/sfparse.c
vendored
File diff suppressed because it is too large
Load diff
326
deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h
vendored
326
deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h
vendored
|
@ -31,90 +31,90 @@
|
|||
libcurl) */
|
||||
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
|
||||
# define WIN32
|
||||
#endif
|
||||
#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1800)
|
||||
/* MSVC < 2013 does not have inttypes.h because it is not C99
|
||||
compliant. See compiler macros and version number in
|
||||
https://sourceforge.net/p/predef/wiki/Compilers/ */
|
||||
# include <stdint.h>
|
||||
#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
||||
#else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
|
||||
# include <inttypes.h>
|
||||
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
||||
#endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @enum
|
||||
*
|
||||
* :type:`sf_type` defines value type.
|
||||
* :type:`sfparse_type` defines value type.
|
||||
*/
|
||||
typedef enum sf_type {
|
||||
typedef enum sfparse_type {
|
||||
/**
|
||||
* :enum:`SF_TYPE_BOOLEAN` indicates boolean type.
|
||||
* :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type.
|
||||
*/
|
||||
SF_TYPE_BOOLEAN,
|
||||
SFPARSE_TYPE_BOOLEAN,
|
||||
/**
|
||||
* :enum:`SF_TYPE_INTEGER` indicates integer type.
|
||||
* :enum:`SFPARSE_TYPE_INTEGER` indicates integer type.
|
||||
*/
|
||||
SF_TYPE_INTEGER,
|
||||
SFPARSE_TYPE_INTEGER,
|
||||
/**
|
||||
* :enum:`SF_TYPE_DECIMAL` indicates decimal type.
|
||||
* :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type.
|
||||
*/
|
||||
SF_TYPE_DECIMAL,
|
||||
SFPARSE_TYPE_DECIMAL,
|
||||
/**
|
||||
* :enum:`SF_TYPE_STRING` indicates string type.
|
||||
* :enum:`SFPARSE_TYPE_STRING` indicates string type.
|
||||
*/
|
||||
SF_TYPE_STRING,
|
||||
SFPARSE_TYPE_STRING,
|
||||
/**
|
||||
* :enum:`SF_TYPE_TOKEN` indicates token type.
|
||||
* :enum:`SFPARSE_TYPE_TOKEN` indicates token type.
|
||||
*/
|
||||
SF_TYPE_TOKEN,
|
||||
SFPARSE_TYPE_TOKEN,
|
||||
/**
|
||||
* :enum:`SF_TYPE_BYTESEQ` indicates byte sequence type.
|
||||
* :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type.
|
||||
*/
|
||||
SF_TYPE_BYTESEQ,
|
||||
SFPARSE_TYPE_BYTESEQ,
|
||||
/**
|
||||
* :enum:`SF_TYPE_INNER_LIST` indicates inner list type.
|
||||
* :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type.
|
||||
*/
|
||||
SF_TYPE_INNER_LIST,
|
||||
SFPARSE_TYPE_INNER_LIST,
|
||||
/**
|
||||
* :enum:`SF_TYPE_DATE` indicates date type.
|
||||
* :enum:`SFPARSE_TYPE_DATE` indicates date type.
|
||||
*/
|
||||
SF_TYPE_DATE,
|
||||
SFPARSE_TYPE_DATE,
|
||||
/**
|
||||
* :enum:`SF_TYPE_DISPSTRING` indicates display string type.
|
||||
* :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type.
|
||||
*/
|
||||
SF_TYPE_DISPSTRING
|
||||
} sf_type;
|
||||
SFPARSE_TYPE_DISPSTRING
|
||||
} sfparse_type;
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`SF_ERR_PARSE_ERROR` indicates fatal parse error has
|
||||
* :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has
|
||||
* occurred, and it is not possible to continue the processing.
|
||||
*/
|
||||
#define SF_ERR_PARSE_ERROR -1
|
||||
#define SFPARSE_ERR_PARSE -1
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`SF_ERR_EOF` indicates that there is nothing left to read.
|
||||
* The context of this error varies depending on the function that
|
||||
* returns this error code.
|
||||
* :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to
|
||||
* read. The context of this error varies depending on the function
|
||||
* that returns this error code.
|
||||
*/
|
||||
#define SF_ERR_EOF -2
|
||||
#define SFPARSE_ERR_EOF -2
|
||||
|
||||
/**
|
||||
* @struct
|
||||
*
|
||||
* :type:`sf_vec` stores sequence of bytes.
|
||||
* :type:`sfparse_vec` stores sequence of bytes.
|
||||
*/
|
||||
typedef struct sf_vec {
|
||||
typedef struct sfparse_vec {
|
||||
/**
|
||||
* :member:`base` points to the beginning of the sequence of bytes.
|
||||
*/
|
||||
|
@ -123,29 +123,29 @@ typedef struct sf_vec {
|
|||
* :member:`len` is the number of bytes contained in this sequence.
|
||||
*/
|
||||
size_t len;
|
||||
} sf_vec;
|
||||
} sfparse_vec;
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`SF_VALUE_FLAG_NONE` indicates no flag set.
|
||||
* :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set.
|
||||
*/
|
||||
#define SF_VALUE_FLAG_NONE 0x0u
|
||||
#define SFPARSE_VALUE_FLAG_NONE 0x0u
|
||||
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* :macro:`SF_VALUE_FLAG_ESCAPED_STRING` indicates that a string
|
||||
* :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string
|
||||
* contains escaped character(s).
|
||||
*/
|
||||
#define SF_VALUE_FLAG_ESCAPED_STRING 0x1u
|
||||
#define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u
|
||||
|
||||
/**
|
||||
* @struct
|
||||
*
|
||||
* :type:`sf_decimal` contains decimal value.
|
||||
* :type:`sfparse_decimal` contains decimal value.
|
||||
*/
|
||||
typedef struct sf_decimal {
|
||||
typedef struct sfparse_decimal {
|
||||
/**
|
||||
* :member:`numer` contains numerator of the decimal value.
|
||||
*/
|
||||
|
@ -154,275 +154,289 @@ typedef struct sf_decimal {
|
|||
* :member:`denom` contains denominator of the decimal value.
|
||||
*/
|
||||
int64_t denom;
|
||||
} sf_decimal;
|
||||
} sfparse_decimal;
|
||||
|
||||
/**
|
||||
* @struct
|
||||
*
|
||||
* :type:`sf_value` stores a Structured Field item. For Inner List,
|
||||
* only type is set to :enum:`sf_type.SF_TYPE_INNER_LIST`. In order
|
||||
* to read the items contained in an inner list, call
|
||||
* `sf_parser_inner_list`.
|
||||
* :type:`sfparse_value` stores a Structured Field item. For Inner
|
||||
* List, only type is set to
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`. In order to read the
|
||||
* items contained in an inner list, call `sfparse_parser_inner_list`.
|
||||
*/
|
||||
typedef struct sf_value {
|
||||
typedef struct sfparse_value {
|
||||
/**
|
||||
* :member:`type` is the type of the value contained in this
|
||||
* particular object.
|
||||
*/
|
||||
sf_type type;
|
||||
sfparse_type type;
|
||||
/**
|
||||
* :member:`flags` is bitwise OR of one or more of
|
||||
* :macro:`SF_VALUE_FLAG_* <SF_VALUE_FLAG_NONE>`.
|
||||
* :macro:`SFPARSE_VALUE_FLAG_* <SFPARSE_VALUE_FLAG_NONE>`.
|
||||
*/
|
||||
uint32_t flags;
|
||||
/**
|
||||
* @anonunion_start
|
||||
*
|
||||
* @sf_value_value
|
||||
* @sfparse_value_value
|
||||
*/
|
||||
union {
|
||||
/**
|
||||
* :member:`boolean` contains boolean value if :member:`type` ==
|
||||
* :enum:`sf_type.SF_TYPE_BOOLEAN`. 1 indicates true, and 0
|
||||
* indicates false.
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`. 1 indicates true,
|
||||
* and 0 indicates false.
|
||||
*/
|
||||
int boolean;
|
||||
/**
|
||||
* :member:`integer` contains integer value if :member:`type` is
|
||||
* either :enum:`sf_type.SF_TYPE_INTEGER` or
|
||||
* :enum:`sf_type.SF_TYPE_DATE`.
|
||||
* either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_DATE`.
|
||||
*/
|
||||
int64_t integer;
|
||||
/**
|
||||
* :member:`decimal` contains decimal value if :member:`type` ==
|
||||
* :enum:`sf_type.SF_TYPE_DECIMAL`.
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`.
|
||||
*/
|
||||
sf_decimal decimal;
|
||||
sfparse_decimal decimal;
|
||||
/**
|
||||
* :member:`vec` contains sequence of bytes if :member:`type` is
|
||||
* either :enum:`sf_type.SF_TYPE_STRING`,
|
||||
* :enum:`sf_type.SF_TYPE_TOKEN`, :enum:`sf_type.SF_TYPE_BYTESEQ`,
|
||||
* or :enum:`sf_type.SF_TYPE_DISPSTRING`.
|
||||
* either :enum:`sfparse_type.SFPARSE_TYPE_STRING`,
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`,
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`.
|
||||
*
|
||||
* For :enum:`sf_type.SF_TYPE_STRING`, this field contains one or
|
||||
* more escaped characters if :member:`flags` has
|
||||
* :macro:`SF_VALUE_FLAG_ESCAPED_STRING` set. To unescape the
|
||||
* string, use `sf_unescape`.
|
||||
* For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field
|
||||
* contains one or more escaped characters if :member:`flags` has
|
||||
* :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set. To unescape
|
||||
* the string, use `sfparse_unescape`.
|
||||
*
|
||||
* For :enum:`sf_type.SF_TYPE_BYTESEQ`, this field contains base64
|
||||
* encoded string. To decode this byte string, use
|
||||
* `sf_base64decode`.
|
||||
* For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field
|
||||
* contains base64 encoded string. To decode this byte string,
|
||||
* use `sfparse_base64decode`.
|
||||
*
|
||||
* For :enum:`sf_type.SF_TYPE_DISPSTRING`, this field may contain
|
||||
* percent-encoded UTF-8 byte sequences. To decode it, use
|
||||
* `sf_pctdecode`.
|
||||
* For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field
|
||||
* may contain percent-encoded UTF-8 byte sequences. To decode
|
||||
* it, use `sfparse_pctdecode`.
|
||||
*
|
||||
* If :member:`vec.len <sf_vec.len>` == 0, :member:`vec.base
|
||||
* <sf_vec.base>` is guaranteed to be NULL.
|
||||
* If :member:`vec.len <sfparse_vec.len>` == 0, :member:`vec.base
|
||||
* <sfparse_vec.base>` is guaranteed to be NULL.
|
||||
*/
|
||||
sf_vec vec;
|
||||
sfparse_vec vec;
|
||||
/**
|
||||
* @anonunion_end
|
||||
*/
|
||||
};
|
||||
} sf_value;
|
||||
} sfparse_value;
|
||||
|
||||
/**
|
||||
* @struct
|
||||
*
|
||||
* :type:`sf_parser` is the Structured Field Values parser. Use
|
||||
* `sf_parser_init` to initialize it.
|
||||
* :type:`sfparse_parser` is the Structured Field Values parser. Use
|
||||
* `sfparse_parser_init` to initialize it.
|
||||
*/
|
||||
typedef struct sf_parser {
|
||||
typedef struct sfparse_parser {
|
||||
/* all fields are private */
|
||||
const uint8_t *pos;
|
||||
const uint8_t *end;
|
||||
uint32_t state;
|
||||
} sf_parser;
|
||||
} sfparse_parser;
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_parser_init` initializes |sfp| with the given buffer pointed by
|
||||
* |data| of length |datalen|.
|
||||
* `sfparse_parser_init` initializes |sfp| with the given data encoded
|
||||
* in Structured Field Values pointed by |data| of length |datalen|.
|
||||
*/
|
||||
void sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen);
|
||||
void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data,
|
||||
size_t datalen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_parser_param` reads a parameter. If this function returns 0,
|
||||
* it stores parameter key and value in |dest_key| and |dest_value|
|
||||
* `sfparse_parser_param` reads a parameter. If this function returns
|
||||
* 0, it stores parameter key and value in |dest_key| and |dest_value|
|
||||
* respectively, if they are not NULL.
|
||||
*
|
||||
* This function does no effort to find duplicated keys. Same key may
|
||||
* be reported more than once.
|
||||
*
|
||||
* Caller should keep calling this function until it returns negative
|
||||
* error code. If it returns :macro:`SF_ERR_EOF`, all parameters have
|
||||
* read, and caller can continue to read rest of the values. If it
|
||||
* returns :macro:`SF_ERR_PARSE_ERROR`, it encountered fatal error
|
||||
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all parameters
|
||||
* have read, and caller can continue to read rest of the values. If
|
||||
* it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error
|
||||
* while parsing field value.
|
||||
*/
|
||||
int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value);
|
||||
int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key,
|
||||
sfparse_value *dest_value);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_parser_dict` reads the next dictionary key and value pair. If
|
||||
* this function returns 0, it stores the key and value in |dest_key|
|
||||
* and |dest_value| respectively, if they are not NULL.
|
||||
* `sfparse_parser_dict` reads the next dictionary key and value pair.
|
||||
* If this function returns 0, it stores the key and value in
|
||||
* |dest_key| and |dest_value| respectively, if they are not NULL.
|
||||
*
|
||||
* Caller can optionally read parameters attached to the pair by
|
||||
* calling `sf_parser_param`.
|
||||
* calling `sfparse_parser_param`.
|
||||
*
|
||||
* This function does no effort to find duplicated keys. Same key may
|
||||
* be reported more than once.
|
||||
*
|
||||
* Caller should keep calling this function until it returns negative
|
||||
* error code. If it returns :macro:`SF_ERR_EOF`, all key and value
|
||||
* pairs have been read, and there is nothing left to read.
|
||||
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all key and
|
||||
* value pairs have been read, and there is nothing left to read.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`SF_ERR_EOF`
|
||||
* :macro:`SFPARSE_ERR_EOF`
|
||||
* All values in the dictionary have read.
|
||||
* :macro:`SF_ERR_PARSE_ERROR`
|
||||
* :macro:`SFPARSE_ERR_PARSE`
|
||||
* It encountered fatal error while parsing field value.
|
||||
*/
|
||||
int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value);
|
||||
int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key,
|
||||
sfparse_value *dest_value);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_parser_list` reads the next list item. If this function
|
||||
* `sfparse_parser_list` reads the next list item. If this function
|
||||
* returns 0, it stores the item in |dest| if it is not NULL.
|
||||
*
|
||||
* Caller can optionally read parameters attached to the item by
|
||||
* calling `sf_parser_param`.
|
||||
* calling `sfparse_parser_param`.
|
||||
*
|
||||
* Caller should keep calling this function until it returns negative
|
||||
* error code. If it returns :macro:`SF_ERR_EOF`, all values in the
|
||||
* list have been read, and there is nothing left to read.
|
||||
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in
|
||||
* the list have been read, and there is nothing left to read.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`SF_ERR_EOF`
|
||||
* :macro:`SFPARSE_ERR_EOF`
|
||||
* All values in the list have read.
|
||||
* :macro:`SF_ERR_PARSE_ERROR`
|
||||
* :macro:`SFPARSE_ERR_PARSE`
|
||||
* It encountered fatal error while parsing field value.
|
||||
*/
|
||||
int sf_parser_list(sf_parser *sfp, sf_value *dest);
|
||||
int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_parser_item` reads a single item. If this function returns 0,
|
||||
* it stores the item in |dest| if it is not NULL.
|
||||
* `sfparse_parser_item` reads a single item. If this function
|
||||
* returns 0, it stores the item in |dest| if it is not NULL.
|
||||
*
|
||||
* This function is only used for the field value that consists of a
|
||||
* single item.
|
||||
*
|
||||
* Caller can optionally read parameters attached to the item by
|
||||
* calling `sf_parser_param`.
|
||||
* calling `sfparse_parser_param`.
|
||||
*
|
||||
* Caller should call this function again to make sure that there is
|
||||
* nothing left to read. If this 2nd function call returns
|
||||
* :macro:`SF_ERR_EOF`, all data have been processed successfully.
|
||||
* :macro:`SFPARSE_ERR_EOF`, all data have been processed
|
||||
* successfully.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`SF_ERR_EOF`
|
||||
* :macro:`SFPARSE_ERR_EOF`
|
||||
* There is nothing left to read.
|
||||
* :macro:`SF_ERR_PARSE_ERROR`
|
||||
* :macro:`SFPARSE_ERR_PARSE`
|
||||
* It encountered fatal error while parsing field value.
|
||||
*/
|
||||
int sf_parser_item(sf_parser *sfp, sf_value *dest);
|
||||
int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_parser_inner_list` reads the next inner list item. If this
|
||||
* function returns 0, it stores the item in |dest| if it is not NULL.
|
||||
* `sfparse_parser_inner_list` reads the next inner list item. If
|
||||
* this function returns 0, it stores the item in |dest| if it is not
|
||||
* NULL.
|
||||
*
|
||||
* Caller can optionally read parameters attached to the item by
|
||||
* calling `sf_parser_param`.
|
||||
* calling `sfparse_parser_param`.
|
||||
*
|
||||
* Caller should keep calling this function until it returns negative
|
||||
* error code. If it returns :macro:`SF_ERR_EOF`, all values in this
|
||||
* inner list have been read, and caller can optionally read
|
||||
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in
|
||||
* this inner list have been read, and caller can optionally read
|
||||
* parameters attached to this inner list by calling
|
||||
* `sf_parser_param`. Then caller can continue to read rest of the
|
||||
* values.
|
||||
* `sfparse_parser_param`. Then caller can continue to read rest of
|
||||
* the values.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :macro:`SF_ERR_EOF`
|
||||
* :macro:`SFPARSE_ERR_EOF`
|
||||
* All values in the inner list have read.
|
||||
* :macro:`SF_ERR_PARSE_ERROR`
|
||||
* :macro:`SFPARSE_ERR_PARSE`
|
||||
* It encountered fatal error while parsing field value.
|
||||
*/
|
||||
int sf_parser_inner_list(sf_parser *sfp, sf_value *dest);
|
||||
int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_unescape` copies |src| to |dest| by removing escapes (``\``).
|
||||
* |src| should be the pointer to :member:`sf_value.vec` of type
|
||||
* :enum:`sf_type.SF_TYPE_STRING` produced by either `sf_parser_dict`,
|
||||
* `sf_parser_list`, `sf_parser_inner_list`, `sf_parser_item`, or
|
||||
* `sf_parser_param`, otherwise the behavior is undefined.
|
||||
* `sfparse_unescape` copies |src| to |dest| by removing escapes
|
||||
* (``\``). |src| should be the pointer to
|
||||
* :member:`sfparse_value.vec` of type
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either
|
||||
* `sfparse_parser_dict`, `sfparse_parser_list`,
|
||||
* `sfparse_parser_inner_list`, `sfparse_parser_item`, or
|
||||
* `sfparse_parser_param`, otherwise the behavior is undefined.
|
||||
*
|
||||
* :member:`dest->base <sf_vec.base>` must point to the buffer that
|
||||
* has sufficient space to store the unescaped string.
|
||||
* :member:`dest->base <sfparse_vec.base>` must point to the buffer
|
||||
* that has sufficient space to store the unescaped string. The
|
||||
* memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
|
||||
* :member:`src->base <sfparse_vec.base>` must not overlap.
|
||||
*
|
||||
* This function sets the length of unescaped string to
|
||||
* :member:`dest->len <sf_vec.len>`.
|
||||
* :member:`dest->len <sfparse_vec.len>`.
|
||||
*/
|
||||
void sf_unescape(sf_vec *dest, const sf_vec *src);
|
||||
void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_base64decode` decodes Base64 encoded string |src| and writes
|
||||
* `sfparse_base64decode` decodes Base64 encoded string |src| and
|
||||
* writes the result into |dest|. |src| should be the pointer to
|
||||
* :member:`sfparse_value.vec` of type
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either
|
||||
* `sfparse_parser_dict`, `sfparse_parser_list`,
|
||||
* `sfparse_parser_inner_list`, `sfparse_parser_item`, or
|
||||
* `sfparse_parser_param`, otherwise the behavior is undefined.
|
||||
*
|
||||
* :member:`dest->base <sfparse_vec.base>` must point to the buffer
|
||||
* that has sufficient space to store the decoded byte string.
|
||||
*
|
||||
* This function sets the length of decoded byte string to
|
||||
* :member:`dest->len <sfparse_vec.len>`.
|
||||
*/
|
||||
void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sfparse_pctdecode` decodes percent-encoded string |src| and writes
|
||||
* the result into |dest|. |src| should be the pointer to
|
||||
* :member:`sf_value.vec` of type :enum:`sf_type.SF_TYPE_BYTESEQ`
|
||||
* produced by either `sf_parser_dict`, `sf_parser_list`,
|
||||
* `sf_parser_inner_list`, `sf_parser_item`, or `sf_parser_param`,
|
||||
* otherwise the behavior is undefined.
|
||||
* :member:`sfparse_value.vec` of type
|
||||
* :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either
|
||||
* `sfparse_parser_dict`, `sfparse_parser_list`,
|
||||
* `sfparse_parser_inner_list`, `sfparse_parser_item`, or
|
||||
* `sfparse_parser_param`, otherwise the behavior is undefined.
|
||||
*
|
||||
* :member:`dest->base <sf_vec.base>` must point to the buffer that
|
||||
* has sufficient space to store the decoded byte string.
|
||||
* :member:`dest->base <sfparse_vec.base>` must point to the buffer
|
||||
* that has sufficient space to store the decoded byte string. The
|
||||
* memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
|
||||
* :member:`src->base <sfparse_vec.base>` must not overlap.
|
||||
*
|
||||
* This function sets the length of decoded byte string to
|
||||
* :member:`dest->len <sf_vec.len>`.
|
||||
* :member:`dest->len <sfparse_vec.len>`.
|
||||
*/
|
||||
void sf_base64decode(sf_vec *dest, const sf_vec *src);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* `sf_pctdecode` decodes percent-encoded string |src| and writes the
|
||||
* result into |dest|. |src| should be the pointer to
|
||||
* :member:`sf_value.vec` of type :enum:`sf_type.SF_TYPE_DISPSTRING`
|
||||
* produced by either `sf_parser_dict`, `sf_parser_list`,
|
||||
* `sf_parser_inner_list`, `sf_parser_item`, or `sf_parser_param`,
|
||||
* otherwise the behavior is undefined.
|
||||
*
|
||||
* :member:`dest->base <sf_vec.base>` must point to the buffer that
|
||||
* has sufficient space to store the decoded byte string.
|
||||
*
|
||||
* This function sets the length of decoded byte string to
|
||||
* :member:`dest->len <sf_vec.len>`.
|
||||
*/
|
||||
void sf_pctdecode(sf_vec *dest, const sf_vec *src);
|
||||
void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* SFPARSE_H */
|
||||
#endif /* !defined(SFPARSE_H) */
|
||||
|
|
4
deps/ngtcp2/ngtcp2.gyp
vendored
4
deps/ngtcp2/ngtcp2.gyp
vendored
|
@ -57,6 +57,7 @@
|
|||
'nghttp3_sources': [
|
||||
'nghttp3/lib/nghttp3_balloc.c',
|
||||
'nghttp3/lib/nghttp3_buf.c',
|
||||
'nghttp3/lib/nghttp3_callbacks.c',
|
||||
'nghttp3/lib/nghttp3_conn.c',
|
||||
'nghttp3/lib/nghttp3_conv.c',
|
||||
'nghttp3/lib/nghttp3_debug.c',
|
||||
|
@ -77,14 +78,13 @@
|
|||
'nghttp3/lib/nghttp3_range.c',
|
||||
'nghttp3/lib/nghttp3_rcbuf.c',
|
||||
'nghttp3/lib/nghttp3_ringbuf.c',
|
||||
'nghttp3/lib/nghttp3_settings.c',
|
||||
'nghttp3/lib/nghttp3_str.c',
|
||||
'nghttp3/lib/nghttp3_stream.c',
|
||||
'nghttp3/lib/nghttp3_tnode.c',
|
||||
'nghttp3/lib/nghttp3_unreachable.c',
|
||||
'nghttp3/lib/nghttp3_vec.c',
|
||||
'nghttp3/lib/nghttp3_version.c',
|
||||
# sfparse is also used by nghttp2 and is included by nghttp2.gyp
|
||||
# 'nghttp3/lib/sfparse.c'
|
||||
]
|
||||
},
|
||||
'targets': [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue