mirror of
https://github.com/nghttp2/nghttp2.git
synced 2026-03-26 16:06:14 +08:00
Compare commits
41 Commits
v1.56.0
...
invoke-res
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a166099ff4 | ||
|
|
bd92902560 | ||
|
|
10a77ce888 | ||
|
|
81c199dd9b | ||
|
|
3b82572b9e | ||
|
|
9d85ab415f | ||
|
|
d0358c0063 | ||
|
|
e103726f4d | ||
|
|
4262c90148 | ||
|
|
bf8f419ca9 | ||
|
|
cccb6ad2c9 | ||
|
|
6f41cc7271 | ||
|
|
9b781ca734 | ||
|
|
aa0973caf5 | ||
|
|
72b4af6143 | ||
|
|
d40829b133 | ||
|
|
939506b68b | ||
|
|
e62ef924fb | ||
|
|
8bad736d48 | ||
|
|
e761014ca5 | ||
|
|
e6ca4ff173 | ||
|
|
62d58bdabc | ||
|
|
e37fe5543f | ||
|
|
d54750b365 | ||
|
|
8ebe7b10fc | ||
|
|
5c1b0f261e | ||
|
|
0866ceffc7 | ||
|
|
3c6f94258f | ||
|
|
959a55f95f | ||
|
|
7d0d8775c9 | ||
|
|
52cb8c35c8 | ||
|
|
d19bc4bb67 | ||
|
|
1ee16fdeca | ||
|
|
b809beacab | ||
|
|
8cafb048be | ||
|
|
627b2408e5 | ||
|
|
0d36a2a050 | ||
|
|
06da18089f | ||
|
|
19697bd44a | ||
|
|
2e6c8ddd15 | ||
|
|
b7f9853968 |
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
17
.github/workflows/build.yml
vendored
17
.github/workflows/build.yml
vendored
@@ -6,11 +6,11 @@ permissions: read-all
|
||||
|
||||
env:
|
||||
LIBBPF_VERSION: v1.2.2
|
||||
OPENSSL1_VERSION: 1_1_1v+quic
|
||||
OPENSSL1_VERSION: 1_1_1w+quic
|
||||
OPENSSL3_VERSION: 3.1.2+quic
|
||||
BORINGSSL_VERSION: 6ca49385b168f47a50e7172d82a590b218f55e4d
|
||||
NGHTTP3_VERSION: v0.15.0
|
||||
NGTCP2_VERSION: v0.19.0
|
||||
NGTCP2_VERSION: v0.19.1
|
||||
|
||||
jobs:
|
||||
build-cache:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Restore libbpf cache
|
||||
id: cache-libbpf
|
||||
uses: actions/cache@v3
|
||||
@@ -200,7 +200,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Linux setup
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
@@ -394,7 +394,7 @@ jobs:
|
||||
cd $NGHTTP2_CMAKE_DIR
|
||||
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
||||
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
|
||||
- uses: actions/setup-go@v3
|
||||
- uses: actions/setup-go@v4
|
||||
if: matrix.buildtool == 'cmake'
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
@@ -417,7 +417,7 @@ jobs:
|
||||
HOST: ${{ matrix.host }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Linux setup
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
@@ -442,7 +442,8 @@ jobs:
|
||||
run: |
|
||||
autoreconf -i && \
|
||||
./configure --enable-werror --enable-lib-only --with-cunit \
|
||||
--host="$HOST" PKG_CONFIG_PATH="$PWD/CUnit-2.1-3/build/lib/pkgconfig"
|
||||
--host="$HOST" PKG_CONFIG_PATH="$PWD/CUnit-2.1-3/build/lib/pkgconfig" \
|
||||
CFLAGS="-g -O2 -D_WIN32_WINNT=0x0600"
|
||||
- name: Build nghttp2
|
||||
run: |
|
||||
make -j$(nproc)
|
||||
@@ -466,7 +467,7 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: microsoft/setup-msbuild@v1
|
||||
- run: |
|
||||
vcpkg --triplet=${{ matrix.arch }}-windows install cunit
|
||||
|
||||
2
.github/workflows/fuzz.yml
vendored
2
.github/workflows/fuzz.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: artifacts
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||
project(nghttp2 VERSION 1.56.0)
|
||||
project(nghttp2 VERSION 1.57.90)
|
||||
|
||||
# See versioning rule:
|
||||
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
set(LT_CURRENT 38)
|
||||
set(LT_REVISION 4)
|
||||
set(LT_AGE 24)
|
||||
set(LT_CURRENT 39)
|
||||
set(LT_REVISION 0)
|
||||
set(LT_AGE 25)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
include(Version)
|
||||
@@ -277,6 +277,7 @@ check_include_file("netinet/ip.h" HAVE_NETINET_IP_H)
|
||||
check_include_file("pwd.h" HAVE_PWD_H)
|
||||
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
|
||||
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
|
||||
check_include_file("sysinfoapi.h" HAVE_SYSINFOAPI_H)
|
||||
check_include_file("syslog.h" HAVE_SYSLOG_H)
|
||||
check_include_file("time.h" HAVE_TIME_H)
|
||||
check_include_file("unistd.h" HAVE_UNISTD_H)
|
||||
@@ -317,8 +318,11 @@ check_type_size("time_t" SIZEOF_TIME_T)
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(_Exit HAVE__EXIT)
|
||||
check_function_exists(accept4 HAVE_ACCEPT4)
|
||||
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
||||
check_function_exists(mkostemp HAVE_MKOSTEMP)
|
||||
|
||||
check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64)
|
||||
|
||||
include(CheckSymbolExists)
|
||||
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
||||
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
|
||||
@@ -339,74 +343,12 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
endif()
|
||||
else()
|
||||
if(ENABLE_WERROR)
|
||||
extract_valid_c_flags(WARNCFLAGS -Werror)
|
||||
extract_valid_c_flags(WARNCXXFLAGS -Werror)
|
||||
set(WARNCFLAGS "-Werror")
|
||||
set(WARNCXXFLAGS "-Werror")
|
||||
endif()
|
||||
|
||||
# For C compiler
|
||||
extract_valid_c_flags(WARNCFLAGS
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wmissing-prototypes
|
||||
-Wstrict-prototypes
|
||||
-Wmissing-declarations
|
||||
-Wpointer-arith
|
||||
-Wdeclaration-after-statement
|
||||
-Wformat-security
|
||||
-Wwrite-strings
|
||||
-Wshadow
|
||||
-Winline
|
||||
-Wnested-externs
|
||||
-Wfloat-equal
|
||||
-Wundef
|
||||
-Wendif-labels
|
||||
-Wempty-body
|
||||
-Wcast-align
|
||||
-Wclobbered
|
||||
-Wvla
|
||||
-Wpragmas
|
||||
-Wunreachable-code
|
||||
-Waddress
|
||||
-Wattributes
|
||||
-Wdiv-by-zero
|
||||
-Wshorten-64-to-32
|
||||
|
||||
-Wconversion
|
||||
-Wextended-offsetof
|
||||
-Wformat-nonliteral
|
||||
-Wlanguage-extension-token
|
||||
-Wmissing-field-initializers
|
||||
-Wmissing-noreturn
|
||||
-Wmissing-variable-declarations
|
||||
# Not used because we cannot change public structs
|
||||
# -Wpadded
|
||||
-Wsign-conversion
|
||||
# Not used because this basically disallows default case
|
||||
# -Wswitch-enum
|
||||
-Wunreachable-code-break
|
||||
-Wunused-macros
|
||||
-Wunused-parameter
|
||||
-Wredundant-decls
|
||||
# Only work with Clang for the moment
|
||||
-Wheader-guard
|
||||
# This is required because we pass format string as "const char*.
|
||||
-Wno-format-nonliteral
|
||||
)
|
||||
|
||||
extract_valid_cxx_flags(WARNCXXFLAGS
|
||||
# For C++ compiler
|
||||
-Wall
|
||||
-Wformat-security
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_STATIC_CRT)
|
||||
foreach(lang C CXX)
|
||||
foreach(suffix "" _DEBUG _MINSIZEREL _RELEASE _RELWITHDEBINFO)
|
||||
set(var "CMAKE_${lang}_FLAGS${suffix}")
|
||||
string(REPLACE "/MD" "/MT" ${var} "${${var}}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
include(PickyWarningsC)
|
||||
include(PickyWarningsCXX)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DEBUG)
|
||||
@@ -502,6 +444,7 @@ message(STATUS "summary of build options:
|
||||
CXXFLAGS: ${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
|
||||
WARNCFLAGS: ${WARNCFLAGS}
|
||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||
WARNCXXFLAGS: ${WARNCXXFLAGS}
|
||||
Python:
|
||||
Python: ${Python3_EXECUTABLE}
|
||||
Python3_VERSION: ${Python3_VERSION}
|
||||
|
||||
@@ -44,7 +44,9 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-env \
|
||||
cmake/FindLibbpf.cmake \
|
||||
cmake/FindLibnghttp3.cmake \
|
||||
cmake/FindLibngtcp2.cmake \
|
||||
cmake/FindLibngtcp2_crypto_quictls.cmake
|
||||
cmake/FindLibngtcp2_crypto_quictls.cmake \
|
||||
cmake/PickyWarningsC.cmake \
|
||||
cmake/PickyWarningsCXX.cmake
|
||||
|
||||
.PHONY: clang-format
|
||||
|
||||
@@ -55,5 +57,5 @@ clang-format:
|
||||
CLANGFORMAT=`git config --get clangformat.binary`; \
|
||||
test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
|
||||
$${CLANGFORMAT} -i lib/*.{c,h} lib/includes/nghttp2/*.h \
|
||||
src/*.{c,cc,h} examples/*.{c,cc} \
|
||||
src/*.{c,cc,h} examples/*.c \
|
||||
tests/*.{c,h} bpf/*.c fuzz/*.cc
|
||||
|
||||
@@ -127,7 +127,7 @@ To enable the experimental HTTP/3 support for h2load and nghttpx, the
|
||||
following libraries are required:
|
||||
|
||||
* `OpenSSL with QUIC support
|
||||
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1v+quic>`_; or
|
||||
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1w+quic>`_; or
|
||||
`BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
|
||||
6ca49385b168f47a50e7172d82a590b218f55e4d)
|
||||
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ 0.19.x
|
||||
@@ -343,7 +343,7 @@ Build custom OpenSSL:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ git clone --depth 1 -b OpenSSL_1_1_1v+quic https://github.com/quictls/openssl
|
||||
$ git clone --depth 1 -b OpenSSL_1_1_1w+quic https://github.com/quictls/openssl
|
||||
$ cd openssl
|
||||
$ ./config --prefix=$PWD/build --openssldir=/etc/ssl
|
||||
$ make -j$(nproc)
|
||||
@@ -366,7 +366,7 @@ Build ngtcp2:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ git clone --depth 1 -b v0.19.0 https://github.com/ngtcp2/ngtcp2
|
||||
$ git clone --depth 1 -b v0.19.1 https://github.com/ngtcp2/ngtcp2
|
||||
$ cd ngtcp2
|
||||
$ autoreconf -i
|
||||
$ ./configure --prefix=$PWD/build --enable-lib-only \
|
||||
|
||||
163
cmake/PickyWarningsC.cmake
Normal file
163
cmake/PickyWarningsC.cmake
Normal file
@@ -0,0 +1,163 @@
|
||||
# nghttp2
|
||||
#
|
||||
# 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.
|
||||
|
||||
# C
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
||||
# https://clang.llvm.org/docs/DiagnosticsReference.html
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
||||
|
||||
# WPICKY_ENABLE = Options we want to enable as-is.
|
||||
# WPICKY_DETECT = Options we want to test first and enable if available.
|
||||
|
||||
# Prefer the -Wextra alias with clang.
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(WPICKY_ENABLE "-Wextra")
|
||||
else()
|
||||
set(WPICKY_ENABLE "-W")
|
||||
endif()
|
||||
|
||||
list(APPEND WPICKY_ENABLE
|
||||
-Wall
|
||||
)
|
||||
|
||||
# ----------------------------------
|
||||
# Add new options here, if in doubt:
|
||||
# ----------------------------------
|
||||
set(WPICKY_DETECT
|
||||
)
|
||||
|
||||
# Assume these options always exist with both clang and gcc.
|
||||
# Require clang 3.0 / gcc 2.95 or later.
|
||||
list(APPEND WPICKY_ENABLE
|
||||
-Wconversion # clang 3.0 gcc 2.95
|
||||
-Winline # clang 1.0 gcc 1.0
|
||||
-Wmissing-declarations # clang 1.0 gcc 2.7
|
||||
-Wmissing-prototypes # clang 1.0 gcc 1.0
|
||||
-Wnested-externs # clang 1.0 gcc 2.7
|
||||
-Wpointer-arith # clang 1.0 gcc 1.4
|
||||
-Wshadow # clang 1.0 gcc 2.95
|
||||
-Wundef # clang 1.0 gcc 2.95
|
||||
-Wwrite-strings # clang 1.0 gcc 1.4
|
||||
)
|
||||
|
||||
# Always enable with clang, version dependent with gcc
|
||||
set(WPICKY_COMMON_OLD
|
||||
-Waddress # clang 3.0 gcc 4.3
|
||||
-Wattributes # clang 3.0 gcc 4.1
|
||||
-Wcast-align # clang 1.0 gcc 4.2
|
||||
-Wdeclaration-after-statement # clang 1.0 gcc 3.4
|
||||
-Wdiv-by-zero # clang 3.0 gcc 4.1
|
||||
-Wempty-body # clang 3.0 gcc 4.3
|
||||
-Wendif-labels # clang 1.0 gcc 3.3
|
||||
-Wfloat-equal # clang 1.0 gcc 2.96 (3.0)
|
||||
-Wformat-nonliteral # clang 3.0 gcc 4.1
|
||||
-Wformat-security # clang 3.0 gcc 4.1
|
||||
-Wmissing-field-initializers # clang 3.0 gcc 4.1
|
||||
-Wmissing-noreturn # clang 3.0 gcc 4.1
|
||||
-Wno-format-nonliteral # clang 1.0 gcc 2.96 (3.0) # This is required because we pass format string as "const char*"
|
||||
# -Wpadded # clang 3.0 gcc 4.1 # Not used because we cannot change public structs
|
||||
-Wredundant-decls # clang 3.0 gcc 4.1
|
||||
-Wsign-conversion # clang 3.0 gcc 4.3
|
||||
-Wstrict-prototypes # clang 1.0 gcc 3.3
|
||||
# -Wswitch-enum # clang 3.0 gcc 4.1 # Not used because this basically disallows default case
|
||||
-Wunreachable-code # clang 3.0 gcc 4.1
|
||||
-Wunused-macros # clang 3.0 gcc 4.1
|
||||
-Wunused-parameter # clang 3.0 gcc 4.1
|
||||
-Wvla # clang 2.8 gcc 4.3
|
||||
)
|
||||
|
||||
set(WPICKY_COMMON
|
||||
-Wpragmas # clang 3.5 gcc 4.1 appleclang 6.0
|
||||
)
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND WPICKY_ENABLE
|
||||
${WPICKY_COMMON_OLD}
|
||||
-Wshorten-64-to-32 # clang 1.0
|
||||
-Wlanguage-extension-token # clang 3.0
|
||||
)
|
||||
# Enable based on compiler version
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.6) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.3))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
${WPICKY_COMMON}
|
||||
-Wunreachable-code-break # clang 3.5 appleclang 6.0
|
||||
-Wheader-guard # clang 3.4 appleclang 5.1
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.9) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.3))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
-Wmissing-variable-declarations # clang 3.2 appleclang 4.6
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.4))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0) OR
|
||||
(CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 10.3))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
)
|
||||
endif()
|
||||
else() # gcc
|
||||
list(APPEND WPICKY_DETECT
|
||||
${WPICKY_COMMON}
|
||||
)
|
||||
# Enable based on compiler version
|
||||
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.3)
|
||||
list(APPEND WPICKY_ENABLE
|
||||
${WPICKY_COMMON_OLD}
|
||||
-Wclobbered # gcc 4.3
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
|
||||
unset(_wpicky)
|
||||
|
||||
foreach(_CCOPT IN LISTS WPICKY_ENABLE)
|
||||
set(_wpicky "${_wpicky} ${_CCOPT}")
|
||||
endforeach()
|
||||
|
||||
foreach(_CCOPT IN LISTS WPICKY_DETECT)
|
||||
# surprisingly, CHECK_C_COMPILER_FLAG needs a new variable to store each new
|
||||
# test result in.
|
||||
string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
|
||||
# GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
|
||||
# so test for the positive form instead
|
||||
string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}")
|
||||
check_c_compiler_flag(${_CCOPT_ON} ${_optvarname})
|
||||
if(${_optvarname})
|
||||
set(_wpicky "${_wpicky} ${_CCOPT}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(WARNCFLAGS "${WARNCFLAGS} ${_wpicky}")
|
||||
endif()
|
||||
117
cmake/PickyWarningsCXX.cmake
Normal file
117
cmake/PickyWarningsCXX.cmake
Normal file
@@ -0,0 +1,117 @@
|
||||
# nghttp2
|
||||
#
|
||||
# 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.
|
||||
|
||||
# C++
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
|
||||
# https://clang.llvm.org/docs/DiagnosticsReference.html
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
|
||||
|
||||
# WPICKY_ENABLE = Options we want to enable as-is.
|
||||
# WPICKY_DETECT = Options we want to test first and enable if available.
|
||||
|
||||
set(WPICKY_ENABLE "-Wall")
|
||||
|
||||
# ----------------------------------
|
||||
# Add new options here, if in doubt:
|
||||
# ----------------------------------
|
||||
set(WPICKY_DETECT
|
||||
)
|
||||
|
||||
# Assume these options always exist with both clang and gcc.
|
||||
# Require clang 3.0 / gcc 2.95 or later.
|
||||
list(APPEND WPICKY_ENABLE
|
||||
)
|
||||
|
||||
# Always enable with clang, version dependent with gcc
|
||||
set(WPICKY_COMMON_OLD
|
||||
-Wformat-security # clang 3.0 gcc 4.1
|
||||
)
|
||||
|
||||
set(WPICKY_COMMON
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND WPICKY_ENABLE
|
||||
${WPICKY_COMMON_OLD}
|
||||
)
|
||||
# Enable based on compiler version
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.6) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.3))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
${WPICKY_COMMON}
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8.3))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.4))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
)
|
||||
endif()
|
||||
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.3))
|
||||
list(APPEND WPICKY_ENABLE
|
||||
)
|
||||
endif()
|
||||
else() # gcc
|
||||
list(APPEND WPICKY_DETECT
|
||||
${WPICKY_COMMON}
|
||||
)
|
||||
# Enable based on compiler version
|
||||
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.3)
|
||||
list(APPEND WPICKY_ENABLE
|
||||
${WPICKY_COMMON_OLD}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
|
||||
unset(_wpicky)
|
||||
|
||||
foreach(_CCOPT IN LISTS WPICKY_ENABLE)
|
||||
set(_wpicky "${_wpicky} ${_CCOPT}")
|
||||
endforeach()
|
||||
|
||||
foreach(_CCOPT IN LISTS WPICKY_DETECT)
|
||||
# surprisingly, CHECK_CXX_COMPILER_FLAG needs a new variable to store each new
|
||||
# test result in.
|
||||
string(MAKE_C_IDENTIFIER "OPT${_CCOPT}" _optvarname)
|
||||
# GCC only warns about unknown -Wno- options if there are also other diagnostic messages,
|
||||
# so test for the positive form instead
|
||||
string(REPLACE "-Wno-" "-W" _CCOPT_ON "${_CCOPT}")
|
||||
check_cxx_compiler_flag(${_CCOPT_ON} ${_optvarname})
|
||||
if(${_optvarname})
|
||||
set(_wpicky "${_wpicky} ${_CCOPT}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(WARNCXXFLAGS "${WARNCXXFLAGS} ${_wpicky}")
|
||||
endif()
|
||||
@@ -31,9 +31,15 @@
|
||||
/* Define to 1 if you have the `accept4` function. */
|
||||
#cmakedefine HAVE_ACCEPT4 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime` function. */
|
||||
#cmakedefine HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the `mkostemp` function. */
|
||||
#cmakedefine HAVE_MKOSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the `GetTickCount64` function. */
|
||||
#cmakedefine HAVE_GETTICKCOUNT64 1
|
||||
|
||||
/* Define to 1 if you have the `initgroups` function. */
|
||||
#cmakedefine01 HAVE_DECL_INITGROUPS
|
||||
|
||||
@@ -73,6 +79,9 @@
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sysinfoapi.h> header file. */
|
||||
#cmakedefine HAVE_SYSINFOAPI_H 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#cmakedefine HAVE_SYSLOG_H 1
|
||||
|
||||
|
||||
29
configure.ac
29
configure.ac
@@ -25,7 +25,7 @@ dnl Do not change user variables!
|
||||
dnl https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([nghttp2], [1.56.0], [t-tujikawa@users.sourceforge.net])
|
||||
AC_INIT([nghttp2], [1.58.0-DEV], [t-tujikawa@users.sourceforge.net])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl See versioning rule:
|
||||
dnl https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
AC_SUBST(LT_CURRENT, 38)
|
||||
AC_SUBST(LT_REVISION, 4)
|
||||
AC_SUBST(LT_AGE, 24)
|
||||
AC_SUBST(LT_CURRENT, 39)
|
||||
AC_SUBST(LT_REVISION, 0)
|
||||
AC_SUBST(LT_AGE, 25)
|
||||
|
||||
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
||||
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
||||
@@ -855,6 +855,7 @@ AC_CHECK_HEADERS([ \
|
||||
string.h \
|
||||
sys/socket.h \
|
||||
sys/time.h \
|
||||
sysinfoapi.h \
|
||||
syslog.h \
|
||||
time.h \
|
||||
unistd.h \
|
||||
@@ -929,6 +930,7 @@ AC_FUNC_STRNLEN
|
||||
AC_CHECK_FUNCS([ \
|
||||
_Exit \
|
||||
accept4 \
|
||||
clock_gettime \
|
||||
dup2 \
|
||||
getcwd \
|
||||
getpwnam \
|
||||
@@ -954,6 +956,25 @@ AC_CHECK_FUNCS([ \
|
||||
AC_CHECK_FUNC([timerfd_create],
|
||||
[have_timerfd_create=yes], [have_timerfd_create=no])
|
||||
|
||||
AC_MSG_CHECKING([checking for GetTickCount64])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <sysinfoapi.h>
|
||||
]],
|
||||
[[
|
||||
GetTickCount64();
|
||||
]])],
|
||||
[have_gettickcount64=yes],
|
||||
[have_gettickcount64=no])
|
||||
|
||||
if test "x${have_gettickcount64}" = "xyes"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_GETTICKCOUNT64], [1],
|
||||
[Define to 1 if you have `GetTickCount64` function.])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
|
||||
# cygwin disables initgroups due to feature test macro magic with our
|
||||
# configuration. FreeBSD declares initgroups() in unistd.h.
|
||||
|
||||
@@ -75,6 +75,7 @@ APIDOCS= \
|
||||
nghttp2_option_set_user_recv_extension_type.rst \
|
||||
nghttp2_option_set_max_outbound_ack.rst \
|
||||
nghttp2_option_set_max_settings.rst \
|
||||
nghttp2_option_set_stream_reset_rate_limit.rst \
|
||||
nghttp2_pack_settings_payload.rst \
|
||||
nghttp2_priority_spec_check_default.rst \
|
||||
nghttp2_priority_spec_default_init.rst \
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "H2LOAD" "1" "Sep 04, 2023" "1.56.0" "nghttp2"
|
||||
.TH "H2LOAD" "1" "Oct 10, 2023" "1.57.0" "nghttp2"
|
||||
.SH NAME
|
||||
h2load \- HTTP/2 benchmarking tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "NGHTTP" "1" "Sep 04, 2023" "1.56.0" "nghttp2"
|
||||
.TH "NGHTTP" "1" "Oct 10, 2023" "1.57.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttp \- HTTP/2 client
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "NGHTTPD" "1" "Sep 04, 2023" "1.56.0" "nghttp2"
|
||||
.TH "NGHTTPD" "1" "Oct 10, 2023" "1.57.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpd \- HTTP/2 server
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||
..
|
||||
.TH "NGHTTPX" "1" "Sep 04, 2023" "1.56.0" "nghttp2"
|
||||
.TH "NGHTTPX" "1" "Oct 10, 2023" "1.57.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpx \- HTTP/2 proxy
|
||||
.SH SYNOPSIS
|
||||
@@ -1546,18 +1546,20 @@ in HTTP/2 frontend.
|
||||
.TP
|
||||
.B \-\-add\-request\-header=<HEADER>
|
||||
Specify additional header field to add to request header
|
||||
set. This option just appends header field and won\(aqt
|
||||
replace anything already set. This option can be used
|
||||
several times to specify multiple header fields.
|
||||
set. The field name must be lowercase. This option
|
||||
just appends header field and won\(aqt replace anything
|
||||
already set. This option can be used several times to
|
||||
specify multiple header fields.
|
||||
Example: \fI\%\-\-add\-request\-header\fP=\(dqfoo: bar\(dq
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-add\-response\-header=<HEADER>
|
||||
Specify additional header field to add to response
|
||||
header set. This option just appends header field and
|
||||
won\(aqt replace anything already set. This option can be
|
||||
used several times to specify multiple header fields.
|
||||
header set. The field name must be lowercase. This
|
||||
option just appends header field and won\(aqt replace
|
||||
anything already set. This option can be used several
|
||||
times to specify multiple header fields.
|
||||
Example: \fI\%\-\-add\-response\-header\fP=\(dqfoo: bar\(dq
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
|
||||
@@ -1402,17 +1402,19 @@ HTTP
|
||||
.. option:: --add-request-header=<HEADER>
|
||||
|
||||
Specify additional header field to add to request header
|
||||
set. This option just appends header field and won't
|
||||
replace anything already set. This option can be used
|
||||
several times to specify multiple header fields.
|
||||
set. The field name must be lowercase. This option
|
||||
just appends header field and won't replace anything
|
||||
already set. This option can be used several times to
|
||||
specify multiple header fields.
|
||||
Example: :option:`--add-request-header`\="foo: bar"
|
||||
|
||||
.. option:: --add-response-header=<HEADER>
|
||||
|
||||
Specify additional header field to add to response
|
||||
header set. This option just appends header field and
|
||||
won't replace anything already set. This option can be
|
||||
used several times to specify multiple header fields.
|
||||
header set. The field name must be lowercase. This
|
||||
option just appends header field and won't replace
|
||||
anything already set. This option can be used several
|
||||
times to specify multiple header fields.
|
||||
Example: :option:`--add-response-header`\="foo: bar"
|
||||
|
||||
.. option:: --request-header-field-buffer=<SIZE>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:11 as build
|
||||
FROM debian:12 as build
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
@@ -7,7 +7,7 @@ RUN apt-get update && \
|
||||
zlib1g-dev libev-dev libjemalloc-dev ruby-dev libc-ares-dev bison \
|
||||
libelf-dev
|
||||
|
||||
RUN git clone --depth 1 -b OpenSSL_1_1_1v+quic https://github.com/quictls/openssl && \
|
||||
RUN git clone --depth 1 -b OpenSSL_1_1_1w+quic https://github.com/quictls/openssl && \
|
||||
cd openssl && \
|
||||
./config --openssldir=/etc/ssl && \
|
||||
make -j$(nproc) && \
|
||||
@@ -24,7 +24,7 @@ RUN git clone --depth 1 -b v0.15.0 https://github.com/ngtcp2/nghttp3 && \
|
||||
cd .. && \
|
||||
rm -rf nghttp3
|
||||
|
||||
RUN git clone --depth 1 -b v0.19.0 https://github.com/ngtcp2/ngtcp2 && \
|
||||
RUN git clone --depth 1 -b v0.19.1 https://github.com/ngtcp2/ngtcp2 && \
|
||||
cd ngtcp2 && \
|
||||
autoreconf -i && \
|
||||
./configure --enable-lib-only \
|
||||
@@ -63,7 +63,7 @@ RUN git clone --depth 1 https://github.com/nghttp2/nghttp2.git && \
|
||||
cd .. && \
|
||||
rm -rf nghttp2
|
||||
|
||||
FROM gcr.io/distroless/base-debian11
|
||||
FROM gcr.io/distroless/base-debian12
|
||||
|
||||
COPY --from=build \
|
||||
/usr/local/share/nghttp2/ \
|
||||
|
||||
8
go.mod
8
go.mod
@@ -6,7 +6,7 @@ require (
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746
|
||||
github.com/quic-go/quic-go v0.35.1
|
||||
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20150408091349-4742878d9c90
|
||||
golang.org/x/net v0.10.0
|
||||
golang.org/x/net v0.17.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -17,10 +17,10 @@ require (
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
|
||||
golang.org/x/crypto v0.4.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
)
|
||||
|
||||
16
go.sum
16
go.sum
@@ -36,8 +36,8 @@ github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20150408091349-4742878d9c90/go.mod h1:Y
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
|
||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
|
||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -46,8 +46,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -56,13 +56,13 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
|
||||
@@ -24,6 +24,8 @@ set(NGHTTP2_SOURCES
|
||||
nghttp2_http.c
|
||||
nghttp2_rcbuf.c
|
||||
nghttp2_extpri.c
|
||||
nghttp2_ratelim.c
|
||||
nghttp2_time.c
|
||||
nghttp2_debug.c
|
||||
sfparse.c
|
||||
)
|
||||
|
||||
@@ -51,6 +51,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
||||
nghttp2_http.c \
|
||||
nghttp2_rcbuf.c \
|
||||
nghttp2_extpri.c \
|
||||
nghttp2_ratelim.c \
|
||||
nghttp2_time.c \
|
||||
nghttp2_debug.c \
|
||||
sfparse.c
|
||||
|
||||
@@ -69,6 +71,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||
nghttp2_http.h \
|
||||
nghttp2_rcbuf.h \
|
||||
nghttp2_extpri.h \
|
||||
nghttp2_ratelim.h \
|
||||
nghttp2_time.h \
|
||||
nghttp2_debug.h \
|
||||
sfparse.h
|
||||
|
||||
|
||||
@@ -2756,6 +2756,23 @@ 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
|
||||
*
|
||||
|
||||
@@ -143,3 +143,10 @@ void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -70,12 +70,18 @@ typedef enum {
|
||||
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
|
||||
*/
|
||||
|
||||
75
lib/nghttp2_ratelim.c
Normal file
75
lib/nghttp2_ratelim.c
Normal file
@@ -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;
|
||||
}
|
||||
57
lib/nghttp2_ratelim.h
Normal file
57
lib/nghttp2_ratelim.h
Normal file
@@ -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 */
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "nghttp2_http.h"
|
||||
#include "nghttp2_pq.h"
|
||||
#include "nghttp2_extpri.h"
|
||||
#include "nghttp2_time.h"
|
||||
#include "nghttp2_debug.h"
|
||||
|
||||
/*
|
||||
@@ -475,6 +476,10 @@ static int session_new(nghttp2_session **session_ptr,
|
||||
(*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;
|
||||
}
|
||||
@@ -573,6 +578,12 @@ static int session_new(nghttp2_session **session_ptr,
|
||||
(*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,
|
||||
@@ -4449,6 +4460,23 @@ static int session_process_priority_frame(nghttp2_session *session) {
|
||||
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;
|
||||
@@ -4478,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) {
|
||||
@@ -7434,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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "nghttp2_buf.h"
|
||||
#include "nghttp2_callbacks.h"
|
||||
#include "nghttp2_mem.h"
|
||||
#include "nghttp2_ratelim.h"
|
||||
|
||||
/* The global variable for tests where we want to disable strict
|
||||
preface handling. */
|
||||
@@ -105,6 +106,10 @@ typedef struct {
|
||||
/* The default value of maximum number of concurrent streams. */
|
||||
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
|
||||
|
||||
/* The default values for stream reset rate limiter. */
|
||||
#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
|
||||
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
|
||||
|
||||
/* Internal state when receiving incoming frame */
|
||||
typedef enum {
|
||||
/* Receiving frame header */
|
||||
@@ -178,7 +183,9 @@ typedef enum {
|
||||
/* Flag means GOAWAY was sent */
|
||||
NGHTTP2_GOAWAY_SENT = 0x4,
|
||||
/* Flag means GOAWAY was received */
|
||||
NGHTTP2_GOAWAY_RECV = 0x8
|
||||
NGHTTP2_GOAWAY_RECV = 0x8,
|
||||
/* Flag means GOAWAY has been submitted at least once */
|
||||
NGHTTP2_GOAWAY_SUBMITTED = 0x10
|
||||
} nghttp2_goaway_flag;
|
||||
|
||||
/* nghttp2_inflight_settings stores the SETTINGS entries which local
|
||||
@@ -235,6 +242,9 @@ struct nghttp2_session {
|
||||
/* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
|
||||
considered as in-flight. */
|
||||
nghttp2_inflight_settings *inflight_settings_head;
|
||||
/* Stream reset rate limiter. If receiving excessive amount of
|
||||
stream resets, GOAWAY will be sent. */
|
||||
nghttp2_ratelim stream_reset_ratelim;
|
||||
/* Sequential number across all streams to process streams in
|
||||
FIFO. */
|
||||
uint64_t stream_seq;
|
||||
|
||||
62
lib/nghttp2_time.c
Normal file
62
lib/nghttp2_time.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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_time.h"
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
# include <time.h>
|
||||
#endif /* HAVE_TIME_H */
|
||||
|
||||
#ifdef HAVE_SYSINFOAPI_H
|
||||
# include <sysinfoapi.h>
|
||||
#endif /* HAVE_SYSINFOAPI_H */
|
||||
|
||||
#ifndef HAVE_GETTICKCOUNT64
|
||||
static uint64_t time_now_sec(void) {
|
||||
time_t t = time(NULL);
|
||||
|
||||
if (t == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (uint64_t)t;
|
||||
}
|
||||
#endif /* HAVE_GETTICKCOUNT64 */
|
||||
|
||||
#ifdef HAVE_GETTICKCOUNT64
|
||||
uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
uint64_t nghttp2_time_now_sec(void) {
|
||||
struct timespec tp;
|
||||
int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
|
||||
if (rv == -1) {
|
||||
return time_now_sec();
|
||||
}
|
||||
|
||||
return (uint64_t)tp.tv_sec;
|
||||
}
|
||||
#else /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */
|
||||
uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
|
||||
#endif /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */
|
||||
38
lib/nghttp2_time.h
Normal file
38
lib/nghttp2_time.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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_TIME_H
|
||||
#define NGHTTP2_TIME_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/* nghttp2_time_now_sec returns seconds from implementation-specific
|
||||
timepoint. If it is unable to get seconds, it returns 0. */
|
||||
uint64_t nghttp2_time_now_sec(void);
|
||||
|
||||
#endif /* NGHTTP2_TIME_H */
|
||||
@@ -754,37 +754,37 @@ int Http2Handler::read_tls() {
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
for (;;) {
|
||||
auto rv = SSL_read(ssl_, buf.data(), buf.size());
|
||||
auto rv = SSL_read(ssl_, buf.data(), buf.size());
|
||||
|
||||
if (rv <= 0) {
|
||||
auto err = SSL_get_error(ssl_, rv);
|
||||
switch (err) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
return write_(*this);
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
// renegotiation started
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
auto nread = rv;
|
||||
|
||||
if (get_config()->hexdump) {
|
||||
util::hexdump(stdout, buf.data(), nread);
|
||||
}
|
||||
|
||||
rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
|
||||
if (rv < 0) {
|
||||
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||
std::cerr << "nghttp2_session_mem_recv() returned error: "
|
||||
<< nghttp2_strerror(rv) << std::endl;
|
||||
}
|
||||
if (rv <= 0) {
|
||||
auto err = SSL_get_error(ssl_, rv);
|
||||
switch (err) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
return write_(*this);
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
// renegotiation started
|
||||
return -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
auto nread = rv;
|
||||
|
||||
if (get_config()->hexdump) {
|
||||
util::hexdump(stdout, buf.data(), nread);
|
||||
}
|
||||
|
||||
rv = nghttp2_session_mem_recv(session_, buf.data(), nread);
|
||||
if (rv < 0) {
|
||||
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||
std::cerr << "nghttp2_session_mem_recv() returned error: "
|
||||
<< nghttp2_strerror(rv) << std::endl;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return write_(*this);
|
||||
}
|
||||
|
||||
int Http2Handler::write_tls() {
|
||||
|
||||
20
src/shrpx.cc
20
src/shrpx.cc
@@ -1675,10 +1675,10 @@ pid_t fork_worker_process(
|
||||
}
|
||||
#endif // ENABLE_HTTP3
|
||||
|
||||
close(worker_process_ready_ipc_fd[0]);
|
||||
shutdown_worker_process_ready_ipc_watcher(EV_DEFAULT);
|
||||
|
||||
if (!config->single_process) {
|
||||
close(worker_process_ready_ipc_fd[0]);
|
||||
shutdown_worker_process_ready_ipc_watcher(EV_DEFAULT);
|
||||
|
||||
shutdown_signal_watchers(EV_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -3324,15 +3324,17 @@ HTTP:
|
||||
in HTTP/2 frontend.
|
||||
--add-request-header=<HEADER>
|
||||
Specify additional header field to add to request header
|
||||
set. This option just appends header field and won't
|
||||
replace anything already set. This option can be used
|
||||
several times to specify multiple header fields.
|
||||
set. The field name must be lowercase. This option
|
||||
just appends header field and won't replace anything
|
||||
already set. This option can be used several times to
|
||||
specify multiple header fields.
|
||||
Example: --add-request-header="foo: bar"
|
||||
--add-response-header=<HEADER>
|
||||
Specify additional header field to add to response
|
||||
header set. This option just appends header field and
|
||||
won't replace anything already set. This option can be
|
||||
used several times to specify multiple header fields.
|
||||
header set. The field name must be lowercase. This
|
||||
option just appends header field and won't replace
|
||||
anything already set. This option can be used several
|
||||
times to specify multiple header fields.
|
||||
Example: --add-response-header="foo: bar"
|
||||
--request-header-field-buffer=<SIZE>
|
||||
Set maximum buffer size for incoming HTTP request header
|
||||
|
||||
@@ -1019,6 +1019,10 @@ ssize_t Connection::read_tls(void *data, size_t len) {
|
||||
tls.last_readlen = 0;
|
||||
}
|
||||
|
||||
auto &tlsconf = get_config()->tls;
|
||||
auto via_bio =
|
||||
tls.server_handshake && !tlsconf.session_cache.memcached.host.empty();
|
||||
|
||||
#if OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
|
||||
if (!tls.early_data_finish) {
|
||||
// TLSv1.3 handshake is still going on.
|
||||
@@ -1056,6 +1060,11 @@ ssize_t Connection::read_tls(void *data, size_t len) {
|
||||
// We may have stopped write watcher in write_tls.
|
||||
wlimit.startw();
|
||||
}
|
||||
|
||||
if (!via_bio) {
|
||||
rlimit.drain(nread);
|
||||
}
|
||||
|
||||
return nread;
|
||||
}
|
||||
#endif // OPENSSL_1_1_1_API && !defined(OPENSSL_IS_BORINGSSL)
|
||||
@@ -1088,6 +1097,10 @@ ssize_t Connection::read_tls(void *data, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!via_bio) {
|
||||
rlimit.drain(rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ int stream_reset(ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size,
|
||||
void *stream_user_data) {
|
||||
auto upstream = static_cast<Http3Upstream *>(user_data);
|
||||
|
||||
if (upstream->http_shutdown_stream_read(stream_id) != 0) {
|
||||
if (upstream->stream_reset(stream_id) != 0) {
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
@@ -429,6 +429,24 @@ int stream_reset(ngtcp2_conn *conn, int64_t stream_id, uint64_t final_size,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int Http3Upstream::stream_reset(int64_t stream_id) {
|
||||
if (http_shutdown_stream_read(stream_id) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ngtcp2_is_bidi_stream(stream_id)) {
|
||||
auto rv = ngtcp2_conn_shutdown_stream_write(conn_, 0, stream_id,
|
||||
NGHTTP3_H3_NO_ERROR);
|
||||
if (rv != 0) {
|
||||
ULOG(ERROR, this) << "ngtcp2_conn_shutdown_stream_write: "
|
||||
<< ngtcp2_strerror(rv);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Http3Upstream::http_shutdown_stream_read(int64_t stream_id) {
|
||||
if (!httpconn_) {
|
||||
return 0;
|
||||
|
||||
@@ -125,6 +125,7 @@ public:
|
||||
void consume(int64_t stream_id, size_t nconsumed);
|
||||
void remove_downstream(Downstream *downstream);
|
||||
int stream_close(int64_t stream_id, uint64_t app_error_code);
|
||||
int stream_reset(int64_t stream_id);
|
||||
void log_response_headers(Downstream *downstream,
|
||||
const std::vector<nghttp3_nv> &nva) const;
|
||||
int http_acked_stream_data(Downstream *downstream, uint64_t datalen);
|
||||
|
||||
@@ -67,8 +67,7 @@ template <typename F, typename... T> struct Defer {
|
||||
Defer(Defer &&o) noexcept : f(std::move(o.f)) {}
|
||||
~Defer() { f(); }
|
||||
|
||||
using ResultType = typename std::result_of<typename std::decay<F>::type(
|
||||
typename std::decay<T>::type...)>::type;
|
||||
using ResultType = std::invoke_result_t<F, T...>;
|
||||
std::function<ResultType()> f;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ if(HAVE_CUNIT)
|
||||
nghttp2_buf_test.c
|
||||
nghttp2_http_test.c
|
||||
nghttp2_extpri_test.c
|
||||
nghttp2_ratelim_test.c
|
||||
)
|
||||
|
||||
add_executable(main EXCLUDE_FROM_ALL
|
||||
|
||||
@@ -42,7 +42,8 @@ OBJECTS = main.c nghttp2_pq_test.c nghttp2_map_test.c nghttp2_queue_test.c \
|
||||
nghttp2_helper_test.c \
|
||||
nghttp2_buf_test.c \
|
||||
nghttp2_http_test.c \
|
||||
nghttp2_extpri_test.c
|
||||
nghttp2_extpri_test.c \
|
||||
nghttp2_ratelim_test.c
|
||||
|
||||
HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \
|
||||
nghttp2_session_test.h \
|
||||
@@ -51,7 +52,8 @@ HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \
|
||||
nghttp2_test_helper.h \
|
||||
nghttp2_buf_test.h \
|
||||
nghttp2_http_test.h \
|
||||
nghttp2_extpri_test.h
|
||||
nghttp2_extpri_test.h \
|
||||
nghttp2_ratelim_test.h
|
||||
|
||||
main_SOURCES = $(HFILES) $(OBJECTS)
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "nghttp2_buf_test.h"
|
||||
#include "nghttp2_http_test.h"
|
||||
#include "nghttp2_extpri_test.h"
|
||||
#include "nghttp2_ratelim_test.h"
|
||||
|
||||
extern int nghttp2_enable_strict_preface;
|
||||
|
||||
@@ -343,6 +344,8 @@ int main(void) {
|
||||
test_nghttp2_session_no_rfc7540_priorities) ||
|
||||
!CU_add_test(pSuite, "session_server_fallback_rfc7540_priorities",
|
||||
test_nghttp2_session_server_fallback_rfc7540_priorities) ||
|
||||
!CU_add_test(pSuite, "session_stream_reset_ratelim",
|
||||
test_nghttp2_session_stream_reset_ratelim) ||
|
||||
!CU_add_test(pSuite, "http_mandatory_headers",
|
||||
test_nghttp2_http_mandatory_headers) ||
|
||||
!CU_add_test(pSuite, "http_content_length",
|
||||
@@ -449,7 +452,9 @@ int main(void) {
|
||||
!CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc) ||
|
||||
!CU_add_test(pSuite, "http_parse_priority",
|
||||
test_nghttp2_http_parse_priority) ||
|
||||
!CU_add_test(pSuite, "extpri_to_uint8", test_nghttp2_extpri_to_uint8)) {
|
||||
!CU_add_test(pSuite, "extpri_to_uint8", test_nghttp2_extpri_to_uint8) ||
|
||||
!CU_add_test(pSuite, "ratelim_update", test_nghttp2_ratelim_update) ||
|
||||
!CU_add_test(pSuite, "ratelim_drain", test_nghttp2_ratelim_drain)) {
|
||||
CU_cleanup_registry();
|
||||
return (int)CU_get_error();
|
||||
}
|
||||
|
||||
101
tests/nghttp2_ratelim_test.c
Normal file
101
tests/nghttp2_ratelim_test.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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_test.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <CUnit/CUnit.h>
|
||||
|
||||
#include "nghttp2_ratelim.h"
|
||||
|
||||
void test_nghttp2_ratelim_update(void) {
|
||||
nghttp2_ratelim rl;
|
||||
|
||||
nghttp2_ratelim_init(&rl, 1000, 21);
|
||||
|
||||
CU_ASSERT(1000 == rl.val);
|
||||
CU_ASSERT(1000 == rl.burst);
|
||||
CU_ASSERT(21 == rl.rate);
|
||||
CU_ASSERT(0 == rl.tstamp);
|
||||
|
||||
nghttp2_ratelim_update(&rl, 999);
|
||||
|
||||
CU_ASSERT(1000 == rl.val);
|
||||
CU_ASSERT(999 == rl.tstamp);
|
||||
|
||||
nghttp2_ratelim_drain(&rl, 100);
|
||||
|
||||
CU_ASSERT(900 == rl.val);
|
||||
|
||||
nghttp2_ratelim_update(&rl, 1000);
|
||||
|
||||
CU_ASSERT(921 == rl.val);
|
||||
|
||||
nghttp2_ratelim_update(&rl, 1002);
|
||||
|
||||
CU_ASSERT(963 == rl.val);
|
||||
|
||||
nghttp2_ratelim_update(&rl, 1004);
|
||||
|
||||
CU_ASSERT(1000 == rl.val);
|
||||
CU_ASSERT(1004 == rl.tstamp);
|
||||
|
||||
/* timer skew */
|
||||
nghttp2_ratelim_init(&rl, 1000, 21);
|
||||
nghttp2_ratelim_update(&rl, 1);
|
||||
|
||||
CU_ASSERT(1000 == rl.val);
|
||||
|
||||
nghttp2_ratelim_update(&rl, 0);
|
||||
|
||||
CU_ASSERT(1000 == rl.val);
|
||||
|
||||
/* rate * duration overflow */
|
||||
nghttp2_ratelim_init(&rl, 1000, 100);
|
||||
nghttp2_ratelim_drain(&rl, 999);
|
||||
|
||||
CU_ASSERT(1 == rl.val);
|
||||
|
||||
nghttp2_ratelim_update(&rl, UINT64_MAX);
|
||||
|
||||
CU_ASSERT(1000 == rl.val);
|
||||
|
||||
/* val + rate * duration overflow */
|
||||
nghttp2_ratelim_init(&rl, UINT64_MAX - 1, 2);
|
||||
nghttp2_ratelim_update(&rl, 1);
|
||||
|
||||
CU_ASSERT(UINT64_MAX - 1 == rl.val);
|
||||
}
|
||||
|
||||
void test_nghttp2_ratelim_drain(void) {
|
||||
nghttp2_ratelim rl;
|
||||
|
||||
nghttp2_ratelim_init(&rl, 100, 7);
|
||||
|
||||
CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 101));
|
||||
CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 51));
|
||||
CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 49));
|
||||
CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 1));
|
||||
}
|
||||
35
tests/nghttp2_ratelim_test.h
Normal file
35
tests/nghttp2_ratelim_test.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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_TEST_H
|
||||
#define NGHTTP2_RATELIM_TEST_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
void test_nghttp2_ratelim_update(void);
|
||||
void test_nghttp2_ratelim_drain(void);
|
||||
|
||||
#endif /* NGHTTP2_RATELIM_TEST_H */
|
||||
@@ -11968,6 +11968,109 @@ void test_nghttp2_session_server_fallback_rfc7540_priorities(void) {
|
||||
nghttp2_bufs_free(&bufs);
|
||||
}
|
||||
|
||||
void test_nghttp2_session_stream_reset_ratelim(void) {
|
||||
nghttp2_session *session;
|
||||
nghttp2_session_callbacks callbacks;
|
||||
nghttp2_frame frame;
|
||||
ssize_t rv;
|
||||
nghttp2_bufs bufs;
|
||||
nghttp2_buf *buf;
|
||||
nghttp2_mem *mem;
|
||||
size_t i;
|
||||
nghttp2_hd_deflater deflater;
|
||||
size_t nvlen;
|
||||
nghttp2_nv *nva;
|
||||
int32_t stream_id;
|
||||
nghttp2_outbound_item *item;
|
||||
nghttp2_option *option;
|
||||
|
||||
mem = nghttp2_mem_default();
|
||||
frame_pack_bufs_init(&bufs);
|
||||
|
||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||
callbacks.send_callback = null_send_callback;
|
||||
|
||||
nghttp2_option_new(&option);
|
||||
nghttp2_option_set_stream_reset_rate_limit(
|
||||
option, NGHTTP2_DEFAULT_STREAM_RESET_BURST, 0);
|
||||
|
||||
nghttp2_session_server_new2(&session, &callbacks, NULL, option);
|
||||
|
||||
nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, NULL, 0);
|
||||
rv = nghttp2_frame_pack_settings(&bufs, &frame.settings);
|
||||
|
||||
CU_ASSERT(0 == rv);
|
||||
|
||||
nghttp2_frame_settings_free(&frame.settings, mem);
|
||||
|
||||
buf = &bufs.head->buf;
|
||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
||||
|
||||
CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
|
||||
|
||||
/* Send SETTINGS ACK */
|
||||
rv = nghttp2_session_send(session);
|
||||
|
||||
CU_ASSERT(0 == rv);
|
||||
|
||||
nghttp2_hd_deflate_init(&deflater, mem);
|
||||
|
||||
for (i = 0; i < NGHTTP2_DEFAULT_STREAM_RESET_BURST + 2; ++i) {
|
||||
stream_id = (int32_t)(i * 2 + 1);
|
||||
|
||||
nghttp2_bufs_reset(&bufs);
|
||||
|
||||
/* HEADERS */
|
||||
nvlen = ARRLEN(reqnv);
|
||||
nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem);
|
||||
nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS,
|
||||
stream_id, NGHTTP2_HCAT_HEADERS, NULL, nva,
|
||||
nvlen);
|
||||
rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater);
|
||||
|
||||
CU_ASSERT(0 == rv);
|
||||
|
||||
nghttp2_frame_headers_free(&frame.headers, mem);
|
||||
|
||||
buf = &bufs.head->buf;
|
||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
||||
|
||||
CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
|
||||
|
||||
nghttp2_bufs_reset(&bufs);
|
||||
|
||||
/* RST_STREAM */
|
||||
nghttp2_frame_rst_stream_init(&frame.rst_stream, stream_id,
|
||||
NGHTTP2_NO_ERROR);
|
||||
nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream);
|
||||
nghttp2_frame_rst_stream_free(&frame.rst_stream);
|
||||
|
||||
buf = &bufs.head->buf;
|
||||
rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
|
||||
|
||||
CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
|
||||
|
||||
if (i < NGHTTP2_DEFAULT_STREAM_RESET_BURST) {
|
||||
CU_ASSERT(0 == nghttp2_outbound_queue_size(&session->ob_reg));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
CU_ASSERT(1 == nghttp2_outbound_queue_size(&session->ob_reg));
|
||||
|
||||
item = nghttp2_session_get_next_ob_item(session);
|
||||
|
||||
CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
|
||||
CU_ASSERT(NGHTTP2_DEFAULT_STREAM_RESET_BURST * 2 + 1 ==
|
||||
item->frame.goaway.last_stream_id);
|
||||
}
|
||||
|
||||
nghttp2_hd_deflate_free(&deflater);
|
||||
nghttp2_session_del(session);
|
||||
nghttp2_bufs_free(&bufs);
|
||||
nghttp2_option_del(option);
|
||||
}
|
||||
|
||||
static void check_nghttp2_http_recv_headers_fail(
|
||||
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
|
||||
int stream_state, const nghttp2_nv *nva, size_t nvlen) {
|
||||
|
||||
@@ -168,6 +168,7 @@ void test_nghttp2_session_no_closed_streams(void);
|
||||
void test_nghttp2_session_set_stream_user_data(void);
|
||||
void test_nghttp2_session_no_rfc7540_priorities(void);
|
||||
void test_nghttp2_session_server_fallback_rfc7540_priorities(void);
|
||||
void test_nghttp2_session_stream_reset_ratelim(void);
|
||||
void test_nghttp2_http_mandatory_headers(void);
|
||||
void test_nghttp2_http_content_length(void);
|
||||
void test_nghttp2_http_content_length_mismatch(void);
|
||||
|
||||
Reference in New Issue
Block a user