public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/nodejs22] rawhide: Update to version 22.23.1 (rhbz#2477273).
@ 2026-07-20 9:27 tjuhasz
0 siblings, 0 replies; only message in thread
From: tjuhasz @ 2026-07-20 9:27 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/nodejs22
Branch : rawhide
Commit : b023a9b3af079efff47fbcbcea5aeb0c66445798
Author : tjuhasz <tjuhasz@redhat.com>
Date : 2026-07-20T09:27:36+00:00
Stats : +32/-7741 in 3 file(s)
URL : https://src.fedoraproject.org/rpms/nodejs22/c/b023a9b3af079efff47fbcbcea5aeb0c66445798?branch=rawhide
Log:
Update to version 22.23.1 (rhbz#2477273).
Fix for:
CVE-2026-6733 - undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse
(rhbz#2490212)
CVE-2026-11525 - undici: Weakening of cookie SameSite policy due to incorrect parsing of Set-Cookie header
(rhbz#2490208)
CVE-2026-12151 - undici: Denial of Service due to unbounded memory growth via WebSocket frames
(rhbz#2490221)
CVE-2026-9679 - undici vulnerable to HTTP header injection via Set-Cookie percent-decoding
(rhbz#2490200)
CVE-2026-48618 tls: normalize hostname for server identity checks.
(rhbz#2493811)
CVE-2026-48933 crypto: guard WebCrypto cipher output length.
(rhbz#2493802)
CVE-2026-48930 dns,net: reject hostnames with embedded NUL bytes.
(rhbz#2493836)
CVE-2026-48619 http2: cap originSet size to prevent unbounded memory growth.
(rhbz#2493733)
CVE-2026-48615 lib,test: redact proxy credentials in tunnel errors.
(rhbz#2493819)
CVE-2026-48934 tls: bind reusable sessions to authenticated host.
(rhbz#2493826)
CVE-2026-48928 tls: fix case-sensitive SNI context matching.
(rhbz#2493822)
CVE-2026-48935 permission: disable FileHandle utimes with permission model.
(rhbz#2493830)
CVE-2026-48936 - Local server can be started without network permission via Permission API flaw
(rhbz#2493815)
CVE-2026-48937 deps: fix integration issues with the latest nghttp2.
CVE-2026-48931 http: fix response queue poisoning in http.Agent.
CVE-2026-48617 permission: handle process.chdir on writereport.
---
diff --git a/0001-deps-update-nghttp2-to-1.68.1.patch b/0001-deps-update-nghttp2-to-1.68.1.patch
deleted file mode 100644
index a17d73d..0000000
--- a/0001-deps-update-nghttp2-to-1.68.1.patch
+++ /dev/null
@@ -1,7712 +0,0 @@
-From cd7cd6dfe1ffd35832f797fe7942f4ccd1d51d07 Mon Sep 17 00:00:00 2001
-From: Andrei Radchenko <aradchen@redhat.com>
-Date: Thu, 26 Mar 2026 11:32:18 +0100
-Subject: [PATCH] deps: update nghttp2 to 1.68.1
-
----
- deps/nghttp2/lib/CMakeLists.txt | 40 +-
- deps/nghttp2/lib/Makefile.am | 2 +-
- deps/nghttp2/lib/Makefile.in | 6 +-
- deps/nghttp2/lib/config.cmake.in | 3 +
- deps/nghttp2/lib/includes/Makefile.in | 4 +
- deps/nghttp2/lib/includes/nghttp2/nghttp2.h | 315 ++---
- .../nghttp2/lib/includes/nghttp2/nghttp2ver.h | 4 +-
- deps/nghttp2/lib/nghttp2_alpn.h | 4 +-
- deps/nghttp2/lib/nghttp2_buf.h | 4 +-
- deps/nghttp2/lib/nghttp2_callbacks.c | 5 +
- deps/nghttp2/lib/nghttp2_callbacks.h | 5 +-
- deps/nghttp2/lib/nghttp2_debug.c | 4 +-
- deps/nghttp2/lib/nghttp2_debug.h | 8 +-
- deps/nghttp2/lib/nghttp2_extpri.h | 4 +-
- deps/nghttp2/lib/nghttp2_frame.c | 10 +
- deps/nghttp2/lib/nghttp2_frame.h | 4 +-
- deps/nghttp2/lib/nghttp2_hd.c | 11 +
- deps/nghttp2/lib/nghttp2_hd.h | 4 +-
- deps/nghttp2/lib/nghttp2_hd_huffman.h | 4 +-
- deps/nghttp2/lib/nghttp2_helper.h | 4 +-
- deps/nghttp2/lib/nghttp2_http.c | 17 +-
- deps/nghttp2/lib/nghttp2_http.h | 4 +-
- deps/nghttp2/lib/nghttp2_int.h | 10 +-
- deps/nghttp2/lib/nghttp2_map.c | 70 +-
- deps/nghttp2/lib/nghttp2_map.h | 9 +-
- deps/nghttp2/lib/nghttp2_mem.h | 4 +-
- deps/nghttp2/lib/nghttp2_net.h | 16 +-
- deps/nghttp2/lib/nghttp2_option.c | 7 +
- deps/nghttp2/lib/nghttp2_option.h | 10 +-
- deps/nghttp2/lib/nghttp2_outbound_item.h | 4 +-
- deps/nghttp2/lib/nghttp2_pq.h | 4 +-
- deps/nghttp2/lib/nghttp2_priority_spec.h | 4 +-
- deps/nghttp2/lib/nghttp2_queue.h | 4 +-
- deps/nghttp2/lib/nghttp2_ratelim.h | 4 +-
- deps/nghttp2/lib/nghttp2_rcbuf.h | 4 +-
- deps/nghttp2/lib/nghttp2_session.c | 1163 ++++++-----------
- deps/nghttp2/lib/nghttp2_session.h | 147 +--
- deps/nghttp2/lib/nghttp2_stream.c | 847 +-----------
- deps/nghttp2/lib/nghttp2_stream.h | 161 +--
- deps/nghttp2/lib/nghttp2_submit.c | 164 +--
- deps/nghttp2/lib/nghttp2_submit.h | 4 +-
- deps/nghttp2/lib/nghttp2_time.c | 15 +-
- deps/nghttp2/lib/nghttp2_time.h | 4 +-
- deps/nghttp2/lib/nghttp2_version.c | 2 +-
- deps/nghttp2/lib/sfparse.c | 1140 ++++++++++++----
- deps/nghttp2/lib/sfparse.h | 313 +++--
- 46 files changed, 1834 insertions(+), 2742 deletions(-)
- create mode 100644 deps/nghttp2/lib/config.cmake.in
-
-diff --git a/deps/nghttp2/lib/CMakeLists.txt b/deps/nghttp2/lib/CMakeLists.txt
-index fda8dcb7..98e3dbe7 100644
---- a/deps/nghttp2/lib/CMakeLists.txt
-+++ b/deps/nghttp2/lib/CMakeLists.txt
-@@ -47,7 +47,29 @@ if(WIN32)
- set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
- endif()
-
--set(EXPORT_SET "${PROJECT_NAME}-targets")
-+set(NGHTTP2_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
-+set(NGHTTP2_VERSION_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
-+set(NGHTTP2_PROJECT_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
-+set(NGHTTP2_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
-+set(NGHTTP2_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
-+set(NGHTTP2_NAMESPACE "${PROJECT_NAME}::")
-+set(NGHTTP2_VERSION ${PROJECT_VERSION})
-+
-+include(CMakePackageConfigHelpers)
-+write_basic_package_version_file(
-+ "${NGHTTP2_VERSION_CONFIG}" VERSION ${NGHTTP2_VERSION} COMPATIBILITY SameMajorVersion
-+)
-+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in" "${NGHTTP2_PROJECT_CONFIG}" @ONLY)
-+
-+# Install cmake config files
-+install(
-+ FILES "${NGHTTP2_PROJECT_CONFIG}" "${NGHTTP2_VERSION_CONFIG}"
-+ DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
-+
-+install(
-+ EXPORT "${NGHTTP2_TARGETS_EXPORT_NAME}"
-+ NAMESPACE "${NGHTTP2_NAMESPACE}"
-+ DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
-
- # Public shared library
- if(BUILD_SHARED_LIBS)
-@@ -65,7 +87,11 @@ if(BUILD_SHARED_LIBS)
- $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
- )
-
-- install(TARGETS ${SHARED_LIB} EXPORT ${EXPORT_SET})
-+ install(TARGETS ${SHARED_LIB}
-+ EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
-+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
-+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
- list(APPEND nghttp2_exports ${SHARED_LIB})
- endif()
-
-@@ -87,7 +113,9 @@ if(BUILD_STATIC_LIBS)
-
- target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB")
-
-- install(TARGETS ${STATIC_LIB} EXPORT ${EXPORT_SET})
-+ install(TARGETS ${STATIC_LIB}
-+ EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
-+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
- list(APPEND nghttp2_exports ${STATIC_LIB})
- endif()
-
-@@ -97,11 +125,7 @@ else()
- set(LIB_SELECTED ${STATIC_LIB})
- endif()
-
--add_library(${PROJECT_NAME}::nghttp2 ALIAS ${LIB_SELECTED})
-+add_library(nghttp2 ALIAS ${LIB_SELECTED})
-
- install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
--
--install(EXPORT ${EXPORT_SET}
-- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
-- NAMESPACE ${PROJECT_NAME}::)
-diff --git a/deps/nghttp2/lib/Makefile.am b/deps/nghttp2/lib/Makefile.am
-index 1168c1e6..3a743df6 100644
---- a/deps/nghttp2/lib/Makefile.am
-+++ b/deps/nghttp2/lib/Makefile.am
-@@ -22,7 +22,7 @@
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- SUBDIRS = includes
-
--EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
-+EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in
-
- AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
- AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
-diff --git a/deps/nghttp2/lib/Makefile.in b/deps/nghttp2/lib/Makefile.in
-index 14686ef1..bb458a18 100644
---- a/deps/nghttp2/lib/Makefile.in
-+++ b/deps/nghttp2/lib/Makefile.in
-@@ -360,6 +360,10 @@ LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
- LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
- LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
- LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
-+LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS = @LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS@
-+LIBNGTCP2_CRYPTO_LIBRESSL_LIBS = @LIBNGTCP2_CRYPTO_LIBRESSL_LIBS@
-+LIBNGTCP2_CRYPTO_OSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OSSL_CFLAGS@
-+LIBNGTCP2_CRYPTO_OSSL_LIBS = @LIBNGTCP2_CRYPTO_OSSL_LIBS@
- LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS = @LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@
- LIBNGTCP2_CRYPTO_QUICTLS_LIBS = @LIBNGTCP2_CRYPTO_QUICTLS_LIBS@
- LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS = @LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@
-@@ -492,7 +496,7 @@ top_srcdir = @top_srcdir@
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- SUBDIRS = includes
--EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
-+EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in
- AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
- AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
- @DEFS@
-diff --git a/deps/nghttp2/lib/config.cmake.in b/deps/nghttp2/lib/config.cmake.in
-new file mode 100644
-index 00000000..0b677718
---- /dev/null
-+++ b/deps/nghttp2/lib/config.cmake.in
-@@ -0,0 +1,3 @@
-+include(CMakeFindDependencyMacro)
-+
-+include("${CMAKE_CURRENT_LIST_DIR}/@NGHTTP2_TARGETS_EXPORT_NAME@.cmake")
-diff --git a/deps/nghttp2/lib/includes/Makefile.in b/deps/nghttp2/lib/includes/Makefile.in
-index 778dcb87..a4687390 100644
---- a/deps/nghttp2/lib/includes/Makefile.in
-+++ b/deps/nghttp2/lib/includes/Makefile.in
-@@ -265,6 +265,10 @@ LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@
- LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@
- LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS = @LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@
- LIBNGTCP2_CRYPTO_BORINGSSL_LIBS = @LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@
-+LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS = @LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS@
-+LIBNGTCP2_CRYPTO_LIBRESSL_LIBS = @LIBNGTCP2_CRYPTO_LIBRESSL_LIBS@
-+LIBNGTCP2_CRYPTO_OSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OSSL_CFLAGS@
-+LIBNGTCP2_CRYPTO_OSSL_LIBS = @LIBNGTCP2_CRYPTO_OSSL_LIBS@
- LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS = @LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@
- LIBNGTCP2_CRYPTO_QUICTLS_LIBS = @LIBNGTCP2_CRYPTO_QUICTLS_LIBS@
- LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS = @LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@
-diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
-index 2ef49b8d..19c1874f 100644
---- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
-+++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
-@@ -2039,18 +2039,19 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
- /**
- * @functypedef
- *
-- * Callback function invoked when a invalid header name/value pair is
-+ * Callback function invoked when an invalid header name/value pair is
- * received for the |frame|.
- *
- * The parameter and behaviour are similar to
- * :type:`nghttp2_on_header_callback`. The difference is that this
-- * callback is only invoked when a invalid header name/value pair is
-- * received which is treated as stream error if this callback is not
-- * set. Only invalid regular header field are passed to this
-- * callback. In other words, invalid pseudo header field is not
-- * passed to this callback. Also header fields which includes upper
-- * cased latter are also treated as error without passing them to this
-- * callback.
-+ * callback is only invoked when an invalid header name/value pair is
-+ * received which is treated as stream error if this callback returns
-+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and
-+ * :type:`nghttp2_on_invalid_header_callback2` is not set. Only
-+ * invalid regular header field are passed to this callback. In other
-+ * words, invalid pseudo header field is not passed to this callback.
-+ * Also header fields which includes upper cased latter are also
-+ * treated as error without passing them to this callback.
- *
- * This callback is only considered if HTTP messaging validation is
- * turned on (which is on by default, see
-@@ -2076,17 +2077,18 @@ typedef int (*nghttp2_on_invalid_header_callback)(
- /**
- * @functypedef
- *
-- * Callback function invoked when a invalid header name/value pair is
-+ * Callback function invoked when an invalid header name/value pair is
- * received for the |frame|.
- *
- * The parameter and behaviour are similar to
- * :type:`nghttp2_on_header_callback2`. The difference is that this
-- * callback is only invoked when a invalid header name/value pair is
-- * received which is silently ignored if this callback is not set.
-- * Only invalid regular header field are passed to this callback. In
-- * other words, invalid pseudo header field is not passed to this
-- * callback. Also header fields which includes upper cased latter are
-- * also treated as error without passing them to this callback.
-+ * callback is only invoked when an invalid header name/value pair is
-+ * received which is silently ignored if neither this callback nor
-+ * :type:`nghttp2_on_invalid_header_callback` is set. Only invalid
-+ * regular header field are passed to this callback. In other words,
-+ * invalid pseudo header field is not passed to this callback. Also
-+ * header fields which includes upper cased latter are also treated as
-+ * error without passing them to this callback.
- *
- * This callback is only considered if HTTP messaging validation is
- * turned on (which is on by default, see
-@@ -2445,6 +2447,15 @@ typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
- int lib_error_code, const char *msg,
- size_t len, void *user_data);
-
-+/**
-+ * @functypedef
-+ *
-+ * Callback function 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 (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen);
-+
- struct nghttp2_session_callbacks;
-
- /**
-@@ -2649,7 +2660,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
- /**
- * @function
- *
-- * Sets callback function invoked when a invalid header name/value
-+ * Sets callback function invoked when an invalid header name/value
- * pair is received. If both
- * `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
- * `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
-@@ -2662,7 +2673,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
- /**
- * @function
- *
-- * Sets callback function invoked when a invalid header name/value
-+ * Sets callback function invoked when an invalid header name/value
- * pair is received.
- */
- NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
-@@ -2833,6 +2844,18 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
- NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
- nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
-
-+/**
-+ * @function
-+ *
-+ * Sets callback function invoked when unpredictable data is needed.
-+ * Although this callback is optional due to the backward
-+ * compatibility, it is recommended to specify it to harden the
-+ * runtime behavior against suspicious activities of a remote
-+ * endpoint.
-+ */
-+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback(
-+ nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback);
-+
- /**
- * @functypedef
- *
-@@ -3133,14 +3156,12 @@ nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
- /**
- * @function
- *
-- * This option prevents the library from retaining closed streams to
-- * maintain the priority tree. If this option is set to nonzero,
-- * applications can discard closed stream completely to save memory.
-+ * .. warning::
- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is submitted via `nghttp2_submit_settings()`, any
-- * closed streams are not retained regardless of this option.
-+ * Deprecated. Closed streams are not retained anymore.
-+ *
-+ * This function works as before, but it does not take any effect
-+ * against :type:`nghttp2_session`.
- */
- NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
- int val);
-@@ -3170,16 +3191,11 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
- /**
- * @function
- *
-- * This option, if set to nonzero, allows server to fallback to
-- * :rfc:`7540` priorities if SETTINGS_NO_RFC7540_PRIORITIES was not
-- * received from client, and server submitted
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * = 1 via `nghttp2_submit_settings()`. Most of the advanced
-- * functionality for RFC 7540 priorities are still disabled. This
-- * fallback only enables the minimal feature set of RFC 7540
-- * priorities to deal with priority signaling from client.
-+ * .. warning::
-+ * Deprecated. :rfc:`7540` priorities have been removed.
- *
-- * Client session ignores this option.
-+ * This function works as before, but it does not take any effect
-+ * against :type:`nghttp2_session`.
- */
- NGHTTP2_EXTERN void
- nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option,
-@@ -3225,6 +3241,23 @@ nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
- NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
- size_t val);
-
-+/**
-+ * @function
-+ *
-+ * This function sets the rate limit for the "glitches", the
-+ * suspicious activities from a remote endpoint. It is a token-bucket
-+ * based rate limiter. |burst| specifies the number of tokens that is
-+ * initially available. The maximum number of tokens is capped to
-+ * this value. |rate| specifies the number of tokens that are
-+ * regenerated per second. When a suspicious activity is detected,
-+ * some amount of tokens are consumed. If there is no token
-+ * available, GOAWAY is sent to tear down the connection. |burst| and
-+ * |rate| default to 1000 and 33 respectively.
-+ */
-+NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
-+ uint64_t burst,
-+ uint64_t rate);
-+
- /**
- * @function
- *
-@@ -4179,39 +4212,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return 0 without doing anything.
-- *
-- * Changes priority of existing stream denoted by |stream_id|. The
-- * new priority specification is |pri_spec|.
-- *
-- * The priority is changed silently and instantly, and no PRIORITY
-- * frame will be sent to notify the peer of this change. This
-- * function may be useful for server to change the priority of pushed
-- * stream.
-- *
-- * If |session| is initialized as server, and ``pri_spec->stream_id``
-- * points to the idle stream, the idle stream is created if it does
-- * not exist. The created idle stream will depend on root stream
-- * (stream 0) with weight 16.
-- *
-- * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not
-- * found, we use default priority instead of given |pri_spec|. That
-- * is make stream depend on root stream with weight 16.
-- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is submitted via `nghttp2_submit_settings()`, this
-- * function does nothing and returns 0.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-+ * prioritization scheme.
- *
-- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
-- * Out of memory.
-- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
-- * Attempted to depend on itself; or no stream exist for the given
-- * |stream_id|; or |stream_id| is 0
-+ * This function is noop. It always returns 0.
- */
- NGHTTP2_EXTERN int
- nghttp2_session_change_stream_priority(nghttp2_session *session,
-@@ -4225,51 +4228,9 @@ nghttp2_session_change_stream_priority(nghttp2_session *session,
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return 0 without doing anything.
-- *
-- * Creates idle stream with the given |stream_id|, and priority
-- * |pri_spec|.
-- *
-- * The stream creation is done without sending PRIORITY frame, which
-- * means that peer does not know about the existence of this idle
-- * stream in the local endpoint.
-- *
-- * RFC 7540 does not disallow the use of creation of idle stream with
-- * odd or even stream ID regardless of client or server. So this
-- * function can create odd or even stream ID regardless of client or
-- * server. But probably it is a bit safer to use the stream ID the
-- * local endpoint can initiate (in other words, use odd stream ID for
-- * client, and even stream ID for server), to avoid potential
-- * collision from peer's instruction. Also we can use
-- * `nghttp2_session_set_next_stream_id()` to avoid to open created
-- * idle streams accidentally if we follow this recommendation.
-- *
-- * If |session| is initialized as server, and ``pri_spec->stream_id``
-- * points to the idle stream, the idle stream is created if it does
-- * not exist. The created idle stream will depend on root stream
-- * (stream 0) with weight 16.
-- *
-- * Otherwise, if stream denoted by ``pri_spec->stream_id`` is not
-- * found, we use default priority instead of given |pri_spec|. That
-- * is make stream depend on root stream with weight 16.
-- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is submitted via `nghttp2_submit_settings()`, this
-- * function does nothing and returns 0.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-+ * prioritization scheme.
- *
-- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
-- * Out of memory.
-- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
-- * Attempted to depend on itself; or stream denoted by |stream_id|
-- * already exists; or |stream_id| cannot be used to create idle
-- * stream (in other words, local endpoint has already opened
-- * stream ID greater than or equal to the given stream ID; or
-- * |stream_id| is 0
-+ * This function is noop. It always returns 0.
- */
- NGHTTP2_EXTERN int
- nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
-@@ -4505,23 +4466,7 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
- *
- * Submits HEADERS frame and optionally one or more DATA frames.
- *
-- * The |pri_spec| is a deprecated priority specification of this
-- * request. ``NULL`` means the default priority (see
-- * `nghttp2_priority_spec_default_init()`). To specify the priority,
-- * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
-- * this function will copy its data members.
-- *
-- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
-- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
-- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MAX_WEIGHT`.
-- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is received by a remote endpoint, |pri_spec| is
-- * ignored, and treated as if ``NULL`` is specified.
-+ * The |pri_spec| is ignored.
- *
- * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
- * |nvlen| elements. The application is responsible to include
-@@ -4564,9 +4509,6 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
- * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
- * No stream ID is available because maximum stream ID was
- * reached.
-- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
-- * Trying to depend on itself (new stream ID equals
-- * ``pri_spec->stream_id``).
- * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
- * The |session| is server session.
- *
-@@ -4594,25 +4536,7 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
- *
- * Submits HEADERS frame and optionally one or more DATA frames.
- *
-- * The |pri_spec| is a deprecated priority specification of this
-- * request. ``NULL`` means the default priority (see
-- * `nghttp2_priority_spec_default_init()`). To specify the priority,
-- * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
-- * this function will copy its data members. In the future release
-- * after the end of 2024, this function will ignore |pri_spec| and
-- * behave as if ``NULL`` is given.
-- *
-- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
-- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
-- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MAX_WEIGHT`.
-- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is received by a remote endpoint, |pri_spec| is
-- * ignored, and treated as if ``NULL`` is specified.
-+ * The |pri_spec| is ignored.
- *
- * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
- * |nvlen| elements. The application is responsible to include
-@@ -4655,9 +4579,6 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request(
- * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
- * No stream ID is available because maximum stream ID was
- * reached.
-- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
-- * Trying to depend on itself (new stream ID equals
-- * ``pri_spec->stream_id``).
- * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
- * The |session| is server session.
- *
-@@ -4899,24 +4820,7 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
- * assigned stream ID will be returned. Otherwise, specify stream ID
- * in |stream_id|.
- *
-- * The |pri_spec| is a deprecated priority specification of this
-- * request. ``NULL`` means the default priority (see
-- * `nghttp2_priority_spec_default_init()`). To specify the priority,
-- * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``,
-- * this function will copy its data members. In the future release
-- * after the end of 2024, this function will ignore |pri_spec| and
-- * behave as if ``NULL`` is given.
-- *
-- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
-- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
-- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
-- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is received by a remote endpoint, |pri_spec| is
-- * ignored, and treated as if ``NULL`` is specified.
-+ * The |pri_spec| is ignored.
- *
- * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
- * |nvlen| elements. The application is responsible to include
-@@ -4956,8 +4860,7 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
- * No stream ID is available because maximum stream ID was
- * reached.
- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
-- * The |stream_id| is 0; or trying to depend on itself (stream ID
-- * equals ``pri_spec->stream_id``).
-+ * The |stream_id| is 0.
- * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
- * DATA or HEADERS has been already submitted and not fully
- * processed yet. This happens if stream denoted by |stream_id|
-@@ -5083,40 +4986,9 @@ NGHTTP2_EXTERN int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags,
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return 0 without doing anything.
-- *
-- * Submits PRIORITY frame to change the priority of stream |stream_id|
-- * to the priority specification |pri_spec|.
-- *
-- * The |flags| is currently ignored and should be
-- * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
-- *
-- * The |pri_spec| is a deprecated priority specification of this
-- * request. ``NULL`` is not allowed for this function. To specify the
-- * priority, use `nghttp2_priority_spec_init()`. This function will
-- * copy its data members.
-- *
-- * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`,
-- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight``
-- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than
-- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
-- * :macro:`NGHTTP2_MAX_WEIGHT`.
-- *
-- * If
-- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
-- * of value of 1 is received by a remote endpoint, this function does
-- * nothing and returns 0.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-+ * prioritization scheme.
- *
-- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
-- * Out of memory.
-- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
-- * The |stream_id| is 0; or the |pri_spec| is NULL; or trying to
-- * depend on itself.
-+ * This function is noop. It always returns 0.
- */
- NGHTTP2_EXTERN int
- nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
-@@ -6885,11 +6757,9 @@ nghttp2_session_get_root_stream(nghttp2_session *session);
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return NULL.
-+ * prioritization scheme.
- *
-- * Returns the parent stream of |stream| in dependency tree. Returns
-- * NULL if there is no such stream.
-+ * This function always returns NULL.
- */
- NGHTTP2_EXTERN nghttp2_stream *
- nghttp2_stream_get_parent(nghttp2_stream *stream);
-@@ -6903,11 +6773,9 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream);
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return NULL.
-+ * prioritization scheme.
- *
-- * Returns the next sibling stream of |stream| in dependency tree.
-- * Returns NULL if there is no such stream.
-+ * This function always returns NULL.
- */
- NGHTTP2_EXTERN nghttp2_stream *
- nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
-@@ -6919,11 +6787,9 @@ nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return NULL.
-+ * prioritization scheme.
- *
-- * Returns the previous sibling stream of |stream| in dependency tree.
-- * Returns NULL if there is no such stream.
-+ * This function always returns NULL.
- */
- NGHTTP2_EXTERN nghttp2_stream *
- nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
-@@ -6935,11 +6801,9 @@ nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return NULL.
-+ * prioritization scheme.
- *
-- * Returns the first child stream of |stream| in dependency tree.
-- * Returns NULL if there is no such stream.
-+ * This function always returns NULL.
- */
- NGHTTP2_EXTERN nghttp2_stream *
- nghttp2_stream_get_first_child(nghttp2_stream *stream);
-@@ -6951,11 +6815,9 @@ nghttp2_stream_get_first_child(nghttp2_stream *stream);
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return
-- * :macro:`NGHTTP2_DEFAULT_WEIGHT`.
-+ * prioritization scheme.
- *
-- * Returns dependency weight to the parent stream of |stream|.
-+ * This function always returns :macro:`NGHTTP2_DEFAULT_WEIGHT`.
- */
- NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
-
-@@ -6966,10 +6828,9 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
- *
- * Deprecated. :rfc:`7540` priorities are deprecated by
- * :rfc:`9113`. Consider migrating to :rfc:`9218` extensible
-- * prioritization scheme. In the future release after the end of
-- * 2024, this function will always return 0.
-+ * prioritization scheme.
- *
-- * Returns the sum of the weight for |stream|'s children.
-+ * This function always returns 0.
- */
- NGHTTP2_EXTERN int32_t
- nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
-diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
-index 827c9989..95acef22 100644
---- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
-+++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
-@@ -29,7 +29,7 @@
- * @macro
- * Version number of the nghttp2 library release
- */
--#define NGHTTP2_VERSION "1.64.0"
-+#define NGHTTP2_VERSION "1.68.1"
-
- /**
- * @macro
-@@ -37,6 +37,6 @@
- * release. This is a 24 bit number with 8 bits for major number, 8 bits
- * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
- */
--#define NGHTTP2_VERSION_NUM 0x014000
-+#define NGHTTP2_VERSION_NUM 0x014401
-
- #endif /* NGHTTP2VER_H */
-diff --git a/deps/nghttp2/lib/nghttp2_alpn.h b/deps/nghttp2/lib/nghttp2_alpn.h
-index 09810fd8..ecc9ed20 100644
---- a/deps/nghttp2/lib/nghttp2_alpn.h
-+++ b/deps/nghttp2/lib/nghttp2_alpn.h
-@@ -27,8 +27,8 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
--#endif /* NGHTTP2_ALPN_H */
-+#endif /* !defined(NGHTTP2_ALPN_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_buf.h b/deps/nghttp2/lib/nghttp2_buf.h
-index 95ff3706..636aa619 100644
---- a/deps/nghttp2/lib/nghttp2_buf.h
-+++ b/deps/nghttp2/lib/nghttp2_buf.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -409,4 +409,4 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
- */
- size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
-
--#endif /* NGHTTP2_BUF_H */
-+#endif /* !defined(NGHTTP2_BUF_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_callbacks.c b/deps/nghttp2/lib/nghttp2_callbacks.c
-index 32fedd52..162ca6bd 100644
---- a/deps/nghttp2/lib/nghttp2_callbacks.c
-+++ b/deps/nghttp2/lib/nghttp2_callbacks.c
-@@ -201,3 +201,8 @@ void nghttp2_session_callbacks_set_error_callback2(
- nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
- cbs->error_callback2 = error_callback2;
- }
-+
-+void nghttp2_session_callbacks_set_rand_callback(
-+ nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) {
-+ cbs->rand_callback = rand_callback;
-+}
-diff --git a/deps/nghttp2/lib/nghttp2_callbacks.h b/deps/nghttp2/lib/nghttp2_callbacks.h
-index a611f485..4b45e578 100644
---- a/deps/nghttp2/lib/nghttp2_callbacks.h
-+++ b/deps/nghttp2/lib/nghttp2_callbacks.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -151,6 +151,7 @@ struct nghttp2_session_callbacks {
- nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
- nghttp2_error_callback error_callback;
- nghttp2_error_callback2 error_callback2;
-+ nghttp2_rand_callback rand_callback;
- };
-
--#endif /* NGHTTP2_CALLBACKS_H */
-+#endif /* !defined(NGHTTP2_CALLBACKS_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_debug.c b/deps/nghttp2/lib/nghttp2_debug.c
-index 09dd2b28..b5f33ef3 100644
---- a/deps/nghttp2/lib/nghttp2_debug.c
-+++ b/deps/nghttp2/lib/nghttp2_debug.c
-@@ -50,11 +50,11 @@ void nghttp2_set_debug_vprintf_callback(
- static_debug_vprintf_callback = debug_vprintf_callback;
- }
-
--#else /* !DEBUGBUILD */
-+#else /* !defined(DEBUGBUILD) */
-
- void nghttp2_set_debug_vprintf_callback(
- nghttp2_debug_vprintf_callback debug_vprintf_callback) {
- (void)debug_vprintf_callback;
- }
-
--#endif /* !DEBUGBUILD */
-+#endif /* !defined(DEBUGBUILD) */
-diff --git a/deps/nghttp2/lib/nghttp2_debug.h b/deps/nghttp2/lib/nghttp2_debug.h
-index cbb4dd57..26566a62 100644
---- a/deps/nghttp2/lib/nghttp2_debug.h
-+++ b/deps/nghttp2/lib/nghttp2_debug.h
-@@ -27,17 +27,17 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
- #ifdef DEBUGBUILD
- # define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
- void nghttp2_debug_vprintf(const char *format, ...);
--#else
-+#else /* !defined(DEBUGBUILD) */
- # define DEBUGF(...) \
- do { \
- } while (0)
--#endif
-+#endif /* !defined(DEBUGBUILD) */
-
--#endif /* NGHTTP2_DEBUG_H */
-+#endif /* !defined(NGHTTP2_DEBUG_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_extpri.h b/deps/nghttp2/lib/nghttp2_extpri.h
-index db911972..2e039165 100644
---- a/deps/nghttp2/lib/nghttp2_extpri.h
-+++ b/deps/nghttp2/lib/nghttp2_extpri.h
-@@ -28,7 +28,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -62,4 +62,4 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri);
- */
- #define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0)
-
--#endif /* NGHTTP2_EXTPRI_H */
-+#endif /* !defined(NGHTTP2_EXTPRI_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_frame.c b/deps/nghttp2/lib/nghttp2_frame.c
-index edc2aaaa..264ae9d3 100644
---- a/deps/nghttp2/lib/nghttp2_frame.c
-+++ b/deps/nghttp2/lib/nghttp2_frame.c
-@@ -750,6 +750,16 @@ void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
- uint8_t *p;
-
- altsvc = frame->payload;
-+
-+ if (payloadlen == 0) {
-+ altsvc->origin = NULL;
-+ altsvc->origin_len = 0;
-+ altsvc->field_value = NULL;
-+ altsvc->field_value_len = 0;
-+
-+ return;
-+ }
-+
- p = payload;
-
- altsvc->origin = p;
-diff --git a/deps/nghttp2/lib/nghttp2_frame.h b/deps/nghttp2/lib/nghttp2_frame.h
-index d5866880..ed4ab2c6 100644
---- a/deps/nghttp2/lib/nghttp2_frame.h
-+++ b/deps/nghttp2/lib/nghttp2_frame.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
- #include "nghttp2_hd.h"
-@@ -634,4 +634,4 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
- void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
- size_t padlen, int framehd_only);
-
--#endif /* NGHTTP2_FRAME_H */
-+#endif /* !defined(NGHTTP2_FRAME_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_hd.c b/deps/nghttp2/lib/nghttp2_hd.c
-index 55fc2cc6..ad85eed1 100644
---- a/deps/nghttp2/lib/nghttp2_hd.c
-+++ b/deps/nghttp2/lib/nghttp2_hd.c
-@@ -594,8 +594,19 @@ static void hd_map_remove(nghttp2_hd_map *map, nghttp2_hd_entry *ent) {
- static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize,
- nghttp2_mem *mem) {
- size_t size;
-+ const size_t max_size = SIZE_MAX / sizeof(nghttp2_hd_entry *);
-+
-+ if (bufsize > max_size) {
-+ return NGHTTP2_ERR_NOMEM;
-+ }
-+
- for (size = 1; size < bufsize; size <<= 1)
- ;
-+
-+ if (size > max_size) {
-+ return NGHTTP2_ERR_NOMEM;
-+ }
-+
- ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size);
- if (ringbuf->buffer == NULL) {
- return NGHTTP2_ERR_NOMEM;
-diff --git a/deps/nghttp2/lib/nghttp2_hd.h b/deps/nghttp2/lib/nghttp2_hd.h
-index 38a31a83..bdc7fad5 100644
---- a/deps/nghttp2/lib/nghttp2_hd.h
-+++ b/deps/nghttp2/lib/nghttp2_hd.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -439,4 +439,4 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
- */
- int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
-
--#endif /* NGHTTP2_HD_H */
-+#endif /* !defined(NGHTTP2_HD_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_hd_huffman.h b/deps/nghttp2/lib/nghttp2_hd_huffman.h
-index 2bfd5318..df037a8b 100644
---- a/deps/nghttp2/lib/nghttp2_hd_huffman.h
-+++ b/deps/nghttp2/lib/nghttp2_hd_huffman.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -69,4 +69,4 @@ typedef struct {
- extern const nghttp2_huff_sym huff_sym_table[];
- extern const nghttp2_huff_decode huff_decode_table[][16];
-
--#endif /* NGHTTP2_HD_HUFFMAN_H */
-+#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_helper.h b/deps/nghttp2/lib/nghttp2_helper.h
-index f5de6290..7d640761 100644
---- a/deps/nghttp2/lib/nghttp2_helper.h
-+++ b/deps/nghttp2/lib/nghttp2_helper.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <string.h>
- #include <stddef.h>
-@@ -142,4 +142,4 @@ int nghttp2_should_send_window_update(int32_t local_window_size,
- */
- uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
-
--#endif /* NGHTTP2_HELPER_H */
-+#endif /* !defined(NGHTTP2_HELPER_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_http.c b/deps/nghttp2/lib/nghttp2_http.c
-index f222fe5e..60a0b01e 100644
---- a/deps/nghttp2/lib/nghttp2_http.c
-+++ b/deps/nghttp2/lib/nghttp2_http.c
-@@ -207,7 +207,6 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
- if (!trailer &&
- /* Do not parse the header field in PUSH_PROMISE. */
- (stream->stream_id & 1) &&
-- (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
- !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) {
- nghttp2_extpri_from_uint8(&extpri, stream->http_extpri);
- if (nghttp2_http_parse_priority(&extpri, nv->value->base,
-@@ -660,17 +659,17 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream,
- int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
- size_t valuelen) {
- nghttp2_extpri 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;
- }
-
-@@ -683,7 +682,7 @@ int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
-
- switch (key.base[0]) {
- case 'i':
-- if (val.type != SF_TYPE_BOOLEAN) {
-+ if (val.type != SFPARSE_TYPE_BOOLEAN) {
- return NGHTTP2_ERR_INVALID_ARGUMENT;
- }
-
-@@ -691,7 +690,7 @@ int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
-
- break;
- case 'u':
-- if (val.type != SF_TYPE_INTEGER ||
-+ if (val.type != SFPARSE_TYPE_INTEGER ||
- val.integer < NGHTTP2_EXTPRI_URGENCY_HIGH ||
- NGHTTP2_EXTPRI_URGENCY_LOW < val.integer) {
- return NGHTTP2_ERR_INVALID_ARGUMENT;
-diff --git a/deps/nghttp2/lib/nghttp2_http.h b/deps/nghttp2/lib/nghttp2_http.h
-index d9992fe6..2925334c 100644
---- a/deps/nghttp2/lib/nghttp2_http.h
-+++ b/deps/nghttp2/lib/nghttp2_http.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
- #include "nghttp2_session.h"
-@@ -97,4 +97,4 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream,
- int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
- size_t valuelen);
-
--#endif /* NGHTTP2_HTTP_H */
-+#endif /* !defined(NGHTTP2_HTTP_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_int.h b/deps/nghttp2/lib/nghttp2_int.h
-index b23585cc..d89cf154 100644
---- a/deps/nghttp2/lib/nghttp2_int.h
-+++ b/deps/nghttp2/lib/nghttp2_int.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -52,7 +52,11 @@ typedef enum {
- * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
- * nghttp2_on_invalid_header_callback.
- */
-- NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
-+ NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106,
-+ /*
-+ * Cancel pushed stream.
-+ */
-+ NGHTTP2_ERR_PUSH_CANCEL = -107,
- } nghttp2_internal_error;
-
--#endif /* NGHTTP2_INT_H */
-+#endif /* !defined(NGHTTP2_INT_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_map.c b/deps/nghttp2/lib/nghttp2_map.c
-index ee6bb196..f89f3103 100644
---- a/deps/nghttp2/lib/nghttp2_map.c
-+++ b/deps/nghttp2/lib/nghttp2_map.c
-@@ -31,12 +31,13 @@
-
- #include "nghttp2_helper.h"
-
--#define NGHTTP2_INITIAL_TABLE_LENBITS 4
-+#define NGHTTP2_INITIAL_HASHBITS 4
-
--void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
-+void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem) {
- map->mem = mem;
- map->hashbits = 0;
- map->table = NULL;
-+ map->seed = seed;
- map->size = 0;
- }
-
-@@ -77,8 +78,13 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
- return 0;
- }
-
--static size_t hash(nghttp2_map_key_type key, size_t bits) {
-- return (size_t)(((uint32_t)key * 2654435769u) >> (32 - bits));
-+static size_t map_hash(const nghttp2_map *map, nghttp2_map_key_type key) {
-+ /* hasher from
-+ https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
-+ We do not perform finalization here because we use top bits
-+ anyway. */
-+ uint32_t h = ((uint32_t)key + map->seed) * 0x93d765dd;
-+ return (size_t)((h * 2654435769u) >> (32 - map->hashbits));
- }
-
- static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) {
-@@ -109,24 +115,28 @@ void nghttp2_map_print_distance(const nghttp2_map *map) {
- continue;
- }
-
-- idx = hash(bkt->key, map->hashbits);
-+ idx = map_hash(map, bkt->key);
- fprintf(stderr, "@%zu hash=%zu key=%d 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 /* !WIN32 */
--
--static int insert(nghttp2_map_bucket *table, size_t hashbits,
-- nghttp2_map_key_type key, void *data) {
-- size_t idx = hash(key, hashbits);
-- nghttp2_map_bucket b = {0, key, data}, *bkt;
-- size_t mask = (1u << hashbits) - 1;
-+#endif /* !defined(WIN32) */
-+
-+static int map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
-+ size_t idx = map_hash(map, key);
-+ nghttp2_map_bucket b = {
-+ .key = key,
-+ .data = data,
-+ };
-+ nghttp2_map_bucket *bkt;
-+ size_t mask = (1u << map->hashbits) - 1;
-
- for (;;) {
-- bkt = &table[idx];
-+ bkt = &map->table[idx];
-
- if (bkt->data == NULL) {
- *bkt = b;
-+ ++map->size;
- return 0;
- }
-
-@@ -147,15 +157,19 @@ static int insert(nghttp2_map_bucket *table, size_t hashbits,
-
- static int map_resize(nghttp2_map *map, size_t new_hashbits) {
- size_t i;
-- nghttp2_map_bucket *new_table;
- nghttp2_map_bucket *bkt;
- size_t tablelen;
- int rv;
-+ nghttp2_map new_map = {
-+ .table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
-+ sizeof(nghttp2_map_bucket)),
-+ .mem = map->mem,
-+ .seed = map->seed,
-+ .hashbits = new_hashbits,
-+ };
- (void)rv;
-
-- new_table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
-- sizeof(nghttp2_map_bucket));
-- if (new_table == NULL) {
-+ if (new_map.table == NULL) {
- return NGHTTP2_ERR_NOMEM;
- }
-
-@@ -168,15 +182,15 @@ static int map_resize(nghttp2_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);
- }
- }
-
- nghttp2_mem_free(map->mem, map->table);
-+ map->table = new_map.table;
- map->hashbits = new_hashbits;
-- map->table = new_table;
-
- return 0;
- }
-@@ -186,30 +200,28 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_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, NGHTTP2_INITIAL_TABLE_LENBITS);
-+ rv = map_resize(map, NGHTTP2_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;
- }
-
-@@ -223,7 +235,7 @@ void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
- return NULL;
- }
-
-- idx = hash(key, map->hashbits);
-+ idx = map_hash(map, key);
- mask = (1u << map->hashbits) - 1;
-
- for (;;) {
-@@ -252,7 +264,7 @@ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
- return NGHTTP2_ERR_INVALID_ARGUMENT;
- }
-
-- idx = hash(key, map->hashbits);
-+ idx = map_hash(map, key);
- mask = (1u << map->hashbits) - 1;
-
- for (;;) {
-diff --git a/deps/nghttp2/lib/nghttp2_map.h b/deps/nghttp2/lib/nghttp2_map.h
-index 5adfb78d..e45685bc 100644
---- a/deps/nghttp2/lib/nghttp2_map.h
-+++ b/deps/nghttp2/lib/nghttp2_map.h
-@@ -28,7 +28,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -47,6 +47,7 @@ typedef struct nghttp2_map_bucket {
- typedef struct nghttp2_map {
- nghttp2_map_bucket *table;
- nghttp2_mem *mem;
-+ uint32_t seed;
- size_t size;
- size_t hashbits;
- } nghttp2_map;
-@@ -54,7 +55,7 @@ typedef struct nghttp2_map {
- /*
- * nghttp2_map_init initializes the map |map|.
- */
--void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
-+void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem);
-
- /*
- * nghttp2_map_free deallocates any resources allocated for |map|.
-@@ -123,6 +124,6 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
-
- #ifndef WIN32
- void nghttp2_map_print_distance(const nghttp2_map *map);
--#endif /* !WIN32 */
-+#endif /* !defined(WIN32) */
-
--#endif /* NGHTTP2_MAP_H */
-+#endif /* !defined(NGHTTP2_MAP_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_mem.h b/deps/nghttp2/lib/nghttp2_mem.h
-index f83dbcb8..10af7c69 100644
---- a/deps/nghttp2/lib/nghttp2_mem.h
-+++ b/deps/nghttp2/lib/nghttp2_mem.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -42,4 +42,4 @@ void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
- void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
- void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
-
--#endif /* NGHTTP2_MEM_H */
-+#endif /* !defined(NGHTTP2_MEM_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_net.h b/deps/nghttp2/lib/nghttp2_net.h
-index 521f9814..0c57d947 100644
---- a/deps/nghttp2/lib/nghttp2_net.h
-+++ b/deps/nghttp2/lib/nghttp2_net.h
-@@ -27,28 +27,28 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #ifdef HAVE_ARPA_INET_H
- # include <arpa/inet.h>
--#endif /* HAVE_ARPA_INET_H */
-+#endif /* defined(HAVE_ARPA_INET_H) */
-
- #ifdef HAVE_NETINET_IN_H
- # include <netinet/in.h>
--#endif /* HAVE_NETINET_IN_H */
-+#endif /* defined(HAVE_NETINET_IN_H) */
-
- #include <nghttp2/nghttp2.h>
-
--#if defined(WIN32)
-+#ifdef WIN32
- /* Windows requires ws2_32 library for ntonl family functions. We
- define inline functions for those function so that we don't have
- dependency on that lib. */
-
- # ifdef _MSC_VER
- # define STIN static __inline
--# else
-+# else /* !defined(_MSC_VER) */
- # define STIN static inline
--# endif
-+# endif /* !defined(_MSC_VER) */
-
- STIN uint32_t htonl(uint32_t hostlong) {
- uint32_t res;
-@@ -86,6 +86,6 @@ STIN uint16_t ntohs(uint16_t netshort) {
- return res;
- }
-
--#endif /* WIN32 */
-+#endif /* defined(WIN32) */
-
--#endif /* NGHTTP2_NET_H */
-+#endif /* !defined(NGHTTP2_NET_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_option.c b/deps/nghttp2/lib/nghttp2_option.c
-index 02a24eee..7e44a241 100644
---- a/deps/nghttp2/lib/nghttp2_option.c
-+++ b/deps/nghttp2/lib/nghttp2_option.c
-@@ -155,3 +155,10 @@ void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) {
- option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
- option->max_continuations = val;
- }
-+
-+void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
-+ uint64_t burst, uint64_t rate) {
-+ option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT;
-+ option->glitch_burst = burst;
-+ option->glitch_rate = rate;
-+}
-diff --git a/deps/nghttp2/lib/nghttp2_option.h b/deps/nghttp2/lib/nghttp2_option.h
-index c89cb97f..711185ba 100644
---- a/deps/nghttp2/lib/nghttp2_option.h
-+++ b/deps/nghttp2/lib/nghttp2_option.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -72,6 +72,7 @@ typedef enum {
- NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
- NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
- NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
-+ NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17,
- } nghttp2_option_flag;
-
- /**
-@@ -83,6 +84,11 @@ struct nghttp2_option {
- */
- uint64_t stream_reset_burst;
- uint64_t stream_reset_rate;
-+ /**
-+ * NGHTTP2_OPT_GLITCH_RATE_LIMIT
-+ */
-+ uint64_t glitch_burst;
-+ uint64_t glitch_rate;
- /**
- * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
- */
-@@ -154,4 +160,4 @@ struct nghttp2_option {
- uint8_t user_recv_ext_types[32];
- };
-
--#endif /* NGHTTP2_OPTION_H */
-+#endif /* !defined(NGHTTP2_OPTION_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_outbound_item.h b/deps/nghttp2/lib/nghttp2_outbound_item.h
-index 4e917500..6e8e310c 100644
---- a/deps/nghttp2/lib/nghttp2_outbound_item.h
-+++ b/deps/nghttp2/lib/nghttp2_outbound_item.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
- #include "nghttp2_frame.h"
-@@ -186,4 +186,4 @@ void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q);
- /* Returns the size of the queue */
- #define nghttp2_outbound_queue_size(Q) ((Q)->n)
-
--#endif /* NGHTTP2_OUTBOUND_ITEM_H */
-+#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_pq.h b/deps/nghttp2/lib/nghttp2_pq.h
-index c8d90ef2..5dd863f8 100644
---- a/deps/nghttp2/lib/nghttp2_pq.h
-+++ b/deps/nghttp2/lib/nghttp2_pq.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
- #include "nghttp2_int.h"
-@@ -121,4 +121,4 @@ int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
- */
- void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
-
--#endif /* NGHTTP2_PQ_H */
-+#endif /* !defined(NGHTTP2_PQ_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_priority_spec.h b/deps/nghttp2/lib/nghttp2_priority_spec.h
-index 92ece822..158e0dcd 100644
---- a/deps/nghttp2/lib/nghttp2_priority_spec.h
-+++ b/deps/nghttp2/lib/nghttp2_priority_spec.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -39,4 +39,4 @@
- */
- void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
-
--#endif /* NGHTTP2_PRIORITY_SPEC_H */
-+#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_queue.h b/deps/nghttp2/lib/nghttp2_queue.h
-index a06fa6c7..c63897c0 100644
---- a/deps/nghttp2/lib/nghttp2_queue.h
-+++ b/deps/nghttp2/lib/nghttp2_queue.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include "config.h"
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -48,4 +48,4 @@ void *nghttp2_queue_front(nghttp2_queue *queue);
- void *nghttp2_queue_back(nghttp2_queue *queue);
- int nghttp2_queue_empty(nghttp2_queue *queue);
-
--#endif /* NGHTTP2_QUEUE_H */
-+#endif /* !defined(NGHTTP2_QUEUE_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_ratelim.h b/deps/nghttp2/lib/nghttp2_ratelim.h
-index 866ed3f0..d1097f2f 100644
---- a/deps/nghttp2/lib/nghttp2_ratelim.h
-+++ b/deps/nghttp2/lib/nghttp2_ratelim.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -54,4 +54,4 @@ void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
- succeeds, or -1. */
- int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
-
--#endif /* NGHTTP2_RATELIM_H */
-+#endif /* !defined(NGHTTP2_RATELIM_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_rcbuf.h b/deps/nghttp2/lib/nghttp2_rcbuf.h
-index 6814e709..ef82e1b3 100644
---- a/deps/nghttp2/lib/nghttp2_rcbuf.h
-+++ b/deps/nghttp2/lib/nghttp2_rcbuf.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -77,4 +77,4 @@ int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
- */
- void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
-
--#endif /* NGHTTP2_RCBUF_H */
-+#endif /* !defined(NGHTTP2_RCBUF_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c
-index df33a89e..0fbcc930 100644
---- a/deps/nghttp2/lib/nghttp2_session.c
-+++ b/deps/nghttp2/lib/nghttp2_session.c
-@@ -41,6 +41,8 @@
- #include "nghttp2_debug.h"
- #include "nghttp2_submit.h"
-
-+nghttp2_stream nghttp2_stream_root;
-+
- /*
- * Returns non-zero if the number of outgoing opened streams is larger
- * than or equal to
-@@ -146,11 +148,6 @@ static int session_detect_idle_stream(nghttp2_session *session,
- return 0;
- }
-
--static int session_no_rfc7540_pri_no_fallback(nghttp2_session *session) {
-- return session->pending_no_rfc7540_priorities == 1 &&
-- !session->fallback_rfc7540_priorities;
--}
--
- static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) {
- return (ext_types[type / 8] & (1 << (type & 0x7))) > 0;
- }
-@@ -441,6 +438,7 @@ static int session_new(nghttp2_session **session_ptr,
- size_t max_deflate_dynamic_table_size =
- NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
- size_t i;
-+ uint32_t map_seed;
-
- if (mem == NULL) {
- mem = nghttp2_mem_default();
-@@ -458,10 +456,6 @@ static int session_new(nghttp2_session **session_ptr,
- /* next_stream_id is initialized in either
- nghttp2_session_client_new2 or nghttp2_session_server_new2 */
-
-- nghttp2_stream_init(&(*session_ptr)->root, 0, NGHTTP2_STREAM_FLAG_NONE,
-- NGHTTP2_STREAM_IDLE, NGHTTP2_DEFAULT_WEIGHT, 0, 0, NULL,
-- mem);
--
- (*session_ptr)->remote_window_size = NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE;
- (*session_ptr)->recv_window_size = 0;
- (*session_ptr)->consumed_size = 0;
-@@ -481,6 +475,10 @@ static int session_new(nghttp2_session **session_ptr,
- NGHTTP2_DEFAULT_STREAM_RESET_BURST,
- NGHTTP2_DEFAULT_STREAM_RESET_RATE);
-
-+ nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
-+ NGHTTP2_DEFAULT_GLITCH_BURST,
-+ NGHTTP2_DEFAULT_GLITCH_RATE);
-+
- if (server) {
- (*session_ptr)->server = 1;
- }
-@@ -548,11 +546,6 @@ static int session_new(nghttp2_session **session_ptr,
- max_deflate_dynamic_table_size = option->max_deflate_dynamic_table_size;
- }
-
-- if ((option->opt_set_mask & NGHTTP2_OPT_NO_CLOSED_STREAMS) &&
-- option->no_closed_streams) {
-- (*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_CLOSED_STREAMS;
-- }
--
- if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
- (*session_ptr)->max_outbound_ack = option->max_outbound_ack;
- }
-@@ -562,13 +555,6 @@ static int session_new(nghttp2_session **session_ptr,
- (*session_ptr)->max_settings = option->max_settings;
- }
-
-- if ((option->opt_set_mask &
-- NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES) &&
-- option->server_fallback_rfc7540_priorities) {
-- (*session_ptr)->opt_flags |=
-- NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES;
-- }
--
- if ((option->opt_set_mask &
- NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) &&
- option->no_rfc9113_leading_and_trailing_ws_validation) {
-@@ -585,6 +571,11 @@ static int session_new(nghttp2_session **session_ptr,
- if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
- (*session_ptr)->max_continuations = option->max_continuations;
- }
-+
-+ if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) {
-+ nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
-+ option->glitch_burst, option->glitch_rate);
-+ }
- }
-
- rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
-@@ -613,7 +604,13 @@ static int session_new(nghttp2_session **session_ptr,
- goto fail_aob_framebuf;
- }
-
-- nghttp2_map_init(&(*session_ptr)->streams, mem);
-+ if (callbacks->rand_callback) {
-+ callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed));
-+ } else {
-+ map_seed = 0;
-+ }
-+
-+ nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem);
-
- active_outbound_item_reset(&(*session_ptr)->aob, mem);
-
-@@ -810,7 +807,6 @@ void nghttp2_session_del(nghttp2_session *session) {
- for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
- nghttp2_pq_free(&session->sched[i].ob_data);
- }
-- nghttp2_stream_free(&session->root);
-
- /* Have to free streams first, so that we can check
- stream->item->queued */
-@@ -829,82 +825,6 @@ void nghttp2_session_del(nghttp2_session *session) {
- nghttp2_mem_free(mem, session);
- }
-
--int nghttp2_session_reprioritize_stream(
-- nghttp2_session *session, nghttp2_stream *stream,
-- const nghttp2_priority_spec *pri_spec_in) {
-- int rv;
-- nghttp2_stream *dep_stream = NULL;
-- nghttp2_priority_spec pri_spec_default;
-- const nghttp2_priority_spec *pri_spec = pri_spec_in;
--
-- assert((!session->server && session->pending_no_rfc7540_priorities != 1) ||
-- (session->server && !session_no_rfc7540_pri_no_fallback(session)));
-- assert(pri_spec->stream_id != stream->stream_id);
--
-- if (!nghttp2_stream_in_dep_tree(stream)) {
-- return 0;
-- }
--
-- if (pri_spec->stream_id != 0) {
-- dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id);
--
-- if (!dep_stream &&
-- session_detect_idle_stream(session, pri_spec->stream_id)) {
-- nghttp2_priority_spec_default_init(&pri_spec_default);
--
-- dep_stream = nghttp2_session_open_stream(
-- session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default,
-- NGHTTP2_STREAM_IDLE, NULL);
--
-- if (dep_stream == NULL) {
-- return NGHTTP2_ERR_NOMEM;
-- }
-- } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) {
-- nghttp2_priority_spec_default_init(&pri_spec_default);
-- pri_spec = &pri_spec_default;
-- }
-- }
--
-- if (pri_spec->stream_id == 0) {
-- dep_stream = &session->root;
-- } else if (nghttp2_stream_dep_find_ancestor(dep_stream, stream)) {
-- DEBUGF("stream: cycle detected, dep_stream(%p)=%d stream(%p)=%d\n",
-- dep_stream, dep_stream->stream_id, stream, stream->stream_id);
--
-- nghttp2_stream_dep_remove_subtree(dep_stream);
-- rv = nghttp2_stream_dep_add_subtree(stream->dep_prev, dep_stream);
-- if (rv != 0) {
-- return rv;
-- }
-- }
--
-- assert(dep_stream);
--
-- if (dep_stream == stream->dep_prev && !pri_spec->exclusive) {
-- /* This is minor optimization when just weight is changed. */
-- nghttp2_stream_change_weight(stream, pri_spec->weight);
--
-- return 0;
-- }
--
-- nghttp2_stream_dep_remove_subtree(stream);
--
-- /* We have to update weight after removing stream from tree */
-- stream->weight = pri_spec->weight;
--
-- if (pri_spec->exclusive) {
-- rv = nghttp2_stream_dep_insert_subtree(dep_stream, stream);
-- } else {
-- rv = nghttp2_stream_dep_add_subtree(dep_stream, stream);
-- }
--
-- if (rv != 0) {
-- return rv;
-- }
--
-- return 0;
--}
--
- static uint64_t pq_get_first_cycle(nghttp2_pq *pq) {
- nghttp2_stream *stream;
-
-@@ -923,7 +843,6 @@ static int session_ob_data_push(nghttp2_session *session,
- int inc;
- nghttp2_pq *pq;
-
-- assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES);
- assert(stream->queued == 0);
-
- urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
-@@ -952,7 +871,6 @@ static void session_ob_data_remove(nghttp2_session *session,
- nghttp2_stream *stream) {
- uint32_t urgency;
-
-- assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES);
- assert(stream->queued == 1);
-
- urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
-@@ -969,14 +887,7 @@ static int session_attach_stream_item(nghttp2_session *session,
- nghttp2_outbound_item *item) {
- int rv;
-
-- rv = nghttp2_stream_attach_item(stream, item);
-- if (rv != 0) {
-- return rv;
-- }
--
-- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
-- return 0;
-- }
-+ nghttp2_stream_attach_item(stream, item);
-
- rv = session_ob_data_push(session, stream);
- if (rv != 0) {
-@@ -992,8 +903,7 @@ static void session_detach_stream_item(nghttp2_session *session,
- nghttp2_stream *stream) {
- nghttp2_stream_detach_item(stream);
-
-- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-- !stream->queued) {
-+ if (!stream->queued) {
- return;
- }
-
-@@ -1004,8 +914,7 @@ static void session_defer_stream_item(nghttp2_session *session,
- nghttp2_stream *stream, uint8_t flags) {
- nghttp2_stream_defer_item(stream, flags);
-
-- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-- !stream->queued) {
-+ if (!stream->queued) {
- return;
- }
-
-@@ -1015,15 +924,9 @@ static void session_defer_stream_item(nghttp2_session *session,
- static int session_resume_deferred_stream_item(nghttp2_session *session,
- nghttp2_stream *stream,
- uint8_t flags) {
-- int rv;
-+ nghttp2_stream_resume_deferred_item(stream, flags);
-
-- rv = nghttp2_stream_resume_deferred_item(stream, flags);
-- if (rv != 0) {
-- return rv;
-- }
--
-- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-- (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL)) {
-+ if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) {
- return 0;
- }
-
-@@ -1168,7 +1071,6 @@ int nghttp2_session_add_item(nghttp2_session *session,
- return 0;
- case NGHTTP2_PUSH_PROMISE: {
- nghttp2_headers_aux_data *aux_data;
-- nghttp2_priority_spec pri_spec;
-
- aux_data = &item->aux_data.headers;
-
-@@ -1176,20 +1078,13 @@ int nghttp2_session_add_item(nghttp2_session *session,
- return NGHTTP2_ERR_STREAM_CLOSED;
- }
-
-- nghttp2_priority_spec_init(&pri_spec, stream->stream_id,
-- NGHTTP2_DEFAULT_WEIGHT, 0);
--
- if (!nghttp2_session_open_stream(
- session, frame->push_promise.promised_stream_id,
-- NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_RESERVED,
-+ NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_RESERVED,
- aux_data->stream_user_data)) {
- return NGHTTP2_ERR_NOMEM;
- }
-
-- /* We don't have to call nghttp2_session_adjust_closed_stream()
-- here, since stream->stream_id is local stream_id, and it does
-- not affect closed stream count. */
--
- nghttp2_outbound_queue_push(&session->ob_reg, item);
- item->queued = 1;
-
-@@ -1213,6 +1108,15 @@ int nghttp2_session_add_item(nghttp2_session *session,
-
- int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
- uint32_t error_code) {
-+ return nghttp2_session_add_rst_stream_continue(
-+ session, stream_id, error_code,
-+ /* continue_without_stream = */ 1);
-+}
-+
-+int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
-+ int32_t stream_id,
-+ uint32_t error_code,
-+ int continue_without_stream) {
- int rv;
- nghttp2_outbound_item *item;
- nghttp2_frame *frame;
-@@ -1269,6 +1173,12 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
- }
- }
-
-+ /* To keep the old behaviour, do not fail if stream was not
-+ found. */
-+ if (!continue_without_stream && !stream) {
-+ return 0;
-+ }
-+
- item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
- if (item == NULL) {
- return NGHTTP2_ERR_NOMEM;
-@@ -1290,15 +1200,11 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
-
- nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- int32_t stream_id, uint8_t flags,
-- nghttp2_priority_spec *pri_spec_in,
- nghttp2_stream_state initial_state,
- void *stream_user_data) {
- int rv;
- nghttp2_stream *stream;
-- nghttp2_stream *dep_stream = NULL;
- int stream_alloc = 0;
-- nghttp2_priority_spec pri_spec_default;
-- nghttp2_priority_spec *pri_spec = pri_spec_in;
- nghttp2_mem *mem;
-
- mem = &session->mem;
-@@ -1311,23 +1217,9 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
-
- if (stream) {
- assert(stream->state == NGHTTP2_STREAM_IDLE);
-- assert((stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-- nghttp2_stream_in_dep_tree(stream));
--
-- nghttp2_session_detach_idle_stream(session, stream);
--
-- if (nghttp2_stream_in_dep_tree(stream)) {
-- assert(!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES));
-+ assert(initial_state != NGHTTP2_STREAM_IDLE);
-
-- rv = nghttp2_stream_dep_remove(stream);
-- if (rv != 0) {
-- return NULL;
-- }
--
-- if (session_no_rfc7540_pri_no_fallback(session)) {
-- stream->flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES;
-- }
-- }
-+ --session->num_idle_streams;
- } else {
- stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream));
- if (stream == NULL) {
-@@ -1337,69 +1229,16 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- stream_alloc = 1;
- }
-
-- if (session_no_rfc7540_pri_no_fallback(session) ||
-- session->remote_settings.no_rfc7540_priorities == 1) {
-- /* For client which has not received server
-- SETTINGS_NO_RFC7540_PRIORITIES = 1, send a priority signal
-- opportunistically. */
-- if (session->server ||
-- session->remote_settings.no_rfc7540_priorities == 1) {
-- nghttp2_priority_spec_default_init(&pri_spec_default);
-- pri_spec = &pri_spec_default;
-- }
--
-- if (session->pending_no_rfc7540_priorities == 1) {
-- flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES;
-- }
-- } else if (pri_spec->stream_id != 0) {
-- dep_stream = nghttp2_session_get_stream_raw(session, pri_spec->stream_id);
--
-- if (!dep_stream &&
-- session_detect_idle_stream(session, pri_spec->stream_id)) {
-- /* Depends on idle stream, which does not exist in memory.
-- Assign default priority for it. */
-- nghttp2_priority_spec_default_init(&pri_spec_default);
--
-- dep_stream = nghttp2_session_open_stream(
-- session, pri_spec->stream_id, NGHTTP2_FLAG_NONE, &pri_spec_default,
-- NGHTTP2_STREAM_IDLE, NULL);
--
-- if (dep_stream == NULL) {
-- if (stream_alloc) {
-- nghttp2_mem_free(mem, stream);
-- }
--
-- return NULL;
-- }
-- } else if (!dep_stream || !nghttp2_stream_in_dep_tree(dep_stream)) {
-- /* If dep_stream is not part of dependency tree, stream will get
-- default priority. This handles the case when
-- pri_spec->stream_id == stream_id. This happens because we
-- don't check pri_spec->stream_id against new stream ID in
-- nghttp2_submit_request. This also handles the case when idle
-- stream created by PRIORITY frame was opened. Somehow we
-- first remove the idle stream from dependency tree. This is
-- done to simplify code base, but ideally we should retain old
-- dependency. But I'm not sure this adds values. */
-- nghttp2_priority_spec_default_init(&pri_spec_default);
-- pri_spec = &pri_spec_default;
-- }
-- }
--
- if (initial_state == NGHTTP2_STREAM_RESERVED) {
- flags |= NGHTTP2_STREAM_FLAG_PUSH;
- }
-
- if (stream_alloc) {
- nghttp2_stream_init(stream, stream_id, flags, initial_state,
-- pri_spec->weight,
- (int32_t)session->remote_settings.initial_window_size,
- (int32_t)session->local_settings.initial_window_size,
-- stream_user_data, mem);
--
-- if (session_no_rfc7540_pri_no_fallback(session)) {
-- stream->seq = session->stream_seq++;
-- }
-+ stream_user_data);
-+ stream->seq = session->stream_seq++;
-
- rv = nghttp2_map_insert(&session->streams, stream_id, stream);
- if (rv != 0) {
-@@ -1410,7 +1249,6 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- } else {
- stream->flags = flags;
- stream->state = initial_state;
-- stream->weight = pri_spec->weight;
- stream->stream_user_data = stream_user_data;
- }
-
-@@ -1428,9 +1266,7 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- limit. That is one of the DOS vector. */
- break;
- case NGHTTP2_STREAM_IDLE:
-- /* Idle stream does not count toward the concurrent streams limit.
-- This is used as anchor node in dependency tree. */
-- nghttp2_session_keep_idle_stream(session, stream);
-+ ++session->num_idle_streams;
- break;
- default:
- if (nghttp2_session_is_my_stream_id(session, stream_id)) {
-@@ -1440,31 +1276,11 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- }
- }
-
-- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-- return stream;
-- }
--
-- if (pri_spec->stream_id == 0) {
-- dep_stream = &session->root;
-- }
--
-- assert(dep_stream);
--
-- if (pri_spec->exclusive) {
-- rv = nghttp2_stream_dep_insert(dep_stream, stream);
-- if (rv != 0) {
-- return NULL;
-- }
-- } else {
-- nghttp2_stream_dep_add(dep_stream, stream);
-- }
--
- return stream;
- }
-
- int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
- uint32_t error_code) {
-- int rv;
- nghttp2_stream *stream;
- nghttp2_mem *mem;
- int is_my_stream_id;
-@@ -1528,207 +1344,26 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
- /* Closes both directions just in case they are not closed yet */
- stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED;
-
-- if (session->pending_no_rfc7540_priorities == 1) {
-- return nghttp2_session_destroy_stream(session, stream);
-- }
--
-- if ((session->opt_flags & NGHTTP2_OPTMASK_NO_CLOSED_STREAMS) == 0 &&
-- session->server && !is_my_stream_id &&
-- nghttp2_stream_in_dep_tree(stream)) {
-- /* On server side, retain stream at most MAX_CONCURRENT_STREAMS
-- combined with the current active incoming streams to make
-- dependency tree work better. */
-- nghttp2_session_keep_closed_stream(session, stream);
-- } else {
-- rv = nghttp2_session_destroy_stream(session, stream);
-- if (rv != 0) {
-- return rv;
-- }
-- }
-+ nghttp2_session_destroy_stream(session, stream);
-
- return 0;
- }
-
--int nghttp2_session_destroy_stream(nghttp2_session *session,
-- nghttp2_stream *stream) {
-+void nghttp2_session_destroy_stream(nghttp2_session *session,
-+ nghttp2_stream *stream) {
- nghttp2_mem *mem;
-- int rv;
-
- DEBUGF("stream: destroy closed stream(%p)=%d\n", stream, stream->stream_id);
-
- mem = &session->mem;
-
-- if (nghttp2_stream_in_dep_tree(stream)) {
-- rv = nghttp2_stream_dep_remove(stream);
-- if (rv != 0) {
-- return rv;
-- }
-- }
--
-- if (stream->queued &&
-- (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
-+ if (stream->queued) {
- session_ob_data_remove(session, stream);
- }
-
- nghttp2_map_remove(&session->streams, stream->stream_id);
- nghttp2_stream_free(stream);
- nghttp2_mem_free(mem, stream);
--
-- return 0;
--}
--
--void nghttp2_session_keep_closed_stream(nghttp2_session *session,
-- nghttp2_stream *stream) {
-- DEBUGF("stream: keep closed stream(%p)=%d, state=%d\n", stream,
-- stream->stream_id, stream->state);
--
-- if (session->closed_stream_tail) {
-- session->closed_stream_tail->closed_next = stream;
-- stream->closed_prev = session->closed_stream_tail;
-- } else {
-- session->closed_stream_head = stream;
-- }
-- session->closed_stream_tail = stream;
--
-- ++session->num_closed_streams;
--}
--
--void nghttp2_session_keep_idle_stream(nghttp2_session *session,
-- nghttp2_stream *stream) {
-- DEBUGF("stream: keep idle stream(%p)=%d, state=%d\n", stream,
-- stream->stream_id, stream->state);
--
-- if (session->idle_stream_tail) {
-- session->idle_stream_tail->closed_next = stream;
-- stream->closed_prev = session->idle_stream_tail;
-- } else {
-- session->idle_stream_head = stream;
-- }
-- session->idle_stream_tail = stream;
--
-- ++session->num_idle_streams;
--}
--
--void nghttp2_session_detach_idle_stream(nghttp2_session *session,
-- nghttp2_stream *stream) {
-- nghttp2_stream *prev_stream, *next_stream;
--
-- DEBUGF("stream: detach idle stream(%p)=%d, state=%d\n", stream,
-- stream->stream_id, stream->state);
--
-- prev_stream = stream->closed_prev;
-- next_stream = stream->closed_next;
--
-- if (prev_stream) {
-- prev_stream->closed_next = next_stream;
-- } else {
-- session->idle_stream_head = next_stream;
-- }
--
-- if (next_stream) {
-- next_stream->closed_prev = prev_stream;
-- } else {
-- session->idle_stream_tail = prev_stream;
-- }
--
-- stream->closed_prev = NULL;
-- stream->closed_next = NULL;
--
-- --session->num_idle_streams;
--}
--
--int nghttp2_session_adjust_closed_stream(nghttp2_session *session) {
-- size_t num_stream_max;
-- int rv;
--
-- if (session->local_settings.max_concurrent_streams ==
-- NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS) {
-- num_stream_max = session->pending_local_max_concurrent_stream;
-- } else {
-- num_stream_max = session->local_settings.max_concurrent_streams;
-- }
--
-- DEBUGF("stream: adjusting kept closed streams num_closed_streams=%zu, "
-- "num_incoming_streams=%zu, max_concurrent_streams=%zu\n",
-- session->num_closed_streams, session->num_incoming_streams,
-- num_stream_max);
--
-- while (session->num_closed_streams > 0 &&
-- session->num_closed_streams + session->num_incoming_streams >
-- num_stream_max) {
-- nghttp2_stream *head_stream;
-- nghttp2_stream *next;
--
-- head_stream = session->closed_stream_head;
--
-- assert(head_stream);
--
-- next = head_stream->closed_next;
--
-- rv = nghttp2_session_destroy_stream(session, head_stream);
-- if (rv != 0) {
-- return rv;
-- }
--
-- /* head_stream is now freed */
--
-- session->closed_stream_head = next;
--
-- if (session->closed_stream_head) {
-- session->closed_stream_head->closed_prev = NULL;
-- } else {
-- session->closed_stream_tail = NULL;
-- }
--
-- --session->num_closed_streams;
-- }
--
-- return 0;
--}
--
--int nghttp2_session_adjust_idle_stream(nghttp2_session *session) {
-- size_t max;
-- int rv;
--
-- /* Make minimum number of idle streams 16, and maximum 100, which
-- are arbitrary chosen numbers. */
-- max = nghttp2_min_uint32(
-- 100,
-- nghttp2_max_uint32(
-- 16, nghttp2_min_uint32(session->local_settings.max_concurrent_streams,
-- session->pending_local_max_concurrent_stream)));
--
-- DEBUGF("stream: adjusting kept idle streams num_idle_streams=%zu, max=%zu\n",
-- session->num_idle_streams, max);
--
-- while (session->num_idle_streams > max) {
-- nghttp2_stream *head;
-- nghttp2_stream *next;
--
-- head = session->idle_stream_head;
-- assert(head);
--
-- next = head->closed_next;
--
-- rv = nghttp2_session_destroy_stream(session, head);
-- if (rv != 0) {
-- return rv;
-- }
--
-- /* head is now destroyed */
--
-- session->idle_stream_head = next;
--
-- if (session->idle_stream_head) {
-- session->idle_stream_head->closed_prev = NULL;
-- } else {
-- session->idle_stream_tail = NULL;
-- }
--
-- --session->num_idle_streams;
-- }
--
-- return 0;
- }
-
- /*
-@@ -2411,16 +2046,12 @@ static int session_prep_frame(nghttp2_session *session,
-
- stream = nghttp2_session_open_stream(
- session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
-- &frame->headers.pri_spec, NGHTTP2_STREAM_INITIAL,
-- aux_data->stream_user_data);
-+ NGHTTP2_STREAM_INITIAL, aux_data->stream_user_data);
-
- if (stream == NULL) {
- return NGHTTP2_ERR_NOMEM;
- }
-
-- /* We don't call nghttp2_session_adjust_closed_stream() here,
-- since we don't keep closed stream in client side */
--
- rv = session_predicate_request_headers_send(session, item);
- if (rv != 0) {
- return rv;
-@@ -2662,8 +2293,6 @@ static int session_prep_frame(nghttp2_session *session,
-
- nghttp2_outbound_item *
- nghttp2_session_get_next_ob_item(nghttp2_session *session) {
-- nghttp2_outbound_item *item;
--
- if (nghttp2_outbound_queue_top(&session->ob_urgent)) {
- return nghttp2_outbound_queue_top(&session->ob_urgent);
- }
-@@ -2679,11 +2308,6 @@ nghttp2_session_get_next_ob_item(nghttp2_session *session) {
- }
-
- if (session->remote_window_size > 0) {
-- item = nghttp2_stream_next_outbound_item(&session->root);
-- if (item) {
-- return item;
-- }
--
- return session_sched_get_next_outbound_item(session);
- }
-
-@@ -2718,11 +2342,6 @@ nghttp2_session_pop_next_ob_item(nghttp2_session *session) {
- }
-
- if (session->remote_window_size > 0) {
-- item = nghttp2_stream_next_outbound_item(&session->root);
-- if (item) {
-- return item;
-- }
--
- return session_sched_get_next_outbound_item(session);
- }
-
-@@ -2781,7 +2400,6 @@ static int find_stream_on_goaway_func(void *entry, void *ptr) {
- nghttp2_session_close_stream() inside nghttp2_map_each().
- Reuse closed_next member.. bad choice? */
- assert(stream->closed_next == NULL);
-- assert(stream->closed_prev == NULL);
-
- if (arg->head) {
- stream->closed_next = arg->head;
-@@ -2837,11 +2455,6 @@ static void session_reschedule_stream(nghttp2_session *session,
- nghttp2_stream *stream) {
- stream->last_writelen = stream->item->frame.hd.length;
-
-- if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
-- nghttp2_stream_reschedule(stream);
-- return;
-- }
--
- if (!session->server) {
- return;
- }
-@@ -3020,37 +2633,6 @@ static int session_after_frame_sent1(nghttp2_session *session) {
- }
- }
- case NGHTTP2_PRIORITY:
-- if (session->server || session->pending_no_rfc7540_priorities == 1) {
-- return 0;
-- }
--
-- stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
--
-- if (!stream) {
-- if (!session_detect_idle_stream(session, frame->hd.stream_id)) {
-- return 0;
-- }
--
-- stream = nghttp2_session_open_stream(
-- session, frame->hd.stream_id, NGHTTP2_FLAG_NONE,
-- &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL);
-- if (!stream) {
-- return NGHTTP2_ERR_NOMEM;
-- }
-- } else {
-- rv = nghttp2_session_reprioritize_stream(session, stream,
-- &frame->priority.pri_spec);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
-- }
--
-- rv = nghttp2_session_adjust_idle_stream(session);
--
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
- return 0;
- case NGHTTP2_RST_STREAM:
- rv = nghttp2_session_close_stream(session, frame->hd.stream_id,
-@@ -3239,14 +2821,6 @@ static nghttp2_ssize nghttp2_session_mem_send_internal(nghttp2_session *session,
- aob = &session->aob;
- framebufs = &aob->framebufs;
-
-- /* We may have idle streams more than we expect (e.g.,
-- nghttp2_session_change_stream_priority() or
-- nghttp2_session_create_idle_stream()). Adjust them here. */
-- rv = nghttp2_session_adjust_idle_stream(session);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
- for (;;) {
- switch (aob->state) {
- case NGHTTP2_OB_POP_ITEM: {
-@@ -3698,7 +3272,9 @@ static int session_call_on_invalid_header(nghttp2_session *session,
- session, frame, nv->name->base, nv->name->len, nv->value->base,
- nv->value->len, nv->flags, session->user_data);
- } else {
-- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-+ /* If both callbacks are not set, the invalid field nv is
-+ ignored. */
-+ return 0;
- }
-
- if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-@@ -3783,6 +3359,10 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) {
- case NGHTTP2_ERR_HTTP_HEADER:
- case NGHTTP2_ERR_HTTP_MESSAGING:
- return NGHTTP2_PROTOCOL_ERROR;
-+ case NGHTTP2_ERR_INTERNAL:
-+ return NGHTTP2_INTERNAL_ERROR;
-+ case NGHTTP2_ERR_PUSH_CANCEL:
-+ return NGHTTP2_CANCEL;
- default:
- return NGHTTP2_INTERNAL_ERROR;
- }
-@@ -3809,17 +3389,32 @@ static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session,
- return 0;
- }
-
-+static int session_update_glitch_ratelim(nghttp2_session *session) {
-+ if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
-+ return 0;
-+ }
-+
-+ nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec());
-+
-+ if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) {
-+ return 0;
-+ }
-+
-+ return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM);
-+}
-+
- static int session_handle_invalid_stream2(nghttp2_session *session,
- int32_t stream_id,
- nghttp2_frame *frame,
- int lib_error_code) {
- int rv;
-+
- rv = nghttp2_session_add_rst_stream(
- session, stream_id, get_error_code_from_lib_error_code(lib_error_code));
- if (rv != 0) {
- return rv;
- }
-- if (session->callbacks.on_invalid_frame_recv_callback) {
-+ if (frame && session->callbacks.on_invalid_frame_recv_callback) {
- if (session->callbacks.on_invalid_frame_recv_callback(
- session, frame, lib_error_code, session->user_data) != 0) {
- return NGHTTP2_ERR_CALLBACK_FAILURE;
-@@ -3974,7 +3569,29 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
-
- rv2 = session_call_on_invalid_header(session, frame, &nv);
- if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-- rv = NGHTTP2_ERR_HTTP_HEADER;
-+ DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n",
-+ frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
-+ nv.name->base, (int)nv.value->len, nv.value->base);
-+
-+ rv = session_call_error_callback(
-+ session, NGHTTP2_ERR_HTTP_HEADER,
-+ "Invalid HTTP header field was received: frame type: "
-+ "%u, stream: %d, name: [%.*s], value: [%.*s]",
-+ frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
-+ nv.name->base, (int)nv.value->len, nv.value->base);
-+
-+ if (nghttp2_is_fatal(rv)) {
-+ return rv;
-+ }
-+
-+ rv = session_handle_invalid_stream2(
-+ session, subject_stream->stream_id, frame,
-+ NGHTTP2_ERR_HTTP_HEADER);
-+ if (nghttp2_is_fatal(rv)) {
-+ return rv;
-+ }
-+
-+ return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
- } else {
- if (rv2 != 0) {
- return rv2;
-@@ -4014,13 +3631,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
- return rv;
- }
-
-- rv =
-- session_handle_invalid_stream2(session, subject_stream->stream_id,
-- frame, NGHTTP2_ERR_HTTP_HEADER);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
-- return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
-+ return nghttp2_session_terminate_session(session,
-+ NGHTTP2_PROTOCOL_ERROR);
- }
- }
- if (rv == 0) {
-@@ -4064,7 +3676,6 @@ static int session_end_stream_headers_received(nghttp2_session *session,
-
- if (session->server && session_enforce_http_messaging(session) &&
- frame->headers.cat == NGHTTP2_HCAT_REQUEST &&
-- (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
- !(stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) &&
- (stream->http_flags & NGHTTP2_HTTP_FLAG_PRIORITY)) {
- rv = session_update_stream_priority(session, stream, stream->http_extpri);
-@@ -4134,27 +3745,7 @@ static int session_after_header_block_received(nghttp2_session *session) {
- }
- }
- if (rv != 0) {
-- int32_t stream_id;
--
-- if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
-- stream_id = frame->push_promise.promised_stream_id;
-- } else {
-- stream_id = frame->hd.stream_id;
-- }
--
-- rv = session_handle_invalid_stream2(session, stream_id, frame,
-- NGHTTP2_ERR_HTTP_MESSAGING);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
-- if (frame->hd.type == NGHTTP2_HEADERS &&
-- (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
-- nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
-- /* Don't call nghttp2_session_close_stream_if_shut_rdwr
-- because RST_STREAM has been submitted. */
-- }
-- return 0;
-+ return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
- }
- }
-
-@@ -4253,18 +3844,13 @@ int nghttp2_session_on_request_headers_received(nghttp2_session *session,
- NGHTTP2_ERR_REFUSED_STREAM);
- }
-
-- stream = nghttp2_session_open_stream(
-- session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
-- &frame->headers.pri_spec, NGHTTP2_STREAM_OPENING, NULL);
-+ stream = nghttp2_session_open_stream(session, frame->hd.stream_id,
-+ NGHTTP2_STREAM_FLAG_NONE,
-+ NGHTTP2_STREAM_OPENING, NULL);
- if (!stream) {
- return NGHTTP2_ERR_NOMEM;
- }
-
-- rv = nghttp2_session_adjust_closed_stream(session);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
- session->last_proc_stream_id = session->last_recv_stream_id;
-
- rv = session_call_on_begin_headers(session, frame);
-@@ -4396,104 +3982,33 @@ int nghttp2_session_on_headers_received(nghttp2_session *session,
- return NGHTTP2_ERR_IGN_HEADER_BLOCK;
- }
-
--static int session_process_headers_frame(nghttp2_session *session) {
-- nghttp2_inbound_frame *iframe = &session->iframe;
-- nghttp2_frame *frame = &iframe->frame;
-- nghttp2_stream *stream;
--
-- nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos);
--
-- stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
-- if (!stream) {
-- frame->headers.cat = NGHTTP2_HCAT_REQUEST;
-- return nghttp2_session_on_request_headers_received(session, frame);
-- }
--
-- if (stream->state == NGHTTP2_STREAM_RESERVED) {
-- frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE;
-- return nghttp2_session_on_push_response_headers_received(session, frame,
-- stream);
-- }
--
-- if (stream->state == NGHTTP2_STREAM_OPENING &&
-- nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
-- frame->headers.cat = NGHTTP2_HCAT_RESPONSE;
-- return nghttp2_session_on_response_headers_received(session, frame, stream);
-- }
--
-- frame->headers.cat = NGHTTP2_HCAT_HEADERS;
-- return nghttp2_session_on_headers_received(session, frame, stream);
--}
--
--int nghttp2_session_on_priority_received(nghttp2_session *session,
-- nghttp2_frame *frame) {
-- int rv;
-- nghttp2_stream *stream;
--
-- assert(!session_no_rfc7540_pri_no_fallback(session));
--
-- if (frame->hd.stream_id == 0) {
-- return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
-- "PRIORITY: stream_id == 0");
-- }
--
-- if (frame->priority.pri_spec.stream_id == frame->hd.stream_id) {
-- return nghttp2_session_terminate_session_with_reason(
-- session, NGHTTP2_PROTOCOL_ERROR, "depend on itself");
-- }
--
-- if (!session->server) {
-- /* Re-prioritization works only in server */
-- return session_call_on_frame_received(session, frame);
-- }
--
-- stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
--
-- if (!stream) {
-- /* PRIORITY against idle stream can create anchor node in
-- dependency tree. */
-- if (!session_detect_idle_stream(session, frame->hd.stream_id)) {
-- return 0;
-- }
--
-- stream = nghttp2_session_open_stream(
-- session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
-- &frame->priority.pri_spec, NGHTTP2_STREAM_IDLE, NULL);
--
-- if (stream == NULL) {
-- return NGHTTP2_ERR_NOMEM;
-- }
--
-- rv = nghttp2_session_adjust_idle_stream(session);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
-- } else {
-- rv = nghttp2_session_reprioritize_stream(session, stream,
-- &frame->priority.pri_spec);
--
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
-- rv = nghttp2_session_adjust_idle_stream(session);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
-- }
--
-- return session_call_on_frame_received(session, frame);
--}
--
--static int session_process_priority_frame(nghttp2_session *session) {
-+static int session_process_headers_frame(nghttp2_session *session) {
- nghttp2_inbound_frame *iframe = &session->iframe;
- nghttp2_frame *frame = &iframe->frame;
-+ nghttp2_stream *stream;
-+
-+ nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos);
-+
-+ stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
-+ if (!stream) {
-+ frame->headers.cat = NGHTTP2_HCAT_REQUEST;
-+ return nghttp2_session_on_request_headers_received(session, frame);
-+ }
-
-- assert(!session_no_rfc7540_pri_no_fallback(session));
-+ if (stream->state == NGHTTP2_STREAM_RESERVED) {
-+ frame->headers.cat = NGHTTP2_HCAT_PUSH_RESPONSE;
-+ return nghttp2_session_on_push_response_headers_received(session, frame,
-+ stream);
-+ }
-
-- nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos);
-+ if (stream->state == NGHTTP2_STREAM_OPENING &&
-+ nghttp2_session_is_my_stream_id(session, frame->hd.stream_id)) {
-+ frame->headers.cat = NGHTTP2_HCAT_RESPONSE;
-+ return nghttp2_session_on_response_headers_received(session, frame, stream);
-+ }
-
-- return nghttp2_session_on_priority_received(session, frame);
-+ frame->headers.cat = NGHTTP2_HCAT_HEADERS;
-+ return nghttp2_session_on_headers_received(session, frame, stream);
- }
-
- static int session_update_stream_reset_ratelim(nghttp2_session *session) {
-@@ -4566,8 +4081,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
- rv = nghttp2_stream_update_remote_initial_window_size(
- stream, arg->new_window_size, arg->old_window_size);
- if (rv != 0) {
-- return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
-- NGHTTP2_FLOW_CONTROL_ERROR);
-+ return NGHTTP2_ERR_FLOW_CONTROL;
- }
-
- /* If window size gets positive, push deferred DATA frame to
-@@ -4593,6 +4107,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
- *
- * NGHTTP2_ERR_NOMEM
- * Out of memory.
-+ * NGHTTP2_ERR_FLOW_CONTROL
-+ * Window size gets out of range.
- */
- static int
- session_update_remote_initial_window_size(nghttp2_session *session,
-@@ -4616,8 +4132,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
- rv = nghttp2_stream_update_local_initial_window_size(
- stream, arg->new_window_size, arg->old_window_size);
- if (rv != 0) {
-- return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
-- NGHTTP2_FLOW_CONTROL_ERROR);
-+ return NGHTTP2_ERR_FLOW_CONTROL;
- }
-
- if (stream->window_update_queued) {
-@@ -4651,6 +4166,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
- *
- * NGHTTP2_ERR_NOMEM
- * Out of memory.
-+ * NGHTTP2_ERR_FLOW_CONTROL
-+ * Window size gets out of range.
- */
- static int
- session_update_local_initial_window_size(nghttp2_session *session,
-@@ -4934,12 +4451,6 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
-
- if (session->remote_settings.no_rfc7540_priorities == UINT32_MAX) {
- session->remote_settings.no_rfc7540_priorities = 0;
--
-- if (session->server && session->pending_no_rfc7540_priorities &&
-- (session->opt_flags &
-- NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES)) {
-- session->fallback_rfc7540_priorities = 1;
-- }
- }
-
- if (!noack && !session_is_closing(session)) {
-@@ -5000,7 +4511,6 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
- int rv;
- nghttp2_stream *stream;
- nghttp2_stream *promised_stream;
-- nghttp2_priority_spec pri_spec;
-
- if (frame->hd.stream_id == 0) {
- return session_inflate_handle_invalid_connection(
-@@ -5044,9 +4554,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
- session->max_incoming_reserved_streams) {
- /* Currently, client does not retain closed stream, so we don't
- check NGHTTP2_SHUT_RD condition here. */
--
-- rv = nghttp2_session_add_rst_stream(
-- session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL);
-+ rv = session_handle_invalid_stream2(session,
-+ frame->push_promise.promised_stream_id,
-+ NULL, NGHTTP2_ERR_PUSH_CANCEL);
- if (rv != 0) {
- return rv;
- }
-@@ -5058,20 +4568,14 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
- session, frame, NGHTTP2_ERR_STREAM_CLOSED, "PUSH_PROMISE: stream closed");
- }
-
-- nghttp2_priority_spec_init(&pri_spec, stream->stream_id,
-- NGHTTP2_DEFAULT_WEIGHT, 0);
--
- promised_stream = nghttp2_session_open_stream(
- session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE,
-- &pri_spec, NGHTTP2_STREAM_RESERVED, NULL);
-+ NGHTTP2_STREAM_RESERVED, NULL);
-
- if (!promised_stream) {
- return NGHTTP2_ERR_NOMEM;
- }
-
-- /* We don't call nghttp2_session_adjust_closed_stream(), since we
-- don't keep closed stream in client side */
--
- session->last_proc_stream_id = session->last_recv_stream_id;
- rv = session_call_on_begin_headers(session, frame);
- if (rv != 0) {
-@@ -5209,8 +4713,9 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
- }
- if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
- stream->remote_window_size) {
-- return session_handle_invalid_stream(session, frame,
-- NGHTTP2_ERR_FLOW_CONTROL);
-+ return session_handle_invalid_connection(
-+ session, frame, NGHTTP2_ERR_FLOW_CONTROL,
-+ "WINDOW_UPDATE: window size overflow");
- }
- stream->remote_window_size += frame->window_update.window_size_increment;
-
-@@ -5292,7 +4797,6 @@ int nghttp2_session_on_priority_update_received(nghttp2_session *session,
- nghttp2_frame *frame) {
- nghttp2_ext_priority_update *priority_update;
- nghttp2_stream *stream;
-- nghttp2_priority_spec pri_spec;
- nghttp2_extpri extpri;
- int rv;
-
-@@ -5330,10 +4834,9 @@ int nghttp2_session_on_priority_update_received(nghttp2_session *session,
- "PRIORITY_UPDATE: max concurrent streams exceeded");
- }
-
-- nghttp2_priority_spec_default_init(&pri_spec);
-- stream = nghttp2_session_open_stream(session, priority_update->stream_id,
-- NGHTTP2_FLAG_NONE, &pri_spec,
-- NGHTTP2_STREAM_IDLE, NULL);
-+ stream =
-+ nghttp2_session_open_stream(session, priority_update->stream_id,
-+ NGHTTP2_FLAG_NONE, NGHTTP2_STREAM_IDLE, NULL);
- if (!stream) {
- return NGHTTP2_ERR_NOMEM;
- }
-@@ -5442,16 +4945,7 @@ int nghttp2_session_on_data_received(nghttp2_session *session,
- if (session_enforce_http_messaging(session) &&
- (frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
- if (nghttp2_http_on_remote_end_stream(stream) != 0) {
-- rv = nghttp2_session_add_rst_stream(session, stream->stream_id,
-- NGHTTP2_PROTOCOL_ERROR);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
-- nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
-- /* Don't call nghttp2_session_close_stream_if_shut_rdwr because
-- RST_STREAM has been submitted. */
-- return 0;
-+ return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
- }
- }
-
-@@ -5509,8 +5003,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
- rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
- stream->local_window_size);
- if (rv != 0) {
-- return nghttp2_session_add_rst_stream(session, stream->stream_id,
-- NGHTTP2_FLOW_CONTROL_ERROR);
-+ return nghttp2_session_terminate_session(session,
-+ NGHTTP2_FLOW_CONTROL_ERROR);
- }
- /* We don't have to send WINDOW_UPDATE if the data received is the
- last chunk in the incoming stream. */
-@@ -5869,14 +5363,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
-
- mem = &session->mem;
-
-- /* We may have idle streams more than we expect (e.g.,
-- nghttp2_session_change_stream_priority() or
-- nghttp2_session_create_idle_stream()). Adjust them here. */
-- rv = nghttp2_session_adjust_idle_stream(session);
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
- if (!nghttp2_session_want_read(session)) {
- return (nghttp2_ssize)inlen;
- }
-@@ -5980,20 +5466,30 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- busy = 1;
-
- rv = session_on_data_received_fail_fast(session);
-+ if (nghttp2_is_fatal(rv)) {
-+ return rv;
-+ }
-+
- if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (nghttp2_ssize)inlen;
- }
- if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
- DEBUGF("recv: DATA not allowed stream_id=%d\n",
- iframe->frame.hd.stream_id);
-+
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- iframe->state = NGHTTP2_IB_IGN_DATA;
- break;
- }
-
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
- rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd);
- if (rv < 0) {
- rv = nghttp2_session_terminate_session_with_reason(
-@@ -6011,6 +5507,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- break;
- }
-
-+ /* Empty DATA frame without END_STREAM flag set is
-+ suspicious. */
-+ if (iframe->payloadleft == 0 &&
-+ (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+ }
-+
- iframe->state = NGHTTP2_IB_READ_DATA;
- break;
- }
-@@ -6063,6 +5573,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- on_begin_frame_called = 1;
-
- rv = session_process_headers_frame(session);
-@@ -6077,8 +5591,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- }
-
- if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-- rv = nghttp2_session_add_rst_stream(
-- session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
-+ rv = session_handle_invalid_stream2(
-+ session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-@@ -6087,6 +5601,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- }
-
- if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
- break;
- }
-@@ -6107,6 +5630,18 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- break;
- }
-
-+ /* This is deprecated RFC 7540 priorities mechanism which is
-+ very unpopular. We do not expect it is received so
-+ frequently. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- iframe->state = NGHTTP2_IB_READ_NBYTE;
-
- inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN);
-@@ -6123,7 +5658,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- DEBUGF("recv: WINDOW_UPDATE\n");
- break;
- }
--#endif /* DEBUGBUILD */
-+#endif /* defined(DEBUGBUILD) */
-
- iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
-
-@@ -6279,8 +5814,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- if (check_ext_type_set(session->user_recv_ext_types,
- iframe->frame.hd.type)) {
- if (!session->callbacks.unpack_extension_callback) {
-- /* Silently ignore unknown frame type. */
-+ /* Receiving too frequent unknown frames is suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-
-+ /* Silently ignore unknown frame type. */
- busy = 1;
-
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
-@@ -6298,6 +5842,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- case NGHTTP2_ALTSVC:
- if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
- 0) {
-+ /* Receiving too frequent unknown frames is suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- busy = 1;
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
- break;
-@@ -6309,6 +5863,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
-
- if (session->server) {
-+ /* Receiving too frequent ALTSVC from client is
-+ suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- busy = 1;
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
- break;
-@@ -6328,6 +5893,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- break;
- case NGHTTP2_ORIGIN:
- if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) {
-+ /* Receiving too frequent unknown frames is suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- busy = 1;
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
- break;
-@@ -6339,6 +5914,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
-
- if (session->server || iframe->frame.hd.stream_id ||
- (iframe->frame.hd.flags & 0xf0)) {
-+ /* Receiving too frequent invalid frames is
-+ suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- busy = 1;
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
- break;
-@@ -6365,6 +5951,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- case NGHTTP2_PRIORITY_UPDATE:
- if ((session->builtin_recv_ext_types &
- NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
-+ /* Receiving too frequent unknown frames is suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- busy = 1;
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
- break;
-@@ -6392,8 +5988,18 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- break;
- }
-
-- if (!session_no_rfc7540_pri_no_fallback(session) ||
-- iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
-+ /* Receiving too frequent PRIORITY_UPDATE is
-+ suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
-+ if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
- busy = 1;
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
- break;
-@@ -6406,6 +6012,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
-
- break;
- default:
-+ /* Receiving too frequent unknown frames is suspicious. */
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- busy = 1;
-
- iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
-@@ -6429,6 +6045,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
- }
- }
-
-@@ -6492,8 +6112,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- }
-
- if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-- rv = nghttp2_session_add_rst_stream(
-- session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
-+ rv = session_handle_invalid_stream2(
-+ session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-@@ -6502,26 +6122,23 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- }
-
- if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
-- iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
-- break;
-- }
--
-- iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK;
--
-- break;
-- case NGHTTP2_PRIORITY:
-- if (!session_no_rfc7540_pri_no_fallback(session) &&
-- session->remote_settings.no_rfc7540_priorities != 1) {
-- rv = session_process_priority_frame(session);
-- if (nghttp2_is_fatal(rv)) {
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
- return rv;
- }
-
- if (iframe->state == NGHTTP2_IB_IGN_ALL) {
- return (nghttp2_ssize)inlen;
- }
-+
-+ iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
-+ break;
- }
-
-+ iframe->state = NGHTTP2_IB_READ_HEADER_BLOCK;
-+
-+ break;
-+ case NGHTTP2_PRIORITY:
- session_inbound_frame_reset(session);
-
- break;
-@@ -6579,9 +6196,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- }
-
- if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-- rv = nghttp2_session_add_rst_stream(
-- session, iframe->frame.push_promise.promised_stream_id,
-- NGHTTP2_INTERNAL_ERROR);
-+ rv = session_handle_invalid_stream2(
-+ session, iframe->frame.push_promise.promised_stream_id, NULL,
-+ NGHTTP2_ERR_INTERNAL);
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-@@ -6684,6 +6301,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- session_inbound_frame_reset(session);
-
- break;
-@@ -6706,7 +6327,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- } else {
- DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n");
- }
--#endif /* DEBUGBUILD */
-+#endif /* defined(DEBUGBUILD) */
-
- readlen = inbound_frame_payload_readlen(iframe, in, last);
-
-@@ -6759,12 +6380,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- iframe->payloadleft -= hd_proclen;
-
- /* Use promised stream ID for PUSH_PROMISE */
-- rv = nghttp2_session_add_rst_stream(
-+ rv = session_handle_invalid_stream2(
- session,
- iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
- ? iframe->frame.push_promise.promised_stream_id
- : iframe->frame.hd.stream_id,
-- NGHTTP2_INTERNAL_ERROR);
-+ NULL, NGHTTP2_ERR_INTERNAL);
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-@@ -6811,6 +6432,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
- }
- session_inbound_frame_reset(session);
-
-@@ -6934,7 +6559,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- } else {
- fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
- }
--#endif /* DEBUGBUILD */
-+#endif /* defined(DEBUGBUILD) */
-
- if (++session->num_continuations > session->max_continuations) {
- return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
-@@ -6986,6 +6611,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
- } else {
- iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
- }
-@@ -7036,6 +6665,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
- }
-
- busy = 1;
-@@ -7052,6 +6685,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
-
- iframe->frame.data.padlen = (size_t)padlen;
-
-+ /* Empty DATA frame without END_STREAM flag set is
-+ suspicious. */
-+ if (iframe->payloadleft == 0 &&
-+ (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
-+ rv = session_update_glitch_ratelim(session);
-+ if (rv != 0) {
-+ return rv;
-+ }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+ }
-+
- iframe->state = NGHTTP2_IB_READ_DATA;
-
- break;
-@@ -7094,6 +6741,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- data_readlen =
- inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen);
-
-@@ -7123,41 +6774,30 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- if (data_readlen > 0) {
- if (session_enforce_http_messaging(session)) {
- if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) {
-- if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
-- /* Consume all data for connection immediately here */
-- rv = session_update_connection_consumed_size(
-- session, (size_t)data_readlen);
--
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
--
-- if (iframe->state == NGHTTP2_IB_IGN_DATA) {
-- return (nghttp2_ssize)inlen;
-- }
-- }
--
-- rv = nghttp2_session_add_rst_stream(
-- session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR);
-+ rv = nghttp2_session_terminate_session(session,
-+ NGHTTP2_PROTOCOL_ERROR);
- if (nghttp2_is_fatal(rv)) {
- return rv;
- }
-- busy = 1;
-- iframe->state = NGHTTP2_IB_IGN_DATA;
-- break;
-+
-+ return (nghttp2_ssize)inlen;
- }
- }
- if (session->callbacks.on_data_chunk_recv_callback) {
- rv = session->callbacks.on_data_chunk_recv_callback(
- session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
- in - readlen, (size_t)data_readlen, session->user_data);
-- if (rv == NGHTTP2_ERR_PAUSE) {
-- return (nghttp2_ssize)(in - first);
-- }
--
- if (nghttp2_is_fatal(rv)) {
- return NGHTTP2_ERR_CALLBACK_FAILURE;
- }
-+
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
-+ if (rv == NGHTTP2_ERR_PAUSE) {
-+ return (nghttp2_ssize)(in - first);
-+ }
- }
- }
- }
-@@ -7171,6 +6811,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- session_inbound_frame_reset(session);
-
- break;
-@@ -7237,6 +6881,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- if (rv != 0) {
- busy = 1;
-
-@@ -7255,6 +6903,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- session_inbound_frame_reset(session);
-
- break;
-@@ -7283,6 +6935,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
- return rv;
- }
-
-+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-+ return (nghttp2_ssize)inlen;
-+ }
-+
- session_inbound_frame_reset(session);
-
- break;
-@@ -7404,9 +7060,7 @@ int nghttp2_session_want_write(nghttp2_session *session) {
- */
- return session->aob.item || nghttp2_outbound_queue_top(&session->ob_urgent) ||
- nghttp2_outbound_queue_top(&session->ob_reg) ||
-- ((!nghttp2_pq_empty(&session->root.obq) ||
-- !session_sched_empty(session)) &&
-- session->remote_window_size > 0) ||
-+ (!session_sched_empty(session) && session->remote_window_size > 0) ||
- (nghttp2_outbound_queue_top(&session->ob_syn) &&
- !session_is_outgoing_concurrent_streams_max(session));
- }
-@@ -8046,7 +7700,6 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
- nghttp2_settings_entry *iv;
- size_t niv;
- int rv;
-- nghttp2_priority_spec pri_spec;
- nghttp2_mem *mem;
-
- mem = &session->mem;
-@@ -8083,18 +7736,13 @@ static int nghttp2_session_upgrade_internal(nghttp2_session *session,
- return rv;
- }
-
-- nghttp2_priority_spec_default_init(&pri_spec);
--
- stream = nghttp2_session_open_stream(
-- session, 1, NGHTTP2_STREAM_FLAG_NONE, &pri_spec, NGHTTP2_STREAM_OPENING,
-+ session, 1, NGHTTP2_STREAM_FLAG_NONE, NGHTTP2_STREAM_OPENING,
- session->server ? NULL : stream_user_data);
- if (stream == NULL) {
- return NGHTTP2_ERR_NOMEM;
- }
-
-- /* We don't call nghttp2_session_adjust_closed_stream(), since this
-- should be the first stream open. */
--
- if (session->server) {
- nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
- session->last_recv_stream_id = 1;
-@@ -8293,14 +7941,16 @@ int32_t nghttp2_session_get_last_proc_stream_id(nghttp2_session *session) {
- nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
- int32_t stream_id) {
- if (stream_id == 0) {
-- return &session->root;
-+ return &nghttp2_stream_root;
- }
-
- return nghttp2_session_get_stream_raw(session, stream_id);
- }
-
- nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
-- return &session->root;
-+ (void)session;
-+
-+ return &nghttp2_stream_root;
- }
-
- int nghttp2_session_check_server_session(nghttp2_session *session) {
-@@ -8310,75 +7960,20 @@ int nghttp2_session_check_server_session(nghttp2_session *session) {
- int nghttp2_session_change_stream_priority(
- nghttp2_session *session, int32_t stream_id,
- const nghttp2_priority_spec *pri_spec) {
-- int rv;
-- nghttp2_stream *stream;
-- nghttp2_priority_spec pri_spec_copy;
--
-- if (session->pending_no_rfc7540_priorities == 1) {
-- return 0;
-- }
--
-- if (stream_id == 0 || stream_id == pri_spec->stream_id) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- stream = nghttp2_session_get_stream_raw(session, stream_id);
-- if (!stream) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- pri_spec_copy = *pri_spec;
-- nghttp2_priority_spec_normalize_weight(&pri_spec_copy);
--
-- rv = nghttp2_session_reprioritize_stream(session, stream, &pri_spec_copy);
--
-- if (nghttp2_is_fatal(rv)) {
-- return rv;
-- }
-+ (void)session;
-+ (void)stream_id;
-+ (void)pri_spec;
-
-- /* We don't intentionally call nghttp2_session_adjust_idle_stream()
-- so that idle stream created by this function, and existing ones
-- are kept for application. We will adjust number of idle stream
-- in nghttp2_session_mem_send2 or nghttp2_session_mem_recv2 is
-- called. */
- return 0;
- }
-
- int nghttp2_session_create_idle_stream(nghttp2_session *session,
- int32_t stream_id,
- const nghttp2_priority_spec *pri_spec) {
-- nghttp2_stream *stream;
-- nghttp2_priority_spec pri_spec_copy;
--
-- if (session->pending_no_rfc7540_priorities == 1) {
-- return 0;
-- }
--
-- if (stream_id == 0 || stream_id == pri_spec->stream_id ||
-- !session_detect_idle_stream(session, stream_id)) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- stream = nghttp2_session_get_stream_raw(session, stream_id);
-- if (stream) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- pri_spec_copy = *pri_spec;
-- nghttp2_priority_spec_normalize_weight(&pri_spec_copy);
--
-- stream =
-- nghttp2_session_open_stream(session, stream_id, NGHTTP2_STREAM_FLAG_NONE,
-- &pri_spec_copy, NGHTTP2_STREAM_IDLE, NULL);
-- if (!stream) {
-- return NGHTTP2_ERR_NOMEM;
-- }
-+ (void)session;
-+ (void)stream_id;
-+ (void)pri_spec;
-
-- /* We don't intentionally call nghttp2_session_adjust_idle_stream()
-- so that idle stream created by this function, and existing ones
-- are kept for application. We will adjust number of idle stream
-- in nghttp2_session_mem_send2 or nghttp2_session_mem_recv2 is
-- called. */
- return 0;
- }
-
-diff --git a/deps/nghttp2/lib/nghttp2_session.h b/deps/nghttp2/lib/nghttp2_session.h
-index ef8f7b27..edbef80d 100644
---- a/deps/nghttp2/lib/nghttp2_session.h
-+++ b/deps/nghttp2/lib/nghttp2_session.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
- #include "nghttp2_map.h"
-@@ -45,6 +45,8 @@
- preface handling. */
- extern int nghttp2_enable_strict_preface;
-
-+extern nghttp2_stream nghttp2_stream_root;
-+
- /*
- * Option flags.
- */
-@@ -53,8 +55,6 @@ typedef enum {
- NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
- NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
- NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3,
-- NGHTTP2_OPTMASK_NO_CLOSED_STREAMS = 1 << 4,
-- NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 5,
- NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6,
- } nghttp2_optmask;
-
-@@ -89,10 +89,6 @@ typedef struct {
- /* The default maximum number of incoming reserved streams */
- #define NGHTTP2_MAX_INCOMING_RESERVED_STREAMS 200
-
--/* Even if we have less SETTINGS_MAX_CONCURRENT_STREAMS than this
-- number, we keep NGHTTP2_MIN_IDLE_STREAMS streams in idle state */
--#define NGHTTP2_MIN_IDLE_STREAMS 16
--
- /* The maximum number of items in outbound queue, which is considered
- as flooding caused by peer. All frames are not considered here.
- We only consider PING + ACK and SETTINGS + ACK. This is because
-@@ -110,6 +106,10 @@ typedef struct {
- #define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
- #define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
-
-+/* The default values for glitch rate limiter. */
-+#define NGHTTP2_DEFAULT_GLITCH_BURST 1000
-+#define NGHTTP2_DEFAULT_GLITCH_RATE 33
-+
- /* The default max number of CONTINUATION frames following an incoming
- HEADER frame. */
- #define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
-@@ -205,8 +205,6 @@ typedef struct nghttp2_inflight_settings nghttp2_inflight_settings;
-
- struct nghttp2_session {
- nghttp2_map /* <nghttp2_stream*> */ streams;
-- /* root of dependency tree*/
-- nghttp2_stream root;
- /* Queue for outbound urgent frames (PING and SETTINGS) */
- nghttp2_outbound_queue ob_urgent;
- /* Queue for non-DATA frames */
-@@ -229,26 +227,14 @@ struct nghttp2_session {
- /* Memory allocator */
- nghttp2_mem mem;
- void *user_data;
-- /* Points to the latest incoming closed stream. NULL if there is no
-- closed stream. Only used when session is initialized as
-- server. */
-- nghttp2_stream *closed_stream_head;
-- /* Points to the oldest incoming closed stream. NULL if there is no
-- closed stream. Only used when session is initialized as
-- server. */
-- nghttp2_stream *closed_stream_tail;
-- /* Points to the latest idle stream. NULL if there is no idle
-- stream. Only used when session is initialized as server .*/
-- nghttp2_stream *idle_stream_head;
-- /* Points to the oldest idle stream. NULL if there is no idle
-- stream. Only used when session is initialized as erver. */
-- nghttp2_stream *idle_stream_tail;
- /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
- considered as in-flight. */
- nghttp2_inflight_settings *inflight_settings_head;
- /* Stream reset rate limiter. If receiving excessive amount of
- stream resets, GOAWAY will be sent. */
- nghttp2_ratelim stream_reset_ratelim;
-+ /* Rate limiter for all kinds of glitches. */
-+ nghttp2_ratelim glitch_ratelim;
- /* Sequential number across all streams to process streams in
- FIFO. */
- uint64_t stream_seq;
-@@ -276,10 +262,9 @@ struct nghttp2_session {
- |closed_stream_head|. The current implementation only keeps
- incoming streams and session is initialized as server. */
- size_t num_closed_streams;
-- /* The number of idle streams kept in |streams| hash. The idle
-- streams can be accessed through doubly linked list
-- |idle_stream_head|. The current implementation only keeps idle
-- streams if session is initialized as server. */
-+ /* The number of idle streams kept in |streams| hash. The current
-+ implementation only keeps idle streams if session is initialized
-+ as server. */
- size_t num_idle_streams;
- /* The number of bytes allocated for nvbuf */
- size_t nvbuflen;
-@@ -362,8 +347,6 @@ struct nghttp2_session {
- /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is
- effective before it is acknowledged. */
- uint8_t pending_no_rfc7540_priorities;
-- /* Turn on fallback to RFC 7540 priorities; for server use only. */
-- uint8_t fallback_rfc7540_priorities;
- /* Nonzero if the session is server side. */
- uint8_t server;
- /* Flags indicating GOAWAY is sent and/or received. The flags are
-@@ -425,6 +408,13 @@ int nghttp2_session_is_my_stream_id(nghttp2_session *session,
- int nghttp2_session_add_item(nghttp2_session *session,
- nghttp2_outbound_item *item);
-
-+/*
-+ * This function wraps around nghttp2_session_add_rst_stream_continue
-+ * with continue_without_stream = 1.
-+ */
-+int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
-+ uint32_t error_code);
-+
- /*
- * Adds RST_STREAM frame for the stream |stream_id| with the error
- * code |error_code|. This is a convenient function built on top of
-@@ -432,7 +422,9 @@ int nghttp2_session_add_item(nghttp2_session *session,
- *
- * This function simply returns 0 without adding RST_STREAM frame if
- * given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
-- * RST_STREAM for a stream is redundant.
-+ * RST_STREAM for a stream is redundant. It also returns 0 without
-+ * adding the frame if |continue_without_stream| is nonzero, and
-+ * stream was already gone.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
-@@ -440,8 +432,10 @@ int nghttp2_session_add_item(nghttp2_session *session,
- * NGHTTP2_ERR_NOMEM
- * Out of memory.
- */
--int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
-- uint32_t error_code);
-+int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
-+ int32_t stream_id,
-+ uint32_t error_code,
-+ int continue_without_stream);
-
- /*
- * Adds PING frame. This is a convenient function built on top of
-@@ -527,15 +521,9 @@ int nghttp2_session_add_settings(nghttp2_session *session, uint8_t flags,
- *
- * This function returns a pointer to created new stream object, or
- * NULL.
-- *
-- * This function adjusts neither the number of closed streams or idle
-- * streams. The caller should manually call
-- * nghttp2_session_adjust_closed_stream() or
-- * nghttp2_session_adjust_idle_stream() respectively.
- */
- nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- int32_t stream_id, uint8_t flags,
-- nghttp2_priority_spec *pri_spec,
- nghttp2_stream_state initial_state,
- void *stream_user_data);
-
-@@ -544,11 +532,6 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
- * is indicated by the |error_code|. When closing the stream,
- * on_stream_close_callback will be called.
- *
-- * If the session is initialized as server and |stream| is incoming
-- * stream, stream is just marked closed and this function calls
-- * nghttp2_session_keep_closed_stream() with |stream|. Otherwise,
-- * |stream| will be deleted from memory.
-- *
- * This function returns 0 if it succeeds, or one the following
- * negative error codes:
- *
-@@ -565,63 +548,9 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
- /*
- * Deletes |stream| from memory. After this function returns, stream
- * cannot be accessed.
-- *
-- * This function returns 0 if it succeeds, or one the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_session_destroy_stream(nghttp2_session *session,
-- nghttp2_stream *stream);
--
--/*
-- * Tries to keep incoming closed stream |stream|. Due to the
-- * limitation of maximum number of streams in memory, |stream| is not
-- * closed and just deleted from memory (see
-- * nghttp2_session_destroy_stream).
-- */
--void nghttp2_session_keep_closed_stream(nghttp2_session *session,
-- nghttp2_stream *stream);
--
--/*
-- * Appends |stream| to linked list |session->idle_stream_head|. We
-- * apply fixed limit for list size. To fit into that limit, one or
-- * more oldest streams are removed from list as necessary.
- */
--void nghttp2_session_keep_idle_stream(nghttp2_session *session,
-- nghttp2_stream *stream);
--
--/*
-- * Detaches |stream| from idle streams linked list.
-- */
--void nghttp2_session_detach_idle_stream(nghttp2_session *session,
-- nghttp2_stream *stream);
--
--/*
-- * Deletes closed stream to ensure that number of incoming streams
-- * including active and closed is in the maximum number of allowed
-- * stream.
-- *
-- * This function returns 0 if it succeeds, or one the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_session_adjust_closed_stream(nghttp2_session *session);
--
--/*
-- * Deletes idle stream to ensure that number of idle streams is in
-- * certain limit.
-- *
-- * This function returns 0 if it succeeds, or one the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_session_adjust_idle_stream(nghttp2_session *session);
-+void nghttp2_session_destroy_stream(nghttp2_session *session,
-+ nghttp2_stream *stream);
-
- /*
- * If further receptions and transmissions over the stream |stream_id|
-@@ -915,24 +844,6 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
- nghttp2_settings_entry *iv,
- size_t niv);
-
--/*
-- * Re-prioritize |stream|. The new priority specification is
-- * |pri_spec|. Caller must ensure that stream->hd.stream_id !=
-- * pri_spec->stream_id.
-- *
-- * This function does not adjust the number of idle streams. The
-- * caller should call nghttp2_session_adjust_idle_stream() later.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_session_reprioritize_stream(nghttp2_session *session,
-- nghttp2_stream *stream,
-- const nghttp2_priority_spec *pri_spec);
--
- /*
- * Terminates current |session| with the |error_code|. The |reason|
- * is NULL-terminated debug string.
-@@ -981,4 +892,4 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
- size_t delta_size,
- int send_window_update);
-
--#endif /* NGHTTP2_SESSION_H */
-+#endif /* !defined(NGHTTP2_SESSION_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_stream.c b/deps/nghttp2/lib/nghttp2_stream.c
-index f2362447..0f2d3658 100644
---- a/deps/nghttp2/lib/nghttp2_stream.c
-+++ b/deps/nghttp2/lib/nghttp2_stream.c
-@@ -25,45 +25,17 @@
- #include "nghttp2_stream.h"
-
- #include <assert.h>
--#include <stdio.h>
-
- #include "nghttp2_session.h"
- #include "nghttp2_helper.h"
- #include "nghttp2_debug.h"
- #include "nghttp2_frame.h"
-
--/* Maximum distance between any two stream's cycle in the same
-- priority queue. Imagine stream A's cycle is A, and stream B's
-- cycle is B, and A < B. The cycle is unsigned 32 bit integer, it
-- may get overflow. Because of how we calculate the next cycle
-- value, if B - A is less than or equals to
-- NGHTTP2_MAX_CYCLE_DISTANCE, A and B are in the same scale, in other
-- words, B is really greater than or equal to A. Otherwise, A is a
-- result of overflow, and it is actually A > B if we consider that
-- fact. */
--#define NGHTTP2_MAX_CYCLE_DISTANCE \
-- ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX * 256 + 255)
--
--static int stream_less(const void *lhsx, const void *rhsx) {
-- const nghttp2_stream *lhs, *rhs;
--
-- lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry);
-- rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry);
--
-- if (lhs->cycle == rhs->cycle) {
-- return lhs->seq < rhs->seq;
-- }
--
-- return rhs->cycle - lhs->cycle <= NGHTTP2_MAX_CYCLE_DISTANCE;
--}
--
- void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
- uint8_t flags, nghttp2_stream_state initial_state,
-- int32_t weight, int32_t remote_initial_window_size,
-+ int32_t remote_initial_window_size,
- int32_t local_initial_window_size,
-- void *stream_user_data, nghttp2_mem *mem) {
-- nghttp2_pq_init(&stream->obq, stream_less, mem);
--
-+ void *stream_user_data) {
- stream->stream_id = stream_id;
- stream->flags = flags;
- stream->state = initial_state;
-@@ -77,428 +49,36 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
- stream->recv_reduction = 0;
- stream->window_update_queued = 0;
-
-- stream->dep_prev = NULL;
-- stream->dep_next = NULL;
-- stream->sib_prev = NULL;
-- stream->sib_next = NULL;
--
-- stream->closed_prev = NULL;
- stream->closed_next = NULL;
-
-- stream->weight = weight;
-- stream->sum_dep_weight = 0;
--
- stream->http_flags = NGHTTP2_HTTP_FLAG_NONE;
- stream->content_length = -1;
- stream->recv_content_length = 0;
- stream->status_code = -1;
-
- stream->queued = 0;
-- stream->descendant_last_cycle = 0;
- stream->cycle = 0;
- stream->pending_penalty = 0;
-- stream->descendant_next_seq = 0;
- stream->seq = 0;
- stream->last_writelen = 0;
-
- stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
- }
-
--void nghttp2_stream_free(nghttp2_stream *stream) {
-- nghttp2_pq_free(&stream->obq);
-- /* We don't free stream->item. If it is assigned to aob, then
-- active_outbound_item_reset() will delete it. Otherwise,
-- nghttp2_stream_close() or session_del() will delete it. */
--}
-+void nghttp2_stream_free(nghttp2_stream *stream) { (void)stream; }
-
- void nghttp2_stream_shutdown(nghttp2_stream *stream, nghttp2_shut_flag flag) {
- stream->shut_flags = (uint8_t)(stream->shut_flags | flag);
- }
-
--/*
-- * Returns nonzero if |stream| is active. This function does not take
-- * into account its descendants.
-- */
--static int stream_active(nghttp2_stream *stream) {
-- return stream->item &&
-- (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0;
--}
--
--/*
-- * Returns nonzero if |stream| or one of its descendants is active
-- */
--static int stream_subtree_active(nghttp2_stream *stream) {
-- return stream_active(stream) || !nghttp2_pq_empty(&stream->obq);
--}
--
--/*
-- * Returns next cycle for |stream|.
-- */
--static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) {
-- uint64_t penalty;
--
-- penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT +
-- stream->pending_penalty;
--
-- stream->cycle = last_cycle + penalty / (uint32_t)stream->weight;
-- stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight);
--}
--
--static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
-- int rv;
--
-- for (; dep_stream && !stream->queued;
-- stream = dep_stream, dep_stream = dep_stream->dep_prev) {
-- stream_next_cycle(stream, dep_stream->descendant_last_cycle);
-- stream->seq = dep_stream->descendant_next_seq++;
--
-- DEBUGF("stream: stream=%d obq push cycle=%lu\n", stream->stream_id,
-- stream->cycle);
--
-- DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
-- dep_stream->stream_id);
--
-- rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
-- if (rv != 0) {
-- return rv;
-- }
-- stream->queued = 1;
-- }
--
-- return 0;
--}
--
--/*
-- * Removes |stream| from parent's obq. If removal of |stream| makes
-- * parent's obq empty, and parent is not active, then parent is also
-- * removed. This process is repeated recursively.
-- */
--static void stream_obq_remove(nghttp2_stream *stream) {
-- nghttp2_stream *dep_stream;
--
-- dep_stream = stream->dep_prev;
--
-- if (!stream->queued) {
-- return;
-- }
--
-- for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
-- DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
-- dep_stream->stream_id);
--
-- nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
--
-- assert(stream->queued);
--
-- stream->queued = 0;
-- stream->cycle = 0;
-- stream->pending_penalty = 0;
-- stream->descendant_last_cycle = 0;
-- stream->last_writelen = 0;
--
-- if (stream_subtree_active(dep_stream)) {
-- return;
-- }
-- }
--}
--
--/*
-- * Moves |stream| from |src|'s obq to |dest|'s obq. Removal from
-- * |src|'s obq is just done calling nghttp2_pq_remove(), so it does
-- * not recursively remove |src| and ancestors, like
-- * stream_obq_remove().
-- */
--static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src,
-- nghttp2_stream *stream) {
-- if (!stream->queued) {
-- return 0;
-- }
--
-- DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
-- src->stream_id);
--
-- nghttp2_pq_remove(&src->obq, &stream->pq_entry);
-- stream->queued = 0;
--
-- return stream_obq_push(dest, stream);
--}
--
--void nghttp2_stream_reschedule(nghttp2_stream *stream) {
-- nghttp2_stream *dep_stream;
--
-- assert(stream->queued);
--
-- dep_stream = stream->dep_prev;
--
-- for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
-- nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
--
-- stream_next_cycle(stream, dep_stream->descendant_last_cycle);
-- stream->seq = dep_stream->descendant_next_seq++;
--
-- nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
--
-- DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
-- stream->cycle);
--
-- dep_stream->last_writelen = stream->last_writelen;
-- }
--}
--
--void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
-- nghttp2_stream *dep_stream;
-- uint64_t last_cycle;
-- int32_t old_weight;
-- uint64_t wlen_penalty;
--
-- if (stream->weight == weight) {
-- return;
-- }
--
-- old_weight = stream->weight;
-- stream->weight = weight;
--
-- dep_stream = stream->dep_prev;
--
-- if (!dep_stream) {
-- return;
-- }
--
-- dep_stream->sum_dep_weight += weight - old_weight;
--
-- if (!stream->queued) {
-- return;
-- }
--
-- nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
--
-- wlen_penalty = (uint64_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT;
--
-- /* Compute old stream->pending_penalty we used to calculate
-- stream->cycle */
-- stream->pending_penalty =
-- (uint32_t)((stream->pending_penalty + (uint32_t)old_weight -
-- (wlen_penalty % (uint32_t)old_weight)) %
-- (uint32_t)old_weight);
--
-- last_cycle = stream->cycle -
-- (wlen_penalty + stream->pending_penalty) / (uint32_t)old_weight;
--
-- /* Now we have old stream->pending_penalty and new stream->weight in
-- place */
-- stream_next_cycle(stream, last_cycle);
--
-- if (dep_stream->descendant_last_cycle - stream->cycle <=
-- NGHTTP2_MAX_CYCLE_DISTANCE) {
-- stream->cycle = dep_stream->descendant_last_cycle;
-- }
--
-- /* Continue to use same stream->seq */
--
-- nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
--
-- DEBUGF("stream: stream=%d obq resched cycle=%lu\n", stream->stream_id,
-- stream->cycle);
--}
--
--static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
-- for (; stream->sib_next; stream = stream->sib_next)
-- ;
--
-- return stream;
--}
--
--int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
-- int32_t weight) {
-- weight = stream->weight * weight / stream->sum_dep_weight;
--
-- return nghttp2_max_int32(1, weight);
--}
--
--#ifdef STREAM_DEP_DEBUG
--
--static void ensure_inactive(nghttp2_stream *stream) {
-- nghttp2_stream *si;
--
-- if (stream->queued) {
-- fprintf(stderr, "stream(%p)=%d, stream->queued = 1; want 0\n", stream,
-- stream->stream_id);
-- assert(0);
-- }
--
-- if (stream_active(stream)) {
-- fprintf(stderr, "stream(%p)=%d, stream_active(stream) = 1; want 0\n",
-- stream, stream->stream_id);
-- assert(0);
-- }
--
-- if (!nghttp2_pq_empty(&stream->obq)) {
-- fprintf(stderr, "stream(%p)=%d, nghttp2_pq_size() = %zu; want 0\n", stream,
-- stream->stream_id, nghttp2_pq_size(&stream->obq));
-- assert(0);
-- }
--
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- ensure_inactive(si);
-- }
--}
--
--static void check_queued(nghttp2_stream *stream) {
-- nghttp2_stream *si;
-- int queued;
--
-- if (stream->queued) {
-- if (!stream_subtree_active(stream)) {
-- fprintf(stderr,
-- "stream(%p)=%d, stream->queued == 1, but "
-- "stream_active() == %d and nghttp2_pq_size(&stream->obq) = %zu\n",
-- stream, stream->stream_id, stream_active(stream),
-- nghttp2_pq_size(&stream->obq));
-- assert(0);
-- }
-- if (!stream_active(stream)) {
-- queued = 0;
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- if (si->queued) {
-- ++queued;
-- }
-- }
-- if (queued == 0) {
-- fprintf(stderr,
-- "stream(%p)=%d, stream->queued == 1, and "
-- "!stream_active(), but no descendants is queued\n",
-- stream, stream->stream_id);
-- assert(0);
-- }
-- }
--
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- check_queued(si);
-- }
-- } else {
-- if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) {
-- fprintf(stderr,
-- "stream(%p) = %d, stream->queued == 0, but "
-- "stream_active(stream) == %d and "
-- "nghttp2_pq_size(&stream->obq) = %zu\n",
-- stream, stream->stream_id, stream_active(stream),
-- nghttp2_pq_size(&stream->obq));
-- assert(0);
-- }
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- ensure_inactive(si);
-- }
-- }
--}
--
--static void check_sum_dep(nghttp2_stream *stream) {
-- nghttp2_stream *si;
-- int32_t n = 0;
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- n += si->weight;
-- }
-- if (n != stream->sum_dep_weight) {
-- fprintf(stderr, "stream(%p)=%d, sum_dep_weight = %d; want %d\n", stream,
-- stream->stream_id, n, stream->sum_dep_weight);
-- assert(0);
-- }
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- check_sum_dep(si);
-- }
--}
--
--static void check_dep_prev(nghttp2_stream *stream) {
-- nghttp2_stream *si;
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- if (si->dep_prev != stream) {
-- fprintf(stderr, "si->dep_prev = %p; want %p\n", si->dep_prev, stream);
-- assert(0);
-- }
-- check_dep_prev(si);
-- }
--}
--
--#endif /* STREAM_DEP_DEBUG */
--
--#ifdef STREAM_DEP_DEBUG
--static void validate_tree(nghttp2_stream *stream) {
-- nghttp2_stream *si;
--
-- if (!stream) {
-- return;
-- }
--
-- for (; stream->dep_prev; stream = stream->dep_prev)
-- ;
--
-- assert(stream->stream_id == 0);
-- assert(!stream->queued);
--
-- fprintf(stderr, "checking...\n");
-- if (nghttp2_pq_empty(&stream->obq)) {
-- fprintf(stderr, "root obq empty\n");
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- ensure_inactive(si);
-- }
-- } else {
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- check_queued(si);
-- }
-- }
--
-- check_sum_dep(stream);
-- check_dep_prev(stream);
--}
--#else /* !STREAM_DEP_DEBUG */
--static void validate_tree(nghttp2_stream *stream) { (void)stream; }
--#endif /* !STREAM_DEP_DEBUG*/
--
--static int stream_update_dep_on_attach_item(nghttp2_stream *stream) {
-- int rv;
--
-- rv = stream_obq_push(stream->dep_prev, stream);
-- if (rv != 0) {
-- return rv;
-- }
--
-- validate_tree(stream);
-- return 0;
--}
--
--static void stream_update_dep_on_detach_item(nghttp2_stream *stream) {
-- if (nghttp2_pq_empty(&stream->obq)) {
-- stream_obq_remove(stream);
-- }
--
-- validate_tree(stream);
--}
--
--int nghttp2_stream_attach_item(nghttp2_stream *stream,
-- nghttp2_outbound_item *item) {
-- int rv;
--
-+void nghttp2_stream_attach_item(nghttp2_stream *stream,
-+ nghttp2_outbound_item *item) {
- assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
- assert(stream->item == NULL);
-
- DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
-
- stream->item = item;
--
-- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-- return 0;
-- }
--
-- rv = stream_update_dep_on_attach_item(stream);
-- if (rv != 0) {
-- /* This may relave stream->queued == 1, but stream->item == NULL.
-- But only consequence of this error is fatal one, and session
-- destruction. In that execution path, these inconsistency does
-- not matter. */
-- stream->item = NULL;
-- return rv;
-- }
--
-- return 0;
- }
-
- void nghttp2_stream_detach_item(nghttp2_stream *stream) {
-@@ -506,12 +86,6 @@ void nghttp2_stream_detach_item(nghttp2_stream *stream) {
-
- stream->item = NULL;
- stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
--
-- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-- return;
-- }
--
-- stream_update_dep_on_detach_item(stream);
- }
-
- void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
-@@ -521,31 +95,16 @@ void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
- stream->item, flags);
-
- stream->flags |= flags;
--
-- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-- return;
-- }
--
-- stream_update_dep_on_detach_item(stream);
- }
-
--int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
-+void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream,
-+ uint8_t flags) {
- assert(stream->item);
-
- DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
- stream->item, flags);
-
- stream->flags = (uint8_t)(stream->flags & ~flags);
--
-- if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) {
-- return 0;
-- }
--
-- if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-- return 0;
-- }
--
-- return stream_update_dep_on_attach_item(stream);
- }
-
- int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) {
-@@ -591,373 +150,11 @@ void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) {
- stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_PUSH);
- }
-
--int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
-- nghttp2_stream *target) {
-- for (; stream; stream = stream->dep_prev) {
-- if (stream == target) {
-- return 1;
-- }
-- }
-- return 0;
--}
--
--int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream) {
-- nghttp2_stream *si;
-- int rv;
--
-- DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
-- dep_stream->stream_id, stream, stream->stream_id);
--
-- stream->sum_dep_weight = dep_stream->sum_dep_weight;
-- dep_stream->sum_dep_weight = stream->weight;
--
-- if (dep_stream->dep_next) {
-- for (si = dep_stream->dep_next; si; si = si->sib_next) {
-- si->dep_prev = stream;
-- if (si->queued) {
-- rv = stream_obq_move(stream, dep_stream, si);
-- if (rv != 0) {
-- return rv;
-- }
-- }
-- }
--
-- if (stream_subtree_active(stream)) {
-- rv = stream_obq_push(dep_stream, stream);
-- if (rv != 0) {
-- return rv;
-- }
-- }
--
-- stream->dep_next = dep_stream->dep_next;
-- }
--
-- dep_stream->dep_next = stream;
-- stream->dep_prev = dep_stream;
--
-- validate_tree(stream);
--
-- return 0;
--}
--
--static void set_dep_prev(nghttp2_stream *stream, nghttp2_stream *dep) {
-- for (; stream; stream = stream->sib_next) {
-- stream->dep_prev = dep;
-- }
--}
--
--static void link_dep(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
-- dep_stream->dep_next = stream;
-- if (stream) {
-- stream->dep_prev = dep_stream;
-- }
--}
--
--static void link_sib(nghttp2_stream *a, nghttp2_stream *b) {
-- a->sib_next = b;
-- if (b) {
-- b->sib_prev = a;
-- }
--}
--
--static void insert_link_dep(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream) {
-- nghttp2_stream *sib_next;
--
-- assert(stream->sib_prev == NULL);
--
-- sib_next = dep_stream->dep_next;
--
-- link_sib(stream, sib_next);
--
-- link_dep(dep_stream, stream);
--}
--
--static void unlink_sib(nghttp2_stream *stream) {
-- nghttp2_stream *prev, *next, *dep_next;
--
-- prev = stream->sib_prev;
-- dep_next = stream->dep_next;
--
-- assert(prev);
--
-- if (dep_next) {
-- /*
-- * prev--stream(--sib_next--...)
-- * |
-- * dep_next
-- */
--
-- link_sib(prev, dep_next);
--
-- set_dep_prev(dep_next, stream->dep_prev);
--
-- if (stream->sib_next) {
-- link_sib(stream_last_sib(dep_next), stream->sib_next);
-- }
-- } else {
-- /*
-- * prev--stream(--sib_next--...)
-- */
-- next = stream->sib_next;
--
-- prev->sib_next = next;
--
-- if (next) {
-- next->sib_prev = prev;
-- }
-- }
--}
--
--static void unlink_dep(nghttp2_stream *stream) {
-- nghttp2_stream *prev, *next, *dep_next;
--
-- prev = stream->dep_prev;
-- dep_next = stream->dep_next;
--
-- assert(prev);
--
-- if (dep_next) {
-- /*
-- * prev
-- * |
-- * stream(--sib_next--...)
-- * |
-- * dep_next
-- */
-- link_dep(prev, dep_next);
--
-- set_dep_prev(dep_next, stream->dep_prev);
--
-- if (stream->sib_next) {
-- link_sib(stream_last_sib(dep_next), stream->sib_next);
-- }
--
-- } else if (stream->sib_next) {
-- /*
-- * prev
-- * |
-- * stream--sib_next
-- */
-- next = stream->sib_next;
--
-- next->sib_prev = NULL;
--
-- link_dep(prev, next);
-- } else {
-- prev->dep_next = NULL;
-- }
--}
--
--void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream) {
-- DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
-- dep_stream->stream_id, stream, stream->stream_id);
--
-- dep_stream->sum_dep_weight += stream->weight;
--
-- if (dep_stream->dep_next == NULL) {
-- link_dep(dep_stream, stream);
-- } else {
-- insert_link_dep(dep_stream, stream);
-- }
--
-- validate_tree(stream);
--}
--
--int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
-- nghttp2_stream *dep_prev, *si;
-- int32_t sum_dep_weight_delta;
-- int rv;
--
-- DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
--
-- /* Distribute weight of |stream| to direct descendants */
-- sum_dep_weight_delta = -stream->weight;
--
-- for (si = stream->dep_next; si; si = si->sib_next) {
-- si->weight = nghttp2_stream_dep_distributed_weight(stream, si->weight);
--
-- sum_dep_weight_delta += si->weight;
--
-- if (si->queued) {
-- rv = stream_obq_move(stream->dep_prev, stream, si);
-- if (rv != 0) {
-- return rv;
-- }
-- }
-- }
--
-- assert(stream->dep_prev);
--
-- dep_prev = stream->dep_prev;
--
-- dep_prev->sum_dep_weight += sum_dep_weight_delta;
--
-- if (stream->queued) {
-- stream_obq_remove(stream);
-- }
--
-- if (stream->sib_prev) {
-- unlink_sib(stream);
-- } else {
-- unlink_dep(stream);
-- }
--
-- stream->sum_dep_weight = 0;
--
-- stream->dep_prev = NULL;
-- stream->dep_next = NULL;
-- stream->sib_prev = NULL;
-- stream->sib_next = NULL;
--
-- validate_tree(dep_prev);
--
-- return 0;
--}
--
--int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream) {
-- nghttp2_stream *last_sib;
-- nghttp2_stream *dep_next;
-- nghttp2_stream *si;
-- int rv;
--
-- DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
-- dep_stream, dep_stream->stream_id, stream, stream->stream_id);
--
-- stream->sum_dep_weight += dep_stream->sum_dep_weight;
-- dep_stream->sum_dep_weight = stream->weight;
--
-- if (dep_stream->dep_next) {
-- dep_next = dep_stream->dep_next;
--
-- link_dep(dep_stream, stream);
--
-- if (stream->dep_next) {
-- last_sib = stream_last_sib(stream->dep_next);
--
-- link_sib(last_sib, dep_next);
-- } else {
-- link_dep(stream, dep_next);
-- }
--
-- for (si = dep_next; si; si = si->sib_next) {
-- si->dep_prev = stream;
-- if (si->queued) {
-- rv = stream_obq_move(stream, dep_stream, si);
-- if (rv != 0) {
-- return rv;
-- }
-- }
-- }
-- } else {
-- link_dep(dep_stream, stream);
-- }
--
-- if (stream_subtree_active(stream)) {
-- rv = stream_obq_push(dep_stream, stream);
-- if (rv != 0) {
-- return rv;
-- }
-- }
--
-- validate_tree(dep_stream);
--
-- return 0;
--}
--
--int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream) {
-- int rv;
--
-- DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
-- dep_stream, dep_stream->stream_id, stream, stream->stream_id);
--
-- dep_stream->sum_dep_weight += stream->weight;
--
-- if (dep_stream->dep_next) {
-- insert_link_dep(dep_stream, stream);
-- } else {
-- link_dep(dep_stream, stream);
-- }
--
-- if (stream_subtree_active(stream)) {
-- rv = stream_obq_push(dep_stream, stream);
-- if (rv != 0) {
-- return rv;
-- }
-- }
--
-- validate_tree(dep_stream);
--
-- return 0;
--}
--
--void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
-- nghttp2_stream *next, *dep_prev;
--
-- DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
-- stream->stream_id);
--
-- assert(stream->dep_prev);
--
-- dep_prev = stream->dep_prev;
--
-- if (stream->sib_prev) {
-- link_sib(stream->sib_prev, stream->sib_next);
-- } else {
-- next = stream->sib_next;
--
-- link_dep(dep_prev, next);
--
-- if (next) {
-- next->sib_prev = NULL;
-- }
-- }
--
-- dep_prev->sum_dep_weight -= stream->weight;
--
-- if (stream->queued) {
-- stream_obq_remove(stream);
-- }
--
-- validate_tree(dep_prev);
--
-- stream->sib_prev = NULL;
-- stream->sib_next = NULL;
-- stream->dep_prev = NULL;
--}
--
--int nghttp2_stream_in_dep_tree(nghttp2_stream *stream) {
-- return stream->dep_prev || stream->dep_next || stream->sib_prev ||
-- stream->sib_next;
--}
--
--nghttp2_outbound_item *
--nghttp2_stream_next_outbound_item(nghttp2_stream *stream) {
-- nghttp2_pq_entry *ent;
-- nghttp2_stream *si;
--
-- for (;;) {
-- if (stream_active(stream)) {
-- /* Update ascendant's descendant_last_cycle here, so that we can
-- assure that new stream is scheduled based on it. */
-- for (si = stream; si->dep_prev; si = si->dep_prev) {
-- si->dep_prev->descendant_last_cycle = si->cycle;
-- }
-- return stream->item;
-- }
-- ent = nghttp2_pq_top(&stream->obq);
-- if (!ent) {
-- return NULL;
-- }
-- stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry);
-+nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
-+ if (stream == &nghttp2_stream_root) {
-+ return NGHTTP2_STREAM_STATE_IDLE;
- }
--}
-
--nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
- if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) {
- return NGHTTP2_STREAM_STATE_CLOSED;
- }
-@@ -988,27 +185,39 @@ nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
- }
-
- nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) {
-- return stream->dep_prev;
-+ (void)stream;
-+
-+ return NULL;
- }
-
- nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) {
-- return stream->sib_next;
-+ (void)stream;
-+
-+ return NULL;
- }
-
- nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) {
-- return stream->sib_prev;
-+ (void)stream;
-+
-+ return NULL;
- }
-
- nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) {
-- return stream->dep_next;
-+ (void)stream;
-+
-+ return NULL;
- }
-
- int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) {
-- return stream->weight;
-+ (void)stream;
-+
-+ return NGHTTP2_DEFAULT_WEIGHT;
- }
-
- int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) {
-- return stream->sum_dep_weight;
-+ (void)stream;
-+
-+ return 0;
- }
-
- int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) {
-diff --git a/deps/nghttp2/lib/nghttp2_stream.h b/deps/nghttp2/lib/nghttp2_stream.h
-index 28add165..603209ec 100644
---- a/deps/nghttp2/lib/nghttp2_stream.h
-+++ b/deps/nghttp2/lib/nghttp2_stream.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
- #include "nghttp2_outbound_item.h"
-@@ -91,9 +91,6 @@ typedef enum {
- /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
- NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
- NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c,
-- /* Indicates that this stream is not subject to RFC7540
-- priorities scheme. */
-- NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES = 0x10,
- /* Ignore client RFC 9218 priority signal. */
- NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20,
- /* Indicates that RFC 9113 leading and trailing white spaces
-@@ -146,39 +143,18 @@ typedef enum {
- } nghttp2_http_flag;
-
- struct nghttp2_stream {
-- /* Entry for dep_prev->obq */
-+ nghttp2_stream_state state;
- nghttp2_pq_entry pq_entry;
-- /* Priority Queue storing direct descendant (nghttp2_stream). Only
-- streams which itself has some data to send, or has a descendant
-- which has some data to sent. */
-- nghttp2_pq obq;
- /* Content-Length of request/response body. -1 if unknown. */
- int64_t content_length;
- /* Received body so far */
- int64_t recv_content_length;
-- /* Base last_cycle for direct descendent streams. */
-- uint64_t descendant_last_cycle;
- /* Next scheduled time to sent item */
- uint64_t cycle;
-- /* Next seq used for direct descendant streams */
-- uint64_t descendant_next_seq;
- /* Secondary key for prioritization to break a tie for cycle. This
- value is monotonically increased for single parent stream. */
- uint64_t seq;
-- /* pointers to form dependency tree. If multiple streams depend on
-- a stream, only one stream (left most) has non-NULL dep_prev which
-- points to the stream it depends on. The remaining streams are
-- linked using sib_prev and sib_next. The stream which has
-- non-NULL dep_prev always NULL sib_prev. The right most stream
-- has NULL sib_next. If this stream is a root of dependency tree,
-- dep_prev and sib_prev are NULL. */
-- nghttp2_stream *dep_prev, *dep_next;
-- nghttp2_stream *sib_prev, *sib_next;
-- /* When stream is kept after closure, it may be kept in doubly
-- linked list pointed by nghttp2_session closed_stream_head.
-- closed_next points to the next stream object if it is the element
-- of the list. */
-- nghttp2_stream *closed_prev, *closed_next;
-+ nghttp2_stream *closed_next;
- /* The arbitrary data provided by user for this stream. */
- void *stream_user_data;
- /* Item to send */
-@@ -205,13 +181,8 @@ struct nghttp2_stream {
- NGHTTP2_INITIAL_WINDOW_SIZE and could be increased/decreased by
- submitting WINDOW_UPDATE. See nghttp2_submit_window_update(). */
- int32_t local_window_size;
-- /* weight of this stream */
-- int32_t weight;
- /* This is unpaid penalty (offset) when calculating cycle. */
- uint32_t pending_penalty;
-- /* sum of weight of direct descendants */
-- int32_t sum_dep_weight;
-- nghttp2_stream_state state;
- /* status code from remote server */
- int16_t status_code;
- /* Bitwise OR of zero or more nghttp2_http_flag values */
-@@ -239,9 +210,9 @@ struct nghttp2_stream {
-
- void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
- uint8_t flags, nghttp2_stream_state initial_state,
-- int32_t weight, int32_t remote_initial_window_size,
-+ int32_t remote_initial_window_size,
- int32_t local_initial_window_size,
-- void *stream_user_data, nghttp2_mem *mem);
-+ void *stream_user_data);
-
- void nghttp2_stream_free(nghttp2_stream *stream);
-
-@@ -267,14 +238,8 @@ void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags);
- * NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and given masks are
- * cleared if they are set. So even if this function is called, if
- * one of flag is still set, data does not become active.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
- */
--int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
-+void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
-
- /*
- * Returns nonzero if item is deferred by whatever reason.
-@@ -317,57 +282,11 @@ int nghttp2_stream_update_local_initial_window_size(
- */
- void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream);
-
--/*
-- * Returns nonzero if |target| is an ancestor of |stream|.
-- */
--int nghttp2_stream_dep_find_ancestor(nghttp2_stream *stream,
-- nghttp2_stream *target);
--
--/*
-- * Computes distributed weight of a stream of the |weight| under the
-- * |stream| if |stream| is removed from a dependency tree.
-- */
--int32_t nghttp2_stream_dep_distributed_weight(nghttp2_stream *stream,
-- int32_t weight);
--
--/*
-- * Makes the |stream| depend on the |dep_stream|. This dependency is
-- * exclusive. All existing direct descendants of |dep_stream| become
-- * the descendants of the |stream|. This function assumes
-- * |stream->item| is NULL.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream);
--
--/*
-- * Makes the |stream| depend on the |dep_stream|. This dependency is
-- * not exclusive. This function assumes |stream->item| is NULL.
-- */
--void nghttp2_stream_dep_add(nghttp2_stream *dep_stream, nghttp2_stream *stream);
--
--/*
-- * Removes the |stream| from the current dependency tree. This
-- * function assumes |stream->item| is NULL.
-- */
--int nghttp2_stream_dep_remove(nghttp2_stream *stream);
--
- /*
- * Attaches |item| to |stream|.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
- */
--int nghttp2_stream_attach_item(nghttp2_stream *stream,
-- nghttp2_outbound_item *item);
-+void nghttp2_stream_attach_item(nghttp2_stream *stream,
-+ nghttp2_outbound_item *item);
-
- /*
- * Detaches |stream->item|. This function does not free
-@@ -375,66 +294,4 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
- */
- void nghttp2_stream_detach_item(nghttp2_stream *stream);
-
--/*
-- * Makes the |stream| depend on the |dep_stream|. This dependency is
-- * exclusive.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream);
--
--/*
-- * Makes the |stream| depend on the |dep_stream|. This dependency is
-- * not exclusive.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
-- nghttp2_stream *stream);
--
--/*
-- * Removes subtree whose root stream is |stream|. The
-- * effective_weight of streams in removed subtree is not updated.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * negative error codes:
-- *
-- * NGHTTP2_ERR_NOMEM
-- * Out of memory
-- */
--void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream);
--
--/*
-- * Returns nonzero if |stream| is in any dependency tree.
-- */
--int nghttp2_stream_in_dep_tree(nghttp2_stream *stream);
--
--/*
-- * Schedules transmission of |stream|'s item, assuming stream->item is
-- * attached, and stream->last_writelen was updated.
-- */
--void nghttp2_stream_reschedule(nghttp2_stream *stream);
--
--/*
-- * Changes |stream|'s weight to |weight|. If |stream| is queued, it
-- * will be rescheduled based on new weight.
-- */
--void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight);
--
--/*
-- * Returns a stream which has highest priority, updating
-- * descendant_last_cycle of selected stream's ancestors.
-- */
--nghttp2_outbound_item *
--nghttp2_stream_next_outbound_item(nghttp2_stream *stream);
--
--#endif /* NGHTTP2_STREAM */
-+#endif /* !defined(NGHTTP2_STREAM_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_submit.c b/deps/nghttp2/lib/nghttp2_submit.c
-index 81c1ab70..8a90f714 100644
---- a/deps/nghttp2/lib/nghttp2_submit.c
-+++ b/deps/nghttp2/lib/nghttp2_submit.c
-@@ -32,42 +32,12 @@
- #include "nghttp2_helper.h"
- #include "nghttp2_priority_spec.h"
-
--/*
-- * Detects the dependency error, that is stream attempted to depend on
-- * itself. If |stream_id| is -1, we use session->next_stream_id as
-- * stream ID.
-- *
-- * This function returns 0 if it succeeds, or one of the following
-- * error codes:
-- *
-- * NGHTTP2_ERR_INVALID_ARGUMENT
-- * Stream attempted to depend on itself.
-- */
--static int detect_self_dependency(nghttp2_session *session, int32_t stream_id,
-- const nghttp2_priority_spec *pri_spec) {
-- assert(pri_spec);
--
-- if (stream_id == -1) {
-- if ((int32_t)session->next_stream_id == pri_spec->stream_id) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
-- return 0;
-- }
--
-- if (stream_id == pri_spec->stream_id) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- return 0;
--}
--
- /* This function takes ownership of |nva_copy|. Regardless of the
- return value, the caller must not free |nva_copy| after this
- function returns. */
- static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
-- int32_t stream_id,
-- const nghttp2_priority_spec *pri_spec,
-- nghttp2_nv *nva_copy, size_t nvlen,
-+ int32_t stream_id, nghttp2_nv *nva_copy,
-+ size_t nvlen,
- const nghttp2_data_provider_wrap *dpw,
- void *stream_user_data) {
- int rv;
-@@ -114,8 +84,8 @@ static int32_t submit_headers_shared(nghttp2_session *session, uint8_t flags,
-
- frame = &item->frame;
-
-- nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat,
-- pri_spec, nva_copy, nvlen);
-+ nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL,
-+ nva_copy, nvlen);
-
- rv = nghttp2_session_add_item(session, item);
-
-@@ -141,31 +111,22 @@ fail2:
-
- static int32_t submit_headers_shared_nva(nghttp2_session *session,
- uint8_t flags, int32_t stream_id,
-- const nghttp2_priority_spec *pri_spec,
- const nghttp2_nv *nva, size_t nvlen,
- const nghttp2_data_provider_wrap *dpw,
- void *stream_user_data) {
- int rv;
- nghttp2_nv *nva_copy;
-- nghttp2_priority_spec copy_pri_spec;
- nghttp2_mem *mem;
-
- mem = &session->mem;
-
-- if (pri_spec) {
-- copy_pri_spec = *pri_spec;
-- nghttp2_priority_spec_normalize_weight(©_pri_spec);
-- } else {
-- nghttp2_priority_spec_default_init(©_pri_spec);
-- }
--
- rv = nghttp2_nv_array_copy(&nva_copy, nva, nvlen, mem);
- if (rv < 0) {
- return rv;
- }
-
-- return submit_headers_shared(session, flags, stream_id, ©_pri_spec,
-- nva_copy, nvlen, dpw, stream_user_data);
-+ return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw,
-+ stream_user_data);
- }
-
- int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
-@@ -174,8 +135,8 @@ int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
- return NGHTTP2_ERR_INVALID_ARGUMENT;
- }
-
-- return (int)submit_headers_shared_nva(
-- session, NGHTTP2_FLAG_END_STREAM, stream_id, NULL, nva, nvlen, NULL, NULL);
-+ return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
-+ stream_id, nva, nvlen, NULL, NULL);
- }
-
- int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
-@@ -183,7 +144,7 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
- const nghttp2_priority_spec *pri_spec,
- const nghttp2_nv *nva, size_t nvlen,
- void *stream_user_data) {
-- int rv;
-+ (void)pri_spec;
-
- if (stream_id == -1) {
- if (session->server) {
-@@ -195,20 +156,8 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
-
- flags &= NGHTTP2_FLAG_END_STREAM;
-
-- if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
-- session->remote_settings.no_rfc7540_priorities != 1) {
-- rv = detect_self_dependency(session, stream_id, pri_spec);
-- if (rv != 0) {
-- return rv;
-- }
--
-- flags |= NGHTTP2_FLAG_PRIORITY;
-- } else {
-- pri_spec = NULL;
-- }
--
-- return submit_headers_shared_nva(session, flags, stream_id, pri_spec, nva,
-- nvlen, NULL, stream_user_data);
-+ return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL,
-+ stream_user_data);
- }
-
- int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
-@@ -220,51 +169,10 @@ int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
- int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
- int32_t stream_id,
- const nghttp2_priority_spec *pri_spec) {
-- int rv;
-- nghttp2_outbound_item *item;
-- nghttp2_frame *frame;
-- nghttp2_priority_spec copy_pri_spec;
-- nghttp2_mem *mem;
-+ (void)session;
- (void)flags;
--
-- mem = &session->mem;
--
-- if (session->remote_settings.no_rfc7540_priorities == 1) {
-- return 0;
-- }
--
-- if (stream_id == 0 || pri_spec == NULL) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- if (stream_id == pri_spec->stream_id) {
-- return NGHTTP2_ERR_INVALID_ARGUMENT;
-- }
--
-- copy_pri_spec = *pri_spec;
--
-- nghttp2_priority_spec_normalize_weight(©_pri_spec);
--
-- item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
--
-- if (item == NULL) {
-- return NGHTTP2_ERR_NOMEM;
-- }
--
-- nghttp2_outbound_item_init(item);
--
-- frame = &item->frame;
--
-- nghttp2_frame_priority_init(&frame->priority, stream_id, ©_pri_spec);
--
-- rv = nghttp2_session_add_item(session, item);
--
-- if (rv != 0) {
-- nghttp2_frame_priority_free(&frame->priority);
-- nghttp2_mem_free(mem, item);
--
-- return rv;
-- }
-+ (void)stream_id;
-+ (void)pri_spec;
-
- return 0;
- }
-@@ -277,7 +185,8 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
- return NGHTTP2_ERR_INVALID_ARGUMENT;
- }
-
-- return nghttp2_session_add_rst_stream(session, stream_id, error_code);
-+ return nghttp2_session_add_rst_stream_continue(
-+ session, stream_id, error_code, /* continue_without_stream = */ 0);
- }
-
- int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
-@@ -578,7 +487,7 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
- return 0;
-
- fail_item_malloc:
-- free(buf);
-+ nghttp2_mem_free(mem, buf);
-
- return rv;
- }
-@@ -661,7 +570,7 @@ int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags,
- return 0;
-
- fail_item_malloc:
-- free(ov_copy);
-+ nghttp2_mem_free(mem, ov_copy);
-
- return rv;
- }
-@@ -733,51 +642,34 @@ int nghttp2_submit_priority_update(nghttp2_session *session, uint8_t flags,
- return 0;
-
- fail_item_malloc:
-- free(buf);
-+ nghttp2_mem_free(mem, buf);
-
- return rv;
- }
-
--static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
-- const nghttp2_data_provider_wrap *dpw) {
-+static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) {
- uint8_t flags = NGHTTP2_FLAG_NONE;
- if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
- flags |= NGHTTP2_FLAG_END_STREAM;
- }
-
-- if (pri_spec) {
-- flags |= NGHTTP2_FLAG_PRIORITY;
-- }
--
- return flags;
- }
-
- static int32_t submit_request_shared(nghttp2_session *session,
-- const nghttp2_priority_spec *pri_spec,
- const nghttp2_nv *nva, size_t nvlen,
- const nghttp2_data_provider_wrap *dpw,
- void *stream_user_data) {
- uint8_t flags;
-- int rv;
-
- if (session->server) {
- return NGHTTP2_ERR_PROTO;
- }
-
-- if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
-- session->remote_settings.no_rfc7540_priorities != 1) {
-- rv = detect_self_dependency(session, -1, pri_spec);
-- if (rv != 0) {
-- return rv;
-- }
-- } else {
-- pri_spec = NULL;
-- }
--
-- flags = set_request_flags(pri_spec, dpw);
-+ flags = set_request_flags(dpw);
-
-- return submit_headers_shared_nva(session, flags, -1, pri_spec, nva, nvlen,
-- dpw, stream_user_data);
-+ return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw,
-+ stream_user_data);
- }
-
- int32_t nghttp2_submit_request(nghttp2_session *session,
-@@ -786,8 +678,9 @@ int32_t nghttp2_submit_request(nghttp2_session *session,
- const nghttp2_data_provider *data_prd,
- void *stream_user_data) {
- nghttp2_data_provider_wrap dpw;
-+ (void)pri_spec;
-
-- return submit_request_shared(session, pri_spec, nva, nvlen,
-+ return submit_request_shared(session, nva, nvlen,
- nghttp2_data_provider_wrap_v1(&dpw, data_prd),
- stream_user_data);
- }
-@@ -798,8 +691,9 @@ int32_t nghttp2_submit_request2(nghttp2_session *session,
- const nghttp2_data_provider2 *data_prd,
- void *stream_user_data) {
- nghttp2_data_provider_wrap dpw;
-+ (void)pri_spec;
-
-- return submit_request_shared(session, pri_spec, nva, nvlen,
-+ return submit_request_shared(session, nva, nvlen,
- nghttp2_data_provider_wrap_v2(&dpw, data_prd),
- stream_user_data);
- }
-@@ -826,8 +720,8 @@ static int submit_response_shared(nghttp2_session *session, int32_t stream_id,
- }
-
- flags = set_response_flags(dpw);
-- return submit_headers_shared_nva(session, flags, stream_id, NULL, nva, nvlen,
-- dpw, NULL);
-+ return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw,
-+ NULL);
- }
-
- int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
-diff --git a/deps/nghttp2/lib/nghttp2_submit.h b/deps/nghttp2/lib/nghttp2_submit.h
-index 350ee022..decf803d 100644
---- a/deps/nghttp2/lib/nghttp2_submit.h
-+++ b/deps/nghttp2/lib/nghttp2_submit.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -37,4 +37,4 @@ int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
- int32_t stream_id,
- const nghttp2_data_provider_wrap *dpw);
-
--#endif /* NGHTTP2_SUBMIT_H */
-+#endif /* !defined(NGHTTP2_SUBMIT_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_time.c b/deps/nghttp2/lib/nghttp2_time.c
-index 148ccfdc..18fd7bca 100644
---- a/deps/nghttp2/lib/nghttp2_time.c
-+++ b/deps/nghttp2/lib/nghttp2_time.c
-@@ -26,7 +26,7 @@
-
- #ifdef HAVE_WINDOWS_H
- # include <windows.h>
--#endif /* HAVE_WINDOWS_H */
-+#endif /* defined(HAVE_WINDOWS_H) */
-
- #include <time.h>
-
-@@ -40,12 +40,11 @@ static uint64_t time_now_sec(void) {
-
- return (uint64_t)t;
- }
--#endif /* !HAVE_GETTICKCOUNT64 || __CYGWIN__ */
-+#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */
-
- #if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__)
- uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
--#elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \
-- HAVE_DECL_CLOCK_MONOTONIC
-+#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
- uint64_t nghttp2_time_now_sec(void) {
- struct timespec tp;
- int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
-@@ -56,8 +55,8 @@ uint64_t nghttp2_time_now_sec(void) {
-
- return (uint64_t)tp.tv_sec;
- }
--#else /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \
-- (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */
-+#else /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \
-+ (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
- uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
--#endif /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \
-- (!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */
-+#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \
-+ (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
-diff --git a/deps/nghttp2/lib/nghttp2_time.h b/deps/nghttp2/lib/nghttp2_time.h
-index 03c0bbe9..a91e62ad 100644
---- a/deps/nghttp2/lib/nghttp2_time.h
-+++ b/deps/nghttp2/lib/nghttp2_time.h
-@@ -27,7 +27,7 @@
-
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-@@ -35,4 +35,4 @@
- timepoint. If it is unable to get seconds, it returns 0. */
- uint64_t nghttp2_time_now_sec(void);
-
--#endif /* NGHTTP2_TIME_H */
-+#endif /* !defined(NGHTTP2_TIME_H) */
-diff --git a/deps/nghttp2/lib/nghttp2_version.c b/deps/nghttp2/lib/nghttp2_version.c
-index 4211f2cf..39a49ff3 100644
---- a/deps/nghttp2/lib/nghttp2_version.c
-+++ b/deps/nghttp2/lib/nghttp2_version.c
-@@ -24,7 +24,7 @@
- */
- #ifdef HAVE_CONFIG_H
- # include <config.h>
--#endif /* HAVE_CONFIG_H */
-+#endif /* defined(HAVE_CONFIG_H) */
-
- #include <nghttp2/nghttp2.h>
-
-diff --git a/deps/nghttp2/lib/sfparse.c b/deps/nghttp2/lib/sfparse.c
-index b5e94cc2..cee089d3 100644
---- a/deps/nghttp2/lib/sfparse.c
-+++ b/deps/nghttp2/lib/sfparse.c
-@@ -30,38 +30,46 @@
- #include <assert.h>
- #include <stdlib.h>
-
--#define SF_STATE_DICT 0x08u
--#define SF_STATE_LIST 0x10u
--#define SF_STATE_ITEM 0x18u
-+#ifdef __AVX2__
-+# include <immintrin.h>
-+#endif /* __AVX2__ */
-
--#define SF_STATE_INNER_LIST 0x04u
-+#define SFPARSE_STATE_DICT 0x08u
-+#define SFPARSE_STATE_LIST 0x10u
-+#define SFPARSE_STATE_ITEM 0x18u
-
--#define SF_STATE_BEFORE 0x00u
--#define SF_STATE_BEFORE_PARAMS 0x01u
--#define SF_STATE_PARAMS 0x02u
--#define SF_STATE_AFTER 0x03u
-+#define SFPARSE_STATE_INNER_LIST 0x04u
-
--#define SF_STATE_OP_MASK 0x03u
-+#define SFPARSE_STATE_BEFORE 0x00u
-+#define SFPARSE_STATE_BEFORE_PARAMS 0x01u
-+#define SFPARSE_STATE_PARAMS 0x02u
-+#define SFPARSE_STATE_AFTER 0x03u
-
--#define SF_SET_STATE_AFTER(NAME) (SF_STATE_##NAME | SF_STATE_AFTER)
--#define SF_SET_STATE_BEFORE_PARAMS(NAME) \
-- (SF_STATE_##NAME | SF_STATE_BEFORE_PARAMS)
--#define SF_SET_STATE_INNER_LIST_BEFORE(NAME) \
-- (SF_STATE_##NAME | SF_STATE_INNER_LIST | SF_STATE_BEFORE)
-+#define SFPARSE_STATE_OP_MASK 0x03u
-
--#define SF_STATE_DICT_AFTER SF_SET_STATE_AFTER(DICT)
--#define SF_STATE_DICT_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(DICT)
--#define SF_STATE_DICT_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(DICT)
-+#define SFPARSE_SET_STATE_AFTER(NAME) \
-+ (SFPARSE_STATE_##NAME | SFPARSE_STATE_AFTER)
-+#define SFPARSE_SET_STATE_BEFORE_PARAMS(NAME) \
-+ (SFPARSE_STATE_##NAME | SFPARSE_STATE_BEFORE_PARAMS)
-+#define SFPARSE_SET_STATE_INNER_LIST_BEFORE(NAME) \
-+ (SFPARSE_STATE_##NAME | SFPARSE_STATE_INNER_LIST | SFPARSE_STATE_BEFORE)
-
--#define SF_STATE_LIST_AFTER SF_SET_STATE_AFTER(LIST)
--#define SF_STATE_LIST_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(LIST)
--#define SF_STATE_LIST_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(LIST)
-+#define SFPARSE_STATE_DICT_AFTER SFPARSE_SET_STATE_AFTER(DICT)
-+#define SFPARSE_STATE_DICT_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(DICT)
-+#define SFPARSE_STATE_DICT_INNER_LIST_BEFORE \
-+ SFPARSE_SET_STATE_INNER_LIST_BEFORE(DICT)
-
--#define SF_STATE_ITEM_AFTER SF_SET_STATE_AFTER(ITEM)
--#define SF_STATE_ITEM_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(ITEM)
--#define SF_STATE_ITEM_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(ITEM)
-+#define SFPARSE_STATE_LIST_AFTER SFPARSE_SET_STATE_AFTER(LIST)
-+#define SFPARSE_STATE_LIST_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(LIST)
-+#define SFPARSE_STATE_LIST_INNER_LIST_BEFORE \
-+ SFPARSE_SET_STATE_INNER_LIST_BEFORE(LIST)
-
--#define SF_STATE_INITIAL 0x00u
-+#define SFPARSE_STATE_ITEM_AFTER SFPARSE_SET_STATE_AFTER(ITEM)
-+#define SFPARSE_STATE_ITEM_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(ITEM)
-+#define SFPARSE_STATE_ITEM_INNER_LIST_BEFORE \
-+ SFPARSE_SET_STATE_INNER_LIST_BEFORE(ITEM)
-+
-+#define SFPARSE_STATE_INITIAL 0x00u
-
- #define DIGIT_CASES \
- case '0': \
-@@ -135,6 +143,70 @@
- UCALPHA_CASES: \
- LCALPHA_CASES
-
-+#define TOKEN_CASES \
-+ case '!': \
-+ case '#': \
-+ case '$': \
-+ case '%': \
-+ case '&': \
-+ case '\'': \
-+ case '*': \
-+ case '+': \
-+ case '-': \
-+ case '.': \
-+ case '/': \
-+ DIGIT_CASES: \
-+ case ':': \
-+ UCALPHA_CASES: \
-+ case '^': \
-+ case '_': \
-+ case '`': \
-+ LCALPHA_CASES: \
-+ case '|': \
-+ case '~'
-+
-+#define LCHEXALPHA_CASES \
-+ case 'a': \
-+ case 'b': \
-+ case 'c': \
-+ case 'd': \
-+ case 'e': \
-+ case 'f'
-+
-+#define X00_1F_CASES \
-+ case 0x00: \
-+ case 0x01: \
-+ case 0x02: \
-+ case 0x03: \
-+ case 0x04: \
-+ case 0x05: \
-+ case 0x06: \
-+ case 0x07: \
-+ case 0x08: \
-+ case 0x09: \
-+ case 0x0a: \
-+ case 0x0b: \
-+ case 0x0c: \
-+ case 0x0d: \
-+ case 0x0e: \
-+ case 0x0f: \
-+ case 0x10: \
-+ case 0x11: \
-+ case 0x12: \
-+ case 0x13: \
-+ case 0x14: \
-+ case 0x15: \
-+ case 0x16: \
-+ case 0x17: \
-+ case 0x18: \
-+ case 0x19: \
-+ case 0x1a: \
-+ case 0x1b: \
-+ case 0x1c: \
-+ case 0x1d: \
-+ case 0x1e: \
-+ case 0x1f
-+
- #define X20_21_CASES \
- case ' ': \
- case '!'
-@@ -175,6 +247,137 @@
- case '}': \
- case '~'
-
-+#define X7F_FF_CASES \
-+ case 0x7f: \
-+ case 0x80: \
-+ case 0x81: \
-+ case 0x82: \
-+ case 0x83: \
-+ case 0x84: \
-+ case 0x85: \
-+ case 0x86: \
-+ case 0x87: \
-+ case 0x88: \
-+ case 0x89: \
-+ case 0x8a: \
-+ case 0x8b: \
-+ case 0x8c: \
-+ case 0x8d: \
-+ case 0x8e: \
-+ case 0x8f: \
-+ case 0x90: \
-+ case 0x91: \
-+ case 0x92: \
-+ case 0x93: \
-+ case 0x94: \
-+ case 0x95: \
-+ case 0x96: \
-+ case 0x97: \
-+ case 0x98: \
-+ case 0x99: \
-+ case 0x9a: \
-+ case 0x9b: \
-+ case 0x9c: \
-+ case 0x9d: \
-+ case 0x9e: \
-+ case 0x9f: \
-+ case 0xa0: \
-+ case 0xa1: \
-+ case 0xa2: \
-+ case 0xa3: \
-+ case 0xa4: \
-+ case 0xa5: \
-+ case 0xa6: \
-+ case 0xa7: \
-+ case 0xa8: \
-+ case 0xa9: \
-+ case 0xaa: \
-+ case 0xab: \
-+ case 0xac: \
-+ case 0xad: \
-+ case 0xae: \
-+ case 0xaf: \
-+ case 0xb0: \
-+ case 0xb1: \
-+ case 0xb2: \
-+ case 0xb3: \
-+ case 0xb4: \
-+ case 0xb5: \
-+ case 0xb6: \
-+ case 0xb7: \
-+ case 0xb8: \
-+ case 0xb9: \
-+ case 0xba: \
-+ case 0xbb: \
-+ case 0xbc: \
-+ case 0xbd: \
-+ case 0xbe: \
-+ case 0xbf: \
-+ case 0xc0: \
-+ case 0xc1: \
-+ case 0xc2: \
-+ case 0xc3: \
-+ case 0xc4: \
-+ case 0xc5: \
-+ case 0xc6: \
-+ case 0xc7: \
-+ case 0xc8: \
-+ case 0xc9: \
-+ case 0xca: \
-+ case 0xcb: \
-+ case 0xcc: \
-+ case 0xcd: \
-+ case 0xce: \
-+ case 0xcf: \
-+ case 0xd0: \
-+ case 0xd1: \
-+ case 0xd2: \
-+ case 0xd3: \
-+ case 0xd4: \
-+ case 0xd5: \
-+ case 0xd6: \
-+ case 0xd7: \
-+ case 0xd8: \
-+ case 0xd9: \
-+ case 0xda: \
-+ case 0xdb: \
-+ case 0xdc: \
-+ case 0xdd: \
-+ case 0xde: \
-+ case 0xdf: \
-+ case 0xe0: \
-+ case 0xe1: \
-+ case 0xe2: \
-+ case 0xe3: \
-+ case 0xe4: \
-+ case 0xe5: \
-+ case 0xe6: \
-+ case 0xe7: \
-+ case 0xe8: \
-+ case 0xe9: \
-+ case 0xea: \
-+ case 0xeb: \
-+ case 0xec: \
-+ case 0xed: \
-+ case 0xee: \
-+ case 0xef: \
-+ case 0xf0: \
-+ case 0xf1: \
-+ case 0xf2: \
-+ case 0xf3: \
-+ case 0xf4: \
-+ case 0xf5: \
-+ case 0xf6: \
-+ case 0xf7: \
-+ case 0xf8: \
-+ case 0xf9: \
-+ case 0xfa: \
-+ case 0xfb: \
-+ case 0xfc: \
-+ case 0xfd: \
-+ case 0xfe: \
-+ case 0xff
-+
- static int is_ws(uint8_t c) {
- switch (c) {
- case ' ':
-@@ -185,40 +388,108 @@ static int is_ws(uint8_t c) {
- }
- }
-
--static int parser_eof(sf_parser *sfp) { return sfp->pos == sfp->end; }
-+#ifdef __AVX2__
-+# ifdef _MSC_VER
-+# include <intrin.h>
-+
-+static int ctz(unsigned int v) {
-+ unsigned long n;
-+
-+ /* Assume that v is not 0. */
-+ _BitScanForward(&n, v);
-+
-+ return (int)n;
-+}
-+# else /* !_MSC_VER */
-+# define ctz __builtin_ctz
-+# endif /* !_MSC_VER */
-+#endif /* __AVX2__ */
-+
-+static int parser_eof(sfparse_parser *sfp) { return sfp->pos == sfp->end; }
-
--static void parser_discard_ows(sf_parser *sfp) {
-+static void parser_discard_ows(sfparse_parser *sfp) {
- for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos)
- ;
- }
-
--static void parser_discard_sp(sf_parser *sfp) {
-+static void parser_discard_sp(sfparse_parser *sfp) {
- for (; !parser_eof(sfp) && *sfp->pos == ' '; ++sfp->pos)
- ;
- }
-
--static void parser_set_op_state(sf_parser *sfp, uint32_t op) {
-- sfp->state &= ~SF_STATE_OP_MASK;
-+static void parser_set_op_state(sfparse_parser *sfp, uint32_t op) {
-+ sfp->state &= ~SFPARSE_STATE_OP_MASK;
- sfp->state |= op;
- }
-
--static void parser_unset_inner_list_state(sf_parser *sfp) {
-- sfp->state &= ~SF_STATE_INNER_LIST;
-+static void parser_unset_inner_list_state(sfparse_parser *sfp) {
-+ sfp->state &= ~SFPARSE_STATE_INNER_LIST;
- }
-
--static int parser_key(sf_parser *sfp, sf_vec *dest) {
-+#ifdef __AVX2__
-+static const uint8_t *find_char_key(const uint8_t *first, const uint8_t *last) {
-+ const __m256i us = _mm256_set1_epi8('_');
-+ const __m256i ds = _mm256_set1_epi8('-');
-+ const __m256i dot = _mm256_set1_epi8('.');
-+ const __m256i ast = _mm256_set1_epi8('*');
-+ const __m256i r0l = _mm256_set1_epi8('0' - 1);
-+ const __m256i r0r = _mm256_set1_epi8('9' + 1);
-+ const __m256i r1l = _mm256_set1_epi8('a' - 1);
-+ const __m256i r1r = _mm256_set1_epi8('z' + 1);
-+ __m256i s, x;
-+ uint32_t m;
-+
-+ for (; first != last; first += 32) {
-+ s = _mm256_loadu_si256((void *)first);
-+
-+ x = _mm256_cmpeq_epi8(s, us);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ds), x);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dot), x);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ast), x);
-+ x = _mm256_or_si256(
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)),
-+ x);
-+ x = _mm256_or_si256(
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)),
-+ x);
-+
-+ m = ~(uint32_t)_mm256_movemask_epi8(x);
-+ if (m) {
-+ return first + ctz(m);
-+ }
-+ }
-+
-+ return last;
-+}
-+#endif /* __AVX2__ */
-+
-+static int parser_key(sfparse_parser *sfp, sfparse_vec *dest) {
- const uint8_t *base;
-+#ifdef __AVX2__
-+ const uint8_t *last;
-+#endif /* __AVX2__ */
-
- switch (*sfp->pos) {
- case '*':
- LCALPHA_CASES:
- break;
- default:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- base = sfp->pos++;
-
-+#ifdef __AVX2__
-+ if (sfp->end - sfp->pos >= 32) {
-+ last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
-+
-+ sfp->pos = find_char_key(sfp->pos, last);
-+ if (sfp->pos != last) {
-+ goto fin;
-+ }
-+ }
-+#endif /* __AVX2__ */
-+
- for (; !parser_eof(sfp); ++sfp->pos) {
- switch (*sfp->pos) {
- case '_':
-@@ -233,6 +504,9 @@ static int parser_key(sf_parser *sfp, sf_vec *dest) {
- break;
- }
-
-+#ifdef __AVX2__
-+fin:
-+#endif /* __AVX2__ */
- if (dest) {
- dest->base = (uint8_t *)base;
- dest->len = (size_t)(sfp->pos - dest->base);
-@@ -241,7 +515,7 @@ static int parser_key(sf_parser *sfp, sf_vec *dest) {
- return 0;
- }
-
--static int parser_number(sf_parser *sfp, sf_value *dest) {
-+static int parser_number(sfparse_parser *sfp, sfparse_value *dest) {
- int sign = 1;
- int64_t value = 0;
- size_t len = 0;
-@@ -250,7 +524,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- if (*sfp->pos == '-') {
- ++sfp->pos;
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- sign = -1;
-@@ -262,7 +536,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- switch (*sfp->pos) {
- DIGIT_CASES:
- if (++len > 15) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- value *= 10;
-@@ -275,13 +549,13 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- }
-
- if (len == 0) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- if (parser_eof(sfp) || *sfp->pos != '.') {
- if (dest) {
-- dest->type = SF_TYPE_INTEGER;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_INTEGER;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- dest->integer = value * sign;
- }
-
-@@ -291,7 +565,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- /* decimal */
-
- if (len > 12) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- fpos = len;
-@@ -302,7 +576,7 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- switch (*sfp->pos) {
- DIGIT_CASES:
- if (++len > 15) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- value *= 10;
-@@ -315,12 +589,12 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- }
-
- if (fpos == len || len - fpos > 3) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- if (dest) {
-- dest->type = SF_TYPE_DECIMAL;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_DECIMAL;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- dest->decimal.numer = value * sign;
-
- switch (len - fpos) {
-@@ -342,9 +616,9 @@ static int parser_number(sf_parser *sfp, sf_value *dest) {
- return 0;
- }
-
--static int parser_date(sf_parser *sfp, sf_value *dest) {
-+static int parser_date(sfparse_parser *sfp, sfparse_value *dest) {
- int rv;
-- sf_value val;
-+ sfparse_value val;
-
- /* The first byte has already been validated by the caller. */
- assert('@' == *sfp->pos);
-@@ -352,7 +626,7 @@ static int parser_date(sf_parser *sfp, sf_value *dest) {
- ++sfp->pos;
-
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- rv = parser_number(sfp, &val);
-@@ -360,27 +634,93 @@ static int parser_date(sf_parser *sfp, sf_value *dest) {
- return rv;
- }
-
-- if (val.type != SF_TYPE_INTEGER) {
-- return SF_ERR_PARSE_ERROR;
-+ if (val.type != SFPARSE_TYPE_INTEGER) {
-+ return SFPARSE_ERR_PARSE;
- }
-
- if (dest) {
- *dest = val;
-- dest->type = SF_TYPE_DATE;
-+ dest->type = SFPARSE_TYPE_DATE;
- }
-
- return 0;
- }
-
--static int parser_string(sf_parser *sfp, sf_value *dest) {
-+#ifdef __AVX2__
-+static const uint8_t *find_char_string(const uint8_t *first,
-+ const uint8_t *last) {
-+ const __m256i bs = _mm256_set1_epi8('\\');
-+ const __m256i dq = _mm256_set1_epi8('"');
-+ const __m256i del = _mm256_set1_epi8(0x7f);
-+ const __m256i sp = _mm256_set1_epi8(' ');
-+ __m256i s, x;
-+ uint32_t m;
-+
-+ for (; first != last; first += 32) {
-+ s = _mm256_loadu_si256((void *)first);
-+
-+ x = _mm256_cmpgt_epi8(sp, s);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, bs), x);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dq), x);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, del), x);
-+
-+ m = (uint32_t)_mm256_movemask_epi8(x);
-+ if (m) {
-+ return first + ctz(m);
-+ }
-+ }
-+
-+ return last;
-+}
-+#endif /* __AVX2__ */
-+
-+static int parser_string(sfparse_parser *sfp, sfparse_value *dest) {
- const uint8_t *base;
-- uint32_t flags = SF_VALUE_FLAG_NONE;
-+#ifdef __AVX2__
-+ const uint8_t *last;
-+#endif /* __AVX2__ */
-+ uint32_t flags = SFPARSE_VALUE_FLAG_NONE;
-
- /* The first byte has already been validated by the caller. */
- assert('"' == *sfp->pos);
-
- base = ++sfp->pos;
-
-+#ifdef __AVX2__
-+ for (; sfp->end - sfp->pos >= 32; ++sfp->pos) {
-+ last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
-+
-+ sfp->pos = find_char_string(sfp->pos, last);
-+ if (sfp->pos == last) {
-+ break;
-+ }
-+
-+ switch (*sfp->pos) {
-+ case '\\':
-+ ++sfp->pos;
-+ if (parser_eof(sfp)) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ switch (*sfp->pos) {
-+ case '"':
-+ case '\\':
-+ flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING;
-+
-+ break;
-+ default:
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ break;
-+ case '"':
-+ goto fin;
-+ default:
-+ return SFPARSE_ERR_PARSE;
-+ }
-+ }
-+#endif /* __AVX2__ */
-+
- for (; !parser_eof(sfp); ++sfp->pos) {
- switch (*sfp->pos) {
- X20_21_CASES:
-@@ -390,75 +730,131 @@ static int parser_string(sf_parser *sfp, sf_value *dest) {
- case '\\':
- ++sfp->pos;
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- switch (*sfp->pos) {
- case '"':
- case '\\':
-- flags = SF_VALUE_FLAG_ESCAPED_STRING;
-+ flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING;
-
- break;
- default:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- break;
- case '"':
-- if (dest) {
-- dest->type = SF_TYPE_STRING;
-- dest->flags = flags;
-- dest->vec.len = (size_t)(sfp->pos - base);
-- dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
-- }
-+ goto fin;
-+ default:
-+ return SFPARSE_ERR_PARSE;
-+ }
-+ }
-
-- ++sfp->pos;
-+ return SFPARSE_ERR_PARSE;
-
-- return 0;
-- default:
-- return SF_ERR_PARSE_ERROR;
-+fin:
-+ if (dest) {
-+ dest->type = SFPARSE_TYPE_STRING;
-+ dest->flags = flags;
-+ dest->vec.len = (size_t)(sfp->pos - base);
-+ dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
-+ }
-+
-+ ++sfp->pos;
-+
-+ return 0;
-+}
-+
-+#ifdef __AVX2__
-+static const uint8_t *find_char_token(const uint8_t *first,
-+ const uint8_t *last) {
-+ /* r0: !..:, excluding "(),
-+ r1: A..Z
-+ r2: ^..~, excluding {} */
-+ const __m256i r0l = _mm256_set1_epi8('!' - 1);
-+ const __m256i r0r = _mm256_set1_epi8(':' + 1);
-+ const __m256i dq = _mm256_set1_epi8('"');
-+ const __m256i prl = _mm256_set1_epi8('(');
-+ const __m256i prr = _mm256_set1_epi8(')');
-+ const __m256i comma = _mm256_set1_epi8(',');
-+ const __m256i r1l = _mm256_set1_epi8('A' - 1);
-+ const __m256i r1r = _mm256_set1_epi8('Z' + 1);
-+ const __m256i r2l = _mm256_set1_epi8('^' - 1);
-+ const __m256i r2r = _mm256_set1_epi8('~' + 1);
-+ const __m256i cbl = _mm256_set1_epi8('{');
-+ const __m256i cbr = _mm256_set1_epi8('}');
-+ __m256i s, x;
-+ uint32_t m;
-+
-+ for (; first != last; first += 32) {
-+ s = _mm256_loadu_si256((void *)first);
-+
-+ x = _mm256_andnot_si256(
-+ _mm256_cmpeq_epi8(s, comma),
-+ _mm256_andnot_si256(
-+ _mm256_cmpeq_epi8(s, prr),
-+ _mm256_andnot_si256(
-+ _mm256_cmpeq_epi8(s, prl),
-+ _mm256_andnot_si256(_mm256_cmpeq_epi8(s, dq),
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l),
-+ _mm256_cmpgt_epi8(r0r, s))))));
-+ x = _mm256_or_si256(
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)),
-+ x);
-+ x = _mm256_or_si256(
-+ _mm256_andnot_si256(
-+ _mm256_cmpeq_epi8(s, cbr),
-+ _mm256_andnot_si256(_mm256_cmpeq_epi8(s, cbl),
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l),
-+ _mm256_cmpgt_epi8(r2r, s)))),
-+ x);
-+
-+ m = ~(uint32_t)_mm256_movemask_epi8(x);
-+ if (m) {
-+ return first + ctz(m);
- }
- }
-
-- return SF_ERR_PARSE_ERROR;
-+ return last;
- }
-+#endif /* __AVX2__ */
-
--static int parser_token(sf_parser *sfp, sf_value *dest) {
-+static int parser_token(sfparse_parser *sfp, sfparse_value *dest) {
- const uint8_t *base;
-+#ifdef __AVX2__
-+ const uint8_t *last;
-+#endif /* __AVX2__ */
-
- /* The first byte has already been validated by the caller. */
- base = sfp->pos++;
-
-+#ifdef __AVX2__
-+ if (sfp->end - sfp->pos >= 32) {
-+ last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
-+
-+ sfp->pos = find_char_token(sfp->pos, last);
-+ if (sfp->pos != last) {
-+ goto fin;
-+ }
-+ }
-+#endif /* __AVX2__ */
-+
- for (; !parser_eof(sfp); ++sfp->pos) {
- switch (*sfp->pos) {
-- case '!':
-- case '#':
-- case '$':
-- case '%':
-- case '&':
-- case '\'':
-- case '*':
-- case '+':
-- case '-':
-- case '.':
-- case '^':
-- case '_':
-- case '`':
-- case '|':
-- case '~':
-- case ':':
-- case '/':
-- DIGIT_CASES:
-- ALPHA_CASES:
-+ TOKEN_CASES:
- continue;
- }
-
- break;
- }
-
-+#ifdef __AVX2__
-+fin:
-+#endif /* __AVX2__ */
- if (dest) {
-- dest->type = SF_TYPE_TOKEN;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_TOKEN;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- dest->vec.base = (uint8_t *)base;
- dest->vec.len = (size_t)(sfp->pos - base);
- }
-@@ -466,14 +862,63 @@ static int parser_token(sf_parser *sfp, sf_value *dest) {
- return 0;
- }
-
--static int parser_byteseq(sf_parser *sfp, sf_value *dest) {
-+#ifdef __AVX2__
-+static const uint8_t *find_char_byteseq(const uint8_t *first,
-+ const uint8_t *last) {
-+ const __m256i pls = _mm256_set1_epi8('+');
-+ const __m256i fs = _mm256_set1_epi8('/');
-+ const __m256i r0l = _mm256_set1_epi8('0' - 1);
-+ const __m256i r0r = _mm256_set1_epi8('9' + 1);
-+ const __m256i r1l = _mm256_set1_epi8('A' - 1);
-+ const __m256i r1r = _mm256_set1_epi8('Z' + 1);
-+ const __m256i r2l = _mm256_set1_epi8('a' - 1);
-+ const __m256i r2r = _mm256_set1_epi8('z' + 1);
-+ __m256i s, x;
-+ uint32_t m;
-+
-+ for (; first != last; first += 32) {
-+ s = _mm256_loadu_si256((void *)first);
-+
-+ x = _mm256_cmpeq_epi8(s, pls);
-+ x = _mm256_or_si256(_mm256_cmpeq_epi8(s, fs), x);
-+ x = _mm256_or_si256(
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)),
-+ x);
-+ x = _mm256_or_si256(
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)),
-+ x);
-+ x = _mm256_or_si256(
-+ _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), _mm256_cmpgt_epi8(r2r, s)),
-+ x);
-+
-+ m = ~(uint32_t)_mm256_movemask_epi8(x);
-+ if (m) {
-+ return first + ctz(m);
-+ }
-+ }
-+
-+ return last;
-+}
-+#endif /* __AVX2__ */
-+
-+static int parser_byteseq(sfparse_parser *sfp, sfparse_value *dest) {
- const uint8_t *base;
-+#ifdef __AVX2__
-+ const uint8_t *last;
-+#endif /* __AVX2__ */
-
- /* The first byte has already been validated by the caller. */
- assert(':' == *sfp->pos);
-
- base = ++sfp->pos;
-
-+#ifdef __AVX2__
-+ if (sfp->end - sfp->pos >= 32) {
-+ last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
-+ sfp->pos = find_char_byteseq(sfp->pos, last);
-+ }
-+#endif /* __AVX2__ */
-+
- for (; !parser_eof(sfp); ++sfp->pos) {
- switch (*sfp->pos) {
- case '+':
-@@ -485,75 +930,47 @@ static int parser_byteseq(sf_parser *sfp, sf_value *dest) {
- switch ((sfp->pos - base) & 0x3) {
- case 0:
- case 1:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- case 2:
-- switch (*(sfp->pos - 1)) {
-- case 'A':
-- case 'Q':
-- case 'g':
-- case 'w':
-- break;
-- default:
-- return SF_ERR_PARSE_ERROR;
-- }
--
- ++sfp->pos;
-
-- if (parser_eof(sfp) || *sfp->pos != '=') {
-- return SF_ERR_PARSE_ERROR;
-+ if (parser_eof(sfp)) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ if (*sfp->pos == '=') {
-+ ++sfp->pos;
- }
-
- break;
- case 3:
-- switch (*(sfp->pos - 1)) {
-- case 'A':
-- case 'E':
-- case 'I':
-- case 'M':
-- case 'Q':
-- case 'U':
-- case 'Y':
-- case 'c':
-- case 'g':
-- case 'k':
-- case 'o':
-- case 's':
-- case 'w':
-- case '0':
-- case '4':
-- case '8':
-- break;
-- default:
-- return SF_ERR_PARSE_ERROR;
-- }
-+ ++sfp->pos;
-
- break;
- }
-
-- ++sfp->pos;
--
- if (parser_eof(sfp) || *sfp->pos != ':') {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- goto fin;
- case ':':
-- if ((sfp->pos - base) & 0x3) {
-- return SF_ERR_PARSE_ERROR;
-+ if (((sfp->pos - base) & 0x3) == 1) {
-+ return SFPARSE_ERR_PARSE;
- }
-
- goto fin;
- default:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
- }
-
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
-
- fin:
- if (dest) {
-- dest->type = SF_TYPE_BYTESEQ;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_BYTESEQ;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- dest->vec.len = (size_t)(sfp->pos - base);
- dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
- }
-@@ -563,7 +980,7 @@ fin:
- return 0;
- }
-
--static int parser_boolean(sf_parser *sfp, sf_value *dest) {
-+static int parser_boolean(sfparse_parser *sfp, sfparse_value *dest) {
- int b;
-
- /* The first byte has already been validated by the caller. */
-@@ -572,7 +989,7 @@ static int parser_boolean(sf_parser *sfp, sf_value *dest) {
- ++sfp->pos;
-
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- switch (*sfp->pos) {
-@@ -585,21 +1002,184 @@ static int parser_boolean(sf_parser *sfp, sf_value *dest) {
-
- break;
- default:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- ++sfp->pos;
-
- if (dest) {
-- dest->type = SF_TYPE_BOOLEAN;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_BOOLEAN;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- dest->boolean = b;
- }
-
- return 0;
- }
-
--static int parser_bare_item(sf_parser *sfp, sf_value *dest) {
-+static int pctdecode(uint8_t *pc, const uint8_t **ppos) {
-+ uint8_t c, b = **ppos;
-+
-+ switch (b) {
-+ DIGIT_CASES:
-+ c = (uint8_t)((b - '0') << 4);
-+
-+ break;
-+ LCHEXALPHA_CASES:
-+ c = (uint8_t)((b - 'a' + 10) << 4);
-+
-+ break;
-+ default:
-+ return -1;
-+ }
-+
-+ b = *++*ppos;
-+
-+ switch (b) {
-+ DIGIT_CASES:
-+ c |= (uint8_t)(b - '0');
-+
-+ break;
-+ LCHEXALPHA_CASES:
-+ c |= (uint8_t)(b - 'a' + 10);
-+
-+ break;
-+ default:
-+ return -1;
-+ }
-+
-+ *pc = c;
-+ ++*ppos;
-+
-+ return 0;
-+}
-+
-+/* Start of utf8 dfa */
-+/* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-+ * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
-+ *
-+ * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
-+ *
-+ * 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.
-+ */
-+#define UTF8_ACCEPT 0
-+#define UTF8_REJECT 12
-+
-+/* clang-format off */
-+static const uint8_t utf8d[] = {
-+ /*
-+ * The first part of the table maps bytes to character classes that
-+ * to reduce the size of the transition table and create bitmasks.
-+ */
-+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-+ 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-+ 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
-+
-+ /*
-+ * The second part is a transition table that maps a combination
-+ * of a state of the automaton and a character class to a state.
-+ */
-+ 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
-+ 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
-+ 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
-+ 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
-+ 12,36,12,12,12,12,12,12,12,12,12,12,
-+};
-+/* clang-format on */
-+
-+static void utf8_decode(uint32_t *state, uint8_t byte) {
-+ *state = utf8d[256 + *state + utf8d[byte]];
-+}
-+
-+/* End of utf8 dfa */
-+
-+static int parser_dispstring(sfparse_parser *sfp, sfparse_value *dest) {
-+ const uint8_t *base;
-+ uint8_t c;
-+ uint32_t utf8state = UTF8_ACCEPT;
-+
-+ assert('%' == *sfp->pos);
-+
-+ ++sfp->pos;
-+
-+ if (parser_eof(sfp) || *sfp->pos != '"') {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ base = ++sfp->pos;
-+
-+ for (; !parser_eof(sfp);) {
-+ switch (*sfp->pos) {
-+ X00_1F_CASES:
-+ X7F_FF_CASES:
-+ return SFPARSE_ERR_PARSE;
-+ case '%':
-+ ++sfp->pos;
-+
-+ if (sfp->pos + 2 > sfp->end) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ if (pctdecode(&c, &sfp->pos) != 0) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ utf8_decode(&utf8state, c);
-+ if (utf8state == UTF8_REJECT) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ break;
-+ case '"':
-+ if (utf8state != UTF8_ACCEPT) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ if (dest) {
-+ dest->type = SFPARSE_TYPE_DISPSTRING;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
-+ dest->vec.len = (size_t)(sfp->pos - base);
-+ dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
-+ }
-+
-+ ++sfp->pos;
-+
-+ return 0;
-+ default:
-+ if (utf8state != UTF8_ACCEPT) {
-+ return SFPARSE_ERR_PARSE;
-+ }
-+
-+ ++sfp->pos;
-+ }
-+ }
-+
-+ return SFPARSE_ERR_PARSE;
-+}
-+
-+static int parser_bare_item(sfparse_parser *sfp, sfparse_value *dest) {
- switch (*sfp->pos) {
- case '"':
- return parser_string(sfp, dest);
-@@ -615,29 +1195,32 @@ static int parser_bare_item(sf_parser *sfp, sf_value *dest) {
- case '*':
- ALPHA_CASES:
- return parser_token(sfp, dest);
-+ case '%':
-+ return parser_dispstring(sfp, dest);
- default:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
- }
-
--static int parser_skip_inner_list(sf_parser *sfp);
-+static int parser_skip_inner_list(sfparse_parser *sfp);
-
--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) {
- int rv;
-
-- switch (sfp->state & SF_STATE_OP_MASK) {
-- case SF_STATE_BEFORE:
-+ switch (sfp->state & SFPARSE_STATE_OP_MASK) {
-+ case SFPARSE_STATE_BEFORE:
- rv = parser_skip_inner_list(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_BEFORE_PARAMS:
-- parser_set_op_state(sfp, SF_STATE_PARAMS);
-+ case SFPARSE_STATE_BEFORE_PARAMS:
-+ parser_set_op_state(sfp, SFPARSE_STATE_PARAMS);
-
- break;
-- case SF_STATE_PARAMS:
-+ case SFPARSE_STATE_PARAMS:
- break;
- default:
- assert(0);
-@@ -645,16 +1228,16 @@ int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) {
- }
-
- if (parser_eof(sfp) || *sfp->pos != ';') {
-- parser_set_op_state(sfp, SF_STATE_AFTER);
-+ parser_set_op_state(sfp, SFPARSE_STATE_AFTER);
-
-- return SF_ERR_EOF;
-+ return SFPARSE_ERR_EOF;
- }
-
- ++sfp->pos;
-
- parser_discard_sp(sfp);
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- rv = parser_key(sfp, dest_key);
-@@ -664,8 +1247,8 @@ int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) {
-
- if (parser_eof(sfp) || *sfp->pos != '=') {
- if (dest_value) {
-- dest_value->type = SF_TYPE_BOOLEAN;
-- dest_value->flags = SF_VALUE_FLAG_NONE;
-+ dest_value->type = SFPARSE_TYPE_BOOLEAN;
-+ dest_value->flags = SFPARSE_VALUE_FLAG_NONE;
- dest_value->boolean = 1;
- }
-
-@@ -675,23 +1258,23 @@ int sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) {
- ++sfp->pos;
-
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- return parser_bare_item(sfp, dest_value);
- }
-
--static int parser_skip_params(sf_parser *sfp) {
-+static int parser_skip_params(sfparse_parser *sfp) {
- int rv;
-
- for (;;) {
-- rv = sf_parser_param(sfp, NULL, NULL);
-+ rv = sfparse_parser_param(sfp, NULL, NULL);
- switch (rv) {
- case 0:
- break;
-- case SF_ERR_EOF:
-+ case SFPARSE_ERR_EOF:
- return 0;
-- case SF_ERR_PARSE_ERROR:
-+ case SFPARSE_ERR_PARSE:
- return rv;
- default:
- assert(0);
-@@ -700,45 +1283,45 @@ static int parser_skip_params(sf_parser *sfp) {
- }
- }
-
--int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) {
-+int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest) {
- int rv;
-
-- switch (sfp->state & SF_STATE_OP_MASK) {
-- case SF_STATE_BEFORE:
-+ switch (sfp->state & SFPARSE_STATE_OP_MASK) {
-+ case SFPARSE_STATE_BEFORE:
- parser_discard_sp(sfp);
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- break;
-- case SF_STATE_BEFORE_PARAMS:
-+ case SFPARSE_STATE_BEFORE_PARAMS:
- rv = parser_skip_params(sfp);
- if (rv != 0) {
- return rv;
- }
-
-- /* Technically, we are entering SF_STATE_AFTER, but we will set
-+ /* Technically, we are entering SFPARSE_STATE_AFTER, but we will set
- another state without reading the state. */
-- /* parser_set_op_state(sfp, SF_STATE_AFTER); */
-+ /* parser_set_op_state(sfp, SFPARSE_STATE_AFTER); */
-
- /* fall through */
-- case SF_STATE_AFTER:
-+ case SFPARSE_STATE_AFTER:
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- switch (*sfp->pos) {
- case ' ':
- parser_discard_sp(sfp);
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- break;
- case ')':
- break;
- default:
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- break;
-@@ -751,9 +1334,9 @@ int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) {
- ++sfp->pos;
-
- parser_unset_inner_list_state(sfp);
-- parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS);
-+ parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS);
-
-- return SF_ERR_EOF;
-+ return SFPARSE_ERR_EOF;
- }
-
- rv = parser_bare_item(sfp, dest);
-@@ -761,22 +1344,22 @@ int sf_parser_inner_list(sf_parser *sfp, sf_value *dest) {
- return rv;
- }
-
-- parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS);
-+ parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS);
-
- return 0;
- }
-
--static int parser_skip_inner_list(sf_parser *sfp) {
-+static int parser_skip_inner_list(sfparse_parser *sfp) {
- int rv;
-
- for (;;) {
-- rv = sf_parser_inner_list(sfp, NULL);
-+ rv = sfparse_parser_inner_list(sfp, NULL);
- switch (rv) {
- case 0:
- break;
-- case SF_ERR_EOF:
-+ case SFPARSE_ERR_EOF:
- return 0;
-- case SF_ERR_PARSE_ERROR:
-+ case SFPARSE_ERR_PARSE:
- return rv;
- default:
- assert(0);
-@@ -785,39 +1368,39 @@ static int parser_skip_inner_list(sf_parser *sfp) {
- }
- }
-
--static int parser_next_key_or_item(sf_parser *sfp) {
-+static int parser_next_key_or_item(sfparse_parser *sfp) {
- parser_discard_ows(sfp);
-
- if (parser_eof(sfp)) {
-- return SF_ERR_EOF;
-+ return SFPARSE_ERR_EOF;
- }
-
- if (*sfp->pos != ',') {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- ++sfp->pos;
-
- parser_discard_ows(sfp);
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- return 0;
- }
-
--static int parser_dict_value(sf_parser *sfp, sf_value *dest) {
-+static int parser_dict_value(sfparse_parser *sfp, sfparse_value *dest) {
- int rv;
-
- if (parser_eof(sfp) || *(sfp->pos) != '=') {
- /* Boolean true */
- if (dest) {
-- dest->type = SF_TYPE_BOOLEAN;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_BOOLEAN;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- dest->boolean = 1;
- }
-
-- sfp->state = SF_STATE_DICT_BEFORE_PARAMS;
-+ sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS;
-
- return 0;
- }
-@@ -825,18 +1408,18 @@ static int parser_dict_value(sf_parser *sfp, sf_value *dest) {
- ++sfp->pos;
-
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- if (*sfp->pos == '(') {
- if (dest) {
-- dest->type = SF_TYPE_INNER_LIST;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_INNER_LIST;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- }
-
- ++sfp->pos;
-
-- sfp->state = SF_STATE_DICT_INNER_LIST_BEFORE;
-+ sfp->state = SFPARSE_STATE_DICT_INNER_LIST_BEFORE;
-
- return 0;
- }
-@@ -846,41 +1429,42 @@ static int parser_dict_value(sf_parser *sfp, sf_value *dest) {
- return rv;
- }
-
-- sfp->state = SF_STATE_DICT_BEFORE_PARAMS;
-+ sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS;
-
- return 0;
- }
-
--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) {
- int rv;
-
- switch (sfp->state) {
-- case SF_STATE_DICT_INNER_LIST_BEFORE:
-+ case SFPARSE_STATE_DICT_INNER_LIST_BEFORE:
- rv = parser_skip_inner_list(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_DICT_BEFORE_PARAMS:
-+ case SFPARSE_STATE_DICT_BEFORE_PARAMS:
- rv = parser_skip_params(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_DICT_AFTER:
-+ case SFPARSE_STATE_DICT_AFTER:
- rv = parser_next_key_or_item(sfp);
- if (rv != 0) {
- return rv;
- }
-
- break;
-- case SF_STATE_INITIAL:
-+ case SFPARSE_STATE_INITIAL:
- parser_discard_sp(sfp);
-
- if (parser_eof(sfp)) {
-- return SF_ERR_EOF;
-+ return SFPARSE_ERR_EOF;
- }
-
- break;
-@@ -897,36 +1481,36 @@ int sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) {
- return parser_dict_value(sfp, dest_value);
- }
-
--int sf_parser_list(sf_parser *sfp, sf_value *dest) {
-+int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest) {
- int rv;
-
- switch (sfp->state) {
-- case SF_STATE_LIST_INNER_LIST_BEFORE:
-+ case SFPARSE_STATE_LIST_INNER_LIST_BEFORE:
- rv = parser_skip_inner_list(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_LIST_BEFORE_PARAMS:
-+ case SFPARSE_STATE_LIST_BEFORE_PARAMS:
- rv = parser_skip_params(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_LIST_AFTER:
-+ case SFPARSE_STATE_LIST_AFTER:
- rv = parser_next_key_or_item(sfp);
- if (rv != 0) {
- return rv;
- }
-
- break;
-- case SF_STATE_INITIAL:
-+ case SFPARSE_STATE_INITIAL:
- parser_discard_sp(sfp);
-
- if (parser_eof(sfp)) {
-- return SF_ERR_EOF;
-+ return SFPARSE_ERR_EOF;
- }
-
- break;
-@@ -937,13 +1521,13 @@ int sf_parser_list(sf_parser *sfp, sf_value *dest) {
-
- if (*sfp->pos == '(') {
- if (dest) {
-- dest->type = SF_TYPE_INNER_LIST;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_INNER_LIST;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- }
-
- ++sfp->pos;
-
-- sfp->state = SF_STATE_LIST_INNER_LIST_BEFORE;
-+ sfp->state = SFPARSE_STATE_LIST_INNER_LIST_BEFORE;
-
- return 0;
- }
-@@ -953,45 +1537,45 @@ int sf_parser_list(sf_parser *sfp, sf_value *dest) {
- return rv;
- }
-
-- sfp->state = SF_STATE_LIST_BEFORE_PARAMS;
-+ sfp->state = SFPARSE_STATE_LIST_BEFORE_PARAMS;
-
- return 0;
- }
-
--int sf_parser_item(sf_parser *sfp, sf_value *dest) {
-+int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest) {
- int rv;
-
- switch (sfp->state) {
-- case SF_STATE_INITIAL:
-+ case SFPARSE_STATE_INITIAL:
- parser_discard_sp(sfp);
-
- if (parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
- break;
-- case SF_STATE_ITEM_INNER_LIST_BEFORE:
-+ case SFPARSE_STATE_ITEM_INNER_LIST_BEFORE:
- rv = parser_skip_inner_list(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_ITEM_BEFORE_PARAMS:
-+ case SFPARSE_STATE_ITEM_BEFORE_PARAMS:
- rv = parser_skip_params(sfp);
- if (rv != 0) {
- return rv;
- }
-
- /* fall through */
-- case SF_STATE_ITEM_AFTER:
-+ case SFPARSE_STATE_ITEM_AFTER:
- parser_discard_sp(sfp);
-
- if (!parser_eof(sfp)) {
-- return SF_ERR_PARSE_ERROR;
-+ return SFPARSE_ERR_PARSE;
- }
-
-- return SF_ERR_EOF;
-+ return SFPARSE_ERR_EOF;
- default:
- assert(0);
- abort();
-@@ -999,13 +1583,13 @@ int sf_parser_item(sf_parser *sfp, sf_value *dest) {
-
- if (*sfp->pos == '(') {
- if (dest) {
-- dest->type = SF_TYPE_INNER_LIST;
-- dest->flags = SF_VALUE_FLAG_NONE;
-+ dest->type = SFPARSE_TYPE_INNER_LIST;
-+ dest->flags = SFPARSE_VALUE_FLAG_NONE;
- }
-
- ++sfp->pos;
-
-- sfp->state = SF_STATE_ITEM_INNER_LIST_BEFORE;
-+ sfp->state = SFPARSE_STATE_ITEM_INNER_LIST_BEFORE;
-
- return 0;
- }
-@@ -1015,12 +1599,13 @@ int sf_parser_item(sf_parser *sfp, sf_value *dest) {
- return rv;
- }
-
-- sfp->state = SF_STATE_ITEM_BEFORE_PARAMS;
-+ sfp->state = SFPARSE_STATE_ITEM_BEFORE_PARAMS;
-
- return 0;
- }
-
--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) {
- if (datalen == 0) {
- sfp->pos = sfp->end = NULL;
- } else {
-@@ -1028,16 +1613,16 @@ void sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen) {
- sfp->end = data + datalen;
- }
-
-- sfp->state = SF_STATE_INITIAL;
-+ sfp->state = SFPARSE_STATE_INITIAL;
- }
-
--void sf_unescape(sf_vec *dest, const sf_vec *src) {
-+void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src) {
- const uint8_t *p, *q;
- uint8_t *o;
- size_t len, slen;
-
- if (src->len == 0) {
-- *dest = *src;
-+ dest->len = 0;
-
- return;
- }
-@@ -1049,16 +1634,12 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) {
- for (;;) {
- q = memchr(p, '\\', len);
- if (q == NULL) {
-- if (len == src->len) {
-- *dest = *src;
--
-- return;
-- }
--
- memcpy(o, p, len);
- o += len;
-
-- break;
-+ dest->len = (size_t)(o - dest->base);
-+
-+ return;
- }
-
- slen = (size_t)(q - p);
-@@ -1069,11 +1650,9 @@ void sf_unescape(sf_vec *dest, const sf_vec *src) {
- *o++ = *p++;
- len -= slen + 2;
- }
--
-- dest->len = (size_t)(o - dest->base);
- }
-
--void sf_base64decode(sf_vec *dest, const sf_vec *src) {
-+void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src) {
- static const int index_tbl[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-@@ -1092,20 +1671,22 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) {
- uint8_t *o;
- const uint8_t *p, *end;
- uint32_t n;
-- size_t i;
-+ size_t i, left;
- int idx;
-
-- assert((src->len & 0x3) == 0);
--
- if (src->len == 0) {
-- *dest = *src;
-+ dest->len = 0;
-
- return;
- }
-
- o = dest->base;
- p = src->base;
-- end = src->base + src->len;
-+ left = src->len & 0x3;
-+ if (left == 0 && src->base[src->len - 1] == '=') {
-+ left = 4;
-+ }
-+ end = src->base + src->len - left;
-
- for (; p != end;) {
- n = 0;
-@@ -1113,33 +1694,94 @@ void sf_base64decode(sf_vec *dest, const sf_vec *src) {
- for (i = 1; i <= 4; ++i, ++p) {
- idx = index_tbl[*p];
-
-- if (idx == -1) {
-- assert(i > 2);
-+ assert(idx != -1);
-
-- if (i == 3) {
-- assert(*p == '=' && *(p + 1) == '=' && p + 2 == end);
-+ n += (uint32_t)(idx << (24 - i * 6));
-+ }
-
-- *o++ = (uint8_t)(n >> 16);
-+ *o++ = (uint8_t)(n >> 16);
-+ *o++ = (n >> 8) & 0xffu;
-+ *o++ = n & 0xffu;
-+ }
-
-- goto fin;
-- }
-+ switch (left) {
-+ case 0:
-+ goto fin;
-+ case 1:
-+ assert(0);
-+ abort();
-+ case 3:
-+ if (src->base[src->len - 1] == '=') {
-+ left = 2;
-+ }
-
-- assert(*p == '=' && p + 1 == end);
-+ break;
-+ case 4:
-+ assert('=' == src->base[src->len - 1]);
-
-- *o++ = (uint8_t)(n >> 16);
-- *o++ = (n >> 8) & 0xffu;
-+ if (src->base[src->len - 2] == '=') {
-+ left = 2;
-+ } else {
-+ left = 3;
-+ }
-
-- goto fin;
-- }
-+ break;
-+ }
-
-- n += (uint32_t)(idx << (24 - i * 6));
-- }
-+ switch (left) {
-+ case 2:
-+ *o = (uint8_t)(index_tbl[*p++] << 2);
-+ *o++ |= (uint8_t)(index_tbl[*p++] >> 4);
-
-- *o++ = (uint8_t)(n >> 16);
-+ break;
-+ case 3:
-+ n = (uint32_t)(index_tbl[*p++] << 10);
-+ n += (uint32_t)(index_tbl[*p++] << 4);
-+ n += (uint32_t)(index_tbl[*p++] >> 2);
- *o++ = (n >> 8) & 0xffu;
- *o++ = n & 0xffu;
-+
-+ break;
- }
-
- fin:
- dest->len = (size_t)(o - dest->base);
- }
-+
-+void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src) {
-+ const uint8_t *p, *q;
-+ uint8_t *o;
-+ size_t len, slen;
-+
-+ if (src->len == 0) {
-+ dest->len = 0;
-+
-+ return;
-+ }
-+
-+ o = dest->base;
-+ p = src->base;
-+ len = src->len;
-+
-+ for (;;) {
-+ q = memchr(p, '%', len);
-+ if (q == NULL) {
-+ memcpy(o, p, len);
-+ o += len;
-+
-+ dest->len = (size_t)(o - dest->base);
-+
-+ return;
-+ }
-+
-+ slen = (size_t)(q - p);
-+ memcpy(o, p, slen);
-+ o += slen;
-+
-+ p = q + 1;
-+
-+ pctdecode(o++, &p);
-+
-+ len -= slen + 3;
-+ }
-+}
-diff --git a/deps/nghttp2/lib/sfparse.h b/deps/nghttp2/lib/sfparse.h
-index 1474db14..9341221a 100644
---- a/deps/nghttp2/lib/sfparse.h
-+++ b/deps/nghttp2/lib/sfparse.h
-@@ -31,86 +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
--} sf_type;
-+ SFPARSE_TYPE_DATE,
-+ /**
-+ * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string 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.
- */
-@@ -119,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.
- */
-@@ -150,260 +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`, or
-- * :enum:`sf_type.SF_TYPE_BYTESEQ`.
-+ * 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`.
- *
-- * If :member:`vec.len <sf_vec.len>` == 0, :member:`vec.base
-- * <sf_vec.base>` is guaranteed to be NULL.
-+ * 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 <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.
-- *
-- * If there is no escape character in |src|, |*src| is assigned to
-- * |*dest|. This includes the case that :member:`src->len
-- * <sf_vec.len>` == 0.
-+ * :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
-- * 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.
-+ * `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.
- *
-- * :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 <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:`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.
- *
-- * If :member:`src->len <sf_vec.len>` == 0, |*src| is assigned to
-- * |*dest|.
-+ * :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);
-+void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src);
-
- #ifdef __cplusplus
- }
--#endif
-+#endif /* defined(__cplusplus) */
-
--#endif /* SFPARSE_H */
-+#endif /* !defined(SFPARSE_H) */
---
-2.53.0
-
diff --git a/nodejs22.spec b/nodejs22.spec
index d34ab7f..ef2debb 100644
--- a/nodejs22.spec
+++ b/nodejs22.spec
@@ -3,7 +3,7 @@
%{load:%{_sourcedir}/nodejs.srpm.macros}
# === Versions of any software shipped in the main nodejs tarball
-%nodejs_define_version node 1:22.22.2-%{autorelease} -p
+%nodejs_define_version node 1:22.23.1-%{autorelease} -p
# Special release for sub-packages with their own version string.
# The complex release string ensures that the subpackage release is always increasing,
@@ -15,44 +15,44 @@
# expect anything between the markers to be overwritten on any update.
# BEGIN automatic-version-macros # DO NOT REMOVE THIS LINE!
-# Version from node-v22.22.2/src/node_version.h
+# Version from node-v22.23.1/src/node_version.h
%global node_soversion 127
-# Version from node-v22.22.2/deps/ada/ada.h
+# Version from node-v22.23.1/deps/ada/ada.h
%nodejs_define_version ada 2.9.2
-# Version from node-v22.22.2/deps/brotli/c/common/version.h
+# Version from node-v22.23.1/deps/brotli/c/common/version.h
%nodejs_define_version brotli 1.1.0
-# Version from node-v22.22.2/deps/cares/include/ares_version.h
+# Version from node-v22.23.1/deps/cares/include/ares_version.h
%nodejs_define_version c_ares 1.34.6
-# Version from node-v22.22.2/deps/histogram/include/hdr/hdr_histogram_version.h
+# Version from node-v22.23.1/deps/histogram/include/hdr/hdr_histogram_version.h
%nodejs_define_version histogram 0.11.9
-# Version from node-v22.22.2/tools/icu/current_ver.dep
+# Version from node-v22.23.1/tools/icu/current_ver.dep
%nodejs_define_version icu 78.2 -p
-# Version from node-v22.22.2/deps/uv/include/uv/version.h
+# Version from node-v22.23.1/deps/uv/include/uv/version.h
%nodejs_define_version libuv 1.51.0
-# Version from node-v22.22.2/deps/llhttp/include/llhttp.h
-%nodejs_define_version llhttp 9.3.0
-# Version from node-v22.22.2/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
-%nodejs_define_version nghttp2 1.68.1
-# Version from node-v22.22.2/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h
+# Version from node-v22.23.1/deps/llhttp/include/llhttp.h
+%nodejs_define_version llhttp 9.4.2
+# Version from node-v22.23.1/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
+%nodejs_define_version nghttp2 1.69.0
+# Version from node-v22.23.1/deps/ngtcp2/nghttp3/lib/includes/nghttp3/version.h
%nodejs_define_version nghttp3 1.6.0
-# Version from node-v22.22.2/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h
+# Version from node-v22.23.1/deps/ngtcp2/ngtcp2/lib/includes/ngtcp2/version.h
%nodejs_define_version ngtcp2 1.11.0
-# Version from node-v22.22.2/deps/cjs-module-lexer/src/package.json
+# Version from node-v22.23.1/deps/cjs-module-lexer/src/package.json
%nodejs_define_version nodejs-cjs-module-lexer 2.2.0
-# Version from node-v22.22.2/lib/punycode.js
+# Version from node-v22.23.1/lib/punycode.js
%nodejs_define_version nodejs-punycode 2.1.0
-# Version from node-v22.22.2/deps/undici/src/package.json
-%nodejs_define_version nodejs-undici 6.24.1
-# Version from node-v22.22.2/deps/npm/package.json
-%nodejs_define_version npm 1:10.9.7-%{nodejs_subpackage_release}
-# Version from node-v22.22.2/deps/sqlite/sqlite3.h
-%nodejs_define_version sqlite 3.51.2
-# Version from node-v22.22.2/deps/uvwasi/include/uvwasi.h
+# Version from node-v22.23.1/deps/undici/src/package.json
+%nodejs_define_version nodejs-undici 6.27.0
+# Version from node-v22.23.1/deps/npm/package.json
+%nodejs_define_version npm 1:10.9.8-%{nodejs_subpackage_release}
+# Version from node-v22.23.1/deps/sqlite/sqlite3.h
+%nodejs_define_version sqlite 3.51.3
+# Version from node-v22.23.1/deps/uvwasi/include/uvwasi.h
%nodejs_define_version uvwasi 0.0.23
-# Version from node-v22.22.2/deps/v8/include/v8-version.h
+# Version from node-v22.23.1/deps/v8/include/v8-version.h
%nodejs_define_version v8 3:12.4.254.21-%{nodejs_subpackage_release} -p
-# Version from node-v22.22.2/deps/zlib/zlib.h
+# Version from node-v22.23.1/deps/zlib/zlib.h
%nodejs_define_version zlib 1.3.1
# END automatic-version-macros # DO NOT REMOVE THIS LINE!
@@ -102,6 +102,7 @@ BuildRequires: python%{python3_pkgversion}-devel
BuildRequires: %{py3_dist setuptools jinja2}
# Additional libraries, either system or vendored ones
BuildRequires: pkgconfig(openssl) >= 3.0.2
+BuildRequires: (pkgconfig(openssl) >= 3.0.2 with pkgconfig(openssl) < 4.0)
%nodejs_declare_bundled -a ada
%nodejs_declare_bundled -a brotli -plibbrotlidec,libbrotlienc
%nodejs_declare_bundled -a c-ares -plibcares
@@ -164,7 +165,6 @@ Source101: nodejs.srpm.macros
%patchlist
0001-Remove-unused-OpenSSL-config.patch
0001-fips-disable-options.patch
-0001-deps-update-nghttp2-to-1.68.1.patch
%description
Node.js is a platform built on Chrome's JavaScript runtime
@@ -296,7 +296,7 @@ Binary symlinks for Node.js Package Manager.
readonly -a devendored_paths=(
deps/v8/third_party/jinja2 tools/inspector_protocol/jinja2
%{?!with_bundled_brotli:deps/brotli}
- %{?!with_bundled_c_ares:deps/cares}
+ #%{?!with_bundled_c_ares:deps/cares}
%{?!with_bundled_libuv:deps/uv}
%{?!with_bundled_nodejs_cjs_module_lexer:deps/cjs-module-lexer}
%{?!with_bundled_nodejs_undici:deps/undici}
@@ -343,7 +343,10 @@ readonly -a configure_flags=(
--openssl-use-def-ca-store
# Link with system libraries where appropriate
%{?!with_bundled_brotli:--shared-brotli}
- %{?!with_bundled_c_ares:--shared-cares}
+ # Switching to bundled c-ares for 22.23.1
+ # Due to:
+ # ../../src/cares_wrap.cc:1730:21: error: no matches converting function ‘Callback’ to type ‘ares_host_callback’
+ #%{?!with_bundled_c_ares:--shared-cares}
%{?!with_bundled_libuv:--shared-libuv}
%{?!with_bundled_sqlite:--shared-sqlite}
%{?!with_bundled_zlib:--shared-zlib}
diff --git a/sources b/sources
index b7cd023..309fda1 100644
--- a/sources
+++ b/sources
@@ -1,4 +1,4 @@
-SHA512 (node-v22.22.2-stripped.tar.gz) = 7eb13fcaaf8aeadfe8135c36a356dede1cd6823f65c4d446f0893326b9d5d3caf6a852a99f04db39a49ae3f6eb3738f932bd2953d97e0680a1c310dfa58ec607
+SHA512 (node-v22.23.1-stripped.tar.gz) = 315b083c9be059ed69658eefcd9b239c9adc6d3f8abfc43cb5be94b1b6e4fdfd0732d2a1127050ad7d2fa9a44faf010c2d38be5a2de80cf70b9d200d5d6a5c14
SHA512 (icu4c-78.2-data-bin-b.zip) = 032a1e519bf92dfa7936ef85ebed697550dbcb4e32c6ecd28ffecb158a403eeff6c0a3545b2551eba73f288e31693be6880e202a38cd86c129dffa395e8ab625
SHA512 (icu4c-78.2-data-bin-l.zip) = c0b46de115332940d3276763904caa6257eb516edce4382632f4b96a5b010fee4cb06a5e10ef5eee2f881515c1ee8277d9ae59015f6de6fe1d175b9d00dbb1ca
SHA512 (packaging-scripts.tar.gz) = 512f21dc653ad841b76851d51a71ba8e8d30e8561d8a745577df9631d19fd4f73609ccb04a81c6c254ea2cf9e2a95df0c4971ed93deb4d6371ba8f8a17aef460
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-20 9:27 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-20 9:27 [rpms/nodejs22] rawhide: Update to version 22.23.1 (rhbz#2477273) tjuhasz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox