public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/nodejs22] f44: Update to version 22.23.1 (rhbz#2477273).
@ 2026-07-21  8:43 tjuhasz
  0 siblings, 0 replies; only message in thread
From: tjuhasz @ 2026-07-21  8:43 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/nodejs22
            Branch : f44
            Commit : a6c2f2b329af0acc4d20e6507c4b3a72de8f5501
            Author : tjuhasz <tjuhasz@redhat.com>
            Date   : 2026-07-20T16:11:49+02:00
            Stats  : +32/-7741 in 3 file(s)
            URL    : https://src.fedoraproject.org/rpms/nodejs22/c/a6c2f2b329af0acc4d20e6507c4b3a72de8f5501?branch=f44

            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(&copy_pri_spec);
--  } else {
--    nghttp2_priority_spec_default_init(&copy_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, &copy_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(&copy_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, &copy_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-21  8:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-21  8:43 [rpms/nodejs22] f44: 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