Compare commits

...

41 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
a166099ff4 Replace the deprecated std::result_of with std::invoke_result 2023-10-14 23:07:56 +09:00
Tatsuhiro Tsujikawa
bd92902560 Merge pull request #1967 from vszakats/cmake-fast-warnopt-detection
cmake: speed up warning option detection
2023-10-14 22:40:46 +09:00
Viktor Szakats
10a77ce888 cmake: display WARNCXXFLAGS flags in summary 2023-10-14 10:27:17 +00:00
Viktor Szakats
81c199dd9b cmake: speed up warning option detection 2023-10-14 10:27:17 +00:00
Tatsuhiro Tsujikawa
3b82572b9e Merge pull request #1965 from nghttp2/dependabot/go_modules/golang.org/x/net-0.17.0
Bump golang.org/x/net from 0.15.0 to 0.17.0
2023-10-14 12:14:08 +09:00
dependabot[bot]
9d85ab415f Bump golang.org/x/net from 0.15.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.15.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.15.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-11 23:10:59 +00:00
Tatsuhiro Tsujikawa
d0358c0063 Merge pull request #1964 from nghttp2/nghttpx-h3-reset-stream
nghttpx: Shutdown h3 stream write if reset by a remote endpoint
2023-10-11 19:48:29 +09:00
Tatsuhiro Tsujikawa
e103726f4d nghttpx: Shutdown h3 stream write if reset by a remote endpoint 2023-10-11 19:13:04 +09:00
Tatsuhiro Tsujikawa
4262c90148 Merge pull request #1963 from nghttp2/fix-build-error
Fix build error when both clock_gettime and GetTickCount64 are available
2023-10-11 17:49:46 +09:00
Tatsuhiro Tsujikawa
bf8f419ca9 Fix build error when both clock_gettime and GetTickCount64 are available 2023-10-11 17:19:05 +09:00
Tatsuhiro Tsujikawa
cccb6ad2c9 Bump package version 2023-10-10 23:10:21 +09:00
Tatsuhiro Tsujikawa
6f41cc7271 Update manual pages 2023-10-10 22:57:01 +09:00
Tatsuhiro Tsujikawa
9b781ca734 Bump package and library versions 2023-10-10 22:57:01 +09:00
Tatsuhiro Tsujikawa
aa0973caf5 Merge pull request #1961 from nghttp2/rework-session-mgmt
Rework session management
2023-10-10 22:55:23 +09:00
Tatsuhiro Tsujikawa
72b4af6143 Rework session management 2023-10-10 22:41:58 +09:00
Tatsuhiro Tsujikawa
d40829b133 Merge pull request #1959 from nghttp2/fix-clang-format
Fix clang-format
2023-10-05 21:37:07 +09:00
Tatsuhiro Tsujikawa
939506b68b Fix clang-format 2023-10-05 20:54:00 +09:00
Tatsuhiro Tsujikawa
e62ef924fb Merge pull request #1958 from nghttp2/nghttpx-fix
nghttpx: Fix bug that --single-process does not work
2023-10-01 15:39:23 +09:00
Tatsuhiro Tsujikawa
8bad736d48 nghttpx: Fix bug that --single-process does not work 2023-10-01 15:18:39 +09:00
Tatsuhiro Tsujikawa
e761014ca5 Merge pull request #1957 from nghttp2/apps-fix
Apps fix
2023-10-01 12:30:44 +09:00
Tatsuhiro Tsujikawa
e6ca4ff173 nghttpd: Do not read too greedy for TLS connection 2023-10-01 11:59:53 +09:00
Tatsuhiro Tsujikawa
62d58bdabc nghttpx: Fix the bug that TLS connection is not rate limited 2023-09-30 22:53:31 +09:00
Tatsuhiro Tsujikawa
e37fe5543f Merge pull request #1945 from nghttp2/bump-quictls
Bump quictls
2023-09-23 16:25:54 +09:00
Tatsuhiro Tsujikawa
d54750b365 Merge pull request #1953 from nghttp2/nghttpx-field-name-lowercase
nghttpx: Header field name must be lowercase
2023-09-22 11:02:01 +09:00
Tatsuhiro Tsujikawa
8ebe7b10fc nghttpx: Header field name must be lowercase 2023-09-22 10:09:54 +09:00
Tatsuhiro Tsujikawa
5c1b0f261e Merge pull request #1951 from nghttp2/docker-debian12
docker: Bump base image to debian 12
2023-09-15 21:41:10 +09:00
Tatsuhiro Tsujikawa
0866ceffc7 Merge pull request #1947 from nghttp2/dependabot/github_actions/actions/upload-artifact-3
Bump actions/upload-artifact from 1 to 3
2023-09-15 20:41:41 +09:00
Tatsuhiro Tsujikawa
3c6f94258f Merge pull request #1949 from nghttp2/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-15 19:36:46 +09:00
Tatsuhiro Tsujikawa
959a55f95f Merge pull request #1948 from nghttp2/dependabot/github_actions/actions/setup-go-4
Bump actions/setup-go from 3 to 4
2023-09-15 19:12:09 +09:00
dependabot[bot]
7d0d8775c9 Bump actions/setup-go from 3 to 4
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 4.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-15 09:50:01 +00:00
Tatsuhiro Tsujikawa
52cb8c35c8 Merge pull request #1950 from nghttp2/bump-golang.org/x/net
Bump golang.org/x/net to v0.15.0
2023-09-15 18:48:49 +09:00
Tatsuhiro Tsujikawa
d19bc4bb67 Bump golang.org/x/net to v0.15.0 2023-09-15 18:28:01 +09:00
Tatsuhiro Tsujikawa
1ee16fdeca docker: Bump base image to debian 12 2023-09-15 18:13:39 +09:00
dependabot[bot]
b809beacab Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-15 08:55:19 +00:00
dependabot[bot]
8cafb048be Bump actions/upload-artifact from 1 to 3
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 1 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v1...v3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-15 08:55:00 +00:00
Tatsuhiro Tsujikawa
627b2408e5 Merge pull request #1946 from nghttp2/dependabot-actions
Add dependabot to update actions
2023-09-15 17:44:06 +09:00
Tatsuhiro Tsujikawa
0d36a2a050 Add dependabot to update actions 2023-09-15 17:13:09 +09:00
Tatsuhiro Tsujikawa
06da18089f Bump quictls 2023-09-12 18:52:06 +09:00
Tatsuhiro Tsujikawa
19697bd44a Merge pull request #1944 from nghttp2/bump-ngtcp2
Bump ngtcp2
2023-09-12 18:50:02 +09:00
Tatsuhiro Tsujikawa
2e6c8ddd15 Bump ngtcp2 2023-09-06 23:23:57 +09:00
Tatsuhiro Tsujikawa
b7f9853968 Bump package version 2023-09-04 18:32:43 +09:00
43 changed files with 1022 additions and 164 deletions

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -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

View File

@@ -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

View File

@@ -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}

View File

@@ -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

View File

@@ -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
View 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()

View 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()

View File

@@ -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

View File

@@ -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.

View File

@@ -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 \

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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
)

View File

@@ -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

View File

@@ -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
*

View File

@@ -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;
}

View File

@@ -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
View 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
View 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 */

View File

@@ -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;
}

View File

@@ -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
View 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
View 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 */

View File

@@ -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() {

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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)

View File

@@ -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();
}

View 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));
}

View 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 */

View File

@@ -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) {

View File

@@ -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);