Compare commits

..

1 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
03cca23306 Build android image 2023-01-31 19:17:53 +09:00
376 changed files with 49835 additions and 42112 deletions

View File

@@ -3,96 +3,41 @@ Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
@@ -101,32 +46,33 @@ BraceWrapping:
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
BreakTemplateDeclarations: MultiLine
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: NextLine
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: true
ForEachMacros:
- foreach
@@ -151,35 +97,21 @@ IncludeCategories:
IncludeIsMainRegex: '$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: AfterHash
IndentRequiresClause: false
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
@@ -187,44 +119,34 @@ ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: NextLine
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes: Never
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
@@ -233,40 +155,32 @@ SpaceBeforeParensOptions:
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
- munit_void_test_decl
- nghttp2_max_def
- nghttp2_min_def
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseCRLF: false
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE

View File

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

View File

@@ -4,21 +4,19 @@ on:
push:
paths:
- Dockerfile.android
- .github/workflows/android.yml
branches:
- '**'
permissions: read-all
pull_request:
paths:
- Dockerfile.android
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build
uses: docker/build-push-action@v6
- uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v2
- name: Build container image
uses: docker/build-push-action@v3
with:
file: Dockerfile.android
tags: ghcr.io/nghttp2/nghttp2

View File

@@ -2,282 +2,49 @@ name: build
on: [push, pull_request]
permissions: read-all
env:
LIBBPF_VERSION: v1.6.2
OPENSSL1_VERSION: 1_1_1w+quic
OPENSSL3_VERSION: 3.6.0
BORINGSSL_VERSION: db1a8456167249f95b854a1cd24c6b553d0f1567
AWSLC_VERSION: v1.62.0
NGHTTP3_VERSION: v1.12.0
NGTCP2_VERSION: v1.17.0
WOLFSSL_VERSION: v5.8.2-stable
jobs:
build-cache:
strategy:
matrix:
os: [ubuntu-24.04, macos-14, macos-15]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Restore libbpf cache
id: cache-libbpf
uses: actions/cache@v4
if: runner.os == 'Linux'
with:
path: libbpf/build
key: ${{ matrix.os }}-libbpf-${{ env.LIBBPF_VERSION }}
- name: Restore OpenSSL v1.1.1 cache
id: cache-openssl1
uses: actions/cache@v4
with:
path: openssl1/build
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL1_VERSION }}
- name: Restore OpenSSL v3.x cache
id: cache-openssl3
uses: actions/cache@v4
with:
path: openssl3/build
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL3_VERSION }}
- name: Restore BoringSSL cache
id: cache-boringssl
uses: actions/cache@v4
with:
path: |
boringssl/build/libcrypto.a
boringssl/build/libssl.a
boringssl/include
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
- name: Restore aws-lc cache
id: cache-awslc
uses: actions/cache@v4
with:
path: |
aws-lc/build/crypto/libcrypto.a
aws-lc/build/ssl/libssl.a
aws-lc/include
key: ${{ matrix.os }}-awslc-${{ env.AWSLC_VERSION }}
- name: Restore wolfSSL cache
id: cache-wolfssl
uses: actions/cache@v4
with:
path: wolfssl/build
key: ${{ matrix.os }}-wolfssl-${{ env.WOLFSSL_VERSION }}
- name: Restore nghttp3 cache
id: cache-nghttp3
uses: actions/cache@v4
with:
path: nghttp3/build
key: ${{ matrix.os }}-nghttp3-${{ env.NGHTTP3_VERSION }}
- name: Restore ngtcp2 + quictls/openssl v1.1.1 cache
id: cache-ngtcp2-openssl1
uses: actions/cache@v4
with:
path: ngtcp2-openssl1/build
key: ${{ matrix.os }}-ngtcp2-${{ env.NGTCP2_VERSION }}-openssl-${{ env.OPENSSL1_VERSION }}
- name: Restore ngtcp2 + quictls/openssl v3.x cache
id: cache-ngtcp2-openssl3
uses: actions/cache@v4
with:
path: ngtcp2-openssl3/build
key: ${{ matrix.os }}-ngtcp2-${{ env.NGTCP2_VERSION }}-openssl-${{ env.OPENSSL3_VERSION }}
- id: settings
if: |
(steps.cache-libbpf.outputs.cache-hit != 'true' && runner.os == 'Linux') ||
steps.cache-openssl1.outputs.cache-hit != 'true' ||
steps.cache-openssl3.outputs.cache-hit != 'true' ||
steps.cache-boringssl.outputs.cache-hit != 'true' ||
steps.cache-awslc.outputs.cache-hit != 'true' ||
steps.cache-wolfssl.outputs.cache-hit != 'true' ||
steps.cache-nghttp3.outputs.cache-hit != 'true' ||
steps.cache-ngtcp2-openssl1.outputs.cache-hit != 'true' ||
steps.cache-ngtcp2-openssl3.outputs.cache-hit != 'true'
run: |
echo 'needs-build=true' >> $GITHUB_OUTPUT
- name: Linux setup
if: runner.os == 'Linux' && steps.settings.outputs.needs-build == 'true'
run: |
sudo apt-get update
sudo apt-get install \
autoconf \
automake \
autotools-dev \
libtool \
pkg-config \
libelf-dev \
cmake \
cmake-data
- name: MacOS setup
if: runner.os == 'macOS' && steps.settings.outputs.needs-build == 'true'
run: |
brew install \
autoconf \
automake \
libtool
- name: Build libbpf
if: steps.cache-libbpf.outputs.cache-hit != 'true' && runner.os == 'Linux'
run: |
git clone --recursive --shallow-submodules -b ${{ env.LIBBPF_VERSION }} https://github.com/libbpf/libbpf
cd libbpf
make -C src install PREFIX=$PWD/build
- name: Build quictls/openssl v1.1.1
if: steps.cache-openssl1.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b OpenSSL_${{ env.OPENSSL1_VERSION }} https://github.com/quictls/openssl openssl1
cd openssl1
./config --prefix=$PWD/build
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install_sw
- name: Build openssl/openssl v3.x
if: steps.cache-openssl3.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b openssl-${{ env.OPENSSL3_VERSION }} https://github.com/openssl/openssl openssl3
cd openssl3
./config enable-ktls --prefix=$PWD/build
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install_sw
- name: Build BoringSSL
if: steps.cache-boringssl.outputs.cache-hit != 'true'
run: |
mkdir boringssl
cd boringssl
git init
git remote add origin https://boringssl.googlesource.com/boringssl
git fetch origin --depth 1 ${{ env.BORINGSSL_VERSION }}
git checkout ${{ env.BORINGSSL_VERSION }}
mkdir build
cd build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON ..
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
- name: Build aws-lc
if: steps.cache-awslc.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b "${AWSLC_VERSION}" https://github.com/aws/aws-lc
cd aws-lc
cmake -B build -DDISABLE_GO=ON
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" -C build
- name: Build wolfSSL
if: steps.cache-wolfssl.outputs.cache-hit != 'true'
run: |
git clone --depth 1 -b ${{ env.WOLFSSL_VERSION }} https://github.com/wolfSSL/wolfssl
cd wolfssl
autoreconf -i
./configure --disable-dependency-tracking --prefix=$PWD/build \
--enable-all --enable-harden --disable-ech
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install
- name: Build nghttp3
if: steps.cache-nghttp3.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b ${{ env.NGHTTP3_VERSION}} https://github.com/ngtcp2/nghttp3
cd nghttp3
autoreconf -i
./configure --disable-dependency-tracking --prefix=$PWD/build \
--enable-lib-only
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
make install
- name: Build ngtcp2 + quictls/openssl v1.1.1 + BoringSSL
if: steps.cache-ngtcp2-openssl1.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b ${{ env.NGTCP2_VERSION }} https://github.com/ngtcp2/ngtcp2 ngtcp2-openssl1
cd ngtcp2-openssl1
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only \
PKG_CONFIG_PATH="../openssl1/build/lib/pkgconfig:../wolfssl/build/lib/pkgconfig" \
BORINGSSL_CFLAGS="-I$PWD/../boringssl/include/" \
BORINGSSL_LIBS="-L$PWD/../boringssl/build -lssl -lcrypto" \
--disable-dependency-tracking \
--with-boringssl \
--with-wolfssl
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
make install
- name: Build ngtcp2 + quictls/openssl v3.x + aws-lc
if: steps.cache-ngtcp2-openssl3.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b ${{ env.NGTCP2_VERSION }} https://github.com/ngtcp2/ngtcp2 ngtcp2-openssl3
cd ngtcp2-openssl3
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only \
PKG_CONFIG_PATH="../openssl3/build/lib64/pkgconfig:../openssl3/build/lib/pkgconfig" \
BORINGSSL_CFLAGS="-I$PWD/../aws-lc/include/" \
BORINGSSL_LIBS="-L$PWD/../aws-lc/build/ssl -lssl -L$PWD/../aws-lc/build/crypto -lcrypto" \
--disable-dependency-tracking \
--with-boringssl
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
make install
build:
needs:
- build-cache
strategy:
matrix:
os: [ubuntu-24.04, macos-14, macos-15]
os: [ubuntu-22.04, macos-11]
compiler: [gcc, clang]
buildtool: [autotools, cmake]
http3: [http3, no-http3]
openssl: [openssl1, openssl3, boringssl, awslc, wolfssl]
openssl: [openssl1, openssl3, boringssl]
exclude:
- os: macos-11
openssl: openssl3
- http3: no-http3
openssl: openssl3
- os: macos-14
compiler: gcc
- os: macos-15
- os: macos-11
compiler: gcc
- # disable macos cmake because of include path issue
os: macos-14
os: macos-11
buildtool: cmake
- # disable macos cmake because of include path issue
os: macos-15
buildtool: cmake
- os: macos-14
openssl: boringssl
- os: macos-15
- os: macos-11
openssl: boringssl
- openssl: boringssl
buildtool: cmake
- openssl: boringssl
compiler: gcc
- os: macos-14
openssl: awslc
- os: macos-15
openssl: awslc
- openssl: awslc
buildtool: cmake
- openssl: awslc
compiler: gcc
include:
- os: ubuntu-24.04
compiler: clang
buildtool: distcheck
http3: http3
openssl: awslc
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
submodules: recursive
- uses: actions/checkout@v3
- name: Linux setup
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install \
g++-14 \
clang-19 \
g++-12 \
clang-14 \
autoconf \
automake \
autotools-dev \
libtool \
pkg-config \
zlib1g-dev \
libcunit1-dev \
libssl-dev \
libxml2-dev \
libev-dev \
@@ -286,32 +53,29 @@ jobs:
libjemalloc-dev \
libc-ares-dev \
libelf-dev \
libbrotli-dev \
cmake \
cmake-data
echo 'CPPFLAGS=-fsanitize=address,undefined -fno-sanitize-recover=undefined -g' >> $GITHUB_ENV
echo 'LDFLAGS=-fsanitize=address,undefined -fno-sanitize-recover=undefined' >> $GITHUB_ENV
# https://github.com/actions/runner-images/issues/9491#issuecomment-1989718917
# Asan in llvm 14 provided in ubuntu 22.04 is incompatible with
# high-entropy ASLR in much newer kernels that GitHub runners are
# using leading to random crashes: https://reviews.llvm.org/D148280
sudo sysctl vm.mmap_rnd_bits=28
- name: MacOS setup
if: runner.os == 'macOS'
run: |
brew install \
libev \
libevent \
c-ares \
cunit \
libressl \
autoconf \
automake \
pkg-config \
libtool
echo 'PKG_CONFIG_PATH=/usr/local/opt/libressl/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig' >> $GITHUB_ENV
- name: Setup clang (Linux)
if: runner.os == 'Linux' && matrix.compiler == 'clang'
run: |
echo 'CC=clang-19' >> $GITHUB_ENV
echo 'CXX=clang++-19' >> $GITHUB_ENV
echo 'CC=clang-14' >> $GITHUB_ENV
echo 'CXX=clang++-14' >> $GITHUB_ENV
- name: Setup clang (MacOS)
if: runner.os == 'macOS' && matrix.compiler == 'clang'
run: |
@@ -320,244 +84,166 @@ jobs:
- name: Setup gcc (Linux)
if: runner.os == 'Linux' && matrix.compiler == 'gcc'
run: |
echo 'CC=gcc-14' >> $GITHUB_ENV
echo 'CXX=g++-14' >> $GITHUB_ENV
# g++-12 is known to produce false positive warnings.
echo 'CXXFLAGS=-Wno-restrict' >> $GITHUB_ENV
echo 'CC=gcc-12' >> $GITHUB_ENV
echo 'CXX=g++-12' >> $GITHUB_ENV
- name: Setup gcc (MacOS)
if: runner.os == 'macOS' && matrix.compiler == 'gcc'
run: |
echo 'CC=gcc' >> $GITHUB_ENV
echo 'CXX=g++' >> $GITHUB_ENV
- name: Restore libbpf cache
uses: actions/cache/restore@v4
if: matrix.http3 == 'http3' && matrix.compiler == 'clang' && runner.os == 'Linux'
with:
path: libbpf/build
key: ${{ matrix.os }}-libbpf-${{ env.LIBBPF_VERSION }}
fail-on-cache-miss: true
- name: Set libbpf variables
- name: Build libbpf
if: matrix.http3 == 'http3' && matrix.compiler == 'clang' && runner.os == 'Linux'
run: |
git clone -b v1.0.1 https://github.com/libbpf/libbpf
cd libbpf
PREFIX=$PWD/build make -C src install
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --with-libbpf"
EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DWITH_LIBBPF=1"
EXTRA_AUTOTOOLS_OPTS="--with-libbpf"
EXTRA_CMAKE_OPTS="-DWITH_LIBBPF=1"
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
- name: Setup libev variables
if: runner.os == 'macOS'
- name: Build quictls/openssl v1.1.1
if: matrix.http3 == 'http3' && matrix.openssl == 'openssl1'
run: |
LIBEV_CFLAGS="-I/opt/homebrew/Cellar/libev/4.33/include"
LIBEV_LIBS="-L/opt/homebrew/Cellar/libev/4.33/lib -lev"
git clone --depth 1 -b OpenSSL_1_1_1s+quic https://github.com/quictls/openssl
cd openssl
./config --prefix=$PWD/build
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install_sw
- name: Build quictls/openssl v3.0.x
if: matrix.http3 == 'http3' && matrix.openssl == 'openssl3'
run: |
unset CPPFLAGS
unset LDFLAGS
echo 'LIBEV_CFLAGS='"$LIBEV_CFLAGS" >> $GITHUB_ENV
echo 'LIBEV_LIBS='"$LIBEV_LIBS" >> $GITHUB_ENV
- name: Restore quictls/openssl v1.1.1 cache
uses: actions/cache/restore@v4
if: matrix.openssl == 'openssl1'
with:
path: openssl1/build
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL1_VERSION }}
fail-on-cache-miss: true
- name: Restore openssl/openssl v3.x cache
uses: actions/cache/restore@v4
if: matrix.openssl == 'openssl3'
with:
path: openssl3/build
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL3_VERSION }}
fail-on-cache-miss: true
- name: Restore BoringSSL cache
uses: actions/cache/restore@v4
if: matrix.openssl == 'boringssl'
with:
path: |
boringssl/build/libcrypto.a
boringssl/build/libssl.a
boringssl/include
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
fail-on-cache-miss: true
- name: Restore aws-lc cache
uses: actions/cache/restore@v4
if: matrix.openssl == 'awslc'
with:
path: |
aws-lc/build/crypto/libcrypto.a
aws-lc/build/ssl/libssl.a
aws-lc/include
key: ${{ matrix.os }}-awslc-${{ env.AWSLC_VERSION }}
fail-on-cache-miss: true
- name: Set BoringSSL variables
git clone --depth 1 -b openssl-3.0.7+quic https://github.com/quictls/openssl
cd openssl
./config enable-ktls --prefix=$PWD/build --libdir=$PWD/build/lib
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install_sw
- name: Build BoringSSL
if: matrix.openssl == 'boringssl'
run: |
git clone https://boringssl.googlesource.com/boringssl
cd boringssl
OPENSSL_CFLAGS="-I$PWD/include/"
OPENSSL_LIBS="-L$PWD/build -lssl -lcrypto -pthread"
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --without-neverbleed --without-jemalloc --disable-examples"
echo 'OPENSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
echo 'OPENSSL_LIBS='"$OPENSSL_LIBS" >> $GITHUB_ENV
echo 'BORINGSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
echo 'BORINGSSL_LIBS='"$OPENSSL_LIBS" >> $GITHUB_ENV
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
- name: Set aws-lc variables
if: matrix.openssl == 'awslc'
run: |
cd aws-lc
git checkout 80a243e07ef77156af66efa7d22ac35aba44c1b3
mkdir build
cd build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON ..
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
cd ..
OPENSSL_CFLAGS="-I$PWD/include/"
OPENSSL_LIBS="-L$PWD/build/ssl -lssl -L$PWD/build/crypto -lcrypto -pthread"
EXTRA_NGTCP2_OPTS="$EXTRA_NGTCP2_OPTS --without-openssl --with-boringssl"
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --without-neverbleed --without-jemalloc"
echo 'OPENSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
echo 'OPENSSL_LIBS='"$OPENSSL_LIBS" >> $GITHUB_ENV
echo 'BORINGSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
echo 'BORINGSSL_LIBS='"$OPENSSL_LIBS" >> $GITHUB_ENV
echo 'EXTRA_NGTCP2_OPTS='"$EXTRA_NGTCP2_OPTS" >> "$GITHUB_ENV"
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
- name: Restore wolfSSL cache
uses: actions/cache/restore@v4
if: matrix.openssl == 'wolfssl'
with:
path: wolfssl/build
key: ${{ matrix.os }}-wolfssl-${{ env.WOLFSSL_VERSION }}
fail-on-cache-miss: true
- name: Set wolfSSL variables
if: matrix.openssl == 'wolfssl'
run: |
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --with-wolfssl --without-neverbleed"
EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DWITH_WOLFSSL=1 -DWITH_NEVERBLEED=0 -DENABLE_EXAMPLES=0"
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
- name: Restore nghttp3 cache
uses: actions/cache/restore@v4
- name: Build nghttp3
if: matrix.http3 == 'http3'
with:
path: nghttp3/build
key: ${{ matrix.os }}-nghttp3-${{ env.NGHTTP3_VERSION }}
fail-on-cache-miss: true
- name: Restore ngtcp2 + quictls/openssl v1.1.1 cache + BoringSSL
uses: actions/cache/restore@v4
if: matrix.http3 == 'http3' && (matrix.openssl == 'openssl1' || matrix.openssl == 'boringssl' || matrix.openssl == 'wolfssl')
with:
path: ngtcp2-openssl1/build
key: ${{ matrix.os }}-ngtcp2-${{ env.NGTCP2_VERSION }}-openssl-${{ env.OPENSSL1_VERSION }}
fail-on-cache-miss: true
- name: Restore ngtcp2 + quictls/openssl v3.x cache + aws-lc
uses: actions/cache/restore@v4
if: matrix.http3 == 'http3' && (matrix.openssl == 'openssl3' || matrix.openssl == 'awslc')
with:
path: ngtcp2-openssl3/build
key: ${{ matrix.os }}-ngtcp2-${{ env.NGTCP2_VERSION }}-openssl-${{ env.OPENSSL3_VERSION }}
fail-on-cache-miss: true
- name: Setup extra environment variables
if: matrix.http3 == 'no-http3'
run: |
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib64/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib64 -Wl,-rpath,$PWD/openssl3/build/lib"
echo 'PKG_CONFIG_PATH='"$PKG_CONFIG_PATH" >> $GITHUB_ENV
echo 'LDFLAGS='"$LDFLAGS" >> $GITHUB_ENV
git clone --depth 1 -b v0.8.0 https://github.com/ngtcp2/nghttp3
cd nghttp3
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
make install
- name: Build ngtcp2
if: matrix.http3 == 'http3'
run: |
git clone --depth 1 -b v0.13.0 https://github.com/ngtcp2/ngtcp2
cd ngtcp2
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only PKG_CONFIG_PATH="../openssl/build/lib/pkgconfig" $EXTRA_NGTCP2_OPTS
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
make install
- name: Setup extra environment variables for HTTP/3
if: matrix.http3 == 'http3'
run: |
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib64/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2-openssl1/build/lib/pkgconfig:$PWD/ngtcp2-openssl3/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib64 -Wl,-rpath,$PWD/openssl3/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --enable-http3"
EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DENABLE_HTTP3=1"
PKG_CONFIG_PATH="$PWD/openssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
EXTRA_AUTOTOOLS_OPTS="--enable-http3 $EXTRA_AUTOTOOLS_OPTS"
EXTRA_CMAKE_OPTS="-DENABLE_HTTP3=1 $EXTRA_CMAKE_OPTS"
echo 'PKG_CONFIG_PATH='"$PKG_CONFIG_PATH" >> $GITHUB_ENV
echo 'LDFLAGS='"$LDFLAGS" >> $GITHUB_ENV
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
- name: Setup git submodules
run: |
git submodule update --init
- name: Configure autotools
run: |
autoreconf -i
./configure --disable-dependency-tracking
- name: Make distribution and unpack
if: matrix.buildtool != 'distcheck'
./configure
- name: Configure cmake (Linux)
if: matrix.buildtool == 'cmake' && runner.os == 'Linux'
run: |
make dist
VERSION=$(grep PACKAGE_VERSION config.h | cut -d' ' -f3 | tr -d '"')
tar xf nghttp2-$VERSION.tar.gz
cd nghttp2-$VERSION
echo 'NGHTTP2_BUILD_DIR='"$PWD" >> $GITHUB_ENV
- name: Configure cmake (Linux)
if: matrix.buildtool == 'cmake' && runner.os == 'Linux'
run: |
cd $NGHTTP2_BUILD_DIR
echo 'NGHTTP2_CMAKE_DIR='"$PWD" >> $GITHUB_ENV
cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DENABLE_APP=1 $EXTRA_CMAKE_OPTS -DCPPFLAGS="$CPPFLAGS" -DLDFLAGS="$LDFLAGS" -DBUILD_STATIC_LIBS=ON -DBUILD_TESTING=ON .
cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DENABLE_APP=1 $EXTRA_CMAKE_OPTS -DCPPFLAGS="$CPPFLAGS" -DLDFLAGS="$LDFLAGS" .
- name: Configure cmake (MacOS)
if: matrix.buildtool == 'cmake' && runner.os == 'macOS'
run: |
make dist
VERSION=$(grep PACKAGE_VERSION config.h | cut -d' ' -f3 | tr -d '"')
tar xf nghttp2-$VERSION.tar.gz
cd nghttp2-$VERSION
echo 'NGHTTP2_CMAKE_DIR='"$PWD" >> $GITHUB_ENV
# This fixes infamous 'stdio.h not found' error.
echo 'SDKROOT='"$(xcrun --sdk macosx --show-sdk-path)" >> $GITHUB_ENV
cd $NGHTTP2_BUILD_DIR
cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DENABLE_APP=1 $EXTRA_CMAKE_OPTS -DCPPFLAGS="$CPPFLAGS" -DLDFLAGS="$LDFLAGS" -DBUILD_STATIC_LIBS=ON -DBUILD_TESTING=ON .
cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DENABLE_APP=1 $EXTRA_CMAKE_OPTS -DCPPFLAGS="$CPPFLAGS" -DLDFLAGS="$LDFLAGS" .
- name: Build nghttp2 with autotools (Linux)
if: matrix.buildtool == 'autotools' && runner.os == 'Linux'
run: |
cd $NGHTTP2_BUILD_DIR
./configure --disable-dependency-tracking --with-mruby --with-neverbleed --with-libev --with-libbrotlienc --with-libbrotlidec --enable-werror $EXTRA_AUTOTOOLS_OPTS
make -j"$(nproc)" check
make -j"$(nproc)" distcheck \
DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-neverbleed --with-libev --enable-werror $EXTRA_AUTOTOOLS_OPTS CPPFLAGS=\"$CPPFLAGS\" LDFLAGS=\"$LDFLAGS\""
- name: Build nghttp2 with autotools (MacOS)
if: matrix.buildtool == 'autotools' && runner.os == 'macOS'
run: |
cd $NGHTTP2_BUILD_DIR
./configure --disable-dependency-tracking --with-mruby --with-libev --with-libbrotlienc --with-libbrotlidec --enable-werror $EXTRA_AUTOTOOLS_OPTS
make -j"$(sysctl -n hw.ncpu)" check
- name: Build nghttp2 with autotools (distcheck)
if: matrix.buildtool == 'distcheck'
run: |
make -j"$(nproc)" distcheck \
DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-neverbleed --with-libev --with-libbrotlienc --with-libbrotlidec --enable-werror $EXTRA_AUTOTOOLS_OPTS CPPFLAGS=\"$CPPFLAGS\" LDFLAGS=\"$LDFLAGS\""
make -j"$(sysctl -n hw.ncpu)" distcheck \
DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-libev --enable-werror $EXTRA_AUTOTOOLS_OPTS CPPFLAGS=\"$CPPFLAGS\" LDFLAGS=\"$LDFLAGS\""
- name: Build nghttp2 with cmake
if: matrix.buildtool == 'cmake'
run: |
cd $NGHTTP2_BUILD_DIR
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@v6
if: matrix.buildtool != 'distcheck'
with:
go-version: "1.24"
- name: Integration test
# Integration tests for nghttpx; autotools erases build
# artifacts.
if: matrix.buildtool != 'distcheck'
if: matrix.buildtool == 'cmake'
run: |
sudo sh -c 'echo "127.0.0.1 127.0.0.1.nip.io" >> /etc/hosts'
cd $NGHTTP2_BUILD_DIR/integration-tests
make it
cd $NGHTTP2_CMAKE_DIR/integration-tests
make itprep it
build-cross:
strategy:
matrix:
host: [x86_64-w64-mingw32, i686-w64-mingw32]
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
env:
HOST: ${{ matrix.host }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
submodules: recursive
- name: Prepare for i386
if: matrix.host == 'i686-w64-mingw32'
run: |
sudo dpkg --add-architecture i386
- uses: actions/checkout@v3
- name: Linux setup
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install \
gcc-mingw-w64 \
@@ -567,113 +253,39 @@ jobs:
libtool \
pkg-config \
wine
- name: Build CUnit
run: |
curl -LO https://jaist.dl.sourceforge.net/project/cunit/CUnit/2.1-3/CUnit-2.1-3.tar.bz2
tar xf CUnit-2.1-3.tar.bz2
cd CUnit-2.1-3
./bootstrap
./configure --disable-shared --host="$HOST" --prefix="$PWD/build"
make -j$(nproc) install
- name: Configure autotools
run: |
autoreconf -i && \
./configure --disable-dependency-tracking --enable-werror \
--enable-lib-only --host="$HOST" \
CFLAGS="-g -O2 -D_WIN32_WINNT=0x0600" LIBS="-pthread"
./configure --enable-werror --enable-lib-only --with-cunit \
--host="$HOST" PKG_CONFIG_PATH="$PWD/CUnit-2.1-3/build/lib/pkgconfig"
- name: Build nghttp2
run: |
make -j$(nproc)
make -j$(nproc) check TESTS=""
- name: Run tests
if: matrix.host == 'x86_64-w64-mingw32'
run: |
export WINEPATH="/usr/${{ matrix.host }}/lib;$(winepath -w /usr/lib/x86_64-linux-gnu/wine/x86_64-windows)"
cd tests
wine main.exe
build-windows:
strategy:
matrix:
arch: [x86, x64]
include:
- arch: x86
platform: Win32
- arch: x64
platform: x64
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
submodules: recursive
- uses: microsoft/setup-msbuild@v2
- uses: actions/checkout@v3
- name: Configure cmake
run: cmake -B build -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_GENERATOR_PLATFORM=${{ matrix.platform }} -DVCPKG_TARGET_TRIPLET=${{ matrix.arch}}-windows -DBUILD_STATIC_LIBS=ON -DBUILD_TESTING=ON
run: |
mkdir build
cd build
cmake ..
- name: Build nghttp2
run: |
cmake --build build
cmake --build build --target check
release:
if: github.ref_type == 'tag'
needs:
- build
- build-cross
- build-windows
permissions:
contents: write
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
submodules: recursive
- name: Make artifacts
run: |
ver='${{ github.ref_name }}'
prev_ver=$(git tag --sort v:refname | grep -v -F "${ver}" | \
grep 'v[0-9]\+\.[0-9]\+\.0' | tail -n1)
echo -n "$GPG_KEY" | gpg --batch --pinentry-mode loopback --import
./makerelease.sh "${ver}" "${prev_ver}"
env:
GPG_KEY: ${{ secrets.GPG_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- name: Make release
uses: actions/github-script@v8
with:
script: |
const fs = require('fs')
let ver = '${{ github.ref_name }}'
let {data: release} = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: ver,
name: `nghttp2 ${ver}`,
draft: true,
generate_release_notes: true,
discussion_category_name: 'Announcements',
})
let v = ver.substring(1)
let files = [
'checksums.txt',
`nghttp2-${v}.tar.bz2`,
`nghttp2-${v}.tar.bz2.asc`,
`nghttp2-${v}.tar.gz`,
`nghttp2-${v}.tar.gz.asc`,
`nghttp2-${v}.tar.xz`,
`nghttp2-${v}.tar.xz.asc`,
]
await Promise.all(files.map(elem =>
github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.id,
name: elem,
data: fs.readFileSync(elem),
})
))

View File

@@ -1,24 +0,0 @@
name: docker-build
on:
push:
paths:
- docker/Dockerfile
branches:
- '**'
permissions: read-all
jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build
uses: docker/build-push-action@v6
with:
context: docker
build-args: NGHTTP2_BRANCH=${{ github.ref_name }}

View File

@@ -1,17 +1,9 @@
name: CIFuzz
on: [pull_request]
permissions: read-all
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: LLVM workaround
run: |
# https://github.com/actions/runner-images/issues/9491#issuecomment-1989718917
# Asan in llvm 14 provided in ubuntu 22.04 is incompatible with
# high-entropy ASLR in much newer kernels that GitHub runners are
# using leading to random crashes: https://reviews.llvm.org/D148280
sudo sysctl vm.mmap_rnd_bits=28
- name: Build Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
@@ -24,7 +16,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v5
uses: actions/upload-artifact@v1
if: failure()
with:
name: artifacts

View File

@@ -1,22 +0,0 @@
name: 'Close stale issues'
on:
schedule:
- cron: '30 1 * * *'
permissions:
issues: write
actions: write
jobs:
stale:
runs-on: ubuntu-24.04
steps:
- uses: actions/stale@v10
with:
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
days-before-stale: 30
days-before-close: 7
days-before-pr-stale: -1
exempt-all-milestones: true

8
.gitignore vendored
View File

@@ -42,7 +42,6 @@ rules.ninja
lib*.so
lib*.so.*
lib*.a
# generated by "make test" with cmake
Testing/
@@ -55,10 +54,3 @@ _VC_ROOT/
.depend.MSVC
*.pyd
*.egg-info/
# Build Directories
build/
# IDEs
cmake-*
.idea/

6
.gitmodules vendored
View File

@@ -5,9 +5,3 @@
path = third-party/neverbleed
url = https://github.com/tatsuhiro-t/neverbleed.git
branch = nghttp2
[submodule "tests/munit"]
path = tests/munit
url = https://github.com/ngtcp2/munit
[submodule "third-party/urlparse"]
path = third-party/urlparse
url = https://github.com/ngtcp2/urlparse

22
AUTHORS
View File

@@ -17,10 +17,8 @@ github issues [2].
Adam Gołębiowski
Alek Storm
Alex Nalivko
Alexandr Vlasov
Alexandros Konstantinakis-Karmis
Alexis La Goutte
Alyssa Ross
Amir Livneh
Amir Pakdel
Anders Bakken
@@ -30,12 +28,10 @@ Andy Davies
Angus Gratton
Anna Henningsen
Ant Bryan
Anthony Alayo
Asra Ali
Benedikt Christoph Wolters
Benjamin Peterson
Bernard Spil
Bernhard Walle
Brendan Heinonen
Brian Card
Brian Suh
@@ -46,8 +42,6 @@ Dave Reisner
David Beitey
David Korczynski
David Weekly
Deel
Deep Chordia
Dimitris Apostolou
Dmitri Tikhonov
Dmitriy Vetutnev
@@ -56,7 +50,6 @@ Dylan Plecki
Etienne Cimon
Fabian Möller
Fabian Wiesel
Fred Sundvik
Gabi Davar
Gaël PORTAY
Geoff Hill
@@ -75,12 +68,9 @@ Jay Satiro
Jeff 'Raid' Baitis
Jianqing Wang
Jim Morrison
Jiwoo Park
Jonas Kvinge
Josh Braegger
José F. Calcerrada
Kamil Dudka
Karthik Dasari
Kazuho Oku
Kenny (kang-yen) Peng
Kenny Peng
@@ -90,11 +80,9 @@ LazyHamster
Leo Neat
Lorenz Nickel
Lucas Pardue
Lukas Märdian
MATSUMOTO Ryosuke
Marc Bachmann
Marcelo Trylesinski
Mark Boddington
Matt Rudary
Matt Way
Michael Kaufmann
@@ -106,7 +94,6 @@ Nora Shoemaker
Paweł Wegner
Pedro Santos
Peeyush Aggarwal
Peng-Yu Chen
Peter Wu
Piotr Sikora
PufferOverflow
@@ -118,12 +105,9 @@ Richard Wolfert
Rick Lei
Ross Smith II
Rudi Heitbaum
Ryan Carsten Schmidt
Ryo Ota
Scott Mitchell
Sebastiaan Deckers
Sergei Trofimovich
Sergey Fedorov
Shelley Vohr
Simon Frankenberger
Simone Basso
@@ -136,7 +120,6 @@ Syohei YOSHIDA
Tapanito
Tatsuhiko Kubo
Tatsuhiro Tsujikawa
Thomas Devoogdt
Tobias Geerinckx-Rice
Tom Harwood
Tomas Krizek
@@ -146,23 +129,18 @@ Vernon Tang
Viacheslav Biriukov
Viktor Szakats
Viktor Szépe
Ville Vesilehto
Wenfeng Liu
William A Rowe Jr
Xiaoguang Sun
Zachary Turner
Zhuoyun Wei
acesso
ayanamist
bmarques1995
bxshi
clemahieu
dalf
dawg
es
fangdingjun
feicong
hrxi
jwchoi
kumagi
lhuang04

View File

