05b1dd9f72
Resolves: RHEL-12598 Fixes: CVE-2023-44487
5803 lines
186 KiB
Diff
5803 lines
186 KiB
Diff
From 3cdb8a61ff25e4d299d9d47284da5134bc5f1072 Mon Sep 17 00:00:00 2001
|
|
From: rpm-build <rpm-build>
|
|
Date: Thu, 12 Oct 2023 14:18:12 +0200
|
|
Subject: [PATCH] deps(nghttp2): update to 1.57.0
|
|
|
|
Resolves: CVE-2023-44487
|
|
Signed-off-by: rpm-build <rpm-build>
|
|
---
|
|
deps/nghttp2/lib/CMakeLists.txt | 4 +
|
|
deps/nghttp2/lib/Makefile.am | 12 +-
|
|
deps/nghttp2/lib/Makefile.in | 66 +-
|
|
deps/nghttp2/lib/includes/Makefile.in | 26 +-
|
|
deps/nghttp2/lib/includes/config.h | 92 --
|
|
deps/nghttp2/lib/includes/nghttp2/nghttp2.h | 266 +++-
|
|
.../nghttp2/lib/includes/nghttp2/nghttp2ver.h | 4 +-
|
|
deps/nghttp2/lib/nghttp2_extpri.c | 35 +
|
|
deps/nghttp2/lib/nghttp2_extpri.h | 65 +
|
|
deps/nghttp2/lib/nghttp2_frame.c | 122 +-
|
|
deps/nghttp2/lib/nghttp2_frame.h | 95 +-
|
|
deps/nghttp2/lib/nghttp2_hd.c | 5 +
|
|
deps/nghttp2/lib/nghttp2_hd.h | 1 +
|
|
deps/nghttp2/lib/nghttp2_helper.c | 13 +
|
|
deps/nghttp2/lib/nghttp2_http.c | 136 +-
|
|
deps/nghttp2/lib/nghttp2_http.h | 3 +
|
|
deps/nghttp2/lib/nghttp2_map.c | 61 +-
|
|
deps/nghttp2/lib/nghttp2_map.h | 8 +-
|
|
deps/nghttp2/lib/nghttp2_net.h | 12 +-
|
|
deps/nghttp2/lib/nghttp2_option.c | 24 +
|
|
deps/nghttp2/lib/nghttp2_option.h | 16 +
|
|
deps/nghttp2/lib/nghttp2_outbound_item.c | 3 +
|
|
deps/nghttp2/lib/nghttp2_pq.c | 3 +-
|
|
deps/nghttp2/lib/nghttp2_pq.h | 8 +-
|
|
deps/nghttp2/lib/nghttp2_ratelim.c | 75 ++
|
|
deps/nghttp2/lib/nghttp2_ratelim.h | 57 +
|
|
deps/nghttp2/lib/nghttp2_session.c | 870 ++++++++++---
|
|
deps/nghttp2/lib/nghttp2_session.h | 53 +-
|
|
deps/nghttp2/lib/nghttp2_stream.c | 30 +-
|
|
deps/nghttp2/lib/nghttp2_stream.h | 40 +-
|
|
deps/nghttp2/lib/nghttp2_submit.c | 82 +-
|
|
deps/nghttp2/lib/nghttp2_time.c | 62 +
|
|
deps/nghttp2/lib/nghttp2_time.h | 38 +
|
|
deps/nghttp2/lib/sfparse.c | 1146 +++++++++++++++++
|
|
deps/nghttp2/lib/sfparse.h | 409 ++++++
|
|
deps/nghttp2/nghttp2.gyp | 7 +-
|
|
36 files changed, 3477 insertions(+), 472 deletions(-)
|
|
delete mode 100644 deps/nghttp2/lib/includes/config.h
|
|
create mode 100644 deps/nghttp2/lib/nghttp2_extpri.c
|
|
create mode 100644 deps/nghttp2/lib/nghttp2_extpri.h
|
|
create mode 100644 deps/nghttp2/lib/nghttp2_ratelim.c
|
|
create mode 100644 deps/nghttp2/lib/nghttp2_ratelim.h
|
|
create mode 100644 deps/nghttp2/lib/nghttp2_time.c
|
|
create mode 100644 deps/nghttp2/lib/nghttp2_time.h
|
|
create mode 100644 deps/nghttp2/lib/sfparse.c
|
|
create mode 100644 deps/nghttp2/lib/sfparse.h
|
|
|
|
diff --git a/deps/nghttp2/lib/CMakeLists.txt b/deps/nghttp2/lib/CMakeLists.txt
|
|
index 4dc2fcd..7adba3a 100644
|
|
--- a/deps/nghttp2/lib/CMakeLists.txt
|
|
+++ b/deps/nghttp2/lib/CMakeLists.txt
|
|
@@ -23,7 +23,11 @@ set(NGHTTP2_SOURCES
|
|
nghttp2_mem.c
|
|
nghttp2_http.c
|
|
nghttp2_rcbuf.c
|
|
+ nghttp2_extpri.c
|
|
+ nghttp2_ratelim.c
|
|
+ nghttp2_time.c
|
|
nghttp2_debug.c
|
|
+ sfparse.c
|
|
)
|
|
|
|
set(NGHTTP2_RES "")
|
|
diff --git a/deps/nghttp2/lib/Makefile.am b/deps/nghttp2/lib/Makefile.am
|
|
index 1e1f248..c3ace40 100644
|
|
--- a/deps/nghttp2/lib/Makefile.am
|
|
+++ b/deps/nghttp2/lib/Makefile.am
|
|
@@ -50,7 +50,11 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
|
nghttp2_mem.c \
|
|
nghttp2_http.c \
|
|
nghttp2_rcbuf.c \
|
|
- nghttp2_debug.c
|
|
+ nghttp2_extpri.c \
|
|
+ nghttp2_ratelim.c \
|
|
+ nghttp2_time.c \
|
|
+ nghttp2_debug.c \
|
|
+ sfparse.c
|
|
|
|
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
|
nghttp2_frame.h \
|
|
@@ -66,7 +70,11 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
|
nghttp2_mem.h \
|
|
nghttp2_http.h \
|
|
nghttp2_rcbuf.h \
|
|
- nghttp2_debug.h
|
|
+ nghttp2_extpri.h \
|
|
+ nghttp2_ratelim.h \
|
|
+ nghttp2_time.h \
|
|
+ nghttp2_debug.h \
|
|
+ sfparse.h
|
|
|
|
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
|
libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
|
|
diff --git a/deps/nghttp2/lib/Makefile.in b/deps/nghttp2/lib/Makefile.in
|
|
index 5653774..0b95613 100644
|
|
--- a/deps/nghttp2/lib/Makefile.in
|
|
+++ b/deps/nghttp2/lib/Makefile.in
|
|
@@ -1,4 +1,4 @@
|
|
-# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
|
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
|
# @configure_input@
|
|
|
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
|
@@ -107,13 +107,8 @@ host_triplet = @host@
|
|
target_triplet = @target@
|
|
subdir = lib
|
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \
|
|
- $(top_srcdir)/m4/ax_boost_base.m4 \
|
|
- $(top_srcdir)/m4/ax_boost_system.m4 \
|
|
- $(top_srcdir)/m4/ax_boost_thread.m4 \
|
|
- $(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
|
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
|
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
|
|
- $(top_srcdir)/m4/ax_python_devel.m4 \
|
|
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
|
|
@@ -162,7 +157,8 @@ am__objects_2 = nghttp2_pq.lo nghttp2_map.lo nghttp2_queue.lo \
|
|
nghttp2_hd_huffman.lo nghttp2_hd_huffman_data.lo \
|
|
nghttp2_version.lo nghttp2_priority_spec.lo nghttp2_option.lo \
|
|
nghttp2_callbacks.lo nghttp2_mem.lo nghttp2_http.lo \
|
|
- nghttp2_rcbuf.lo nghttp2_debug.lo
|
|
+ nghttp2_rcbuf.lo nghttp2_extpri.lo nghttp2_ratelim.lo \
|
|
+ nghttp2_time.lo nghttp2_debug.lo sfparse.lo
|
|
am_libnghttp2_la_OBJECTS = $(am__objects_1) $(am__objects_2)
|
|
libnghttp2_la_OBJECTS = $(am_libnghttp2_la_OBJECTS)
|
|
AM_V_lt = $(am__v_lt_@AM_V@)
|
|
@@ -189,8 +185,9 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
|
|
am__maybe_remake_depfiles = depfiles
|
|
am__depfiles_remade = ./$(DEPDIR)/nghttp2_buf.Plo \
|
|
./$(DEPDIR)/nghttp2_callbacks.Plo \
|
|
- ./$(DEPDIR)/nghttp2_debug.Plo ./$(DEPDIR)/nghttp2_frame.Plo \
|
|
- ./$(DEPDIR)/nghttp2_hd.Plo ./$(DEPDIR)/nghttp2_hd_huffman.Plo \
|
|
+ ./$(DEPDIR)/nghttp2_debug.Plo ./$(DEPDIR)/nghttp2_extpri.Plo \
|
|
+ ./$(DEPDIR)/nghttp2_frame.Plo ./$(DEPDIR)/nghttp2_hd.Plo \
|
|
+ ./$(DEPDIR)/nghttp2_hd_huffman.Plo \
|
|
./$(DEPDIR)/nghttp2_hd_huffman_data.Plo \
|
|
./$(DEPDIR)/nghttp2_helper.Plo ./$(DEPDIR)/nghttp2_http.Plo \
|
|
./$(DEPDIR)/nghttp2_map.Plo ./$(DEPDIR)/nghttp2_mem.Plo \
|
|
@@ -198,9 +195,11 @@ am__depfiles_remade = ./$(DEPDIR)/nghttp2_buf.Plo \
|
|
./$(DEPDIR)/nghttp2_outbound_item.Plo \
|
|
./$(DEPDIR)/nghttp2_pq.Plo \
|
|
./$(DEPDIR)/nghttp2_priority_spec.Plo \
|
|
- ./$(DEPDIR)/nghttp2_queue.Plo ./$(DEPDIR)/nghttp2_rcbuf.Plo \
|
|
- ./$(DEPDIR)/nghttp2_session.Plo ./$(DEPDIR)/nghttp2_stream.Plo \
|
|
- ./$(DEPDIR)/nghttp2_submit.Plo ./$(DEPDIR)/nghttp2_version.Plo
|
|
+ ./$(DEPDIR)/nghttp2_queue.Plo ./$(DEPDIR)/nghttp2_ratelim.Plo \
|
|
+ ./$(DEPDIR)/nghttp2_rcbuf.Plo ./$(DEPDIR)/nghttp2_session.Plo \
|
|
+ ./$(DEPDIR)/nghttp2_stream.Plo ./$(DEPDIR)/nghttp2_submit.Plo \
|
|
+ ./$(DEPDIR)/nghttp2_time.Plo ./$(DEPDIR)/nghttp2_version.Plo \
|
|
+ ./$(DEPDIR)/sfparse.Plo
|
|
am__mv = mv -f
|
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
|
@@ -299,11 +298,6 @@ AUTOCONF = @AUTOCONF@
|
|
AUTOHEADER = @AUTOHEADER@
|
|
AUTOMAKE = @AUTOMAKE@
|
|
AWK = @AWK@
|
|
-BOOST_ASIO_LIB = @BOOST_ASIO_LIB@
|
|
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
|
|
-BOOST_LDFLAGS = @BOOST_LDFLAGS@
|
|
-BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
|
|
-BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
|
|
BPFCFLAGS = @BPFCFLAGS@
|
|
CC = @CC@
|
|
CCDEPMODE = @CCDEPMODE@
|
|
@@ -320,7 +314,6 @@ CXXCPP = @CXXCPP@
|
|
CXXDEPMODE = @CXXDEPMODE@
|
|
CXXFLAGS = @CXXFLAGS@
|
|
CYGPATH_W = @CYGPATH_W@
|
|
-CYTHON = @CYTHON@
|
|
DEFS = @DEFS@
|
|
DEPDIR = @DEPDIR@
|
|
DLLTOOL = @DLLTOOL@
|
|
@@ -336,6 +329,7 @@ EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
|
|
EXTRACFLAG = @EXTRACFLAG@
|
|
EXTRA_DEFS = @EXTRA_DEFS@
|
|
FGREP = @FGREP@
|
|
+FILECMD = @FILECMD@
|
|
GREP = @GREP@
|
|
HAVE_CXX14 = @HAVE_CXX14@
|
|
INSTALL = @INSTALL@
|
|
@@ -364,8 +358,8 @@ 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_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
|
|
-LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
|
|
+LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS = @LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@
|
|
+LIBNGTCP2_CRYPTO_QUICTLS_LIBS = @LIBNGTCP2_CRYPTO_QUICTLS_LIBS@
|
|
LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
|
|
LIBOBJS = @LIBOBJS@
|
|
LIBS = @LIBS@
|
|
@@ -404,15 +398,9 @@ PKG_CONFIG = @PKG_CONFIG@
|
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
|
PYTHON = @PYTHON@
|
|
-PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
|
|
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
|
|
-PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
|
|
-PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
|
|
-PYTHON_LIBS = @PYTHON_LIBS@
|
|
PYTHON_PLATFORM = @PYTHON_PLATFORM@
|
|
-PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
|
|
PYTHON_PREFIX = @PYTHON_PREFIX@
|
|
-PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
|
|
PYTHON_VERSION = @PYTHON_VERSION@
|
|
RANLIB = @RANLIB@
|
|
SED = @SED@
|
|
@@ -523,7 +511,11 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
|
nghttp2_mem.c \
|
|
nghttp2_http.c \
|
|
nghttp2_rcbuf.c \
|
|
- nghttp2_debug.c
|
|
+ nghttp2_extpri.c \
|
|
+ nghttp2_ratelim.c \
|
|
+ nghttp2_time.c \
|
|
+ nghttp2_debug.c \
|
|
+ sfparse.c
|
|
|
|
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
|
nghttp2_frame.h \
|
|
@@ -539,7 +531,11 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
|
nghttp2_mem.h \
|
|
nghttp2_http.h \
|
|
nghttp2_rcbuf.h \
|
|
- nghttp2_debug.h
|
|
+ nghttp2_extpri.h \
|
|
+ nghttp2_ratelim.h \
|
|
+ nghttp2_time.h \
|
|
+ nghttp2_debug.h \
|
|
+ sfparse.h
|
|
|
|
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
|
libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
|
|
@@ -628,6 +624,7 @@ distclean-compile:
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_buf.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_callbacks.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_debug.Plo@am__quote@ # am--include-marker
|
|
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_extpri.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_frame.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_hd.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_hd_huffman.Plo@am__quote@ # am--include-marker
|
|
@@ -642,11 +639,14 @@ distclean-compile:
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_pq.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_priority_spec.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_queue.Plo@am__quote@ # am--include-marker
|
|
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_ratelim.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_rcbuf.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_session.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_stream.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_submit.Plo@am__quote@ # am--include-marker
|
|
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_time.Plo@am__quote@ # am--include-marker
|
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_version.Plo@am__quote@ # am--include-marker
|
|
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sfparse.Plo@am__quote@ # am--include-marker
|
|
|
|
$(am__depfiles_remade):
|
|
@$(MKDIR_P) $(@D)
|
|
@@ -909,6 +909,7 @@ distclean: distclean-recursive
|
|
-rm -f ./$(DEPDIR)/nghttp2_buf.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_callbacks.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_debug.Plo
|
|
+ -rm -f ./$(DEPDIR)/nghttp2_extpri.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_frame.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_hd.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_hd_huffman.Plo
|
|
@@ -923,11 +924,14 @@ distclean: distclean-recursive
|
|
-rm -f ./$(DEPDIR)/nghttp2_pq.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_priority_spec.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_queue.Plo
|
|
+ -rm -f ./$(DEPDIR)/nghttp2_ratelim.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_rcbuf.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_session.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_stream.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_submit.Plo
|
|
+ -rm -f ./$(DEPDIR)/nghttp2_time.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_version.Plo
|
|
+ -rm -f ./$(DEPDIR)/sfparse.Plo
|
|
-rm -f Makefile
|
|
distclean-am: clean-am distclean-compile distclean-generic \
|
|
distclean-tags
|
|
@@ -976,6 +980,7 @@ maintainer-clean: maintainer-clean-recursive
|
|
-rm -f ./$(DEPDIR)/nghttp2_buf.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_callbacks.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_debug.Plo
|
|
+ -rm -f ./$(DEPDIR)/nghttp2_extpri.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_frame.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_hd.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_hd_huffman.Plo
|
|
@@ -990,11 +995,14 @@ maintainer-clean: maintainer-clean-recursive
|
|
-rm -f ./$(DEPDIR)/nghttp2_pq.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_priority_spec.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_queue.Plo
|
|
+ -rm -f ./$(DEPDIR)/nghttp2_ratelim.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_rcbuf.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_session.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_stream.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_submit.Plo
|
|
+ -rm -f ./$(DEPDIR)/nghttp2_time.Plo
|
|
-rm -f ./$(DEPDIR)/nghttp2_version.Plo
|
|
+ -rm -f ./$(DEPDIR)/sfparse.Plo
|
|
-rm -f Makefile
|
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
|
|
|
diff --git a/deps/nghttp2/lib/includes/Makefile.in b/deps/nghttp2/lib/includes/Makefile.in
|
|
index 327e523..3de90d7 100644
|
|
--- a/deps/nghttp2/lib/includes/Makefile.in
|
|
+++ b/deps/nghttp2/lib/includes/Makefile.in
|
|
@@ -1,4 +1,4 @@
|
|
-# Makefile.in generated by automake 1.16.4 from Makefile.am.
|
|
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
|
|
# @configure_input@
|
|
|
|
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
|
|
@@ -114,13 +114,8 @@ host_triplet = @host@
|
|
target_triplet = @target@
|
|
subdir = lib/includes
|
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
|
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_boost_asio.m4 \
|
|
- $(top_srcdir)/m4/ax_boost_base.m4 \
|
|
- $(top_srcdir)/m4/ax_boost_system.m4 \
|
|
- $(top_srcdir)/m4/ax_boost_thread.m4 \
|
|
- $(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
|
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
|
$(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
|
|
- $(top_srcdir)/m4/ax_python_devel.m4 \
|
|
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
|
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
|
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
|
|
@@ -208,11 +203,6 @@ AUTOCONF = @AUTOCONF@
|
|
AUTOHEADER = @AUTOHEADER@
|
|
AUTOMAKE = @AUTOMAKE@
|
|
AWK = @AWK@
|
|
-BOOST_ASIO_LIB = @BOOST_ASIO_LIB@
|
|
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
|
|
-BOOST_LDFLAGS = @BOOST_LDFLAGS@
|
|
-BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@
|
|
-BOOST_THREAD_LIB = @BOOST_THREAD_LIB@
|
|
BPFCFLAGS = @BPFCFLAGS@
|
|
CC = @CC@
|
|
CCDEPMODE = @CCDEPMODE@
|
|
@@ -229,7 +219,6 @@ CXXCPP = @CXXCPP@
|
|
CXXDEPMODE = @CXXDEPMODE@
|
|
CXXFLAGS = @CXXFLAGS@
|
|
CYGPATH_W = @CYGPATH_W@
|
|
-CYTHON = @CYTHON@
|
|
DEFS = @DEFS@
|
|
DEPDIR = @DEPDIR@
|
|
DLLTOOL = @DLLTOOL@
|
|
@@ -245,6 +234,7 @@ EXTRABPFCFLAGS = @EXTRABPFCFLAGS@
|
|
EXTRACFLAG = @EXTRACFLAG@
|
|
EXTRA_DEFS = @EXTRA_DEFS@
|
|
FGREP = @FGREP@
|
|
+FILECMD = @FILECMD@
|
|
GREP = @GREP@
|
|
HAVE_CXX14 = @HAVE_CXX14@
|
|
INSTALL = @INSTALL@
|
|
@@ -273,8 +263,8 @@ 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_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@
|
|
-LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@
|
|
+LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS = @LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@
|
|
+LIBNGTCP2_CRYPTO_QUICTLS_LIBS = @LIBNGTCP2_CRYPTO_QUICTLS_LIBS@
|
|
LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@
|
|
LIBOBJS = @LIBOBJS@
|
|
LIBS = @LIBS@
|
|
@@ -313,15 +303,9 @@ PKG_CONFIG = @PKG_CONFIG@
|
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
|
PYTHON = @PYTHON@
|
|
-PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@
|
|
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
|
|
-PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@
|
|
-PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@
|
|
-PYTHON_LIBS = @PYTHON_LIBS@
|
|
PYTHON_PLATFORM = @PYTHON_PLATFORM@
|
|
-PYTHON_PLATFORM_SITE_PKG = @PYTHON_PLATFORM_SITE_PKG@
|
|
PYTHON_PREFIX = @PYTHON_PREFIX@
|
|
-PYTHON_SITE_PKG = @PYTHON_SITE_PKG@
|
|
PYTHON_VERSION = @PYTHON_VERSION@
|
|
RANLIB = @RANLIB@
|
|
SED = @SED@
|
|
diff --git a/deps/nghttp2/lib/includes/config.h b/deps/nghttp2/lib/includes/config.h
|
|
deleted file mode 100644
|
|
index 12a816e..0000000
|
|
--- a/deps/nghttp2/lib/includes/config.h
|
|
+++ /dev/null
|
|
@@ -1,92 +0,0 @@
|
|
-/* Hint to the compiler that a function never returns */
|
|
-#define NGHTTP2_NORETURN
|
|
-
|
|
-/* Edited to match src/node.h. */
|
|
-#include <stdint.h>
|
|
-
|
|
-#ifdef _WIN32
|
|
-#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED)
|
|
-typedef intptr_t ssize_t;
|
|
-# define _SSIZE_T_
|
|
-# define _SSIZE_T_DEFINED
|
|
-#endif
|
|
-#else // !_WIN32
|
|
-# include <sys/types.h> // size_t, ssize_t
|
|
-#endif // _WIN32
|
|
-
|
|
-/* Define to 1 if you have the `std::map::emplace`. */
|
|
-#define HAVE_STD_MAP_EMPLACE 1
|
|
-
|
|
-/* Define to 1 if you have `libjansson` library. */
|
|
-/* #undef HAVE_JANSSON */
|
|
-
|
|
-/* Define to 1 if you have `libxml2` library. */
|
|
-/* #undef HAVE_LIBXML2 */
|
|
-
|
|
-/* Define to 1 if you have `spdylay` library. */
|
|
-/* #undef HAVE_SPDYLAY */
|
|
-
|
|
-/* Define to 1 if you have `mruby` library. */
|
|
-/* #undef HAVE_MRUBY */
|
|
-
|
|
-/* Define to 1 if you have `neverbleed` library. */
|
|
-/* #undef HAVE_NEVERBLEED */
|
|
-
|
|
-/* sizeof(int *) */
|
|
-#define SIZEOF_INT_P 4
|
|
-
|
|
-/* sizeof(time_t) */
|
|
-#define SIZEOF_TIME_T 8
|
|
-
|
|
-/* Define to 1 if you have the `_Exit` function. */
|
|
-#define HAVE__EXIT 1
|
|
-
|
|
-/* Define to 1 if you have the `accept4` function. */
|
|
-/* #undef HAVE_ACCEPT4 */
|
|
-
|
|
-/* Define to 1 if you have the `initgroups` function. */
|
|
-#define HAVE_DECL_INITGROUPS 0
|
|
-
|
|
-/* Define to 1 to enable debug output. */
|
|
-/* #undef DEBUGBUILD */
|
|
-
|
|
-/* Define to 1 if you want to disable threads. */
|
|
-/* #undef NOTHREADS */
|
|
-
|
|
-/* Define to 1 if you have the <arpa/inet.h> header file. */
|
|
-#ifndef _WIN32
|
|
-# define HAVE_ARPA_INET_H 1
|
|
-#endif
|
|
-
|
|
-/* Define to 1 if you have the <fcntl.h> header file. */
|
|
-#define HAVE_FCNTL_H 1
|
|
-
|
|
-/* Define to 1 if you have the <inttypes.h> header file. */
|
|
-#define HAVE_INTTYPES_H 1
|
|
-
|
|
-/* Define to 1 if you have the <limits.h> header file. */
|
|
-#define HAVE_LIMITS_H 1
|
|
-
|
|
-/* Define to 1 if you have the <netdb.h> header file. */
|
|
-/* #undef HAVE_NETDB_H */
|
|
-
|
|
-/* Define to 1 if you have the <netinet/in.h> header file. */
|
|
-/* #undef HAVE_NETINET_IN_H */
|
|
-
|
|
-/* Define to 1 if you have the <pwd.h> header file. */
|
|
-/* #undef HAVE_PWD_H */
|
|
-
|
|
-/* Define to 1 if you have the <sys/socket.h> header file. */
|
|
-/* #undef HAVE_SYS_SOCKET_H */
|
|
-
|
|
-/* Define to 1 if you have the <sys/time.h> header file. */
|
|
-/* #undef HAVE_SYS_TIME_H */
|
|
-
|
|
-/* Define to 1 if you have the <syslog.h> header file. */
|
|
-/* #undef HAVE_SYSLOG_H */
|
|
-
|
|
-/* Define to 1 if you have the <time.h> header file. */
|
|
-#define HAVE_TIME_H 1
|
|
-
|
|
-/* Define to 1 if you have the <unistd.h> header file. */
|
|
-/* #undef HAVE_UNISTD_H */
|
|
diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
|
|
index 04321a6..fa22081 100644
|
|
--- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
|
|
+++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h
|
|
@@ -634,7 +634,11 @@ typedef enum {
|
|
* The ORIGIN frame, which is defined by `RFC 8336
|
|
* <https://tools.ietf.org/html/rfc8336>`_.
|
|
*/
|
|
- NGHTTP2_ORIGIN = 0x0c
|
|
+ NGHTTP2_ORIGIN = 0x0c,
|
|
+ /**
|
|
+ * The PRIORITY_UPDATE frame, which is defined by :rfc:`9218`.
|
|
+ */
|
|
+ NGHTTP2_PRIORITY_UPDATE = 0x10
|
|
} nghttp2_frame_type;
|
|
|
|
/**
|
|
@@ -703,7 +707,11 @@ typedef enum {
|
|
* SETTINGS_ENABLE_CONNECT_PROTOCOL
|
|
* (`RFC 8441 <https://tools.ietf.org/html/rfc8441>`_)
|
|
*/
|
|
- NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08
|
|
+ NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08,
|
|
+ /**
|
|
+ * SETTINGS_NO_RFC7540_PRIORITIES (:rfc:`9218`)
|
|
+ */
|
|
+ NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES = 0x09
|
|
} nghttp2_settings_id;
|
|
/* Note: If we add SETTINGS, update the capacity of
|
|
NGHTTP2_INBOUND_NUM_IV as well */
|
|
@@ -1422,12 +1430,6 @@ typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf,
|
|
* respectively. The header name/value pairs are emitted via
|
|
* :type:`nghttp2_on_header_callback`.
|
|
*
|
|
- * For HEADERS, PUSH_PROMISE and DATA frames, this callback may be
|
|
- * called after stream is closed (see
|
|
- * :type:`nghttp2_on_stream_close_callback`). The application should
|
|
- * check that stream is still alive using its own stream management or
|
|
- * :func:`nghttp2_session_get_stream_user_data()`.
|
|
- *
|
|
* Only HEADERS and DATA frame can signal the end of incoming data.
|
|
* If ``frame->hd.flags & NGHTTP2_FLAG_END_STREAM`` is nonzero, the
|
|
* |frame| is the last frame from the remote peer in this stream.
|
|
@@ -2693,6 +2695,11 @@ nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
|
|
* 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.
|
|
+ *
|
|
+ * 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.
|
|
*/
|
|
NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
|
|
int val);
|
|
@@ -2719,6 +2726,53 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_outbound_ack(nghttp2_option *option,
|
|
NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
|
|
size_t val);
|
|
|
|
+/**
|
|
+ * @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.
|
|
+ *
|
|
+ * Client session ignores this option.
|
|
+ */
|
|
+NGHTTP2_EXTERN void
|
|
+nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option,
|
|
+ int val);
|
|
+
|
|
+/**
|
|
+ * @function
|
|
+ *
|
|
+ * This option, if set to nonzero, turns off RFC 9113 leading and
|
|
+ * trailing white spaces validation against HTTP field value. Some
|
|
+ * important fields, such as HTTP/2 pseudo header fields, are
|
|
+ * validated more strictly and this option does not apply to them.
|
|
+ */
|
|
+NGHTTP2_EXTERN void
|
|
+nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
|
|
+ nghttp2_option *option, int val);
|
|
+
|
|
+/**
|
|
+ * @function
|
|
+ *
|
|
+ * This function sets the rate limit for the incoming stream reset
|
|
+ * (RST_STREAM frame). It is server use only. 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. An incoming RST_STREAM consumes one token.
|
|
+ * 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_stream_reset_rate_limit(nghttp2_option *option,
|
|
+ uint64_t burst, uint64_t rate);
|
|
+
|
|
/**
|
|
* @function
|
|
*
|
|
@@ -3589,6 +3643,11 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session,
|
|
* 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:
|
|
*
|
|
@@ -3632,6 +3691,11 @@ nghttp2_session_change_stream_priority(nghttp2_session *session,
|
|
* 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:
|
|
*
|
|
@@ -3837,6 +3901,11 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
|
|
* :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 |nva| is an array of name/value pair :type:`nghttp2_nv` with
|
|
* |nvlen| elements. The application is responsible to include
|
|
* required pseudo-header fields (header field whose name starts with
|
|
@@ -4057,6 +4126,11 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
|
|
* :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 |nva| is an array of name/value pair :type:`nghttp2_nv` with
|
|
* |nvlen| elements. The application is responsible to include
|
|
* required pseudo-header fields (header field whose name starts with
|
|
@@ -4184,6 +4258,11 @@ NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
|
|
* :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:
|
|
*
|
|
@@ -4198,6 +4277,61 @@ nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
|
|
int32_t stream_id,
|
|
const nghttp2_priority_spec *pri_spec);
|
|
|
|
+/**
|
|
+ * @macro
|
|
+ *
|
|
+ * :macro:`NGHTTP2_EXTPRI_DEFAULT_URGENCY` is the default urgency
|
|
+ * level for :rfc:`9218` extensible priorities.
|
|
+ */
|
|
+#define NGHTTP2_EXTPRI_DEFAULT_URGENCY 3
|
|
+
|
|
+/**
|
|
+ * @macro
|
|
+ *
|
|
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_HIGH` is the highest urgency level
|
|
+ * for :rfc:`9218` extensible priorities.
|
|
+ */
|
|
+#define NGHTTP2_EXTPRI_URGENCY_HIGH 0
|
|
+
|
|
+/**
|
|
+ * @macro
|
|
+ *
|
|
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_LOW` is the lowest urgency level for
|
|
+ * :rfc:`9218` extensible priorities.
|
|
+ */
|
|
+#define NGHTTP2_EXTPRI_URGENCY_LOW 7
|
|
+
|
|
+/**
|
|
+ * @macro
|
|
+ *
|
|
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_LEVELS` is the number of urgency
|
|
+ * levels for :rfc:`9218` extensible priorities.
|
|
+ */
|
|
+#define NGHTTP2_EXTPRI_URGENCY_LEVELS (NGHTTP2_EXTPRI_URGENCY_LOW + 1)
|
|
+
|
|
+/**
|
|
+ * @struct
|
|
+ *
|
|
+ * :type:`nghttp2_extpri` is :rfc:`9218` extensible priorities
|
|
+ * specification for a stream.
|
|
+ */
|
|
+typedef struct nghttp2_extpri {
|
|
+ /**
|
|
+ * :member:`urgency` is the urgency of a stream, it must be in
|
|
+ * [:macro:`NGHTTP2_EXTPRI_URGENCY_HIGH`,
|
|
+ * :macro:`NGHTTP2_EXTPRI_URGENCY_LOW`], inclusive, and 0 is the
|
|
+ * highest urgency.
|
|
+ */
|
|
+ uint32_t urgency;
|
|
+ /**
|
|
+ * :member:`inc` indicates that a content can be processed
|
|
+ * incrementally or not. If inc is 0, it cannot be processed
|
|
+ * incrementally. If inc is 1, it can be processed incrementally.
|
|
+ * Other value is not permitted.
|
|
+ */
|
|
+ int inc;
|
|
+} nghttp2_extpri;
|
|
+
|
|
/**
|
|
* @function
|
|
*
|
|
@@ -4722,6 +4856,108 @@ NGHTTP2_EXTERN int nghttp2_submit_origin(nghttp2_session *session,
|
|
const nghttp2_origin_entry *ov,
|
|
size_t nov);
|
|
|
|
+/**
|
|
+ * @struct
|
|
+ *
|
|
+ * The payload of PRIORITY_UPDATE frame. PRIORITY_UPDATE frame is a
|
|
+ * non-critical extension to HTTP/2. If this frame is received, and
|
|
+ * `nghttp2_option_set_user_recv_extension_type()` is not set, and
|
|
+ * `nghttp2_option_set_builtin_recv_extension_type()` is set for
|
|
+ * :enum:`nghttp2_frame_type.NGHTTP2_PRIORITY_UPDATE`,
|
|
+ * ``nghttp2_extension.payload`` will point to this struct.
|
|
+ *
|
|
+ * It has the following members:
|
|
+ */
|
|
+typedef struct {
|
|
+ /**
|
|
+ * The stream ID of the stream whose priority is updated.
|
|
+ */
|
|
+ int32_t stream_id;
|
|
+ /**
|
|
+ * The pointer to Priority field value. It is not necessarily
|
|
+ * NULL-terminated.
|
|
+ */
|
|
+ uint8_t *field_value;
|
|
+ /**
|
|
+ * The length of the :member:`field_value`.
|
|
+ */
|
|
+ size_t field_value_len;
|
|
+} nghttp2_ext_priority_update;
|
|
+
|
|
+/**
|
|
+ * @function
|
|
+ *
|
|
+ * Submits PRIORITY_UPDATE frame.
|
|
+ *
|
|
+ * PRIORITY_UPDATE frame is a non-critical extension to HTTP/2, and
|
|
+ * defined in :rfc:`9218#section-7.1`.
|
|
+ *
|
|
+ * The |flags| is currently ignored and should be
|
|
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`.
|
|
+ *
|
|
+ * The |stream_id| is the ID of stream which is prioritized. The
|
|
+ * |field_value| points to the Priority field value. The
|
|
+ * |field_value_len| is the length of the Priority field value.
|
|
+ *
|
|
+ * If this function is called by server,
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` is returned.
|
|
+ *
|
|
+ * If
|
|
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
|
|
+ * of value of 0 is received by a remote endpoint (or it is omitted),
|
|
+ * this function does nothing and returns 0.
|
|
+ *
|
|
+ * This function returns 0 if it succeeds, or one of the following
|
|
+ * negative error codes:
|
|
+ *
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
|
|
+ * Out of memory
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
|
|
+ * The function is called from server side session
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
|
|
+ * The |field_value_len| is larger than 16380; or |stream_id| is
|
|
+ * 0.
|
|
+ */
|
|
+NGHTTP2_EXTERN int nghttp2_submit_priority_update(nghttp2_session *session,
|
|
+ uint8_t flags,
|
|
+ int32_t stream_id,
|
|
+ const uint8_t *field_value,
|
|
+ size_t field_value_len);
|
|
+
|
|
+/**
|
|
+ * @function
|
|
+ *
|
|
+ * Changes the priority of the existing stream denoted by |stream_id|.
|
|
+ * The new priority is |extpri|. This function is meant to be used by
|
|
+ * server for :rfc:`9218` extensible prioritization scheme.
|
|
+ *
|
|
+ * If |session| is initialized as client, this function returns
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. For client, use
|
|
+ * `nghttp2_submit_priority_update()` instead.
|
|
+ *
|
|
+ * If :member:`extpri->urgency <nghttp2_extpri.urgency>` is out of
|
|
+ * bound, it is set to :macro:`NGHTTP2_EXTPRI_URGENCY_LOW`.
|
|
+ *
|
|
+ * If |ignore_client_signal| is nonzero, server starts to ignore
|
|
+ * client priority signals for this stream.
|
|
+ *
|
|
+ * If
|
|
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
|
|
+ * of value of 1 is not submitted via `nghttp2_submit_settings()`,
|
|
+ * this function does nothing and returns 0.
|
|
+ *
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
|
|
+ * Out of memory.
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
|
|
+ * The |session| is initialized as client.
|
|
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
|
|
+ * |stream_id| is zero; or a stream denoted by |stream_id| is not
|
|
+ * found.
|
|
+ */
|
|
+NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority(
|
|
+ nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri,
|
|
+ int ignore_client_signal);
|
|
+
|
|
/**
|
|
* @function
|
|
*
|
|
@@ -4833,9 +5069,23 @@ NGHTTP2_EXTERN int nghttp2_check_header_name(const uint8_t *name, size_t len);
|
|
* Returns nonzero if HTTP header field value |value| of length |len|
|
|
* is valid according to
|
|
* http://tools.ietf.org/html/rfc7230#section-3.2
|
|
+ *
|
|
+ * This function is considered obsolete, and application should
|
|
+ * consider to use `nghttp2_check_header_value_rfc9113()` instead.
|
|
*/
|
|
NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len);
|
|
|
|
+/**
|
|
+ * @function
|
|
+ *
|
|
+ * Returns nonzero if HTTP header field value |value| of length |len|
|
|
+ * is valid according to
|
|
+ * http://tools.ietf.org/html/rfc7230#section-3.2, plus
|
|
+ * https://datatracker.ietf.org/doc/html/rfc9113#section-8.2.1
|
|
+ */
|
|
+NGHTTP2_EXTERN int nghttp2_check_header_value_rfc9113(const uint8_t *value,
|
|
+ size_t len);
|
|
+
|
|
/**
|
|
* @function
|
|
*
|
|
diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h
|
|
index c608251..f56954e 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.47.0"
|
|
+#define NGHTTP2_VERSION "1.57.0"
|
|
|
|
/**
|
|
* @macro
|
|
@@ -37,6 +37,6 @@
|
|
* release. This is a 24 bit number with 8 bits for major number, 8 bits
|
|
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
|
|
*/
|
|
-#define NGHTTP2_VERSION_NUM 0x012f00
|
|
+#define NGHTTP2_VERSION_NUM 0x013900
|
|
|
|
#endif /* NGHTTP2VER_H */
|
|
diff --git a/deps/nghttp2/lib/nghttp2_extpri.c b/deps/nghttp2/lib/nghttp2_extpri.c
|
|
new file mode 100644
|
|
index 0000000..3fd9b78
|
|
--- /dev/null
|
|
+++ b/deps/nghttp2/lib/nghttp2_extpri.c
|
|
@@ -0,0 +1,35 @@
|
|
+/*
|
|
+ * nghttp2 - HTTP/2 C Library
|
|
+ *
|
|
+ * Copyright (c) 2022 nghttp3 contributors
|
|
+ * Copyright (c) 2022 nghttp2 contributors
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be
|
|
+ * included in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+#include "nghttp2_extpri.h"
|
|
+
|
|
+uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri) {
|
|
+ return (uint8_t)((uint32_t)extpri->inc << 7 | extpri->urgency);
|
|
+}
|
|
+
|
|
+void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri) {
|
|
+ extpri->urgency = nghttp2_extpri_uint8_urgency(u8extpri);
|
|
+ extpri->inc = nghttp2_extpri_uint8_inc(u8extpri);
|
|
+}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_extpri.h b/deps/nghttp2/lib/nghttp2_extpri.h
|
|
new file mode 100644
|
|
index 0000000..23c6ddc
|
|
--- /dev/null
|
|
+++ b/deps/nghttp2/lib/nghttp2_extpri.h
|
|
@@ -0,0 +1,65 @@
|
|
+/*
|
|
+ * nghttp2 - HTTP/2 C Library
|
|
+ *
|
|
+ * Copyright (c) 2022 nghttp3 contributors
|
|
+ * Copyright (c) 2022 nghttp2 contributors
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be
|
|
+ * included in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+#ifndef NGHTTP2_EXTPRI_H
|
|
+#define NGHTTP2_EXTPRI_H
|
|
+
|
|
+#ifdef HAVE_CONFIG_H
|
|
+# include <config.h>
|
|
+#endif /* HAVE_CONFIG_H */
|
|
+
|
|
+#include <nghttp2/nghttp2.h>
|
|
+
|
|
+/*
|
|
+ * NGHTTP2_EXTPRI_INC_MASK is a bit mask to retrieve incremental bit
|
|
+ * from a value produced by nghttp2_extpri_to_uint8.
|
|
+ */
|
|
+#define NGHTTP2_EXTPRI_INC_MASK (1 << 7)
|
|
+
|
|
+/*
|
|
+ * nghttp2_extpri_to_uint8 encodes |pri| into uint8_t variable.
|
|
+ */
|
|
+uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri);
|
|
+
|
|
+/*
|
|
+ * nghttp2_extpri_from_uint8 decodes |u8extpri|, which is produced by
|
|
+ * nghttp2_extpri_to_uint8, intto |extpri|.
|
|
+ */
|
|
+void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri);
|
|
+
|
|
+/*
|
|
+ * nghttp2_extpri_uint8_urgency extracts urgency from |PRI| which is
|
|
+ * supposed to be constructed by nghttp2_extpri_to_uint8.
|
|
+ */
|
|
+#define nghttp2_extpri_uint8_urgency(PRI) \
|
|
+ ((uint32_t)((PRI) & ~NGHTTP2_EXTPRI_INC_MASK))
|
|
+
|
|
+/*
|
|
+ * nghttp2_extpri_uint8_inc extracts inc from |PRI| which is supposed to
|
|
+ * be constructed by nghttp2_extpri_to_uint8.
|
|
+ */
|
|
+#define nghttp2_extpri_uint8_inc(PRI) (((PRI)&NGHTTP2_EXTPRI_INC_MASK) != 0)
|
|
+
|
|
+#endif /* NGHTTP2_EXTPRI_H */
|
|
diff --git a/deps/nghttp2/lib/nghttp2_frame.c b/deps/nghttp2/lib/nghttp2_frame.c
|
|
index 3648b23..77cb463 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_frame.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_frame.c
|
|
@@ -253,6 +253,31 @@ void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem) {
|
|
nghttp2_mem_free(mem, origin->ov);
|
|
}
|
|
|
|
+void nghttp2_frame_priority_update_init(nghttp2_extension *frame,
|
|
+ int32_t stream_id, uint8_t *field_value,
|
|
+ size_t field_value_len) {
|
|
+ nghttp2_ext_priority_update *priority_update;
|
|
+
|
|
+ nghttp2_frame_hd_init(&frame->hd, 4 + field_value_len,
|
|
+ NGHTTP2_PRIORITY_UPDATE, NGHTTP2_FLAG_NONE, 0);
|
|
+
|
|
+ priority_update = frame->payload;
|
|
+ priority_update->stream_id = stream_id;
|
|
+ priority_update->field_value = field_value;
|
|
+ priority_update->field_value_len = field_value_len;
|
|
+}
|
|
+
|
|
+void nghttp2_frame_priority_update_free(nghttp2_extension *frame,
|
|
+ nghttp2_mem *mem) {
|
|
+ nghttp2_ext_priority_update *priority_update;
|
|
+
|
|
+ priority_update = frame->payload;
|
|
+ if (priority_update == NULL) {
|
|
+ return;
|
|
+ }
|
|
+ nghttp2_mem_free(mem, priority_update->field_value);
|
|
+}
|
|
+
|
|
size_t nghttp2_frame_priority_len(uint8_t flags) {
|
|
if (flags & NGHTTP2_FLAG_PRIORITY) {
|
|
return NGHTTP2_PRIORITY_SPECLEN;
|
|
@@ -393,8 +418,8 @@ void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
|
|
nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive);
|
|
}
|
|
|
|
-int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
|
- const uint8_t *payload) {
|
|
+void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
|
+ const uint8_t *payload) {
|
|
if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
|
|
nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
|
|
} else {
|
|
@@ -403,11 +428,9 @@ int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
|
|
|
frame->nva = NULL;
|
|
frame->nvlen = 0;
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
-int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
|
|
+void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
|
|
nghttp2_buf *buf;
|
|
|
|
assert(bufs->head == bufs->cur);
|
|
@@ -423,8 +446,6 @@ int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
|
|
nghttp2_frame_pack_priority_spec(buf->last, &frame->pri_spec);
|
|
|
|
buf->last += NGHTTP2_PRIORITY_SPECLEN;
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
|
|
@@ -432,8 +453,8 @@ void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
|
|
nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
|
|
}
|
|
|
|
-int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
|
- nghttp2_rst_stream *frame) {
|
|
+void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
|
+ nghttp2_rst_stream *frame) {
|
|
nghttp2_buf *buf;
|
|
|
|
assert(bufs->head == bufs->cur);
|
|
@@ -448,8 +469,6 @@ int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
|
|
|
nghttp2_put_uint32be(buf->last, frame->error_code);
|
|
buf->last += 4;
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
|
|
@@ -567,16 +586,15 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
|
|
return frame_pack_headers_shared(bufs, &frame->hd);
|
|
}
|
|
|
|
-int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
|
- const uint8_t *payload) {
|
|
+void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
|
+ const uint8_t *payload) {
|
|
frame->promised_stream_id =
|
|
nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
|
|
frame->nva = NULL;
|
|
frame->nvlen = 0;
|
|
- return 0;
|
|
}
|
|
|
|
-int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
|
|
+void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
|
|
nghttp2_buf *buf;
|
|
|
|
assert(bufs->head == bufs->cur);
|
|
@@ -591,8 +609,6 @@ int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
|
|
|
|
buf->last =
|
|
nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data));
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
|
|
@@ -672,8 +688,8 @@ int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
|
|
return 0;
|
|
}
|
|
|
|
-int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
|
- nghttp2_window_update *frame) {
|
|
+void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
|
+ nghttp2_window_update *frame) {
|
|
nghttp2_buf *buf;
|
|
|
|
assert(bufs->head == bufs->cur);
|
|
@@ -688,8 +704,6 @@ int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
|
|
|
nghttp2_put_uint32be(buf->last, (uint32_t)frame->window_size_increment);
|
|
buf->last += 4;
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
|
@@ -698,7 +712,7 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
|
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
|
}
|
|
|
|
-int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
|
|
+void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
|
|
int rv;
|
|
nghttp2_buf *buf;
|
|
nghttp2_ext_altsvc *altsvc;
|
|
@@ -727,8 +741,6 @@ int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
|
|
rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
|
|
|
|
assert(rv == 0);
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
|
@@ -876,6 +888,55 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
|
|
return 0;
|
|
}
|
|
|
|
+void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
|
|
+ nghttp2_extension *frame) {
|
|
+ int rv;
|
|
+ nghttp2_buf *buf;
|
|
+ nghttp2_ext_priority_update *priority_update;
|
|
+
|
|
+ /* This is required with --disable-assert. */
|
|
+ (void)rv;
|
|
+
|
|
+ priority_update = frame->payload;
|
|
+
|
|
+ buf = &bufs->head->buf;
|
|
+
|
|
+ assert(nghttp2_buf_avail(buf) >= 4 + priority_update->field_value_len);
|
|
+
|
|
+ buf->pos -= NGHTTP2_FRAME_HDLEN;
|
|
+
|
|
+ nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
|
|
+
|
|
+ nghttp2_put_uint32be(buf->last, (uint32_t)priority_update->stream_id);
|
|
+ buf->last += 4;
|
|
+
|
|
+ rv = nghttp2_bufs_add(bufs, priority_update->field_value,
|
|
+ priority_update->field_value_len);
|
|
+
|
|
+ assert(rv == 0);
|
|
+}
|
|
+
|
|
+void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
|
|
+ uint8_t *payload,
|
|
+ size_t payloadlen) {
|
|
+ nghttp2_ext_priority_update *priority_update;
|
|
+
|
|
+ assert(payloadlen >= 4);
|
|
+
|
|
+ priority_update = frame->payload;
|
|
+
|
|
+ priority_update->stream_id =
|
|
+ nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
|
|
+
|
|
+ if (payloadlen > 4) {
|
|
+ priority_update->field_value = payload + 4;
|
|
+ priority_update->field_value_len = payloadlen - 4;
|
|
+ } else {
|
|
+ priority_update->field_value = NULL;
|
|
+ priority_update->field_value_len = 0;
|
|
+ }
|
|
+}
|
|
+
|
|
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
|
size_t niv, nghttp2_mem *mem) {
|
|
nghttp2_settings_entry *iv_copy;
|
|
@@ -1071,6 +1132,11 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) {
|
|
return 0;
|
|
}
|
|
break;
|
|
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
|
|
+ if (iv[i].value != 0 && iv[i].value != 1) {
|
|
+ return 0;
|
|
+ }
|
|
+ break;
|
|
}
|
|
}
|
|
return 1;
|
|
@@ -1105,14 +1171,14 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
|
|
buf->last += trail_padlen;
|
|
}
|
|
|
|
-int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|
- size_t padlen, int framehd_only) {
|
|
+void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|
+ size_t padlen, int framehd_only) {
|
|
nghttp2_buf *buf;
|
|
|
|
if (padlen == 0) {
|
|
DEBUGF("send: padlen = 0, nothing to do\n");
|
|
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
|
|
/*
|
|
@@ -1145,6 +1211,4 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|
hd->flags |= NGHTTP2_FLAG_PADDED;
|
|
|
|
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
|
|
-
|
|
- return 0;
|
|
}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_frame.h b/deps/nghttp2/lib/nghttp2_frame.h
|
|
index 3859926..d586688 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_frame.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_frame.h
|
|
@@ -73,6 +73,7 @@
|
|
typedef union {
|
|
nghttp2_ext_altsvc altsvc;
|
|
nghttp2_ext_origin origin;
|
|
+ nghttp2_ext_priority_update priority_update;
|
|
} nghttp2_ext_frame_payload;
|
|
|
|
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
|
|
@@ -142,11 +143,9 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame,
|
|
* Unpacks HEADERS frame byte sequence into |frame|. This function
|
|
* only unapcks bytes that come before name/value header block and
|
|
* after possible Pad Length field.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
-int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
|
- const uint8_t *payload);
|
|
+void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
|
+ const uint8_t *payload);
|
|
|
|
/*
|
|
* Packs PRIORITY frame |frame| in wire format and store it in
|
|
@@ -154,10 +153,8 @@ int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
|
*
|
|
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
|
* before calling this function.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
-int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
|
|
+void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
|
|
|
|
/*
|
|
* Unpacks PRIORITY wire format into |frame|.
|
|
@@ -171,11 +168,9 @@ void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
|
|
*
|
|
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
|
* before calling this function.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
-int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
|
- nghttp2_rst_stream *frame);
|
|
+void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
|
+ nghttp2_rst_stream *frame);
|
|
|
|
/*
|
|
* Unpacks RST_STREAM frame byte sequence into |frame|.
|
|
@@ -264,15 +259,9 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
|
|
* Unpacks PUSH_PROMISE frame byte sequence into |frame|. This
|
|
* function only unapcks bytes that come before name/value header
|
|
* block and after possible Pad Length field.
|
|
- *
|
|
- * This function returns 0 if it succeeds or one of the following
|
|
- * negative error codes:
|
|
- *
|
|
- * NGHTTP2_ERR_PROTO
|
|
- * TODO END_HEADERS flag is not set
|
|
*/
|
|
-int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
|
- const uint8_t *payload);
|
|
+void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
|
+ const uint8_t *payload);
|
|
|
|
/*
|
|
* Packs PING frame |frame| in wire format and store it in
|
|
@@ -280,10 +269,8 @@ int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
|
*
|
|
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
|
* before calling this function.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
-int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
|
|
+void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
|
|
|
|
/*
|
|
* Unpacks PING wire format into |frame|.
|
|
@@ -342,11 +329,9 @@ int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
|
|
*
|
|
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
|
* before calling this function.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
-int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
|
- nghttp2_window_update *frame);
|
|
+void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
|
+ nghttp2_window_update *frame);
|
|
|
|
/*
|
|
* Unpacks WINDOW_UPDATE frame byte sequence into |frame|.
|
|
@@ -360,17 +345,13 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
|
*
|
|
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
|
* before calling this function.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
-int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
|
+void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
|
|
|
/*
|
|
* Unpacks ALTSVC wire format into |frame|. The |payload| of
|
|
* |payloadlen| bytes contains frame payload. This function assumes
|
|
* that frame->payload points to the nghttp2_ext_altsvc object.
|
|
- *
|
|
- * This function always succeeds and returns 0.
|
|
*/
|
|
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
|
size_t origin_len, uint8_t *payload,
|
|
@@ -423,6 +404,27 @@ int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
|
int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
|
|
const uint8_t *payload,
|
|
size_t payloadlen, nghttp2_mem *mem);
|
|
+
|
|
+/*
|
|
+ * Packs PRIORITY_UPDATE frame |frame| in wire frame format and store
|
|
+ * it in |bufs|.
|
|
+ *
|
|
+ * The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
|
+ * before calling this function.
|
|
+ */
|
|
+void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
|
|
+ nghttp2_extension *ext);
|
|
+
|
|
+/*
|
|
+ * Unpacks PRIORITY_UPDATE wire format into |frame|. The |payload| of
|
|
+ * |payloadlen| bytes contains frame payload. This function assumes
|
|
+ * that frame->payload points to the nghttp2_ext_priority_update
|
|
+ * object.
|
|
+ */
|
|
+void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
|
|
+ uint8_t *payload,
|
|
+ size_t payloadlen);
|
|
+
|
|
/*
|
|
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
|
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
|
@@ -538,6 +540,25 @@ void nghttp2_frame_origin_init(nghttp2_extension *frame,
|
|
*/
|
|
void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem);
|
|
|
|
+/*
|
|
+ * Initializes PRIORITY_UPDATE frame |frame| with given values. This
|
|
+ * function assumes that frame->payload points to
|
|
+ * nghttp2_ext_priority_update object. On success, this function
|
|
+ * takes ownership of |field_value|, so caller must not free it.
|
|
+ */
|
|
+void nghttp2_frame_priority_update_init(nghttp2_extension *frame,
|
|
+ int32_t stream_id, uint8_t *field_value,
|
|
+ size_t field_value_len);
|
|
+
|
|
+/*
|
|
+ * Frees up resources under |frame|. This function does not free
|
|
+ * nghttp2_ext_priority_update object pointed by frame->payload. This
|
|
+ * function only frees field_value pointed by
|
|
+ * nghttp2_ext_priority_update.field_value.
|
|
+ */
|
|
+void nghttp2_frame_priority_update_free(nghttp2_extension *frame,
|
|
+ nghttp2_mem *mem);
|
|
+
|
|
/*
|
|
* Returns the number of padding bytes after payload. The total
|
|
* padding length is given in the |padlen|. The returned value does
|
|
@@ -609,16 +630,8 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
|
|
* |padlen| including Pad Length field. The |hd| is the frame header
|
|
* for the serialized data. This function fills zeros padding region
|
|
* unless framehd_only is nonzero.
|
|
- *
|
|
- * This function returns 0 if it succeeds, or one of the following
|
|
- * negative error codes:
|
|
- *
|
|
- * NGHTTP2_ERR_NOMEM
|
|
- * Out of memory.
|
|
- * NGHTTP2_ERR_FRAME_SIZE_ERROR
|
|
- * The length of the resulting frame is too large.
|
|
*/
|
|
-int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|
- size_t padlen, int framehd_only);
|
|
+void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|
+ size_t padlen, int framehd_only);
|
|
|
|
#endif /* NGHTTP2_FRAME_H */
|
|
diff --git a/deps/nghttp2/lib/nghttp2_hd.c b/deps/nghttp2/lib/nghttp2_hd.c
|
|
index 30ee9b8..8a2bda6 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_hd.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_hd.c
|
|
@@ -269,6 +269,11 @@ static int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
|
return NGHTTP2_TOKEN_LOCATION;
|
|
}
|
|
break;
|
|
+ case 'y':
|
|
+ if (memeq("priorit", name, 7)) {
|
|
+ return NGHTTP2_TOKEN_PRIORITY;
|
|
+ }
|
|
+ break;
|
|
}
|
|
break;
|
|
case 9:
|
|
diff --git a/deps/nghttp2/lib/nghttp2_hd.h b/deps/nghttp2/lib/nghttp2_hd.h
|
|
index 2674028..6de0052 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_hd.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_hd.h
|
|
@@ -112,6 +112,7 @@ typedef enum {
|
|
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
|
NGHTTP2_TOKEN_UPGRADE,
|
|
NGHTTP2_TOKEN__PROTOCOL,
|
|
+ NGHTTP2_TOKEN_PRIORITY,
|
|
} nghttp2_token;
|
|
|
|
struct nghttp2_hd_entry;
|
|
diff --git a/deps/nghttp2/lib/nghttp2_helper.c b/deps/nghttp2/lib/nghttp2_helper.c
|
|
index 588e269..93dd475 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_helper.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_helper.c
|
|
@@ -507,6 +507,19 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
|
return 1;
|
|
}
|
|
|
|
+int nghttp2_check_header_value_rfc9113(const uint8_t *value, size_t len) {
|
|
+ if (len == 0) {
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ if (*value == ' ' || *value == '\t' || *(value + len - 1) == ' ' ||
|
|
+ *(value + len - 1) == '\t') {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return nghttp2_check_header_value(value, len);
|
|
+}
|
|
+
|
|
/* Generated by genmethodchartbl.py */
|
|
static char VALID_METHOD_CHARS[] = {
|
|
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
|
diff --git a/deps/nghttp2/lib/nghttp2_http.c b/deps/nghttp2/lib/nghttp2_http.c
|
|
index a2bcd2c..ecdeb21 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_http.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_http.c
|
|
@@ -30,6 +30,8 @@
|
|
|
|
#include "nghttp2_hd.h"
|
|
#include "nghttp2_helper.h"
|
|
+#include "nghttp2_extpri.h"
|
|
+#include "sfparse.h"
|
|
|
|
static uint8_t downcase(uint8_t c) {
|
|
return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c;
|
|
@@ -72,25 +74,12 @@ static int64_t parse_uint(const uint8_t *s, size_t len) {
|
|
return n;
|
|
}
|
|
|
|
-static int lws(const uint8_t *s, size_t n) {
|
|
- size_t i;
|
|
- for (i = 0; i < n; ++i) {
|
|
- if (s[i] != ' ' && s[i] != '\t') {
|
|
- return 0;
|
|
- }
|
|
- }
|
|
- return 1;
|
|
-}
|
|
-
|
|
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
|
|
- int flag) {
|
|
- if (stream->http_flags & flag) {
|
|
- return 0;
|
|
- }
|
|
- if (lws(nv->value->base, nv->value->len)) {
|
|
+ uint32_t flag) {
|
|
+ if ((stream->http_flags & flag) || nv->value->len == 0) {
|
|
return 0;
|
|
}
|
|
- stream->http_flags = (uint16_t)(stream->http_flags | flag);
|
|
+ stream->http_flags = stream->http_flags | flag;
|
|
return 1;
|
|
}
|
|
|
|
@@ -114,6 +103,8 @@ static int check_path(nghttp2_stream *stream) {
|
|
|
|
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|
int trailer, int connect_protocol) {
|
|
+ nghttp2_extpri extpri;
|
|
+
|
|
if (nv->name->base[0] == ':') {
|
|
if (trailer ||
|
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
|
@@ -212,6 +203,23 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|
return NGHTTP2_ERR_HTTP_HEADER;
|
|
}
|
|
break;
|
|
+ case NGHTTP2_TOKEN_PRIORITY:
|
|
+ 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,
|
|
+ nv->value->len) == 0) {
|
|
+ stream->http_extpri = nghttp2_extpri_to_uint8(&extpri);
|
|
+ stream->http_flags |= NGHTTP2_HTTP_FLAG_PRIORITY;
|
|
+ } else {
|
|
+ stream->http_flags &= (uint32_t)~NGHTTP2_HTTP_FLAG_PRIORITY;
|
|
+ stream->http_flags |= NGHTTP2_HTTP_FLAG_BAD_PRIORITY;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
default:
|
|
if (nv->name->base[0] == ':') {
|
|
return NGHTTP2_ERR_HTTP_HEADER;
|
|
@@ -329,6 +337,16 @@ static int check_scheme(const uint8_t *value, size_t len) {
|
|
return 1;
|
|
}
|
|
|
|
+static int lws(const uint8_t *s, size_t n) {
|
|
+ size_t i;
|
|
+ for (i = 0; i < n; ++i) {
|
|
+ if (s[i] != ' ' && s[i] != '\t') {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ return 1;
|
|
+}
|
|
+
|
|
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
|
int trailer) {
|
|
@@ -369,13 +387,37 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|
break;
|
|
case NGHTTP2_TOKEN__AUTHORITY:
|
|
case NGHTTP2_TOKEN_HOST:
|
|
- rv = nghttp2_check_authority(nv->value->base, nv->value->len);
|
|
+ if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
|
+ rv = nghttp2_check_authority(nv->value->base, nv->value->len);
|
|
+ } else if (
|
|
+ stream->flags &
|
|
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
|
|
+ rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
|
|
+ } else {
|
|
+ rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len);
|
|
+ }
|
|
break;
|
|
case NGHTTP2_TOKEN__SCHEME:
|
|
rv = check_scheme(nv->value->base, nv->value->len);
|
|
break;
|
|
+ case NGHTTP2_TOKEN__PROTOCOL:
|
|
+ /* Check the value consists of just white spaces, which was done
|
|
+ in check_pseudo_header before
|
|
+ nghttp2_check_header_value_rfc9113 has been introduced. */
|
|
+ if ((stream->flags &
|
|
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) &&
|
|
+ lws(nv->value->base, nv->value->len)) {
|
|
+ rv = 0;
|
|
+ break;
|
|
+ }
|
|
+ /* fall through */
|
|
default:
|
|
- rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
|
|
+ if (stream->flags &
|
|
+ NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
|
|
+ rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
|
|
+ } else {
|
|
+ rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len);
|
|
+ }
|
|
}
|
|
|
|
if (rv == 0) {
|
|
@@ -443,16 +485,15 @@ int nghttp2_http_on_response_headers(nghttp2_stream *stream) {
|
|
|
|
if (stream->status_code / 100 == 1) {
|
|
/* non-final response */
|
|
- stream->http_flags =
|
|
- (uint16_t)((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_ALL) |
|
|
- NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE);
|
|
+ stream->http_flags = (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_ALL) |
|
|
+ NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE;
|
|
stream->content_length = -1;
|
|
stream->status_code = -1;
|
|
return 0;
|
|
}
|
|
|
|
stream->http_flags =
|
|
- (uint16_t)(stream->http_flags & ~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE);
|
|
+ stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE;
|
|
|
|
if (!expect_response_body(stream)) {
|
|
stream->content_length = 0;
|
|
@@ -537,3 +578,54 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream,
|
|
return;
|
|
}
|
|
}
|
|
+
|
|
+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;
|
|
+ int rv;
|
|
+
|
|
+ sf_parser_init(&sfp, value, valuelen);
|
|
+
|
|
+ for (;;) {
|
|
+ rv = sf_parser_dict(&sfp, &key, &val);
|
|
+ if (rv != 0) {
|
|
+ if (rv == SF_ERR_EOF) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
|
|
+ }
|
|
+
|
|
+ if (key.len != 1) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ switch (key.base[0]) {
|
|
+ case 'i':
|
|
+ if (val.type != SF_TYPE_BOOLEAN) {
|
|
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
|
|
+ }
|
|
+
|
|
+ pri.inc = val.boolean;
|
|
+
|
|
+ break;
|
|
+ case 'u':
|
|
+ if (val.type != SF_TYPE_INTEGER ||
|
|
+ val.integer < NGHTTP2_EXTPRI_URGENCY_HIGH ||
|
|
+ NGHTTP2_EXTPRI_URGENCY_LOW < val.integer) {
|
|
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
|
|
+ }
|
|
+
|
|
+ pri.urgency = (uint32_t)val.integer;
|
|
+
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *dest = pri;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_http.h b/deps/nghttp2/lib/nghttp2_http.h
|
|
index dd057cd..d9992fe 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_http.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_http.h
|
|
@@ -94,4 +94,7 @@ int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n);
|
|
void nghttp2_http_record_request_method(nghttp2_stream *stream,
|
|
nghttp2_frame *frame);
|
|
|
|
+int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
|
|
+ size_t valuelen);
|
|
+
|
|
#endif /* NGHTTP2_HTTP_H */
|
|
diff --git a/deps/nghttp2/lib/nghttp2_map.c b/deps/nghttp2/lib/nghttp2_map.c
|
|
index e5db168..5f63fc2 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_map.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_map.c
|
|
@@ -31,21 +31,14 @@
|
|
|
|
#include "nghttp2_helper.h"
|
|
|
|
-#define NGHTTP2_INITIAL_TABLE_LENBITS 8
|
|
+#define NGHTTP2_INITIAL_TABLE_LENBITS 4
|
|
|
|
-int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
|
|
+void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
|
|
map->mem = mem;
|
|
- map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS;
|
|
- map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS;
|
|
- map->table =
|
|
- nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket));
|
|
- if (map->table == NULL) {
|
|
- return NGHTTP2_ERR_NOMEM;
|
|
- }
|
|
-
|
|
+ map->tablelen = 0;
|
|
+ map->tablelenbits = 0;
|
|
+ map->table = NULL;
|
|
map->size = 0;
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_map_free(nghttp2_map *map) {
|
|
@@ -78,6 +71,10 @@ int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
|
|
uint32_t i;
|
|
nghttp2_map_bucket *bkt;
|
|
|
|
+ if (map->size == 0) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
for (i = 0; i < map->tablelen; ++i) {
|
|
bkt = &map->table[i];
|
|
|
|
@@ -223,9 +220,17 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
|
|
|
|
/* Load factor is 0.75 */
|
|
if ((map->size + 1) * 4 > map->tablelen * 3) {
|
|
- rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
|
|
- if (rv != 0) {
|
|
- return rv;
|
|
+ if (map->tablelen) {
|
|
+ rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
|
|
+ if (rv != 0) {
|
|
+ return rv;
|
|
+ }
|
|
+ } else {
|
|
+ rv = map_resize(map, 1 << NGHTTP2_INITIAL_TABLE_LENBITS,
|
|
+ NGHTTP2_INITIAL_TABLE_LENBITS);
|
|
+ if (rv != 0) {
|
|
+ return rv;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -239,11 +244,18 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
|
|
}
|
|
|
|
void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
|
|
- uint32_t h = hash(key);
|
|
- size_t idx = h2idx(h, map->tablelenbits);
|
|
+ uint32_t h;
|
|
+ size_t idx;
|
|
nghttp2_map_bucket *bkt;
|
|
size_t d = 0;
|
|
|
|
+ if (map->size == 0) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ h = hash(key);
|
|
+ idx = h2idx(h, map->tablelenbits);
|
|
+
|
|
for (;;) {
|
|
bkt = &map->table[idx];
|
|
|
|
@@ -262,11 +274,18 @@ void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
|
|
}
|
|
|
|
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
|
|
- uint32_t h = hash(key);
|
|
- size_t idx = h2idx(h, map->tablelenbits), didx;
|
|
+ uint32_t h;
|
|
+ size_t idx, didx;
|
|
nghttp2_map_bucket *bkt;
|
|
size_t d = 0;
|
|
|
|
+ if (map->size == 0) {
|
|
+ return NGHTTP2_ERR_INVALID_ARGUMENT;
|
|
+ }
|
|
+
|
|
+ h = hash(key);
|
|
+ idx = h2idx(h, map->tablelenbits);
|
|
+
|
|
for (;;) {
|
|
bkt = &map->table[idx];
|
|
|
|
@@ -306,6 +325,10 @@ int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
|
|
}
|
|
|
|
void nghttp2_map_clear(nghttp2_map *map) {
|
|
+ if (map->tablelen == 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
memset(map->table, 0, sizeof(*map->table) * map->tablelen);
|
|
map->size = 0;
|
|
}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_map.h b/deps/nghttp2/lib/nghttp2_map.h
|
|
index 1419a09..d90245a 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_map.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_map.h
|
|
@@ -54,14 +54,8 @@ typedef struct nghttp2_map {
|
|
|
|
/*
|
|
* Initializes the map |map|.
|
|
- *
|
|
- * This function returns 0 if it succeeds, or one of the following
|
|
- * negative error codes:
|
|
- *
|
|
- * NGHTTP2_ERR_NOMEM
|
|
- * Out of memory
|
|
*/
|
|
-int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
|
|
+void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
|
|
|
|
/*
|
|
* Deallocates any resources allocated for |map|. The stored entries
|
|
diff --git a/deps/nghttp2/lib/nghttp2_net.h b/deps/nghttp2/lib/nghttp2_net.h
|
|
index 582099b..521f981 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_net.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_net.h
|
|
@@ -53,7 +53,7 @@
|
|
STIN uint32_t htonl(uint32_t hostlong) {
|
|
uint32_t res;
|
|
unsigned char *p = (unsigned char *)&res;
|
|
- *p++ = hostlong >> 24;
|
|
+ *p++ = (unsigned char)(hostlong >> 24);
|
|
*p++ = (hostlong >> 16) & 0xffu;
|
|
*p++ = (hostlong >> 8) & 0xffu;
|
|
*p = hostlong & 0xffu;
|
|
@@ -63,7 +63,7 @@ STIN uint32_t htonl(uint32_t hostlong) {
|
|
STIN uint16_t htons(uint16_t hostshort) {
|
|
uint16_t res;
|
|
unsigned char *p = (unsigned char *)&res;
|
|
- *p++ = hostshort >> 8;
|
|
+ *p++ = (unsigned char)(hostshort >> 8);
|
|
*p = hostshort & 0xffu;
|
|
return res;
|
|
}
|
|
@@ -71,9 +71,9 @@ STIN uint16_t htons(uint16_t hostshort) {
|
|
STIN uint32_t ntohl(uint32_t netlong) {
|
|
uint32_t res;
|
|
unsigned char *p = (unsigned char *)&netlong;
|
|
- res = *p++ << 24;
|
|
- res += *p++ << 16;
|
|
- res += *p++ << 8;
|
|
+ res = (uint32_t)(*p++ << 24);
|
|
+ res += (uint32_t)(*p++ << 16);
|
|
+ res += (uint32_t)(*p++ << 8);
|
|
res += *p;
|
|
return res;
|
|
}
|
|
@@ -81,7 +81,7 @@ STIN uint32_t ntohl(uint32_t netlong) {
|
|
STIN uint16_t ntohs(uint16_t netshort) {
|
|
uint16_t res;
|
|
unsigned char *p = (unsigned char *)&netshort;
|
|
- res = *p++ << 8;
|
|
+ res = (uint16_t)(*p++ << 8);
|
|
res += *p;
|
|
return res;
|
|
}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_option.c b/deps/nghttp2/lib/nghttp2_option.c
|
|
index 34348e6..43d4e95 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_option.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_option.c
|
|
@@ -90,6 +90,10 @@ void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
|
|
option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
|
|
option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ORIGIN;
|
|
return;
|
|
+ case NGHTTP2_PRIORITY_UPDATE:
|
|
+ option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
|
|
+ option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_PRIORITY_UPDATE;
|
|
+ return;
|
|
default:
|
|
return;
|
|
}
|
|
@@ -126,3 +130,23 @@ void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) {
|
|
option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
|
|
option->max_settings = val;
|
|
}
|
|
+
|
|
+void nghttp2_option_set_server_fallback_rfc7540_priorities(
|
|
+ nghttp2_option *option, int val) {
|
|
+ option->opt_set_mask |= NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES;
|
|
+ option->server_fallback_rfc7540_priorities = val;
|
|
+}
|
|
+
|
|
+void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
|
|
+ nghttp2_option *option, int val) {
|
|
+ option->opt_set_mask |=
|
|
+ NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
|
|
+ option->no_rfc9113_leading_and_trailing_ws_validation = val;
|
|
+}
|
|
+
|
|
+void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
|
|
+ uint64_t burst, uint64_t rate) {
|
|
+ option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT;
|
|
+ option->stream_reset_burst = burst;
|
|
+ option->stream_reset_rate = rate;
|
|
+}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_option.h b/deps/nghttp2/lib/nghttp2_option.h
|
|
index 939729f..2259e18 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_option.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_option.h
|
|
@@ -68,12 +68,20 @@ typedef enum {
|
|
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
|
|
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
|
|
NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
|
|
+ NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13,
|
|
+ NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
|
|
+ NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
|
|
} nghttp2_option_flag;
|
|
|
|
/**
|
|
* Struct to store option values for nghttp2_session.
|
|
*/
|
|
struct nghttp2_option {
|
|
+ /**
|
|
+ * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT
|
|
+ */
|
|
+ uint64_t stream_reset_burst;
|
|
+ uint64_t stream_reset_rate;
|
|
/**
|
|
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
|
*/
|
|
@@ -127,6 +135,14 @@ struct nghttp2_option {
|
|
* NGHTTP2_OPT_NO_CLOSED_STREAMS
|
|
*/
|
|
int no_closed_streams;
|
|
+ /**
|
|
+ * NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES
|
|
+ */
|
|
+ int server_fallback_rfc7540_priorities;
|
|
+ /**
|
|
+ * NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION
|
|
+ */
|
|
+ int no_rfc9113_leading_and_trailing_ws_validation;
|
|
/**
|
|
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
|
|
*/
|
|
diff --git a/deps/nghttp2/lib/nghttp2_outbound_item.c b/deps/nghttp2/lib/nghttp2_outbound_item.c
|
|
index f651c80..2a3041d 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_outbound_item.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_outbound_item.c
|
|
@@ -89,6 +89,9 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
|
|
case NGHTTP2_ORIGIN:
|
|
nghttp2_frame_origin_free(&frame->ext, mem);
|
|
break;
|
|
+ case NGHTTP2_PRIORITY_UPDATE:
|
|
+ nghttp2_frame_priority_update_free(&frame->ext, mem);
|
|
+ break;
|
|
default:
|
|
assert(0);
|
|
break;
|
|
diff --git a/deps/nghttp2/lib/nghttp2_pq.c b/deps/nghttp2/lib/nghttp2_pq.c
|
|
index bebccc7..64353ac 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_pq.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_pq.c
|
|
@@ -29,13 +29,12 @@
|
|
|
|
#include "nghttp2_helper.h"
|
|
|
|
-int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem) {
|
|
+void nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem) {
|
|
pq->mem = mem;
|
|
pq->capacity = 0;
|
|
pq->q = NULL;
|
|
pq->length = 0;
|
|
pq->less = less;
|
|
- return 0;
|
|
}
|
|
|
|
void nghttp2_pq_free(nghttp2_pq *pq) {
|
|
diff --git a/deps/nghttp2/lib/nghttp2_pq.h b/deps/nghttp2/lib/nghttp2_pq.h
|
|
index 7b7b739..c8d90ef 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_pq.h
|
|
+++ b/deps/nghttp2/lib/nghttp2_pq.h
|
|
@@ -55,14 +55,8 @@ typedef struct {
|
|
|
|
/*
|
|
* Initializes priority queue |pq| with compare function |cmp|.
|
|
- *
|
|
- * This function returns 0 if it succeeds, or one of the following
|
|
- * negative error codes:
|
|
- *
|
|
- * NGHTTP2_ERR_NOMEM
|
|
- * Out of memory.
|
|
*/
|
|
-int nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem);
|
|
+void nghttp2_pq_init(nghttp2_pq *pq, nghttp2_less less, nghttp2_mem *mem);
|
|
|
|
/*
|
|
* Deallocates any resources allocated for |pq|. The stored items are
|
|
diff --git a/deps/nghttp2/lib/nghttp2_ratelim.c b/deps/nghttp2/lib/nghttp2_ratelim.c
|
|
new file mode 100644
|
|
index 0000000..7011655
|
|
--- /dev/null
|
|
+++ b/deps/nghttp2/lib/nghttp2_ratelim.c
|
|
@@ -0,0 +1,75 @@
|
|
+/*
|
|
+ * nghttp2 - HTTP/2 C Library
|
|
+ *
|
|
+ * Copyright (c) 2023 nghttp2 contributors
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be
|
|
+ * included in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+#include "nghttp2_ratelim.h"
|
|
+#include "nghttp2_helper.h"
|
|
+
|
|
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) {
|
|
+ rl->val = rl->burst = burst;
|
|
+ rl->rate = rate;
|
|
+ rl->tstamp = 0;
|
|
+}
|
|
+
|
|
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) {
|
|
+ uint64_t d, gain;
|
|
+
|
|
+ if (tstamp == rl->tstamp) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (tstamp > rl->tstamp) {
|
|
+ d = tstamp - rl->tstamp;
|
|
+ } else {
|
|
+ d = 1;
|
|
+ }
|
|
+
|
|
+ rl->tstamp = tstamp;
|
|
+
|
|
+ if (UINT64_MAX / d < rl->rate) {
|
|
+ rl->val = rl->burst;
|
|
+
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ gain = rl->rate * d;
|
|
+
|
|
+ if (UINT64_MAX - gain < rl->val) {
|
|
+ rl->val = rl->burst;
|
|
+
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ rl->val += gain;
|
|
+ rl->val = nghttp2_min(rl->val, rl->burst);
|
|
+}
|
|
+
|
|
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) {
|
|
+ if (rl->val < n) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ rl->val -= n;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/deps/nghttp2/lib/nghttp2_ratelim.h b/deps/nghttp2/lib/nghttp2_ratelim.h
|
|
new file mode 100644
|
|
index 0000000..866ed3f
|
|
--- /dev/null
|
|
+++ b/deps/nghttp2/lib/nghttp2_ratelim.h
|
|
@@ -0,0 +1,57 @@
|
|
+/*
|
|
+ * nghttp2 - HTTP/2 C Library
|
|
+ *
|
|
+ * Copyright (c) 2023 nghttp2 contributors
|
|
+ *
|
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
+ * a copy of this software and associated documentation files (the
|
|
+ * "Software"), to deal in the Software without restriction, including
|
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
+ * the following conditions:
|
|
+ *
|
|
+ * The above copyright notice and this permission notice shall be
|
|
+ * included in all copies or substantial portions of the Software.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
+ */
|
|
+#ifndef NGHTTP2_RATELIM_H
|
|
+#define NGHTTP2_RATELIM_H
|
|
+
|
|
+#ifdef HAVE_CONFIG_H
|
|
+# include <config.h>
|
|
+#endif /* HAVE_CONFIG_H */
|
|
+
|
|
+#include <nghttp2/nghttp2.h>
|
|
+
|
|
+typedef struct nghttp2_ratelim {
|
|
+ /* burst is the maximum value of val. */
|
|
+ uint64_t burst;
|
|
+ /* rate is the amount of value that is regenerated per 1 tstamp. */
|
|
+ uint64_t rate;
|
|
+ /* val is the amount of value available to drain. */
|
|
+ uint64_t val;
|
|
+ /* tstamp is the last timestamp in second resolution that is known
|
|
+ to this object. */
|
|
+ uint64_t tstamp;
|
|
+} nghttp2_ratelim;
|
|
+
|
|
+/* nghttp2_ratelim_init initializes |rl| with the given parameters. */
|
|
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate);
|
|
+
|
|
+/* nghttp2_ratelim_update updates rl->val with the current |tstamp|
|
|
+ given in second resolution. */
|
|
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
|
|
+
|
|
+/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it
|
|
+ succeeds, or -1. */
|
|
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
|
|
+
|
|
+#endif /* NGHTTP2_RATELIM_H */
|
|
diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c
|
|
index 380a47c..ec5024d 100644
|
|
--- a/deps/nghttp2/lib/nghttp2_session.c
|
|
+++ b/deps/nghttp2/lib/nghttp2_session.c
|
|
@@ -36,6 +36,8 @@
|
|
#include "nghttp2_option.h"
|
|
#include "nghttp2_http.h"
|
|
#include "nghttp2_pq.h"
|
|
+#include "nghttp2_extpri.h"
|
|
+#include "nghttp2_time.h"
|
|
#include "nghttp2_debug.h"
|
|
|
|
/*
|
|
@@ -143,6 +145,11 @@ 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;
|
|
}
|
|
@@ -354,6 +361,14 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
|
|
}
|
|
nghttp2_frame_origin_free(&iframe->frame.ext, mem);
|
|
break;
|
|
+ case NGHTTP2_PRIORITY_UPDATE:
|
|
+ if ((session->builtin_recv_ext_types &
|
|
+ NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
|
|
+ break;
|
|
+ }
|
|
+ /* Do not call nghttp2_frame_priority_update_free, because all
|
|
+ fields point to sbuf. */
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
@@ -385,6 +400,7 @@ static void init_settings(nghttp2_settings_storage *settings) {
|
|
settings->initial_window_size = NGHTTP2_INITIAL_WINDOW_SIZE;
|
|
settings->max_frame_size = NGHTTP2_MAX_FRAME_SIZE_MIN;
|
|
settings->max_header_list_size = UINT32_MAX;
|
|
+ settings->no_rfc7540_priorities = UINT32_MAX;
|
|
}
|
|
|
|
static void active_outbound_item_reset(nghttp2_active_outbound_item *aob,
|
|
@@ -398,6 +414,21 @@ static void active_outbound_item_reset(nghttp2_active_outbound_item *aob,
|
|
aob->state = NGHTTP2_OB_POP_ITEM;
|
|
}
|
|
|
|
+#define NGHTTP2_STREAM_MAX_CYCLE_GAP ((uint64_t)NGHTTP2_MAX_FRAME_SIZE_MAX)
|
|
+
|
|
+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_STREAM_MAX_CYCLE_GAP;
|
|
+}
|
|
+
|
|
int nghttp2_enable_strict_preface = 1;
|
|
|
|
static int session_new(nghttp2_session **session_ptr,
|
|
@@ -408,6 +439,7 @@ static int session_new(nghttp2_session **session_ptr,
|
|
size_t nbuffer;
|
|
size_t max_deflate_dynamic_table_size =
|
|
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
|
|
+ size_t i;
|
|
|
|
if (mem == NULL) {
|
|
mem = nghttp2_mem_default();
|
|
@@ -442,6 +474,11 @@ static int session_new(nghttp2_session **session_ptr,
|
|
(*session_ptr)->pending_local_max_concurrent_stream =
|
|
NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
|
|
(*session_ptr)->pending_enable_push = 1;
|
|
+ (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX;
|
|
+
|
|
+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
|
|
+ NGHTTP2_DEFAULT_STREAM_RESET_BURST,
|
|
+ NGHTTP2_DEFAULT_STREAM_RESET_RATE);
|
|
|
|
if (server) {
|
|
(*session_ptr)->server = 1;
|
|
@@ -527,6 +564,26 @@ static int session_new(nghttp2_session **session_ptr,
|
|
option->max_settings) {
|
|
(*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) {
|
|
+ (*session_ptr)->opt_flags |=
|
|
+ NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
|
|
+ }
|
|
+
|
|
+ if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) {
|
|
+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
|
|
+ option->stream_reset_burst,
|
|
+ option->stream_reset_rate);
|
|
+ }
|
|
}
|
|
|
|
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
|
|
@@ -538,10 +595,6 @@ static int session_new(nghttp2_session **session_ptr,
|
|
if (rv != 0) {
|
|
goto fail_hd_inflater;
|
|
}
|
|
- rv = nghttp2_map_init(&(*session_ptr)->streams, mem);
|
|
- if (rv != 0) {
|
|
- goto fail_map;
|
|
- }
|
|
|
|
nbuffer = ((*session_ptr)->max_send_header_block_length +
|
|
NGHTTP2_FRAMEBUF_CHUNKLEN - 1) /
|
|
@@ -559,6 +612,8 @@ static int session_new(nghttp2_session **session_ptr,
|
|
goto fail_aob_framebuf;
|
|
}
|
|
|
|
+ nghttp2_map_init(&(*session_ptr)->streams, mem);
|
|
+
|
|
active_outbound_item_reset(&(*session_ptr)->aob, mem);
|
|
|
|
(*session_ptr)->callbacks = *callbacks;
|
|
@@ -584,11 +639,13 @@ static int session_new(nghttp2_session **session_ptr,
|
|
}
|
|
}
|
|
|
|
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
|
|
+ nghttp2_pq_init(&(*session_ptr)->sched[i].ob_data, stream_less, mem);
|
|
+ }
|
|
+
|
|
return 0;
|
|
|
|
fail_aob_framebuf:
|
|
- nghttp2_map_free(&(*session_ptr)->streams);
|
|
-fail_map:
|
|
nghttp2_hd_inflate_free(&(*session_ptr)->hd_inflater);
|
|
fail_hd_inflater:
|
|
nghttp2_hd_deflate_free(&(*session_ptr)->hd_deflater);
|
|
@@ -735,6 +792,7 @@ static void inflight_settings_del(nghttp2_inflight_settings *settings,
|
|
void nghttp2_session_del(nghttp2_session *session) {
|
|
nghttp2_mem *mem;
|
|
nghttp2_inflight_settings *settings;
|
|
+ size_t i;
|
|
|
|
if (session == NULL) {
|
|
return;
|
|
@@ -748,6 +806,9 @@ void nghttp2_session_del(nghttp2_session *session) {
|
|
settings = next;
|
|
}
|
|
|
|
+ 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
|
|
@@ -775,6 +836,8 @@ int nghttp2_session_reprioritize_stream(
|
|
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)) {
|
|
@@ -842,6 +905,202 @@ int nghttp2_session_reprioritize_stream(
|
|
return 0;
|
|
}
|
|
|
|
+static uint64_t pq_get_first_cycle(nghttp2_pq *pq) {
|
|
+ nghttp2_stream *stream;
|
|
+
|
|
+ if (nghttp2_pq_empty(pq)) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ stream = nghttp2_struct_of(nghttp2_pq_top(pq), nghttp2_stream, pq_entry);
|
|
+ return stream->cycle;
|
|
+}
|
|
+
|
|
+static int session_ob_data_push(nghttp2_session *session,
|
|
+ nghttp2_stream *stream) {
|
|
+ int rv;
|
|
+ uint32_t urgency;
|
|
+ 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);
|
|
+ inc = nghttp2_extpri_uint8_inc(stream->extpri);
|
|
+
|
|
+ assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS);
|
|
+
|
|
+ pq = &session->sched[urgency].ob_data;
|
|
+
|
|
+ stream->cycle = pq_get_first_cycle(pq);
|
|
+ if (inc) {
|
|
+ stream->cycle += stream->last_writelen;
|
|
+ }
|
|
+
|
|
+ rv = nghttp2_pq_push(pq, &stream->pq_entry);
|
|
+ if (rv != 0) {
|
|
+ return rv;
|
|
+ }
|
|
+
|
|
+ stream->queued = 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+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);
|
|
+
|
|
+ assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS);
|
|
+
|
|
+ nghttp2_pq_remove(&session->sched[urgency].ob_data, &stream->pq_entry);
|
|
+
|
|
+ stream->queued = 0;
|
|
+}
|
|
+
|
|
+static int session_attach_stream_item(nghttp2_session *session,
|
|
+ nghttp2_stream *stream,
|
|
+ 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;
|
|
+ }
|
|
+
|
|
+ return session_ob_data_push(session, stream);
|
|
+}
|
|
+
|
|
+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) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ session_ob_data_remove(session, stream);
|
|
+}
|
|
+
|
|
+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) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ session_ob_data_remove(session, stream);
|
|
+}
|
|
+
|
|
+static int session_resume_deferred_stream_item(nghttp2_session *session,
|
|
+ nghttp2_stream *stream,
|
|
+ uint8_t flags) {
|
|
+ int rv;
|
|
+
|
|
+ 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)) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return session_ob_data_push(session, stream);
|
|
+}
|
|
+
|
|
+static nghttp2_outbound_item *
|
|
+session_sched_get_next_outbound_item(nghttp2_session *session) {
|
|
+ size_t i;
|
|
+ nghttp2_pq_entry *ent;
|
|
+ nghttp2_stream *stream;
|
|
+
|
|
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
|
|
+ ent = nghttp2_pq_top(&session->sched[i].ob_data);
|
|
+ if (!ent) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ stream = nghttp2_struct_of(ent, nghttp2_stream, pq_entry);
|
|
+ return stream->item;
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static int session_sched_empty(nghttp2_session *session) {
|
|
+ size_t i;
|
|
+
|
|
+ for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
|
|
+ if (!nghttp2_pq_empty(&session->sched[i].ob_data)) {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+static void session_sched_reschedule_stream(nghttp2_session *session,
|
|
+ nghttp2_stream *stream) {
|
|
+ nghttp2_pq *pq;
|
|
+ uint32_t urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
|
|
+ int inc = nghttp2_extpri_uint8_inc(stream->extpri);
|
|
+ uint64_t penalty = (uint64_t)stream->last_writelen;
|
|
+ int rv;
|
|
+
|
|
+ (void)rv;
|
|
+
|
|
+ assert(urgency < NGHTTP2_EXTPRI_URGENCY_LEVELS);
|
|
+
|
|
+ pq = &session->sched[urgency].ob_data;
|
|
+
|
|
+ if (!inc || nghttp2_pq_size(pq) == 1) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ nghttp2_pq_remove(pq, &stream->pq_entry);
|
|
+
|
|
+ stream->cycle += penalty;
|
|
+
|
|
+ rv = nghttp2_pq_push(pq, &stream->pq_entry);
|
|
+
|
|
+ assert(0 == rv);
|
|
+}
|
|
+
|
|
+static int session_update_stream_priority(nghttp2_session *session,
|
|
+ nghttp2_stream *stream,
|
|
+ uint8_t u8extpri) {
|
|
+ if (stream->extpri == u8extpri) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (stream->queued) {
|
|
+ session_ob_data_remove(session, stream);
|
|
+
|
|
+ stream->extpri = u8extpri;
|
|
+
|
|
+ return session_ob_data_push(session, stream);
|
|
+ }
|
|
+
|
|
+ stream->extpri = u8extpri;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int nghttp2_session_add_item(nghttp2_session *session,
|
|
nghttp2_outbound_item *item) {
|
|
/* TODO Return error if stream is not found for the frame requiring
|
|
@@ -863,7 +1122,7 @@ int nghttp2_session_add_item(nghttp2_session *session,
|
|
return NGHTTP2_ERR_DATA_EXIST;
|
|
}
|
|
|
|
- rv = nghttp2_stream_attach_item(stream, item);
|
|
+ rv = session_attach_stream_item(session, stream, item);
|
|
|
|
if (rv != 0) {
|
|
return rv;
|
|
@@ -1039,13 +1298,27 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
|
|
mem = &session->mem;
|
|
stream = nghttp2_session_get_stream_raw(session, stream_id);
|
|
|
|
+ if (session->opt_flags &
|
|
+ NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
|
|
+ flags |= NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
|
|
+ }
|
|
+
|
|
if (stream) {
|
|
assert(stream->state == NGHTTP2_STREAM_IDLE);
|
|
- assert(nghttp2_stream_in_dep_tree(stream));
|
|
- nghttp2_session_detach_idle_stream(session, stream);
|
|
- rv = nghttp2_stream_dep_remove(stream);
|
|
- if (rv != 0) {
|
|
- return NULL;
|
|
+ assert((stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
|
|
+ nghttp2_stream_in_dep_tree(stream));
|
|
+
|
|
+ if (nghttp2_stream_in_dep_tree(stream)) {
|
|
+ assert(!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES));
|
|
+ nghttp2_session_detach_idle_stream(session, stream);
|
|
+ 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;
|
|
+ }
|
|
}
|
|
} else {
|
|
stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream));
|
|
@@ -1056,7 +1329,21 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
|
|
stream_alloc = 1;
|
|
}
|
|
|
|
- if (pri_spec->stream_id != 0) {
|
|
+ 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 &&
|
|
@@ -1102,6 +1389,10 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session,
|
|
(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++;
|
|
+ }
|
|
+
|
|
rv = nghttp2_map_insert(&session->streams, stream_id, stream);
|
|
if (rv != 0) {
|
|
nghttp2_stream_free(stream);
|
|
@@ -1141,6 +1432,10 @@ 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;
|
|
}
|
|
@@ -1180,11 +1475,7 @@ int nghttp2_session_close_stream(nghttp2_session *session, int32_t stream_id,
|
|
|
|
item = stream->item;
|
|
|
|
- rv = nghttp2_stream_detach_item(stream);
|
|
-
|
|
- if (rv != 0) {
|
|
- return rv;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
|
|
/* If item is queued, it will be deleted when it is popped
|
|
(nghttp2_session_prep_frame() will fail). If session->aob.item
|
|
@@ -1230,6 +1521,10 @@ 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)) {
|
|
@@ -1784,6 +2079,28 @@ static int session_predicate_origin_send(nghttp2_session *session) {
|
|
return 0;
|
|
}
|
|
|
|
+static int session_predicate_priority_update_send(nghttp2_session *session,
|
|
+ int32_t stream_id) {
|
|
+ nghttp2_stream *stream;
|
|
+
|
|
+ if (session_is_closing(session)) {
|
|
+ return NGHTTP2_ERR_SESSION_CLOSING;
|
|
+ }
|
|
+
|
|
+ stream = nghttp2_session_get_stream(session, stream_id);
|
|
+ if (stream == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+ if (stream->state == NGHTTP2_STREAM_CLOSING) {
|
|
+ return NGHTTP2_ERR_STREAM_CLOSING;
|
|
+ }
|
|
+ if (stream->shut_flags & NGHTTP2_SHUT_RD) {
|
|
+ return NGHTTP2_ERR_INVALID_STREAM_STATE;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Take into account settings max frame size and both connection-level
|
|
flow control here */
|
|
static ssize_t
|
|
@@ -1899,7 +2216,6 @@ static ssize_t session_call_select_padding(nghttp2_session *session,
|
|
frame->push_promise has also padlen in the same position. */
|
|
static int session_headers_add_pad(nghttp2_session *session,
|
|
nghttp2_frame *frame) {
|
|
- int rv;
|
|
ssize_t padded_payloadlen;
|
|
nghttp2_active_outbound_item *aob;
|
|
nghttp2_bufs *framebufs;
|
|
@@ -1924,11 +2240,7 @@ static int session_headers_add_pad(nghttp2_session *session,
|
|
DEBUGF("send: padding selected: payloadlen=%zd, padlen=%zu\n",
|
|
padded_payloadlen, padlen);
|
|
|
|
- rv = nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0);
|
|
-
|
|
- if (rv != 0) {
|
|
- return rv;
|
|
- }
|
|
+ nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0);
|
|
|
|
frame->headers.padlen = padlen;
|
|
|
|
@@ -2011,13 +2323,7 @@ static int session_prep_frame(nghttp2_session *session,
|
|
// Search stream including closed again.
|
|
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
|
|
if (stream) {
|
|
- int rv2;
|
|
-
|
|
- rv2 = nghttp2_stream_detach_item(stream);
|
|
-
|
|
- if (nghttp2_is_fatal(rv2)) {
|
|
- return rv2;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
}
|
|
|
|
return rv;
|
|
@@ -2032,12 +2338,8 @@ static int session_prep_frame(nghttp2_session *session,
|
|
queue when session->remote_window_size > 0 */
|
|
assert(session->remote_window_size > 0);
|
|
|
|
- rv = nghttp2_stream_defer_item(stream,
|
|
- NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
|
-
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ session_defer_stream_item(session, stream,
|
|
+ NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
|
|
|
session->aob.item = NULL;
|
|
active_outbound_item_reset(&session->aob, mem);
|
|
@@ -2051,22 +2353,15 @@ static int session_prep_frame(nghttp2_session *session,
|
|
return rv;
|
|
}
|
|
if (rv == NGHTTP2_ERR_DEFERRED) {
|
|
- rv = nghttp2_stream_defer_item(stream, NGHTTP2_STREAM_FLAG_DEFERRED_USER);
|
|
-
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ session_defer_stream_item(session, stream,
|
|
+ NGHTTP2_STREAM_FLAG_DEFERRED_USER);
|
|
|
|
session->aob.item = NULL;
|
|
active_outbound_item_reset(&session->aob, mem);
|
|
return NGHTTP2_ERR_DEFERRED;
|
|
}
|
|
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
|
- rv = nghttp2_stream_detach_item(stream);
|
|
-
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
|
|
rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
|
|
NGHTTP2_INTERNAL_ERROR);
|
|
@@ -2076,13 +2371,7 @@ static int session_prep_frame(nghttp2_session *session,
|
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
|
}
|
|
if (rv != 0) {
|
|
- int rv2;
|
|
-
|
|
- rv2 = nghttp2_stream_detach_item(stream);
|
|
-
|
|
- if (nghttp2_is_fatal(rv2)) {
|
|
- return rv2;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
|
|
return rv;
|
|
}
|
|
@@ -2328,6 +2617,18 @@ static int session_prep_frame(nghttp2_session *session,
|
|
}
|
|
|
|
return 0;
|
|
+ case NGHTTP2_PRIORITY_UPDATE: {
|
|
+ nghttp2_ext_priority_update *priority_update = frame->ext.payload;
|
|
+ rv = session_predicate_priority_update_send(session,
|
|
+ priority_update->stream_id);
|
|
+ if (rv != 0) {
|
|
+ return rv;
|
|
+ }
|
|
+
|
|
+ nghttp2_frame_pack_priority_update(&session->aob.framebufs, &frame->ext);
|
|
+
|
|
+ return 0;
|
|
+ }
|
|
default:
|
|
/* Unreachable here */
|
|
assert(0);
|
|
@@ -2339,6 +2640,8 @@ 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);
|
|
}
|
|
@@ -2354,7 +2657,12 @@ nghttp2_session_get_next_ob_item(nghttp2_session *session) {
|
|
}
|
|
|
|
if (session->remote_window_size > 0) {
|
|
- return nghttp2_stream_next_outbound_item(&session->root);
|
|
+ item = nghttp2_stream_next_outbound_item(&session->root);
|
|
+ if (item) {
|
|
+ return item;
|
|
+ }
|
|
+
|
|
+ return session_sched_get_next_outbound_item(session);
|
|
}
|
|
|
|
return NULL;
|
|
@@ -2388,7 +2696,12 @@ nghttp2_session_pop_next_ob_item(nghttp2_session *session) {
|
|
}
|
|
|
|
if (session->remote_window_size > 0) {
|
|
- return nghttp2_stream_next_outbound_item(&session->root);
|
|
+ item = nghttp2_stream_next_outbound_item(&session->root);
|
|
+ if (item) {
|
|
+ return item;
|
|
+ }
|
|
+
|
|
+ return session_sched_get_next_outbound_item(session);
|
|
}
|
|
|
|
return NULL;
|
|
@@ -2498,10 +2811,20 @@ static int session_close_stream_on_goaway(nghttp2_session *session,
|
|
return 0;
|
|
}
|
|
|
|
-static void reschedule_stream(nghttp2_stream *stream) {
|
|
+static void session_reschedule_stream(nghttp2_session *session,
|
|
+ nghttp2_stream *stream) {
|
|
stream->last_writelen = stream->item->frame.hd.length;
|
|
|
|
- nghttp2_stream_reschedule(stream);
|
|
+ if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
|
|
+ nghttp2_stream_reschedule(stream);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!session->server) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ session_sched_reschedule_stream(session, stream);
|
|
}
|
|
|
|
static int session_update_stream_consumed_size(nghttp2_session *session,
|
|
@@ -2550,10 +2873,7 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
|
}
|
|
|
|
if (stream && aux_data->eof) {
|
|
- rv = nghttp2_stream_detach_item(stream);
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
|
|
/* Call on_frame_send_callback after
|
|
nghttp2_stream_detach_item(), so that application can issue
|
|
@@ -2675,9 +2995,8 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
|
}
|
|
}
|
|
case NGHTTP2_PRIORITY:
|
|
- if (session->server) {
|
|
+ if (session->server || session->pending_no_rfc7540_priorities == 1) {
|
|
return 0;
|
|
- ;
|
|
}
|
|
|
|
stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
|
|
@@ -2787,17 +3106,8 @@ static int session_after_frame_sent1(nghttp2_session *session) {
|
|
/*
|
|
* Called after a frame is sent and session_after_frame_sent1. This
|
|
* function is responsible to reset session->aob.
|
|
- *
|
|
- * This function returns 0 if it succeeds, or one of the following
|
|
- * negative error codes:
|
|
- *
|
|
- * NGHTTP2_ERR_NOMEM
|
|
- * Out of memory.
|
|
- * NGHTTP2_ERR_CALLBACK_FAILURE
|
|
- * The callback function failed.
|
|
*/
|
|
-static int session_after_frame_sent2(nghttp2_session *session) {
|
|
- int rv;
|
|
+static void session_after_frame_sent2(nghttp2_session *session) {
|
|
nghttp2_active_outbound_item *aob = &session->aob;
|
|
nghttp2_outbound_item *item = aob->item;
|
|
nghttp2_bufs *framebufs = &aob->framebufs;
|
|
@@ -2820,13 +3130,13 @@ static int session_after_frame_sent2(nghttp2_session *session) {
|
|
DEBUGF("send: next CONTINUATION frame, %zu bytes\n",
|
|
nghttp2_buf_len(&framebufs->cur->buf));
|
|
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
active_outbound_item_reset(&session->aob, mem);
|
|
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
|
|
/* DATA frame */
|
|
@@ -2840,7 +3150,7 @@ static int session_after_frame_sent2(nghttp2_session *session) {
|
|
if (aux_data->eof) {
|
|
active_outbound_item_reset(aob, mem);
|
|
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
|
|
/* Reset no_copy here because next write may not use this. */
|
|
@@ -2852,22 +3162,18 @@ static int session_after_frame_sent2(nghttp2_session *session) {
|
|
further data. */
|
|
if (nghttp2_session_predicate_data_send(session, stream) != 0) {
|
|
if (stream) {
|
|
- rv = nghttp2_stream_detach_item(stream);
|
|
-
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
}
|
|
|
|
active_outbound_item_reset(aob, mem);
|
|
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
|
|
aob->item = NULL;
|
|
active_outbound_item_reset(&session->aob, mem);
|
|
|
|
- return 0;
|
|
+ return;
|
|
}
|
|
|
|
static int session_call_send_data(nghttp2_session *session,
|
|
@@ -2940,6 +3246,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
|
if (rv < 0) {
|
|
int32_t opened_stream_id = 0;
|
|
uint32_t error_code = NGHTTP2_INTERNAL_ERROR;
|
|
+ int rv2 = 0;
|
|
|
|
DEBUGF("send: frame preparation failed with %s\n",
|
|
nghttp2_strerror(rv));
|
|
@@ -2982,19 +3289,18 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
|
}
|
|
if (opened_stream_id) {
|
|
/* careful not to override rv */
|
|
- int rv2;
|
|
rv2 = nghttp2_session_close_stream(session, opened_stream_id,
|
|
error_code);
|
|
-
|
|
- if (nghttp2_is_fatal(rv2)) {
|
|
- return rv2;
|
|
- }
|
|
}
|
|
|
|
nghttp2_outbound_item_free(item, mem);
|
|
nghttp2_mem_free(mem, item);
|
|
active_outbound_item_reset(aob, mem);
|
|
|
|
+ if (nghttp2_is_fatal(rv2)) {
|
|
+ return rv2;
|
|
+ }
|
|
+
|
|
if (rv == NGHTTP2_ERR_HEADER_COMP) {
|
|
/* If header compression error occurred, should terminiate
|
|
connection. */
|
|
@@ -3098,7 +3404,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
|
|
|
/* Frame has completely sent */
|
|
if (fast_cb) {
|
|
- rv = session_after_frame_sent2(session);
|
|
+ session_after_frame_sent2(session);
|
|
} else {
|
|
rv = session_after_frame_sent1(session);
|
|
if (rv < 0) {
|
|
@@ -3106,12 +3412,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
|
assert(nghttp2_is_fatal(rv));
|
|
return rv;
|
|
}
|
|
- rv = session_after_frame_sent2(session);
|
|
- }
|
|
- if (rv < 0) {
|
|
- /* FATAL */
|
|
- assert(nghttp2_is_fatal(rv));
|
|
- return rv;
|
|
+ session_after_frame_sent2(session);
|
|
}
|
|
/* We have already adjusted the next state */
|
|
break;
|
|
@@ -3150,11 +3451,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
|
}
|
|
|
|
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
|
- rv = nghttp2_stream_detach_item(stream);
|
|
-
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ session_detach_stream_item(session, stream);
|
|
|
|
rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
|
|
NGHTTP2_INTERNAL_ERROR);
|
|
@@ -3178,11 +3475,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
|
assert(nghttp2_is_fatal(rv));
|
|
return rv;
|
|
}
|
|
- rv = session_after_frame_sent2(session);
|
|
- if (rv < 0) {
|
|
- assert(nghttp2_is_fatal(rv));
|
|
- return rv;
|
|
- }
|
|
+ session_after_frame_sent2(session);
|
|
|
|
/* We have already adjusted the next state */
|
|
|
|
@@ -3730,6 +4023,21 @@ static int session_end_stream_headers_received(nghttp2_session *session,
|
|
nghttp2_frame *frame,
|
|
nghttp2_stream *stream) {
|
|
int rv;
|
|
+
|
|
+ assert(frame->hd.type == NGHTTP2_HEADERS);
|
|
+
|
|
+ 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);
|
|
+ if (rv != 0) {
|
|
+ assert(nghttp2_is_fatal(rv));
|
|
+ return rv;
|
|
+ }
|
|
+ }
|
|
+
|
|
if ((frame->hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
|
|
return 0;
|
|
}
|
|
@@ -4053,17 +4361,12 @@ int nghttp2_session_on_headers_received(nghttp2_session *session,
|
|
}
|
|
|
|
static int session_process_headers_frame(nghttp2_session *session) {
|
|
- int rv;
|
|
nghttp2_inbound_frame *iframe = &session->iframe;
|
|
nghttp2_frame *frame = &iframe->frame;
|
|
nghttp2_stream *stream;
|
|
|
|
- rv = nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos);
|
|
+ nghttp2_frame_unpack_headers_payload(&frame->headers, iframe->sbuf.pos);
|
|
|
|
- if (rv != 0) {
|
|
- return nghttp2_session_terminate_session_with_reason(
|
|
- session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: could not unpack");
|
|
- }
|
|
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
|
|
if (!stream) {
|
|
frame->headers.cat = NGHTTP2_HCAT_REQUEST;
|
|
@@ -4091,6 +4394,8 @@ int nghttp2_session_on_priority_received(nghttp2_session *session,
|
|
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");
|
|
@@ -4148,11 +4453,30 @@ static int session_process_priority_frame(nghttp2_session *session) {
|
|
nghttp2_inbound_frame *iframe = &session->iframe;
|
|
nghttp2_frame *frame = &iframe->frame;
|
|
|
|
+ assert(!session_no_rfc7540_pri_no_fallback(session));
|
|
+
|
|
nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos);
|
|
|
|
return nghttp2_session_on_priority_received(session, frame);
|
|
}
|
|
|
|
+static int session_update_stream_reset_ratelim(nghttp2_session *session) {
|
|
+ if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ nghttp2_ratelim_update(&session->stream_reset_ratelim,
|
|
+ nghttp2_time_now_sec());
|
|
+
|
|
+ if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return nghttp2_session_add_goaway(session, session->last_recv_stream_id,
|
|
+ NGHTTP2_INTERNAL_ERROR, NULL, 0,
|
|
+ NGHTTP2_GOAWAY_AUX_NONE);
|
|
+}
|
|
+
|
|
int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
|
|
nghttp2_frame *frame) {
|
|
int rv;
|
|
@@ -4182,7 +4506,8 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
|
|
if (nghttp2_is_fatal(rv)) {
|
|
return rv;
|
|
}
|
|
- return 0;
|
|
+
|
|
+ return session_update_stream_reset_ratelim(session);
|
|
}
|
|
|
|
static int session_process_rst_stream_frame(nghttp2_session *session) {
|
|
@@ -4214,8 +4539,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
|
|
if (stream->remote_window_size > 0 &&
|
|
nghttp2_stream_check_deferred_by_flow_control(stream)) {
|
|
|
|
- rv = nghttp2_stream_resume_deferred_item(
|
|
- stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
|
+ rv = session_resume_deferred_stream_item(
|
|
+ arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
|
|
|
if (nghttp2_is_fatal(rv)) {
|
|
return rv;
|
|
@@ -4259,9 +4584,16 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
|
|
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
|
|
NGHTTP2_FLOW_CONTROL_ERROR);
|
|
}
|
|
- if (!(arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
|
|
- stream->window_update_queued == 0 &&
|
|
- nghttp2_should_send_window_update(stream->local_window_size,
|
|
+
|
|
+ if (stream->window_update_queued) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
|
+ return session_update_stream_consumed_size(arg->session, stream, 0);
|
|
+ }
|
|
+
|
|
+ if (nghttp2_should_send_window_update(stream->local_window_size,
|
|
stream->recv_window_size)) {
|
|
|
|
rv = nghttp2_session_add_window_update(arg->session, NGHTTP2_FLAG_NONE,
|
|
@@ -4382,6 +4714,9 @@ int nghttp2_session_update_local_settings(nghttp2_session *session,
|
|
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
|
|
session->local_settings.enable_connect_protocol = iv[i].value;
|
|
break;
|
|
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
|
|
+ session->local_settings.no_rfc7540_priorities = iv[i].value;
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
@@ -4540,10 +4875,38 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
|
|
|
|
session->remote_settings.enable_connect_protocol = entry->value;
|
|
|
|
+ break;
|
|
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
|
|
+
|
|
+ if (entry->value != 0 && entry->value != 1) {
|
|
+ return session_handle_invalid_connection(
|
|
+ session, frame, NGHTTP2_ERR_PROTO,
|
|
+ "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES");
|
|
+ }
|
|
+
|
|
+ if (session->remote_settings.no_rfc7540_priorities != UINT32_MAX &&
|
|
+ session->remote_settings.no_rfc7540_priorities != entry->value) {
|
|
+ return session_handle_invalid_connection(
|
|
+ session, frame, NGHTTP2_ERR_PROTO,
|
|
+ "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed");
|
|
+ }
|
|
+
|
|
+ session->remote_settings.no_rfc7540_priorities = entry->value;
|
|
+
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ 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)) {
|
|
rv = nghttp2_session_add_settings(session, NGHTTP2_FLAG_ACK, NULL, 0);
|
|
|
|
@@ -4684,17 +5047,11 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
|
|
}
|
|
|
|
static int session_process_push_promise_frame(nghttp2_session *session) {
|
|
- int rv;
|
|
nghttp2_inbound_frame *iframe = &session->iframe;
|
|
nghttp2_frame *frame = &iframe->frame;
|
|
|
|
- rv = nghttp2_frame_unpack_push_promise_payload(&frame->push_promise,
|
|
- iframe->sbuf.pos);
|
|
-
|
|
- if (rv != 0) {
|
|
- return nghttp2_session_terminate_session_with_reason(
|
|
- session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: could not unpack");
|
|
- }
|
|
+ nghttp2_frame_unpack_push_promise_payload(&frame->push_promise,
|
|
+ iframe->sbuf.pos);
|
|
|
|
return nghttp2_session_on_push_promise_received(session, frame);
|
|
}
|
|
@@ -4826,8 +5183,8 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
|
|
if (stream->remote_window_size > 0 &&
|
|
nghttp2_stream_check_deferred_by_flow_control(stream)) {
|
|
|
|
- rv = nghttp2_stream_resume_deferred_item(
|
|
- stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
|
+ rv = session_resume_deferred_stream_item(
|
|
+ session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
|
|
|
|
if (nghttp2_is_fatal(rv)) {
|
|
return rv;
|
|
@@ -4898,6 +5255,80 @@ int nghttp2_session_on_origin_received(nghttp2_session *session,
|
|
return session_call_on_frame_received(session, frame);
|
|
}
|
|
|
|
+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;
|
|
+
|
|
+ assert(session->server);
|
|
+
|
|
+ priority_update = frame->ext.payload;
|
|
+
|
|
+ if (frame->hd.stream_id != 0) {
|
|
+ return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
|
|
+ "PRIORITY_UPDATE: stream_id == 0");
|
|
+ }
|
|
+
|
|
+ if (nghttp2_session_is_my_stream_id(session, priority_update->stream_id)) {
|
|
+ if (session_detect_idle_stream(session, priority_update->stream_id)) {
|
|
+ return session_handle_invalid_connection(
|
|
+ session, frame, NGHTTP2_ERR_PROTO,
|
|
+ "PRIORITY_UPDATE: prioritizing idle push is not allowed");
|
|
+ }
|
|
+
|
|
+ /* TODO Ignore priority signal to a push stream for now */
|
|
+ return session_call_on_frame_received(session, frame);
|
|
+ }
|
|
+
|
|
+ stream = nghttp2_session_get_stream_raw(session, priority_update->stream_id);
|
|
+ if (stream) {
|
|
+ /* Stream already exists. */
|
|
+ if (stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) {
|
|
+ return session_call_on_frame_received(session, frame);
|
|
+ }
|
|
+ } else if (session_detect_idle_stream(session, priority_update->stream_id)) {
|
|
+ if (session->num_idle_streams + session->num_incoming_streams >=
|
|
+ session->local_settings.max_concurrent_streams) {
|
|
+ return session_handle_invalid_connection(
|
|
+ session, frame, NGHTTP2_ERR_PROTO,
|
|
+ "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);
|
|
+ if (!stream) {
|
|
+ return NGHTTP2_ERR_NOMEM;
|
|
+ }
|
|
+ } else {
|
|
+ return session_call_on_frame_received(session, frame);
|
|
+ }
|
|
+
|
|
+ extpri.urgency = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
|
|
+ extpri.inc = 0;
|
|
+
|
|
+ rv = nghttp2_http_parse_priority(&extpri, priority_update->field_value,
|
|
+ priority_update->field_value_len);
|
|
+ if (rv != 0) {
|
|
+ /* Just ignore field_value if it cannot be parsed. */
|
|
+ return session_call_on_frame_received(session, frame);
|
|
+ }
|
|
+
|
|
+ rv = session_update_stream_priority(session, stream,
|
|
+ nghttp2_extpri_to_uint8(&extpri));
|
|
+ if (rv != 0) {
|
|
+ if (nghttp2_is_fatal(rv)) {
|
|
+ return rv;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return session_call_on_frame_received(session, frame);
|
|
+}
|
|
+
|
|
static int session_process_altsvc_frame(nghttp2_session *session) {
|
|
nghttp2_inbound_frame *iframe = &session->iframe;
|
|
nghttp2_frame *frame = &iframe->frame;
|
|
@@ -4932,6 +5363,16 @@ static int session_process_origin_frame(nghttp2_session *session) {
|
|
return nghttp2_session_on_origin_received(session, frame);
|
|
}
|
|
|
|
+static int session_process_priority_update_frame(nghttp2_session *session) {
|
|
+ nghttp2_inbound_frame *iframe = &session->iframe;
|
|
+ nghttp2_frame *frame = &iframe->frame;
|
|
+
|
|
+ nghttp2_frame_unpack_priority_update_payload(&frame->ext, iframe->sbuf.pos,
|
|
+ nghttp2_buf_len(&iframe->sbuf));
|
|
+
|
|
+ return nghttp2_session_on_priority_update_received(session, frame);
|
|
+}
|
|
+
|
|
static int session_process_extension_frame(nghttp2_session *session) {
|
|
int rv;
|
|
nghttp2_inbound_frame *iframe = &session->iframe;
|
|
@@ -5269,6 +5710,7 @@ static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
|
|
case NGHTTP2_SETTINGS_MAX_FRAME_SIZE:
|
|
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
|
|
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
|
|
+ case NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES:
|
|
break;
|
|
default:
|
|
DEBUGF("recv: unknown settings id=0x%02x\n", iv.settings_id);
|
|
@@ -5429,7 +5871,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
in += readlen;
|
|
|
|
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
if (iframe->sbuf.pos[3] != NGHTTP2_SETTINGS ||
|
|
@@ -5466,7 +5908,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
in += readlen;
|
|
|
|
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
nghttp2_frame_unpack_frame_hd(&iframe->frame.hd, iframe->sbuf.pos);
|
|
@@ -5882,6 +6324,49 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
|
|
iframe->state = NGHTTP2_IB_READ_ORIGIN_PAYLOAD;
|
|
|
|
+ break;
|
|
+ case NGHTTP2_PRIORITY_UPDATE:
|
|
+ if ((session->builtin_recv_ext_types &
|
|
+ NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
|
|
+ busy = 1;
|
|
+ iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ DEBUGF("recv: PRIORITY_UPDATE\n");
|
|
+
|
|
+ iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
|
|
+ iframe->frame.ext.payload =
|
|
+ &iframe->ext_frame_payload.priority_update;
|
|
+
|
|
+ if (!session->server) {
|
|
+ rv = nghttp2_session_terminate_session_with_reason(
|
|
+ session, NGHTTP2_PROTOCOL_ERROR,
|
|
+ "PRIORITY_UPDATE is received from server");
|
|
+ if (nghttp2_is_fatal(rv)) {
|
|
+ return rv;
|
|
+ }
|
|
+ return (ssize_t)inlen;
|
|
+ }
|
|
+
|
|
+ if (iframe->payloadleft < 4) {
|
|
+ busy = 1;
|
|
+ iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (!session_no_rfc7540_pri_no_fallback(session) ||
|
|
+ iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
|
|
+ busy = 1;
|
|
+ iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ busy = 1;
|
|
+
|
|
+ iframe->state = NGHTTP2_IB_READ_NBYTE;
|
|
+ inbound_frame_set_mark(iframe, iframe->payloadleft);
|
|
+
|
|
break;
|
|
default:
|
|
busy = 1;
|
|
@@ -5923,7 +6408,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
|
|
|
|
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
switch (iframe->frame.hd.type) {
|
|
@@ -5988,13 +6473,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
|
|
break;
|
|
case NGHTTP2_PRIORITY:
|
|
- rv = session_process_priority_frame(session);
|
|
- if (nghttp2_is_fatal(rv)) {
|
|
- return rv;
|
|
- }
|
|
+ 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)) {
|
|
+ return rv;
|
|
+ }
|
|
|
|
- if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
|
- return (ssize_t)inlen;
|
|
+ if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
|
+ return (ssize_t)inlen;
|
|
+ }
|
|
}
|
|
|
|
session_inbound_frame_reset(session);
|
|
@@ -6150,6 +6638,18 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
|
|
iframe->state = NGHTTP2_IB_READ_ALTSVC_PAYLOAD;
|
|
|
|
+ break;
|
|
+ case NGHTTP2_PRIORITY_UPDATE:
|
|
+ DEBUGF("recv: prioritized_stream_id=%d\n",
|
|
+ nghttp2_get_uint32(iframe->sbuf.pos) & NGHTTP2_STREAM_ID_MASK);
|
|
+
|
|
+ rv = session_process_priority_update_frame(session);
|
|
+ if (nghttp2_is_fatal(rv)) {
|
|
+ return rv;
|
|
+ }
|
|
+
|
|
+ session_inbound_frame_reset(session);
|
|
+
|
|
break;
|
|
}
|
|
default:
|
|
@@ -6212,7 +6712,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
in += hd_proclen;
|
|
iframe->payloadleft -= hd_proclen;
|
|
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
|
@@ -6403,7 +6903,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
in += readlen;
|
|
|
|
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
nghttp2_frame_unpack_frame_hd(&cont_hd, iframe->sbuf.pos);
|
|
@@ -6461,7 +6961,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
|
|
|
|
if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
/* Pad Length field is subject to flow control */
|
|
@@ -6611,7 +7111,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
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 in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
if (nghttp2_is_fatal(rv)) {
|
|
@@ -6791,7 +7291,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
|
|
|
|
assert(in == last);
|
|
|
|
- return in - first;
|
|
+ return (ssize_t)(in - first);
|
|
}
|
|
|
|
int nghttp2_session_recv(nghttp2_session *session) {
|
|
@@ -6863,7 +7363,8 @@ 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) &&
|
|
+ ((!nghttp2_pq_empty(&session->root.obq) ||
|
|
+ !session_sched_empty(session)) &&
|
|
session->remote_window_size > 0) ||
|
|
(nghttp2_outbound_queue_top(&session->ob_syn) &&
|
|
!session_is_outgoing_concurrent_streams_max(session));
|
|
@@ -6962,6 +7463,9 @@ int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id,
|
|
nghttp2_mem_free(mem, item);
|
|
return rv;
|
|
}
|
|
+
|
|
+ session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED;
|
|
+
|