@@ -22,15 +22,15 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cmake_minimum_required(VERSION 3.14)
cmake_minimum_required(VERSION 3.0)
# XXX using 1.8.90 instead of 1.9.0-DEV
project(nghttp2 VERSION 1.68.90 LANGUAGES C)
project(nghttp2 VERSION 1.51.90)
# See versioning rule:
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
set(LT_CURRENT 43)
set(LT_REVISION 2)
set(LT_AGE 29)
set(LT_CURRENT 38)
set(LT_REVISION 1)
set(LT_AGE 24)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
include(Version)
@@ -51,35 +51,28 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
endif()
include(GNUInstallDirs)
include(CMakeDependentOption)
# For documentation
find_package(Python3 COMPONENTS Interpreter)
# Auto-detection of features that can be toggled
if(NOT ENABLE_LIB_ONLY)
enable_language(CXX)
find_package(Libev 4.11)
find_package(Libcares 1.7.5)
find_package(ZLIB 1.2.3)
find_package(Libbrotlienc 1.0.9)
find_package(Libbrotlidec 1.0.9)
find_package(OpenSSL 1.0.1)
find_package(Libev 4.11)
find_package(Libcares 1.7.5)
find_package(ZLIB 1.2.3)
find_package(Libngtcp2 0.0.0)
find_package(Libngtcp2_crypto_openssl 0.0.0)
if(LIBNGTCP2_CRYPTO_OPENSSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_OPENSSL 1)
endif()
if(WITH_WOLFSSL)
find_package(WolfSSL 5.7.0)
else()
find_package(OpenSSL 1.1.1)
endif()
find_package(Libngtcp2 1.15.0)
find_package(Libnghttp3 1.11.0)
find_package(Libnghttp3 0.0.0)
if(WITH_LIBBPF)
find_package(Libbpf 0.7.0)
find_package(Libbpf 0.4.0)
if(NOT LIBBPF_FOUND)
message(FATAL_ERROR "libbpf was requested (WITH_LIBBPF=1) but not found.")
endif()
endif()
if((OPENSSL_FOUND OR WOLFSSL_FOUND) AND LIBEV_FOUND AND ZLIB_FOUND)
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
set(ENABLE_APP_DEFAULT ON)
else()
set(ENABLE_APP_DEFAULT OFF)
@@ -124,31 +117,30 @@ else()
set(HINT_NORETURN)
endif()
if(NOT ENABLE_LIB_ONLY)
include(ExtractValidFlags)
foreach(_cxx1x_flag -std=c++20)
include(ExtractValidFlags)
foreach(_cxx1x_flag -std=c++14)
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
if(_cxx1x_flag_supported)
set(CXX1XCXXFLAGS ${_cxx1x_flag})
break()
endif()
endforeach()
endforeach()
include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
cmake_push_check_state()
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
# Check that std::future is available.
check_cxx_source_compiles("
#include <vector>
#include <future>
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
# Check that std::map::emplace is available for g++-4.7.
check_cxx_source_compiles("
#include <map>
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
cmake_pop_check_state()
include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
cmake_push_check_state()
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
# Check that std::future is available.
check_cxx_source_compiles("
#include <vector>
#include <future>
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
# Check that std::chrono::time_zone is available.
check_cxx_source_compiles("
#include <chrono>
int main() { auto tz = std::chrono::current_zone(); (void)tz; }" HAVE_STD_CHRONO_TIME_ZONE)
cmake_pop_check_state()
endif()
# Checks for libraries.
# Additional libraries required for programs under src directory.
@@ -170,13 +162,17 @@ endif()
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
# APP_LIBRARIES if it is really specific to OpenSSL?
find_package(CUnit 2.1)
enable_testing()
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
set(HAVE_CUNIT ${CUNIT_FOUND})
if(HAVE_CUNIT)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
endif()
# openssl (for src)
include(CheckSymbolExists)
set(HAVE_OPENSSL ${OPENSSL_FOUND})
if(NOT ENABLE_LIB_ONLY AND OPENSSL_FOUND)
if(OPENSSL_FOUND)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES "${OPENSSL_INCLUDE_DIR}")
@@ -184,37 +180,15 @@ if(NOT ENABLE_LIB_ONLY AND OPENSSL_FOUND)
if(WIN32)
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}" "ws2_32" "bcrypt")
endif()
check_symbol_exists("LIBRESSL_VERSION_NUMBER" "openssl/opensslv.h" LIBRESSL_FOUND)
if(ENABLE_HTTP3)
check_symbol_exists(SSL_provide_quic_data "openssl/ssl.h" HAVE_SSL_PROVIDE_QUIC_DATA)
if(NOT HAVE_SSL_PROVIDE_QUIC_DATA)
check_symbol_exists(SSL_set_quic_tls_cbs "openssl/ssl.h" HAVE_SSL_SET_QUIC_TLS_CBS)
if(NOT HAVE_SSL_SET_QUIC_TLS_CBS)
message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} has neither SSL_provide_quic_data nor SSL_set_quic_tls_cbs. HTTP/3 support cannot be enabled")
endif()
endif()
check_symbol_exists(SSL_is_quic "openssl/ssl.h" HAVE_SSL_IS_QUIC)
if(NOT HAVE_SSL_IS_QUIC)
message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} does not have SSL_is_quic. HTTP/3 support cannot be enabled")
endif()
cmake_pop_check_state()
else()
set(OPENSSL_INCLUDE_DIRS "")
set(OPENSSL_LIBRARIES "")
endif()
# wolfSSL (for src)
set(HAVE_WOLFSSL ${WOLFSSL_FOUND})
if(WOLFSSL_FOUND)
set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
cmake_push_check_state()
set(CMAKE_REQUIRED_INCLUDES "${WOLFSSL_INCLUDE_DIR}")
set(CMAKE_REQUIRED_LIBRARIES "${WOLFSSL_LIBRARIES}")
check_symbol_exists(SSL_provide_quic_data "wolfssl/options.h;wolfssl/ssl.h" HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA)
if(NOT HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA)
message(WARNING "wolfSSL in ${WOLFSSL_LIBRARIES} does not have SSL_provide_quic_data. HTTP/3 support cannot be enabled")
endif()
cmake_pop_check_state()
else()
set(WOLFSSL_INCLUDE_DIRS "")
set(WOLFSSL_LIBRARIES "")
endif()
# libev (for src)
set(HAVE_LIBEV ${LIBEV_FOUND})
set(HAVE_ZLIB ${ZLIB_FOUND})
@@ -245,13 +219,6 @@ endif()
# jemalloc
set(HAVE_JEMALLOC ${JEMALLOC_FOUND})
# libbrotli (for src)
set(HAVE_LIBBROTLIENC ${LIBBROTLIENC_FOUND})
set(HAVE_LIBBROTLIDEC ${LIBBROTLIDEC_FOUND})
if(LIBBROTLIENC_FOUND AND LIBBROTLIDEC_FOUND)
set(HAVE_LIBBROTLI 1)
endif()
# libbpf (for bpf)
set(HAVE_LIBBPF ${LIBBPF_FOUND})
if(LIBBPF_FOUND)
@@ -267,45 +234,13 @@ int main() { enum bpf_stats_type foo; (void)foo; }" HAVE_BPF_STATS_TYPE)
endif()
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
if(ENABLE_APP AND NOT (ZLIB_FOUND AND (OPENSSL_FOUND OR WOLFSSL_FOUND) AND LIBEV_FOUND))
if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
endif()
if(ENABLE_HTTP3)
if(HAVE_SSL_PROVIDE_QUIC_DATA AND NOT LIBRESSL_FOUND)
find_package(Libngtcp2_crypto_quictls 1.15.0)
if(LIBNGTCP2_CRYPTO_QUICTLS_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_QUICTLS 1)
endif()
elseif(HAVE_SSL_PROVIDE_QUIC_DATA AND LIBRESSL_FOUND)
find_package(Libngtcp2_crypto_libressl 1.15.0)
if(LIBNGTCP2_CRYPTO_LIBRESSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_LIBRESSL 1)
endif()
elseif(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA)
find_package(Libngtcp2_crypto_wolfssl 1.15.0)
if(LIBNGTCP2_CRYPTO_WOLFSSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1)
endif()
elseif(HAVE_SSL_SET_QUIC_TLS_CBS)
find_package(Libngtcp2_crypto_ossl 1.15.0)
if(LIBNGTCP2_CRYPTO_OSSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_OSSL 1)
endif()
endif()
endif()
# HTTP/3 requires libngtcp2 + nghttp3 + one of:
#
# - quictls/openssl + libngtcp2_crypto_quictls
# - libressl + libngtcp2_crypto_libressl
# - wolfSSL + libngtcp2_crypto_wolfssl
# - openssl/openssl + libngtcp2_crypto_ossl
if(ENABLE_HTTP3 AND NOT (LIBNGTCP2_FOUND AND LIBNGHTTP3_FOUND AND
((HAVE_SSL_PROVIDE_QUIC_DATA AND NOT LIBRESSL_FOUND AND LIBNGTCP2_CRYPTO_QUICTLS_FOUND) OR
(HAVE_SSL_PROVIDE_QUIC_DATA AND LIBRESSL_FOUND AND LIBNGTCP2_CRYPTO_LIBRESSL_FOUND) OR
(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_WOLFSSL_FOUND) OR
(HAVE_SSL_SET_QUIC_TLS_CBS AND LIBNGTCP2_CRYPTO_OSSL_FOUND))))
# HTTP/3 requires quictls/openssl, libngtcp2, libngtcp2_crypto_openssl
# and libnghttp3.
if(ENABLE_HTTP3 AND NOT (HAVE_SSL_IS_QUIC AND LIBNGTCP2_FOUND AND LIBNGTCP2_CRYPTO_OPENSSL_FOUND AND LIBNGHTTP3_FOUND))
message(FATAL_ERROR "HTTP/3 was requested (ENABLE_HTTP3=1) but dependencies are not met.")
endif()
@@ -338,13 +273,12 @@ check_include_file("inttypes.h" HAVE_INTTYPES_H)
check_include_file("limits.h" HAVE_LIMITS_H)
check_include_file("netdb.h" HAVE_NETDB_H)
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
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("syslog.h" HAVE_SYSLOG_H)
check_include_file("time.h" HAVE_TIME_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
check_include_file("windows.h" HAVE_WINDOWS_H)
include(CheckTypeSize)
# Checks for typedefs, structures, and compiler characteristics.
@@ -374,15 +308,15 @@ endif()
include(CheckStructHasMember)
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
# Check size of pointer to decide we need 8 bytes alignment adjustment.
check_type_size("int *" SIZEOF_INT_P)
check_type_size("time_t" SIZEOF_TIME_T)
# Checks for library functions.
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_function_exists(pipe2 HAVE_PIPE2)
check_symbol_exists(GetTickCount64 "windows.h;sysinfoapi.h" HAVE_GETTICKCOUNT64)
include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin?
@@ -395,8 +329,6 @@ if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
endif()
endif()
check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_DECL_CLOCK_MONOTONIC)
set(WARNCFLAGS)
set(WARNCXXFLAGS)
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
@@ -406,12 +338,65 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
endif()
else()
if(ENABLE_WERROR)
set(WARNCFLAGS "-Werror")
set(WARNCXXFLAGS "-Werror")
extract_valid_c_flags(WARNCFLAGS -Werror)
extract_valid_c_flags(WARNCXXFLAGS -Werror)
endif()
include(PickyWarningsC)
include(PickyWarningsCXX)
# 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)
@@ -490,15 +475,14 @@ add_subdirectory(lib)
add_subdirectory(third-party)
add_subdirectory(src)
add_subdirectory(examples)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_subdirectory(tests)
#add_subdirectory(tests/testdata)
add_subdirectory(integration-tests)
endif()
add_subdirectory(tests)
#add_subdirectory(tests/testdata)
add_subdirectory(integration-tests)
if(ENABLE_DOC)
add_subdirectory(doc)
endif()
add_subdirectory(contrib)
add_subdirectory(script)
add_subdirectory(bpf)
@@ -517,23 +501,19 @@ 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}
Test:
CUnit: ${HAVE_CUNIT} (LIBS='${CUNIT_LIBRARIES}')
Failmalloc: ${ENABLE_FAILMALLOC}
Build Test: ${BUILD_TESTING}
Libs:
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
wolfSSL: ${HAVE_WOLFSSL} (LIBS='${WOLFSSL_LIBRARIES}')
Libxml2: ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
Libngtcp2: ${HAVE_LIBNGTCP2} (LIBS='${LIBNGTCP2_LIBRARIES}')
Libngtcp2_crypto_quictls: ${HAVE_LIBNGTCP2_CRYPTO_QUICTLS} (LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}')
Libngtcp2_crypto_libressl: ${HAVE_LIBNGTCP2_CRYPTO_LIBRESSL} (LIBS='${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES}')
Libngtcp2_crypto_wolfssl: ${HAVE_LIBNGTCP2_CRYPTO_WOLFSSL} (LIBS='${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}')
Libngtcp2_crypto_openssl: ${HAVE_LIBNGTCP2_CRYPTO_OPENSSL} (LIBS='${LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES}')
Libnghttp3: ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}')
Libbpf: ${HAVE_LIBBPF} (LIBS='${LIBBPF_LIBRARIES}')
Libevent(SSL): ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
@@ -541,8 +521,6 @@ message(STATUS "summary of build options:
Jemalloc: ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
Zlib: ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
Systemd: ${HAVE_SYSTEMD} (LIBS='${SYSTEMD_LIBRARIES}')
Libbrotlienc: ${HAVE_LIBBROTLIENC} (LIBS='${LIBBROTLIENC_LIBRARIES}')
Libbrotlidec: ${HAVE_LIBBROTLIDEC} (LIBS='${LIBBROTLIDEC_LIBRARIES}')
Third-party:
http-parser: ${ENABLE_THIRD_PARTY}
MRuby: ${HAVE_MRUBY}

View File

@@ -11,12 +11,11 @@ option(ENABLE_EXAMPLES "Build examples"
${ENABLE_EXAMPLES_DEFAULT})
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0")
option(BUILD_SHARED_LIBS "Build libnghttp2 as a shared library" ON)
option(BUILD_STATIC_LIBS "Build libnghttp2 in static mode also" OFF)
option(ENABLE_STATIC_LIB "Build libnghttp2 in static mode also")
option(ENABLE_SHARED_LIB "Build libnghttp2 as a shared library" ON)
option(ENABLE_STATIC_CRT "Build libnghttp2 against the MS LIBCMT[d]")
option(ENABLE_HTTP3 "Enable HTTP/3 support" OFF)
option(ENABLE_DOC "Build documentation" ON)
cmake_dependent_option(BUILD_TESTING "Enable tests" ON "BUILD_STATIC_LIBS" OFF)
option(WITH_LIBXML2 "Use libxml2"
${WITH_LIBXML2_DEFAULT})
@@ -25,6 +24,5 @@ option(WITH_JEMALLOC "Use jemalloc"
option(WITH_MRUBY "Use mruby")
option(WITH_NEVERBLEED "Use neverbleed")
option(WITH_LIBBPF "Use libbpf")
option(WITH_WOLFSSL "Use wolfSSL")
# vim: ft=cmake:

View File

@@ -12,21 +12,21 @@
# Only use standalone-toolchain for reduce size
FROM ubuntu:24.04
LABEL org.opencontainers.image.authors="Tatsuhiro Tsujikawa"
FROM ubuntu:22.04
MAINTAINER Tatsuhiro Tsujikawa
ARG NDK_VERSION=r27c
ARG NDK=/root/android-ndk-$NDK_VERSION
ARG TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
ARG TARGET=aarch64-linux-android
ARG API=33
ARG AR=$TOOLCHAIN/bin/llvm-ar
ARG CC=$TOOLCHAIN/bin/$TARGET$API-clang
ARG CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
ARG LD=$TOOLCHAIN/bin/ld
ARG RANDLIB=$TOOLCHAIN/bin/llvm-ranlib
ARG STRIP=$TOOLCHAIN/bin/llvm-strip
ARG PREFIX=/root/usr/local
ENV NDK_VERSION r25b
ENV NDK /root/android-ndk-$NDK_VERSION
ENV TOOLCHAIN $NDK/toolchains/llvm/prebuilt/linux-x86_64
ENV TARGET aarch64-linux-android
ENV API 33
ENV AR $TOOLCHAIN/bin/llvm-ar
ENV CC $TOOLCHAIN/bin/$TARGET$API-clang
ENV CXX $TOOLCHAIN/bin/$TARGET$API-clang++
ENV LD $TOOLCHAIN/bin/ld
ENV RANDLIB $TOOLCHAIN/bin/llvm-ranlib
ENV STRIP $TOOLCHAIN/bin/llvm-strip
ENV PREFIX /root/usr/local
WORKDIR /root
RUN apt-get update && \
@@ -42,11 +42,11 @@ RUN curl -L -O https://dl.google.com/android/repository/android-ndk-$NDK_VERSION
rm android-ndk-$NDK_VERSION-linux.zip
# Setup version of libraries
ARG OPENSSL_VERSION=1.1.1w
ARG LIBEV_VERSION=4.33
ARG ZLIB_VERSION=1.3.1
ARG CARES_VERSION=1.18.1
ARG NGHTTP2_VERSION=master
ENV OPENSSL_VERSION 1.1.1q
ENV LIBEV_VERSION 4.33
ENV ZLIB_VERSION 1.2.13
ENV CARES_VERSION 1.18.1
ENV NGHTTP2_VERSION master
WORKDIR /root/build
RUN curl -L -O https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz && \
@@ -65,7 +65,6 @@ RUN curl -L -O http://dist.schmorp.de/libev/Attic/libev-$LIBEV_VERSION.tar.gz &&
WORKDIR /root/build/libev-$LIBEV_VERSION
RUN ./configure \
--disable-dependency-tracking \
--host=$TARGET \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
@@ -76,7 +75,7 @@ RUN ./configure \
make install
WORKDIR /root/build
RUN curl -L -O https://github.com/madler/zlib/releases/download/v$ZLIB_VERSION/zlib-$ZLIB_VERSION.tar.gz && \
RUN curl -L -O https://zlib.net/zlib-$ZLIB_VERSION.tar.gz && \
tar xf zlib-$ZLIB_VERSION.tar.gz && \
rm zlib-$ZLIB_VERSION.tar.gz
@@ -91,13 +90,12 @@ RUN HOST=$TARGET \
WORKDIR /root/build
RUN curl -L -O https://github.com/c-ares/c-ares/releases/download/cares-1_18_1/c-ares-$CARES_VERSION.tar.gz && \
RUN curl -L -O https://c-ares.haxx.se/download/c-ares-$CARES_VERSION.tar.gz && \
tar xf c-ares-$CARES_VERSION.tar.gz && \
rm c-ares-$CARES_VERSION.tar.gz
WORKDIR /root/build/c-ares-$CARES_VERSION
RUN ./configure \
--disable-dependency-tracking \
--host=$TARGET \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
@@ -105,11 +103,10 @@ RUN ./configure \
make install
WORKDIR /root/build
RUN git clone --recursive --shallow-submodules https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
RUN git clone https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
WORKDIR /root/build/nghttp2
RUN autoreconf -i && \
./configure \
--disable-dependency-tracking \
--enable-app \
--disable-shared \
--host=$TARGET \
@@ -119,6 +116,6 @@ RUN autoreconf -i && \
--disable-threads \
CPPFLAGS="-fPIE -I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-static-libstdc++ -static-libgcc -fPIE -pie -L$PREFIX/lib" && \
LDFLAGS="-fPIE -pie -L$PREFIX/lib" && \
make && \
$STRIP src/nghttpx src/nghttpd src/nghttp

View File

@@ -20,8 +20,8 @@
# 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.
SUBDIRS = lib tests third-party src bpf examples integration-tests \
doc contrib
SUBDIRS = lib third-party src bpf examples tests integration-tests \
doc contrib script
ACLOCAL_AMFLAGS = -I m4
@@ -35,6 +35,7 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-env \
cmake/ExtractValidFlags.cmake \
cmake/FindJemalloc.cmake \
cmake/FindLibev.cmake \
cmake/FindCUnit.cmake \
cmake/Version.cmake \
cmake/FindLibevent.cmake \
cmake/FindJansson.cmake \
@@ -43,14 +44,7 @@ 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/FindLibbrotlienc.cmake \
cmake/FindLibbrotlidec.cmake \
cmake/FindLibngtcp2_crypto_wolfssl.cmake \
cmake/FindLibngtcp2_crypto_ossl.cmake \
cmake/FindWolfSSL.cmake \
cmake/PickyWarningsC.cmake \
cmake/PickyWarningsCXX.cmake
cmake/FindLibngtcp2_crypto_openssl.cmake
.PHONY: clang-format
@@ -61,5 +55,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 \
src/*.{c,cc,h} examples/*.{c,cc} \
tests/*.{c,h} bpf/*.c fuzz/*.cc

View File

@@ -29,10 +29,11 @@ Public Test Server
The following endpoints are available to try out our nghttp2
implementation.
* https://nghttp2.org/ (TLS + ALPN and HTTP/3)
* https://nghttp2.org/ (TLS + ALPN/NPN and HTTP/3)
This endpoint supports ``h2`` and ``http/1.1`` via ALPN and requires
TLSv1.2 for HTTP/2 connection.
This endpoint supports ``h2``, ``h2-16``, ``h2-14``, and
``http/1.1`` via ALPN/NPN and requires TLSv1.2 for HTTP/2
connection.
It also supports HTTP/3.
@@ -47,6 +48,11 @@ The following package is required to build the libnghttp2 library:
* pkg-config >= 0.20
To build and run the unit test programs, the following package is
required:
* cunit >= 2.1
To build the documentation, you need to install:
* sphinx (http://sphinx-doc.org/)
@@ -60,12 +66,15 @@ To build and run the application programs (``nghttp``, ``nghttpd``,
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
are required:
* OpenSSL >= 1.1.1; or wolfSSL >= 5.7.0; or LibreSSL >= 3.8.1; or
aws-lc >= 1.19.0; or BoringSSL
* OpenSSL >= 1.0.1
* libev >= 4.11
* zlib >= 1.2.3
* libc-ares >= 1.7.5
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more
features than LibreSSL at the time of this writing.
To enable ``-a`` option (getting linked assets from the downloaded
resource) in ``nghttp``, the following package is required:
@@ -94,15 +103,10 @@ To mitigate heap fragmentation in long running server programs
Alpine Linux currently does not support malloc replacement
due to musl limitations. See details in issue `#762 <https://github.com/nghttp2/nghttp2/issues/762>`_.
For BoringSSL or aws-lc build, to enable :rfc:`8879` TLS Certificate
Compression in applications, the following library is required:
* libbrotli-dev >= 1.0.9
To enable mruby support for nghttpx, `mruby
<https://github.com/mruby/mruby>`_ is required. We need to build
mruby with C++ ABI explicitly turned on, and probably need other
mrgems, mruby is managed by git submodule under third-party/mruby
mrgems, mruby is manged by git submodule under third-party/mruby
directory. Currently, mruby support for nghttpx is disabled by
default. To enable mruby support, use ``--with-mruby`` configure
option. Note that at the time of this writing, libmruby-dev and mruby
@@ -114,21 +118,20 @@ required:
* bison
nghttpx supports `neverbleed <https://github.com/h2o/neverbleed>`_,
privilege separation engine for OpenSSL. In short, it minimizes the
risk of private key leakage when serious bug like Heartbleed is
exploited. The neverbleed is disabled by default. To enable it, use
``--with-neverbleed`` configure option.
privilege separation engine for OpenSSL / LibreSSL. In short, it
minimizes the risk of private key leakage when serious bug like
Heartbleed is exploited. The neverbleed is disabled by default. To
enable it, use ``--with-neverbleed`` configure option.
To enable the experimental HTTP/3 support for h2load and nghttpx, the
following libraries are required:
* `quictls
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1w+quic>`_; or
wolfSSL; or LibreSSL (does not support 0RTT); or aws-lc; or
* `OpenSSL with QUIC support
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1s+quic>`_; or
`BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
db1a8456167249f95b854a1cd24c6b553d0f1567); or OpenSSL >= 3.5.0
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ >= 1.16.0
* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ >= 1.12.0
80a243e07ef77156af66efa7d22ac35aba44c1b3)
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ >= 0.13.0
* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ >= 0.7.0
Use ``--enable-http3`` configure option to enable HTTP/3 feature for
h2load and nghttpx.
@@ -143,14 +146,14 @@ Use ``--with-libbpf`` configure option to build eBPF program.
libelf-dev is needed to build libbpf.
For Ubuntu 20.04, you can build libbpf from `the source code
<https://github.com/libbpf/libbpf/releases>`_. nghttpx requires eBPF
program for reloading its configuration and hot swapping its
executable.
<https://github.com/libbpf/libbpf/releases/tag/v1.0.1>`_. nghttpx
requires eBPF program for reloading its configuration and hot swapping
its executable.
Compiling libnghttp2 C source code requires a C99 compiler. gcc 4.8
is known to be adequate. In order to compile the C++ source code,
C++20 compliant compiler is required. At least g++ >= 12 and
clang++ >= 18 are known to work.
is known to be adequate. In order to compile the C++ source code, gcc
>= 6.0 or clang >= 6.0 is required. C++ source code requires C++14
language features.
.. note::
@@ -204,7 +207,7 @@ required packages:
sudo apt-get install g++ clang make binutils autoconf automake \
autotools-dev libtool pkg-config \
zlib1g-dev libssl-dev libxml2-dev libev-dev \
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev \
libevent-dev libjansson-dev \
libc-ares-dev libjemalloc-dev libsystemd-dev \
ruby-dev bison libelf-dev
@@ -336,24 +339,23 @@ connections alive during reload.
The detailed steps to build HTTP/3 enabled h2load and nghttpx follow.
Build aws-lc:
Build custom OpenSSL:
.. code-block:: text
$ git clone --depth 1 -b v1.62.0 https://github.com/aws/aws-lc
$ cd aws-lc
$ cmake -B build -DDISABLE_GO=ON --install-prefix=$PWD/opt
$ make -j$(nproc) -C build
$ cmake --install build
$ git clone --depth 1 -b OpenSSL_1_1_1s+quic https://github.com/quictls/openssl
$ cd openssl
$ ./config --prefix=$PWD/build --openssldir=/etc/ssl
$ make -j$(nproc)
$ make install_sw
$ cd ..
Build nghttp3:
.. code-block:: text
$ git clone --depth 1 -b v1.12.0 https://github.com/ngtcp2/nghttp3
$ git clone --depth 1 -b v0.8.0 https://github.com/ngtcp2/nghttp3
$ cd nghttp3
$ git submodule update --init --depth 1
$ autoreconf -i
$ ./configure --prefix=$PWD/build --enable-lib-only
$ make -j$(nproc)
@@ -364,13 +366,11 @@ Build ngtcp2:
.. code-block:: text
$ git clone --depth 1 -b v1.17.0 https://github.com/ngtcp2/ngtcp2
$ git clone --depth 1 -b v0.13.0 https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ git submodule update --init --depth 1
$ autoreconf -i
$ ./configure --prefix=$PWD/build --enable-lib-only --with-boringssl \
BORINGSSL_CFLAGS="-I$PWD/../aws-lc/opt/include" \
BORINGSSL_LIBS="-L$PWD/../aws-lc/opt/lib -lssl -lcrypto"
$ ./configure --prefix=$PWD/build --enable-lib-only \
PKG_CONFIG_PATH="$PWD/../openssl/build/lib/pkgconfig"
$ make -j$(nproc)
$ make install
$ cd ..
@@ -380,7 +380,7 @@ from source:
.. code-block:: text
$ git clone --depth 1 -b v1.6.2 https://github.com/libbpf/libbpf
$ git clone --depth 1 -b v1.0.1 https://github.com/libbpf/libbpf
$ cd libbpf
$ PREFIX=$PWD/build make -C src install
$ cd ..
@@ -393,10 +393,10 @@ Build nghttp2:
$ cd nghttp2
$ git submodule update --init
$ autoreconf -i
$ ./configure --with-mruby --enable-http3 --with-libbpf \
CC=clang-19 CXX=clang++-19 \
PKG_CONFIG_PATH="$PWD/../aws-lc/opt/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/../libbpf/build/lib64/pkgconfig" \
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../aws-lc/opt/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
$ ./configure --with-mruby --with-neverbleed --enable-http3 --with-libbpf \
CC=clang-14 CXX=clang++-14 \
PKG_CONFIG_PATH="$PWD/../openssl/build/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/../libbpf/build/lib64/pkgconfig" \
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../openssl/build/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
$ make -j$(nproc)
The eBPF program ``reuseport_kern.o`` should be found under bpf
@@ -481,7 +481,7 @@ Previously nghttp2 library did not send client magic, which is first
24 bytes byte string of client connection preface, and client
applications have to send it by themselves. Since v1.0.0, client
magic is sent by library via first call of ``nghttp2_session_send()``
or ``nghttp2_session_mem_send2()``.
or ``nghttp2_session_mem_send()``.
The client applications which send client magic must remove the
relevant code.
@@ -539,7 +539,7 @@ nghttp - client
+++++++++++++++
``nghttp`` is a HTTP/2 client. It can connect to the HTTP/2 server
with prior knowledge, HTTP Upgrade and ALPN TLS extension.
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
It has verbose output mode for framing information. Here is sample
output from ``nghttp`` client:
@@ -765,8 +765,8 @@ nghttpd - server
By default, it uses SSL/TLS connection. Use ``--no-tls`` option to
disable it.
``nghttpd`` only accepts HTTP/2 connections via ALPN or direct HTTP/2
connections. No HTTP Upgrade is supported.
``nghttpd`` only accepts HTTP/2 connections via NPN/ALPN or direct
HTTP/2 connections. No HTTP Upgrade is supported.
The ``-p`` option allows users to configure server push.
@@ -846,10 +846,10 @@ to know how to migrate from earlier releases.
``nghttpx`` implements `important performance-oriented features
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
session IDs, session tickets (with automatic key rotation), dynamic
record sizing, ALPN, forward secrecy and HTTP/2. ``nghttpx`` also
offers the functionality to share ticket keys among multiple
``nghttpx`` instances via memcached.
session IDs, session tickets (with automatic key rotation), OCSP
stapling, dynamic record sizing, ALPN/NPN, forward secrecy and HTTP/2.
``nghttpx`` also offers the functionality to share session cache and
ticket keys among multiple ``nghttpx`` instances via memcached.
``nghttpx`` has 2 operation modes:
@@ -974,15 +974,12 @@ threads to avoid saturating a single core on client side.
servers.
If the experimental HTTP/3 is enabled, h2load can send requests to
HTTP/3 server. To do this, specify ``h3`` to ``--alpn-list`` option
HTTP/3 server. To do this, specify ``h3`` to ``--npn-list`` option
like so:
.. code-block:: text
$ h2load --alpn-list h3 https://127.0.0.1:4433
For nghttp2 v1.58 or earlier, use ``--npn-list`` instead of
``--alpn-list``.
$ h2load --npn-list h3 https://127.0.0.1:4433
HPACK tools
-----------
@@ -1448,10 +1445,23 @@ See `Contribution Guidelines
<https://nghttp2.org/documentation/contribute.html>`_ for more
details.
Versioning
----------
Reporting vulnerability
-----------------------
In general, we follow `Semantic Versioning <http://semver.org/>`_.
If you find a vulnerability in our software, please send the email to
"tatsuhiro.t at gmail dot com" about its details instead of submitting
issues on github issue page. It is a standard practice not to
disclose vulnerability information publicly until a fixed version is
released, or mitigation is worked out.
In the future, we may setup a dedicated mail address for this purpose.
Release schedule
----------------
In general, we follow `Semantic Versioning <http://semver.org/>`_. We
release MINOR version update every month, and usually we ship it
around 25th day of every month.
We may release PATCH releases between the regular releases, mainly for
severe security bug fixes.

View File

@@ -1,31 +0,0 @@
# Security Process
If you find a vulnerability in our software, please report it via
GitHub "Private vulnerability reporting" feature at
https://github.com/nghttp2/nghttp2/security instead of submitting
issues on github issue page. It is a standard practice not to
disclose vulnerability information publicly until a fixed version is
released, or mitigation is worked out.
If we identify that the reported issue is really a vulnerability, we
open a new security advisory draft using [GitHub security
feature](https://github.com/nghttp2/nghttp2/security) and discuss the
mitigation and bug fixes there. The fixes are committed to the
private repository.
We write the security advisory and get CVE number from GitHub
privately. We also discuss the disclosure date to the public.
We make a new release with the fix at the same time when the
vulnerability is disclosed to public.
At least 7 days before the public disclosure date, we open a new issue
on [nghttp2 issue tracker](https://github.com/nghttp2/nghttp2/issues)
which notifies that the upcoming release will have a security fix.
The `SECURITY` label is attached to this kind of issue. The issue is
not opened if a vulnerability is already disclosed, and it is publicly
known that nghttp2 is affected by that.
Before few hours of new release, we merge the fixes to the master
branch (and/or a release branch if necessary) and make a new release.
Security advisory is disclosed on GitHub.

View File

@@ -42,6 +42,11 @@
License is Public Domain. Commit hash:
12e7744b4919e9d55de75b7ab566326a1c8e7a67 */
#define AES_BLOCKLEN \
16 /* Block length in bytes - AES is 128b block \
only */
#define AES_KEYLEN 16 /* Key length in bytes */
#define AES_keyExpSize 176
struct AES_ctx {
@@ -52,6 +57,7 @@ struct AES_ctx {
in AES. Value=4 */
#define Nb 4
#define Nk 4 /* The number of 32 bit words in a key. */
#define Nr 10 /* The number of rounds in AES Cipher. */
/* state - array holding the intermediate results during
@@ -62,27 +68,126 @@ typedef __u8 state_t[4][4];
read-only storage instead of RAM The numbers below can be computed
dynamically trading ROM for RAM - This can be useful in (embedded)
bootloader applications, where ROM is often limited. */
static const __u8 sbox[256] = {
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16};
static const __u8 rsbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81,
0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e,
0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23,
0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66,
0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72,
0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65,
0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46,
0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca,
0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91,
0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f,
0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2,
0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8,
0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93,
0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb,
0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32,
0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50,
0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41,
0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d,
0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0c, 0x7d};
/* The round constant word array, Rcon[i], contains the values given
by x to the power (i-1) being powers of x (x is denoted as {02}) in
the field GF(2^8) */
static const __u8 Rcon[11] = {0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36};
#define getSBoxValue(num) (sbox[(num)])
/* This function produces Nb(Nr+1) round keys. The round keys are used
in each round to decrypt the states. */
static void KeyExpansion(__u8 *RoundKey, const __u8 *Key) {
unsigned i, j, k;
__u8 tempa[4]; /* Used for the column/row operations */
/* The first round key is the key itself. */
for (i = 0; i < Nk; ++i) {
RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];
RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];
RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];
RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];
}
/* All other round keys are found from the previous round keys. */
for (i = Nk; i < Nb * (Nr + 1); ++i) {
{
k = (i - 1) * 4;
tempa[0] = RoundKey[k + 0];
tempa[1] = RoundKey[k + 1];
tempa[2] = RoundKey[k + 2];
tempa[3] = RoundKey[k + 3];
}
if (i % Nk == 0) {
/* This function shifts the 4 bytes in a word to the left once.
[a0,a1,a2,a3] becomes [a1,a2,a3,a0] */
/* Function RotWord() */
{
const __u8 u8tmp = tempa[0];
tempa[0] = tempa[1];
tempa[1] = tempa[2];
tempa[2] = tempa[3];
tempa[3] = u8tmp;
}
/* SubWord() is a function that takes a four-byte input word and
applies the S-box to each of the four bytes to produce an
output word. */
/* Function Subword() */
{
tempa[0] = getSBoxValue(tempa[0]);
tempa[1] = getSBoxValue(tempa[1]);
tempa[2] = getSBoxValue(tempa[2]);
tempa[3] = getSBoxValue(tempa[3]);
}
tempa[0] = tempa[0] ^ Rcon[i / Nk];
}
j = i * 4;
k = (i - Nk) * 4;
RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];
RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];
RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];
RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];
}
}
static void AES_init_ctx(struct AES_ctx *ctx, const __u8 *key) {
KeyExpansion(ctx->RoundKey, key);
}
/* This function adds the round key to state. The round key is added
to the state by an XOR function. */
@@ -323,7 +428,7 @@ struct {
__uint(max_entries, 255);
__type(key, __u64);
__type(value, __u32);
} worker_id_map SEC(".maps");
} cid_prefix_map SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
@@ -334,18 +439,11 @@ struct {
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__uint(max_entries, 3);
__type(key, __u32);
__type(value, __u64);
} sk_info SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 1);
__type(key, __u32);
__type(value, struct AES_ctx);
} aes_key SEC(".maps");
typedef struct quic_hd {
__u8 *dcid;
__u32 dcidlen;
@@ -353,11 +451,11 @@ typedef struct quic_hd {
__u8 type;
} quic_hd;
#define SV_DCIDLEN 17
#define SV_DCIDLEN 20
#define MAX_DCIDLEN 20
#define MIN_DCIDLEN 8
#define WORKER_IDLEN 8
#define WORKER_ID_OFFSET 1
#define CID_PREFIXLEN 8
#define CID_PREFIX_OFFSET 1
enum {
NGTCP2_PKT_INITIAL = 0x0,
@@ -475,39 +573,14 @@ static __u32 sk_index_from_dcid(const quic_hd *qhd,
SEC("sk_reuseport")
int select_reuseport(struct sk_reuseport_md *reuse_md) {
__u32 sk_index, *psk_index;
__u64 *pnum_socks;
__u32 zero = 0;
__u64 *pnum_socks, *pkey;
__u32 zero = 0, key_high_idx = 1, key_low_idx = 2;
int rv;
quic_hd qhd;
__u8 qpktbuf[6 + MAX_DCIDLEN];
struct AES_ctx *aes_ctx;
__u8 *worker_id;
__u16 remote_port;
__u8 *data = reuse_md->data;
/* Packets less than 22 bytes never be a valid QUIC packet. */
if (reuse_md->len < sizeof(struct udphdr) + 22) {
return SK_DROP;
}
if (reuse_md->data + sizeof(struct udphdr) > reuse_md->data_end) {
return SK_DROP;
}
remote_port = (data[0] << 8) + data[1];
switch (remote_port) {
case 1900:
case 5353:
case 11211:
case 20800:
case 27015:
return SK_DROP;
default:
if (remote_port < 1024) {
return SK_DROP;
}
}
struct AES_ctx aes_ctx;
__u8 key[AES_KEYLEN];
__u8 *cid_prefix;
if (bpf_skb_load_bytes(reuse_md, sizeof(struct udphdr), qpktbuf,
sizeof(qpktbuf)) != 0) {
@@ -519,24 +592,35 @@ int select_reuseport(struct sk_reuseport_md *reuse_md) {
return SK_DROP;
}
aes_ctx = bpf_map_lookup_elem(&aes_key, &zero);
if (aes_ctx == NULL) {
pkey = bpf_map_lookup_elem(&sk_info, &key_high_idx);
if (pkey == NULL) {
return SK_DROP;
}
__builtin_memcpy(key, pkey, sizeof(*pkey));
pkey = bpf_map_lookup_elem(&sk_info, &key_low_idx);
if (pkey == NULL) {
return SK_DROP;
}
__builtin_memcpy(key + sizeof(*pkey), pkey, sizeof(*pkey));
rv = parse_quic(&qhd, qpktbuf, qpktbuf + sizeof(qpktbuf));
if (rv != 0) {
return SK_DROP;
}
AES_init_ctx(&aes_ctx, key);
switch (qhd.type) {
case NGTCP2_PKT_INITIAL:
case NGTCP2_PKT_0RTT:
if (qhd.dcidlen == SV_DCIDLEN) {
worker_id = qhd.dcid + WORKER_ID_OFFSET;
AES_ECB_decrypt(aes_ctx, worker_id);
cid_prefix = qhd.dcid + CID_PREFIX_OFFSET;
AES_ECB_decrypt(&aes_ctx, cid_prefix);
psk_index = bpf_map_lookup_elem(&worker_id_map, worker_id);
psk_index = bpf_map_lookup_elem(&cid_prefix_map, cid_prefix);
if (psk_index != NULL) {
sk_index = *psk_index;
@@ -553,10 +637,10 @@ int select_reuseport(struct sk_reuseport_md *reuse_md) {
return SK_DROP;
}
worker_id = qhd.dcid + WORKER_ID_OFFSET;
AES_ECB_decrypt(aes_ctx, worker_id);
cid_prefix = qhd.dcid + CID_PREFIX_OFFSET;
AES_ECB_decrypt(&aes_ctx, cid_prefix);
psk_index = bpf_map_lookup_elem(&worker_id_map, worker_id);
psk_index = bpf_map_lookup_elem(&cid_prefix_map, cid_prefix);
if (psk_index == NULL) {
sk_index = sk_index_from_dcid(&qhd, reuse_md, *pnum_socks);

40
cmake/FindCUnit.cmake Normal file
View File

@@ -0,0 +1,40 @@
# - Try to find cunit
# Once done this will define
# CUNIT_FOUND - System has cunit
# CUNIT_INCLUDE_DIRS - The cunit include directories
# CUNIT_LIBRARIES - The libraries needed to use cunit
find_package(PkgConfig QUIET)
pkg_check_modules(PC_CUNIT QUIET cunit)
find_path(CUNIT_INCLUDE_DIR
NAMES CUnit/CUnit.h
HINTS ${PC_CUNIT_INCLUDE_DIRS}
)
find_library(CUNIT_LIBRARY
NAMES cunit
HINTS ${PC_CUNIT_LIBRARY_DIRS}
)
if(CUNIT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+CU_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${CUNIT_INCLUDE_DIR}/CUnit/CUnit.h"
CUNIT_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
CUNIT_VERSION "${CUNIT_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set CUNIT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(CUnit REQUIRED_VARS
CUNIT_LIBRARY CUNIT_INCLUDE_DIR
VERSION_VAR CUNIT_VERSION)
if(CUNIT_FOUND)
set(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
set(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
endif()
mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)

View File

@@ -1,36 +0,0 @@
# - Try to find libbrotlidec
# Once done this will define
# LIBBROTLIDEC_FOUND - System has libbrotlidec
# LIBBROTLIDEC_INCLUDE_DIRS - The libbrotlidec include directories
# LIBBROTLIDEC_LIBRARIES - The libraries needed to use libbrotlidec
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBBROTLIDEC QUIET libbrotlidec)
find_path(LIBBROTLIDEC_INCLUDE_DIR
NAMES brotli/decode.h
HINTS ${PC_LIBBROTLIDEC_INCLUDE_DIRS}
)
find_library(LIBBROTLIDEC_LIBRARY
NAMES brotlidec
HINTS ${PC_LIBBROTLIDEC_LIBRARY_DIRS}
)
if(PC_LIBBROTLIDEC_FOUND)
set(LIBBROTLIDEC_VERSION ${PC_LIBBROTLIDEC_VERSION})
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBBROTLIDEC_FOUND
# to TRUE if all listed variables are TRUE and the requested version
# matches.
find_package_handle_standard_args(Libbrotlidec REQUIRED_VARS
LIBBROTLIDEC_LIBRARY LIBBROTLIDEC_INCLUDE_DIR
VERSION_VAR LIBBROTLIDEC_VERSION)
if(LIBBROTLIDEC_FOUND)
set(LIBBROTLIDEC_LIBRARIES ${LIBBROTLIDEC_LIBRARY})
set(LIBBROTLIDEC_INCLUDE_DIRS ${LIBBROTLIDEC_INCLUDE_DIR})
endif()
mark_as_advanced(LIBBROTLIDEC_INCLUDE_DIR LIBBROTLIDEC_LIBRARY)

View File

@@ -1,36 +0,0 @@
# - Try to find libbrotlienc
# Once done this will define
# LIBBROTLIENC_FOUND - System has libbrotlienc
# LIBBROTLIENC_INCLUDE_DIRS - The libbrotlienc include directories
# LIBBROTLIENC_LIBRARIES - The libraries needed to use libbrotlienc
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBBROTLIENC QUIET libbrotlienc)
find_path(LIBBROTLIENC_INCLUDE_DIR
NAMES brotli/encode.h
HINTS ${PC_LIBBROTLIENC_INCLUDE_DIRS}
)
find_library(LIBBROTLIENC_LIBRARY
NAMES brotlienc
HINTS ${PC_LIBBROTLIENC_LIBRARY_DIRS}
)
if(PC_LIBBROTLIENC_FOUND)
set(LIBBROTLIENC_VERSION ${PC_LIBBROTLIENC_VERSION})
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBBROTLIENC_FOUND
# to TRUE if all listed variables are TRUE and the requested version
# matches.
find_package_handle_standard_args(Libbrotlienc REQUIRED_VARS
LIBBROTLIENC_LIBRARY LIBBROTLIENC_INCLUDE_DIR
VERSION_VAR LIBBROTLIENC_VERSION)
if(LIBBROTLIENC_FOUND)
set(LIBBROTLIENC_LIBRARIES ${LIBBROTLIENC_LIBRARY})
set(LIBBROTLIENC_INCLUDE_DIRS ${LIBBROTLIENC_INCLUDE_DIR})
endif()
mark_as_advanced(LIBBROTLIENC_INCLUDE_DIR LIBBROTLIENC_LIBRARY)

View File

@@ -17,18 +17,12 @@ find_library(LIBCARES_LIBRARY
)
if(LIBCARES_INCLUDE_DIR)
file(READ "${LIBCARES_INCLUDE_DIR}/ares_version.h" _ares_version_h)
string(REGEX REPLACE ".*#define[ \t]+ARES_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1"
_ares_version_major ${_ares_version_h})
string(REGEX REPLACE ".*#define[ \t]+ARES_VERSION_MINOR[ \t]+([0-9]+).*" "\\1"
_ares_version_minor ${_ares_version_h})
string(REGEX REPLACE ".*#define[ \t]+ARES_VERSION_PATCH[ \t]+([0-9]+).*" "\\1"
_ares_version_patch ${_ares_version_h})
set(LIBCARES_VERSION "${_ares_version_major}.${_ares_version_minor}.${_ares_version_patch}")
unset(_ares_version_patch)
unset(_ares_version_minor)
unset(_ares_version_major)
unset(_ares_version_h)
set(_version_regex "^#define[ \t]+ARES_VERSION_STR[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBCARES_INCLUDE_DIR}/ares_version.h"
LIBCARES_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBCARES_VERSION "${LIBCARES_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)

View File

@@ -1,43 +0,0 @@
# - Try to find libngtcp2_crypto_libressl
# Once done this will define
# LIBNGTCP2_CRYPTO_LIBRESSL_FOUND - System has libngtcp2_crypto_libressl
# LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS - The libngtcp2_crypto_libressl include directories
# LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_libressl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_LIBRESSL QUIET libngtcp2_crypto_libressl)
find_path(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_quictls.h
HINTS ${PC_LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY
NAMES ngtcp2_crypto_libressl
HINTS ${PC_LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_LIBRESSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_LIBRESSL_VERSION "${LIBNGTCP2_CRYPTO_LIBRESSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_LIBRESSL_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_libressl REQUIRED_VARS
LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY
LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_LIBRESSL_VERSION)
if(LIBNGTCP2_CRYPTO_LIBRESSL_FOUND)
set(LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES ${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY})
set(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY)

View File

@@ -0,0 +1,43 @@
# - Try to find libngtcp2_crypto_openssl
# Once done this will define
# LIBNGTCP2_CRYPTO_OPENSSL_FOUND - System has libngtcp2_crypto_openssl
# LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS - The libngtcp2_crypto_openssl include directories
# LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_openssl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_OPENSSL QUIET libngtcp2_crypto_openssl)
find_path(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_openssl.h
HINTS ${PC_LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY
NAMES ngtcp2_crypto_openssl
HINTS ${PC_LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_OPENSSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_OPENSSL_VERSION "${LIBNGTCP2_CRYPTO_OPENSSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_OPENSSL_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_openssl REQUIRED_VARS
LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY
LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_OPENSSL_VERSION)
if(LIBNGTCP2_CRYPTO_OPENSSL_FOUND)
set(LIBNGTCP2_CRYPTO_OPENSSL_LIBRARIES ${LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY})
set(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_OPENSSL_INCLUDE_DIR
LIBNGTCP2_CRYPTO_OPENSSL_LIBRARY)

View File

@@ -1,43 +0,0 @@
# - Try to find libngtcp2_crypto_ossl
# Once done this will define
# LIBNGTCP2_CRYPTO_OSSL_FOUND - System has libngtcp2_crypto_ossl
# LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS - The libngtcp2_crypto_ossl include directories
# LIBNGTCP2_CRYPTO_OSSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_ossl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_OSSL QUIET libngtcp2_crypto_ossl)
find_path(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_ossl.h
HINTS ${PC_LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_OSSL_LIBRARY
NAMES ngtcp2_crypto_ossl
HINTS ${PC_LIBNGTCP2_CRYPTO_OSSL_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_OSSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_OSSL_VERSION "${LIBNGTCP2_CRYPTO_OSSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_OSSL_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_ossl REQUIRED_VARS
LIBNGTCP2_CRYPTO_OSSL_LIBRARY
LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_OSSL_VERSION)
if(LIBNGTCP2_CRYPTO_OSSL_FOUND)
set(LIBNGTCP2_CRYPTO_OSSL_LIBRARIES ${LIBNGTCP2_CRYPTO_OSSL_LIBRARY})
set(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
LIBNGTCP2_CRYPTO_OSSL_LIBRARY)

View File

@@ -1,43 +0,0 @@
# - Try to find libngtcp2_crypto_quictls
# Once done this will define
# LIBNGTCP2_CRYPTO_QUICTLS_FOUND - System has libngtcp2_crypto_quictls
# LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIRS - The libngtcp2_crypto_quictls include directories
# LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES - The libraries needed to use libngtcp2_crypto_quictls
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_QUICTLS QUIET libngtcp2_crypto_quictls)
find_path(LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_quictls.h
HINTS ${PC_LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_QUICTLS_LIBRARY
NAMES ngtcp2_crypto_quictls
HINTS ${PC_LIBNGTCP2_CRYPTO_QUICTLS_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_QUICTLS_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_QUICTLS_VERSION "${LIBNGTCP2_CRYPTO_QUICTLS_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_QUICTLS_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_quictls REQUIRED_VARS
LIBNGTCP2_CRYPTO_QUICTLS_LIBRARY
LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_QUICTLS_VERSION)
if(LIBNGTCP2_CRYPTO_QUICTLS_FOUND)
set(LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES ${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARY})
set(LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIR
LIBNGTCP2_CRYPTO_QUICTLS_LIBRARY)

View File

@@ -1,43 +0,0 @@
# - Try to find libngtcp2_crypto_wolfssl
# Once done this will define
# LIBNGTCP2_CRYPTO_WOLFSSL_FOUND - System has libngtcp2_crypto_wolfssl
# LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIRS - The libngtcp2_crypto_wolfssl include directories
# LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_wolfssl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_WOLFSSL QUIET libngtcp2_crypto_wolfssl)
find_path(LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_wolfssl.h
HINTS ${PC_LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARY
NAMES ngtcp2_crypto_wolfssl
HINTS ${PC_LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_WOLFSSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_WOLFSSL_VERSION "${LIBNGTCP2_CRYPTO_WOLFSSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_WOLFSSL_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_wolfssl REQUIRED_VARS
LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARY
LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_WOLFSSL_VERSION)
if(LIBNGTCP2_CRYPTO_WOLFSSL_FOUND)
set(LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES ${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARY})
set(LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIR
LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARY)

View File

@@ -1,41 +0,0 @@
# - Try to find wolfssl
# Once done this will define
# WOLFSSL_FOUND - System has wolfssl
# WOLFSSL_INCLUDE_DIRS - The wolfssl include directories
# WOLFSSL_LIBRARIES - The libraries needed to use wolfssl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_WOLFSSL QUIET wolfssl)
find_path(WOLFSSL_INCLUDE_DIR
NAMES wolfssl/ssl.h
HINTS ${PC_WOLFSSL_INCLUDE_DIRS}
)
find_library(WOLFSSL_LIBRARY
NAMES wolfssl
HINTS ${PC_WOLFSSL_LIBRARY_DIRS}
)
if(WOLFSSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+LIBWOLFSSL_VERSION_STRING[ \t]+\"([^\"]+)\".*")
file(STRINGS "${WOLFSSL_INCLUDE_DIR}/wolfssl/version.h"
WOLFSSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
WOLFSSL_VERSION "${WOLFSSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set WOLFSSL_FOUND
# to TRUE if all listed variables are TRUE and the requested version
# matches.
find_package_handle_standard_args(WolfSSL REQUIRED_VARS
WOLFSSL_LIBRARY WOLFSSL_INCLUDE_DIR
VERSION_VAR WOLFSSL_VERSION)
if(WOLFSSL_FOUND)
set(WOLFSSL_LIBRARIES ${WOLFSSL_LIBRARY})
set(WOLFSSL_INCLUDE_DIRS ${WOLFSSL_INCLUDE_DIR})
endif()
mark_as_advanced(WOLFSSL_INCLUDE_DIR WOLFSSL_LIBRARY)

View File

@@ -1,162 +0,0 @@
# 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-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

@@ -1,121 +0,0 @@
# 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}
)
list(APPEND WPICKY_ENABLE
# clang++-18 warns this when building with wolfSSL >= v5.7.6-stable.
-Wno-extern-c-compat
)
# 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

@@ -4,8 +4,8 @@
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine ssize_t @ssize_t@
/* Define to 1 if you have the `std::chrono::time_zone`. */
#cmakedefine HAVE_STD_CHRONO_TIME_ZONE 1
/* Define to 1 if you have the `std::map::emplace`. */
#cmakedefine HAVE_STD_MAP_EMPLACE 1
/* Define to 1 if you have `libjansson` library. */
#cmakedefine HAVE_JANSSON 1
@@ -19,30 +19,24 @@
/* Define to 1 if you have `neverbleed` library. */
#cmakedefine HAVE_NEVERBLEED 1
/* sizeof(int *) */
#cmakedefine SIZEOF_INT_P @SIZEOF_INT_P@
/* sizeof(time_t) */
#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
/* Define to 1 if you have the `_Exit` function. */
#cmakedefine HAVE__EXIT 1
/* 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 `pipe2` function. */
#cmakedefine HAVE_PIPE2 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
/* Define to 1 if you have the `CLOCK_MONOTONIC` defined. */
#cmakedefine01 HAVE_DECL_CLOCK_MONOTONIC
/* Define to 1 to enable debug output. */
#cmakedefine DEBUGBUILD 1
@@ -67,9 +61,6 @@
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <netinet/ip.h> header file. */
#cmakedefine HAVE_NETINET_IP_H 1
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
@@ -82,12 +73,12 @@
/* Define to 1 if you have the <syslog.h> header file. */
#cmakedefine HAVE_SYSLOG_H 1
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
/* Define to 1 if you have the <windows.h> header file. */
#cmakedefine HAVE_WINDOWS_H 1
/* Define to 1 if HTTP/3 is enabled. */
#cmakedefine ENABLE_HTTP3 1
@@ -97,20 +88,5 @@
/* Define to 1 if you have enum bpf_stats_type in linux/bpf.h. */
#cmakedefine HAVE_BPF_STATS_TYPE 1
/* Define to 1 if you have `libngtcp2_crypto_quictls` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_QUICTLS
/* Define to 1 if you have `libngtcp2_crypto_libressl` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_LIBRESSL
/* Define to 1 if you have `libngtcp2_crypto_wolfssl` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1
/* Define to 1 if you have `libev` library. */
#cmakedefine HAVE_LIBEV 1
/* Define to 1 if you have `libbrotlienc` and `libbrotlidec` libraries. */
#cmakedefine HAVE_LIBBROTLI 1
/* Define to 1 if you have `wolfssl` library. */
#cmakedefine HAVE_WOLFSSL 1
/* Define to 1 if you have `libngtcp2_crypto_openssl` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_OPENSSL

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.69.0-DEV], [t-tujikawa@users.sourceforge.net])
AC_INIT([nghttp2], [1.52.0-DEV], [t-tujikawa@users.sourceforge.net])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
@@ -38,15 +38,15 @@ AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects tar-pax])
AM_INIT_AUTOMAKE([subdir-objects])
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, 43)
AC_SUBST(LT_REVISION, 2)
AC_SUBST(LT_AGE, 29)
AC_SUBST(LT_CURRENT, 38)
AC_SUBST(LT_REVISION, 1)
AC_SUBST(LT_AGE, 24)
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"`
@@ -127,11 +127,6 @@ AC_ARG_WITH([libcares],
[Use libc-ares [default=check]])],
[request_libcares=$withval], [request_libcares=check])
AC_ARG_WITH([wolfssl],
[AS_HELP_STRING([--with-wolfssl],
[Use wolfSSL [default=check]])],
[request_wolfssl=$withval], [request_wolfssl=check])
AC_ARG_WITH([openssl],
[AS_HELP_STRING([--with-openssl],
[Use openssl [default=check]])],
@@ -142,6 +137,11 @@ AC_ARG_WITH([libev],
[Use libev [default=check]])],
[request_libev=$withval], [request_libev=check])
AC_ARG_WITH([cunit],
[AS_HELP_STRING([--with-cunit],
[Use cunit [default=check]])],
[request_cunit=$withval], [request_cunit=check])
AC_ARG_WITH([jemalloc],
[AS_HELP_STRING([--with-jemalloc],
[Use jemalloc [default=check]])],
@@ -177,16 +177,6 @@ AC_ARG_WITH([libbpf],
[Use libbpf [default=no]])],
[request_libbpf=$withval], [request_libbpf=no])
AC_ARG_WITH([libbrotlienc],
[AS_HELP_STRING([--with-libbrotlienc],
[Use libbrotlienc [default=no]])],
[request_libbrotlienc=$withval], [request_libbrotlienc=no])
AC_ARG_WITH([libbrotlidec],
[AS_HELP_STRING([--with-libbrotlidec],
[Use libbrotlidec [default=no]])],
[request_libbrotlidec=$withval], [request_libbrotlidec=no])
dnl Define variables
AC_ARG_VAR([LIBEV_CFLAGS], [C compiler flags for libev, skipping any checks])
AC_ARG_VAR([LIBEV_LIBS], [linker flags for libev, skipping any checks])
@@ -243,7 +233,7 @@ fi
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS=
AX_CXX_COMPILE_STDCXX([20], [], [optional])
AX_CXX_COMPILE_STDCXX([14], [noext], [optional])
CXX1XCXXFLAGS="$CXXFLAGS"
CXXFLAGS="$save_CXXFLAGS"
@@ -272,40 +262,55 @@ std::vector<std::future<int>> v;
[have_std_future=no
AC_MSG_RESULT([no])])
# Check that std::atomic<std::shared_ptr<T>> is supported.
AC_MSG_CHECKING([whether std::atomic<std::shared_ptr<T>> is supported])
# Check that std::map::emplace is available for g++-4.7.
AC_MSG_CHECKING([whether std::map::emplace is available])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <map>
]],
[[
std::map<int, int>().emplace(1, 2);
]])],
[AC_DEFINE([HAVE_STD_MAP_EMPLACE], [1],
[Define to 1 if you have the `std::map::emplace`.])
have_std_map_emplace=yes
AC_MSG_RESULT([yes])],
[have_std_map_emplace=no
AC_MSG_RESULT([no])])
# Check that std::atomic_* overloads for std::shared_ptr are
# available.
AC_MSG_CHECKING([whether std::atomic_* overloads for std::shared_ptr are available])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <memory>
]],
[[
auto a = std::atomic<std::shared_ptr<int>>(std::make_shared<int>(1000000007));
auto p = a.load();
auto a = std::make_shared<int>(1000000007);
auto p = std::atomic_load(&a);
++*p;
a.store(p);
std::atomic_store(&a, p);
]])],
[AC_DEFINE([HAVE_ATOMIC_STD_SHARED_PTR], [1],
[Define to 1 if you have the std::atomic<std::shared_ptr<T>> is supported.])
[Define to 1 if you have the std::atomic_* overloads for std::shared_ptr.])
have_atomic_std_shared_ptr=yes
AC_MSG_RESULT([yes])],
[have_atomic_std_shared_ptr=no
AC_MSG_RESULT([no])])
# Check that std::chrono::time_zone is available.
AC_MSG_CHECKING([whether std::chrono::time_zone is available])
# Check that thread_local storage specifier is available
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
,
[[
#include <chrono>
]],
[[
auto tz = std::chrono::current_zone();
(void)tz;
thread_local int a = 0;
(void)a;
]])],
[AC_DEFINE([HAVE_STD_CHRONO_TIME_ZONE], [1],
[Define to 1 if you have the `std::chrono::time_zone`.])
have_std_chrono_time_zone=yes
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
[Define to 1 if you have thread_local storage specifier.])
have_thread_local=yes
AC_MSG_RESULT([yes])],
[have_std_chrono_time_zone=no
[have_Thread_local=no
AC_MSG_RESULT([no])])
CXXFLAGS=$save_CXXFLAGS
@@ -324,7 +329,7 @@ case "$host_os" in
*android*)
android_build=yes
# android does not need -pthread, but needs following 2 libs for C++
APPLDFLAGS="$APPLDFLAGS -latomic"
APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic"
;;
*)
PTHREAD_LDFLAGS="-pthread"
@@ -372,6 +377,43 @@ case "${host_os}" in
;;
esac
# cunit
have_cunit=no
if test "x${request_cunit}" != "xno"; then
PKG_CHECK_MODULES([CUNIT], [cunit >= 2.1], [have_cunit=yes], [have_cunit=no])
# If pkg-config does not find cunit, check it using AC_CHECK_LIB. We
# do this because Debian (Ubuntu) lacks pkg-config file for cunit.
if test "x${have_cunit}" = "xno"; then
AC_MSG_WARN([${CUNIT_PKG_ERRORS}])
AC_CHECK_LIB([cunit], [CU_initialize_registry],
[have_cunit=yes], [have_cunit=no])
if test "x${have_cunit}" = "xyes"; then
CUNIT_LIBS="-lcunit"
CUNIT_CFLAGS=""
AC_SUBST([CUNIT_LIBS])
AC_SUBST([CUNIT_CFLAGS])
fi
fi
if test "x${have_cunit}" = "xyes"; then
# cunit in Mac OS X requires ncurses. Note that in Mac OS X, test
# program can be built without -lncurses, but it emits runtime
# error.
case "${build}" in
*-apple-darwin*)
CUNIT_LIBS="$CUNIT_LIBS -lncurses"
AC_SUBST([CUNIT_LIBS])
;;
esac
fi
fi
if test "x${request_cunit}" = "xyes" &&
test "x${have_cunit}" != "xyes"; then
AC_MSG_ERROR([cunit was requested (--with-cunit) but not found])
fi
AM_CONDITIONAL([HAVE_CUNIT], [ test "x${have_cunit}" = "xyes" ])
# libev (for src)
have_libev=no
if test "x${request_libev}" != "xno"; then
@@ -391,10 +433,6 @@ if test "x${request_libev}" != "xno"; then
else
have_libev=yes
fi
if test "x${have_libev}" = "xyes"; then
AC_DEFINE([HAVE_LIBEV], [1], [Define to 1 if you have `libev` library.])
fi
fi
if test "x${request_libev}" = "xyes" &&
@@ -402,55 +440,30 @@ if test "x${request_libev}" = "xyes" &&
AC_MSG_ERROR([libev was requested (--with-libev) but not found])
fi
if test "x${request_openssl}" = "xyes" &&
test "x${request_wolfssl}" = "xyes"; then
AC_MSG_ERROR([Requesting both OpenSSL and wolfSSL is not allowed])
fi
# openssl (for src)
have_openssl=no
if test "x${request_openssl}" != "xno" &&
test "x${request_wolfssl}" != "xyes"; then
PKG_CHECK_MODULES([OPENSSL], [openssl >= 1.1.1],
if test "x${request_openssl}" != "xno"; then
PKG_CHECK_MODULES([OPENSSL], [openssl >= 1.0.1],
[have_openssl=yes], [have_openssl=no])
if test "x${have_openssl}" = "xno"; then
AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
else
# Use C++ compiler because boringssl needs C++ runtime.
AC_LANG_PUSH(C++)
save_CXXFLAGS="$CXXFLAGS"
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"
CFLAGS="$OPENSSL_CFLAGS $CFLAGS"
LIBS="$OPENSSL_LIBS $LIBS"
# quictls/openssl has SSL_provide_quic_data. boringssl also has
# it. We will deal with it later.
have_ssl_provide_quic_data=no
AC_MSG_CHECKING([for SSL_provide_quic_data])
# quictls/openssl has SSL_is_quic.
have_ssl_is_quic=no
AC_MSG_CHECKING([for SSL_is_quic])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/ssl.h>
]], [[
SSL_provide_quic_data(NULL, (ssl_encryption_level_t)0, NULL, 0);
SSL *ssl = NULL;
SSL_is_quic(ssl);
]])],
[AC_MSG_RESULT([yes]); have_ssl_provide_quic_data=yes],
[AC_MSG_RESULT([no]); have_ssl_provide_quic_data=no])
# Check whether this is libressl or not
AC_CHECK_DECLS([LIBRESSL_VERSION_NUMBER],
[have_libressl=yes], [have_libressl=no],
[[
#include <openssl/opensslv.h>
]])
AC_MSG_CHECKING([for SSL_set_quic_tls_cbs])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/ssl.h>
]], [[
SSL_set_quic_tls_cbs(NULL, NULL, NULL);
]])],
[AC_MSG_RESULT([yes]); have_ossl_quic=yes],
[AC_MSG_RESULT([no]); have_ossl_quic=no])
[AC_MSG_RESULT([yes]); have_ssl_is_quic=yes],
[AC_MSG_RESULT([no]); have_ssl_is_quic=no])
# boringssl has SSL_set_quic_early_data_context.
AC_MSG_CHECKING([for SSL_set_quic_early_data_context])
@@ -463,10 +476,8 @@ if test "x${request_openssl}" != "xno" &&
[AC_MSG_RESULT([yes]); have_boringssl_quic=yes],
[AC_MSG_RESULT([no]); have_boringssl_quic=no])
CXXFLAGS="$save_CXXFLAGS"
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
AC_LANG_POP()
fi
fi
@@ -475,49 +486,10 @@ if test "x${request_openssl}" = "xyes" &&
AC_MSG_ERROR([openssl was requested (--with-openssl) but not found])
fi
# wolfSSL (for src)
have_wolfssl=no
if test "x${request_wolfssl}" != "xno" &&
test "x${request_openssl}" != "xyes" &&
test "x${have_openssl}" != "xyes"; then
PKG_CHECK_MODULES([WOLFSSL], [wolfssl >= 5.7.0],
[have_wolfssl=yes], [have_wolfssl=no])
if test "x${have_wolfssl}" = "xno"; then
AC_MSG_NOTICE($WOLFSSL_PKG_ERRORS)
else
AC_DEFINE([HAVE_WOLFSSL], [1],
[Define to 1 if you have 'wolfssl' library.])
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
CFLAGS="$WOLFSSL_CFLAGS $CFLAGS"
LIBS="$WOLFSSL_LIBS $LIBS"
have_wolfssl_quic=no
AC_MSG_CHECKING([for wolfSSL QUIC])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <wolfssl/options.h>
#include <wolfssl/openssl/ssl.h>
]], [[
SSL_provide_quic_data(NULL, 0, NULL, 0);
]])],
[AC_MSG_RESULT([yes]); have_wolfssl_quic=yes],
[AC_MSG_RESULT([no]); have_wolfssl_quic=no])
CFLAGS="$save_CFLAGS"
LIBS="$save_LIBS"
fi
fi
if test "x${request_wolfssl}" = "xyes" &&
test "x${have_wolfssl}" != "xyes"; then
AC_MSG_ERROR([wolfSSL was requested (--with-wolfssl) but not found])
fi
# c-ares (for src)
have_libcares=no
if test "x${request_libcares}" != "xno"; then
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.16.0], [have_libcares=yes],
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.5], [have_libcares=yes],
[have_libcares=no])
if test "x${have_libcares}" = "xno"; then
AC_MSG_NOTICE($LIBCARES_PKG_ERRORS)
@@ -532,7 +504,7 @@ fi
# ngtcp2 (for src)
have_libngtcp2=no
if test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 1.16.0], [have_libngtcp2=yes],
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 0.13.0], [have_libngtcp2=yes],
[have_libngtcp2=no])
if test "x${have_libngtcp2}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
@@ -544,76 +516,26 @@ if test "x${request_libngtcp2}" = "xyes" &&
AC_MSG_ERROR([libngtcp2 was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_wolfssl (for src)
have_libngtcp2_crypto_wolfssl=no
if test "x${have_wolfssl_quic}" = "xyes" &&
# ngtcp2_crypto_openssl (for src)
have_libngtcp2_crypto_openssl=no
if test "x${have_ssl_is_quic}" = "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_WOLFSSL],
[libngtcp2_crypto_wolfssl >= 1.16.0],
[have_libngtcp2_crypto_wolfssl=yes],
[have_libngtcp2_crypto_wolfssl=no])
if test "x${have_libngtcp2_crypto_wolfssl}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_WOLFSSL_PKG_ERRORS)
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OPENSSL],
[libngtcp2_crypto_openssl >= 0.13.0],
[have_libngtcp2_crypto_openssl=yes],
[have_libngtcp2_crypto_openssl=no])
if test "x${have_libngtcp2_crypto_openssl}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OPENSSL_PKG_ERRORS)
else
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_WOLFSSL], [1],
[Define to 1 if you have `libngtcp2_crypto_wolfssl` library.])
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_OPENSSL], [1],
[Define to 1 if you have `libngtcp2_crypto_openssl` library.])
fi
fi
if test "x${have_wolfssl_quic}" = "xyes" &&
if test "x${have_ssl_is_quic}" = "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_wolfssl}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_wolfssl was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_quictls (for src)
have_libngtcp2_crypto_quictls=no
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" != "xyes" &&
test "x${have_boringssl_quic}" != "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_QUICTLS],
[libngtcp2_crypto_quictls >= 1.16.0],
[have_libngtcp2_crypto_quictls=yes],
[have_libngtcp2_crypto_quictls=no])
if test "x${have_libngtcp2_crypto_quictls}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_QUICTLS_PKG_ERRORS)
else
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_QUICTLS], [1],
[Define to 1 if you have `libngtcp2_crypto_quictls` library.])
fi
fi
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" != "xyes" &&
test "x${have_boringssl_quic}" != "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_quictls}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_quictls was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_libressl (for src)
have_libngtcp2_crypto_libressl=no
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" = "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_LIBRESSL],
[libngtcp2_crypto_libressl >= 1.16.0],
[have_libngtcp2_crypto_libressl=yes],
[have_libngtcp2_crypto_libressl=no])
if test "x${have_libngtcp2_crypto_libressl}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_LIBRESSL_PKG_ERRORS)
else
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_LIBRESSL], [1],
[Define to 1 if you have `libngtcp2_crypto_libressl` library.])
fi
fi
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" = "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_libressl}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_libressl was requested (--with-libngtcp2) but not found])
test "x${have_libngtcp2_crypto_openssl}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_openssl was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_boringssl (for src)
@@ -638,32 +560,10 @@ if test "x${have_boringssl_quic}" = "xyes" &&
AC_MSG_ERROR([libngtcp2_crypto_boringssl was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_ossl (for src)
have_libngtcp2_crypto_ossl=no
if test "x${have_ossl_quic}" = "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OSSL],
[libngtcp2_crypto_ossl >= 1.16.0],
[have_libngtcp2_crypto_ossl=yes],
[have_libngtcp2_crypto_ossl=no])
if test "x${have_libngtcp2_crypto_ossl}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OSSL_PKG_ERRORS)
else
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_OSSL], [1],
[Define to 1 if you have `libngtcp2_crypto_ossl` library.])
fi
fi
if test "x${have_ossl_quic}" = "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_ossl}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_ossl was requested (--with-libngtcp2) but not found])
fi
# nghttp3 (for src)
have_libnghttp3=no
if test "x${request_libnghttp3}" != "xno"; then
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 1.12.0], [have_libnghttp3=yes],
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 0.7.0], [have_libnghttp3=yes],
[have_libnghttp3=no])
if test "x${have_libnghttp3}" = "xno"; then
AC_MSG_NOTICE($LIBNGHTTP3_PKG_ERRORS)
@@ -720,47 +620,6 @@ fi
AM_CONDITIONAL([HAVE_LIBBPF], [ test "x${have_libbpf}" = "xyes" ])
# libbrotlienc (for src)
have_libbrotlienc=no
if test "x${request_libbrotlienc}" != "xno"; then
PKG_CHECK_MODULES([LIBBROTLIENC], [libbrotlienc >= 1.0.9],
[have_libbrotlienc=yes],
[have_libbrotlienc=no])
if test "x${have_libbrotlienc}" = "xno"; then
AC_MSG_NOTICE($LIBBROTLIENC_PKG_ERRORS)
fi
fi
if test "x${request_libbrotlienc}" = "xyes" &&
test "x${have_libbrotlienc}" != "xyes"; then
AC_MSG_ERROR([libbrotlienc was requested (--with-libbrotlienc) but not found])
fi
# libbrotlidec (for src)
have_libbrotlidec=no
if test "x${request_libbrotlidec}" != "xno"; then
PKG_CHECK_MODULES([LIBBROTLIDEC], [libbrotlidec >= 1.0.9],
[have_libbrotlidec=yes],
[have_libbrotlidec=no])
if test "x${have_libbrotlidec}" = "xno"; then
AC_MSG_NOTICE($LIBBROTLIDEC_PKG_ERRORS)
fi
fi
if test "x${request_libbrotlidec}" = "xyes" &&
test "x${have_libbrotlidec}" != "xyes"; then
AC_MSG_ERROR([libbrotlidec was requested (--with-libbrotlidec) but not found])
fi
have_libbrotli=no
if test "x${have_libbrotlienc}" = "xyes" &&
test "x${have_libbrotlidec}" = "xyes"; then
have_libbrotli=yes
AC_DEFINE([HAVE_LIBBROTLI], [1],
[Define to 1 if you have `libbrotlienc` and `libbrotlidec` libraries.])
fi
# libevent_openssl (for examples)
# 2.0.8 is required because we use evconnlistener_set_error_cb()
have_libevent_openssl=no
@@ -873,7 +732,7 @@ fi
enable_app=no
if test "x${request_app}" != "xno" &&
test "x${have_zlib}" = "xyes" &&
(test "x${have_openssl}" = "xyes" || test "x${have_wolfssl}" = "xyes") &&
test "x${have_openssl}" = "xyes" &&
test "x${have_libev}" = "xyes" &&
test "x${have_libcares}" = "xyes"; then
enable_app=yes
@@ -889,12 +748,11 @@ AM_CONDITIONAL([ENABLE_APP], [ test "x${enable_app}" = "xyes" ])
# Check HTTP/3 support
enable_http3=no
if test "x${request_http3}" != "xno" &&
(test "x${have_ssl_is_quic}" = "xyes" ||
test "x${have_boringssl_quic}" = "xyes") &&
test "x${have_libngtcp2}" = "xyes" &&
(test "x${have_libngtcp2_crypto_wolfssl}" = "xyes" ||
test "x${have_libngtcp2_crypto_quictls}" = "xyes" ||
test "x${have_libngtcp2_crypto_libressl}" = "xyes" ||
test "x${have_libngtcp2_crypto_boringssl}" = "xyes" ||
test "x${have_libngtcp2_crypto_ossl}" = "xyes") &&
(test "x${have_libngtcp2_crypto_openssl}" = "xyes" ||
test "x${have_libngtcp2_crypto_boringssl}" = "xyes") &&
test "x${have_libnghttp3}" = "xyes"; then
enable_http3=yes
AC_DEFINE([ENABLE_HTTP3], [1], [Define to 1 if HTTP/3 is enabled.])
@@ -985,7 +843,6 @@ AC_CHECK_HEADERS([ \
limits.h \
netdb.h \
netinet/in.h \
netinet/ip.h \
pwd.h \
stddef.h \
stdint.h \
@@ -994,8 +851,8 @@ AC_CHECK_HEADERS([ \
sys/socket.h \
sys/time.h \
syslog.h \
time.h \
unistd.h \
windows.h \
])
# Checks for typedefs, structures, and compiler characteristics.
@@ -1045,6 +902,12 @@ if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
[Define to 1 if you have `struct tm.tm_gmtoff` member.])
fi
# Check size of pointer to decide we need 8 bytes alignment
# adjustment.
AC_CHECK_SIZEOF([int *])
AC_CHECK_SIZEOF([time_t])
# Checks for library functions.
# Don't check malloc, since it does not play nicely with C++ stdlib
@@ -1061,7 +924,6 @@ AC_FUNC_STRNLEN
AC_CHECK_FUNCS([ \
_Exit \
accept4 \
clock_gettime \
dup2 \
getcwd \
getpwnam \
@@ -1070,7 +932,6 @@ AC_CHECK_FUNCS([ \
memmove \
memset \
mkostemp \
pipe2 \
socket \
sqrt \
strchr \
@@ -1088,25 +949,6 @@ 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 <windows.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.
@@ -1117,10 +959,6 @@ AC_CHECK_DECLS([initgroups], [], [], [[
#include <grp.h>
]])
AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[
#include <time.h>
]])
save_CFLAGS=$CFLAGS
save_CXXFLAGS=$CXXFLAGS
@@ -1175,7 +1013,6 @@ if test "x$werror" != "xno"; then
# Only work with Clang for the moment
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CFLAGS="$CFLAGS -Wsometimes-uninitialized"])
AX_CHECK_COMPILE_FLAG([-Wextra-semi], [CFLAGS="$CFLAGS -Wextra-semi"])
# This is required because we pass format string as "const char*.
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
@@ -1186,13 +1023,9 @@ if test "x$werror" != "xno"; then
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
AX_CHECK_COMPILE_FLAG([-Wextra-semi], [CXXFLAGS="$CXXFLAGS -Wextra-semi"])
AX_CHECK_COMPILE_FLAG([-Wconversion], [CXXFLAGS="$CXXFLAGS -Wconversion"])
# Disable noexcept-type warning of g++-7. This is not harmful as
# long as all source files are compiled with the same compiler.
AX_CHECK_COMPILE_FLAG([-Wno-noexcept-type], [CXXFLAGS="$CXXFLAGS -Wno-noexcept-type"])
# clang++-18 warns this when building with wolfSSL >= v5.7.6-stable.
AX_CHECK_COMPILE_FLAG([-Wno-extern-c-compat], [CXXFLAGS="$CXXFLAGS -Wno-extern-c-compat"])
AC_LANG_POP()
fi
@@ -1239,7 +1072,6 @@ AC_CONFIG_FILES([
tests/testdata/Makefile
third-party/Makefile
src/Makefile
src/testdata/Makefile
bpf/Makefile
examples/Makefile
integration-tests/Makefile
@@ -1259,6 +1091,7 @@ AC_CONFIG_FILES([
doc/nghttp2ver.h.rst
doc/contribute.rst
contrib/Makefile
script/Makefile
])
AC_OUTPUT
@@ -1298,18 +1131,16 @@ AC_MSG_NOTICE([summary of build options:
Python: ${PYTHON}
PYTHON_VERSION: ${PYTHON_VERSION}
Test:
CUnit: ${have_cunit} (CFLAGS='${CUNIT_CFLAGS}' LIBS='${CUNIT_LIBS}')
Failmalloc: ${enable_failmalloc}
Libs:
wolfSSL: ${have_wolfssl} (CFLAGS='${WOLFSSL_CFLAGS}' LIBS='${WOLFSSL_LIBS}')
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
Libxml2: ${have_libxml2} (CFLAGS='${LIBXML2_CFLAGS}' LIBS='${LIBXML2_LIBS}')
Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
Libc-ares: ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
libngtcp2: ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
libngtcp2_crypto_quictls: ${have_libngtcp2_crypto_quictls} (CFLAGS='${LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBS}')
libngtcp2_crypto_libressl: ${have_libngtcp2_crypto_libressl} (CFLAGS='${LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_LIBRESSL_LIBS}')
libngtcp2_crypto_openssl: ${have_libngtcp2_crypto_openssl} (CFLAGS='${LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OPENSSL_LIBS}')
libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
libngtcp2_crypto_ossl: ${have_libngtcp2_crypto_ossl} (CFLAGS='${LIBNGTCP2_CRYPTO_OSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OSSL_LIBS}')
libnghttp3: ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
libbpf: ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
@@ -1317,8 +1148,6 @@ AC_MSG_NOTICE([summary of build options:
Jemalloc: ${have_jemalloc} (CFLAGS='${JEMALLOC_CFLAGS}' LIBS='${JEMALLOC_LIBS}')
Zlib: ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}')
Systemd: ${have_libsystemd} (CFLAGS='${SYSTEMD_CFLAGS}' LIBS='${SYSTEMD_LIBS}')
Libbrotlienc: ${have_libbrotlienc} (CFLAGS="${LIBBROTLIENC_CFLAGS}' LIBS='${LIBBROTLIENC_LIBS}')
Libbrotlidec: ${have_libbrotlidec} (CFLAGS="${LIBBROTLIDEC_CFLAGS}' LIBS='${LIBBROTLIDEC_LIBS}')
Third-party:
http-parser: ${enable_third_party}
MRuby: ${have_mruby} (CFLAGS='${LIBMRUBY_CFLAGS}' LIBS='${LIBMRUBY_LIBS}')

View File

@@ -33,7 +33,6 @@ APIDOCS= \
nghttp2_check_header_value_rfc9113.rst \
nghttp2_check_method.rst \
nghttp2_check_path.rst \
nghttp2_extpri_parse_priority.rst \
nghttp2_hd_deflate_bound.rst \
nghttp2_hd_deflate_change_table_size.rst \
nghttp2_hd_deflate_del.rst \
@@ -42,9 +41,7 @@ APIDOCS= \
nghttp2_hd_deflate_get_num_table_entries.rst \
nghttp2_hd_deflate_get_table_entry.rst \
nghttp2_hd_deflate_hd.rst \
nghttp2_hd_deflate_hd2.rst \
nghttp2_hd_deflate_hd_vec.rst \
nghttp2_hd_deflate_hd_vec2.rst \
nghttp2_hd_deflate_new.rst \
nghttp2_hd_deflate_new2.rst \
nghttp2_hd_inflate_change_table_size.rst \
@@ -56,7 +53,6 @@ APIDOCS= \
nghttp2_hd_inflate_get_table_entry.rst \
nghttp2_hd_inflate_hd.rst \
nghttp2_hd_inflate_hd2.rst \
nghttp2_hd_inflate_hd3.rst \
nghttp2_hd_inflate_new.rst \
nghttp2_hd_inflate_new2.rst \
nghttp2_http2_strerror.rst \
@@ -77,13 +73,9 @@ APIDOCS= \
nghttp2_option_set_peer_max_concurrent_streams.rst \
nghttp2_option_set_server_fallback_rfc7540_priorities.rst \
nghttp2_option_set_user_recv_extension_type.rst \
nghttp2_option_set_max_continuations.rst \
nghttp2_option_set_max_outbound_ack.rst \
nghttp2_option_set_max_settings.rst \
nghttp2_option_set_stream_reset_rate_limit.rst \
nghttp2_option_set_glitch_rate_limit.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_pack_settings_payload2.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
nghttp2_priority_spec_init.rst \
@@ -92,12 +84,10 @@ APIDOCS= \
nghttp2_rcbuf_incref.rst \
nghttp2_rcbuf_is_static.rst \
nghttp2_select_next_protocol.rst \
nghttp2_select_alpn.rst \
nghttp2_session_callbacks_del.rst \
nghttp2_session_callbacks_new.rst \
nghttp2_session_callbacks_set_before_frame_send_callback.rst \
nghttp2_session_callbacks_set_data_source_read_length_callback.rst \
nghttp2_session_callbacks_set_data_source_read_length_callback2.rst \
nghttp2_session_callbacks_set_error_callback.rst \
nghttp2_session_callbacks_set_error_callback2.rst \
nghttp2_session_callbacks_set_on_begin_frame_callback.rst \
@@ -114,14 +104,9 @@ APIDOCS= \
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst \
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback2.rst \
nghttp2_session_callbacks_set_rand_callback.rst \
nghttp2_session_callbacks_set_recv_callback.rst \
nghttp2_session_callbacks_set_recv_callback2.rst \
nghttp2_session_callbacks_set_select_padding_callback.rst \
nghttp2_session_callbacks_set_select_padding_callback2.rst \
nghttp2_session_callbacks_set_send_callback.rst \
nghttp2_session_callbacks_set_send_callback2.rst \
nghttp2_session_callbacks_set_send_data_callback.rst \
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
nghttp2_session_change_extpri_stream_priority.rst \
@@ -139,7 +124,6 @@ APIDOCS= \
nghttp2_session_find_stream.rst \
nghttp2_session_get_effective_local_window_size.rst \
nghttp2_session_get_effective_recv_data_length.rst \
nghttp2_session_get_extpri_stream_priority.rst \
nghttp2_session_get_hd_deflate_dynamic_table_size.rst \
nghttp2_session_get_hd_inflate_dynamic_table_size.rst \
nghttp2_session_get_last_proc_stream_id.rst \
@@ -158,9 +142,7 @@ APIDOCS= \
nghttp2_session_get_stream_remote_window_size.rst \
nghttp2_session_get_stream_user_data.rst \
nghttp2_session_mem_recv.rst \
nghttp2_session_mem_recv2.rst \
nghttp2_session_mem_send.rst \
nghttp2_session_mem_send2.rst \
nghttp2_session_recv.rst \
nghttp2_session_resume_data.rst \
nghttp2_session_send.rst \
@@ -188,7 +170,6 @@ APIDOCS= \
nghttp2_strerror.rst \
nghttp2_submit_altsvc.rst \
nghttp2_submit_data.rst \
nghttp2_submit_data2.rst \
nghttp2_submit_extension.rst \
nghttp2_submit_goaway.rst \
nghttp2_submit_headers.rst \
@@ -198,9 +179,7 @@ APIDOCS= \
nghttp2_submit_priority_update.rst \
nghttp2_submit_push_promise.rst \
nghttp2_submit_request.rst \
nghttp2_submit_request2.rst \
nghttp2_submit_response.rst \
nghttp2_submit_response2.rst \
nghttp2_submit_rst_stream.rst \
nghttp2_submit_settings.rst \
nghttp2_submit_shutdown_notice.rst \
@@ -229,6 +208,7 @@ EXTRA_DIST = \
sources/h2load-howto.rst \
sources/building-android-binary.rst \
sources/contribute.rst \
sources/security.rst \
_exts/rubydomain/LICENSE.rubydomain \
_exts/rubydomain/__init__.py \
_exts/rubydomain/rubydomain.py \

View File

@@ -68,7 +68,7 @@ The example follows::
* Callback function invoked when |session| wants to send data to
* remote peer.
*/
typedef nghttp2_ssize (*nghttp2_send_callback2)
typedef ssize_t (*nghttp2_send_callback)
(nghttp2_session *session,
const uint8_t *data, size_t length, int flags, void *user_data);
@@ -111,7 +111,7 @@ The example follows::
``@struct`` is used to refer to the struct. Currently, only struct
typedefs are supported. The comment block is used for the document for
the struct type itself. To document each member, put comment block
the struct type itself.To document each member, put comment block
starting with the line ``/**`` and ending with the ``*/`` just before
the member. When the line starts with ``}`` is encountered, the
``mkapiref.py`` extracts strings next to ``}`` as the name of struct.

View File

@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
"""
sphinxcontrib
~~~~~~~~~~~~~
This package is a namespace package that contains all extensions
distributed in the ``sphinx-contrib`` distribution.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
__import__('pkg_resources').declare_namespace(__name__)

View File

@@ -8,7 +8,7 @@ _h2load()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--requests --clients --threads --input-file --max-concurrent-streams --max-frame-size --window-bits --connection-window-bits --header --ciphers --tls13-ciphers --no-tls-proto --data --rate --rate-period --duration --warm-up-time --connection-active-timeout --connection-inactivity-timeout --timing-script-file --base-uri --alpn-list --h1 --header-table-size --encoder-header-table-size --log-file --qlog-file-base --connect-to --rps --groups --no-udp-gso --max-udp-payload-size --ktls --sni --verbose --version --help ' -- "$cur" ) )
COMPREPLY=( $( compgen -W '--requests --clients --threads --input-file --max-concurrent-streams --max-frame-size --window-bits --connection-window-bits --header --ciphers --tls13-ciphers --no-tls-proto --data --rate --rate-period --duration --warm-up-time --connection-active-timeout --connection-inactivity-timeout --timing-script-file --base-uri --npn-list --h1 --header-table-size --encoder-header-table-size --log-file --qlog-file-base --connect-to --rps --groups --no-udp-gso --max-udp-payload-size --ktls --verbose --version --help ' -- "$cur" ) )
;;
*)
_filedir

View File

@@ -8,7 +8,7 @@ _nghttp()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--verbose --null-out --remote-name --timeout --window-bits --connection-window-bits --get-assets --stat --header --trailer --cert --key --data --multiply --upgrade --extpri --peer-max-concurrent-streams --header-table-size --encoder-header-table-size --padding --har --color --continuation --no-content-length --hexdump --no-push --max-concurrent-streams --expect-continue --no-verify-peer --ktls --version --help ' -- "$cur" ) )
COMPREPLY=( $( compgen -W '--verbose --null-out --remote-name --timeout --window-bits --connection-window-bits --get-assets --stat --header --trailer --cert --key --data --multiply --upgrade --weight --peer-max-concurrent-streams --header-table-size --encoder-header-table-size --padding --har --color --continuation --no-content-length --no-dep --hexdump --no-push --max-concurrent-streams --expect-continue --no-verify-peer --ktls --no-rfc7540-pri --version --help ' -- "$cur" ) )
;;
*)
_filedir

View File

@@ -8,7 +8,7 @@ _nghttpd()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --groups --ktls --version --help ' -- "$cur" ) )
COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --ktls --no-rfc7540-pri --version --help ' -- "$cur" ) )
;;
*)
_filedir

View File

@@ -8,7 +8,7 @@ _nghttpx()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-idle-timeout --frontend-http3-idle-timeout --frontend-write-timeout --frontend-keep-alive-timeout --frontend-header-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --groups --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --alpn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --tls-ktls --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-window-size --frontend-http2-encoder-dynamic-table-size --frontend-http2-decoder-dynamic-table-size --backend-http2-encoder-dynamic-table-size --backend-http2-decoder-dynamic-table-size --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --require-http-scheme --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-read-timeout --frontend-http3-read-timeout --frontend-read-timeout --frontend-write-timeout --frontend-keep-alive-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --ecdh-curves --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --npn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --fetch-ocsp-response-file --ocsp-update-interval --ocsp-startup --no-verify-ocsp --no-ocsp --tls-session-cache-memcached --tls-session-cache-memcached-address-family --tls-session-cache-memcached-cert-file --tls-session-cache-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --tls-ktls --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-window-size --frontend-http2-encoder-dynamic-table-size --frontend-http2-decoder-dynamic-table-size --backend-http2-encoder-dynamic-table-size --backend-http2-decoder-dynamic-table-size --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --require-http-scheme --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
;;
*)
_filedir

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" "Oct 25, 2025" "1.68.0" "nghttp2"
.TH "H2LOAD" "1" "Nov 13, 2022" "1.51.0" "nghttp2"
.SH NAME
h2load \- HTTP/2 benchmarking tool
.SH SYNOPSIS
@@ -109,9 +109,9 @@ Default: \fB16K\fP
.TP
.B \-w, \-\-window\-bits=<N>
Sets the stream level initial window size to (2**<N>)\-1.
For QUIC, <N> is capped to 26 (roughly 64MiB). It
defaults to 24 (16MiB) for QUIC, and 30 for other
protocols.
For QUIC, <N> is capped to 26 (roughly 64MiB).
.sp
Default: \fB30\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -246,7 +246,7 @@ mutually exclusive.
Specify URI from which the scheme, host and port will be
used for all requests. The base URI overrides all
values defined either at the command line or inside
input files. If argument starts with \(dqunix:\(dq, then the
input files. If argument starts with "unix:", then the
rest of the argument will be treated as UNIX domain
socket path. The connection is made through that path
instead of TCP. In this case, scheme is inferred from
@@ -255,19 +255,20 @@ input files as usual.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-alpn\-list=<LIST>
.B \-\-npn\-list=<LIST>
Comma delimited list of ALPN protocol identifier sorted
in the order of preference. That means most desirable
protocol comes first. The parameter must be delimited
by a single comma only and any white spaces are treated
as a part of protocol string.
protocol comes first. This is used in both ALPN and
NPN. The parameter must be delimited by a single comma
only and any white spaces are treated as a part of
protocol string.
.sp
Default: \fBh2,http/1.1\fP
Default: \fBh2,h2\-16,h2\-14,http/1.1\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-h1
Short hand for \fI\%\-\-alpn\-list\fP=http/1.1
Short hand for \fI\%\-\-npn\-list\fP=http/1.1
\fI\%\-\-no\-tls\-proto\fP=http/1.1, which effectively force
http/1.1 for both http and https URI.
.UNINDENT
@@ -304,9 +305,9 @@ to buffering. Status code is \-1 for failed streams.
.B \-\-qlog\-file\-base=<PATH>
Enable qlog output and specify base file name for qlogs.
Qlog is emitted for each connection. For a given base
name \(dqbase\(dq, each output file name becomes
\(dqbase.M.N.sqlog\(dq where M is worker ID and N is client ID
(e.g. \(dqbase.0.3.sqlog\(dq). Only effective in QUIC runs.
name "base", each output file name becomes
"base.M.N.sqlog" where M is worker ID and N is client ID
(e.g. "base.0.3.sqlog"). Only effective in QUIC runs.
.UNINDENT
.INDENT 0.0
.TP
@@ -344,12 +345,6 @@ Enable ktls.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-sni=<DNSNAME>
Send <DNSNAME> in TLS SNI, overriding the host name
specified in URI.
.UNINDENT
.INDENT 0.0
.TP
.B \-v, \-\-verbose
Output debug information.
.UNINDENT
@@ -388,7 +383,7 @@ The number of requests completed.
.TP
.B succeeded
The number of requests completed successfully. Only HTTP status
code 2xx or 3xx are considered as success.
code 2xx or3xx are considered as success.
.TP
.B failed
The number of requests failed, including HTTP level failures
@@ -413,7 +408,7 @@ The number of status code h2load received.
.INDENT 7.0
.TP
.B total
The number of bytes received from the server \(dqon the wire\(dq. If
The number of bytes received from the server "on the wire". If
requests were made via TLS, this value is the number of decrypted
bytes.
.TP

View File

@@ -83,9 +83,9 @@ OPTIONS
.. option:: -w, --window-bits=<N>
Sets the stream level initial window size to (2\*\*<N>)-1.
For QUIC, <N> is capped to 26 (roughly 64MiB). It
defaults to 24 (16MiB) for QUIC, and 30 for other
protocols.
For QUIC, <N> is capped to 26 (roughly 64MiB).
Default: ``30``
.. option:: -W, --connection-window-bits=<N>
@@ -213,19 +213,20 @@ OPTIONS
the first URI appeared in the command line or inside
input files as usual.
.. option:: --alpn-list=<LIST>
.. option:: --npn-list=<LIST>
Comma delimited list of ALPN protocol identifier sorted
in the order of preference. That means most desirable
protocol comes first. The parameter must be delimited
by a single comma only and any white spaces are treated
as a part of protocol string.
protocol comes first. This is used in both ALPN and
NPN. The parameter must be delimited by a single comma
only and any white spaces are treated as a part of
protocol string.
Default: ``h2,http/1.1``
Default: ``h2,h2-16,h2-14,http/1.1``
.. option:: --h1
Short hand for :option:`--alpn-list`\=http/1.1
Short hand for :option:`--npn-list`\=http/1.1
:option:`--no-tls-proto`\=http/1.1, which effectively force
http/1.1 for both http and https URI.
@@ -290,11 +291,6 @@ OPTIONS
Enable ktls.
.. option:: --sni=<DNSNAME>
Send <DNSNAME> in TLS SNI, overriding the host name
specified in URI.
.. option:: -v, --verbose
Output debug information.
@@ -331,7 +327,7 @@ requests
The number of requests completed.
succeeded
The number of requests completed successfully. Only HTTP status
code 2xx or 3xx are considered as success.
code 2xx or3xx are considered as success.
failed
The number of requests failed, including HTTP level failures
(non-successful HTTP status code).

View File

@@ -12,7 +12,7 @@ requests
The number of requests completed.
succeeded
The number of requests completed successfully. Only HTTP status
code 2xx or 3xx are considered as success.
code 2xx or3xx are considered as success.
failed
The number of requests failed, including HTTP level failures
(non-successful HTTP status code).

View File

@@ -307,6 +307,7 @@ def arg_repl(matchobj):
def transform_content(content):
content = re.sub(r'^\s+\* ?', '', content)
content = re.sub(r'\|([^\s|]+)\|', arg_repl, content)
content = re.sub(r':enum:', ':macro:', content)
return content
if __name__ == '__main__':

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" "Oct 25, 2025" "1.68.0" "nghttp2"
.TH "NGHTTP" "1" "Nov 13, 2022" "1.51.0" "nghttp2"
.SH NAME
nghttp \- HTTP/2 client
.SH SYNOPSIS
@@ -141,15 +141,14 @@ HTTP upgrade request is performed with OPTIONS method.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-extpri=<PRI>
Sets RFC 9218 priority of given URI. <PRI> must be the
wire format of priority header field (e.g., \(dqu=3,i\(dq).
This option can be used multiple times, and N\-th
\fI\%\-\-extpri\fP option sets priority of N\-th URI in the command
line. If the number of this option is less than the
number of URI, the last option value is repeated. If
there is no \fI\%\-\-extpri\fP option, urgency is 3, and
incremental is false.
.B \-p, \-\-weight=<WEIGHT>
Sets weight of given URI. This option can be used
multiple times, and N\-th \fI\%\-p\fP option sets weight of N\-th
URI in the command line. If the number of \fI\%\-p\fP option is
less than the number of URI, the last \fI\%\-p\fP option value is
repeated. If there is no \fI\%\-p\fP option, default weight, 16,
is assumed. The valid value range is
[1, 256], inclusive.
.UNINDENT
.INDENT 0.0
.TP
@@ -206,6 +205,11 @@ Don\(aqt send content\-length header field.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-dep
Don\(aqt send dependency based priority hint to server.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-hexdump
Display the incoming traffic in hexadecimal (Canonical
hex+ASCII display). If SSL/TLS is used, decrypted data
@@ -243,6 +247,11 @@ Enable ktls.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-rfc7540\-pri
Disable RFC7540 priorities.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-version
Display version information and exit.
.UNINDENT
@@ -259,6 +268,63 @@ The <DURATION> argument is an integer and an optional unit (e.g., 1s
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
(hours, minutes, seconds and milliseconds, respectively). If a unit
is omitted, a second is used as unit.
.SH DEPENDENCY BASED PRIORITY
.sp
nghttp sends priority hints to server by default unless
\fI\%\-\-no\-dep\fP is used. nghttp mimics the way Firefox employs to
manages dependency using idle streams. We follows the behaviour of
Firefox Nightly as of April, 2015, and nghttp\(aqs behaviour is very
static and could be different from Firefox in detail. But reproducing
the same behaviour of Firefox is not our goal. The goal is provide
the easy way to test out the dependency priority in server
implementation.
.sp
When connection is established, nghttp sends 5 PRIORITY frames to idle
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
tree:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
+\-\-\-\-\-+
|id=0 |
+\-\-\-\-\-+
^ ^ ^
w=201 / | \e w=1
/ | \e
/ w=101| \e
+\-\-\-\-\-+ +\-\-\-\-\-+ +\-\-\-\-\-+
|id=3 | |id=5 | |id=7 |
+\-\-\-\-\-+ +\-\-\-\-\-+ +\-\-\-\-\-+
^ ^
w=1 | w=1 |
| |
+\-\-\-\-\-+ +\-\-\-\-\-+
|id=11| |id=9 |
+\-\-\-\-\-+ +\-\-\-\-\-+
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
In the above figure, \fBid\fP means stream ID, and \fBw\fP means weight.
The stream 0 is non\-existence stream, and forms the root of the tree.
The stream 7 and 9 are not used for now.
.sp
The URIs given in the command\-line depend on stream 11 with the weight
given in \fI\%\-p\fP option, which defaults to 16.
.sp
If \fI\%\-a\fP option is used, nghttp parses the resource pointed by
URI given in command\-line as html, and extracts resource links from
it. When requesting those resources, nghttp uses dependency according
to its resource type.
.sp
For CSS, and Javascript files inside "head" element, they depend on
stream 3 with the weight 2. The Javascript files outside "head"
element depend on stream 5 with the weight 2. The mages depend on
stream 11 with the weight 12. The other resources (e.g., icon) depend
on stream 11 with the weight 2.
.SH SEE ALSO
.sp
\fBnghttpd(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP

View File

@@ -105,16 +105,15 @@ OPTIONS
if the request URI has https scheme. If :option:`-d` is used, the
HTTP upgrade request is performed with OPTIONS method.
.. option:: --extpri=<PRI>
.. option:: -p, --weight=<WEIGHT>
Sets RFC 9218 priority of given URI. <PRI> must be the
wire format of priority header field (e.g., "u=3,i").
This option can be used multiple times, and N-th
:option:`--extpri` option sets priority of N-th URI in the command
line. If the number of this option is less than the
number of URI, the last option value is repeated. If
there is no :option:`--extpri` option, urgency is 3, and
incremental is false.
Sets weight of given URI. This option can be used
multiple times, and N-th :option:`-p` option sets weight of N-th
URI in the command line. If the number of :option:`-p` option is
less than the number of URI, the last :option:`-p` option value is
repeated. If there is no :option:`-p` option, default weight, 16,
is assumed. The valid value range is
[1, 256], inclusive.
.. option:: -M, --peer-max-concurrent-streams=<N>
@@ -161,6 +160,10 @@ OPTIONS
Don't send content-length header field.
.. option:: --no-dep
Don't send dependency based priority hint to server.
.. option:: --hexdump
Display the incoming traffic in hexadecimal (Canonical
@@ -192,6 +195,10 @@ OPTIONS
Enable ktls.
.. option:: --no-rfc7540-pri
Disable RFC7540 priorities.
.. option:: --version
Display version information and exit.
@@ -210,6 +217,59 @@ is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
(hours, minutes, seconds and milliseconds, respectively). If a unit
is omitted, a second is used as unit.
DEPENDENCY BASED PRIORITY
-------------------------
nghttp sends priority hints to server by default unless
:option:`--no-dep` is used. nghttp mimics the way Firefox employs to
manages dependency using idle streams. We follows the behaviour of
Firefox Nightly as of April, 2015, and nghttp's behaviour is very
static and could be different from Firefox in detail. But reproducing
the same behaviour of Firefox is not our goal. The goal is provide
the easy way to test out the dependency priority in server
implementation.
When connection is established, nghttp sends 5 PRIORITY frames to idle
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
tree:
.. code-block:: text
+-----+
|id=0 |
+-----+
^ ^ ^
w=201 / | \ w=1
/ | \
/ w=101| \
+-----+ +-----+ +-----+
|id=3 | |id=5 | |id=7 |
+-----+ +-----+ +-----+
^ ^
w=1 | w=1 |
| |
+-----+ +-----+
|id=11| |id=9 |
+-----+ +-----+
In the above figure, ``id`` means stream ID, and ``w`` means weight.
The stream 0 is non-existence stream, and forms the root of the tree.
The stream 7 and 9 are not used for now.
The URIs given in the command-line depend on stream 11 with the weight
given in :option:`-p` option, which defaults to 16.
If :option:`-a` option is used, nghttp parses the resource pointed by
URI given in command-line as html, and extracts resource links from
it. When requesting those resources, nghttp uses dependency according
to its resource type.
For CSS, and Javascript files inside "head" element, they depend on
stream 3 with the weight 2. The Javascript files outside "head"
element depend on stream 5 with the weight 2. The mages depend on
stream 11 with the weight 12. The other resources (e.g., icon) depend
on stream 11 with the weight 2.
SEE ALSO
--------

View File

@@ -1,3 +1,56 @@
DEPENDENCY BASED PRIORITY
-------------------------
nghttp sends priority hints to server by default unless
:option:`--no-dep` is used. nghttp mimics the way Firefox employs to
manages dependency using idle streams. We follows the behaviour of
Firefox Nightly as of April, 2015, and nghttp's behaviour is very
static and could be different from Firefox in detail. But reproducing
the same behaviour of Firefox is not our goal. The goal is provide
the easy way to test out the dependency priority in server
implementation.
When connection is established, nghttp sends 5 PRIORITY frames to idle
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
tree:
.. code-block:: text
+-----+
|id=0 |
+-----+
^ ^ ^
w=201 / | \ w=1
/ | \
/ w=101| \
+-----+ +-----+ +-----+
|id=3 | |id=5 | |id=7 |
+-----+ +-----+ +-----+
^ ^
w=1 | w=1 |
| |
+-----+ +-----+
|id=11| |id=9 |
+-----+ +-----+
In the above figure, ``id`` means stream ID, and ``w`` means weight.
The stream 0 is non-existence stream, and forms the root of the tree.
The stream 7 and 9 are not used for now.
The URIs given in the command-line depend on stream 11 with the weight
given in :option:`-p` option, which defaults to 16.
If :option:`-a` option is used, nghttp parses the resource pointed by
URI given in command-line as html, and extracts resource links from
it. When requesting those resources, nghttp uses dependency according
to its resource type.
For CSS, and Javascript files inside "head" element, they depend on
stream 3 with the weight 2. The Javascript files outside "head"
element depend on stream 5 with the weight 2. The mages depend on
stream 11 with the weight 12. The other resources (e.g., icon) depend
on stream 11 with the weight 2.
SEE ALSO
--------

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" "Oct 25, 2025" "1.68.0" "nghttp2"
.TH "NGHTTPD" "1" "Nov 13, 2022" "1.51.0" "nghttp2"
.SH NAME
nghttpd \- HTTP/2 server
.SH SYNOPSIS
@@ -204,15 +204,13 @@ Don\(aqt send content\-length header field.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-groups=<GROUPS>
Specify the supported groups.
.sp
Default: \fBX25519:P\-256:P\-384:P\-521\fP
.B \-\-ktls
Enable ktls.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ktls
Enable ktls.
.B \-\-no\-rfc7540\-pri
Disable RFC7540 priorities.
.UNINDENT
.INDENT 0.0
.TP

View File

@@ -159,16 +159,14 @@ OPTIONS
Don't send content-length header field.
.. option:: --groups=<GROUPS>
Specify the supported groups.
Default: ``X25519:P-256:P-384:P-521``
.. option:: --ktls
Enable ktls.
.. option:: --no-rfc7540-pri
Disable RFC7540 priorities.
.. option:: --version
Display version information and exit.

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,8 @@ A reverse proxy for HTTP/3, HTTP/2, and HTTP/1.
.. describe:: <CERT>
Set path to server's certificate. Required unless
"no-tls" parameter is used in :option:`--frontend` option.
"no-tls" parameter is used in :option:`--frontend` option. To
make OCSP stapling work, this must be an absolute path.
OPTIONS
@@ -521,22 +522,24 @@ Performance
Timeout
~~~~~~~
.. option:: --frontend-http2-idle-timeout=<DURATION>
.. option:: --frontend-http2-read-timeout=<DURATION>
Specify idle timeout for HTTP/2 frontend connection. If
no active streams exist for this duration, connection is
closed.
Specify read timeout for HTTP/2 frontend connection.
Default: ``3m``
.. option:: --frontend-http3-idle-timeout=<DURATION>
.. option:: --frontend-http3-read-timeout=<DURATION>
Specify idle timeout for HTTP/3 frontend connection. If
no active streams exist for this duration, connection is
closed.
Specify read timeout for HTTP/3 frontend connection.
Default: ``3m``
.. option:: --frontend-read-timeout=<DURATION>
Specify read timeout for HTTP/1.1 frontend connection.
Default: ``1m``
.. option:: --frontend-write-timeout=<DURATION>
Specify write timeout for all frontend connections.
@@ -550,16 +553,6 @@ Timeout
Default: ``1m``
.. option:: --frontend-header-timeout=<DURATION>
Specify duration that the server waits for an HTTP
request header fields to be received completely. On
timeout, HTTP/1 and HTTP/2 connections are closed. For
HTTP/3, the stream is shutdown, and the connection
itself is left intact.
Default: ``1m``
.. option:: --stream-read-timeout=<DURATION>
Specify read timeout for HTTP/2 streams. 0 means no
@@ -643,8 +636,8 @@ SSL/TLS
Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2. Use
:option:`--tls13-ciphers` for TLSv1.3.
This option sets cipher suites for TLSv1.2 or earlier.
Use :option:`--tls13-ciphers` for TLSv1.3.
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
@@ -653,7 +646,7 @@ SSL/TLS
Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.3. Use
:option:`--ciphers` for TLSv1.2.
:option:`--ciphers` for TLSv1.2 or earlier.
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
@@ -661,8 +654,8 @@ SSL/TLS
Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2. Use
:option:`--tls13-client-ciphers` for TLSv1.3.
This option sets cipher suites for TLSv1.2 or earlier.
Use :option:`--tls13-client-ciphers` for TLSv1.3.
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
@@ -671,14 +664,14 @@ SSL/TLS
Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.3. Use
:option:`--client-ciphers` for TLSv1.2.
:option:`--tls13-client-ciphers` for TLSv1.2 or earlier.
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
.. option:: --groups=<LIST>
.. option:: --ecdh-curves=<LIST>
Set the supported group list for frontend connections.
<LIST> is a colon separated list of group NID or names
Set supported curve list for frontend connections.
<LIST> is a colon separated list of curve NID or names
in the preference order. The supported curves depend on
the linked OpenSSL library. This function requires
OpenSSL >= 1.0.2.
@@ -694,10 +687,12 @@ SSL/TLS
Set path to trusted CA certificate file. It is used in
backend TLS connections to verify peer's certificate.
The file must be in PEM format. It can contain multiple
certificates. If the linked OpenSSL is configured to
load system wide certificates, they are loaded at
startup regardless of this option.
It is also used to verify OCSP response from the script
set by :option:`--fetch-ocsp-response-file`\. The file must be in
PEM format. It can contain multiple certificates. If
the linked OpenSSL is configured to load system wide
certificates, they are loaded at startup regardless of
this option.
.. option:: --private-key-passwd-file=<PATH>
@@ -710,12 +705,13 @@ SSL/TLS
Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. If nghttpx
is built with OpenSSL >= 1.0.2, the signature algorithms
(e.g., ECDSA+SHA256) presented by client are also taken
into consideration. This allows nghttpx to send ML-DSA
or ECDSA certificate to modern clients, while sending
RSA based certificate to older clients. This option can
be used multiple times.
is built with OpenSSL >= 1.0.2, the shared elliptic
curves (e.g., P-256) between client and server are also
taken into consideration. This allows nghttpx to send
ECDSA certificate to modern clients, while sending RSA
based certificate to older clients. This option can be
used multiple times. To make OCSP stapling work,
<CERTPATH> must be absolute path.
Additional parameter can be specified in <PARAM>. The
available <PARAM> is "sct-dir=<DIR>".
@@ -732,15 +728,16 @@ SSL/TLS
Without this option, DHE cipher suites are not
available.
.. option:: --alpn-list=<LIST>
.. option:: --npn-list=<LIST>
Comma delimited list of ALPN protocol identifier sorted
in the order of preference. That means most desirable
protocol comes first. The parameter must be delimited
by a single comma only and any white spaces are treated
as a part of protocol string.
protocol comes first. This is used in both ALPN and
NPN. The parameter must be delimited by a single comma
only and any white spaces are treated as a part of
protocol string.
Default: ``h2,http/1.1``
Default: ``h2,h2-16,h2-14,http/1.1``
.. option:: --verify-client
@@ -776,8 +773,12 @@ SSL/TLS
:option:`--tls-min-proto-version` and :option:`\--tls-max-proto-version` are
enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error
message "unknown protocol". The available versions are:
TLSv1.3 and TLSv1.2
message "unknown protocol". If a protocol version lower
than TLSv1.2 is specified, make sure that the compatible
ciphers are included in :option:`--ciphers` option. The default
cipher list only includes ciphers compatible with
TLSv1.2 or above. The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
Default: ``TLSv1.2``
@@ -789,7 +790,7 @@ SSL/TLS
enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error
message "unknown protocol". The available versions are:
TLSv1.3 and TLSv1.2
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
Default: ``TLSv1.3``
@@ -882,6 +883,63 @@ SSL/TLS
Path to client private key for memcached connections to
get TLS ticket keys.
.. option:: --fetch-ocsp-response-file=<PATH>
Path to fetch-ocsp-response script file. It should be
absolute path.
Default: ``/usr/local/share/nghttp2/fetch-ocsp-response``
.. option:: --ocsp-update-interval=<DURATION>
Set interval to update OCSP response cache.
Default: ``4h``
.. option:: --ocsp-startup
Start accepting connections after initial attempts to
get OCSP responses finish. It does not matter some of
the attempts fail. This feature is useful if OCSP
responses must be available before accepting
connections.
.. option:: --no-verify-ocsp
nghttpx does not verify OCSP response.
.. option:: --no-ocsp
Disable OCSP stapling.
.. option:: --tls-session-cache-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session
cache. This enables shared session cache between
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying "tls"
parameter.
.. option:: --tls-session-cache-memcached-address-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to store
session cache. If "auto" is given, both IPv4 and IPv6
are considered. If "IPv4" is given, only IPv4 address
is considered. If "IPv6" is given, only IPv6 address is
considered.
Default: ``auto``
.. option:: --tls-session-cache-memcached-cert-file=<PATH>
Path to client certificate for memcached connections to
store session cache.
.. option:: --tls-session-cache-memcached-private-key-file=<PATH>
Path to client private key for memcached connections to
store session cache.
.. option:: --tls-dyn-rec-warmup-threshold=<SIZE>
Specify the threshold size for TLS dynamic record size
@@ -981,7 +1039,8 @@ SSL/TLS
.. option:: --tls-ktls
Enable ktls.
Enable ktls. For server, ktls is enable if
:option:`--tls-session-cache-memcached` is not configured.
HTTP/2
@@ -1343,19 +1402,17 @@ HTTP
.. option:: --add-request-header=<HEADER>
Specify additional header field to add to request 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.
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.
Example: :option:`--add-request-header`\="foo: bar"
.. option:: --add-response-header=<HEADER>
Specify additional header field to add to response
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.
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.
Example: :option:`--add-response-header`\="foo: bar"
.. option:: --request-header-field-buffer=<SIZE>
@@ -1458,14 +1515,14 @@ DNS
server is given time based on this timeout, and it is
scaled linearly.
Default: ``250ms``
Default: ``5s``
.. option:: --dns-max-try=<N>
Set the number of DNS query before nghttpx gives up name
lookup.
Default: ``3``
Default: ``2``
.. option:: --frontend-max-requests=<N>
@@ -1616,8 +1673,8 @@ HTTP/3 and QUIC
.. option:: --frontend-quic-congestion-controller=<CC>
Specify a congestion controller algorithm for a frontend
QUIC connection. <CC> should be either "cubic" or
"bbr".
QUIC connection. <CC> should be one of "cubic", "bbr",
and "bbr2".
Default: ``cubic``
@@ -1628,12 +1685,12 @@ HTTP/3 and QUIC
encrypting tokens and Connection IDs. It is not used to
encrypt QUIC packets. Each line of this file must
contain exactly 136 bytes hex-encoded string (when
decoded the byte string is 68 bytes long). The first 3
decoded the byte string is 68 bytes long). The first 2
bits of decoded byte string are used to identify the
keying material. An empty line or a line which starts
'#' is ignored. The file can contain more than one
keying materials. Because the identifier is 3 bits, at
most 8 keying materials are read and the remaining data
keying materials. Because the identifier is 2 bits, at
most 4 keying materials are read and the remaining data
is discarded. The first keying material in the file is
primarily used for encryption and decryption for new
connection. The other ones are used to decrypt data for
@@ -1905,6 +1962,37 @@ deletes it. However, if SIGUSR2 is used to execute new binary and
both old and new configurations use same filename, new binary does not
delete the socket and continues to use it.
OCSP STAPLING
-------------
OCSP query is done using external Python script
``fetch-ocsp-response``, which has been originally developed in Perl
as part of h2o project (https://github.com/h2o/h2o), and was
translated into Python.
The script file is usually installed under
``$(prefix)/share/nghttp2/`` directory. The actual path to script can
be customized using :option:`--fetch-ocsp-response-file` option.
If OCSP query is failed, previous OCSP response, if any, is continued
to be used.
:option:`--fetch-ocsp-response-file` option provides wide range of
possibility to manage OCSP response. It can take an arbitrary script
or executable. The requirement is that it supports the command-line
interface of ``fetch-ocsp-response`` script, and it must return a
valid DER encoded OCSP response on success. It must return exit code
0 on success, and 75 for temporary error, and the other error code for
generic failure. For large cluster of servers, it is not efficient
for each server to perform OCSP query using ``fetch-ocsp-response``.
Instead, you can retrieve OCSP response in some way, and store it in a
disk or a shared database. Then specify a program in
:option:`--fetch-ocsp-response-file` to fetch it from those stores.
This could provide a way to share the OCSP response between fleet of
servers, and also any OCSP query strategy can be applied which may be
beyond the ability of nghttpx itself or ``fetch-ocsp-response``
script.
TLS SESSION RESUMPTION
----------------------
@@ -1916,6 +2004,16 @@ SESSION ID RESUMPTION
By default, session ID is shared by all worker threads.
If :option:`--tls-session-cache-memcached` is given, nghttpx will
insert serialized session data to memcached with
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -156,6 +156,37 @@ deletes it. However, if SIGUSR2 is used to execute new binary and
both old and new configurations use same filename, new binary does not
delete the socket and continues to use it.
OCSP STAPLING
-------------
OCSP query is done using external Python script
``fetch-ocsp-response``, which has been originally developed in Perl
as part of h2o project (https://github.com/h2o/h2o), and was
translated into Python.
The script file is usually installed under
``$(prefix)/share/nghttp2/`` directory. The actual path to script can
be customized using :option:`--fetch-ocsp-response-file` option.
If OCSP query is failed, previous OCSP response, if any, is continued
to be used.
:option:`--fetch-ocsp-response-file` option provides wide range of
possibility to manage OCSP response. It can take an arbitrary script
or executable. The requirement is that it supports the command-line
interface of ``fetch-ocsp-response`` script, and it must return a
valid DER encoded OCSP response on success. It must return exit code
0 on success, and 75 for temporary error, and the other error code for
generic failure. For large cluster of servers, it is not efficient
for each server to perform OCSP query using ``fetch-ocsp-response``.
Instead, you can retrieve OCSP response in some way, and store it in a
disk or a shared database. Then specify a program in
:option:`--fetch-ocsp-response-file` to fetch it from those stores.
This could provide a way to share the OCSP response between fleet of
servers, and also any OCSP query strategy can be applied which may be
beyond the ability of nghttpx itself or ``fetch-ocsp-response``
script.
TLS SESSION RESUMPTION
----------------------
@@ -167,6 +198,16 @@ SESSION ID RESUMPTION
By default, session ID is shared by all worker threads.
If :option:`--tls-session-cache-memcached` is given, nghttpx will
insert serialized session data to memcached with
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -40,28 +40,28 @@ most event-based architecture applications use is single thread per
core, and handling one connection I/O is done by single thread.
To feed input to :type:`nghttp2_session` object, one can use
`nghttp2_session_recv()` or `nghttp2_session_mem_recv2()` functions.
`nghttp2_session_recv()` or `nghttp2_session_mem_recv()` functions.
They behave similarly, and the difference is that
`nghttp2_session_recv()` will use :type:`nghttp2_read_callback` to get
input. On the other hand, `nghttp2_session_mem_recv2()` will take
input as its parameter. If in doubt, use
`nghttp2_session_mem_recv2()` since it is simpler, and could be faster
since it avoids calling callback function.
input. On the other hand, `nghttp2_session_mem_recv()` will take
input as its parameter. If in doubt, use `nghttp2_session_mem_recv()`
since it is simpler, and could be faster since it avoids calling
callback function.
To get output from :type:`nghttp2_session` object, one can use
`nghttp2_session_send()` or `nghttp2_session_mem_send2()`. The
`nghttp2_session_send()` or `nghttp2_session_mem_send()`. The
difference between them is that the former uses
:type:`nghttp2_send_callback` to pass output to an application. On
the other hand, the latter returns the output to the caller. If in
doubt, use `nghttp2_session_mem_send2()` since it is simpler. But
doubt, use `nghttp2_session_mem_send()` since it is simpler. But
`nghttp2_session_send()` might be easier to use if the output buffer
an application has is fixed sized.
In general, an application should call `nghttp2_session_mem_send2()`
In general, an application should call `nghttp2_session_mem_send()`
when it gets input from underlying connection. Since there is great
chance to get something pushed into transmission queue while the call
of `nghttp2_session_mem_send2()`, it is recommended to call
`nghttp2_session_mem_recv2()` after `nghttp2_session_mem_send2()`.
of `nghttp2_session_mem_send()`, it is recommended to call
`nghttp2_session_mem_recv()` after `nghttp2_session_mem_send()`.
There is a question when we are safe to close HTTP/2 session without
waiting for the closure of underlying connection. We offer 2 API
@@ -70,7 +70,7 @@ calls for this: `nghttp2_session_want_read()` and
can destroy :type:`nghttp2_session`, and then close the underlying
connection. But make sure that the buffered output has been
transmitted to the peer before closing the connection when
`nghttp2_session_mem_send2()` is used, since
`nghttp2_session_mem_send()` is used, since
`nghttp2_session_want_write()` does not take into account the
transmission of the buffered data outside of :type:`nghttp2_session`.
@@ -87,18 +87,18 @@ The header files are also available online: :doc:`nghttp2.h` and
Remarks
-------
Do not call `nghttp2_session_send()`, `nghttp2_session_mem_send2()`,
`nghttp2_session_recv()` or `nghttp2_session_mem_recv2()` from the
Do not call `nghttp2_session_send()`, `nghttp2_session_mem_send()`,
`nghttp2_session_recv()` or `nghttp2_session_mem_recv()` from the
nghttp2 callback functions directly or indirectly. It will lead to the
crash. You can submit requests or frames in the callbacks then call
these functions outside the callbacks.
`nghttp2_session_send()` and `nghttp2_session_mem_send2()` send first
`nghttp2_session_send()` and `nghttp2_session_mem_send()` send first
24 bytes of client magic string (MAGIC)
(:macro:`NGHTTP2_CLIENT_MAGIC`) on client configuration. The
applications are responsible to send SETTINGS frame as part of
connection preface using `nghttp2_submit_settings()`. Similarly,
`nghttp2_session_recv()` and `nghttp2_session_mem_recv2()` consume
`nghttp2_session_recv()` and `nghttp2_session_mem_recv()` consume
MAGIC on server configuration unless
`nghttp2_option_set_no_recv_client_magic()` is used with nonzero
option value.
@@ -222,7 +222,7 @@ above, the following code does not work:
.. code-block:: c
nghttp2_submit_response2(...)
nghttp2_submit_response(...)
nghttp2_submit_rst_stream(...)
RST_STREAM cancels HEADERS (and DATA), and just RST_STREAM is sent.
@@ -258,7 +258,7 @@ For example, we will illustrate how to send `ALTSVC
const char *field;
} alt_svc;
nghttp2_ssize pack_extension_callback(nghttp2_session *session, uint8_t *buf,
ssize_t pack_extension_callback(nghttp2_session *session, uint8_t *buf,
size_t len, const nghttp2_frame *frame,
void *user_data) {
const alt_svc *altsvc = (const alt_svc *)frame->ext.payload;
@@ -482,26 +482,45 @@ be called as usual.
Stream priorities
-----------------
The stream prioritization scheme described in :rfc:`7540`, which has
been formally deprecated by :rfc:`9113`, has been removed. An
application is advised to send
By default, the stream prioritization scheme described in :rfc:`7540`
is used. This scheme has been formally deprecated by :rfc:`9113`. In
order to disable it, send
:enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` of
value of 1 via `nghttp2_submit_settings()`, and migrate to
:rfc:`9218`.
The sender of this settings value disables :rfc:`7540` priorities, and
instead it enables :rfc:`9218` Extensible Prioritization Scheme. This
new prioritization scheme has 2 methods to convey the stream
priorities to a remote endpoint: Priority header field and
PRIORITY_UPDATE frame. nghttp2 supports both methods. In order to
receive and process PRIORITY_UPDATE frame, server has to call
`nghttp2_option_set_builtin_recv_extension_type()` with
NGHTTP2_PRIORITY_UPDATE as type argument (see the above section), and
pass the option to `nghttp2_session_server_new2()` or
value of 1 via `nghttp2_submit_settings()`. This settings ID is
defined by :rfc:`9218`. The sender of this settings value disables
RFC 7540 priorities, and instead it enables RFC 9218 Extensible
Prioritization Scheme. This new prioritization scheme has 2 methods
to convey the stream priorities to a remote endpoint: Priority header
field and PRIORITY_UPDATE frame. nghttp2 supports both methods. In
order to receive and process PRIORITY_UPDATE frame, server has to call
``nghttp2_option_set_builtin_recv_extension_type(option,
NGHTTP2_PRIORITY_UPDATE)`` (see the above section), and pass the
option to `nghttp2_session_server_new2()` or
`nghttp2_session_server_new3()` to create a server session. Client
can send Priority header field via `nghttp2_submit_request2()`. It
can also send PRIORITY_UPDATE frame via
can send Priority header field via `nghttp2_submit_request()`. It can
also send PRIORITY_UPDATE frame via
`nghttp2_submit_priority_update()`. Server processes Priority header
field in a request header field and updates the stream priority unless
HTTP messaging rule enforcement is disabled (see
`nghttp2_option_set_no_http_messaging()`).
For the purpose of smooth migration from RFC 7540 priorities, client
is advised to send
:enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES` of
value of 1. Until it receives the first server SETTINGS frame, it can
send both RFC 7540 and RFC 9128 priority signals. If client receives
SETTINGS_NO_RFC7540_PRIORITIES of value of 0, or it is omitted ,
client stops sending PRIORITY_UPDATE frame. Priority header field
will be sent in anyway since it is an end-to-end signal. If
SETTINGS_NO_RFC7540_PRIORITIES of value of 1 is received, client stops
sending RFC 7540 priority signals. This is the advice described in
:rfc:`9218#section-2.1.1`.
Server has an optional mechanism to fallback to RFC 7540 priorities.
By default, if server sends SETTINGS_NO_RFC7540_PRIORITIES of value of
1, it completely disables RFC 7540 priorities and no fallback. By
setting nonzero value to
`nghttp2_option_set_server_fallback_rfc7540_priorities()`, server
falls back to RFC 7540 priorities if it sends
SETTINGS_NO_RFC7540_PRIORITIES value of value of 1, and client omits
SETTINGS_NO_RFC7540_PRIORITIES in its SETTINGS frame.

1
doc/security.rst Normal file
View File

@@ -0,0 +1 @@
.. include:: ../doc/sources/security.rst

View File

@@ -26,7 +26,7 @@ Coding style
We use clang-format to format source code consistently. The
clang-format configuration file .clang-format is located at the root
directory. Since clang-format produces slightly different results
between versions, we currently use clang-format-19.
between versions, we currently use clang-format-14.
To detect any violation to the coding style, we recommend to setup git
pre-commit hook to check coding style of the changes you introduced.
@@ -34,7 +34,7 @@ The pre-commit file is located at the root directory. Copy it under
.git/hooks and make sure that it is executable. The pre-commit script
uses clang-format-diff.py to detect any style errors. If it is not in
your PATH or it exists under different name (e.g.,
clang-format-diff-18 in debian), either add it to PATH variable or add
clang-format-diff-14 in debian), either add it to PATH variable or add
git option ``clangformatdiff.binary`` to point to the script.
For emacs users, integrating clang-format to emacs is very easy.

View File

@@ -30,8 +30,8 @@ In order to set benchmark settings, specify following 3 options.
:option:`-m`
The max concurrent streams to issue per client. Default: 1
For SSL/TLS connection, the protocol will be negotiated via ALPN. You
can set specific protocols in :option:`--alpn-list` option. For
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
You can set specific protocols in :option:`--npn-list` option. For
cleartext connection, the default protocol is HTTP/2. To change the
protocol in cleartext connection, use :option:`--no-tls-proto` option.
For convenience, :option:`--h1` option forces HTTP/1.1 for both
@@ -139,4 +139,4 @@ h2load supports HTTP/3 if it is built with HTTP/3 enabled. HTTP/3
support is experimental.
In order to send HTTP/3 request, specify ``h3`` to
:option:`--alpn-list`.
:option:`--npn-list`.

View File

@@ -18,6 +18,7 @@ Contents:
package_README
contribute
security
building-android-binary
tutorial-client
tutorial-server

View File

@@ -20,7 +20,7 @@ known as "HTTP/2 router".
By default, frontend connection is encrypted using SSL/TLS. So
server's private key and certificate must be supplied to the command
line (or through configuration file). In this case, the frontend
protocol selection will be done via ALPN.
protocol selection will be done via ALPN or NPN.
To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option. HTTP/2 and HTTP/1 are available on
@@ -167,7 +167,8 @@ Enable SSL/TLS on memcached connection
By default, memcached connection is not encrypted. To enable
encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached`.
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
:option:`--tls-session-cache-memcached` for TLS session cache.
Specifying additional server certificates
-----------------------------------------
@@ -545,8 +546,8 @@ keys in order to keep the existing connections alive during reload.
The construction of Connection ID closely follows Block Cipher CID
Algorithm described in `QUIC-LB draft
<https://datatracker.ietf.org/doc/html/draft-ietf-quic-load-balancers>`_.
A Connection ID that nghttpx generates is always 17 bytes long. It
uses first 3 bits as a configuration ID. The remaining bits in the
A Connection ID that nghttpx generates is always 20 bytes long. It
uses first 2 bits as a configuration ID. The remaining bits in the
first byte are reserved and random. The next 4 bytes are server ID.
The next 4 bytes are used to route UDP datagram to a correct
``SO_REUSEPORT`` socket. The remaining bytes are randomly generated.

38
doc/sources/security.rst Normal file
View File

@@ -0,0 +1,38 @@
Security Process
================
If you find a vulnerability in our software, please send the email to
"tatsuhiro.t at gmail dot com" about its details instead of submitting
issues on github issue page. It is a standard practice not to
disclose vulnerability information publicly until a fixed version is
released, or mitigation is worked out. In the future, we may setup a
dedicated mail address for this purpose.
If we identify that the reported issue is really a vulnerability, we
open a new security advisory draft using `GitHub security feature
<https://github.com/nghttp2/nghttp2/security>`_ and discuss the
mitigation and bug fixes there. The fixes are committed to the
private repository.
We write the security advisory and get CVE number from GitHub
privately. We also discuss the disclosure date to the public.
We make a new release with the fix at the same time when the
vulnerability is disclosed to public.
At least 7 days before the public disclosure date, we will post
security advisory (which includes all the details of the vulnerability
and the possible mitigation strategies) and the patches to fix the
issue to `distros@openwall
<https://oss-security.openwall.org/wiki/mailing-lists/distros>`_
mailing list. We also open a new issue on `nghttp2 issue tracker
<https://github.com/nghttp2/nghttp2/issues>`_ which notifies that the
upcoming release will have a security fix. The ``SECURITY`` label is
attached to this kind of issue.
Before few hours of new release, we merge the fixes to the master
branch (and/or a release branch if necessary) and make a new release.
Security advisory is disclosed on GitHub. We also post the
vulnerability information to `oss-security
<https://oss-security.openwall.org/wiki/mailing-lists/oss-security>`_
mailing list.

View File

@@ -18,8 +18,34 @@ note that nghttp2 itself does not depend on libevent.
The client starts with some libevent and OpenSSL setup in the
``main()`` and ``run()`` functions. This setup isn't specific to
nghttp2, but one thing you should look at is setup of ALPN. Client
tells application protocols that it supports to server via ALPN::
nghttp2, but one thing you should look at is setup of the NPN
callback. The NPN callback is used by the client to select the next
application protocol over TLS. In this tutorial, we use the
`nghttp2_select_next_protocol()` helper function to select the HTTP/2
protocol the library supports::
static int select_next_proto_cb(SSL *ssl _U_, unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg _U_) {
if (nghttp2_select_next_protocol(out, outlen, in, inlen) <= 0) {
errx(1, "Server did not advertise " NGHTTP2_PROTO_VERSION_ID);
}
return SSL_TLSEXT_ERR_OK;
}
If you are following TLS related RFC, you know that NPN is not the
standardized way to negotiate HTTP/2. NPN itself is not event
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
ALPN support depending on OpenSSL version. OpenSSL's ALPN
implementation does not require callback function like the above. But
we have to instruct OpenSSL SSL_CTX to use ALPN, which we'll talk
about soon.
The callback is added to the SSL_CTX object using
``SSL_CTX_set_next_proto_select_cb()``::
static SSL_CTX *create_ssl_ctx(void) {
SSL_CTX *ssl_ctx;
@@ -32,8 +58,11 @@ tells application protocols that it supports to server via ALPN::
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
@@ -63,7 +92,7 @@ structure is defined as follows::
/* The NULL-terminated URI string to retrieve. */
const char *uri;
/* Parsed result of the |uri| */
urlparse_url *u;
struct http_parser_url *u;
/* The authority portion of the |uri|, not NULL-terminated */
char *authority;
/* The path portion of the |uri|, including query, not
@@ -126,7 +155,12 @@ underlying network socket::
ssl = bufferevent_openssl_get_ssl(session_data->bev);
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "h2 is not negotiated\n");
@@ -171,7 +205,7 @@ session object and several callbacks::
nghttp2_session_callbacks_new(&callbacks);
nghttp2_session_callbacks_set_send_callback2(callbacks, send_callback);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
on_frame_recv_callback);
@@ -237,16 +271,16 @@ HTTP request in the ``submit_request()`` function::
int32_t stream_id;
http2_stream_data *stream_data = session_data->stream_data;
const char *uri = stream_data->uri;
const urlparse_url *u = stream_data->u;
const struct http_parser_url *u = stream_data->u;
nghttp2_nv hdrs[] = {
MAKE_NV2(":method", "GET"),
MAKE_NV(":scheme", &uri[u->field_data[URLPARSE_SCHEMA].off],
u->field_data[URLPARSE_SCHEMA].len),
MAKE_NV(":scheme", &uri[u->field_data[UF_SCHEMA].off],
u->field_data[UF_SCHEMA].len),
MAKE_NV(":authority", stream_data->authority, stream_data->authoritylen),
MAKE_NV(":path", stream_data->path, stream_data->pathlen)};
fprintf(stderr, "Request headers:\n");
print_headers(stderr, hdrs, ARRLEN(hdrs));
stream_id = nghttp2_submit_request2(session_data->session, NULL, hdrs,
stream_id = nghttp2_submit_request(session_data->session, NULL, hdrs,
ARRLEN(hdrs), NULL, stream_data);
if (stream_id < 0) {
errx(1, "Could not submit HTTP request: %s", nghttp2_strerror(stream_id));
@@ -258,11 +292,11 @@ HTTP request in the ``submit_request()`` function::
We build the HTTP request header fields in ``hdrs``, which is an array
of :type:`nghttp2_nv`. There are four header fields to be sent:
``:method``, ``:scheme``, ``:authority``, and ``:path``. To queue the
HTTP request, we call `nghttp2_submit_request2()`. The ``stream_data``
HTTP request, we call `nghttp2_submit_request()`. The ``stream_data``
is passed via the *stream_user_data* parameter, which is helpfully
later passed back to callback functions.
`nghttp2_submit_request2()` returns the newly assigned stream ID for
`nghttp2_submit_request()` returns the newly assigned stream ID for
the request.
The next bufferevent callback is ``readcb()``, which is invoked when
@@ -270,12 +304,12 @@ data is available to read from the bufferevent input buffer::
static void readcb(struct bufferevent *bev, void *ptr) {
http2_session_data *session_data = (http2_session_data *)ptr;
nghttp2_ssize readlen;
ssize_t readlen;
struct evbuffer *input = bufferevent_get_input(bev);
size_t datalen = evbuffer_get_length(input);
unsigned char *data = evbuffer_pullup(input, -1);
readlen = nghttp2_session_mem_recv2(session_data->session, data, datalen);
readlen = nghttp2_session_mem_recv(session_data->session, data, datalen);
if (readlen < 0) {
warnx("Fatal error: %s", nghttp2_strerror((int)readlen));
delete_http2_session_data(session_data);
@@ -293,8 +327,8 @@ data is available to read from the bufferevent input buffer::
}
In this function we feed all unprocessed, received data to the nghttp2
session object using the `nghttp2_session_mem_recv2()` function.
`nghttp2_session_mem_recv2()` processes the received data and may
session object using the `nghttp2_session_mem_recv()` function.
`nghttp2_session_mem_recv()` processes the received data and may
invoke nghttp2 callbacks and queue frames for transmission. Since
there may be pending frames for transmission, we call immediately
``session_send()`` to send them. ``session_send()`` is defined as
@@ -313,16 +347,15 @@ follows::
The `nghttp2_session_send()` function serializes pending frames into
wire format and calls the ``send_callback()`` function to send them.
``send_callback()`` has type :type:`nghttp2_send_callback2` and is
``send_callback()`` has type :type:`nghttp2_send_callback` and is
defined as::
static nghttp2_ssize send_callback(nghttp2_session *session _U_,
const uint8_t *data, size_t length,
int flags _U_, void *user_data) {
static ssize_t send_callback(nghttp2_session *session _U_, const uint8_t *data,
size_t length, int flags _U_, void *user_data) {
http2_session_data *session_data = (http2_session_data *)user_data;
struct bufferevent *bev = session_data->bev;
bufferevent_write(bev, data, length);
return (nghttp2_ssize)length;
return (ssize_t)length;
}
Since we use bufferevent to abstract network I/O, we just write the

View File

@@ -24,9 +24,9 @@ deflater object for the dynamic header table. If in doubt, just
specify 4096 here, which is the default upper bound of dynamic header
table buffer size.
To encode header fields, use the `nghttp2_hd_deflate_hd2()` function::
To encode header fields, use the `nghttp2_hd_deflate_hd()` function::
nghttp2_ssize nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater,
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
uint8_t *buf, size_t buflen,
const nghttp2_nv *nva, size_t nvlen);
@@ -44,7 +44,7 @@ cookies), set the :macro:`NGHTTP2_NV_FLAG_NO_INDEX` flag in
sensitive header fields by compression based attacks: This is achieved
by not inserting the header field into the dynamic header table.
`nghttp2_hd_deflate_hd2()` processes all headers given in *nva*. The
`nghttp2_hd_deflate_hd()` processes all headers given in *nva*. The
*nva* must include all request or response header fields to be sent in
one HEADERS (or optionally following (multiple) CONTINUATION
frame(s)). The *buf* must have enough space to store the encoded
@@ -55,13 +55,13 @@ of the encoded result length, use `nghttp2_hd_deflate_bound()`::
const nghttp2_nv *nva, size_t nvlen);
Pass this function the same parameters (*deflater*, *nva*, and
*nvlen*) which will be passed to `nghttp2_hd_deflate_hd2()`.
*nvlen*) which will be passed to `nghttp2_hd_deflate_hd()`.
Subsequent calls to `nghttp2_hd_deflate_hd2()` will use the current
Subsequent calls to `nghttp2_hd_deflate_hd()` will use the current
encoder state and perform differential encoding, which yields HPAC's
fundamental compression gain.
If `nghttp2_hd_deflate_hd2()` fails, the failure is fatal and any
If `nghttp2_hd_deflate_hd()` fails, the failure is fatal and any
further calls with the same deflater object will fail. Thus it's very
important to use `nghttp2_hd_deflate_bound()` to determine the
required size of the output buffer.
@@ -78,14 +78,14 @@ header data. To initialize the object, use
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
To inflate header data, use `nghttp2_hd_inflate_hd3()`::
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater,
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen,
int in_final);
`nghttp2_hd_inflate_hd3()` reads a stream of bytes and outputs a
`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a
single header field at a time. Multiple calls are normally required to
read a full stream of bytes and output all of the header fields.
@@ -119,7 +119,7 @@ If *in_final* is zero and the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag is
not set, it indicates that all given data was processed. The caller
is required to pass additional data.
Example usage of `nghttp2_hd_inflate_hd3()` is shown in the
Example usage of `nghttp2_hd_inflate_hd2()` is shown in the
`inflate_header_block()` function in `deflate.c`_.
Finally, to delete a :type:`nghttp2_hd_inflater` object, use

View File

@@ -21,18 +21,41 @@ note that nghttp2 itself does not depend on libevent.
The server starts with some libevent and OpenSSL setup in the
``main()`` and ``run()`` functions. This setup isn't specific to
nghttp2, but one thing you should look at is setup of ALPN callback.
The ALPN callback is used by the server to select application
protocols offered by client. In ALPN, client sends the list of
supported application protocols, and server selects one of them. We
provide the callback for it::
nghttp2, but one thing you should look at is setup of the NPN
callback. The NPN callback is used by the server to advertise which
application protocols the server supports to a client. In this
example program, when creating the ``SSL_CTX`` object, we store the
application protocol name in the wire format of NPN in a statically
allocated buffer. This is safe because we only create one ``SSL_CTX``
object in the program's entire lifetime.
If you are following TLS related RFC, you know that NPN is not the
standardized way to negotiate HTTP/2. NPN itself is not even
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
ALPN support depending on OpenSSL version. In ALPN, client sends the
list of supported application protocols, and server selects one of
them. We provide the callback for it::
static unsigned char next_proto_list[256];
static size_t next_proto_list_len;
static int next_proto_cb(SSL *s _U_, const unsigned char **data,
unsigned int *len, void *arg _U_) {
*data = next_proto_list;
*len = (unsigned int)next_proto_list_len;
return SSL_TLSEXT_ERR_OK;
}
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg _U_) {
int rv;
rv = nghttp2_select_alpn(out, outlen, in, inlen);
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
if (rv != 1) {
return SSL_TLSEXT_ERR_NOACK;
@@ -40,6 +63,7 @@ provide the callback for it::
return SSL_TLSEXT_ERR_OK;
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_CTX *ssl_ctx;
@@ -49,14 +73,33 @@ provide the callback for it::
...
next_proto_list[0] = NGHTTP2_PROTO_VERSION_ID_LEN;
memcpy(&next_proto_list[1], NGHTTP2_PROTO_VERSION_ID,
NGHTTP2_PROTO_VERSION_ID_LEN);
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
In ``alpn_select_proto_cb()``, we use `nghttp2_select_alpn()` to
select application protocol. The `nghttp2_select_alpn()` returns 1
only if it selected h2 (ALPN identifier for HTTP/2), and out
The wire format of NPN is a sequence of length prefixed strings, with
exactly one byte used to specify the length of each protocol
identifier. In this tutorial, we advertise the specific HTTP/2
protocol version the current nghttp2 library supports, which is
exported in the identifier :macro:`NGHTTP2_PROTO_VERSION_ID`. The
``next_proto_cb()`` function is the server-side NPN callback. In the
OpenSSL implementation, we just assign the pointer to the NPN buffers
we filled in earlier. The NPN callback function is set to the
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
In ``alpn_select_proto_cb()``, we use `nghttp2_select_next_protocol()`
to select application protocol. The `nghttp2_select_next_protocol()`
returns 1 only if it selected h2 (ALPN identifier for HTTP/2), and out
parameters were assigned accordingly.
Next, let's take a look at the main structures used by the example
@@ -170,7 +213,12 @@ underlying network socket::
ssl = bufferevent_openssl_get_ssl(session_data->bev);
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
@@ -220,7 +268,7 @@ session object and several callbacks::
nghttp2_session_callbacks_new(&callbacks);
nghttp2_session_callbacks_set_send_callback2(callbacks, send_callback);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
on_frame_recv_callback);
@@ -275,12 +323,12 @@ this pending data. To process the received data, we call the
``session_recv()`` function::
static int session_recv(http2_session_data *session_data) {
nghttp2_ssize readlen;
ssize_t readlen;
struct evbuffer *input = bufferevent_get_input(session_data->bev);
size_t datalen = evbuffer_get_length(input);
unsigned char *data = evbuffer_pullup(input, -1);
readlen = nghttp2_session_mem_recv2(session_data->session, data, datalen);
readlen = nghttp2_session_mem_recv(session_data->session, data, datalen);
if (readlen < 0) {
warnx("Fatal error: %s", nghttp2_strerror((int)readlen));
return -1;
@@ -296,9 +344,9 @@ this pending data. To process the received data, we call the
}
In this function, we feed all unprocessed but already received data to
the nghttp2 session object using the `nghttp2_session_mem_recv2()`
function. The `nghttp2_session_mem_recv2()` function processes the
data and may both invoke the previously setup callbacks and also queue
the nghttp2 session object using the `nghttp2_session_mem_recv()`
function. The `nghttp2_session_mem_recv()` function processes the data
and may both invoke the previously setup callbacks and also queue
outgoing frames. To send any pending outgoing frames, we immediately
call ``session_send()``.
@@ -316,12 +364,11 @@ The ``session_send()`` function is defined as follows::
The `nghttp2_session_send()` function serializes the frame into wire
format and calls the ``send_callback()``, which is of type
:type:`nghttp2_send_callback2`. The ``send_callback()`` is defined as
:type:`nghttp2_send_callback`. The ``send_callback()`` is defined as
follows::
static nghttp2_ssize send_callback(nghttp2_session *session _U_,
const uint8_t *data, size_t length,
int flags _U_, void *user_data) {
static ssize_t send_callback(nghttp2_session *session _U_, const uint8_t *data,
size_t length, int flags _U_, void *user_data) {
http2_session_data *session_data = (http2_session_data *)user_data;
struct bufferevent *bev = session_data->bev;
/* Avoid excessive buffering in server side. */
@@ -330,7 +377,7 @@ follows::
return NGHTTP2_ERR_WOULDBLOCK;
}
bufferevent_write(bev, data, length);
return (nghttp2_ssize)length;
return (ssize_t)length;
}
Since we use bufferevent to abstract network I/O, we just write the
@@ -510,11 +557,11 @@ Sending the file content is performed by the ``send_response()`` function::
static int send_response(nghttp2_session *session, int32_t stream_id,
nghttp2_nv *nva, size_t nvlen, int fd) {
int rv;
nghttp2_data_provider2 data_prd;
nghttp2_data_provider data_prd;
data_prd.source.fd = fd;
data_prd.read_callback = file_read_callback;
rv = nghttp2_submit_response2(session, stream_id, nva, nvlen, &data_prd);
rv = nghttp2_submit_response(session, stream_id, nva, nvlen, &data_prd);
if (rv != 0) {
warnx("Fatal error: %s", nghttp2_strerror(rv));
return -1;
@@ -522,7 +569,7 @@ Sending the file content is performed by the ``send_response()`` function::
return 0;
}
nghttp2 uses the :type:`nghttp2_data_provider2` structure to send the
nghttp2 uses the :type:`nghttp2_data_provider` structure to send the
entity body to the remote peer. The ``source`` member of this
structure is a union, which can be either a void pointer or an int
(which is intended to be used as file descriptor). In this example
@@ -530,7 +577,7 @@ server, we use it as a file descriptor. We also set the
``file_read_callback()`` callback function to read the contents of the
file::
static nghttp2_ssize file_read_callback(nghttp2_session *session _U_,
static ssize_t file_read_callback(nghttp2_session *session _U_,
int32_t stream_id _U_, uint8_t *buf,
size_t length, uint32_t *data_flags,
nghttp2_data_source *source,
@@ -545,7 +592,7 @@ file::
if (r == 0) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
}
return (nghttp2_ssize)r;
return r;
}
If an error occurs while reading the file, we return
@@ -554,8 +601,8 @@ library to send RST_STREAM to the stream. When all data has been
read, the :macro:`NGHTTP2_DATA_FLAG_EOF` flag is set to signal nghttp2
that we have finished reading the file.
The `nghttp2_submit_response2()` function is used to send the response
to the remote peer.
The `nghttp2_submit_response()` function is used to send the response to the
remote peer.
The ``on_stream_close_callback()`` function is invoked when the stream
is about to close::

View File

@@ -1,84 +1,78 @@
FROM debian:12 as build
ARG NGHTTP2_BRANCH=master
FROM debian:11 as build
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git clang-19 make binutils autoconf automake autotools-dev libtool \
pkg-config cmake cmake-data \
apt-get install -y --no-install-recommends \
git clang make binutils autoconf automake autotools-dev libtool \
pkg-config \
zlib1g-dev libev-dev libjemalloc-dev ruby-dev libc-ares-dev bison \
libelf-dev libbrotli-dev
libelf-dev
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.62.0 https://github.com/aws/aws-lc && \
cd aws-lc && \
export CC=clang-19 CXX=clang++-19 && \
cmake -B build -DDISABLE_GO=ON && \
make -j$(nproc) -C build && \
cmake --install build && \
RUN git clone --depth 1 -b OpenSSL_1_1_1s+quic https://github.com/quictls/openssl && \
cd openssl && \
./config --openssldir=/etc/ssl && \
make -j$(nproc) && \
make install_sw && \
cd .. && \
rm -rf aws-lc
rm -rf openssl
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.12.0 https://github.com/ngtcp2/nghttp3 && \
RUN git clone --depth 1 -b v0.8.0 https://github.com/ngtcp2/nghttp3 && \
cd nghttp3 && \
autoreconf -i && \
./configure --disable-dependency-tracking --enable-lib-only \
CC=clang-19 CXX=clang++-19 && \
./configure --enable-lib-only && \
make -j$(nproc) && \
make install-strip && \
cd .. && \
rm -rf nghttp3
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.17.0 https://github.com/ngtcp2/ngtcp2 && \
RUN git clone --depth 1 -b v0.12.0 https://github.com/ngtcp2/ngtcp2 && \
cd ngtcp2 && \
autoreconf -i && \
./configure --disable-dependency-tracking --enable-lib-only \
--with-boringssl \
CC=clang-19 CXX=clang++-19 \
./configure --enable-lib-only \
LIBTOOL_LDFLAGS="-static-libtool-libs" \
BORINGSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
OPENSSL_LIBS="-l:libssl.a -l:libcrypto.a -ldl -lpthread" \
PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig" && \
make -j$(nproc) && \
make install-strip && \
cd .. && \
rm -rf ngtcp2
RUN git clone --depth 1 -b v1.6.2 https://github.com/libbpf/libbpf && \
RUN git clone --depth 1 -b v1.0.1 https://github.com/libbpf/libbpf && \
cd libbpf && \
CC=clang-19 PREFIX=/usr/local make -C src install && \
PREFIX=/usr/local make -C src install && \
cd .. && \
rm -rf libbpf
RUN git clone --recursive --shallow-submodules --depth 1 -b $NGHTTP2_BRANCH https://github.com/nghttp2/nghttp2 && \
RUN git clone --depth 1 https://github.com/nghttp2/nghttp2.git && \
cd nghttp2 && \
git submodule update --init && \
autoreconf -i && \
./configure --disable-dependency-tracking --disable-examples \
--disable-hpack-tools \
--with-mruby \
./configure --disable-examples --disable-hpack-tools \
--with-mruby --with-neverbleed \
--enable-http3 --with-libbpf \
--with-libbrotlienc --with-libbrotlidec \
CC=clang-19 CXX=clang++-19 \
CC=clang CXX=clang++ \
LIBTOOL_LDFLAGS="-static-libtool-libs" \
OPENSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
OPENSSL_LIBS="-l:libssl.a -l:libcrypto.a -ldl -pthread" \
LIBEV_LIBS="-l:libev.a" \
JEMALLOC_LIBS="-l:libjemalloc.a" \
LIBCARES_LIBS="-l:libcares.a" \
ZLIB_LIBS="-l:libz.a" \
LIBBPF_LIBS="-L/usr/local/lib64 -l:libbpf.a -l:libelf.a" \
LIBBROTLIENC_LIBS="-l:libbrotlienc.a -l:libbrotlicommon.a" \
LIBBROTLIDEC_LIBS="-l:libbrotlidec.a -l:libbrotlicommon.a" \
LDFLAGS="-static-libgcc -static-libstdc++" \
PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig" && \
make -j$(nproc) install-strip && \
cd .. && \
rm -rf nghttp2
FROM gcr.io/distroless/base-nossl-debian12
FROM gcr.io/distroless/base-debian11
COPY --from=build --link \
COPY --from=build \
/usr/local/share/nghttp2/ \
/usr/local/share/nghttp2/
COPY --from=build \
/usr/local/bin/h2load \
/usr/local/bin/nghttpx \
/usr/local/bin/nghttp \
/usr/local/bin/nghttpd \
/usr/local/bin/
COPY --from=build --link /usr/local/lib/nghttp2/reuseport_kern.o \
COPY --from=build /usr/local/lib/nghttp2/reuseport_kern.o \
/usr/local/lib/nghttp2/

View File

@@ -8,7 +8,7 @@ if(ENABLE_EXAMPLES)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/../third-party/urlparse"
"${CMAKE_CURRENT_SOURCE_DIR}/../third-party"
"${CMAKE_CURRENT_SOURCE_DIR}/../third-party/llhttp/include"
${LIBEVENT_INCLUDE_DIRS}
@@ -23,15 +23,15 @@ if(ENABLE_EXAMPLES)
)
add_executable(client client.c $<TARGET_OBJECTS:llhttp>
$<TARGET_OBJECTS:urlparse>
$<TARGET_OBJECTS:url-parser>
)
add_executable(libevent-client libevent-client.c $<TARGET_OBJECTS:llhttp>
$<TARGET_OBJECTS:urlparse>
$<TARGET_OBJECTS:url-parser>
)
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:llhttp>
$<TARGET_OBJECTS:urlparse>
$<TARGET_OBJECTS:url-parser>
)
add_executable(deflate deflate.c $<TARGET_OBJECTS:llhttp>
$<TARGET_OBJECTS:urlparse>
$<TARGET_OBJECTS:url-parser>
)
endif()

View File

@@ -30,13 +30,13 @@ AM_CXXFLAGS = $(WARNCXXFLAGS) $(CXX1XCXXFLAGS)
AM_CPPFLAGS = \
-I$(top_srcdir)/lib/includes \
-I$(top_builddir)/lib/includes \
-I$(top_srcdir)/third-party/urlparse \
-I$(top_srcdir)/third-party \
@LIBEVENT_OPENSSL_CFLAGS@ \
@OPENSSL_CFLAGS@ \
@DEFS@
AM_LDFLAGS = @LIBTOOL_LDFLAGS@
LDADD = $(top_builddir)/lib/libnghttp2.la \
$(top_builddir)/third-party/liburlparse.la \
$(top_builddir)/third-party/liburl-parser.la \
@LIBEVENT_OPENSSL_LIBS@ \
@OPENSSL_LIBS@ \
@APPLDFLAGS@

View File

@@ -28,26 +28,26 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <inttypes.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* defined(HAVE_UNISTD_H) */
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif /* defined(HAVE_FCNTL_H) */
#endif /* HAVE_FCNTL_H */
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* defined(HAVE_SYS_SOCKET_H) */
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif /* defined(HAVE_NETDB_H) */
#endif /* HAVE_NETDB_H */
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* defined(HAVE_NETINET_IN_H) */
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h>
#include <poll.h>
#include <signal.h>
@@ -56,7 +56,6 @@
#include <string.h>
#include <errno.h>
#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#include <openssl/ssl.h>
@@ -67,14 +66,14 @@ enum { IO_NONE, WANT_READ, WANT_WRITE };
#define MAKE_NV(NAME, VALUE) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, \
sizeof(VALUE) - 1, NGHTTP2_NV_FLAG_NONE, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
#define MAKE_NV_CS(NAME, VALUE) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, \
strlen(VALUE), NGHTTP2_NV_FLAG_NONE, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
NGHTTP2_NV_FLAG_NONE \
}
struct Connection {
@@ -155,14 +154,13 @@ static void diec(const char *func, int error_code) {
}
/*
* The implementation of nghttp2_send_callback2 type. Here we write
* The implementation of nghttp2_send_callback type. Here we write
* |data| with size |length| to the network and return the number of
* bytes actually written. See the documentation of
* nghttp2_send_callback for the details.
*/
static nghttp2_ssize send_callback(nghttp2_session *session,
const uint8_t *data, size_t length,
int flags, void *user_data) {
static ssize_t send_callback(nghttp2_session *session, const uint8_t *data,
size_t length, int flags, void *user_data) {
struct Connection *connection;
int rv;
(void)session;
@@ -186,13 +184,12 @@ static nghttp2_ssize send_callback(nghttp2_session *session,
}
/*
* The implementation of nghttp2_recv_callback2 type. Here we read
* data from the network and write them in |buf|. The capacity of
* |buf| is |length| bytes. Returns the number of bytes stored in
* |buf|. See the documentation of nghttp2_recv_callback for the
* details.
* The implementation of nghttp2_recv_callback type. Here we read data
* from the network and write them in |buf|. The capacity of |buf| is
* |length| bytes. Returns the number of bytes stored in |buf|. See
* the documentation of nghttp2_recv_callback for the details.
*/
static nghttp2_ssize recv_callback(nghttp2_session *session, uint8_t *buf,
static ssize_t recv_callback(nghttp2_session *session, uint8_t *buf,
size_t length, int flags, void *user_data) {
struct Connection *connection;
int rv;
@@ -331,9 +328,9 @@ static int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
* recv_callback is also required.
*/
static void setup_nghttp2_callbacks(nghttp2_session_callbacks *callbacks) {
nghttp2_session_callbacks_set_send_callback2(callbacks, send_callback);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_recv_callback2(callbacks, recv_callback);
nghttp2_session_callbacks_set_recv_callback(callbacks, recv_callback);
nghttp2_session_callbacks_set_on_frame_send_callback(callbacks,
on_frame_send_callback);
@@ -348,6 +345,29 @@ static void setup_nghttp2_callbacks(nghttp2_session_callbacks *callbacks) {
callbacks, on_data_chunk_recv_callback);
}
#ifndef OPENSSL_NO_NEXTPROTONEG
/*
* Callback function for TLS NPN. Since this program only supports
* HTTP/2 protocol, if server does not offer HTTP/2 the nghttp2
* library supports, we terminate program.
*/
static int select_next_proto_cb(SSL *ssl, unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg) {
int rv;
(void)ssl;
(void)arg;
/* nghttp2_select_next_protocol() selects HTTP/2 protocol the
nghttp2 library supports. */
rv = nghttp2_select_next_protocol(out, outlen, in, inlen);
if (rv <= 0) {
die("Server did not advertise HTTP/2 protocol");
}
return SSL_TLSEXT_ERR_OK;
}
#endif /* !OPENSSL_NO_NEXTPROTONEG */
/*
* Setup SSL/TLS context.
*/
@@ -356,8 +376,14 @@ static void init_ssl_ctx(SSL_CTX *ssl_ctx) {
SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
/* Set NPN callback */
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
}
static void ssl_handshake(SSL *ssl, int fd) {
@@ -461,7 +487,7 @@ static void submit_request(struct Connection *connection, struct Request *req) {
MAKE_NV("accept", "*/*"),
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
stream_id = nghttp2_submit_request2(connection->session, NULL, nva,
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
sizeof(nva) / sizeof(nva[0]), NULL, req);
if (stream_id < 0) {
@@ -693,6 +719,19 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, 0);
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
/* No explicit initialization is required. */
#elif defined(OPENSSL_IS_BORINGSSL)
CRYPTO_library_init();
#else /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
OPENSSL_config(NULL);
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
rv = parse_uri(&uri, argv[1]);
if (rv != 0) {
die("parse_uri failed");

View File

@@ -24,18 +24,17 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* !HAVE_CONFIG_H */
#include <stdio.h>
#include <string.h>
#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#define MAKE_NV(K, V) \
{ \
(uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, \
sizeof(V) - 1, NGHTTP2_NV_FLAG_NONE, \
(uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
static void deflate(nghttp2_hd_deflater *deflater,
@@ -94,7 +93,7 @@ int main(void) {
static void deflate(nghttp2_hd_deflater *deflater,
nghttp2_hd_inflater *inflater, const nghttp2_nv *const nva,
size_t nvlen) {
nghttp2_ssize rv;
ssize_t rv;
uint8_t *buf;
size_t buflen;
size_t outlen;
@@ -119,10 +118,10 @@ static void deflate(nghttp2_hd_deflater *deflater,
buflen = nghttp2_hd_deflate_bound(deflater, nva, nvlen);
buf = malloc(buflen);
rv = nghttp2_hd_deflate_hd2(deflater, buf, buflen, nva, nvlen);
rv = nghttp2_hd_deflate_hd(deflater, buf, buflen, nva, nvlen);
if (rv < 0) {
fprintf(stderr, "nghttp2_hd_deflate_hd2() failed with error: %s\n",
fprintf(stderr, "nghttp2_hd_deflate_hd() failed with error: %s\n",
nghttp2_strerror((int)rv));
free(buf);
@@ -167,18 +166,17 @@ static void deflate(nghttp2_hd_deflater *deflater,
int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
size_t inlen, int final) {
nghttp2_ssize rv;
ssize_t rv;
for (;;) {
nghttp2_nv nv;
int inflate_flags = 0;
size_t proclen;
rv =
nghttp2_hd_inflate_hd3(inflater, &nv, &inflate_flags, in, inlen, final);
rv = nghttp2_hd_inflate_hd(inflater, &nv, &inflate_flags, in, inlen, final);
if (rv < 0) {
fprintf(stderr, "inflate failed with error code %td", rv);
fprintf(stderr, "inflate failed with error code %zd", rv);
return -1;
}

View File

@@ -31,26 +31,26 @@
}
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
char *strndup(const char *s, size_t size);
#endif /* defined(__sgi) */
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* defined(HAVE_UNISTD_H) */
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* defined(HAVE_SYS_SOCKET_H) */
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* defined(HAVE_NETINET_IN_H) */
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h>
#ifndef __sgi
# include <err.h>
#endif /* !defined(__sgi) */
#endif
#include <signal.h>
#include <string.h>
@@ -63,10 +63,9 @@ char *strndup(const char *s, size_t size);
#include <event2/bufferevent_ssl.h>
#include <event2/dns.h>
#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#include "urlparse.h"
#include "url-parser/url_parser.h"
#define ARRLEN(x) (sizeof(x) / sizeof(x[0]))
@@ -74,7 +73,7 @@ typedef struct {
/* The NULL-terminated URI string to retrieve. */
const char *uri;
/* Parsed result of the |uri| */
urlparse_url *u;
struct http_parser_url *u;
/* The authority portion of the |uri|, not NULL-terminated */
char *authority;
/* The path portion of the |uri|, including query, not
@@ -96,7 +95,7 @@ typedef struct {
} http2_session_data;
static http2_stream_data *create_http2_stream_data(const char *uri,
urlparse_url *u) {
struct http_parser_url *u) {
/* MAX 5 digits (max 65535) + 1 ':' + 1 NULL (because of snprintf) */
size_t extra = 7;
http2_stream_data *stream_data = malloc(sizeof(http2_stream_data));
@@ -105,41 +104,39 @@ static http2_stream_data *create_http2_stream_data(const char *uri,
stream_data->u = u;
stream_data->stream_id = -1;
stream_data->authoritylen = u->field_data[URLPARSE_HOST].len;
stream_data->authoritylen = u->field_data[UF_HOST].len;
stream_data->authority = malloc(stream_data->authoritylen + extra);
memcpy(stream_data->authority, &uri[u->field_data[URLPARSE_HOST].off],
u->field_data[URLPARSE_HOST].len);
if (u->field_set & (1 << URLPARSE_PORT)) {
stream_data->authoritylen += (size_t)snprintf(
stream_data->authority + u->field_data[URLPARSE_HOST].len, extra, ":%u",
u->port);
memcpy(stream_data->authority, &uri[u->field_data[UF_HOST].off],
u->field_data[UF_HOST].len);
if (u->field_set & (1 << UF_PORT)) {
stream_data->authoritylen +=
(size_t)snprintf(stream_data->authority + u->field_data[UF_HOST].len,
extra, ":%u", u->port);
}
/* If we don't have path in URI, we use "/" as path. */
stream_data->pathlen = 1;
if (u->field_set & (1 << URLPARSE_PATH)) {
stream_data->pathlen = u->field_data[URLPARSE_PATH].len;
if (u->field_set & (1 << UF_PATH)) {
stream_data->pathlen = u->field_data[UF_PATH].len;
}
if (u->field_set & (1 << URLPARSE_QUERY)) {
if (u->field_set & (1 << UF_QUERY)) {
/* +1 for '?' character */
stream_data->pathlen += (size_t)(u->field_data[URLPARSE_QUERY].len + 1);
stream_data->pathlen += (size_t)(u->field_data[UF_QUERY].len + 1);
}
stream_data->path = malloc(stream_data->pathlen);
if (u->field_set & (1 << URLPARSE_PATH)) {
memcpy(stream_data->path, &uri[u->field_data[URLPARSE_PATH].off],
u->field_data[URLPARSE_PATH].len);
if (u->field_set & (1 << UF_PATH)) {
memcpy(stream_data->path, &uri[u->field_data[UF_PATH].off],
u->field_data[UF_PATH].len);
} else {
stream_data->path[0] = '/';
}
if (u->field_set & (1 << URLPARSE_QUERY)) {
stream_data
->path[stream_data->pathlen - u->field_data[URLPARSE_QUERY].len - 1] =
if (u->field_set & (1 << UF_QUERY)) {
stream_data->path[stream_data->pathlen - u->field_data[UF_QUERY].len - 1] =
'?';
memcpy(stream_data->path + stream_data->pathlen -
u->field_data[URLPARSE_QUERY].len,
&uri[u->field_data[URLPARSE_QUERY].off],
u->field_data[URLPARSE_QUERY].len);
u->field_data[UF_QUERY].len,
&uri[u->field_data[UF_QUERY].off], u->field_data[UF_QUERY].len);
}
return stream_data;
@@ -199,19 +196,18 @@ static void print_headers(FILE *f, nghttp2_nv *nva, size_t nvlen) {
fprintf(f, "\n");
}
/* nghttp2_send_callback2. Here we transmit the |data|, |length|
bytes, to the network. Because we are using libevent bufferevent,
we just write those bytes into bufferevent buffer. */
static nghttp2_ssize send_callback(nghttp2_session *session,
const uint8_t *data, size_t length,
int flags, void *user_data) {
/* nghttp2_send_callback. Here we transmit the |data|, |length| bytes,
to the network. Because we are using libevent bufferevent, we just
write those bytes into bufferevent buffer. */
static ssize_t send_callback(nghttp2_session *session, const uint8_t *data,
size_t length, int flags, void *user_data) {
http2_session_data *session_data = (http2_session_data *)user_data;
struct bufferevent *bev = session_data->bev;
(void)session;
(void)flags;
bufferevent_write(bev, data, length);
return (nghttp2_ssize)length;
return (ssize_t)length;
}
/* nghttp2_on_header_callback: Called when nghttp2 library emits
@@ -312,6 +308,23 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
return 0;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
/* NPN TLS extension client callback. We check that server advertised
the HTTP/2 protocol the nghttp2 library supports. If not, exit
the program. */
static int select_next_proto_cb(SSL *ssl, unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg) {
(void)ssl;
(void)arg;
if (nghttp2_select_next_protocol(out, outlen, in, inlen) <= 0) {
errx(1, "Server did not advertise " NGHTTP2_PROTO_VERSION_ID);
}
return SSL_TLSEXT_ERR_OK;
}
#endif /* !OPENSSL_NO_NEXTPROTONEG */
/* Create SSL_CTX. */
static SSL_CTX *create_ssl_ctx(void) {
SSL_CTX *ssl_ctx;
@@ -320,11 +333,17 @@ static SSL_CTX *create_ssl_ctx(void) {
errx(1, "Could not create SSL/TLS context: %s",
ERR_error_string(ERR_get_error(), NULL));
}
SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_CTX_set_options(ssl_ctx,
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
return ssl_ctx;
}
@@ -345,7 +364,7 @@ static void initialize_nghttp2_session(http2_session_data *session_data) {
nghttp2_session_callbacks_new(&callbacks);
nghttp2_session_callbacks_set_send_callback2(callbacks, send_callback);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
on_frame_recv_callback);
@@ -382,14 +401,14 @@ static void send_client_connection_header(http2_session_data *session_data) {
#define MAKE_NV(NAME, VALUE, VALUELEN) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, \
VALUELEN, NGHTTP2_NV_FLAG_NONE, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
NGHTTP2_NV_FLAG_NONE \
}
#define MAKE_NV2(NAME, VALUE) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, \
sizeof(VALUE) - 1, NGHTTP2_NV_FLAG_NONE, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
/* Send HTTP request to the remote peer */
@@ -397,16 +416,16 @@ static void submit_request(http2_session_data *session_data) {
int32_t stream_id;
http2_stream_data *stream_data = session_data->stream_data;
const char *uri = stream_data->uri;
const urlparse_url *u = stream_data->u;
const struct http_parser_url *u = stream_data->u;
nghttp2_nv hdrs[] = {
MAKE_NV2(":method", "GET"),
MAKE_NV(":scheme", &uri[u->field_data[URLPARSE_SCHEMA].off],
u->field_data[URLPARSE_SCHEMA].len),
MAKE_NV(":scheme", &uri[u->field_data[UF_SCHEMA].off],
u->field_data[UF_SCHEMA].len),
MAKE_NV(":authority", stream_data->authority, stream_data->authoritylen),
MAKE_NV(":path", stream_data->path, stream_data->pathlen)};
fprintf(stderr, "Request headers:\n");
print_headers(stderr, hdrs, ARRLEN(hdrs));
stream_id = nghttp2_submit_request2(session_data->session, NULL, hdrs,
stream_id = nghttp2_submit_request(session_data->session, NULL, hdrs,
ARRLEN(hdrs), NULL, stream_data);
if (stream_id < 0) {
errx(1, "Could not submit HTTP request: %s", nghttp2_strerror(stream_id));
@@ -434,12 +453,12 @@ static int session_send(http2_session_data *session_data) {
context. To send them, we call session_send() in the end. */
static void readcb(struct bufferevent *bev, void *ptr) {
http2_session_data *session_data = (http2_session_data *)ptr;
nghttp2_ssize readlen;
ssize_t readlen;
struct evbuffer *input = bufferevent_get_input(bev);
size_t datalen = evbuffer_get_length(input);
unsigned char *data = evbuffer_pullup(input, -1);
readlen = nghttp2_session_mem_recv2(session_data->session, data, datalen);
readlen = nghttp2_session_mem_recv(session_data->session, data, datalen);
if (readlen < 0) {
warnx("Fatal error: %s", nghttp2_strerror((int)readlen));
delete_http2_session_data(session_data);
@@ -489,9 +508,14 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
ssl = bufferevent_openssl_get_ssl(session_data->bev);
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "h2 is not negotiated\n");
@@ -544,7 +568,7 @@ static void initiate_connection(struct event_base *evbase, SSL_CTX *ssl_ctx,
/* Get resource denoted by the |uri|. The debug and error messages are
printed in stderr, while the response body is printed in stdout. */
static void run(const char *uri) {
urlparse_url u;
struct http_parser_url u;
char *host;
uint16_t port;
int rv;
@@ -553,13 +577,12 @@ static void run(const char *uri) {
http2_session_data *session_data;
/* Parse the |uri| and stores its components in |u| */
rv = urlparse_parse_url(uri, strlen(uri), 0, &u);
rv = http_parser_parse_url(uri, strlen(uri), 0, &u);
if (rv != 0) {
errx(1, "Could not parse URI %s", uri);
}
host = strndup(&uri[u.field_data[URLPARSE_HOST].off],
u.field_data[URLPARSE_HOST].len);
if (!(u.field_set & (1 << URLPARSE_PORT))) {
host = strndup(&uri[u.field_data[UF_HOST].off], u.field_data[UF_HOST].len);
if (!(u.field_set & (1 << UF_PORT))) {
port = 443;
} else {
port = u.port;
@@ -594,6 +617,19 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
/* No explicit initialization is required. */
#elif defined(OPENSSL_IS_BORINGSSL)
CRYPTO_library_init();
#else /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
OPENSSL_config(NULL);
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
run(argv[1]);
return 0;
}

View File

@@ -30,35 +30,35 @@
}
# define warn(format, args...) warnx(format ": %s", ##args, strerror(errno))
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
#endif /* defined(__sgi) */
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* defined(HAVE_SYS_SOCKET_H) */
#endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif /* defined(HAVE_NETDB_H) */
#endif /* HAVE_NETDB_H */
#include <signal.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* defined(HAVE_UNISTD_H) */
#endif /* HAVE_UNISTD_H */
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif /* defined(HAVE_FCNTL_H) */
#endif /* HAVE_FCNTL_H */
#include <ctype.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* defined(HAVE_NETINET_IN_H) */
#endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h>
#ifndef __sgi
# include <err.h>
#endif /* !defined(__sgi) */
#endif
#include <string.h>
#include <errno.h>
@@ -71,7 +71,6 @@
#include <event2/bufferevent_ssl.h>
#include <event2/listener.h>
#define NGHTTP2_NO_SSIZE_T
#include <nghttp2/nghttp2.h>
#define OUTPUT_WOULDBLOCK_THRESHOLD (1 << 16)
@@ -80,8 +79,8 @@
#define MAKE_NV(NAME, VALUE) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, \
sizeof(VALUE) - 1, NGHTTP2_NV_FLAG_NONE, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
struct app_context;
@@ -107,6 +106,22 @@ struct app_context {
struct event_base *evbase;
};
static unsigned char next_proto_list[256];
static size_t next_proto_list_len;
#ifndef OPENSSL_NO_NEXTPROTONEG
static int next_proto_cb(SSL *ssl, const unsigned char **data,
unsigned int *len, void *arg) {
(void)ssl;
(void)arg;
*data = next_proto_list;
*len = (unsigned int)next_proto_list_len;
return SSL_TLSEXT_ERR_OK;
}
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg) {
@@ -114,7 +129,7 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
(void)ssl;
(void)arg;
rv = nghttp2_select_alpn(out, outlen, in, inlen);
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
if (rv != 1) {
return SSL_TLSEXT_ERR_NOACK;
@@ -122,6 +137,7 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
return SSL_TLSEXT_ERR_OK;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
/* Create SSL_CTX. */
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
@@ -132,15 +148,16 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
errx(1, "Could not create SSL/TLS context: %s",
ERR_error_string(ERR_get_error(), NULL));
}
SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_CTX_set_options(ssl_ctx,
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (SSL_CTX_set1_groups_list(ssl_ctx, "P-256") != 1) {
errx(1, "SSL_CTX_set1_groups_list failed: %s",
if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
errx(1, "SSL_CTX_set1_curves_list failed: %s",
ERR_error_string(ERR_get_error(), NULL));
}
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
#else /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
{
EC_KEY *ecdh;
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
@@ -151,7 +168,7 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
EC_KEY_free(ecdh);
}
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
errx(1, "Could not read private key file %s", key_file);
@@ -160,7 +177,18 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
errx(1, "Could not read certificate file %s", cert_file);
}
next_proto_list[0] = NGHTTP2_PROTO_VERSION_ID_LEN;
memcpy(&next_proto_list[1], NGHTTP2_PROTO_VERSION_ID,
NGHTTP2_PROTO_VERSION_ID_LEN);
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
return ssl_ctx;
}
@@ -277,16 +305,16 @@ static int session_send(http2_session_data *session_data) {
}
/* Read the data in the bufferevent and feed them into nghttp2 library
function. Invocation of nghttp2_session_mem_recv2() may make
function. Invocation of nghttp2_session_mem_recv() may make
additional pending frames, so call session_send() at the end of the
function. */
static int session_recv(http2_session_data *session_data) {
nghttp2_ssize readlen;
ssize_t readlen;
struct evbuffer *input = bufferevent_get_input(session_data->bev);
size_t datalen = evbuffer_get_length(input);
unsigned char *data = evbuffer_pullup(input, -1);
readlen = nghttp2_session_mem_recv2(session_data->session, data, datalen);
readlen = nghttp2_session_mem_recv(session_data->session, data, datalen);
if (readlen < 0) {
warnx("Fatal error: %s", nghttp2_strerror((int)readlen));
return -1;
@@ -301,9 +329,8 @@ static int session_recv(http2_session_data *session_data) {
return 0;
}
static nghttp2_ssize send_callback(nghttp2_session *session,
const uint8_t *data, size_t length,
int flags, void *user_data) {
static ssize_t send_callback(nghttp2_session *session, const uint8_t *data,
size_t length, int flags, void *user_data) {
http2_session_data *session_data = (http2_session_data *)user_data;
struct bufferevent *bev = session_data->bev;
(void)session;
@@ -315,7 +342,7 @@ static nghttp2_ssize send_callback(nghttp2_session *session,
return NGHTTP2_ERR_WOULDBLOCK;
}
bufferevent_write(bev, data, length);
return (nghttp2_ssize)length;
return (ssize_t)length;
}
/* Returns nonzero if the string |s| ends with the substring |sub| */
@@ -371,9 +398,9 @@ static char *percent_decode(const uint8_t *value, size_t valuelen) {
return res;
}
static nghttp2_ssize file_read_callback(nghttp2_session *session,
int32_t stream_id, uint8_t *buf,
size_t length, uint32_t *data_flags,
static ssize_t file_read_callback(nghttp2_session *session, int32_t stream_id,
uint8_t *buf, size_t length,
uint32_t *data_flags,
nghttp2_data_source *source,
void *user_data) {
int fd = source->fd;
@@ -390,17 +417,17 @@ static nghttp2_ssize file_read_callback(nghttp2_session *session,
if (r == 0) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
}
return (nghttp2_ssize)r;
return r;
}
static int send_response(nghttp2_session *session, int32_t stream_id,
nghttp2_nv *nva, size_t nvlen, int fd) {
int rv;
nghttp2_data_provider2 data_prd;
nghttp2_data_provider data_prd;
data_prd.source.fd = fd;
data_prd.read_callback = file_read_callback;
rv = nghttp2_submit_response2(session, stream_id, nva, nvlen, &data_prd);
rv = nghttp2_submit_response(session, stream_id, nva, nvlen, &data_prd);
if (rv != 0) {
warnx("Fatal error: %s", nghttp2_strerror(rv));
return -1;
@@ -421,9 +448,9 @@ static int error_reply(nghttp2_session *session,
rv = pipe(pipefd);
if (rv != 0) {
warn("Could not create pipe");
rv =
nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
stream_data->stream_id, NGHTTP2_INTERNAL_ERROR);
rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE,
stream_data->stream_id,
NGHTTP2_INTERNAL_ERROR);
if (rv != 0) {
warnx("Fatal error: %s", nghttp2_strerror(rv));
return -1;
@@ -591,7 +618,7 @@ static void initialize_nghttp2_session(http2_session_data *session_data) {
nghttp2_session_callbacks_new(&callbacks);
nghttp2_session_callbacks_set_send_callback2(callbacks, send_callback);
nghttp2_session_callbacks_set_send_callback(callbacks, send_callback);
nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks,
on_frame_recv_callback);
@@ -675,7 +702,14 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
ssl = bufferevent_openssl_get_ssl(session_data->bev);
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
@@ -727,7 +761,7 @@ static void start_listen(struct event_base *evbase, const char *service,
hints.ai_flags = AI_PASSIVE;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif /* defined(AI_ADDRCONFIG) */
#endif /* AI_ADDRCONFIG */
rv = getaddrinfo(NULL, service, &hints, &res);
if (rv != 0) {
@@ -736,8 +770,8 @@ static void start_listen(struct event_base *evbase, const char *service,
for (rp = res; rp; rp = rp->ai_next) {
struct evconnlistener *listener;
listener = evconnlistener_new_bind(
evbase, acceptcb, app_ctx, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 16,
rp->ai_addr, (int)rp->ai_addrlen);
evbase, acceptcb, app_ctx, LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE,
16, rp->ai_addr, (int)rp->ai_addrlen);
if (listener) {
freeaddrinfo(res);
@@ -783,6 +817,19 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
/* No explicit initialization is required. */
#elif defined(OPENSSL_IS_BORINGSSL)
CRYPTO_library_init();
#else /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
OPENSSL_config(NULL);
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x1010000fL) && \
!defined(OPENSSL_IS_BORINGSSL) */
run(argv[1], argv[2], argv[3]);
return 0;
}

View File

@@ -40,7 +40,7 @@ namespace {
void send_pending(nghttp2_session *session) {
for (;;) {
const uint8_t *data;
auto n = nghttp2_session_mem_send2(session, &data);
auto n = nghttp2_session_mem_send(session, &data);
if (n == 0) {
return;
}
@@ -70,7 +70,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
nghttp2_settings_entry iv{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100};
nghttp2_submit_settings(session, NGHTTP2_FLAG_NONE, &iv, 1);
send_pending(session);
nghttp2_session_mem_recv2(session, data, size);
nghttp2_session_mem_recv(session, data, size);
send_pending(session);
nghttp2_session_del(session);

View File

@@ -44,7 +44,7 @@ namespace {
void send_pending(nghttp2_session *session) {
for (;;) {
const uint8_t *data;
auto n = nghttp2_session_mem_send2(session, &data);
auto n = nghttp2_session_mem_send(session, &data);
if (n == 0) {
return;
}
@@ -87,7 +87,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
send_pending(session);
std::vector<uint8_t> d = data_provider.ConsumeRemainingBytes<uint8_t>();
nghttp2_session_mem_recv2(session, d.data(), d.size());
nghttp2_session_mem_recv(session, d.data(), d.size());
send_pending(session);

View File

@@ -35,7 +35,6 @@ HEADERS = [
"early-data",
"sec-websocket-accept",
"sec-websocket-key",
"priority",
# disallowed h1 headers
'connection',
'keep-alive',

View File

@@ -200,11 +200,6 @@ OPTIONS = [
"frontend-quic-initial-rtt",
"require-http-scheme",
"tls-ktls",
"alpn-list",
"frontend-header-timeout",
"frontend-http2-idle-timeout",
"frontend-http3-idle-timeout",
"groups",
]
LOGVARS = [
@@ -242,5 +237,5 @@ LOGVARS = [
]
if __name__ == '__main__':
gentokenlookup(OPTIONS, 'SHRPX_OPTID_', comp_fun='util::strieq')
gentokenlookup(LOGVARS, 'LogFragmentType::', comp_fun='util::strieq', return_type='LogFragmentType', fail_value='LogFragmentType::NONE')
gentokenlookup(OPTIONS, 'SHRPX_OPTID_', value_type='char', comp_fun='util::strieq_l')
gentokenlookup(LOGVARS, 'LogFragmentType::', value_type='char', comp_fun='util::strieq_l', return_type='LogFragmentType', fail_value='LogFragmentType::NONE')

View File

@@ -33,10 +33,10 @@ enum {''')
{}MAXIDX,
}};'''.format(prefix))
def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
def gen_index_header(tokens, prefix, value_type, comp_fun, return_type, fail_value):
print('''\
{} lookup_token(const std::string_view &name) {{
switch (name.size()) {{'''.format(return_type))
{} lookup_token(const {} *name, size_t namelen) {{
switch (namelen) {{'''.format(return_type, value_type))
b = build_header(tokens)
for size in sorted(b.keys()):
ents = b[size]
@@ -50,7 +50,7 @@ def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
case '{}':'''.format(c))
for k in headers:
print('''\
if ({}("{}"sv, name.substr(0, {}))) {{
if ({}("{}", name, {})) {{
return {};
}}'''.format(comp_fun, k[:-1], size - 1, to_enum_hd(k, prefix)))
print('''\
@@ -63,7 +63,7 @@ def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
return {};
}}'''.format(fail_value))
def gentokenlookup(tokens, prefix, comp_fun='util::streq', return_type='int', fail_value='-1'):
def gentokenlookup(tokens, prefix, value_type='uint8_t', comp_fun='util::streq_l', return_type='int', fail_value='-1'):
gen_enum(tokens, prefix)
print()
gen_index_header(tokens, prefix, comp_fun, return_type, fail_value)
gen_index_header(tokens, prefix, value_type, comp_fun, return_type, fail_value)

30
go.mod
View File

@@ -1,20 +1,26 @@
module github.com/nghttp2/nghttp2
go 1.24.0
go 1.18
require (
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
github.com/quic-go/quic-go v0.55.0
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8
golang.org/x/net v0.46.0
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d
github.com/lucas-clemente/quic-go v0.30.0
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20150408091349-4742878d9c90
golang.org/x/net v0.0.0-20220722155237-a158d28d115b
)
require (
github.com/quic-go/qpack v0.5.1 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.37.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/marten-seemann/qpack v0.3.0 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
github.com/onsi/ginkgo/v2 v2.2.0 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.12 // indirect
)

102
go.sum
View File

@@ -1,34 +1,78 @@
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw=
github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/lucas-clemente/quic-go v0.30.0 h1:nwLW0h8ahVQ5EPTIM7uhl/stHqQDea15oRlYKZmw2O0=
github.com/lucas-clemente/quic-go v0.30.0/go.mod h1:ssOrRsOmdxa768Wr78vnh2B8JozgLsMzG/g+0qEC7uk=
github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE=
github.com/marten-seemann/qpack v0.3.0/go.mod h1:cGfKPBiP4a9EQdxCwEwI/GEeWAsjSekBvx/X8mh58+g=
github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI=
github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE=
github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI=
github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8 h1:zKJxuRe+a0O34V81GAZWOrotuU6mveT30QLjJ7OPMMg=
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8/go.mod h1:gTqc3Q4boc+cKRlSFywTYdX9t6VGRcsThlNIWwaL3Dc=
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20150408091349-4742878d9c90 h1:ccVm9C6f5YMcVv6t9MXahIDkqVvzD6vklkJTIE4D2nY=
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20150408091349-4742878d9c90/go.mod h1:YZhsh86DfZgAShPKeg1eBLVrmuQxWcR9H4TdpgNvSnw=
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.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
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.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
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=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/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.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
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=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -2,7 +2,6 @@ set(GO_FILES
nghttpx_http1_test.go
nghttpx_http2_test.go
server_tester.go
server_tester_http3.go
)
# XXX unused
@@ -19,6 +18,12 @@ set(EXTRA_DIST
resp-return.rb
)
add_custom_target(itprep
COMMAND go get -d -v golang.org/x/net/http2
COMMAND go get -d -v github.com/tatsuhiro-t/go-nghttp2
COMMAND go get -d -v golang.org/x/net/websocket
)
# 'go test' requires both config.go and the test files in the same directory.
# For out-of-tree builds, config.go is normally not placed next to the source
# files, so copy the tests to the build directory as a workaround.
@@ -35,11 +40,7 @@ if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
endforeach()
endif()
if(ENABLE_HTTP3)
set(GO_TEST_TAGS quic)
endif()
add_custom_target(it
COMMAND sh setenv go test -v --tags=${GO_TEST_TAGS}
COMMAND sh setenv go test -v
DEPENDS ${GO_BUILD_FILES}
)

View File

@@ -25,8 +25,7 @@ GO_FILES = \
nghttpx_http1_test.go \
nghttpx_http2_test.go \
nghttpx_http3_test.go \
server_tester.go \
server_tester_http3.go
server_tester.go
EXTRA_DIST = \
CMakeLists.txt \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,6 @@ package nghttp2
import (
"bytes"
"crypto/rand"
"errors"
"io"
"net/http"
"regexp"
@@ -36,14 +35,13 @@ func TestH3H1PlainGET(t *testing.T) {
// TestH3H1RequestBody tests HTTP/3 request with body works.
func TestH3H1RequestBody(t *testing.T) {
body := make([]byte, 3333)
_, err := rand.Read(body)
if err != nil {
t.Fatalf("Unable to create request body: %v", err)
}
opts := options{
handler: func(_ http.ResponseWriter, r *http.Request) {
handler: func(w http.ResponseWriter, r *http.Request) {
buf := make([]byte, 4096)
buflen := 0
p := buf
@@ -59,7 +57,7 @@ func TestH3H1RequestBody(t *testing.T) {
buflen += n
if err != nil {
if errors.Is(err, io.EOF) {
if err == io.EOF {
break
}
@@ -75,7 +73,6 @@ func TestH3H1RequestBody(t *testing.T) {
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -86,7 +83,6 @@ func TestH3H1RequestBody(t *testing.T) {
if err != nil {
t.Fatalf("Error st.http3() = %v", err)
}
if got, want := res.status, http.StatusOK; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
@@ -96,14 +92,13 @@ func TestH3H1RequestBody(t *testing.T) {
// and from backend server.
func TestH3H1GenerateVia(t *testing.T) {
opts := options{
handler: func(_ http.ResponseWriter, r *http.Request) {
handler: func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("Via"), "3 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -113,7 +108,6 @@ func TestH3H1GenerateVia(t *testing.T) {
if err != nil {
t.Fatalf("Error st.http3() = %v", err)
}
if got, want := res.header.Get("Via"), "1.1 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
@@ -131,7 +125,6 @@ func TestH3H1AppendVia(t *testing.T) {
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -144,7 +137,6 @@ func TestH3H1AppendVia(t *testing.T) {
if err != nil {
t.Fatalf("Error st.http3() = %v", err)
}
if got, want := res.header.Get("Via"), "bar, 1.1 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
@@ -163,7 +155,6 @@ func TestH3H1NoVia(t *testing.T) {
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -176,7 +167,6 @@ func TestH3H1NoVia(t *testing.T) {
if err != nil {
t.Fatalf("Error st.http3() = %v", err)
}
if got, want := res.header.Get("Via"), "bar"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
@@ -187,7 +177,7 @@ func TestH3H1NoVia(t *testing.T) {
// response body size.
func TestH3H1BadResponseCL(t *testing.T) {
opts := options{
handler: func(w http.ResponseWriter, _ *http.Request) {
handler: func(w http.ResponseWriter, r *http.Request) {
// we set content-length: 1024, but only send 3 bytes.
w.Header().Add("Content-Length", "1024")
if _, err := w.Write([]byte("foo")); err != nil {
@@ -196,7 +186,6 @@ func TestH3H1BadResponseCL(t *testing.T) {
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -215,7 +204,6 @@ func TestH3H1HTTPSRedirect(t *testing.T) {
args: []string{"--redirect-if-not-tls"},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -238,7 +226,6 @@ func TestH3H1AffinityCookieTLS(t *testing.T) {
args: []string{"--affinity-cookie"},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -256,7 +243,6 @@ func TestH3H1AffinityCookieTLS(t *testing.T) {
const pattern = `affinity=[0-9a-f]{8}; Path=/foo/bar; Secure`
validCookie := regexp.MustCompile(pattern)
if got := res.header.Get("Set-Cookie"); !validCookie.MatchString(got) {
t.Errorf("Set-Cookie: %v; want pattern %v", got, pattern)
}
@@ -270,12 +256,11 @@ func TestH3H2ReqPhaseReturn(t *testing.T) {
"--http2-bridge",
"--mruby-file=" + testDir + "/req-return.rb",
},
handler: func(http.ResponseWriter, *http.Request) {
handler: func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -317,7 +302,6 @@ func TestH3H2RespPhaseReturn(t *testing.T) {
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -354,12 +338,11 @@ func TestH3H2RespPhaseReturn(t *testing.T) {
func TestH3ResponseBeforeRequestEnd(t *testing.T) {
opts := options{
args: []string{"--mruby-file=" + testDir + "/req-return.rb"},
handler: func(http.ResponseWriter, *http.Request) {
handler: func(w http.ResponseWriter, r *http.Request) {
t.Fatal("request should not be forwarded")
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()
@@ -370,7 +353,6 @@ func TestH3ResponseBeforeRequestEnd(t *testing.T) {
if err != nil {
t.Fatalf("Error st.http3() = %v", err)
}
if got, want := res.status, http.StatusNotFound; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
@@ -380,7 +362,7 @@ func TestH3ResponseBeforeRequestEnd(t *testing.T) {
// backend chunked encoded response ends prematurely.
func TestH3H1ChunkedEndsPrematurely(t *testing.T) {
opts := options{
handler: func(w http.ResponseWriter, _ *http.Request) {
handler: func(w http.ResponseWriter, r *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
@@ -399,7 +381,6 @@ func TestH3H1ChunkedEndsPrematurely(t *testing.T) {
},
quic: true,
}
st := newServerTester(t, opts)
defer st.Close()

View File

@@ -3,7 +3,6 @@ package nghttp2
import (
"bufio"
"bytes"
"cmp"
"context"
"crypto/tls"
"encoding/binary"
@@ -16,13 +15,14 @@ import (
"net/url"
"os"
"os/exec"
"slices"
"sort"
"strconv"
"strings"
"syscall"
"testing"
"time"
"github.com/lucas-clemente/quic-go/http3"
"github.com/tatsuhiro-t/go-nghttp2"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
@@ -95,17 +95,14 @@ func newServerTester(t *testing.T, opts options) *serverTester {
if opts.handler == nil {
opts.handler = noopHandler
}
if opts.connectPort == 0 {
opts.connectPort = serverPort
}
ts := httptest.NewUnstartedServer(opts.handler)
var (
args []string
backendTLS, dns, externalDNS, acceptProxyProtocol, redirectIfNotTLS, affinityCookie, alpnH1 bool
)
var args []string
var backendTLS, dns, externalDNS, acceptProxyProtocol, redirectIfNotTLS, affinityCookie, alpnH1 bool
for _, k := range opts.args {
switch k {
@@ -128,7 +125,6 @@ func newServerTester(t *testing.T, opts options) *serverTester {
args = append(args, k)
}
}
if backendTLS {
nghttp2.ConfigureServer(ts.Config, &nghttp2.Server{})
// According to httptest/server.go, we have to set
@@ -137,17 +133,13 @@ func newServerTester(t *testing.T, opts options) *serverTester {
ts.TLS = new(tls.Config)
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
ts.StartTLS()
args = append(args, "-k")
} else {
ts.Start()
}
scheme := "http"
if opts.tls {
scheme = "https"
args = append(args, testDir+"/server.key", testDir+"/server.crt")
}
@@ -159,25 +151,20 @@ func newServerTester(t *testing.T, opts options) *serverTester {
// URL.Host looks like "127.0.0.1:8080", but we want
// "127.0.0.1,8080"
b := "-b"
if !externalDNS {
b += fmt.Sprintf("%v;", strings.ReplaceAll(backendURL.Host, ":", ","))
b += fmt.Sprintf("%v;", strings.Replace(backendURL.Host, ":", ",", -1))
} else {
sep := strings.LastIndex(backendURL.Host, ":")
if sep == -1 {
t.Fatalf("backendURL.Host %v does not contain separator ':'", backendURL.Host)
}
// We use awesome service nip.io.
b += fmt.Sprintf("%v.nip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
// Make external DNS tests less flaky.
args = append(args, "--backend-address-family=IPv4")
}
if backendTLS {
b += ";proto=h2;tls"
}
if dns {
b += ";dns"
}
@@ -191,13 +178,11 @@ func newServerTester(t *testing.T, opts options) *serverTester {
}
noTLS := ";no-tls"
if opts.tls {
noTLS = ""
}
var proxyProto string
if acceptProxyProtocol {
proxyProto = ";proxyproto"
}
@@ -208,19 +193,7 @@ func newServerTester(t *testing.T, opts options) *serverTester {
if opts.quic {
args = append(args,
fmt.Sprintf("-f127.0.0.1,%v;quic", serverPort),
"--no-quic-bpf",
// quic-go client just closes connection after
// receiving the first GOAWAY without any
// indication like sending CONNECTION_CLOSE if
// there is no active stream. If that
// happens, server keeps resending 2nd GOAWAY
// until idle timeout passes. If that happens
// during Close(), the process will be killed
// because the default idle timeout is longer
// than the close timeout. Shorten the idle
// timeout to prevent it from happening.
"--frontend-quic-idle-timeout=5",
)
"--no-quic-bpf")
}
authority := fmt.Sprintf("127.0.0.1:%v", opts.connectPort)
@@ -246,7 +219,6 @@ func newServerTester(t *testing.T, opts options) *serverTester {
}
retry := 0
for {
time.Sleep(50 * time.Millisecond)
@@ -260,41 +232,32 @@ func newServerTester(t *testing.T, opts options) *serverTester {
}
var tlsConfig *tls.Config
if opts.tlsConfig == nil {
tlsConfig = new(tls.Config)
} else {
tlsConfig = opts.tlsConfig.Clone()
}
tlsConfig.InsecureSkipVerify = true
if alpnH1 {
tlsConfig.NextProtos = []string{"http/1.1"}
} else {
tlsConfig.NextProtos = []string{"h2"}
}
tlsConn := tls.Client(conn, tlsConfig)
err = tlsConn.Handshake()
if err == nil {
conn = tlsConn
}
}
if err != nil {
retry++
if retry >= 100 {
st.Close()
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
}
continue
}
st.conn = conn
break
}
@@ -311,15 +274,12 @@ func (st *serverTester) Close() {
if st.conn != nil {
st.conn.Close()
}
if st.cmd != nil {
done := make(chan struct{})
go func() {
if err := st.cmd.Wait(); err != nil {
st.t.Errorf("Error st.cmd.Wait() = %v", err)
}
close(done)
}()
@@ -333,11 +293,9 @@ func (st *serverTester) Close() {
if err := st.cmd.Process.Kill(); err != nil {
st.t.Errorf("Error st.cmd.Process.Kill() = %v", err)
}
<-done
}
}
if st.ts != nil {
st.ts.Close()
}
@@ -350,7 +308,6 @@ func (st *serverTester) readFrame() (http2.Frame, error) {
st.errCh <- err
return
}
st.frCh <- f
}()
@@ -391,12 +348,10 @@ func (cbr *chunkedBodyReader) Read(p []byte) (n int, err error) {
// after request was sent and before body returns EOF.
if !cbr.trailerWritten {
cbr.trailerWritten = true
for _, h := range cbr.trailer {
cbr.req.Trailer.Set(h.Name, h.Value)
}
}
return cbr.body.Read(p)
}
@@ -409,7 +364,6 @@ func (st *serverTester) websocket(rp requestParam) *serverResponse {
}
config.Header.Add("Test-Case", rp.name)
for _, h := range rp.header {
config.Header.Add(h.Name, h.Value)
}
@@ -424,9 +378,7 @@ func (st *serverTester) websocket(rp requestParam) *serverResponse {
}
msg := make([]byte, 1024)
var n int
if n, err = ws.Read(msg); err != nil {
st.t.Fatalf("ws.Read() returned error: %v", err)
}
@@ -438,29 +390,28 @@ func (st *serverTester) websocket(rp requestParam) *serverResponse {
return res
}
func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
method := "GET"
func (st *serverTester) http3(rp requestParam) (*serverResponse, error) {
rt := &http3.RoundTripper{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
defer rt.Close()
c := &http.Client{
Transport: rt,
}
method := "GET"
if rp.method != "" {
method = rp.method
}
var (
body io.Reader
cbr *chunkedBodyReader
)
var body io.Reader
if rp.body != nil {
body = bytes.NewBuffer(rp.body)
if len(rp.trailer) != 0 {
cbr = &chunkedBodyReader{
trailer: rp.trailer,
body: body,
}
body = cbr
}
}
reqURL := st.url
@@ -470,7 +421,6 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
if err != nil {
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
}
u.Path = ""
u.RawQuery = ""
reqURL = u.String() + rp.path
@@ -490,31 +440,93 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
req.Header.Add("Test-Case", rp.name)
if cbr != nil {
cbr.req = req
// this makes request use chunked encoding
req.ContentLength = -1
req.Trailer = make(http.Header)
// TODO http3 package does not support trailer at the time of
// this writing.
for _, h := range cbr.trailer {
req.Trailer.Set(h.Name, "")
}
}
if err := req.Write(st.conn); err != nil {
return nil, err
}
resp, err := http.ReadResponse(bufio.NewReader(st.conn), req)
resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
res := &serverResponse{
status: resp.StatusCode,
header: resp.Header,
body: respBody,
connClose: resp.Close,
}
return res, nil
}
func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
method := "GET"
if rp.method != "" {
method = rp.method
}
var body io.Reader
var cbr *chunkedBodyReader
if rp.body != nil {
body = bytes.NewBuffer(rp.body)
if len(rp.trailer) != 0 {
cbr = &chunkedBodyReader{
trailer: rp.trailer,
body: body,
}
body = cbr
}
}
reqURL := st.url
if rp.path != "" {
u, err := url.Parse(st.url)
if err != nil {
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
}
u.Path = ""
u.RawQuery = ""
reqURL = u.String() + rp.path
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, method, reqURL, body)
if err != nil {
return nil, err
}
for _, h := range rp.header {
req.Header.Add(h.Name, h.Value)
}
req.Header.Add("Test-Case", rp.name)
if cbr != nil {
cbr.req = req
// this makes request use chunked encoding
req.ContentLength = -1
req.Trailer = make(http.Header)
for _, h := range cbr.trailer {
req.Trailer.Set(h.Name, "")
}
}
if err := req.Write(st.conn); err != nil {
return nil, err
}
resp, err := http.ReadResponse(bufio.NewReader(st.conn), req)
if err != nil {
return nil, err
}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
resp.Body.Close()
res := &serverResponse{
@@ -532,7 +544,6 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
st.header = make(http.Header)
var id uint32
if rp.streamID != 0 {
id = rp.streamID
if id >= st.nextStreamID && id%2 == 1 {
@@ -546,7 +557,6 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
if !st.h2PrefaceSent {
st.h2PrefaceSent = true
fmt.Fprint(st.conn, "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n")
if err := st.fr.WriteSettings(); err != nil {
return nil, err
}
@@ -564,32 +574,26 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
if rp.method != "" {
method = rp.method
}
_ = st.enc.WriteField(pair(":method", method))
scheme := "http"
if rp.scheme != "" {
scheme = rp.scheme
}
_ = st.enc.WriteField(pair(":scheme", scheme))
authority := st.authority
if rp.authority != "" {
authority = rp.authority
}
_ = st.enc.WriteField(pair(":authority", authority))
path := "/"
if rp.path != "" {
path = rp.path
}
_ = st.enc.WriteField(pair(":path", path))
_ = st.enc.WriteField(pair("test-case", rp.name))
for _, h := range rp.header {
@@ -615,11 +619,9 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
if len(rp.trailer) != 0 {
st.headerBlkBuf.Reset()
for _, h := range rp.trailer {
_ = st.enc.WriteField(h)
}
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
StreamID: id,
EndStream: true,
@@ -637,65 +639,56 @@ loop:
if err != nil {
return res, err
}
switch f := fr.(type) {
case *http2.HeadersFrame:
_, err := st.dec.Write(f.HeaderBlockFragment())
if err != nil {
return res, err
}
sr, ok := streams[f.StreamID]
sr, ok := streams[f.FrameHeader.StreamID]
if !ok {
st.header = make(http.Header)
break
}
sr.header = cloneHeader(st.header)
var status int
status, err = strconv.Atoi(sr.header.Get(":status"))
if err != nil {
return res, fmt.Errorf("could not parse :status: %w", err)
return res, fmt.Errorf("Error parsing status code: %w", err)
}
sr.status = status
if f.StreamEnded() && streamEnded(res, streams, sr) {
if f.StreamEnded() {
if streamEnded(res, streams, sr) {
break loop
}
}
case *http2.PushPromiseFrame:
_, err := st.dec.Write(f.HeaderBlockFragment())
if err != nil {
return res, err
}
sr := &serverResponse{
streamID: f.PromiseID,
reqHeader: cloneHeader(st.header),
}
streams[sr.streamID] = sr
case *http2.DataFrame:
sr, ok := streams[f.StreamID]
sr, ok := streams[f.FrameHeader.StreamID]
if !ok {
break
}
sr.body = append(sr.body, f.Data()...)
if f.StreamEnded() && streamEnded(res, streams, sr) {
if f.StreamEnded() {
if streamEnded(res, streams, sr) {
break loop
}
}
case *http2.RSTStreamFrame:
sr, ok := streams[f.StreamID]
sr, ok := streams[f.FrameHeader.StreamID]
if !ok {
break
}
sr.errCode = f.ErrCode
if streamEnded(res, streams, sr) {
break loop
}
@@ -703,36 +696,27 @@ loop:
if f.ErrCode == http2.ErrCodeNo {
break
}
res.errCode = f.ErrCode
res.connErr = true
break loop
case *http2.SettingsFrame:
if f.IsAck() {
break
}
if err := st.fr.WriteSettingsAck(); err != nil {
return res, err
}
}
}
slices.SortFunc(res.pushResponse, func(a, b *serverResponse) int {
return cmp.Compare(a.streamID, b.streamID)
})
sort.Sort(ByStreamID(res.pushResponse))
return res, nil
}
func streamEnded(mainSr *serverResponse, streams map[uint32]*serverResponse, sr *serverResponse) bool {
delete(streams, sr.streamID)
if mainSr.streamID != sr.streamID {
mainSr.pushResponse = append(mainSr.pushResponse, sr)
}
return len(streams) == 0
}
@@ -744,19 +728,31 @@ type serverResponse struct {
errCode http2.ErrCode // error code received in HTTP/2 RST_STREAM or GOAWAY
connErr bool // true if HTTP/2 connection error
connClose bool // Connection: close is included in response header in HTTP/1 test
reqHeader http.Header // http request header, currently only stores pushed request header
reqHeader http.Header // http request header, currently only sotres pushed request header
pushResponse []*serverResponse // pushed response
}
type ByStreamID []*serverResponse
func (b ByStreamID) Len() int {
return len(b)
}
func (b ByStreamID) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
func (b ByStreamID) Less(i, j int) bool {
return b[i].streamID < b[j].streamID
}
func cloneHeader(h http.Header) http.Header {
h2 := make(http.Header, len(h))
for k, vv := range h {
vv2 := make([]string, len(vv))
copy(vv2, vv)
h2[k] = vv2
}
return h2
}
@@ -807,7 +803,6 @@ func writeProxyProtocolV2(w io.Writer, hdr proxyProtocolV2) error {
if _, err := w.Write([]byte{0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, 0x55, 0x49, 0x54, 0x0A}); err != nil {
return err
}
if _, err := w.Write([]byte{byte(0x20 | hdr.command)}); err != nil {
return err
}
@@ -815,59 +810,44 @@ func writeProxyProtocolV2(w io.Writer, hdr proxyProtocolV2) error {
switch srcAddr := hdr.sourceAddress.(type) {
case *net.TCPAddr:
dstAddr := hdr.destinationAddress.(*net.TCPAddr)
if len(srcAddr.IP) != len(dstAddr.IP) {
panic("len(srcAddr.IP) != len(dstAddr.IP)")
}
var fam byte
if len(srcAddr.IP) == 4 {
fam = byte(proxyProtocolV2FamilyInet << 4)
} else {
fam = byte(proxyProtocolV2FamilyInet6 << 4)
}
fam |= byte(proxyProtocolV2ProtocolStream)
if _, err := w.Write([]byte{fam}); err != nil {
return err
}
length := uint16(len(srcAddr.IP)*2 + 4 + len(hdr.additionalData))
if err := binary.Write(w, binary.BigEndian, length); err != nil {
return err
}
if _, err := w.Write(srcAddr.IP); err != nil {
return err
}
if _, err := w.Write(dstAddr.IP); err != nil {
return err
}
if err := binary.Write(w, binary.BigEndian, uint16(srcAddr.Port)); err != nil {
return err
}
if err := binary.Write(w, binary.BigEndian, uint16(dstAddr.Port)); err != nil {
return err
}
case *net.UnixAddr:
dstAddr := hdr.destinationAddress.(*net.UnixAddr)
if len(srcAddr.Name) > 108 {
panic("too long Unix source address")
}
if len(dstAddr.Name) > 108 {
panic("too long Unix destination address")
}
fam := byte(proxyProtocolV2FamilyUnix << 4)
switch srcAddr.Net {
case "unix":
fam |= byte(proxyProtocolV2ProtocolStream)
@@ -876,43 +856,32 @@ func writeProxyProtocolV2(w io.Writer, hdr proxyProtocolV2) error {
default:
fam |= byte(proxyProtocolV2ProtocolUnspec)
}
if _, err := w.Write([]byte{fam}); err != nil {
return err
}
length := uint16(216 + len(hdr.additionalData))
if err := binary.Write(w, binary.BigEndian, length); err != nil {
return err
}
zeros := make([]byte, 108)
if _, err := w.Write([]byte(srcAddr.Name)); err != nil {
return err
}
if _, err := w.Write(zeros[:108-len(srcAddr.Name)]); err != nil {
return err
}
if _, err := w.Write([]byte(dstAddr.Name)); err != nil {
return err
}
if _, err := w.Write(zeros[:108-len(dstAddr.Name)]); err != nil {
return err
}
default:
fam := byte(proxyProtocolV2FamilyUnspec<<4) | byte(proxyProtocolV2ProtocolUnspec)
if _, err := w.Write([]byte{fam}); err != nil {
return err
}
length := uint16(len(hdr.additionalData))
if err := binary.Write(w, binary.BigEndian, length); err != nil {
return err
}

View File

@@ -1,91 +0,0 @@
//go:build quic
package nghttp2
import (
"bytes"
"context"
"crypto/tls"
"io"
"net/http"
"net/url"
"time"
"github.com/quic-go/quic-go/http3"
)
func (st *serverTester) http3(rp requestParam) (*serverResponse, error) {
rt := &http3.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
defer rt.Close()
c := &http.Client{
Transport: rt,
}
method := "GET"
if rp.method != "" {
method = rp.method
}
var body io.Reader
if rp.body != nil {
body = bytes.NewBuffer(rp.body)
}
reqURL := st.url
if rp.path != "" {
u, err := url.Parse(st.url)
if err != nil {
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
}
u.Path = ""
u.RawQuery = ""
reqURL = u.String() + rp.path
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, method, reqURL, body)
if err != nil {
return nil, err
}
for _, h := range rp.header {
req.Header.Add(h.Name, h.Value)
}
req.Header.Add("Test-Case", rp.name)
// TODO http3 package does not support trailer at the time of
// this writing.
resp, err := c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
res := &serverResponse{
status: resp.StatusCode,
header: resp.Header,
body: respBody,
connClose: resp.Close,
}
return res, nil
}

View File

@@ -9,6 +9,5 @@ export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/incl
export CGO_CPPFLAGS="@CPPFLAGS@"
export CGO_LDFLAGS="-L$libdir @LDFLAGS@"
export LD_LIBRARY_PATH="$libdir"
export DYLD_LIBRARY_PATH="$libdir"
export GODEBUG=cgocheck=0
"$@"

View File

@@ -14,7 +14,7 @@ set(NGHTTP2_SOURCES
nghttp2_stream.c nghttp2_outbound_item.c
nghttp2_session.c nghttp2_submit.c
nghttp2_helper.c
nghttp2_alpn.c
nghttp2_npn.c
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
nghttp2_version.c
nghttp2_priority_spec.c
@@ -24,19 +24,10 @@ set(NGHTTP2_SOURCES
nghttp2_http.c
nghttp2_rcbuf.c
nghttp2_extpri.c
nghttp2_ratelim.c
nghttp2_time.c
nghttp2_debug.c
sfparse.c
)
set(NGHTTP2_RES "")
set(STATIC_LIB "nghttp2_static")
set(SHARED_LIB "nghttp2")
if(BUILD_SHARED_LIBS AND BUILD_STATIC_LIBS AND MSVC AND NOT STATIC_LIB_SUFFIX)
set(STATIC_LIB_SUFFIX "_static")
endif()
if(WIN32)
configure_file(
@@ -47,85 +38,40 @@ if(WIN32)
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
endif()
set(NGHTTP2_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(NGHTTP2_VERSION_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(NGHTTP2_PROJECT_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
set(NGHTTP2_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(NGHTTP2_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(NGHTTP2_NAMESPACE "${PROJECT_NAME}::")
set(NGHTTP2_VERSION ${PROJECT_VERSION})
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${NGHTTP2_VERSION_CONFIG}" VERSION ${NGHTTP2_VERSION} COMPATIBILITY SameMajorVersion
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in" "${NGHTTP2_PROJECT_CONFIG}" @ONLY)
# Install cmake config files
install(
FILES "${NGHTTP2_PROJECT_CONFIG}" "${NGHTTP2_VERSION_CONFIG}"
DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
install(
EXPORT "${NGHTTP2_TARGETS_EXPORT_NAME}"
NAMESPACE "${NGHTTP2_NAMESPACE}"
DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
# Public shared library
if(BUILD_SHARED_LIBS)
add_library(${SHARED_LIB} SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
set_target_properties(${SHARED_LIB} PROPERTIES
if(ENABLE_SHARED_LIB)
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
set_target_properties(nghttp2 PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden
)
target_include_directories(${SHARED_LIB} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/includes>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
target_include_directories(nghttp2 INTERFACE
"${CMAKE_CURRENT_BINARY_DIR}/includes"
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
)
install(TARGETS ${SHARED_LIB}
EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
install(TARGETS nghttp2
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
list(APPEND nghttp2_exports ${SHARED_LIB})
endif()
# Static library (for unittests because of symbol visibility)
if(BUILD_STATIC_LIBS)
add_library(${STATIC_LIB} STATIC ${NGHTTP2_SOURCES})
set_target_properties(${STATIC_LIB} PROPERTIES
if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
# Static library (for unittests because of symbol visibility)
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
set_target_properties(nghttp2_static PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
ARCHIVE_OUTPUT_NAME nghttp2${STATIC_LIB_SUFFIX}
)
target_include_directories(${STATIC_LIB} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/includes>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/includes>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB")
install(TARGETS ${STATIC_LIB}
EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
list(APPEND nghttp2_exports ${STATIC_LIB})
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
if(ENABLE_STATIC_LIB)
install(TARGETS nghttp2_static
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
endif()
if(BUILD_SHARED_LIBS)
set(LIB_SELECTED ${SHARED_LIB})
else()
set(LIB_SELECTED ${STATIC_LIB})
endif()
add_library(nghttp2 ALIAS ${LIB_SELECTED})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

View File

@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = includes
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
@@ -41,7 +41,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_stream.c nghttp2_outbound_item.c \
nghttp2_session.c nghttp2_submit.c \
nghttp2_helper.c \
nghttp2_alpn.c \
nghttp2_npn.c \
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c \
nghttp2_version.c \
nghttp2_priority_spec.c \
@@ -51,16 +51,13 @@ 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
nghttp2_debug.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
nghttp2_buf.h \
nghttp2_session.h nghttp2_helper.h nghttp2_stream.h nghttp2_int.h \
nghttp2_alpn.h \
nghttp2_npn.h \
nghttp2_submit.h nghttp2_outbound_item.h \
nghttp2_net.h \
nghttp2_hd.h nghttp2_hd_huffman.h \
@@ -71,10 +68,7 @@ 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
nghttp2_debug.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \

View File

@@ -74,7 +74,7 @@ NGHTTP2_SRC := nghttp2_pq.c \
nghttp2_session.c \
nghttp2_submit.c \
nghttp2_helper.c \
nghttp2_alpn.c \
nghttp2_npn.c \
nghttp2_hd.c \
nghttp2_hd_huffman.c \
nghttp2_hd_huffman_data.c \

View File

@@ -1,3 +0,0 @@
include(CMakeFindDependencyMacro)
include("${CMAKE_CURRENT_LIST_DIR}/@NGHTTP2_TARGETS_EXPORT_NAME@.cmake")

File diff suppressed because it is too large Load Diff

View File

@@ -61,7 +61,7 @@ int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem) {
return 0;
}
new_cap = nghttp2_max_size(new_cap, cap * 2);
new_cap = nghttp2_max(new_cap, cap * 2);
ptr = nghttp2_mem_realloc(mem, buf->begin, new_cap);
if (ptr == NULL) {
@@ -343,7 +343,7 @@ int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) {
while (len) {
buf = &bufs->cur->buf;
nwrite = nghttp2_min_size(nghttp2_buf_avail(buf), len);
nwrite = nghttp2_min(nghttp2_buf_avail(buf), len);
if (nwrite == 0) {
rv = bufs_alloc_chain(bufs);
if (rv != 0) {
@@ -430,7 +430,7 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b) {
return 0;
}
nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
size_t len;
nghttp2_buf_chain *chain;
nghttp2_buf *buf;
@@ -462,7 +462,7 @@ nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
*out = res;
return (nghttp2_ssize)len;
return (ssize_t)len;
}
size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) {

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
@@ -349,7 +349,7 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
* NGHTTP2_ERR_NOMEM
* Out of memory
*/
nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
/*
* Copies all data stored in |bufs| to |out|. This function assumes
@@ -409,4 +409,4 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
*/
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
#endif /* !defined(NGHTTP2_BUF_H) */
#endif /* NGHTTP2_BUF_H */

View File

@@ -45,21 +45,11 @@ void nghttp2_session_callbacks_set_send_callback(
cbs->send_callback = send_callback;
}
void nghttp2_session_callbacks_set_send_callback2(
nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) {
cbs->send_callback2 = send_callback;
}
void nghttp2_session_callbacks_set_recv_callback(
nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) {
cbs->recv_callback = recv_callback;
}
void nghttp2_session_callbacks_set_recv_callback2(
nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) {
cbs->recv_callback2 = recv_callback;
}
void nghttp2_session_callbacks_set_on_frame_recv_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_frame_recv_callback on_frame_recv_callback) {
@@ -138,24 +128,12 @@ void nghttp2_session_callbacks_set_select_padding_callback(
cbs->select_padding_callback = select_padding_callback;
}
void nghttp2_session_callbacks_set_select_padding_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback2 select_padding_callback) {
cbs->select_padding_callback2 = select_padding_callback;
}
void nghttp2_session_callbacks_set_data_source_read_length_callback(
nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback data_source_read_length_callback) {
cbs->read_length_callback = data_source_read_length_callback;
}
void nghttp2_session_callbacks_set_data_source_read_length_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_data_source_read_length_callback2 data_source_read_length_callback) {
cbs->read_length_callback2 = data_source_read_length_callback;
}
void nghttp2_session_callbacks_set_on_begin_frame_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_begin_frame_callback on_begin_frame_callback) {
@@ -174,12 +152,6 @@ void nghttp2_session_callbacks_set_pack_extension_callback(
cbs->pack_extension_callback = pack_extension_callback;
}
void nghttp2_session_callbacks_set_pack_extension_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_pack_extension_callback2 pack_extension_callback) {
cbs->pack_extension_callback2 = pack_extension_callback;
}
void nghttp2_session_callbacks_set_unpack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_unpack_extension_callback unpack_extension_callback) {
@@ -201,8 +173,3 @@ void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
cbs->error_callback2 = error_callback2;
}
void nghttp2_session_callbacks_set_rand_callback(
nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) {
cbs->rand_callback = rand_callback;
}

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
@@ -36,33 +36,19 @@
*/
struct nghttp2_session_callbacks {
/**
* Deprecated. Use send_callback2 instead. Callback function
* invoked when the session wants to send data to the remote peer.
* This callback is not necessary if the application uses solely
* `nghttp2_session_mem_send()` to serialize data to transmit.
* Callback function invoked when the session wants to send data to
* the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_send()` to serialize
* data to transmit.
*/
nghttp2_send_callback send_callback;
/**
* Callback function invoked when the session wants to send data to
* the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_send2()` to
* serialize data to transmit.
*/
nghttp2_send_callback2 send_callback2;
/**
* Deprecated. Use recv_callback2 instead. Callback function
* invoked when the session wants to receive data from the remote
* peer. This callback is not necessary if the application uses
* solely `nghttp2_session_mem_recv()` to process received data.
*/
nghttp2_recv_callback recv_callback;
/**
* Callback function invoked when the session wants to receive data
* from the remote peer. This callback is not necessary if the
* application uses solely `nghttp2_session_mem_recv2()` to process
* application uses solely `nghttp2_session_mem_recv()` to process
* received data.
*/
nghttp2_recv_callback2 recv_callback2;
nghttp2_recv_callback recv_callback;
/**
* Callback function invoked by `nghttp2_session_recv()` when a
* frame is received.
@@ -113,45 +99,27 @@ struct nghttp2_session_callbacks {
*/
nghttp2_on_invalid_header_callback on_invalid_header_callback;
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
/**
* Deprecated. Use select_padding_callback2 instead. Callback
* function invoked when the library asks application how many
* padding bytes are required for the transmission of the given
* frame.
*/
nghttp2_select_padding_callback select_padding_callback;
/**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given
* frame.
*/
nghttp2_select_padding_callback2 select_padding_callback2;
nghttp2_select_padding_callback select_padding_callback;
/**
* Deprecated. Use read_length_callback2 instead. The callback
* function used to determine the length allowed in
* The callback function used to determine the length allowed in
* `nghttp2_data_source_read_callback()`
*/
nghttp2_data_source_read_length_callback read_length_callback;
/**
* The callback function used to determine the length allowed in
* `nghttp2_data_source_read_callback2()`
*/
nghttp2_data_source_read_length_callback2 read_length_callback2;
/**
* Sets callback function invoked when a frame header is received.
*/
nghttp2_on_begin_frame_callback on_begin_frame_callback;
nghttp2_send_data_callback send_data_callback;
/**
* Deprecated. Use pack_extension_callback2 instead.
*/
nghttp2_pack_extension_callback pack_extension_callback;
nghttp2_pack_extension_callback2 pack_extension_callback2;
nghttp2_unpack_extension_callback unpack_extension_callback;
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback;
nghttp2_error_callback2 error_callback2;
nghttp2_rand_callback rand_callback;
};
#endif /* !defined(NGHTTP2_CALLBACKS_H) */
#endif /* NGHTTP2_CALLBACKS_H */

View File

@@ -50,11 +50,11 @@ void nghttp2_set_debug_vprintf_callback(
static_debug_vprintf_callback = debug_vprintf_callback;
}
#else /* !defined(DEBUGBUILD) */
#else /* !DEBUGBUILD */
void nghttp2_set_debug_vprintf_callback(
nghttp2_debug_vprintf_callback debug_vprintf_callback) {
(void)debug_vprintf_callback;
}
#endif /* !defined(DEBUGBUILD) */
#endif /* !DEBUGBUILD */

View File

@@ -27,17 +27,17 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
#ifdef DEBUGBUILD
# define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
void nghttp2_debug_vprintf(const char *format, ...);
#else /* !defined(DEBUGBUILD) */
#else
# define DEBUGF(...) \
do { \
} while (0)
#endif /* !defined(DEBUGBUILD) */
#endif
#endif /* !defined(NGHTTP2_DEBUG_H) */
#endif /* NGHTTP2_DEBUG_H */

View File

@@ -24,7 +24,6 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "nghttp2_extpri.h"
#include "nghttp2_http.h"
uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri) {
return (uint8_t)((uint32_t)extpri->inc << 7 | extpri->urgency);
@@ -34,8 +33,3 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri) {
extpri->urgency = nghttp2_extpri_uint8_urgency(u8extpri);
extpri->inc = nghttp2_extpri_uint8_inc(u8extpri);
}
int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri, const uint8_t *value,
size_t len) {
return nghttp2_http_parse_priority(extpri, value, len);
}

View File

@@ -28,7 +28,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
@@ -60,6 +60,6 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri);
* nghttp2_extpri_uint8_inc extracts inc from |PRI| which is supposed to
* be constructed by nghttp2_extpri_to_uint8.
*/
#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0)
#define nghttp2_extpri_uint8_inc(PRI) (((PRI)&NGHTTP2_EXTPRI_INC_MASK) != 0)
#endif /* !defined(NGHTTP2_EXTPRI_H) */
#endif /* NGHTTP2_EXTPRI_H */

View File

@@ -418,7 +418,7 @@ void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive);
}
void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
const uint8_t *payload) {
if (frame->hd.flags & NGHTTP2_FLAG_PRIORITY) {
nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
@@ -428,9 +428,11 @@ void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
frame->nva = NULL;
frame->nvlen = 0;
return 0;
}
void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
nghttp2_buf *buf;
assert(bufs->head == bufs->cur);
@@ -446,6 +448,8 @@ void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
nghttp2_frame_pack_priority_spec(buf->last, &frame->pri_spec);
buf->last += NGHTTP2_PRIORITY_SPECLEN;
return 0;
}
void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
@@ -453,7 +457,7 @@ void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
}
void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
nghttp2_rst_stream *frame) {
nghttp2_buf *buf;
@@ -469,6 +473,8 @@ void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
nghttp2_put_uint32be(buf->last, frame->error_code);
buf->last += 4;
return 0;
}
void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
@@ -586,15 +592,16 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
return frame_pack_headers_shared(bufs, &frame->hd);
}
void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
const uint8_t *payload) {
frame->promised_stream_id =
nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
frame->nva = NULL;
frame->nvlen = 0;
return 0;
}
void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
nghttp2_buf *buf;
assert(bufs->head == bufs->cur);
@@ -609,6 +616,8 @@ void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
buf->last =
nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data));
return 0;
}
void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
@@ -688,7 +697,7 @@ int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
return 0;
}
void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
nghttp2_window_update *frame) {
nghttp2_buf *buf;
@@ -704,6 +713,8 @@ void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
nghttp2_put_uint32be(buf->last, (uint32_t)frame->window_size_increment);
buf->last += 4;
return 0;
}
void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
@@ -712,7 +723,7 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
}
void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
int rv;
nghttp2_buf *buf;
nghttp2_ext_altsvc *altsvc;
@@ -741,6 +752,8 @@ void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
assert(rv == 0);
return 0;
}
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
@@ -888,7 +901,7 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
return 0;
}
void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
nghttp2_extension *frame) {
int rv;
nghttp2_buf *buf;
@@ -914,6 +927,8 @@ void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
priority_update->field_value_len);
assert(rv == 0);
return 0;
}
void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
@@ -1171,14 +1186,14 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
buf->last += trail_padlen;
}
void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
size_t padlen, int framehd_only) {
nghttp2_buf *buf;
if (padlen == 0) {
DEBUGF("send: padlen = 0, nothing to do\n");
return;
return 0;
}
/*
@@ -1211,4 +1226,6 @@ void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
hd->flags |= NGHTTP2_FLAG_PADDED;
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
return 0;
}

View File

@@ -27,14 +27,17 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
#include "nghttp2_hd.h"
#include "nghttp2_buf.h"
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
/* The number of bytes of frame header. */
#define NGHTTP2_FRAME_HDLEN 9
@@ -140,8 +143,10 @@ int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame,
* Unpacks HEADERS frame byte sequence into |frame|. This function
* only unapcks bytes that come before name/value header block and
* after possible Pad Length field.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
const uint8_t *payload);
/*
@@ -150,8 +155,10 @@ void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
/*
* Unpacks PRIORITY wire format into |frame|.
@@ -165,8 +172,10 @@ void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
nghttp2_rst_stream *frame);
/*
@@ -256,8 +265,14 @@ int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
* Unpacks PUSH_PROMISE frame byte sequence into |frame|. This
* function only unapcks bytes that come before name/value header
* block and after possible Pad Length field.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_PROTO
* TODO END_HEADERS flag is not set
*/
void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
const uint8_t *payload);
/*
@@ -266,8 +281,10 @@ void nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
/*
* Unpacks PING wire format into |frame|.
@@ -326,8 +343,10 @@ int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
nghttp2_window_update *frame);
/*
@@ -342,13 +361,17 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
/*
* Unpacks ALTSVC wire format into |frame|. The |payload| of
* |payloadlen| bytes contains frame payload. This function assumes
* that frame->payload points to the nghttp2_ext_altsvc object.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
size_t origin_len, uint8_t *payload,
@@ -408,8 +431,10 @@ int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
nghttp2_extension *ext);
/*
@@ -417,6 +442,8 @@ void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
* |payloadlen| bytes contains frame payload. This function assumes
* that frame->payload points to the nghttp2_ext_priority_update
* object.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
uint8_t *payload,
@@ -627,8 +654,16 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
* |padlen| including Pad Length field. The |hd| is the frame header
* for the serialized data. This function fills zeros padding region
* unless framehd_only is nonzero.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FRAME_SIZE_ERROR
* The length of the resulting frame is too large.
*/
void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
size_t padlen, int framehd_only);
#endif /* !defined(NGHTTP2_FRAME_H) */
#endif /* NGHTTP2_FRAME_H */

View File

@@ -38,8 +38,7 @@
{NULL, NULL, (uint8_t *)(N), sizeof((N)) - 1, -1}, \
{NULL, NULL, (uint8_t *)(V), sizeof((V)) - 1, -1}, \
{(uint8_t *)(N), (uint8_t *)(V), sizeof((N)) - 1, sizeof((V)) - 1, 0}, \
T, \
H, \
T, H \
}
/* Generated by mkstatictbl.py */
@@ -594,19 +593,8 @@ static void hd_map_remove(nghttp2_hd_map *map, nghttp2_hd_entry *ent) {
static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize,
nghttp2_mem *mem) {
size_t size;
const size_t max_size = SIZE_MAX / sizeof(nghttp2_hd_entry *);
if (bufsize > max_size) {
return NGHTTP2_ERR_NOMEM;
}
for (size = 1; size < bufsize; size <<= 1)
;
if (size > max_size) {
return NGHTTP2_ERR_NOMEM;
}
ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size);
if (ringbuf->buffer == NULL) {
return NGHTTP2_ERR_NOMEM;
@@ -862,10 +850,9 @@ static size_t encode_length(uint8_t *buf, size_t n, size_t prefix) {
* in the next call will be stored in |*shift_ptr|) and returns number
* of bytes processed, or returns -1, indicating decoding error.
*/
static nghttp2_ssize decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
uint32_t initial, size_t shift,
const uint8_t *in, const uint8_t *last,
size_t prefix) {
static ssize_t decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
uint32_t initial, size_t shift, const uint8_t *in,
const uint8_t *last, size_t prefix) {
uint32_t k = (uint8_t)((1 << prefix) - 1);
uint32_t n = initial;
const uint8_t *start = in;
@@ -884,7 +871,7 @@ static nghttp2_ssize decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
if (++in == last) {
*res = n;
return (nghttp2_ssize)(in - start);
return (ssize_t)(in - start);
}
}
@@ -919,12 +906,12 @@ static nghttp2_ssize decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
if (in == last) {
*res = n;
return (nghttp2_ssize)(in - start);
return (ssize_t)(in - start);
}
*res = n;
*fin = 1;
return (nghttp2_ssize)(in + 1 - start);
return (ssize_t)(in + 1 - start);
}
static int emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
@@ -1123,6 +1110,7 @@ static int add_hd_table_incremental(nghttp2_hd_context *context,
while (context->hd_table_bufsize + room > context->hd_table_bufsize_max &&
context->hd_table.len > 0) {
size_t idx = context->hd_table.len - 1;
nghttp2_hd_entry *ent = hd_ringbuf_get(&context->hd_table, idx);
@@ -1176,7 +1164,7 @@ static int add_hd_table_incremental(nghttp2_hd_context *context,
}
typedef struct {
nghttp2_ssize index;
ssize_t index;
/* Nonzero if both name and value are matched. */
int name_value_match;
} search_result;
@@ -1225,8 +1213,8 @@ static search_result search_hd_table(nghttp2_hd_context *context,
return res;
}
res.index = (nghttp2_ssize)(context->next_seq - 1 - ent->seq +
NGHTTP2_STATIC_TABLE_LENGTH);
res.index =
(ssize_t)(context->next_seq - 1 - ent->seq + NGHTTP2_STATIC_TABLE_LENGTH);
res.name_value_match = exact_match;
return res;
@@ -1256,13 +1244,13 @@ static void hd_context_shrink_table_size(nghttp2_hd_context *context,
int nghttp2_hd_deflate_change_table_size(
nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) {
size_t next_bufsize = nghttp2_min_size(
settings_max_dynamic_table_size, deflater->deflate_hd_table_bufsize_max);
size_t next_bufsize = nghttp2_min(settings_max_dynamic_table_size,
deflater->deflate_hd_table_bufsize_max);
deflater->ctx.hd_table_bufsize_max = next_bufsize;
deflater->min_hd_table_bufsize_max =
nghttp2_min_size(deflater->min_hd_table_bufsize_max, next_bufsize);
nghttp2_min(deflater->min_hd_table_bufsize_max, next_bufsize);
deflater->notify_table_size_change = 1;
@@ -1355,7 +1343,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
const nghttp2_nv *nv) {
int rv;
search_result res;
nghttp2_ssize idx;
ssize_t idx;
int indexing_mode;
int32_t token;
nghttp2_mem *mem;
@@ -1377,7 +1365,8 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
entropy secret data (e.g., id/password). Also cookie header
field with less than 20 bytes value is also never indexed. This
is the same criteria used in Firefox codebase. */
indexing_mode = token == NGHTTP2_TOKEN_AUTHORIZATION ||
indexing_mode =
token == NGHTTP2_TOKEN_AUTHORIZATION ||
(token == NGHTTP2_TOKEN_COOKIE && nv->valuelen < 20) ||
(nv->flags & NGHTTP2_NV_FLAG_NO_INDEX)
? NGHTTP2_HD_NEVER_INDEXING
@@ -1389,7 +1378,8 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
idx = res.index;
if (res.name_value_match) {
DEBUGF("deflatehd: name/value match index=%td\n", idx);
DEBUGF("deflatehd: name/value match index=%zd\n", idx);
rv = emit_indexed_block(bufs, (size_t)idx);
if (rv != 0) {
@@ -1400,7 +1390,7 @@ static int deflate_nv(nghttp2_hd_deflater *deflater, nghttp2_bufs *bufs,
}
if (res.index != -1) {
DEBUGF("deflatehd: name match index=%td\n", res.index);
DEBUGF("deflatehd: name match index=%zd\n", res.index);
}
if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) {
@@ -1466,6 +1456,7 @@ int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
deflater->min_hd_table_bufsize_max = UINT32_MAX;
if (deflater->ctx.hd_table_bufsize_max > min_hd_table_bufsize_max) {
rv = emit_table_size(bufs, min_hd_table_bufsize_max);
if (rv != 0) {
@@ -1500,12 +1491,6 @@ fail:
ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
size_t buflen, const nghttp2_nv *nv,
size_t nvlen) {
return (ssize_t)nghttp2_hd_deflate_hd2(deflater, buf, buflen, nv, nvlen);
}
nghttp2_ssize nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater,
uint8_t *buf, size_t buflen,
const nghttp2_nv *nv, size_t nvlen) {
nghttp2_bufs bufs;
int rv;
nghttp2_mem *mem;
@@ -1532,18 +1517,12 @@ nghttp2_ssize nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater,
return rv;
}
return (nghttp2_ssize)buflen;
return (ssize_t)buflen;
}
ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
const nghttp2_vec *vec, size_t veclen,
const nghttp2_nv *nv, size_t nvlen) {
return (ssize_t)nghttp2_hd_deflate_hd_vec2(deflater, vec, veclen, nv, nvlen);
}
nghttp2_ssize nghttp2_hd_deflate_hd_vec2(nghttp2_hd_deflater *deflater,
const nghttp2_vec *vec, size_t veclen,
const nghttp2_nv *nv, size_t nvlen) {
nghttp2_bufs bufs;
int rv;
nghttp2_mem *mem;
@@ -1571,7 +1550,7 @@ nghttp2_ssize nghttp2_hd_deflate_hd_vec2(nghttp2_hd_deflater *deflater,
return rv;
}
return (nghttp2_ssize)buflen;
return (ssize_t)buflen;
}
size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
@@ -1664,11 +1643,10 @@ static void hd_inflate_set_huffman_encoded(nghttp2_hd_inflater *inflater,
* NGHTTP2_ERR_HEADER_COMP
* Integer decoding failed
*/
static nghttp2_ssize hd_inflate_read_len(nghttp2_hd_inflater *inflater,
int *rfin, const uint8_t *in,
const uint8_t *last, size_t prefix,
size_t maxlen) {
nghttp2_ssize rv;
static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
const uint8_t *in, const uint8_t *last,
size_t prefix, size_t maxlen) {
ssize_t rv;
uint32_t out;
*rfin = 0;
@@ -1706,10 +1684,10 @@ static nghttp2_ssize hd_inflate_read_len(nghttp2_hd_inflater *inflater,
* NGHTTP2_ERR_HEADER_COMP
* Huffman decoding failed
*/
static nghttp2_ssize hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
nghttp2_buf *buf, const uint8_t *in,
const uint8_t *last) {
nghttp2_ssize readlen;
ssize_t readlen;
int fin = 0;
if ((size_t)(last - in) >= inflater->left) {
last = in + inflater->left;
@@ -1743,15 +1721,14 @@ static nghttp2_ssize hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
* NGHTTP2_ERR_HEADER_COMP
* Header decompression failed
*/
static nghttp2_ssize hd_inflate_read(nghttp2_hd_inflater *inflater,
nghttp2_buf *buf, const uint8_t *in,
const uint8_t *last) {
size_t len = nghttp2_min_size((size_t)(last - in), inflater->left);
static ssize_t hd_inflate_read(nghttp2_hd_inflater *inflater, nghttp2_buf *buf,
const uint8_t *in, const uint8_t *last) {
size_t len = nghttp2_min((size_t)(last - in), inflater->left);
buf->last = nghttp2_cpymem(buf->last, in, len);
inflater->left -= len;
return (nghttp2_ssize)len;
return (ssize_t)len;
}
/*
@@ -1866,15 +1843,7 @@ ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out,
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen, int in_final) {
return (nghttp2_ssize)nghttp2_hd_inflate_hd3(inflater, nv_out, inflate_flags,
in, inlen, in_final);
}
nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen,
int in_final) {
nghttp2_ssize rv;
ssize_t rv;
nghttp2_hd_nv hd_nv;
rv = nghttp2_hd_inflate_hd_nv(inflater, &hd_nv, inflate_flags, in, inlen,
@@ -1897,11 +1866,11 @@ nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater,
return rv;
}
nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out,
int *inflate_flags, const uint8_t *in,
size_t inlen, int in_final) {
nghttp2_ssize rv = 0;
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen,
int in_final) {
ssize_t rv = 0;
const uint8_t *first = in;
const uint8_t *last = in + inlen;
int rfin = 0;
@@ -1970,7 +1939,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
rfin = 0;
rv = hd_inflate_read_len(
inflater, &rfin, in, last, 5,
nghttp2_min_size(inflater->min_hd_table_bufsize_max,
nghttp2_min(inflater->min_hd_table_bufsize_max,
inflater->settings_hd_table_bufsize_max));
if (rv < 0) {
goto fail;
@@ -2023,7 +1992,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_OPCODE;
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
return (nghttp2_ssize)(in - first);
return (ssize_t)(in - first);
} else {
inflater->index = inflater->left;
--inflater->index;
@@ -2058,8 +2027,8 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF;
rv =
nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1, mem);
rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1,
mem);
} else {
inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAME;
rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left + 1, mem);
@@ -2081,7 +2050,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
in += rv;
DEBUGF("inflatehd: %td bytes read\n", rv);
DEBUGF("inflatehd: %zd bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2103,7 +2072,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
in += rv;
DEBUGF("inflatehd: %td bytes read\n", rv);
DEBUGF("inflatehd: %zd bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2143,8 +2112,8 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF;
rv =
nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem);
rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1,
mem);
} else {
inflater->state = NGHTTP2_HD_STATE_READ_VALUE;
@@ -2169,7 +2138,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
in += rv;
DEBUGF("inflatehd: %td bytes read\n", rv);
DEBUGF("inflatehd: %zd bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2193,18 +2162,18 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_OPCODE;
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
return (nghttp2_ssize)(in - first);
return (ssize_t)(in - first);
case NGHTTP2_HD_STATE_READ_VALUE:
rv = hd_inflate_read(inflater, &inflater->valuebuf, in, last);
if (rv < 0) {
DEBUGF("inflatehd: value read failure %td: %s\n", rv,
DEBUGF("inflatehd: value read failure %zd: %s\n", rv,
nghttp2_strerror((int)rv));
goto fail;
}
in += rv;
DEBUGF("inflatehd: %td bytes read\n", rv);
DEBUGF("inflatehd: %zd bytes read\n", rv);
if (inflater->left) {
DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2227,7 +2196,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
inflater->state = NGHTTP2_HD_STATE_OPCODE;
*inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
return (nghttp2_ssize)(in - first);
return (ssize_t)(in - first);
}
}
@@ -2247,7 +2216,7 @@ nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
}
*inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
}
return (nghttp2_ssize)(in - first);
return (ssize_t)(in - first);
almost_ok:
if (in_final) {
@@ -2257,10 +2226,10 @@ almost_ok:
goto fail;
}
return (nghttp2_ssize)(in - first);
return (ssize_t)(in - first);
fail:
DEBUGF("inflatehd: error return %td\n", rv);
DEBUGF("inflatehd: error return %zd\n", rv);
inflater->ctx.bad = 1;
return rv;
@@ -2315,6 +2284,7 @@ void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater) {
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t idx,
nghttp2_nv *nv, int indexing_mode) {
return emit_indname_block(bufs, idx, nv, indexing_mode);
}
@@ -2327,10 +2297,9 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
return emit_table_size(bufs, table_size);
}
nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr,
int *fin, uint32_t initial, size_t shift,
uint8_t *in, uint8_t *last,
size_t prefix) {
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
uint32_t initial, size_t shift, uint8_t *in,
uint8_t *last, size_t prefix) {
return decode_length(res, shift_ptr, fin, initial, shift, in, last, prefix);
}

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* defined(HAVE_CONFIG_H) */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
@@ -357,10 +357,9 @@ void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
* that return values and semantics are the same as
* nghttp2_hd_inflate_hd().
*/
nghttp2_ssize nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out,
int *inflate_flags, const uint8_t *in,
size_t inlen, int in_final);
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen, int in_final);
/* For unittesting purpose */
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
@@ -377,10 +376,9 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
/* For unittesting purpose */
nghttp2_ssize nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr,
int *fin, uint32_t initial, size_t shift,
uint8_t *in, uint8_t *last,
size_t prefix);
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
uint32_t initial, size_t shift, uint8_t *in,
uint8_t *last, size_t prefix);
/* Huffman encoding/decoding functions */
@@ -429,7 +427,7 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
* NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed.
*/
nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int fin);
@@ -439,4 +437,4 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
*/
int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
#endif /* !defined(NGHTTP2_HD_H) */
#endif /* NGHTTP2_HD_H */

View File

@@ -104,42 +104,39 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
}
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->fstate = 0;
ctx->flags = NGHTTP2_HUFF_ACCEPTED;
ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
}
nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final) {
const uint8_t *end = src + srclen;
nghttp2_huff_decode t = {ctx->fstate, ctx->flags, 0};
nghttp2_huff_decode node = {ctx->fstate, 0};
const nghttp2_huff_decode *t = &node;
uint8_t c;
/* We use the decoding algorithm described in
- http://graphics.ics.uci.edu/pub/Prefix.pdf [!!! NO LONGER VALID !!!]
- https://ics.uci.edu/~dan/pubs/Prefix.pdf
- https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
http://graphics.ics.uci.edu/pub/Prefix.pdf */
for (; src != end;) {
c = *src++;
t = huff_decode_table[t.fstate][c >> 4];
if (t.flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t.sym;
t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
}
t = huff_decode_table[t.fstate][c & 0xf];
if (t.flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t.sym;
t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
}
}
ctx->fstate = t.fstate;
ctx->flags = t.flags;
ctx->fstate = t->fstate;
if (final && !(ctx->flags & NGHTTP2_HUFF_ACCEPTED)) {
if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) {
return NGHTTP2_ERR_HEADER_COMP;
}
return (nghttp2_ssize)srclen;
return (ssize_t)srclen;
}
int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) {

Some files were not shown because too many files have changed in this diff Show More