Compare commits

..

5 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
ec542f140b Update manual pages 2017-04-09 21:29:58 +09:00
Tatsuhiro Tsujikawa
39a2a2437c Bump up version number to 1.21.1 2017-04-09 21:26:58 +09:00
Tatsuhiro Tsujikawa
a073dfc633 nghttpx: Fix bug that 204 from h1 backend is always treated as error 2017-04-09 21:26:00 +09:00
Tatsuhiro Tsujikawa
d2ba169f79 asio: Fix crash if connect takes longer time than ping interval 2017-04-09 21:26:00 +09:00
Tatsuhiro Tsujikawa
a629a0c677 asio: Fix compile error 2017-04-09 21:26:00 +09:00
254 changed files with 6381 additions and 11259 deletions

View File

@@ -4,7 +4,7 @@ AccessModifierOffset: -2
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right AlignEscapedNewlinesLeft: false
AlignOperands: true AlignOperands: true
AlignTrailingComments: true AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true
@@ -28,24 +28,17 @@ BraceWrapping:
AfterObjCDeclaration: false AfterObjCDeclaration: false
AfterStruct: false AfterStruct: false
AfterUnion: false AfterUnion: false
AfterExternBlock: false
BeforeCatch: false BeforeCatch: false
BeforeElse: false BeforeElse: false
IndentBraces: false IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true BreakStringLiterals: true
ColumnLimit: 80 ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4 ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4 ContinuationIndentWidth: 4
@@ -53,12 +46,7 @@ Cpp11BracedListStyle: true
DerivePointerAlignment: false DerivePointerAlignment: false
DisableFormat: false DisableFormat: false
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories: IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2 Priority: 2
@@ -68,7 +56,6 @@ IncludeCategories:
Priority: 1 Priority: 1
IncludeIsMainRegex: '$' IncludeIsMainRegex: '$'
IndentCaseLabels: false IndentCaseLabels: false
IndentPPDirectives: AfterHash
IndentWidth: 2 IndentWidth: 2
IndentWrappedFunctionNames: false IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave JavaScriptQuotes: Leave
@@ -81,7 +68,6 @@ NamespaceIndentation: None
ObjCBlockIndentWidth: 2 ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300 PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120 PenaltyBreakFirstLessLess: 120
@@ -89,15 +75,9 @@ PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000 PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60 PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right PointerAlignment: Right
RawStringFormats:
- Delimiter: pb
Language: TextProto
BasedOnStyle: google
ReflowComments: true ReflowComments: true
SortIncludes: false SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false SpaceInEmptyParentheses: false

3
.gitmodules vendored
View File

@@ -3,5 +3,4 @@
url = https://github.com/mruby/mruby url = https://github.com/mruby/mruby
[submodule "third-party/neverbleed"] [submodule "third-party/neverbleed"]
path = third-party/neverbleed path = third-party/neverbleed
url = https://github.com/tatsuhiro-t/neverbleed.git url = https://github.com/h2o/neverbleed.git
branch = openssl111fix

View File

@@ -1,4 +1,3 @@
dist: trusty
env: env:
matrix: matrix:
- CI_BUILD=cmake - CI_BUILD=cmake
@@ -7,15 +6,15 @@ language: cpp
compiler: compiler:
- clang - clang
- gcc - gcc
sudo: required sudo: false
addons: addons:
apt: apt:
sources: sources:
- ubuntu-toolchain-r-test - ubuntu-toolchain-r-test
- llvm-toolchain-trusty-7 - george-edison55-precise-backports
packages: packages:
- g++-8 - g++-4.9
- clang-7 - libstdc++-4.9-dev
- autoconf - autoconf
- automake - automake
- autotools-dev - autotools-dev
@@ -34,19 +33,29 @@ addons:
- cmake-data - cmake-data
before_install: before_install:
- $CC --version - $CC --version
- if [ "$CXX" = "g++" ]; then export CXX="g++-8" CC="gcc-8"; fi - if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
- if [ "$CXX" = "clang++" ]; then export CXX="clang++-7" CC="clang-7"; fi
- $CC --version - $CC --version
- go version - go version
- cmake --version - cmake --version
before_script: before_script:
# First build spdylay, since integration tests require it.
# spdylay is going to be built under third-party/spdylay
- cd third-party
- git clone https://github.com/tatsuhiro-t/spdylay.git
- cd spdylay
- autoreconf -i
# Don't use ASAN for spdylay since failmalloc does not work with it.
- ./configure --disable-src --disable-examples
- make check
- export SPDYLAY_HOME=$PWD
- cd ../..
# Now build nghttp2 # Now build nghttp2
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi - if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
- git submodule update --init - git submodule update --init
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --with-mruby; fi - if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay" CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address; fi
- if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1; fi - if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DSPDYLAY_INCLUDE_DIR="$SPDYLAY_HOME/lib/includes" -DSPDYLAY_LIBRARY="$SPDYLAY_HOME/lib/.libs/libspdylay.so"; fi
script: script:
- if [ "$CI_BUILD" = "autotools" ]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-neverbleed --enable-werror CPPFLAGS=-fsanitize=address LDFLAGS=\"-fsanitize=address -fuse-ld=gold\""; fi - if [ "$CI_BUILD" = "autotools" ]; then make distcheck; fi
- if [ "$CI_BUILD" = "cmake" ]; then make check; fi - if [ "$CI_BUILD" = "cmake" ]; then make check; fi
# As of April, 23, 2016, golang http2 build fails, probably because # As of April, 23, 2016, golang http2 build fails, probably because
# the default go version is too old. # the default go version is too old.

25
AUTHORS
View File

@@ -16,36 +16,28 @@ github issues [2].
187j3x1 187j3x1
Alek Storm Alek Storm
Alex Nalivko Alex Nalivko
Alexandros Konstantinakis-Karmis
Alexis La Goutte Alexis La Goutte
Amir Pakdel Amir Pakdel
Anders Bakken Anders Bakken
Andreas Pohl Andreas Pohl
Andy Davies Andy Davies
Angus Gratton
Anna Henningsen
Ant Bryan Ant Bryan
Benedikt Christoph Wolters Benedikt Christoph Wolters
Benjamin Peterson Benedikt Christoph Wolters
Bernard Spil
Bernard Spil Bernard Spil
Brian Card Brian Card
Brian Suh Brian Suh
Daniel Evers
Daniel Stenberg Daniel Stenberg
Dave Reisner Dave Reisner
David Beitey David Beitey
David Weekly David Weekly
Dmitriy Vetutnev
Don
Dylan Plecki
Etienne Cimon Etienne Cimon
Fabian Möller Fabian Möller
Fabian Wiesel Fabian Wiesel
Gabi Davar Gabi Davar
Gitai
Google Inc. Google Inc.
Jacob Champion Jacob Champion
Jan Kundrát
Jan-E Jan-E
Janusz Dziemidowicz Janusz Dziemidowicz
Jay Satiro Jay Satiro
@@ -58,15 +50,11 @@ Kenny (kang-yen) Peng
Kenny Peng Kenny Peng
Kit Chan Kit Chan
Kyle Schomp Kyle Schomp
LazyHamster
Lucas Pardue Lucas Pardue
MATSUMOTO Ryosuke MATSUMOTO Ryosuke
Marc Bachmann
Matt Rudary Matt Rudary
Matt Way
Mike Conlen Mike Conlen
Mike Frysinger Mike Frysinger
Mike Lothian
Nicholas Hurley Nicholas Hurley
Nora Shoemaker Nora Shoemaker
Peeyush Aggarwal Peeyush Aggarwal
@@ -75,27 +63,20 @@ Piotr Sikora
Raul Gutierrez Segales Raul Gutierrez Segales
Remo E Remo E
Reza Tavakoli Reza Tavakoli
Rick Lei
Ross Smith II Ross Smith II
Scott Mitchell Scott Mitchell
Sebastiaan Deckers
Simone Basso
Soham Sinha
Stefan Eissing Stefan Eissing
Stephen Ludin Stephen Ludin
Sunpoet Po-Chuan Hsieh Sunpoet Po-Chuan Hsieh
Svante Signell Svante Signell
Syohei YOSHIDA Syohei YOSHIDA
Tapanito
Tatsuhiko Kubo Tatsuhiko Kubo
Tatsuhiro Tsujikawa Tatsuhiro Tsujikawa
Tobias Geerinckx-Rice
Tom Harwood Tom Harwood
Tomasz Buchert Tomasz Buchert
Tomasz Torcz Tomasz Torcz
Vernon Tang Vernon Tang
Viacheslav Biriukov Viacheslav Biriukov
Viktor Szakats
Viktor Szépe Viktor Szépe
Wenfeng Liu Wenfeng Liu
Xiaoguang Sun Xiaoguang Sun
@@ -107,9 +88,7 @@ clemahieu
dalf dalf
es es
fangdingjun fangdingjun
jwchoi
kumagi kumagi
lstefani
makovich makovich
mod-h2-dev mod-h2-dev
moparisthebest moparisthebest

View File

@@ -24,15 +24,15 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
# XXX using 1.8.90 instead of 1.9.0-DEV # XXX using 1.8.90 instead of 1.9.0-DEV
project(nghttp2 VERSION 1.35.0) project(nghttp2 VERSION 1.21.1)
# See versioning rule: # See versioning rule:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
set(LT_CURRENT 31) set(LT_CURRENT 27)
set(LT_REVISION 1) set(LT_REVISION 1)
set(LT_AGE 17) set(LT_AGE 13)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Version) include(Version)
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}") math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
@@ -79,7 +79,7 @@ else()
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF) set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
endif() endif()
find_package(LibXml2 2.6.26) find_package(LibXml2 2.7.7)
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND}) set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
find_package(Jemalloc) find_package(Jemalloc)
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND}) set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
@@ -106,7 +106,7 @@ endif()
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo") foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
foreach(_lang C CXX) foreach(_lang C CXX)
string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var) string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " ${_var} "${${_var}}") string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" "" ${_var} "${${_var}}")
endforeach() endforeach()
endforeach() endforeach()
@@ -117,7 +117,7 @@ else()
endif() endif()
include(ExtractValidFlags) include(ExtractValidFlags)
foreach(_cxx1x_flag -std=c++14) foreach(_cxx1x_flag -std=c++11 -std=c++0x)
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag}) extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
if(_cxx1x_flag_supported) if(_cxx1x_flag_supported)
set(CXX1XCXXFLAGS ${_cxx1x_flag}) set(CXX1XCXXFLAGS ${_cxx1x_flag})
@@ -302,7 +302,6 @@ check_type_size("time_t" SIZEOF_TIME_T)
include(CheckFunctionExists) include(CheckFunctionExists)
check_function_exists(_Exit HAVE__EXIT) check_function_exists(_Exit HAVE__EXIT)
check_function_exists(accept4 HAVE_ACCEPT4) check_function_exists(accept4 HAVE_ACCEPT4)
check_function_exists(mkostemp HAVE_MKOSTEMP)
include(CheckSymbolExists) include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin? # XXX does this correctly detect initgroups (un)availability on cygwin?

View File

@@ -14,7 +14,6 @@ option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
${ENABLE_PYTHON_BINDINGS_DEFAULT}) ${ENABLE_PYTHON_BINDINGS_DEFAULT})
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON) 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 -DENABLE_PYTHON_BINDINGS=0") option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
option(ENABLE_STATIC_LIB "Build libnghttp2 in static mode also")
option(WITH_LIBXML2 "Use libxml2" option(WITH_LIBXML2 "Use libxml2"
${WITH_LIBXML2_DEFAULT}) ${WITH_LIBXML2_DEFAULT})

View File

@@ -10,47 +10,39 @@
# #
# $ sudo docker run -v /path/to/dest:/out nghttp2-android cp /root/build/nghttp2/src/nghttpx /out # $ sudo docker run -v /path/to/dest:/out nghttp2-android cp /root/build/nghttp2/src/nghttpx /out
FROM ubuntu:vivid
# Only use standalone-toolchain for reduce size
FROM ubuntu:xenial
MAINTAINER Tatsuhiro Tsujikawa MAINTAINER Tatsuhiro Tsujikawa
ENV ANDROID_HOME /root
ENV ANDROID_HOME /root/android
ENV PREFIX $ANDROID_HOME/usr/local
ENV TOOLCHAIN $ANDROID_HOME/toolchain ENV TOOLCHAIN $ANDROID_HOME/toolchain
ENV PATH $TOOLCHAIN/bin:$PATH ENV PATH $TOOLCHAIN/bin:$PATH
ENV NDK_VERSION r14b # It would be better to use nearest ubuntu archive mirror for faster
# downloads.
# RUN sed -ie 's/archive\.ubuntu/jp.archive.ubuntu/g' /etc/apt/sources.list
WORKDIR /root RUN apt-get update
RUN apt-get update && \ # genisoimage, libc6-i386 and lib32stdc++6 are required to decompress ndk.
apt-get install -y unzip make binutils autoconf \ RUN apt-get install -y make binutils autoconf automake autotools-dev libtool \
automake autotools-dev libtool pkg-config git \ pkg-config git curl dpkg-dev libxml2-dev \
curl dpkg-dev libxml2-dev genisoimage libc6-i386 \ genisoimage libc6-i386 lib32stdc++6
lib32stdc++6 python&& \
rm -rf /var/cache/apk/*
# Install toolchain
RUN curl -L -O https://dl.google.com/android/repository/android-ndk-$NDK_VERSION-linux-x86_64.zip && \
unzip -q android-ndk-$NDK_VERSION-linux-x86_64.zip && \
rm android-ndk-$NDK_VERSION-linux-x86_64.zip && \
mkdir -p $ANDROID_HOME/toolchain && \
$ANDROID_HOME/android-ndk-$NDK_VERSION/build/tools/make-standalone-toolchain.sh \
--install-dir=$ANDROID_HOME/toolchain \
--toolchain=arm-linux-androideabi-4.9 \
--force && \
rm -r android-ndk-$NDK_VERSION
ENV PREFIX /root/usr/local
# Setup version of libraries
ENV OPENSSL_VERSION 1.0.2d
ENV SPDYLAY_VERSION v1.4.0
ENV LIBEV_VERSION 4.19
ENV ZLIB_VERSION 1.2.8
ENV CARES_VERSION 1.13.0
ENV NGHTTP2_VERSION v1.24.0
WORKDIR /root/build WORKDIR /root/build
RUN git clone https://github.com/tatsuhiro-t/spdylay -b $SPDYLAY_VERSION --depth 1 RUN curl -L -O http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin && \
chmod a+x android-ndk-r10d-linux-x86_64.bin && \
./android-ndk-r10d-linux-x86_64.bin && \
rm android-ndk-r10d-linux-x86_64.bin
WORKDIR /root/build/android-ndk-r10d
RUN /bin/bash build/tools/make-standalone-toolchain.sh \
--install-dir=$ANDROID_HOME/toolchain \
--toolchain=arm-linux-androideabi-4.9 --llvm-version=3.5 \
--system=linux-x86_64
WORKDIR /root/build
RUN git clone https://github.com/tatsuhiro-t/spdylay
WORKDIR /root/build/spdylay WORKDIR /root/build/spdylay
RUN autoreconf -i && \ RUN autoreconf -i && \
./configure \ ./configure \
@@ -67,22 +59,22 @@ RUN autoreconf -i && \
make install make install
WORKDIR /root/build WORKDIR /root/build
RUN curl -L -O https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz && \ RUN curl -L -O https://www.openssl.org/source/openssl-1.0.2d.tar.gz && \
tar xf openssl-$OPENSSL_VERSION.tar.gz && \ tar xf openssl-1.0.2d.tar.gz && \
rm openssl-$OPENSSL_VERSION.tar.gz rm openssl-1.0.2d.tar.gz
WORKDIR /root/build/openssl-$OPENSSL_VERSION WORKDIR /root/build/openssl-1.0.2d
RUN export CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi- && \ RUN export CROSS_COMPILE=$TOOLCHAIN/bin/arm-linux-androideabi- && \
./Configure --prefix=$PREFIX android && \ ./Configure --prefix=$PREFIX android && \
make && make install_sw make && make install_sw
WORKDIR /root/build WORKDIR /root/build
RUN curl -L -O http://dist.schmorp.de/libev/Attic/libev-$LIBEV_VERSION.tar.gz && \ RUN curl -L -O http://dist.schmorp.de/libev/libev-4.19.tar.gz && \
curl -L -O https://gist.github.com/tatsuhiro-t/48c45f08950f587180ed/raw/80a8f003b5d1091eae497c5995bbaa68096e739b/libev-4.19-android.patch && \ curl -L -O https://gist.github.com/tatsuhiro-t/48c45f08950f587180ed/raw/80a8f003b5d1091eae497c5995bbaa68096e739b/libev-4.19-android.patch && \
tar xf libev-$LIBEV_VERSION.tar.gz && \ tar xf libev-4.19.tar.gz && \
rm libev-$LIBEV_VERSION.tar.gz rm libev-4.19.tar.gz
WORKDIR /root/build/libev-$LIBEV_VERSION WORKDIR /root/build/libev-4.19
RUN patch -p1 < ../libev-4.19-android.patch && \ RUN patch -p1 < ../libev-4.19-android.patch && \
./configure \ ./configure \
--host=arm-linux-androideabi \ --host=arm-linux-androideabi \
@@ -95,11 +87,11 @@ RUN patch -p1 < ../libev-4.19-android.patch && \
make install make install
WORKDIR /root/build WORKDIR /root/build
RUN curl -L -O https://downloads.sourceforge.net/project/libpng/zlib/$ZLIB_VERSION/zlib-$ZLIB_VERSION.tar.gz && \ RUN curl -L -O http://zlib.net/zlib-1.2.8.tar.gz && \
tar xf zlib-$ZLIB_VERSION.tar.gz && \ tar xf zlib-1.2.8.tar.gz && \
rm zlib-$ZLIB_VERSION.tar.gz rm zlib-1.2.8.tar.gz
WORKDIR /root/build/zlib-$ZLIB_VERSION WORKDIR /root/build/zlib-1.2.8
RUN HOST=arm-linux-androideabi \ RUN HOST=arm-linux-androideabi \
CC=$HOST-gcc \ CC=$HOST-gcc \
AR=$HOST-ar \ AR=$HOST-ar \
@@ -113,26 +105,11 @@ RUN HOST=arm-linux-androideabi \
--static && \ --static && \
make install make install
WORKDIR /root/build WORKDIR /root/build
RUN curl -L -O https://c-ares.haxx.se/download/c-ares-$CARES_VERSION.tar.gz && \ RUN git clone https://github.com/nghttp2/nghttp2
tar xf c-ares-$CARES_VERSION.tar.gz && \
rm c-ares-$CARES_VERSION.tar.gz
WORKDIR /root/build/c-ares-$CARES_VERSION
RUN ./configure \
--host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
--disable-shared && \
make install
WORKDIR /root/build
RUN git clone https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
WORKDIR /root/build/nghttp2 WORKDIR /root/build/nghttp2
RUN autoreconf -i && \ RUN autoreconf -i && \
./configure \ ./configure \
--enable-app \
--disable-shared \ --disable-shared \
--host=arm-linux-androideabi \ --host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \ --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
@@ -141,10 +118,11 @@ RUN autoreconf -i && \
--disable-python-bindings \ --disable-python-bindings \
--disable-examples \ --disable-examples \
--disable-threads \ --disable-threads \
CC="$TOOLCHAIN"/bin/arm-linux-androideabi-clang \ LIBSPDYLAY_CFLAGS=-I$PREFIX/usr/local/include \
CXX="$TOOLCHAIN"/bin/arm-linux-androideabi-clang++ \ LIBSPDYLAY_LIBS="-L$PREFIX/usr/local/lib -lspdylay" \
CPPFLAGS="-fPIE -I$PREFIX/include" \ CPPFLAGS="-fPIE -I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \ CXXFLAGS="-fno-strict-aliasing" \
LDFLAGS="-fPIE -pie -L$PREFIX/lib" && \ PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-fPIE -pie -L$PREFIX/lib" && \
make && \ make && \
arm-linux-androideabi-strip src/nghttpx src/nghttpd src/nghttp arm-linux-androideabi-strip src/nghttpx src/nghttpd src/nghttp

View File

@@ -4,10 +4,10 @@ nghttp2 - HTTP/2 C Library
This is an implementation of the Hypertext Transfer Protocol version 2 This is an implementation of the Hypertext Transfer Protocol version 2
in C. in C.
The framing layer of HTTP/2 is implemented as a reusable C library. The framing layer of HTTP/2 is implemented as a reusable C
On top of that, we have implemented an HTTP/2 client, server and library. On top of that, we have implemented an HTTP/2 client, server
proxy. We have also developed load test and benchmarking tools for and proxy. We have also developed load test and benchmarking tools for
HTTP/2. HTTP/2 and SPDY.
An HPACK encoder and decoder are available as a public API. An HPACK encoder and decoder are available as a public API.
@@ -34,8 +34,8 @@ implementation.
* https://nghttp2.org/ (TLS + ALPN/NPN) * https://nghttp2.org/ (TLS + ALPN/NPN)
This endpoint supports ``h2``, ``h2-16``, ``h2-14``, and This endpoint supports ``h2``, ``h2-16``, ``h2-14``, ``spdy/3.1``
``http/1.1`` via ALPN/NPN and requires TLSv1.2 for HTTP/2 and ``http/1.1`` via ALPN/NPN and requires TLSv1.2 for HTTP/2
connection. connection.
* http://nghttp2.org/ (HTTP Upgrade and HTTP/2 Direct) * http://nghttp2.org/ (HTTP Upgrade and HTTP/2 Direct)
@@ -76,10 +76,18 @@ 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 LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more
features than LibreSSL at the time of this writing. features than LibreSSL at the time of this writing.
To enable the SPDY protocol in the application program ``nghttpx`` and
``h2load``, the following package is required:
* spdylay >= 1.3.2
We no longer recommend to build nghttp2 with SPDY protocol support
enabled. SPDY support will be removed soon.
To enable ``-a`` option (getting linked assets from the downloaded To enable ``-a`` option (getting linked assets from the downloaded
resource) in ``nghttp``, the following package is required: resource) in ``nghttp``, the following package is required:
* libxml2 >= 2.6.26 * libxml2 >= 2.7.7
To enable systemd support in nghttpx, the following package is To enable systemd support in nghttpx, the following package is
required: required:
@@ -122,9 +130,13 @@ and above, run the following to install the required packages:
sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \ sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \ zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
libc-ares-dev libjemalloc-dev libsystemd-dev \ libc-ares-dev libjemalloc-dev libsystemd-dev libspdylay-dev \
cython python3-dev python-setuptools cython python3-dev python-setuptools
Since Ubuntu 15.10, spdylay has been available as a package named
`libspdylay-dev`. For the earlier Ubuntu release, you need to build
it yourself: http://tatsuhiro-t.github.io/spdylay/
To enable mruby support for nghttpx, `mruby To enable mruby support for nghttpx, `mruby
<https://github.com/mruby/mruby>`_ is required. We need to build <https://github.com/mruby/mruby>`_ is required. We need to build
mruby with C++ ABI explicitly turned on, and probably need other mruby with C++ ABI explicitly turned on, and probably need other
@@ -145,8 +157,22 @@ minimizes the risk of private key leakage when serious bug like
Heartbleed is exploited. The neverbleed is disabled by default. To Heartbleed is exploited. The neverbleed is disabled by default. To
enable it, use ``--with-neverbleed`` configure option. enable it, use ``--with-neverbleed`` configure option.
In order to compile the source code, gcc >= 6.0 or clang >= 6.0 is Building from git
required. C++ source code requires C++14 language features. -----------------
Building from git is easy, but please be sure that at least autoconf 2.68 is
used:
.. code-block:: text
$ git submodule update --init
$ autoreconf -i
$ automake
$ autoconf
$ ./configure
$ make
To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
.. note:: .. note::
@@ -193,40 +219,6 @@ required. C++ source code requires C++14 language features.
responsible to specify the correct values to these variables. For responsible to specify the correct values to these variables. For
complete list of these variables, run ``./configure -h``. complete list of these variables, run ``./configure -h``.
Building nghttp2 from release tar archive
-----------------------------------------
The nghttp2 project regularly releases tar archives which includes
nghttp2 source code, and generated build files. They can be
downloaded from `Releases
<https://github.com/nghttp2/nghttp2/releases>`_ page.
Building nghttp2 from git requires autotools development packages.
Building from tar archives does not require them, and thus it is much
easier. The usual build step is as follows:
.. code-block:: text
$ tar xf nghttp2-X.Y.Z.tar.bz2
$ cd nghttp2-X.Y.Z
$ ./configure
$ make
Building from git
-----------------
Building from git is easy, but please be sure that at least autoconf 2.68 is
used:
.. code-block:: text
$ git submodule update --init
$ autoreconf -i
$ automake
$ autoconf
$ ./configure
$ make
Notes for building on Windows (MSVC) Notes for building on Windows (MSVC)
------------------------------------ ------------------------------------
@@ -273,18 +265,6 @@ If you want to compile the applications under ``examples/``, you need
to remove or rename the ``event.h`` from libev's installation, because to remove or rename the ``event.h`` from libev's installation, because
it conflicts with libevent's installation. it conflicts with libevent's installation.
Notes for installation on Linux systems
--------------------------------------------
After installing nghttp2 tool suite with ``make install`` one might experience a similar error:
.. code-block:: text
nghttpx: error while loading shared libraries: libnghttp2.so.14: cannot open shared object file: No such file or directory
This means that the tool is unable to locate the ``libnghttp2.so`` shared library.
To update the shared library cache run ``sudo ldconfig``.
Building the documentation Building the documentation
-------------------------- --------------------------
@@ -320,6 +300,7 @@ its testing framework. We depend on the following libraries:
* golang.org/x/net/http2 * golang.org/x/net/http2
* golang.org/x/net/websocket * golang.org/x/net/websocket
* https://github.com/tatsuhiro-t/go-nghttp2 * https://github.com/tatsuhiro-t/go-nghttp2
* https://github.com/tatsuhiro-t/spdy
To download the above packages, after settings ``GOPATH``, run the To download the above packages, after settings ``GOPATH``, run the
following command under ``integration-tests`` directory: following command under ``integration-tests`` directory:
@@ -337,6 +318,11 @@ To run the tests, run the following command under
Inside the tests, we use port 3009 to run the test subject server. Inside the tests, we use port 3009 to run the test subject server.
.. note::
github.com/tatsuhiro-t/spdy is a copy used to be available at
golang.org/x/net/spdy, but it is now gone.
Migration from v0.7.15 or earlier Migration from v0.7.15 or earlier
--------------------------------- ---------------------------------
@@ -737,7 +723,7 @@ information. Here is sample output from ``nghttpd``:
nghttpx - proxy nghttpx - proxy
+++++++++++++++ +++++++++++++++
``nghttpx`` is a multi-threaded reverse proxy for HTTP/2, and ``nghttpx`` is a multi-threaded reverse proxy for HTTP/2, SPDY and
HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
push. push.
@@ -752,30 +738,31 @@ to know how to migrate from earlier releases.
``nghttpx`` implements `important performance-oriented features ``nghttpx`` implements `important performance-oriented features
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as <https://istlsfastyet.com/#server-performance>`_ in TLS, such as
session IDs, session tickets (with automatic key rotation), OCSP session IDs, session tickets (with automatic key rotation), OCSP
stapling, dynamic record sizing, ALPN/NPN, forward secrecy and HTTP/2. stapling, dynamic record sizing, ALPN/NPN, forward secrecy and SPDY &
``nghttpx`` also offers the functionality to share session cache and HTTP/2. ``nghttpx`` also offers the functionality to share session
ticket keys among multiple ``nghttpx`` instances via memcached. cache and ticket keys among multiple ``nghttpx`` instances via
memcached.
``nghttpx`` has 2 operation modes: ``nghttpx`` has 2 operation modes:
================== ================ ================ ============= ================== ====================== ================ =============
Mode option Frontend Backend Note Mode option Frontend Backend Note
================== ================ ================ ============= ================== ====================== ================ =============
default mode HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy default mode HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
``--http2-proxy`` HTTP/2, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy ``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
================== ================ ================ ============= ================== ====================== ================ =============
The interesting mode at the moment is the default mode. It works like The interesting mode at the moment is the default mode. It works like
a reverse proxy and listens for HTTP/2, and HTTP/1.1 and can be a reverse proxy and listens for HTTP/2, SPDY and HTTP/1.1 and can be
deployed as a SSL/TLS terminator for existing web server. deployed as a SSL/TLS terminator for existing web server.
In all modes, the frontend connections are encrypted by SSL/TLS by In all modes, the frontend connections are encrypted by SSL/TLS by
default. To disable encryption, use the ``no-tls`` keyword in default. To disable encryption, use the ``no-tls`` keyword in
``--frontend`` option. If encryption is disabled, incoming HTTP/1.1 ``--frontend`` option. If encryption is disabled, SPDY is disabled in
connections can be upgraded to HTTP/2 through HTTP Upgrade. On the the frontend and incoming HTTP/1.1 connections can be upgraded to
other hard, backend connections are not encrypted by default. To HTTP/2 through HTTP Upgrade. On the other hard, backend connections
encrypt backend connections, use ``tls`` keyword in ``--backend`` are not encrypted by default. To encrypt backend connections, use
option. ``tls`` keyword in ``--backend`` option.
``nghttpx`` supports a configuration file. See the ``--conf`` option and ``nghttpx`` supports a configuration file. See the ``--conf`` option and
sample configuration file ``nghttpx.conf.sample``. sample configuration file ``nghttpx.conf.sample``.
@@ -785,16 +772,16 @@ server:
.. code-block:: text .. code-block:: text
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
[reverse proxy] [reverse proxy]
With the ``--http2-proxy`` option, it works as forward proxy, and it With the ``--http2-proxy`` option, it works as forward proxy, and it
is so called secure HTTP/2 proxy: is so called secure HTTP/2 proxy (aka SPDY proxy):
.. code-block:: text .. code-block:: text
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
[secure proxy] (e.g., Squid, ATS) [secure proxy] (e.g., Squid, ATS)
The ``Client`` in the above example needs to be configured to use The ``Client`` in the above example needs to be configured to use
``nghttpx`` as secure proxy. ``nghttpx`` as secure proxy.
@@ -826,7 +813,7 @@ proxy through an HTTP proxy:
.. code-block:: text .. code-block:: text
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) -- Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
--===================---> HTTP/2 Proxy --===================---> HTTP/2 Proxy
(HTTP proxy tunnel) (e.g., nghttpx -s) (HTTP proxy tunnel) (e.g., nghttpx -s)
@@ -834,8 +821,9 @@ proxy through an HTTP proxy:
Benchmarking tool Benchmarking tool
----------------- -----------------
The ``h2load`` program is a benchmarking tool for HTTP/2. The UI of The ``h2load`` program is a benchmarking tool for HTTP/2 and SPDY.
``h2load`` is heavily inspired by ``weighttp`` The SPDY support is enabled if the program was built with the spdylay
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
(https://github.com/lighttpd/weighttp). The typical usage is as (https://github.com/lighttpd/weighttp). The typical usage is as
follows: follows:
@@ -951,7 +939,7 @@ output_length
The length of the compressed header block. The length of the compressed header block.
percentage_of_original_size percentage_of_original_size
``output_length`` / ``input_length`` * 100 ``input_length`` / ``output_length`` * 100
wire wire
The compressed header block as a hex string. The compressed header block as a hex string.
@@ -1332,7 +1320,7 @@ are:
* Boost::Thread * Boost::Thread
The server API is designed to build an HTTP/2 server very easily to utilize The server API is designed to build an HTTP/2 server very easily to utilize
C++14 anonymous functions and closures. The bare minimum example of C++11 anonymous functions and closures. The bare minimum example of
an HTTP/2 server looks like this: an HTTP/2 server looks like this:
.. code-block:: cpp .. code-block:: cpp

View File

@@ -40,9 +40,6 @@ if(LIBEVENT_INCLUDE_DIR)
# Libevent 2.0 # Libevent 2.0
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h" file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}") LIBEVENT_VERSION REGEX "${_version_regex}")
if("${LIBEVENT_VERSION}" STREQUAL "")
set(LIBEVENT_VERSION ${PC_LIBEVENT_VERSION})
endif()
else() else()
# Libevent 1.4 # Libevent 1.4
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h" file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h"

View File

@@ -34,9 +34,6 @@
/* Define to 1 if you have the `accept4` function. */ /* Define to 1 if you have the `accept4` function. */
#cmakedefine HAVE_ACCEPT4 1 #cmakedefine HAVE_ACCEPT4 1
/* Define to 1 if you have the `mkostemp` function. */
#cmakedefine HAVE_MKOSTEMP 1
/* Define to 1 if you have the `initgroups` function. */ /* Define to 1 if you have the `initgroups` function. */
#cmakedefine01 HAVE_DECL_INITGROUPS #cmakedefine01 HAVE_DECL_INITGROUPS

View File

@@ -25,7 +25,7 @@ dnl Do not change user variables!
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
AC_PREREQ(2.61) AC_PREREQ(2.61)
AC_INIT([nghttp2], [1.35.0], [t-tujikawa@users.sourceforge.net]) AC_INIT([nghttp2], [1.21.1], [t-tujikawa@users.sourceforge.net])
AC_CONFIG_AUX_DIR([.]) AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
@@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl See versioning rule: dnl See versioning rule:
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
AC_SUBST(LT_CURRENT, 31) AC_SUBST(LT_CURRENT, 27)
AC_SUBST(LT_REVISION, 1) AC_SUBST(LT_REVISION, 1)
AC_SUBST(LT_AGE, 17) AC_SUBST(LT_AGE, 13)
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"` 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"` minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
@@ -117,6 +117,11 @@ AC_ARG_WITH([jemalloc],
[Use jemalloc [default=check]])], [Use jemalloc [default=check]])],
[request_jemalloc=$withval], [request_jemalloc=check]) [request_jemalloc=$withval], [request_jemalloc=check])
AC_ARG_WITH([spdylay],
[AS_HELP_STRING([--with-spdylay],
[Use spdylay [default=no]])],
[request_spdylay=$withval], [request_spdylay=no])
AC_ARG_WITH([systemd], AC_ARG_WITH([systemd],
[AS_HELP_STRING([--with-systemd], [AS_HELP_STRING([--with-systemd],
[Enable systemd support in nghttpx [default=check]])], [Enable systemd support in nghttpx [default=check]])],
@@ -180,7 +185,7 @@ fi
save_CXXFLAGS="$CXXFLAGS" save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS= CXXFLAGS=
AX_CXX_COMPILE_STDCXX([14], [noext], [optional]) AX_CXX_COMPILE_STDCXX_11([noext], [optional])
CXX1XCXXFLAGS="$CXXFLAGS" CXX1XCXXFLAGS="$CXXFLAGS"
CXXFLAGS="$save_CXXFLAGS" CXXFLAGS="$save_CXXFLAGS"
@@ -405,7 +410,7 @@ if test "x${request_systemd}" = "xyes" &&
fi fi
# libxml2 (for src/nghttp) # libxml2 (for src/nghttp)
PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.6.26], PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.7.7],
[have_libxml2=yes], [have_libxml2=no]) [have_libxml2=yes], [have_libxml2=no])
if test "x${have_libxml2}" = "xyes"; then if test "x${have_libxml2}" = "xyes"; then
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.]) AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
@@ -453,6 +458,26 @@ if test "x${request_jemalloc}" = "xyes" &&
AC_MSG_ERROR([jemalloc was requested (--with-jemalloc) but not found]) AC_MSG_ERROR([jemalloc was requested (--with-jemalloc) but not found])
fi fi
# spdylay (for src/nghttpx and src/h2load)
have_spdylay=no
if test "x${request_spdylay}" != "xno"; then
PKG_CHECK_MODULES([LIBSPDYLAY], [libspdylay >= 1.3.2],
[have_spdylay=yes], [have_spdylay=no])
if test "x${have_spdylay}" = "xyes"; then
AC_DEFINE([HAVE_SPDYLAY], [1], [Define to 1 if you have `spdylay` library.])
else
AC_MSG_NOTICE($LIBSPDYLAY_PKG_ERRORS)
AC_MSG_NOTICE([The SPDY support in nghttpx and h2load will be disabled.])
fi
fi
if test "x${request_spdylay}" = "xyes" &&
test "x${have_spdylay}" != "xyes"; then
AC_MSG_ERROR([spdylay was requested (--with-spdylay) but not found])
fi
AM_CONDITIONAL([HAVE_SPDYLAY], [ test "x${have_spdylay}" = "xyes" ])
# Check Boost Asio library # Check Boost Asio library
have_asio_lib=no have_asio_lib=no
@@ -688,7 +713,6 @@ AC_CHECK_FUNCS([ \
memchr \ memchr \
memmove \ memmove \
memset \ memset \
mkostemp \
socket \ socket \
sqrt \ sqrt \
strchr \ strchr \
@@ -780,9 +804,6 @@ if test "x$werror" != "xno"; then
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"]) AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"]) AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"]) AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
# 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"])
AC_LANG_POP() AC_LANG_POP()
fi fi
@@ -903,6 +924,7 @@ AC_MSG_NOTICE([summary of build options:
Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}') Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
Libc-ares ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}') Libc-ares ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}') Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
Spdylay: ${have_spdylay} (CFLAGS='${LIBSPDYLAY_CFLAGS}' LIBS='${LIBSPDYLAY_LIBS}')
Jansson: ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}') Jansson: ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}')
Jemalloc: ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}') Jemalloc: ${have_jemalloc} (LIBS='${JEMALLOC_LIBS}')
Zlib: ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}') Zlib: ${have_zlib} (CFLAGS='${ZLIB_CFLAGS}' LIBS='${ZLIB_LIBS}')

View File

@@ -49,7 +49,6 @@ set(APIDOCS
nghttp2_rcbuf_decref.rst nghttp2_rcbuf_decref.rst
nghttp2_rcbuf_get_buf.rst nghttp2_rcbuf_get_buf.rst
nghttp2_rcbuf_incref.rst nghttp2_rcbuf_incref.rst
nghttp2_rcbuf_is_static.rst
nghttp2_select_next_protocol.rst nghttp2_select_next_protocol.rst
nghttp2_session_callbacks_del.rst nghttp2_session_callbacks_del.rst
nghttp2_session_callbacks_new.rst nghttp2_session_callbacks_new.rst

View File

@@ -74,14 +74,12 @@ APIDOCS= \
nghttp2_rcbuf_decref.rst \ nghttp2_rcbuf_decref.rst \
nghttp2_rcbuf_get_buf.rst \ nghttp2_rcbuf_get_buf.rst \
nghttp2_rcbuf_incref.rst \ nghttp2_rcbuf_incref.rst \
nghttp2_rcbuf_is_static.rst \
nghttp2_select_next_protocol.rst \ nghttp2_select_next_protocol.rst \
nghttp2_session_callbacks_del.rst \ nghttp2_session_callbacks_del.rst \
nghttp2_session_callbacks_new.rst \ nghttp2_session_callbacks_new.rst \
nghttp2_session_callbacks_set_before_frame_send_callback.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_callback.rst \
nghttp2_session_callbacks_set_error_callback.rst \ nghttp2_session_callbacks_set_error_callback.rst \
nghttp2_session_callbacks_set_error_callback2.rst \
nghttp2_session_callbacks_set_on_begin_frame_callback.rst \ nghttp2_session_callbacks_set_on_begin_frame_callback.rst \
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \ nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \ nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \
@@ -143,7 +141,6 @@ APIDOCS= \
nghttp2_session_set_local_window_size.rst \ nghttp2_session_set_local_window_size.rst \
nghttp2_session_set_next_stream_id.rst \ nghttp2_session_set_next_stream_id.rst \
nghttp2_session_set_stream_user_data.rst \ nghttp2_session_set_stream_user_data.rst \
nghttp2_session_set_user_data.rst \
nghttp2_session_terminate_session.rst \ nghttp2_session_terminate_session.rst \
nghttp2_session_terminate_session2.rst \ nghttp2_session_terminate_session2.rst \
nghttp2_session_upgrade.rst \ nghttp2_session_upgrade.rst \
@@ -164,7 +161,6 @@ APIDOCS= \
nghttp2_submit_extension.rst \ nghttp2_submit_extension.rst \
nghttp2_submit_goaway.rst \ nghttp2_submit_goaway.rst \
nghttp2_submit_headers.rst \ nghttp2_submit_headers.rst \
nghttp2_submit_origin.rst \
nghttp2_submit_ping.rst \ nghttp2_submit_ping.rst \
nghttp2_submit_priority.rst \ nghttp2_submit_priority.rst \
nghttp2_submit_push_promise.rst \ nghttp2_submit_push_promise.rst \
@@ -271,7 +267,7 @@ apiref.rst: \
$(APIDOCS): apiref.rst $(APIDOCS): apiref.rst
clean-local: clean-local:
if [ $(srcdir) != $(builddir) ]; then for i in $(RST_FILES); do rm -f $(builddir)/$$i; done fi [ $(srcdir) = $(builddir) ] || for i in $(RST_FILES); do [ -e $(builddir)/$$i ] && rm -f $(builddir)/$$i; done
-rm -f apiref.rst -rm -f apiref.rst
-rm -f $(APIDOCS) -rm -f $(APIDOCS)
-rm -rf $(BUILDDIR)/* -rm -rf $(BUILDDIR)/*

View File

@@ -13,7 +13,6 @@ import re
from docutils import nodes from docutils import nodes
from docutils.parsers.rst import directives from docutils.parsers.rst import directives
from docutils.parsers.rst import Directive
from sphinx import addnodes from sphinx import addnodes
from sphinx import version_info from sphinx import version_info
@@ -22,8 +21,10 @@ from sphinx.locale import l_, _
from sphinx.domains import Domain, ObjType, Index from sphinx.domains import Domain, ObjType, Index
from sphinx.directives import ObjectDescription from sphinx.directives import ObjectDescription
from sphinx.util.nodes import make_refnode from sphinx.util.nodes import make_refnode
from sphinx.util.compat import Directive
from sphinx.util.docfields import Field, GroupedField, TypedField from sphinx.util.docfields import Field, GroupedField, TypedField
# REs for Ruby signatures # REs for Ruby signatures
rb_sig_re = re.compile( rb_sig_re = re.compile(
r'''^ ([\w.]*\.)? # class name(s) r'''^ ([\w.]*\.)? # class name(s)

View File

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

View File

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

View File

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

View File

@@ -157,7 +157,7 @@ html_theme_path = ['@top_srcdir@/doc/_themes']
# If true, SmartyPants will be used to convert quotes and dashes to # If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities. # typographically correct entities.
#html_use_smartypants = False html_use_smartypants = False
# Custom sidebar templates, maps document names to template names. # Custom sidebar templates, maps document names to template names.
html_sidebars = { html_sidebars = {

View File

@@ -1,2 +0,0 @@
[parsers]
smart_quotes=no

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "H2LOAD" "1" "Nov 23, 2018" "1.35.0" "nghttp2" .TH "H2LOAD" "1" "Apr 09, 2017" "1.21.1" "nghttp2"
.SH NAME .SH NAME
h2load \- HTTP/2 benchmarking tool h2load \- HTTP/2 benchmarking tool
. .
@@ -35,7 +35,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
\fBh2load\fP [OPTIONS]... [URI]... \fBh2load\fP [OPTIONS]... [URI]...
.SH DESCRIPTION .SH DESCRIPTION
.sp .sp
benchmarking tool for HTTP/2 server benchmarking tool for HTTP/2 and SPDY server
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B <URI> .B <URI>
@@ -54,9 +54,7 @@ scheme, host or port values.
Number of requests across all clients. If it is used Number of requests across all clients. If it is used
with \fI\%\-\-timing\-script\-file\fP option, this option specifies with \fI\%\-\-timing\-script\-file\fP option, this option specifies
the number of requests each client performs rather than the number of requests each client performs rather than
the number of requests across all clients. This option the number of requests across all clients.
is ignored if timing\-based benchmarking is enabled (see
\fI\%\-\-duration\fP option).
.sp .sp
Default: \fB1\fP Default: \fB1\fP
.UNINDENT .UNINDENT
@@ -101,6 +99,7 @@ Default: \fB1\fP
.TP .TP
.B \-w, \-\-window\-bits=<N> .B \-w, \-\-window\-bits=<N>
Sets the stream level initial window size to (2**<N>)\-1. Sets the stream level initial window size to (2**<N>)\-1.
For SPDY, 2**<N> is used instead.
.sp .sp
Default: \fB30\fP Default: \fB30\fP
.UNINDENT .UNINDENT
@@ -108,7 +107,9 @@ Default: \fB30\fP
.TP .TP
.B \-W, \-\-connection\-window\-bits=<N> .B \-W, \-\-connection\-window\-bits=<N>
Sets the connection level initial window size to Sets the connection level initial window size to
(2**<N>)\-1. (2**<N>)\-1. For SPDY, if <N> is strictly less than 16,
this option is ignored. Otherwise 2**<N> is used for
SPDY.
.sp .sp
Default: \fB30\fP Default: \fB30\fP
.UNINDENT .UNINDENT
@@ -130,7 +131,8 @@ Default: \fBECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:EC
.B \-p, \-\-no\-tls\-proto=<PROTOID> .B \-p, \-\-no\-tls\-proto=<PROTOID>
Specify ALPN identifier of the protocol to be used when Specify ALPN identifier of the protocol to be used when
accessing http URI without SSL/TLS. accessing http URI without SSL/TLS.
Available protocols: h2c and http/1.1 Available protocols: h2c and
http/1.1
.sp .sp
Default: \fBh2c\fP Default: \fBh2c\fP
.UNINDENT .UNINDENT
@@ -155,7 +157,7 @@ example, with \fI\%\-t\fP2 and \fI\%\-r\fP4, each thread gets 2
connections per period. When the rate is 0, the program connections per period. When the rate is 0, the program
will run as it normally does, creating connections at will run as it normally does, creating connections at
whatever variable rate it wants. The default value for whatever variable rate it wants. The default value for
this option is 0. \fI\%\-r\fP and \fI\%\-D\fP are mutually exclusive. this option is 0.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -168,20 +170,6 @@ option is 1s.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-D, \-\-duration=<N>
Specifies the main duration for the measurements in case
of timing\-based benchmarking. \fI\%\-D\fP and \fI\%\-r\fP are mutually
exclusive.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-warm\-up\-time=<DURATION>
Specifies the time period before starting the actual
measurements, in case of timing\-based benchmarking.
Needs to provided along with \fI\%\-D\fP option.
.UNINDENT
.INDENT 0.0
.TP
.B \-T, \-\-connection\-active\-timeout=<DURATION> .B \-T, \-\-connection\-active\-timeout=<DURATION>
Specifies the maximum time that h2load is willing to Specifies the maximum time that h2load is willing to
keep a connection open, regardless of the activity on keep a connection open, regardless of the activity on
@@ -347,7 +335,8 @@ compression. Let \fBdecompressed(headers)\fP to the number of bytes
used for header fields after decompression. The \fBspace savings\fP used for header fields after decompression. The \fBspace savings\fP
is calculated by (1 \- \fBheaders\fP / \fBdecompressed(headers)\fP) * is calculated by (1 \- \fBheaders\fP / \fBdecompressed(headers)\fP) *
100. For HTTP/1.1, this is usually 0.00%, since it does not have 100. For HTTP/1.1, this is usually 0.00%, since it does not have
header compression. For HTTP/2, it shows some insightful numbers. header compression. For HTTP/2 and SPDY, it shows some insightful
numbers.
.TP .TP
.B data .B data
The number of response body bytes received from the server. The number of response body bytes received from the server.
@@ -377,16 +366,13 @@ range (mean +/\- sd) against total number of successful requests.
.INDENT 7.0 .INDENT 7.0
.TP .TP
.B min .B min
The minimum time taken to connect to a server including TLS The minimum time taken to connect to a server.
handshake.
.TP .TP
.B max .B max
The maximum time taken to connect to a server including TLS The maximum time taken to connect to a server.
handshake.
.TP .TP
.B mean .B mean
The mean time taken to connect to a server including TLS The mean time taken to connect to a server.
handshake.
.TP .TP
.B sd .B sd
The standard deviation of the time taken to connect to a server. The standard deviation of the time taken to connect to a server.
@@ -447,7 +433,7 @@ h2load sets large flow control window by default, and effectively
disables flow control to avoid under utilization of server disables flow control to avoid under utilization of server
performance. To set smaller flow control window, use \fI\%\-w\fP and performance. To set smaller flow control window, use \fI\%\-w\fP and
\fI\%\-W\fP options. For example, use \fB\-w16 \-W16\fP to set default \fI\%\-W\fP options. For example, use \fB\-w16 \-W16\fP to set default
window size described in HTTP/2 protocol specification. window size described in HTTP/2 and SPDY protocol specification.
.SH SEE ALSO .SH SEE ALSO
.sp .sp
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP \fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP

View File

@@ -14,7 +14,7 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
benchmarking tool for HTTP/2 server benchmarking tool for HTTP/2 and SPDY server
.. describe:: <URI> .. describe:: <URI>
@@ -34,9 +34,7 @@ OPTIONS
Number of requests across all clients. If it is used Number of requests across all clients. If it is used
with :option:`--timing-script-file` option, this option specifies with :option:`--timing-script-file` option, this option specifies
the number of requests each client performs rather than the number of requests each client performs rather than
the number of requests across all clients. This option the number of requests across all clients.
is ignored if timing-based benchmarking is enabled (see
:option:`--duration` option).
Default: ``1`` Default: ``1``
@@ -76,13 +74,16 @@ OPTIONS
.. option:: -w, --window-bits=<N> .. option:: -w, --window-bits=<N>
Sets the stream level initial window size to (2\*\*<N>)-1. Sets the stream level initial window size to (2\*\*<N>)-1.
For SPDY, 2\*\*<N> is used instead.
Default: ``30`` Default: ``30``
.. option:: -W, --connection-window-bits=<N> .. option:: -W, --connection-window-bits=<N>
Sets the connection level initial window size to Sets the connection level initial window size to
(2\*\*<N>)-1. (2\*\*<N>)-1. For SPDY, if <N> is strictly less than 16,
this option is ignored. Otherwise 2\*\*<N> is used for
SPDY.
Default: ``30`` Default: ``30``
@@ -101,7 +102,8 @@ OPTIONS
Specify ALPN identifier of the protocol to be used when Specify ALPN identifier of the protocol to be used when
accessing http URI without SSL/TLS. accessing http URI without SSL/TLS.
Available protocols: h2c and http/1.1 Available protocols: h2c and
http/1.1
Default: ``h2c`` Default: ``h2c``
@@ -124,7 +126,7 @@ OPTIONS
connections per period. When the rate is 0, the program connections per period. When the rate is 0, the program
will run as it normally does, creating connections at will run as it normally does, creating connections at
whatever variable rate it wants. The default value for whatever variable rate it wants. The default value for
this option is 0. :option:`-r` and :option:`\-D` are mutually exclusive. this option is 0.
.. option:: --rate-period=<DURATION> .. option:: --rate-period=<DURATION>
@@ -134,18 +136,6 @@ OPTIONS
the rate option is not used. The default value for this the rate option is not used. The default value for this
option is 1s. option is 1s.
.. option:: -D, --duration=<N>
Specifies the main duration for the measurements in case
of timing-based benchmarking. :option:`-D` and :option:`\-r` are mutually
exclusive.
.. option:: --warm-up-time=<DURATION>
Specifies the time period before starting the actual
measurements, in case of timing-based benchmarking.
Needs to provided along with :option:`-D` option.
.. option:: -T, --connection-active-timeout=<DURATION> .. option:: -T, --connection-active-timeout=<DURATION>
Specifies the maximum time that h2load is willing to Specifies the maximum time that h2load is willing to
@@ -294,7 +284,8 @@ traffic
used for header fields after decompression. The ``space savings`` used for header fields after decompression. The ``space savings``
is calculated by (1 - ``headers`` / ``decompressed(headers)``) * is calculated by (1 - ``headers`` / ``decompressed(headers)``) *
100. For HTTP/1.1, this is usually 0.00%, since it does not have 100. For HTTP/1.1, this is usually 0.00%, since it does not have
header compression. For HTTP/2, it shows some insightful numbers. header compression. For HTTP/2 and SPDY, it shows some insightful
numbers.
data data
The number of response body bytes received from the server. The number of response body bytes received from the server.
@@ -313,14 +304,11 @@ time for request
time for connect time for connect
min min
The minimum time taken to connect to a server including TLS The minimum time taken to connect to a server.
handshake.
max max
The maximum time taken to connect to a server including TLS The maximum time taken to connect to a server.
handshake.
mean mean
The mean time taken to connect to a server including TLS The mean time taken to connect to a server.
handshake.
sd sd
The standard deviation of the time taken to connect to a server. The standard deviation of the time taken to connect to a server.
+/- sd +/- sd
@@ -365,7 +353,7 @@ h2load sets large flow control window by default, and effectively
disables flow control to avoid under utilization of server disables flow control to avoid under utilization of server
performance. To set smaller flow control window, use :option:`-w` and performance. To set smaller flow control window, use :option:`-w` and
:option:`-W` options. For example, use ``-w16 -W16`` to set default :option:`-W` options. For example, use ``-w16 -W16`` to set default
window size described in HTTP/2 protocol specification. window size described in HTTP/2 and SPDY protocol specification.
SEE ALSO SEE ALSO
-------- --------

View File

@@ -41,7 +41,8 @@ traffic
used for header fields after decompression. The ``space savings`` used for header fields after decompression. The ``space savings``
is calculated by (1 - ``headers`` / ``decompressed(headers)``) * is calculated by (1 - ``headers`` / ``decompressed(headers)``) *
100. For HTTP/1.1, this is usually 0.00%, since it does not have 100. For HTTP/1.1, this is usually 0.00%, since it does not have
header compression. For HTTP/2, it shows some insightful numbers. header compression. For HTTP/2 and SPDY, it shows some insightful
numbers.
data data
The number of response body bytes received from the server. The number of response body bytes received from the server.
@@ -60,14 +61,11 @@ time for request
time for connect time for connect
min min
The minimum time taken to connect to a server including TLS The minimum time taken to connect to a server.
handshake.
max max
The maximum time taken to connect to a server including TLS The maximum time taken to connect to a server.
handshake.
mean mean
The mean time taken to connect to a server including TLS The mean time taken to connect to a server.
handshake.
sd sd
The standard deviation of the time taken to connect to a server. The standard deviation of the time taken to connect to a server.
+/- sd +/- sd
@@ -112,7 +110,7 @@ h2load sets large flow control window by default, and effectively
disables flow control to avoid under utilization of server disables flow control to avoid under utilization of server
performance. To set smaller flow control window, use :option:`-w` and performance. To set smaller flow control window, use :option:`-w` and
:option:`-W` options. For example, use ``-w16 -W16`` to set default :option:`-W` options. For example, use ``-w16 -W16`` to set default
window size described in HTTP/2 protocol specification. window size described in HTTP/2 and SPDY protocol specification.
SEE ALSO SEE ALSO
-------- --------

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "NGHTTP" "1" "Nov 23, 2018" "1.35.0" "nghttp2" .TH "NGHTTP" "1" "Apr 09, 2017" "1.21.1" "nghttp2"
.SH NAME .SH NAME
nghttp \- HTTP/2 client nghttp \- HTTP/2 client
. .
@@ -236,12 +236,6 @@ combined with the \fI\%\-d\fP option.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-y, \-\-no\-verify\-peer
Suppress warning on server certificate verification
failure.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-version .B \-\-version
Display version information and exit. Display version information and exit.
.UNINDENT .UNINDENT

View File

@@ -186,11 +186,6 @@ OPTIONS
Continue interim response. This option is ignored unless Continue interim response. This option is ignored unless
combined with the :option:`-d` option. combined with the :option:`-d` option.
.. option:: -y, --no-verify-peer
Suppress warning on server certificate verification
failure.
.. option:: --version .. option:: --version
Display version information and exit. Display version information and exit.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "NGHTTPD" "1" "Nov 23, 2018" "1.35.0" "nghttp2" .TH "NGHTTPD" "1" "Apr 09, 2017" "1.21.1" "nghttp2"
.SH NAME .SH NAME
nghttpd \- HTTP/2 server nghttpd \- HTTP/2 server
. .

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText. .\" Man page generated from reStructuredText.
. .
.TH "NGHTTPX" "1" "Nov 23, 2018" "1.35.0" "nghttp2" .TH "NGHTTPX" "1" "Apr 09, 2017" "1.21.1" "nghttp2"
.SH NAME .SH NAME
nghttpx \- HTTP/2 proxy nghttpx \- HTTP/2 proxy
. .
@@ -35,7 +35,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
\fBnghttpx\fP [OPTIONS]... [<PRIVATE_KEY> <CERT>] \fBnghttpx\fP [OPTIONS]... [<PRIVATE_KEY> <CERT>]
.SH DESCRIPTION .SH DESCRIPTION
.sp .sp
A reverse proxy for HTTP/2, and HTTP/1. A reverse proxy for HTTP/2, HTTP/1 and SPDY.
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B <PRIVATE_KEY> .B <PRIVATE_KEY>
@@ -73,16 +73,14 @@ path which ends with "\fI/\fP" also matches the request path
which only lacks trailing \(aq\fI/\fP\(aq (e.g., path "\fI/foo/\fP" which only lacks trailing \(aq\fI/\fP\(aq (e.g., path "\fI/foo/\fP"
matches request path "\fI/foo\fP"). If it does not end with matches request path "\fI/foo\fP"). If it does not end with
"\fI/\fP", it performs exact match against the request path. "\fI/\fP", it performs exact match against the request path.
If host is given, it performs a match against the If host is given, it performs exact match against the
request host. For a request received on the frontend request host. If host alone is given, "\fI/\fP" is appended
listener with "sni\-fwd" parameter enabled, SNI host is to it, so that it matches all request paths under the
used instead of a request host. If host alone is given, host (e.g., specifying "nghttp2.org" equals to
"\fI/\fP" is appended to it, so that it matches all request "nghttp2.org/"). CONNECT method is treated specially.
paths under the host (e.g., specifying "nghttp2.org" It does not have path, and we don\(aqt allow empty path.
equals to "nghttp2.org/"). CONNECT method is treated To workaround this, we assume that CONNECT method has
specially. It does not have path, and we don\(aqt allow "\fI/\fP" as path.
empty path. To workaround this, we assume that CONNECT
method has "\fI/\fP" as path.
.sp .sp
Patterns with host take precedence over patterns with Patterns with host take precedence over patterns with
just path. Then, longer patterns take precedence over just path. Then, longer patterns take precedence over
@@ -96,18 +94,6 @@ host pattern "*.nghttp2.org" matches against
match against "nghttp2.org". The exact hosts match match against "nghttp2.org". The exact hosts match
takes precedence over the wildcard hosts match. takes precedence over the wildcard hosts match.
.sp .sp
If path part ends with "*", it is treated as wildcard
path. The wildcard path behaves differently from the
normal path. For normal path, match is made around the
boundary of path component separator,"\fI/\fP". On the other
hand, the wildcard path does not take into account the
path component separator. All paths which include the
wildcard path without last "*" as prefix, and are
strictly longer than wildcard path without last "*" are
matched. "*" must match at least one character. For
example, the pattern "\fI/foo*\fP" matches "\fI/foo/\fP" and
"\fI/foobar\fP". But it does not match "\fI/foo\fP", or "\fI/fo\fP".
.sp
If <PATTERN> is omitted or empty string, "\fI/\fP" is used as If <PATTERN> is omitted or empty string, "\fI/\fP" is used as
pattern, which matches all request paths (catch\-all pattern, which matches all request paths (catch\-all
pattern). The catch\-all backend must be given. pattern). The catch\-all backend must be given.
@@ -137,15 +123,12 @@ Several parameters <PARAM> are accepted after <PATTERN>.
The parameters are delimited by ";". The available The parameters are delimited by ";". The available
parameters are: "proto=<PROTO>", "tls", parameters are: "proto=<PROTO>", "tls",
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", "sni=<SNI_HOST>", "fall=<N>", "rise=<N>",
"affinity=<METHOD>", "dns", "redirect\-if\-not\-tls", "affinity=<METHOD>", "dns", and "redirect\-if\-not\-tls".
"upgrade\-scheme", "mruby=<PATH>", The parameter consists of keyword, and optionally
"read\-timeout=<DURATION>", and followed by "=" and value. For example, the parameter
"write\-timeout=<DURATION>". The parameter consists of "proto=h2" consists of the keyword "proto" and value
keyword, and optionally followed by "=" and value. For "h2". The parameter "tls" consists of the keyword "tls"
example, the parameter "proto=h2" consists of the without value. Each parameter is described as follows.
keyword "proto" and value "h2". The parameter "tls"
consists of the keyword "tls" without value. Each
parameter is described as follows.
.sp .sp
The backend application protocol can be specified using The backend application protocol can be specified using
optional "proto" parameter, and in the form of optional "proto" parameter, and in the form of
@@ -183,32 +166,16 @@ state, and this is the default behaviour.
The session affinity is enabled using The session affinity is enabled using
"affinity=<METHOD>" parameter. If "ip" is given in "affinity=<METHOD>" parameter. If "ip" is given in
<METHOD>, client IP based session affinity is enabled. <METHOD>, client IP based session affinity is enabled.
If "cookie" is given in <METHOD>, cookie based session If "none" is given in <METHOD>, session affinity is
affinity is enabled. If "none" is given in <METHOD>, disabled, and this is the default. The session affinity
session affinity is disabled, and this is the default. is enabled per <PATTERN>. If at least one backend has
The session affinity is enabled per <PATTERN>. If at "affinity" parameter, and its <METHOD> is not "none",
least one backend has "affinity" parameter, and its session affinity is enabled for all backend servers
<METHOD> is not "none", session affinity is enabled for sharing the same <PATTERN>. It is advised to set
all backend servers sharing the same <PATTERN>. It is "affinity" parameter to all backend explicitly if
advised to set "affinity" parameter to all backend session affinity is desired. The session affinity may
explicitly if session affinity is desired. The session break if one of the backend gets unreachable, or backend
affinity may break if one of the backend gets settings are reloaded or replaced by API.
unreachable, or backend settings are reloaded or
replaced by API.
.sp
If "affinity=cookie" is used, the additional
configuration is required.
"affinity\-cookie\-name=<NAME>" must be used to specify a
name of cookie to use. Optionally,
"affinity\-cookie\-path=<PATH>" can be used to specify a
path which cookie is applied. The optional
"affinity\-cookie\-secure=<SECURE>" controls the Secure
attribute of a cookie. The default value is "auto", and
the Secure attribute is determined by a request scheme.
If a request scheme is "https", then Secure attribute is
set. Otherwise, it is not set. If <SECURE> is "yes",
the Secure attribute is always set. If <SECURE> is
"no", the Secure attribute is always omitted.
.sp .sp
By default, name resolution of backend host name is done By default, name resolution of backend host name is done
at start up, or reloading configuration. If "dns" at start up, or reloading configuration. If "dns"
@@ -231,26 +198,6 @@ the same <PATTERN>. It is advised to set
"redirect\-if\-no\-tls" parameter to all backends "redirect\-if\-no\-tls" parameter to all backends
explicitly if this feature is desired. explicitly if this feature is desired.
.sp .sp
If "upgrade\-scheme" parameter is used along with "tls"
parameter, HTTP/2 :scheme pseudo header field is changed
to "https" from "http" when forwarding a request to this
particular backend. This is a workaround for a backend
server which requires "https" :scheme pseudo header
field on TLS encrypted connection.
.sp
"mruby=<PATH>" parameter specifies a path to mruby
script file which is invoked when this pattern is
matched. All backends which share the same pattern must
have the same mruby path.
.sp
"read\-timeout=<DURATION>" and "write\-timeout=<DURATION>"
parameters specify the read and write timeout of the
backend connection when this pattern is matched. All
backends which share the same pattern must have the same
timeouts. If these timeouts are entirely omitted for a
pattern, \fI\%\-\-backend\-read\-timeout\fP and
\fI\%\-\-backend\-write\-timeout\fP are used.
.sp
Since ";" and ":" are used as delimiter, <PATTERN> must Since ";" and ":" are used as delimiter, <PATTERN> must
not contain these characters. Since ";" has special not contain these characters. Since ";" has special
meaning in shell, the option value must be quoted. meaning in shell, the option value must be quoted.
@@ -274,11 +221,6 @@ parameters are mutually exclusive.
Optionally, TLS can be disabled by specifying "no\-tls" Optionally, TLS can be disabled by specifying "no\-tls"
parameter. TLS is enabled by default. parameter. TLS is enabled by default.
.sp .sp
If "sni\-fwd" parameter is used, when performing a match
to select a backend server, SNI host name received from
the client is used instead of the request host. See
\fI\%\-\-backend\fP option about the pattern match.
.sp
To make this frontend as API endpoint, specify "api" To make this frontend as API endpoint, specify "api"
parameter. This is disabled by default. It is parameter. This is disabled by default. It is
important to limit the access to the API frontend. important to limit the access to the API frontend.
@@ -494,7 +436,8 @@ this option will be simply ignored.
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-frontend\-http2\-read\-timeout=<DURATION> .B \-\-frontend\-http2\-read\-timeout=<DURATION>
Specify read timeout for HTTP/2 frontend connection. Specify read timeout for HTTP/2 and SPDY frontend
connection.
.sp .sp
Default: \fB3m\fP Default: \fB3m\fP
.UNINDENT .UNINDENT
@@ -523,16 +466,16 @@ Default: \fB1m\fP
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-stream\-read\-timeout=<DURATION> .B \-\-stream\-read\-timeout=<DURATION>
Specify read timeout for HTTP/2 streams. 0 means no Specify read timeout for HTTP/2 and SPDY streams. 0
timeout. means no timeout.
.sp .sp
Default: \fB0\fP Default: \fB0\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-stream\-write\-timeout=<DURATION> .B \-\-stream\-write\-timeout=<DURATION>
Specify write timeout for HTTP/2 streams. 0 means no Specify write timeout for HTTP/2 and SPDY streams. 0
timeout. means no timeout.
.sp .sp
Default: \fB1m\fP Default: \fB1m\fP
.UNINDENT .UNINDENT
@@ -611,43 +554,19 @@ Default: \fB2m\fP
.B \-\-ciphers=<SUITE> .B \-\-ciphers=<SUITE>
Set allowed cipher list for frontend connection. The Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1). format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use \fI\%\-\-tls13\-ciphers\fP for TLSv1.3.
.sp .sp
Default: \fBECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256\fP Default: \fBECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-tls13\-ciphers=<SUITE>
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
\fI\%\-\-ciphers\fP for TLSv1.2 or earlier.
.sp
Default: \fBTLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-client\-ciphers=<SUITE> .B \-\-client\-ciphers=<SUITE>
Set allowed cipher list for backend connection. The Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1). format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use \fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.3.
.sp .sp
Default: \fBECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256\fP Default: \fBECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-tls13\-client\-ciphers=<SUITE>
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
\fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.2 or earlier.
.sp
Default: \fBTLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ecdh\-curves=<LIST> .B \-\-ecdh\-curves=<LIST>
Set supported curve list for frontend connections. Set supported curve list for frontend connections.
<LIST> is a colon separated list of curve NID or names <LIST> is a colon separated list of curve NID or names
@@ -666,14 +585,11 @@ enabled for backend connections.
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-cacert=<PATH> .B \-\-cacert=<PATH>
Set path to trusted CA certificate file. It is used in Set path to trusted CA certificate file used in backend
backend TLS connections to verify peer\(aqs certificate. TLS connections. The file must be in PEM format. It
It is also used to verify OCSP response from the script can contain multiple certificates. If the linked
set by \fI\%\-\-fetch\-ocsp\-response\-file\fP\&. The file must be in OpenSSL is configured to load system wide certificates,
PEM format. It can contain multiple certificates. If they are loaded at startup regardless of this option.
the linked OpenSSL is configured to load system wide
certificates, they are loaded at startup regardless of
this option.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -688,12 +604,12 @@ password protected it\(aqll be requested interactively.
Specify additional certificate and private key file. Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. If nghttpx indicated by client using TLS SNI extension. If nghttpx
is built with OpenSSL >= 1.0.2, the shared elliptic is built with OpenSSL >= 1.0.2, signature algorithms
curves (e.g., P\-256) between client and server are also (e.g., ECDSA+SHA256, RSA+SHA256) presented by client are
taken into consideration. This allows nghttpx to send also taken into consideration. This allows nghttpx to
ECDSA certificate to modern clients, while sending RSA send ECDSA certificate to modern clients, while sending
based certificate to older clients. This option can be RSA based certificate to older clients. This option can
used multiple times. To make OCSP stapling work, be used multiple times. To make OCSP stapling work,
<CERTPATH> must be absolute path. <CERTPATH> must be absolute path.
.sp .sp
Additional parameter can be specified in <PARAM>. The Additional parameter can be specified in <PARAM>. The
@@ -738,14 +654,6 @@ can contain multiple certificates.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-verify\-client\-tolerate\-expired
Accept expired client certificate. Operator should
handle the expired client certificate by some means
(e.g., mruby script). Otherwise, this option might
cause a security risk.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-client\-private\-key\-file=<PATH> .B \-\-client\-private\-key\-file=<PATH>
Path to file that contains client private key used in Path to file that contains client private key used in
backend client authentication. backend client authentication.
@@ -764,14 +672,10 @@ done in case\-insensitive manner. The versions between
\fI\%\-\-tls\-min\-proto\-version\fP and \fI\%\-\-tls\-max\-proto\-version\fP are \fI\%\-\-tls\-min\-proto\-version\fP and \fI\%\-\-tls\-max\-proto\-version\fP are
enabled. If the protocol list advertised by client does enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error not overlap this range, you will receive the error
message "unknown protocol". If a protocol version lower message "unknown protocol". The available versions are:
than TLSv1.2 is specified, make sure that the compatible TLSv1.2, TLSv1.1, and TLSv1.0
ciphers are included in \fI\%\-\-ciphers\fP 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
.sp .sp
Default: \fBTLSv1.2\fP Default: \fBTLSv1.1\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -782,9 +686,9 @@ done in case\-insensitive manner. The versions between
enabled. If the protocol list advertised by client does enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error not overlap this range, you will receive the error
message "unknown protocol". The available versions are: message "unknown protocol". The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0 TLSv1.2, TLSv1.1, and TLSv1.0
.sp .sp
Default: \fBTLSv1.3\fP Default: \fBTLSv1.2\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -901,20 +805,6 @@ Default: \fB4h\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-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.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-verify\-ocsp
nghttpx does not verify OCSP response.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-ocsp .B \-\-no\-ocsp
Disable OCSP stapling. Disable OCSP stapling.
.UNINDENT .UNINDENT
@@ -1037,32 +927,14 @@ HTTP/2. To use those cipher suites with HTTP/2,
consider to use \fI\%\-\-client\-no\-http2\-cipher\-black\-list\fP consider to use \fI\%\-\-client\-no\-http2\-cipher\-black\-list\fP
option. But be aware its implications. option. But be aware its implications.
.UNINDENT .UNINDENT
.INDENT 0.0 .SS HTTP/2 and SPDY
.TP
.B \-\-tls\-no\-postpone\-early\-data
By default, nghttpx postpones forwarding HTTP requests
sent in early data, including those sent in partially in
it, until TLS handshake finishes. If all backend server
recognizes "Early\-Data" header field, using this option
makes nghttpx not postpone forwarding request and get
full potential of 0\-RTT data.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-max\-early\-data=<SIZE>
Sets the maximum amount of 0\-RTT data that server
accepts.
.sp
Default: \fB16K\fP
.UNINDENT
.SS HTTP/2
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-c, \-\-frontend\-http2\-max\-concurrent\-streams=<N> .B \-c, \-\-frontend\-http2\-max\-concurrent\-streams=<N>
Set the maximum number of the concurrent streams in one Set the maximum number of the concurrent streams in one
frontend HTTP/2 session. frontend HTTP/2 and SPDY session.
.sp .sp
Default: \fB100\fP Default: \(ga\(ga 100\(ga\(ga
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -1077,16 +949,17 @@ Default: \fB100\fP
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-frontend\-http2\-window\-size=<SIZE> .B \-\-frontend\-http2\-window\-size=<SIZE>
Sets the per\-stream initial window size of HTTP/2 Sets the per\-stream initial window size of HTTP/2 and
frontend connection. SPDY frontend connection.
.sp .sp
Default: \fB65535\fP Default: \fB65535\fP
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-frontend\-http2\-connection\-window\-size=<SIZE> .B \-\-frontend\-http2\-connection\-window\-size=<SIZE>
Sets the per\-connection window size of HTTP/2 frontend Sets the per\-connection window size of HTTP/2 and SPDY
connection. frontend connection. For SPDY connection, the value
less than 64KiB is rounded up to 64KiB.
.sp .sp
Default: \fB65535\fP Default: \fB65535\fP
.UNINDENT .UNINDENT
@@ -1127,7 +1000,8 @@ default mode and HTTP/2 frontend via Link header field.
It is also supported if both frontend and backend are It is also supported if both frontend and backend are
HTTP/2 in default mode. In this case, server push from HTTP/2 in default mode. In this case, server push from
backend session is relayed to frontend, and server push backend session is relayed to frontend, and server push
via Link header field is also supported. via Link header field is also supported. SPDY frontend
does not support server push.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -1198,7 +1072,7 @@ Default: \fB4K\fP
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B (default mode) .B (default mode)
Accept HTTP/2, and HTTP/1.1 over SSL/TLS. "no\-tls" Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no\-tls"
parameter is used in \fI\%\-\-frontend\fP option, accept HTTP/2 parameter is used in \fI\%\-\-frontend\fP option, accept HTTP/2
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1 and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
connection can be upgraded to HTTP/2 through HTTP connection can be upgraded to HTTP/2 through HTTP
@@ -1268,32 +1142,15 @@ $alpn: ALPN identifier of the protocol which generates
the response. For HTTP/1, ALPN is always http/1.1, the response. For HTTP/1, ALPN is always http/1.1,
regardless of minor version. regardless of minor version.
.IP \(bu 2 .IP \(bu 2
$tls_cipher: cipher used for SSL/TLS connection. $ssl_cipher: cipher used for SSL/TLS connection.
.IP \(bu 2 .IP \(bu 2
$tls_client_fingerprint_sha256: SHA\-256 fingerprint of $ssl_protocol: protocol for SSL/TLS connection.
client certificate.
.IP \(bu 2 .IP \(bu 2
$tls_client_fingerprint_sha1: SHA\-1 fingerprint of $ssl_session_id: session ID for SSL/TLS connection.
client certificate.
.IP \(bu 2 .IP \(bu 2
$tls_client_subject_name: subject name in client $ssl_session_reused: "r" if SSL/TLS session was
certificate.
.IP \(bu 2
$tls_client_issuer_name: issuer name in client
certificate.
.IP \(bu 2
$tls_client_serial: serial number in client
certificate.
.IP \(bu 2
$tls_protocol: protocol for SSL/TLS connection.
.IP \(bu 2
$tls_session_id: session ID for SSL/TLS connection.
.IP \(bu 2
$tls_session_reused: "r" if SSL/TLS session was
reused. Otherwise, "." reused. Otherwise, "."
.IP \(bu 2 .IP \(bu 2
$tls_sni: SNI server name for SSL/TLS connection.
.IP \(bu 2
$backend_host: backend host used to fulfill the $backend_host: backend host used to fulfill the
request. "\-" if backend host is not available. request. "\-" if backend host is not available.
.IP \(bu 2 .IP \(bu 2
@@ -1350,21 +1207,6 @@ requests.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-no\-add\-x\-forwarded\-proto
Don\(aqt append additional X\-Forwarded\-Proto header field
to the backend request. If inbound client sets
X\-Forwarded\-Proto, and
\fI\%\-\-no\-strip\-incoming\-x\-forwarded\-proto\fP option is used,
they are passed to the backend.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-strip\-incoming\-x\-forwarded\-proto
Don\(aqt strip X\-Forwarded\-Proto header field from inbound
client requests.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-add\-forwarded=<LIST> .B \-\-add\-forwarded=<LIST>
Append RFC 7239 Forwarded header field with parameters Append RFC 7239 Forwarded header field with parameters
specified in comma delimited list <LIST>. The supported specified in comma delimited list <LIST>. The supported
@@ -1418,12 +1260,6 @@ is received, it is left unaltered.
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-no\-strip\-incoming\-early\-data
Don\(aqt strip Early\-Data header field from inbound client
requests.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-location\-rewrite .B \-\-no\-location\-rewrite
Don\(aqt rewrite location header field in default mode. Don\(aqt rewrite location header field in default mode.
When \fI\%\-\-http2\-proxy\fP is used, location header field will When \fI\%\-\-http2\-proxy\fP is used, location header field will
@@ -1541,7 +1377,7 @@ Default: \fB443\fP
.B \-\-api\-max\-request\-body=<SIZE> .B \-\-api\-max\-request\-body=<SIZE>
Set the maximum size of request body for API request. Set the maximum size of request body for API request.
.sp .sp
Default: \fB32M\fP Default: \fB16K\fP
.UNINDENT .UNINDENT
.SS DNS .SS DNS
.INDENT 0.0 .INDENT 0.0
@@ -1624,37 +1460,17 @@ Set path to save PID of this program.
Run this program as <USER>. This option is intended to Run this program as <USER>. This option is intended to
be used to drop root privileges. be used to drop root privileges.
.UNINDENT .UNINDENT
.INDENT 0.0
.TP
.B \-\-single\-process
Run this program in a single process mode for debugging
purpose. Without this option, nghttpx creates at least
2 processes: master and worker processes. If this
option is used, master and worker are unified into a
single process. nghttpx still spawns additional process
if neverbleed is used. In the single process mode, the
signal handling feature is disabled.
.UNINDENT
.SS Scripting .SS Scripting
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-mruby\-file=<PATH> .B \-\-mruby\-file=<PATH>
Set mruby script file Set mruby script file
.UNINDENT .UNINDENT
.INDENT 0.0
.TP
.B \-\-ignore\-per\-pattern\-mruby\-error
Ignore mruby compile error for per\-pattern mruby script
file. If error occurred, it is treated as if no mruby
file were specified for the pattern.
.UNINDENT
.SS Misc .SS Misc
.INDENT 0.0 .INDENT 0.0
.TP .TP
.B \-\-conf=<PATH> .B \-\-conf=<PATH>
Load configuration from <PATH>. Please note that Load configuration from <PATH>.
nghttpx always tries to read the default configuration
file if \fI\%\-\-conf\fP is not given.
.sp .sp
Default: \fB/etc/nghttpx/nghttpx.conf\fP Default: \fB/etc/nghttpx/nghttpx.conf\fP
.UNINDENT .UNINDENT
@@ -1748,7 +1564,7 @@ follows:
.INDENT 7.0 .INDENT 7.0
.TP .TP
.B <datetime> .B <datetime>
It is a combination of date and time when the log is written. It It is a conbination of date and time when the log is written. It
is in ISO 8601 format. is in ISO 8601 format.
.TP .TP
.B <master\-pid> .B <master\-pid>
@@ -1877,22 +1693,6 @@ be customized using \fI\%\-\-fetch\-ocsp\-response\-file\fP option.
.sp .sp
If OCSP query is failed, previous OCSP response, if any, is continued If OCSP query is failed, previous OCSP response, if any, is continued
to be used. to be used.
.sp
\fI\%\-\-fetch\-ocsp\-response\-file\fP 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 \fBfetch\-ocsp\-response\fP 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 \fBfetch\-ocsp\-response\fP\&.
Instead, you can retrieve OCSP response in some way, and store it in a
disk or a shared database. Then specify a program in
\fI\%\-\-fetch\-ocsp\-response\-file\fP 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 \fBfetch\-ocsp\-response\fP
script.
.SH TLS SESSION RESUMPTION .SH TLS SESSION RESUMPTION
.sp .sp
nghttpx supports TLS session resumption through both session ID and nghttpx supports TLS session resumption through both session ID and
@@ -1903,7 +1703,7 @@ By default, session ID is shared by all worker threads.
.sp .sp
If \fI\%\-\-tls\-session\-cache\-memcached\fP is given, nghttpx will If \fI\%\-\-tls\-session\-cache\-memcached\fP is given, nghttpx will
insert serialized session data to memcached with insert serialized session data to memcached with
\fBnghttpx:tls\-session\-cache:\fP + lowercase hex string of session ID \fBnghttpx:tls\-session\-cache:\fP + lowercased hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours. is set to 12 hours.
.sp .sp
@@ -1985,17 +1785,6 @@ API is subject to change in the future release.
.UNINDENT .UNINDENT
.UNINDENT .UNINDENT
.sp .sp
\fBWARNING:\fP
.INDENT 0.0
.INDENT 3.5
Almost all string value returned from method, or attribute is a
fresh new mruby string, which involves memory allocation, and
copies. Therefore, it is strongly recommended to store a return
value in a local variable, and use it, instead of calling method or
accessing attribute repeatedly.
.UNINDENT
.UNINDENT
.sp
nghttpx allows users to extend its capability using mruby scripts. nghttpx allows users to extend its capability using mruby scripts.
nghttpx has 2 hook points to execute mruby script: request phase and nghttpx has 2 hook points to execute mruby script: request phase and
response phase. The request phase hook is invoked after all request response phase. The request phase hook is invoked after all request
@@ -2005,28 +1794,9 @@ server. These hooks allows users to modify header fields, or common
HTTP variables, like authority or request path, and even return custom HTTP variables, like authority or request path, and even return custom
response without forwarding request to backend servers. response without forwarding request to backend servers.
.sp .sp
There are 2 levels of mruby script invocations: global and To specify mruby script file, use \fI\%\-\-mruby\-file\fP option. The
per\-pattern. The global mruby script is set by \fI\%\-\-mruby\-file\fP script will be evaluated once per thread on startup, and it must
option and is called for all requests. The per\-pattern mruby script instantiate object and evaluate it as the return value (e.g.,
is set by "mruby" parameter in \fI\%\-b\fP option. It is invoked for
a request which matches the particular pattern. The order of hook
invocation is: global request phase hook, per\-pattern request phase
hook, per\-pattern response phase hook, and finally global response
phase hook. If a hook returns a response, any later hooks are not
invoked. The global request hook is invoked before the pattern
matching is made and changing request path may affect the pattern
matching.
.sp
Please note that request and response hooks of per\-pattern mruby
script for a single request might not come from the same script. This
might happen after a request hook is executed, backend failed for some
reason, and at the same time, backend configuration is replaced by API
request, and then the request uses new configuration on retry. The
response hook from new configuration, if it is specified, will be
invoked.
.sp
The all mruby script will be evaluated once per thread on startup, and
it must instantiate object and evaluate it as the return value (e.g.,
\fBApp.new\fP). This object is called app object. If app object \fBApp.new\fP). This object is called app object. If app object
defines \fBon_req\fP method, it is called with \fI\%Nghttpx::Env\fP defines \fBon_req\fP method, it is called with \fI\%Nghttpx::Env\fP
object on request hook. Similarly, if app object defines \fBon_resp\fP object on request hook. Similarly, if app object defines \fBon_resp\fP
@@ -2063,7 +1833,7 @@ Return \fI\%Response\fP object.
.TP .TP
.B attribute [R] ctx .B attribute [R] ctx
Return Ruby hash object. It persists until request finishes. Return Ruby hash object. It persists until request finishes.
So values set in request phase hook can be retrieved in So values set in request phase hoo can be retrieved in
response phase hook. response phase hook.
.UNINDENT .UNINDENT
.INDENT 7.0 .INDENT 7.0
@@ -2101,77 +1871,6 @@ Return true if TLS is used on the connection.
.B attribute [R] tls_sni .B attribute [R] tls_sni
Return the TLS SNI value which client sent in this connection. Return the TLS SNI value which client sent in this connection.
.UNINDENT .UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_fingerprint_sha256
Return the SHA\-256 fingerprint of a client certificate.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_fingerprint_sha1
Return the SHA\-1 fingerprint of a client certificate.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_issuer_name
Return the issuer name of a client certificate.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_subject_name
Return the subject name of a client certificate.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_serial
Return the serial number of a client certificate.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_not_before
Return the start date of a client certificate in seconds since
the epoch.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_client_not_after
Return the end date of a client certificate in seconds since
the epoch.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_cipher
Return a TLS cipher negotiated in this connection.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_protocol
Return a TLS protocol version negotiated in this connection.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_session_id
Return a session ID for this connection in hex string.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_session_reused
Return true if, and only if a SSL/TLS session is reused.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] alpn
Return ALPN identifier negotiated in this connection.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_handshake_finished
Return true if SSL/TLS handshake has finished. If it returns
false in the request phase hook, the request is received in
TLSv1.3 early data (0\-RTT) and might be vulnerable to the
replay attack. nghttpx will send Early\-Data header field to
backend servers to indicate this.
.UNINDENT
.UNINDENT .UNINDENT
.INDENT 0.0 .INDENT 0.0
.TP .TP
@@ -2323,10 +2022,10 @@ to the backend, and response phase hook for this request will
not be invoked. When this method is called in response phase not be invoked. When this method is called in response phase
hook, response from backend server is canceled and discarded. hook, response from backend server is canceled and discarded.
The status code and response header fields should be set The status code and response header fields should be set
before using this method. To set status code, use before using this method. To set status code, use :rb:meth To
set response header fields, use
\fI\%Nghttpx::Response#status\fP\&. If status code is not \fI\%Nghttpx::Response#status\fP\&. If status code is not
set, 200 is used. To set response header fields, set, 200 is used. \fI\%Nghttpx::Response#add_header\fP and
\fI\%Nghttpx::Response#add_header\fP and
\fI\%Nghttpx::Response#set_header\fP\&. When this method is \fI\%Nghttpx::Response#set_header\fP\&. When this method is
invoked in response phase hook, the response headers are invoked in response phase hook, the response headers are
filled with the ones received from backend server. To send filled with the ones received from backend server. To send
@@ -2449,7 +2148,7 @@ The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is connections or requests. It also avoids any process creation as is
the case with hot swapping with signals. the case with hot swapping with signals.
.sp .sp
The one limitation is that only numeric IP address is allowed in The one limitation is that only numeric IP address is allowd in
\fI\%backend\fP in request body unless "dns" parameter \fI\%backend\fP in request body unless "dns" parameter
is used while non numeric hostname is allowed in command\-line or is used while non numeric hostname is allowed in command\-line or
configuration file is read using \fI\%\-\-conf\fP\&. configuration file is read using \fI\%\-\-conf\fP\&.

View File

@@ -14,7 +14,7 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
A reverse proxy for HTTP/2, and HTTP/1. A reverse proxy for HTTP/2, HTTP/1 and SPDY.
.. describe:: <PRIVATE_KEY> .. describe:: <PRIVATE_KEY>
@@ -57,16 +57,14 @@ Connections
which only lacks trailing '*/*' (e.g., path "*/foo/*" which only lacks trailing '*/*' (e.g., path "*/foo/*"
matches request path "*/foo*"). If it does not end with matches request path "*/foo*"). If it does not end with
"*/*", it performs exact match against the request path. "*/*", it performs exact match against the request path.
If host is given, it performs a match against the If host is given, it performs exact match against the
request host. For a request received on the frontend request host. If host alone is given, "*/*" is appended
listener with "sni-fwd" parameter enabled, SNI host is to it, so that it matches all request paths under the
used instead of a request host. If host alone is given, host (e.g., specifying "nghttp2.org" equals to
"*/*" is appended to it, so that it matches all request "nghttp2.org/"). CONNECT method is treated specially.
paths under the host (e.g., specifying "nghttp2.org" It does not have path, and we don't allow empty path.
equals to "nghttp2.org/"). CONNECT method is treated To workaround this, we assume that CONNECT method has
specially. It does not have path, and we don't allow "*/*" as path.
empty path. To workaround this, we assume that CONNECT
method has "*/*" as path.
Patterns with host take precedence over patterns with Patterns with host take precedence over patterns with
just path. Then, longer patterns take precedence over just path. Then, longer patterns take precedence over
@@ -80,18 +78,6 @@ Connections
match against "nghttp2.org". The exact hosts match match against "nghttp2.org". The exact hosts match
takes precedence over the wildcard hosts match. takes precedence over the wildcard hosts match.
If path part ends with "\*", it is treated as wildcard
path. The wildcard path behaves differently from the
normal path. For normal path, match is made around the
boundary of path component separator,"*/*". On the other
hand, the wildcard path does not take into account the
path component separator. All paths which include the
wildcard path without last "\*" as prefix, and are
strictly longer than wildcard path without last "\*" are
matched. "\*" must match at least one character. For
example, the pattern "*/foo\**" matches "*/foo/*" and
"*/foobar*". But it does not match "*/foo*", or "*/fo*".
If <PATTERN> is omitted or empty string, "*/*" is used as If <PATTERN> is omitted or empty string, "*/*" is used as
pattern, which matches all request paths (catch-all pattern, which matches all request paths (catch-all
pattern). The catch-all backend must be given. pattern). The catch-all backend must be given.
@@ -121,15 +107,12 @@ Connections
The parameters are delimited by ";". The available The parameters are delimited by ";". The available
parameters are: "proto=<PROTO>", "tls", parameters are: "proto=<PROTO>", "tls",
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", "sni=<SNI_HOST>", "fall=<N>", "rise=<N>",
"affinity=<METHOD>", "dns", "redirect-if-not-tls", "affinity=<METHOD>", "dns", and "redirect-if-not-tls".
"upgrade-scheme", "mruby=<PATH>", The parameter consists of keyword, and optionally
"read-timeout=<DURATION>", and followed by "=" and value. For example, the parameter
"write-timeout=<DURATION>". The parameter consists of "proto=h2" consists of the keyword "proto" and value
keyword, and optionally followed by "=" and value. For "h2". The parameter "tls" consists of the keyword "tls"
example, the parameter "proto=h2" consists of the without value. Each parameter is described as follows.
keyword "proto" and value "h2". The parameter "tls"
consists of the keyword "tls" without value. Each
parameter is described as follows.
The backend application protocol can be specified using The backend application protocol can be specified using
optional "proto" parameter, and in the form of optional "proto" parameter, and in the form of
@@ -167,32 +150,16 @@ Connections
The session affinity is enabled using The session affinity is enabled using
"affinity=<METHOD>" parameter. If "ip" is given in "affinity=<METHOD>" parameter. If "ip" is given in
<METHOD>, client IP based session affinity is enabled. <METHOD>, client IP based session affinity is enabled.
If "cookie" is given in <METHOD>, cookie based session If "none" is given in <METHOD>, session affinity is
affinity is enabled. If "none" is given in <METHOD>, disabled, and this is the default. The session affinity
session affinity is disabled, and this is the default. is enabled per <PATTERN>. If at least one backend has
The session affinity is enabled per <PATTERN>. If at "affinity" parameter, and its <METHOD> is not "none",
least one backend has "affinity" parameter, and its session affinity is enabled for all backend servers
<METHOD> is not "none", session affinity is enabled for sharing the same <PATTERN>. It is advised to set
all backend servers sharing the same <PATTERN>. It is "affinity" parameter to all backend explicitly if
advised to set "affinity" parameter to all backend session affinity is desired. The session affinity may
explicitly if session affinity is desired. The session break if one of the backend gets unreachable, or backend
affinity may break if one of the backend gets settings are reloaded or replaced by API.
unreachable, or backend settings are reloaded or
replaced by API.
If "affinity=cookie" is used, the additional
configuration is required.
"affinity-cookie-name=<NAME>" must be used to specify a
name of cookie to use. Optionally,
"affinity-cookie-path=<PATH>" can be used to specify a
path which cookie is applied. The optional
"affinity-cookie-secure=<SECURE>" controls the Secure
attribute of a cookie. The default value is "auto", and
the Secure attribute is determined by a request scheme.
If a request scheme is "https", then Secure attribute is
set. Otherwise, it is not set. If <SECURE> is "yes",
the Secure attribute is always set. If <SECURE> is
"no", the Secure attribute is always omitted.
By default, name resolution of backend host name is done By default, name resolution of backend host name is done
at start up, or reloading configuration. If "dns" at start up, or reloading configuration. If "dns"
@@ -215,26 +182,6 @@ Connections
"redirect-if-no-tls" parameter to all backends "redirect-if-no-tls" parameter to all backends
explicitly if this feature is desired. explicitly if this feature is desired.
If "upgrade-scheme" parameter is used along with "tls"
parameter, HTTP/2 :scheme pseudo header field is changed
to "https" from "http" when forwarding a request to this
particular backend. This is a workaround for a backend
server which requires "https" :scheme pseudo header
field on TLS encrypted connection.
"mruby=<PATH>" parameter specifies a path to mruby
script file which is invoked when this pattern is
matched. All backends which share the same pattern must
have the same mruby path.
"read-timeout=<DURATION>" and "write-timeout=<DURATION>"
parameters specify the read and write timeout of the
backend connection when this pattern is matched. All
backends which share the same pattern must have the same
timeouts. If these timeouts are entirely omitted for a
pattern, :option:`--backend-read-timeout` and
:option:`--backend-write-timeout` are used.
Since ";" and ":" are used as delimiter, <PATTERN> must Since ";" and ":" are used as delimiter, <PATTERN> must
not contain these characters. Since ";" has special not contain these characters. Since ";" has special
meaning in shell, the option value must be quoted. meaning in shell, the option value must be quoted.
@@ -258,11 +205,6 @@ Connections
Optionally, TLS can be disabled by specifying "no-tls" Optionally, TLS can be disabled by specifying "no-tls"
parameter. TLS is enabled by default. parameter. TLS is enabled by default.
If "sni-fwd" parameter is used, when performing a match
to select a backend server, SNI host name received from
the client is used instead of the request host. See
:option:`--backend` option about the pattern match.
To make this frontend as API endpoint, specify "api" To make this frontend as API endpoint, specify "api"
parameter. This is disabled by default. It is parameter. This is disabled by default. It is
important to limit the access to the API frontend. important to limit the access to the API frontend.
@@ -463,7 +405,8 @@ Timeout
.. option:: --frontend-http2-read-timeout=<DURATION> .. option:: --frontend-http2-read-timeout=<DURATION>
Specify read timeout for HTTP/2 frontend connection. Specify read timeout for HTTP/2 and SPDY frontend
connection.
Default: ``3m`` Default: ``3m``
@@ -488,15 +431,15 @@ Timeout
.. option:: --stream-read-timeout=<DURATION> .. option:: --stream-read-timeout=<DURATION>
Specify read timeout for HTTP/2 streams. 0 means no Specify read timeout for HTTP/2 and SPDY streams. 0
timeout. means no timeout.
Default: ``0`` Default: ``0``
.. option:: --stream-write-timeout=<DURATION> .. option:: --stream-write-timeout=<DURATION>
Specify write timeout for HTTP/2 streams. 0 means no Specify write timeout for HTTP/2 and SPDY streams. 0
timeout. means no timeout.
Default: ``1m`` Default: ``1m``
@@ -569,38 +512,16 @@ SSL/TLS
Set allowed cipher list for frontend connection. The Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1). format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use :option:`--tls13-ciphers` for TLSv1.3.
Default: ``ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256`` Default: ``ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256``
.. option:: --tls13-ciphers=<SUITE>
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 or earlier.
Default: ``TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256``
.. option:: --client-ciphers=<SUITE> .. option:: --client-ciphers=<SUITE>
Set allowed cipher list for backend connection. The Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1). format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use :option:`--tls13-client-ciphers` for TLSv1.3.
Default: ``ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256`` Default: ``ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256``
.. option:: --tls13-client-ciphers=<SUITE>
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:`--tls13-client-ciphers` for TLSv1.2 or earlier.
Default: ``TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256``
.. option:: --ecdh-curves=<LIST> .. option:: --ecdh-curves=<LIST>
Set supported curve list for frontend connections. Set supported curve list for frontend connections.
@@ -618,14 +539,11 @@ SSL/TLS
.. option:: --cacert=<PATH> .. option:: --cacert=<PATH>
Set path to trusted CA certificate file. It is used in Set path to trusted CA certificate file used in backend
backend TLS connections to verify peer's certificate. TLS connections. The file must be in PEM format. It
It is also used to verify OCSP response from the script can contain multiple certificates. If the linked
set by :option:`--fetch-ocsp-response-file`\. The file must be in OpenSSL is configured to load system wide certificates,
PEM format. It can contain multiple certificates. If they are loaded at startup regardless of this option.
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> .. option:: --private-key-passwd-file=<PATH>
@@ -638,12 +556,12 @@ SSL/TLS
Specify additional certificate and private key file. Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. If nghttpx indicated by client using TLS SNI extension. If nghttpx
is built with OpenSSL >= 1.0.2, the shared elliptic is built with OpenSSL >= 1.0.2, signature algorithms
curves (e.g., P-256) between client and server are also (e.g., ECDSA+SHA256, RSA+SHA256) presented by client are
taken into consideration. This allows nghttpx to send also taken into consideration. This allows nghttpx to
ECDSA certificate to modern clients, while sending RSA send ECDSA certificate to modern clients, while sending
based certificate to older clients. This option can be RSA based certificate to older clients. This option can
used multiple times. To make OCSP stapling work, be used multiple times. To make OCSP stapling work,
<CERTPATH> must be absolute path. <CERTPATH> must be absolute path.
Additional parameter can be specified in <PARAM>. The Additional parameter can be specified in <PARAM>. The
@@ -682,13 +600,6 @@ SSL/TLS
client certificate. The file must be in PEM format. It client certificate. The file must be in PEM format. It
can contain multiple certificates. can contain multiple certificates.
.. option:: --verify-client-tolerate-expired
Accept expired client certificate. Operator should
handle the expired client certificate by some means
(e.g., mruby script). Otherwise, this option might
cause a security risk.
.. option:: --client-private-key-file=<PATH> .. option:: --client-private-key-file=<PATH>
Path to file that contains client private key used in Path to file that contains client private key used in
@@ -706,14 +617,10 @@ SSL/TLS
:option:`--tls-min-proto-version` and :option:`\--tls-max-proto-version` are :option:`--tls-min-proto-version` and :option:`\--tls-max-proto-version` are
enabled. If the protocol list advertised by client does enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error not overlap this range, you will receive the error
message "unknown protocol". If a protocol version lower message "unknown protocol". The available versions are:
than TLSv1.2 is specified, make sure that the compatible TLSv1.2, TLSv1.1, and TLSv1.0
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`` Default: ``TLSv1.1``
.. option:: --tls-max-proto-version=<VER> .. option:: --tls-max-proto-version=<VER>
@@ -723,9 +630,9 @@ SSL/TLS
enabled. If the protocol list advertised by client does enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error not overlap this range, you will receive the error
message "unknown protocol". The available versions are: message "unknown protocol". The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0 TLSv1.2, TLSv1.1, and TLSv1.0
Default: ``TLSv1.3`` Default: ``TLSv1.2``
.. option:: --tls-ticket-key-file=<PATH> .. option:: --tls-ticket-key-file=<PATH>
@@ -829,18 +736,6 @@ SSL/TLS
Default: ``4h`` 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 .. option:: --no-ocsp
Disable OCSP stapling. Disable OCSP stapling.
@@ -953,32 +848,16 @@ SSL/TLS
consider to use :option:`--client-no-http2-cipher-black-list` consider to use :option:`--client-no-http2-cipher-black-list`
option. But be aware its implications. option. But be aware its implications.
.. option:: --tls-no-postpone-early-data
By default, nghttpx postpones forwarding HTTP requests HTTP/2 and SPDY
sent in early data, including those sent in partially in ~~~~~~~~~~~~~~~
it, until TLS handshake finishes. If all backend server
recognizes "Early-Data" header field, using this option
makes nghttpx not postpone forwarding request and get
full potential of 0-RTT data.
.. option:: --tls-max-early-data=<SIZE>
Sets the maximum amount of 0-RTT data that server
accepts.
Default: ``16K``
HTTP/2
~~~~~~
.. option:: -c, --frontend-http2-max-concurrent-streams=<N> .. option:: -c, --frontend-http2-max-concurrent-streams=<N>
Set the maximum number of the concurrent streams in one Set the maximum number of the concurrent streams in one
frontend HTTP/2 session. frontend HTTP/2 and SPDY session.
Default: ``100`` Default: `` 100``
.. option:: --backend-http2-max-concurrent-streams=<N> .. option:: --backend-http2-max-concurrent-streams=<N>
@@ -991,15 +870,16 @@ HTTP/2
.. option:: --frontend-http2-window-size=<SIZE> .. option:: --frontend-http2-window-size=<SIZE>
Sets the per-stream initial window size of HTTP/2 Sets the per-stream initial window size of HTTP/2 and
frontend connection. SPDY frontend connection.
Default: ``65535`` Default: ``65535``
.. option:: --frontend-http2-connection-window-size=<SIZE> .. option:: --frontend-http2-connection-window-size=<SIZE>
Sets the per-connection window size of HTTP/2 frontend Sets the per-connection window size of HTTP/2 and SPDY
connection. frontend connection. For SPDY connection, the value
less than 64KiB is rounded up to 64KiB.
Default: ``65535`` Default: ``65535``
@@ -1035,7 +915,8 @@ HTTP/2
It is also supported if both frontend and backend are It is also supported if both frontend and backend are
HTTP/2 in default mode. In this case, server push from HTTP/2 in default mode. In this case, server push from
backend session is relayed to frontend, and server push backend session is relayed to frontend, and server push
via Link header field is also supported. via Link header field is also supported. SPDY frontend
does not support server push.
.. option:: --frontend-http2-optimize-write-buffer-size .. option:: --frontend-http2-optimize-write-buffer-size
@@ -1103,7 +984,7 @@ Mode
.. describe:: (default mode) .. describe:: (default mode)
Accept HTTP/2, and HTTP/1.1 over SSL/TLS. "no-tls" Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no-tls"
parameter is used in :option:`--frontend` option, accept HTTP/2 parameter is used in :option:`--frontend` option, accept HTTP/2
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1 and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
connection can be upgraded to HTTP/2 through HTTP connection can be upgraded to HTTP/2 through HTTP
@@ -1158,22 +1039,11 @@ Logging
* $alpn: ALPN identifier of the protocol which generates * $alpn: ALPN identifier of the protocol which generates
the response. For HTTP/1, ALPN is always http/1.1, the response. For HTTP/1, ALPN is always http/1.1,
regardless of minor version. regardless of minor version.
* $tls_cipher: cipher used for SSL/TLS connection. * $ssl_cipher: cipher used for SSL/TLS connection.
* $tls_client_fingerprint_sha256: SHA-256 fingerprint of * $ssl_protocol: protocol for SSL/TLS connection.
client certificate. * $ssl_session_id: session ID for SSL/TLS connection.
* $tls_client_fingerprint_sha1: SHA-1 fingerprint of * $ssl_session_reused: "r" if SSL/TLS session was
client certificate.
* $tls_client_subject_name: subject name in client
certificate.
* $tls_client_issuer_name: issuer name in client
certificate.
* $tls_client_serial: serial number in client
certificate.
* $tls_protocol: protocol for SSL/TLS connection.
* $tls_session_id: session ID for SSL/TLS connection.
* $tls_session_reused: "r" if SSL/TLS session was
reused. Otherwise, "." reused. Otherwise, "."
* $tls_sni: SNI server name for SSL/TLS connection.
* $backend_host: backend host used to fulfill the * $backend_host: backend host used to fulfill the
request. "-" if backend host is not available. request. "-" if backend host is not available.
* $backend_port: backend port used to fulfill the * $backend_port: backend port used to fulfill the
@@ -1224,19 +1094,6 @@ HTTP
Strip X-Forwarded-For header field from inbound client Strip X-Forwarded-For header field from inbound client
requests. requests.
.. option:: --no-add-x-forwarded-proto
Don't append additional X-Forwarded-Proto header field
to the backend request. If inbound client sets
X-Forwarded-Proto, and
:option:`--no-strip-incoming-x-forwarded-proto` option is used,
they are passed to the backend.
.. option:: --no-strip-incoming-x-forwarded-proto
Don't strip X-Forwarded-Proto header field from inbound
client requests.
.. option:: --add-forwarded=<LIST> .. option:: --add-forwarded=<LIST>
Append RFC 7239 Forwarded header field with parameters Append RFC 7239 Forwarded header field with parameters
@@ -1285,11 +1142,6 @@ HTTP
Don't append to Via header field. If Via header field Don't append to Via header field. If Via header field
is received, it is left unaltered. is received, it is left unaltered.
.. option:: --no-strip-incoming-early-data
Don't strip Early-Data header field from inbound client
requests.
.. option:: --no-location-rewrite .. option:: --no-location-rewrite
Don't rewrite location header field in default mode. Don't rewrite location header field in default mode.
@@ -1398,7 +1250,7 @@ API
Set the maximum size of request body for API request. Set the maximum size of request body for API request.
Default: ``32M`` Default: ``16K``
DNS DNS
@@ -1480,16 +1332,6 @@ Process
Run this program as <USER>. This option is intended to Run this program as <USER>. This option is intended to
be used to drop root privileges. be used to drop root privileges.
.. option:: --single-process
Run this program in a single process mode for debugging
purpose. Without this option, nghttpx creates at least
2 processes: master and worker processes. If this
option is used, master and worker are unified into a
single process. nghttpx still spawns additional process
if neverbleed is used. In the single process mode, the
signal handling feature is disabled.
Scripting Scripting
~~~~~~~~~ ~~~~~~~~~
@@ -1498,21 +1340,13 @@ Scripting
Set mruby script file Set mruby script file
.. option:: --ignore-per-pattern-mruby-error
Ignore mruby compile error for per-pattern mruby script
file. If error occurred, it is treated as if no mruby
file were specified for the pattern.
Misc Misc
~~~~ ~~~~
.. option:: --conf=<PATH> .. option:: --conf=<PATH>
Load configuration from <PATH>. Please note that Load configuration from <PATH>.
nghttpx always tries to read the default configuration
file if :option:`--conf` is not given.
Default: ``/etc/nghttpx/nghttpx.conf`` Default: ``/etc/nghttpx/nghttpx.conf``
@@ -1592,7 +1426,7 @@ Error log
<datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg> <datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
<datetime> <datetime>
It is a combination of date and time when the log is written. It It is a conbination of date and time when the log is written. It
is in ISO 8601 format. is in ISO 8601 format.
<master-pid> <master-pid>
@@ -1714,22 +1548,6 @@ be customized using :option:`--fetch-ocsp-response-file` option.
If OCSP query is failed, previous OCSP response, if any, is continued If OCSP query is failed, previous OCSP response, if any, is continued
to be used. 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 TLS SESSION RESUMPTION
---------------------- ----------------------
@@ -1743,7 +1561,7 @@ By default, session ID is shared by all worker threads.
If :option:`--tls-session-cache-memcached` is given, nghttpx will If :option:`--tls-session-cache-memcached` is given, nghttpx will
insert serialized session data to memcached with insert serialized session data to memcached with
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID ``nghttpx:tls-session-cache:`` + lowercased hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours. is set to 12 hours.
@@ -1825,14 +1643,6 @@ MRUBY SCRIPTING
The current mruby extension API is experimental and not frozen. The The current mruby extension API is experimental and not frozen. The
API is subject to change in the future release. API is subject to change in the future release.
.. warning::
Almost all string value returned from method, or attribute is a
fresh new mruby string, which involves memory allocation, and
copies. Therefore, it is strongly recommended to store a return
value in a local variable, and use it, instead of calling method or
accessing attribute repeatedly.
nghttpx allows users to extend its capability using mruby scripts. nghttpx allows users to extend its capability using mruby scripts.
nghttpx has 2 hook points to execute mruby script: request phase and nghttpx has 2 hook points to execute mruby script: request phase and
response phase. The request phase hook is invoked after all request response phase. The request phase hook is invoked after all request
@@ -1842,28 +1652,9 @@ server. These hooks allows users to modify header fields, or common
HTTP variables, like authority or request path, and even return custom HTTP variables, like authority or request path, and even return custom
response without forwarding request to backend servers. response without forwarding request to backend servers.
There are 2 levels of mruby script invocations: global and To specify mruby script file, use :option:`--mruby-file` option. The
per-pattern. The global mruby script is set by :option:`--mruby-file` script will be evaluated once per thread on startup, and it must
option and is called for all requests. The per-pattern mruby script instantiate object and evaluate it as the return value (e.g.,
is set by "mruby" parameter in :option:`-b` option. It is invoked for
a request which matches the particular pattern. The order of hook
invocation is: global request phase hook, per-pattern request phase
hook, per-pattern response phase hook, and finally global response
phase hook. If a hook returns a response, any later hooks are not
invoked. The global request hook is invoked before the pattern
matching is made and changing request path may affect the pattern
matching.
Please note that request and response hooks of per-pattern mruby
script for a single request might not come from the same script. This
might happen after a request hook is executed, backend failed for some
reason, and at the same time, backend configuration is replaced by API
request, and then the request uses new configuration on retry. The
response hook from new configuration, if it is specified, will be
invoked.
The all mruby script will be evaluated once per thread on startup, and
it must instantiate object and evaluate it as the return value (e.g.,
``App.new``). This object is called app object. If app object ``App.new``). This object is called app object. If app object
defines ``on_req`` method, it is called with :rb:class:`Nghttpx::Env` defines ``on_req`` method, it is called with :rb:class:`Nghttpx::Env`
object on request hook. Similarly, if app object defines ``on_resp`` object on request hook. Similarly, if app object defines ``on_resp``
@@ -1898,7 +1689,7 @@ respectively.
.. rb:attr_reader:: ctx .. rb:attr_reader:: ctx
Return Ruby hash object. It persists until request finishes. Return Ruby hash object. It persists until request finishes.
So values set in request phase hook can be retrieved in So values set in request phase hoo can be retrieved in
response phase hook. response phase hook.
.. rb:attr_reader:: phase .. rb:attr_reader:: phase
@@ -1930,64 +1721,6 @@ respectively.
Return the TLS SNI value which client sent in this connection. Return the TLS SNI value which client sent in this connection.
.. rb:attr_reader:: tls_client_fingerprint_sha256
Return the SHA-256 fingerprint of a client certificate.
.. rb:attr_reader:: tls_client_fingerprint_sha1
Return the SHA-1 fingerprint of a client certificate.
.. rb:attr_reader:: tls_client_issuer_name
Return the issuer name of a client certificate.
.. rb:attr_reader:: tls_client_subject_name
Return the subject name of a client certificate.
.. rb:attr_reader:: tls_client_serial
Return the serial number of a client certificate.
.. rb:attr_reader:: tls_client_not_before
Return the start date of a client certificate in seconds since
the epoch.
.. rb:attr_reader:: tls_client_not_after
Return the end date of a client certificate in seconds since
the epoch.
.. rb:attr_reader:: tls_cipher
Return a TLS cipher negotiated in this connection.
.. rb:attr_reader:: tls_protocol
Return a TLS protocol version negotiated in this connection.
.. rb:attr_reader:: tls_session_id
Return a session ID for this connection in hex string.
.. rb:attr_reader:: tls_session_reused
Return true if, and only if a SSL/TLS session is reused.
.. rb:attr_reader:: alpn
Return ALPN identifier negotiated in this connection.
.. rb:attr_reader:: tls_handshake_finished
Return true if SSL/TLS handshake has finished. If it returns
false in the request phase hook, the request is received in
TLSv1.3 early data (0-RTT) and might be vulnerable to the
replay attack. nghttpx will send Early-Data header field to
backend servers to indicate this.
.. rb:class:: Request .. rb:class:: Request
Object to represent request from client. The modification to Object to represent request from client. The modification to
@@ -2118,10 +1851,10 @@ respectively.
not be invoked. When this method is called in response phase not be invoked. When this method is called in response phase
hook, response from backend server is canceled and discarded. hook, response from backend server is canceled and discarded.
The status code and response header fields should be set The status code and response header fields should be set
before using this method. To set status code, use before using this method. To set status code, use :rb:meth To
set response header fields, use
:rb:attr:`Nghttpx::Response#status`. If status code is not :rb:attr:`Nghttpx::Response#status`. If status code is not
set, 200 is used. To set response header fields, set, 200 is used. :rb:meth:`Nghttpx::Response#add_header` and
:rb:meth:`Nghttpx::Response#add_header` and
:rb:meth:`Nghttpx::Response#set_header`. When this method is :rb:meth:`Nghttpx::Response#set_header`. When this method is
invoked in response phase hook, the response headers are invoked in response phase hook, the response headers are
filled with the ones received from backend server. To send filled with the ones received from backend server. To send
@@ -2232,7 +1965,7 @@ The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is connections or requests. It also avoids any process creation as is
the case with hot swapping with signals. the case with hot swapping with signals.
The one limitation is that only numeric IP address is allowed in The one limitation is that only numeric IP address is allowd in
:option:`backend <--backend>` in request body unless "dns" parameter :option:`backend <--backend>` in request body unless "dns" parameter
is used while non numeric hostname is allowed in command-line or is used while non numeric hostname is allowed in command-line or
configuration file is read using :option:`--conf`. configuration file is read using :option:`--conf`.

View File

@@ -49,7 +49,7 @@ Error log
<datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg> <datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
<datetime> <datetime>
It is a combination of date and time when the log is written. It It is a conbination of date and time when the log is written. It
is in ISO 8601 format. is in ISO 8601 format.
<master-pid> <master-pid>
@@ -171,22 +171,6 @@ be customized using :option:`--fetch-ocsp-response-file` option.
If OCSP query is failed, previous OCSP response, if any, is continued If OCSP query is failed, previous OCSP response, if any, is continued
to be used. 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 TLS SESSION RESUMPTION
---------------------- ----------------------
@@ -200,7 +184,7 @@ By default, session ID is shared by all worker threads.
If :option:`--tls-session-cache-memcached` is given, nghttpx will If :option:`--tls-session-cache-memcached` is given, nghttpx will
insert serialized session data to memcached with insert serialized session data to memcached with
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID ``nghttpx:tls-session-cache:`` + lowercased hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours. is set to 12 hours.
@@ -282,14 +266,6 @@ MRUBY SCRIPTING
The current mruby extension API is experimental and not frozen. The The current mruby extension API is experimental and not frozen. The
API is subject to change in the future release. API is subject to change in the future release.
.. warning::
Almost all string value returned from method, or attribute is a
fresh new mruby string, which involves memory allocation, and
copies. Therefore, it is strongly recommended to store a return
value in a local variable, and use it, instead of calling method or
accessing attribute repeatedly.
nghttpx allows users to extend its capability using mruby scripts. nghttpx allows users to extend its capability using mruby scripts.
nghttpx has 2 hook points to execute mruby script: request phase and nghttpx has 2 hook points to execute mruby script: request phase and
response phase. The request phase hook is invoked after all request response phase. The request phase hook is invoked after all request
@@ -299,28 +275,9 @@ server. These hooks allows users to modify header fields, or common
HTTP variables, like authority or request path, and even return custom HTTP variables, like authority or request path, and even return custom
response without forwarding request to backend servers. response without forwarding request to backend servers.
There are 2 levels of mruby script invocations: global and To specify mruby script file, use :option:`--mruby-file` option. The
per-pattern. The global mruby script is set by :option:`--mruby-file` script will be evaluated once per thread on startup, and it must
option and is called for all requests. The per-pattern mruby script instantiate object and evaluate it as the return value (e.g.,
is set by "mruby" parameter in :option:`-b` option. It is invoked for
a request which matches the particular pattern. The order of hook
invocation is: global request phase hook, per-pattern request phase
hook, per-pattern response phase hook, and finally global response
phase hook. If a hook returns a response, any later hooks are not
invoked. The global request hook is invoked before the pattern
matching is made and changing request path may affect the pattern
matching.
Please note that request and response hooks of per-pattern mruby
script for a single request might not come from the same script. This
might happen after a request hook is executed, backend failed for some
reason, and at the same time, backend configuration is replaced by API
request, and then the request uses new configuration on retry. The
response hook from new configuration, if it is specified, will be
invoked.
The all mruby script will be evaluated once per thread on startup, and
it must instantiate object and evaluate it as the return value (e.g.,
``App.new``). This object is called app object. If app object ``App.new``). This object is called app object. If app object
defines ``on_req`` method, it is called with :rb:class:`Nghttpx::Env` defines ``on_req`` method, it is called with :rb:class:`Nghttpx::Env`
object on request hook. Similarly, if app object defines ``on_resp`` object on request hook. Similarly, if app object defines ``on_resp``
@@ -355,7 +312,7 @@ respectively.
.. rb:attr_reader:: ctx .. rb:attr_reader:: ctx
Return Ruby hash object. It persists until request finishes. Return Ruby hash object. It persists until request finishes.
So values set in request phase hook can be retrieved in So values set in request phase hoo can be retrieved in
response phase hook. response phase hook.
.. rb:attr_reader:: phase .. rb:attr_reader:: phase
@@ -387,64 +344,6 @@ respectively.
Return the TLS SNI value which client sent in this connection. Return the TLS SNI value which client sent in this connection.
.. rb:attr_reader:: tls_client_fingerprint_sha256
Return the SHA-256 fingerprint of a client certificate.
.. rb:attr_reader:: tls_client_fingerprint_sha1
Return the SHA-1 fingerprint of a client certificate.
.. rb:attr_reader:: tls_client_issuer_name
Return the issuer name of a client certificate.
.. rb:attr_reader:: tls_client_subject_name
Return the subject name of a client certificate.
.. rb:attr_reader:: tls_client_serial
Return the serial number of a client certificate.
.. rb:attr_reader:: tls_client_not_before
Return the start date of a client certificate in seconds since
the epoch.
.. rb:attr_reader:: tls_client_not_after
Return the end date of a client certificate in seconds since
the epoch.
.. rb:attr_reader:: tls_cipher
Return a TLS cipher negotiated in this connection.
.. rb:attr_reader:: tls_protocol
Return a TLS protocol version negotiated in this connection.
.. rb:attr_reader:: tls_session_id
Return a session ID for this connection in hex string.
.. rb:attr_reader:: tls_session_reused
Return true if, and only if a SSL/TLS session is reused.
.. rb:attr_reader:: alpn
Return ALPN identifier negotiated in this connection.
.. rb:attr_reader:: tls_handshake_finished
Return true if SSL/TLS handshake has finished. If it returns
false in the request phase hook, the request is received in
TLSv1.3 early data (0-RTT) and might be vulnerable to the
replay attack. nghttpx will send Early-Data header field to
backend servers to indicate this.
.. rb:class:: Request .. rb:class:: Request
Object to represent request from client. The modification to Object to represent request from client. The modification to
@@ -575,10 +474,10 @@ respectively.
not be invoked. When this method is called in response phase not be invoked. When this method is called in response phase
hook, response from backend server is canceled and discarded. hook, response from backend server is canceled and discarded.
The status code and response header fields should be set The status code and response header fields should be set
before using this method. To set status code, use before using this method. To set status code, use :rb:meth To
set response header fields, use
:rb:attr:`Nghttpx::Response#status`. If status code is not :rb:attr:`Nghttpx::Response#status`. If status code is not
set, 200 is used. To set response header fields, set, 200 is used. :rb:meth:`Nghttpx::Response#add_header` and
:rb:meth:`Nghttpx::Response#add_header` and
:rb:meth:`Nghttpx::Response#set_header`. When this method is :rb:meth:`Nghttpx::Response#set_header`. When this method is
invoked in response phase hook, the response headers are invoked in response phase hook, the response headers are
filled with the ones received from backend server. To send filled with the ones received from backend server. To send
@@ -689,7 +588,7 @@ The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is connections or requests. It also avoids any process creation as is
the case with hot swapping with signals. the case with hot swapping with signals.
The one limitation is that only numeric IP address is allowed in The one limitation is that only numeric IP address is allowd in
:option:`backend <--backend>` in request body unless "dns" parameter :option:`backend <--backend>` in request body unless "dns" parameter
is used while non numeric hostname is allowed in command-line or is used while non numeric hostname is allowed in command-line or
configuration file is read using :option:`--conf`. configuration file is read using :option:`--conf`.

View File

@@ -110,16 +110,13 @@ HTTP Messaging
By default, nghttp2 library checks HTTP messaging rules described in By default, nghttp2 library checks HTTP messaging rules described in
`HTTP/2 specification, section 8 `HTTP/2 specification, section 8
<https://tools.ietf.org/html/rfc7540#section-8>`_. Everything <https://tools.ietf.org/html/draft-ietf-httpbis-http2-17#section-8>`_.
described in that section is not validated however. We briefly Everything described in that section is not validated however. We
describe what the library does in this area. In the following briefly describe what the library does in this area. In the following
description, without loss of generality we omit CONTINUATION frame description, without loss of generality we omit CONTINUATION frame
since they must follow HEADERS frame and are processed atomically. In since they must follow HEADERS frame and are processed atomically. In
other words, they are just one big HEADERS frame. To disable these other words, they are just one big HEADERS frame. To disable these
validations, use `nghttp2_option_set_no_http_messaging()`. Please validations, use `nghttp2_option_set_no_http_messaging()`.
note that disabling this feature does not change the fundamental
client and server model of HTTP. That is, even if the validation is
disabled, only client can send requests.
For HTTP request, including those carried by PUSH_PROMISE, HTTP For HTTP request, including those carried by PUSH_PROMISE, HTTP
message starts with one HEADERS frame containing request headers. It message starts with one HEADERS frame containing request headers. It
@@ -152,11 +149,13 @@ header fields must not appear: "Connection", "Keep-Alive",
Each header field name and value must obey the field-name and Each header field name and value must obey the field-name and
field-value production rules described in `RFC 7230, section field-value production rules described in `RFC 7230, section
3.2. <https://tools.ietf.org/html/rfc7230#section-3.2>`_. 3.2. <https://tools.ietf.org/html/rfc7230#section-3.2>`_.
Additionally, all field name must be lower cased. The invalid header Additionally, all field name must be lower cased. While the pseudo
fields are treated as stream error, and that stream is reset. If header fields must satisfy these rules, we just ignore illegal regular
application wants to treat these headers in their own way, use headers (this means that these header fields are not passed to
`nghttp2_on_invalid_header_callback application callback). This is because these illegal header fields
<https://nghttp2.org/documentation/types.html#c.nghttp2_on_invalid_header_callback>`_. are floating around in existing internet and resetting stream just
because of this may break many web sites. This is especially true if
we forward to or translate from HTTP/1 traffic.
For "http" or "https" URIs, ":path" pseudo header fields must start For "http" or "https" URIs, ":path" pseudo header fields must start
with "/". The only exception is OPTIONS request, in that case, "*" is with "/". The only exception is OPTIONS request, in that case, "*" is
@@ -249,7 +248,7 @@ set to :type:`nghttp2_session_callbacks` using
`nghttp2_session_callbacks_set_pack_extension_callback()`. `nghttp2_session_callbacks_set_pack_extension_callback()`.
For example, we will illustrate how to send `ALTSVC For example, we will illustrate how to send `ALTSVC
<https://tools.ietf.org/html/rfc7838>`_ frame. <https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-14>`_ frame.
.. code-block:: c .. code-block:: c

View File

@@ -2,7 +2,7 @@ Building Android binary
======================= =======================
In this article, we briefly describe how to build Android binary using In this article, we briefly describe how to build Android binary using
`Android NDK <https://developer.android.com/ndk/index.html>`_ `Android NDK <http://developer.android.com/tools/sdk/ndk/index.html>`_
cross-compiler on Debian Linux. cross-compiler on Debian Linux.
The easiest way to build android binary is use Dockerfile.android. The easiest way to build android binary is use Dockerfile.android.

View File

@@ -26,7 +26,8 @@ Coding style
We use clang-format to format source code consistently. The We use clang-format to format source code consistently. The
clang-format configuration file .clang-format is located at the root clang-format configuration file .clang-format is located at the root
directory. Since clang-format produces slightly different results directory. Since clang-format produces slightly different results
between versions, we currently use clang-format-6.0. between versions, we currently use clang-format which comes with
clang-3.9.
To detect any violation to the coding style, we recommend to setup git 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. pre-commit hook to check coding style of the changes you introduced.
@@ -34,7 +35,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 .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 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., your PATH or it exists under different name (e.g.,
clang-format-diff-6.0 in debian), either add it to PATH variable or clang-format-diff-3.9 in debian), either add it to PATH variable or
add git option ``clangformatdiff.binary`` to point to the script. add git option ``clangformatdiff.binary`` to point to the script.
For emacs users, integrating clang-format to emacs is very easy. For emacs users, integrating clang-format to emacs is very easy.

View File

@@ -3,14 +3,16 @@
h2load - HTTP/2 benchmarking tool - HOW-TO h2load - HTTP/2 benchmarking tool - HOW-TO
========================================== ==========================================
:doc:`h2load.1` is benchmarking tool for HTTP/2 and HTTP/1.1. It :doc:`h2load.1` is benchmarking tool for HTTP/2 and HTTP/1.1. If
supports SSL/TLS and clear text for all supported protocols. built with spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it
also supports SPDY protocol. It supports SSL/TLS and clear text for
all supported protocols.
Compiling from source Compiling from source
--------------------- ---------------------
h2load is compiled alongside nghttp2 and requires that the h2load is compiled alongside nghttp2 and requires that the
``--enable-app`` flag is passed to ``./configure`` and `required ``--enable-apps`` flag is passed to ``./configure`` and `required
dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are
available during compilation. For details on compiling, see `nghttp2: available during compilation. For details on compiling, see `nghttp2:
Building from Git Building from Git
@@ -62,40 +64,23 @@ The benchmarking result looks like this:
See the h2load manual page :ref:`h2load-1-output` section for the See the h2load manual page :ref:`h2load-1-output` section for the
explanation of the above numbers. explanation of the above numbers.
Timing-based load-testing
-------------------------
As of v1.26.0, h2load supports timing-based load-testing. This method
performs load-testing in terms of a given duration instead of a
pre-defined number of requests. The new option :option:`--duration`
specifies how long the load-testing takes. For example,
``--duration=10`` makes h2load perform load-testing against a server
for 10 seconds. You can also specify a “warming-up” period with
:option:`--warm-up-time`. If :option:`--duration` is used,
:option:`-n` option is ignored.
The following command performs load-testing for 10 seconds after 5
seconds warming up period:
.. code-block:: text
$ h2load -c100 -m100 --duration=10 --warm-up-time=5 https://localhost
Flow Control Flow Control
------------ ------------
HTTP/2 has flow control and it may affect benchmarking results. By HTTP/2 and SPDY/3 or later employ flow control and it may affect
default, h2load uses large enough flow control window, which benchmarking results. By default, h2load uses large enough flow
effectively disables flow control. To adjust receiver flow control control window, which effectively disables flow control. To adjust
window size, there are following options: receiver flow control window size, there are following options:
:option:`-w` :option:`-w`
Sets the stream level initial window size to Sets the stream level initial window size to
(2**<N>)-1. (2**<N>)-1. For SPDY, 2**<N> is used instead.
:option:`-W` :option:`-W`
Sets the connection level initial window size to Sets the connection level initial window size to
(2**<N>)-1. (2**<N>)-1. For SPDY, if <N> is strictly less
than 16, this option is ignored. Otherwise
2**<N> is used for SPDY.
Multi-Threading Multi-Threading
--------------- ---------------

View File

@@ -290,7 +290,7 @@ Normally, client does not stop even after all requests are done unless
connection is lost. To stop client, call connection is lost. To stop client, call
``nghttp2::asio_http2::server::session::shutdown()``. ``nghttp2::asio_http2::server::session::shutdown()``.
Receive server push and enable SSL/TLS Recieve server push and enable SSL/TLS
++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++
.. code-block:: cpp .. code-block:: cpp

View File

@@ -4,10 +4,10 @@ nghttpx - HTTP/2 proxy - HOW-TO
=============================== ===============================
:doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and :doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and
other protocols (e.g., HTTP/1). It operates in several modes and each other protocols (e.g., HTTP/1, SPDY). It operates in several modes
mode may require additional programs to work with. This article and each mode may require additional programs to work with. This
describes each operation mode and explains the intended use-cases. It article describes each operation mode and explains the intended
also covers some useful options later. use-cases. It also covers some useful options later.
Default mode Default mode
------------ ------------
@@ -15,7 +15,9 @@ Default mode
If nghttpx is invoked without :option:`--http2-proxy`, it operates in If nghttpx is invoked without :option:`--http2-proxy`, it operates in
default mode. In this mode, it works as reverse proxy (gateway) for default mode. In this mode, it works as reverse proxy (gateway) for
both HTTP/2 and HTTP/1 clients to backend servers. This is also known both HTTP/2 and HTTP/1 clients to backend servers. This is also known
as "HTTP/2 router". as "HTTP/2 router". If nghttpx is linked with spdylay library and
frontend connection is SSL/TLS, the frontend also supports SPDY
protocol.
By default, frontend connection is encrypted using SSL/TLS. So By default, frontend connection is encrypted using SSL/TLS. So
server's private key and certificate must be supplied to the command server's private key and certificate must be supplied to the command
@@ -23,10 +25,11 @@ line (or through configuration file). In this case, the frontend
protocol selection will be done via ALPN or NPN. protocol selection will be done via ALPN or NPN.
To turn off encryption on frontend connection, use ``no-tls`` keyword To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option. HTTP/2 and HTTP/1 are available on in :option:`--frontend` option. In this case, SPDY protocol is not
the frontend, and an HTTP/1 connection can be upgraded to HTTP/2 using available even if spdylay library is liked to nghttpx. HTTP/2 and
HTTP Upgrade. Starting HTTP/2 connection by sending HTTP/2 connection HTTP/1 are available on the frontend, and an HTTP/1 connection can be
preface is also supported. upgraded to HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by
sending HTTP/2 connection preface is also supported.
nghttpx can listen on multiple frontend addresses. This is achieved nghttpx can listen on multiple frontend addresses. This is achieved
by using multiple :option:`--frontend` options. For each frontend by using multiple :option:`--frontend` options. For each frontend
@@ -42,17 +45,17 @@ that default backend protocol is HTTP/1.1. To use HTTP/2 in backend,
you have to specify ``h2`` in ``proto`` keyword in :option:`--backend` you have to specify ``h2`` in ``proto`` keyword in :option:`--backend`
explicitly. explicitly.
The backend is supposed to be a Web server. For example, to make The backend is supposed to be Web server. For example, to make
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
backend Web server is configured to listen to HTTP requests at port backend Web server is configured to listen to HTTP request at port
8080 on the same host, run nghttpx command-line like this: 8080 in the same host, run nghttpx command-line like this:
.. code-block:: text .. code-block:: text
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt $ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
Then an HTTP/2 enabled client can access the nghttpx server using HTTP/2. For Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
example, you can send a GET request using nghttp: example, you can send GET request to the server using nghttp:
.. code-block:: text .. code-block:: text
@@ -63,18 +66,19 @@ HTTP/2 proxy mode
If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported :option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
protocols in frontend and backend connections are the same as in `default protocols in frontend and backend connections are the same in `default
mode`_. The difference is that this mode acts like a forward proxy and mode`_. The difference is that this mode acts like forward proxy and
assumes the backend is an HTTP proxy server (e.g., Squid, Apache Traffic assumes the backend is HTTP proxy server (e.g., Squid, Apache Traffic
Server). HTTP/1 requests must include an absolute URI in request line. Server). HTTP/1 request must include absolute URI in request line.
By default, the frontend connection is encrypted. So this mode is By default, frontend connection is encrypted. So this mode is also
also called secure proxy. called secure proxy. If nghttpx is linked with spdylay, it supports
SPDY protocols and it works as so called SPDY proxy.
To turn off encryption on the frontend connection, use ``no-tls`` keyword To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option. in :option:`--frontend` option.
The backend must be an HTTP proxy server. nghttpx supports multiple The backend must be HTTP proxy server. nghttpx supports multiple
backend server addresses. It translates incoming requests to HTTP backend server addresses. It translates incoming requests to HTTP
request to backend server. The backend server performs real proxy request to backend server. The backend server performs real proxy
work for each request, for example, dispatching requests to the origin work for each request, for example, dispatching requests to the origin
@@ -88,7 +92,7 @@ connection, use :option:`--backend` option, and specify ``h2`` in
For example, to make nghttpx listen to encrypted HTTP/2 requests at For example, to make nghttpx listen to encrypted HTTP/2 requests at
port 8443, and a backend HTTP proxy server is configured to listen to port 8443, and a backend HTTP proxy server is configured to listen to
HTTP/1 requests at port 8080 on the same host, run nghttpx command-line HTTP/1 request at port 8080 in the same host, run nghttpx command-line
like this: like this:
.. code-block:: text .. code-block:: text
@@ -98,8 +102,8 @@ like this:
At the time of this writing, Firefox 41 and Chromium v46 can use At the time of this writing, Firefox 41 and Chromium v46 can use
nghttpx as HTTP/2 proxy. nghttpx as HTTP/2 proxy.
To make Firefox or Chromium use nghttpx as HTTP/2 proxy, user has to To make Firefox or Chromium use nghttpx as HTTP/2 or SPDY proxy, user
create proxy.pac script file like this: has to create proxy.pac script file like this:
.. code-block:: javascript .. code-block:: javascript
@@ -293,31 +297,13 @@ When you write this option in command-line, you should enclose
argument with single or double quotes, since the character ``;`` has a argument with single or double quotes, since the character ``;`` has a
special meaning in shell. special meaning in shell.
To route, request to request path ``/foo`` to backend server To route, request to request path whose prefix is ``/foo`` to backend
``[::1]:8080``, you can write like so: server ``[::1]:8080``, you can write like so:
.. code-block:: text .. code-block:: text
backend=::1,8080;/foo backend=::1,8080;/foo
If the last character of path pattern is ``/``, all request paths
which start with that pattern match:
.. code-block:: text
backend=::1,8080;/bar/
The request path ``/bar/buzz`` matches the ``/bar/``.
You can use ``*`` at the end of the path pattern to make it wildcard
pattern. ``*`` must match at least one character:
.. code-block:: text
backend=::1,8080;/sample*
The request path ``/sample1/foo`` matches the ``/sample*`` pattern.
Of course, you can specify both host and request path at the same Of course, you can specify both host and request path at the same
time: time:
@@ -385,7 +371,7 @@ parameter in :option:`--backend` option, like so:
.. code-block:: text .. code-block:: text
backend=foo.example.com,80;;dns backend=foo.example.com;;dns
nghttpx will cache resolved addresses for certain period of time. To nghttpx will cache resolved addresses for certain period of time. To
change this cache period, use :option:`--dns-cache-timeout`. change this cache period, use :option:`--dns-cache-timeout`.
@@ -401,28 +387,6 @@ like so:
frontend=*,443;proxyproto frontend=*,443;proxyproto
Session affinity
----------------
Two kinds of session affinity are available: client IP, and HTTP
Cookie.
To enable client IP based affinity, specify ``affinity=ip`` parameter
in :option:`--backend` option. If PROXY protocol is enabled, then an
address obtained from PROXY protocol is taken into consideration.
To enable HTTP Cookie based affinity, specify ``affinity=cookie``
parameter, and specify a name of cookie in ``affinity-cookie-name``
parameter. Optionally, a Path attribute can be specified in
``affinity-cookie-path`` parameter:
.. code-block:: text
backend=127.0.0.1,3000;;affinity=cookie;affinity-cookie-name=nghttpxlb;affinity-cookie-path=/
Secure attribute of cookie is set if client connection is protected by
TLS.
PSK cipher suites PSK cipher suites
----------------- -----------------
@@ -471,33 +435,6 @@ such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
using :option:`--client-no-http2-cipher-black-list` option. But you using :option:`--client-no-http2-cipher-black-list` option. But you
should understand its implications. should understand its implications.
TLSv1.3
-------
As of nghttpx v1.34.0, if it is built with OpenSSL 1.1.1 or later, it
supports TLSv1.3. 0-RTT data is supported, but by default its
processing is postponed until TLS handshake completes to mitigate
replay attack. This costs extra round trip and reduces effectiveness
of 0-RTT data. :option:`--tls-no-postpone-early-data` makes nghttpx
not wait for handshake to complete before forwarding request included
in 0-RTT to get full potential of 0-RTT data. In this case, nghttpx
adds ``Early-Data: 1`` header field when forwarding a request to a
backend server. All backend servers should recognize this header
field and understand that there is a risk for replay attack. See `RFC
8470 <https://tools.ietf.org/html/rfc8470>`_ for ``Early-Data`` header
field.
nghttpx disables anti replay protection provided by OpenSSL. The anti
replay protection of OpenSSL requires that a resumed request must hit
the same server which generates the session ticket. Therefore it
might not work nicely in a deployment where there are multiple nghttpx
instances sharing ticket encryption keys via memcached.
Because TLSv1.3 completely changes the semantics of cipher suite
naming scheme and structure, nghttpx provides the new option
:option:`--tls13-ciphers` and :option:`--tls13-client-ciphers` to
change preferred cipher list for TLSv1.3.
Migration from nghttpx v1.18.x or earlier Migration from nghttpx v1.18.x or earlier
----------------------------------------- -----------------------------------------

View File

@@ -124,7 +124,6 @@ remote server. It's defined as::
bev = bufferevent_openssl_socket_new( bev = bufferevent_openssl_socket_new(
evbase, -1, ssl, BUFFEREVENT_SSL_CONNECTING, evbase, -1, ssl, BUFFEREVENT_SSL_CONNECTING,
BEV_OPT_DEFER_CALLBACKS | BEV_OPT_CLOSE_ON_FREE); BEV_OPT_DEFER_CALLBACKS | BEV_OPT_CLOSE_ON_FREE);
bufferevent_enable(bev, EV_READ | EV_WRITE);
bufferevent_setcb(bev, readcb, writecb, eventcb, session_data); bufferevent_setcb(bev, readcb, writecb, eventcb, session_data);
rv = bufferevent_socket_connect_hostname(bev, session_data->dnsbase, rv = bufferevent_socket_connect_hostname(bev, session_data->dnsbase,
AF_UNSPEC, host, port); AF_UNSPEC, host, port);

View File

@@ -7,8 +7,11 @@ if(ENABLE_EXAMPLES)
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}") COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
include_directories( include_directories(
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
"${CMAKE_CURRENT_SOURCE_DIR}/../third-party" ${CMAKE_SOURCE_DIR}/lib/includes
${CMAKE_BINARY_DIR}/lib/includes
${CMAKE_SOURCE_DIR}/src/includes
${CMAKE_SOURCE_DIR}/third-party
${LIBEVENT_INCLUDE_DIRS} ${LIBEVENT_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS}

View File

@@ -62,11 +62,11 @@ ASIOCPPFLAGS = ${AM_CPPFLAGS} ${BOOST_CPPFLAGS}
ASIOLDADD = $(top_builddir)/lib/libnghttp2.la \ ASIOLDADD = $(top_builddir)/lib/libnghttp2.la \
$(top_builddir)/src/libnghttp2_asio.la @JEMALLOC_LIBS@ \ $(top_builddir)/src/libnghttp2_asio.la @JEMALLOC_LIBS@ \
$(top_builddir)/third-party/libhttp-parser.la \ $(top_builddir)/third-party/libhttp-parser.la \
@OPENSSL_LIBS@ \
${BOOST_LDFLAGS} \ ${BOOST_LDFLAGS} \
${BOOST_ASIO_LIB} \ ${BOOST_ASIO_LIB} \
${BOOST_THREAD_LIB} \ ${BOOST_THREAD_LIB} \
${BOOST_SYSTEM_LIB} \ ${BOOST_SYSTEM_LIB} \
@OPENSSL_LIBS@ \
@APPLDFLAGS@ @APPLDFLAGS@
asio_sv_SOURCES = asio-sv.cc asio_sv_SOURCES = asio-sv.cc

View File

@@ -67,14 +67,14 @@ int main(int argc, char *argv[]) {
return; return;
} }
req->on_response([](const response &res) { req->on_response([&sess](const response &res) {
std::cerr << "HTTP/2 " << res.status_code() << std::endl; std::cerr << "HTTP/2 " << res.status_code() << std::endl;
for (auto &kv : res.header()) { for (auto &kv : res.header()) {
std::cerr << kv.first << ": " << kv.second.value << "\n"; std::cerr << kv.first << ": " << kv.second.value << "\n";
} }
std::cerr << std::endl; std::cerr << std::endl;
res.on_data([](const uint8_t *data, std::size_t len) { res.on_data([&sess](const uint8_t *data, std::size_t len) {
std::cerr.write(reinterpret_cast<const char *>(data), len); std::cerr.write(reinterpret_cast<const char *>(data), len);
std::cerr << std::endl; std::cerr << std::endl;
}); });

View File

@@ -91,17 +91,17 @@ int main(int argc, char *argv[]) {
return; return;
} }
req->on_response([](const response &res) { req->on_response([&sess, req](const response &res) {
std::cerr << "response header was received" << std::endl; std::cerr << "response header was received" << std::endl;
print_header(res); print_header(res);
res.on_data([](const uint8_t *data, std::size_t len) { res.on_data([&sess](const uint8_t *data, std::size_t len) {
std::cerr.write(reinterpret_cast<const char *>(data), len); std::cerr.write(reinterpret_cast<const char *>(data), len);
std::cerr << std::endl; std::cerr << std::endl;
}); });
}); });
req->on_close([](uint32_t error_code) { req->on_close([&sess](uint32_t error_code) {
std::cerr << "request done with error_code=" << error_code << std::endl; std::cerr << "request done with error_code=" << error_code << std::endl;
}); });

View File

@@ -36,10 +36,10 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H #endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H #endif // HAVE_FCNTL_H
#include <iostream> #include <iostream>
#include <string> #include <string>

View File

@@ -27,26 +27,26 @@
* intentionally made simple. * intentionally made simple.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */ #endif /* HAVE_UNISTD_H */
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> #include <fcntl.h>
#endif /* HAVE_FCNTL_H */ #endif /* HAVE_FCNTL_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */ #endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H #ifdef HAVE_NETDB_H
# include <netdb.h> #include <netdb.h>
#endif /* HAVE_NETDB_H */ #endif /* HAVE_NETDB_H */
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */ #endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <poll.h> #include <poll.h>
@@ -345,7 +345,6 @@ static void setup_nghttp2_callbacks(nghttp2_session_callbacks *callbacks) {
callbacks, on_data_chunk_recv_callback); callbacks, on_data_chunk_recv_callback);
} }
#ifndef OPENSSL_NO_NEXTPROTONEG
/* /*
* Callback function for TLS NPN. Since this program only supports * Callback function for TLS NPN. Since this program only supports
* HTTP/2 protocol, if server does not offer HTTP/2 the nghttp2 * HTTP/2 protocol, if server does not offer HTTP/2 the nghttp2
@@ -366,7 +365,6 @@ static int select_next_proto_cb(SSL *ssl, unsigned char **out,
} }
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
#endif /* !OPENSSL_NO_NEXTPROTONEG */
/* /*
* Setup SSL/TLS context. * Setup SSL/TLS context.
@@ -377,9 +375,7 @@ static void init_ssl_ctx(SSL_CTX *ssl_ctx) {
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
/* Set NPN callback */ /* Set NPN callback */
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL); SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
} }
static void ssl_handshake(SSL *ssl, int fd) { static void ssl_handshake(SSL *ssl, int fd) {

View File

@@ -23,7 +23,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* !HAVE_CONFIG_H */ #endif /* !HAVE_CONFIG_H */
#include <stdio.h> #include <stdio.h>

View File

@@ -23,33 +23,33 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef __sgi #ifdef __sgi
# include <string.h> #include <string.h>
# define errx(exitcode, format, args...) \ #define errx(exitcode, format, args...) \
{ \ { \
warnx(format, ##args); \ warnx(format, ##args); \
exit(exitcode); \ exit(exitcode); \
} }
# define warnx(format, args...) fprintf(stderr, format "\n", ##args) #define warnx(format, args...) fprintf(stderr, format "\n", ##args)
char *strndup(const char *s, size_t size); char *strndup(const char *s, size_t size);
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */ #endif /* HAVE_UNISTD_H */
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */ #endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */ #endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifndef __sgi #ifndef __sgi
# include <err.h> #include <err.h>
#endif #endif
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
@@ -308,7 +308,6 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
return 0; return 0;
} }
#ifndef OPENSSL_NO_NEXTPROTONEG
/* NPN TLS extension client callback. We check that server advertised /* NPN TLS extension client callback. We check that server advertised
the HTTP/2 protocol the nghttp2 library supports. If not, exit the HTTP/2 protocol the nghttp2 library supports. If not, exit
the program. */ the program. */
@@ -323,7 +322,6 @@ static int select_next_proto_cb(SSL *ssl, unsigned char **out,
} }
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
#endif /* !OPENSSL_NO_NEXTPROTONEG */
/* Create SSL_CTX. */ /* Create SSL_CTX. */
static SSL_CTX *create_ssl_ctx(void) { static SSL_CTX *create_ssl_ctx(void) {
@@ -337,13 +335,11 @@ static SSL_CTX *create_ssl_ctx(void) {
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_COMPRESSION | SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); 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); SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3); SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx; return ssl_ctx;
} }
@@ -508,14 +504,12 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
ssl = bufferevent_openssl_get_ssl(session_data->bev); ssl = bufferevent_openssl_get_ssl(session_data->bev);
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) { if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
} }
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "h2 is not negotiated\n"); fprintf(stderr, "h2 is not negotiated\n");
@@ -554,7 +548,6 @@ static void initiate_connection(struct event_base *evbase, SSL_CTX *ssl_ctx,
bev = bufferevent_openssl_socket_new( bev = bufferevent_openssl_socket_new(
evbase, -1, ssl, BUFFEREVENT_SSL_CONNECTING, evbase, -1, ssl, BUFFEREVENT_SSL_CONNECTING,
BEV_OPT_DEFER_CALLBACKS | BEV_OPT_CLOSE_ON_FREE); BEV_OPT_DEFER_CALLBACKS | BEV_OPT_CLOSE_ON_FREE);
bufferevent_enable(bev, EV_READ | EV_WRITE);
bufferevent_setcb(bev, readcb, writecb, eventcb, session_data); bufferevent_setcb(bev, readcb, writecb, eventcb, session_data);
rv = bufferevent_socket_connect_hostname(bev, session_data->dnsbase, rv = bufferevent_socket_connect_hostname(bev, session_data->dnsbase,
AF_UNSPEC, host, port); AF_UNSPEC, host, port);

View File

@@ -23,41 +23,41 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef __sgi #ifdef __sgi
# define errx(exitcode, format, args...) \ #define errx(exitcode, format, args...) \
{ \ { \
warnx(format, ##args); \ warnx(format, ##args); \
exit(exitcode); \ exit(exitcode); \
} }
# define warn(format, args...) warnx(format ": %s", ##args, strerror(errno)) #define warn(format, args...) warnx(format ": %s", ##args, strerror(errno))
# define warnx(format, args...) fprintf(stderr, format "\n", ##args) #define warnx(format, args...) fprintf(stderr, format "\n", ##args)
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h> #include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */ #endif /* HAVE_SYS_SOCKET_H */
#ifdef HAVE_NETDB_H #ifdef HAVE_NETDB_H
# include <netdb.h> #include <netdb.h>
#endif /* HAVE_NETDB_H */ #endif /* HAVE_NETDB_H */
#include <signal.h> #include <signal.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> #include <unistd.h>
#endif /* HAVE_UNISTD_H */ #endif /* HAVE_UNISTD_H */
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> #include <fcntl.h>
#endif /* HAVE_FCNTL_H */ #endif /* HAVE_FCNTL_H */
#include <ctype.h> #include <ctype.h>
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */ #endif /* HAVE_NETINET_IN_H */
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifndef __sgi #ifndef __sgi
# include <err.h> #include <err.h>
#endif #endif
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@@ -109,7 +109,6 @@ struct app_context {
static unsigned char next_proto_list[256]; static unsigned char next_proto_list[256];
static size_t next_proto_list_len; static size_t next_proto_list_len;
#ifndef OPENSSL_NO_NEXTPROTONEG
static int next_proto_cb(SSL *ssl, const unsigned char **data, static int next_proto_cb(SSL *ssl, const unsigned char **data,
unsigned int *len, void *arg) { unsigned int *len, void *arg) {
(void)ssl; (void)ssl;
@@ -119,7 +118,6 @@ static int next_proto_cb(SSL *ssl, const unsigned char **data,
*len = (unsigned int)next_proto_list_len; *len = (unsigned int)next_proto_list_len;
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out, static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
@@ -137,7 +135,7 @@ static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
/* Create SSL_CTX. */ /* Create SSL_CTX. */
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) { static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
@@ -174,13 +172,11 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
NGHTTP2_PROTO_VERSION_ID_LEN); NGHTTP2_PROTO_VERSION_ID_LEN);
next_proto_list_len = 1 + 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); SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL); SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx; return ssl_ctx;
} }
@@ -254,7 +250,6 @@ static http2_session_data *create_http2_session_data(app_context *app_ctx,
session_data->bev = bufferevent_openssl_socket_new( session_data->bev = bufferevent_openssl_socket_new(
app_ctx->evbase, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, app_ctx->evbase, fd, ssl, BUFFEREVENT_SSL_ACCEPTING,
BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS); BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
bufferevent_enable(session_data->bev, EV_READ | EV_WRITE);
rv = getnameinfo(addr, (socklen_t)addrlen, host, sizeof(host), NULL, 0, rv = getnameinfo(addr, (socklen_t)addrlen, host, sizeof(host), NULL, 0,
NI_NUMERICHOST); NI_NUMERICHOST);
if (rv != 0) { if (rv != 0) {
@@ -694,14 +689,12 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
ssl = bufferevent_openssl_get_ssl(session_data->bev); ssl = bufferevent_openssl_get_ssl(session_data->bev);
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) { if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
} }
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr); fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);

View File

@@ -23,8 +23,8 @@ following compiler/linker flags:
.. code-block:: text .. code-block:: text
CPPFLAGS="-fsanitize-coverage=edge -fsanitize=address" CPPFLAGS="-fsanitize-coverage=edge -fsanitize=addres"
LDFLAGS="-fsanitize-coverage=edge -fsanitize=address" LDFLAGS="-fsanitize-coverage=edge -fsanitize=addres"
Then, fuzz_target.cc can be built using the following command: Then, fuzz_target.cc can be built using the following command:

View File

@@ -9,7 +9,6 @@ HEADERS = [
':scheme', ':scheme',
':status', ':status',
':host', # for spdy ':host', # for spdy
':protocol',
'expect', 'expect',
'host', 'host',
'if-modified-since', 'if-modified-since',
@@ -32,9 +31,6 @@ HEADERS = [
"user-agent", "user-agent",
"date", "date",
"content-type", "content-type",
"early-data",
"sec-websocket-accept",
"sec-websocket-key",
# disallowed h1 headers # disallowed h1 headers
'connection', 'connection',
'keep-alive', 'keep-alive',
@@ -44,4 +40,4 @@ HEADERS = [
] ]
if __name__ == '__main__': if __name__ == '__main__':
gentokenlookup(HEADERS, 'HD_') gentokenlookup(HEADERS, 'HD')

View File

@@ -67,7 +67,6 @@ HEADERS = [
('keep-alive',None), ('keep-alive',None),
('proxy-connection', None), ('proxy-connection', None),
('upgrade', None), ('upgrade', None),
(':protocol', None),
] ]
def to_enum_hd(k): def to_enum_hd(k):

View File

@@ -50,4 +50,4 @@ if __name__ == '__main__':
continue continue
_, m, _ = line.split(',', 2) _, m, _ = line.split(',', 2)
methods.append(m.strip()) methods.append(m.strip())
gentokenlookup(methods, 'HTTP_') gentokenlookup(methods, 'HTTP')

View File

@@ -163,18 +163,6 @@ OPTIONS = [
"redirect-https-port", "redirect-https-port",
"frontend-max-requests", "frontend-max-requests",
"single-thread", "single-thread",
"single-process",
"no-add-x-forwarded-proto",
"no-strip-incoming-x-forwarded-proto",
"ocsp-startup",
"no-verify-ocsp",
"verify-client-tolerate-expired",
"ignore-per-pattern-mruby-error",
"tls-no-postpone-early-data",
"tls-max-early-data",
"tls13-ciphers",
"tls13-client-ciphers",
"no-strip-incoming-early-data",
] ]
LOGVARS = [ LOGVARS = [
@@ -193,20 +181,10 @@ LOGVARS = [
"ssl_protocol", "ssl_protocol",
"ssl_session_id", "ssl_session_id",
"ssl_session_reused", "ssl_session_reused",
"tls_cipher",
"tls_protocol",
"tls_session_id",
"tls_session_reused",
"tls_sni",
"tls_client_fingerprint_sha256",
"tls_client_fingerprint_sha1",
"tls_client_subject_name",
"tls_client_issuer_name",
"tls_client_serial",
"backend_host", "backend_host",
"backend_port", "backend_port",
] ]
if __name__ == '__main__': if __name__ == '__main__':
gentokenlookup(OPTIONS, 'SHRPX_OPTID_', value_type='char', comp_fun='util::strieq_l') 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') gentokenlookup(LOGVARS, 'SHRPX_LOGF', value_type='char', comp_fun='util::strieq_l', return_type='LogFragmentType', fail_value='SHRPX_LOGF_NONE')

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
def to_enum_hd(k, prefix): def to_enum_hd(k, prefix):
res = prefix res = prefix + '_'
for c in k.upper(): for c in k.upper():
if c == ':' or c == '-': if c == ':' or c == '-':
res += '_' res += '_'
@@ -30,7 +30,7 @@ enum {'''
print '''\ print '''\
{},'''.format(to_enum_hd(k, prefix)) {},'''.format(to_enum_hd(k, prefix))
print '''\ print '''\
{}MAXIDX, {}_MAXIDX,
}};'''.format(prefix) }};'''.format(prefix)
def gen_index_header(tokens, prefix, value_type, comp_fun, return_type, fail_value): def gen_index_header(tokens, prefix, value_type, comp_fun, return_type, fail_value):

View File

@@ -1,6 +1,7 @@
set(GO_FILES set(GO_FILES
nghttpx_http1_test.go nghttpx_http1_test.go
nghttpx_http2_test.go nghttpx_http2_test.go
nghttpx_spdy_test.go
server_tester.go server_tester.go
) )
@@ -21,6 +22,7 @@ set(EXTRA_DIST
add_custom_target(itprep add_custom_target(itprep
COMMAND go get -d -v golang.org/x/net/http2 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 github.com/tatsuhiro-t/go-nghttp2
COMMAND go get -d -v github.com/tatsuhiro-t/spdy
COMMAND go get -d -v golang.org/x/net/websocket COMMAND go get -d -v golang.org/x/net/websocket
) )

View File

@@ -24,6 +24,7 @@
GO_FILES = \ GO_FILES = \
nghttpx_http1_test.go \ nghttpx_http1_test.go \
nghttpx_http2_test.go \ nghttpx_http2_test.go \
nghttpx_spdy_test.go \
server_tester.go server_tester.go
EXTRA_DIST = \ EXTRA_DIST = \
@@ -42,6 +43,7 @@ EXTRA_DIST = \
itprep: itprep:
go get -d -v golang.org/x/net/http2 go get -d -v golang.org/x/net/http2
go get -d -v github.com/tatsuhiro-t/go-nghttp2 go get -d -v github.com/tatsuhiro-t/go-nghttp2
go get -d -v github.com/tatsuhiro-t/spdy
go get -d -v golang.org/x/net/websocket go get -d -v golang.org/x/net/websocket
it: it:

View File

@@ -9,7 +9,6 @@ import (
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
"io" "io"
"net/http" "net/http"
"regexp"
"syscall" "syscall"
"testing" "testing"
"time" "time"
@@ -126,54 +125,6 @@ Content-Length: 0
// } // }
// } // }
// TestH1H1AffinityCookie tests that affinity cookie is sent back in
// cleartext http.
func TestH1H1AffinityCookie(t *testing.T) {
st := newServerTester([]string{"--affinity-cookie"}, t, noopHandler)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1H1AffinityCookie",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
const pattern = `affinity=[0-9a-f]{8}; Path=/foo/bar`
validCookie := regexp.MustCompile(pattern)
if got := res.header.Get("Set-Cookie"); !validCookie.MatchString(got) {
t.Errorf("Set-Cookie: %v; want pattern %v", got, pattern)
}
}
// TestH1H1AffinityCookieTLS tests that affinity cookie is sent back
// in https.
func TestH1H1AffinityCookieTLS(t *testing.T) {
st := newServerTesterTLS([]string{"--alpn-h1", "--affinity-cookie"}, t, noopHandler)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1H1AffinityCookieTLS",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
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)
}
}
// TestH1H1GracefulShutdown tests graceful shutdown. // TestH1H1GracefulShutdown tests graceful shutdown.
func TestH1H1GracefulShutdown(t *testing.T) { func TestH1H1GracefulShutdown(t *testing.T) {
st := newServerTester(nil, t, noopHandler) st := newServerTester(nil, t, noopHandler)
@@ -211,7 +162,7 @@ func TestH1H1GracefulShutdown(t *testing.T) {
want := io.EOF want := io.EOF
b := make([]byte, 256) b := make([]byte, 256)
if _, err := st.conn.Read(b); err == nil || err != want { if _, err := st.conn.Read(b); err == nil || err != want {
t.Errorf("st.conn.Read(): %v; want %v", err, want) t.Errorf("st.conn.Read(): %v; want %v, %v", err, want)
} }
} }

View File

@@ -35,105 +35,6 @@ func TestH2H1PlainGET(t *testing.T) {
} }
} }
// TestH2H1AddXfp tests that server appends :scheme to the existing
// x-forwarded-proto header field.
func TestH2H1AddXfp(t *testing.T) {
st := newServerTester([]string{"--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
xfp := r.Header.Get("X-Forwarded-Proto")
if got, want := xfp, "foo, http"; got != want {
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1AddXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1NoAddXfp tests that server does not append :scheme to the
// existing x-forwarded-proto header field.
func TestH2H1NoAddXfp(t *testing.T) {
st := newServerTester([]string{"--no-add-x-forwarded-proto", "--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
xfp := r.Header.Get("X-Forwarded-Proto")
if got, want := xfp, "foo"; got != want {
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1NoAddXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1StripXfp tests that server strips incoming
// x-forwarded-proto header field.
func TestH2H1StripXfp(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
xfp := r.Header.Get("X-Forwarded-Proto")
if got, want := xfp, "http"; got != want {
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1StripXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1StripNoAddXfp tests that server strips incoming
// x-forwarded-proto header field, and does not add another.
func TestH2H1StripNoAddXfp(t *testing.T) {
st := newServerTester([]string{"--no-add-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, found := r.Header["X-Forwarded-Proto"]; found {
t.Errorf("X-Forwarded-Proto = %q; want nothing", got)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1StripNoAddXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1AddXff tests that server generates X-Forwarded-For header // TestH2H1AddXff tests that server generates X-Forwarded-For header
// field when forwarding request to backend. // field when forwarding request to backend.
func TestH2H1AddXff(t *testing.T) { func TestH2H1AddXff(t *testing.T) {
@@ -1113,45 +1014,14 @@ func TestH2H1Upgrade(t *testing.T) {
} }
} }
// TestH2H1ProxyProtocolV1ForwardedForObfuscated tests that Forwarded
// header field includes obfuscated address even if PROXY protocol
// version 1 containing TCP4 entry is accepted.
func TestH2H1ProxyProtocolV1ForwardedForObfuscated(t *testing.T) {
pattern := fmt.Sprintf(`^for=_[^;]+$`)
validFwd := regexp.MustCompile(pattern)
st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for", "--add-forwarded=for", "--forwarded-for=obfuscated"}, t, func(w http.ResponseWriter, r *http.Request) {
if got := r.Header.Get("Forwarded"); !validFwd.MatchString(got) {
t.Errorf("Forwarded: %v; want pattern %v", got, pattern)
}
})
defer st.Close()
st.conn.Write([]byte("PROXY TCP4 192.168.0.2 192.168.0.100 12345 8080\r\n"))
res, err := st.http2(requestParam{
name: "TestH2H1ProxyProtocolV1ForwardedForObfuscated",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}
// TestH2H1ProxyProtocolV1TCP4 tests PROXY protocol version 1 // TestH2H1ProxyProtocolV1TCP4 tests PROXY protocol version 1
// containing TCP4 entry is accepted and X-Forwarded-For contains // containing TCP4 entry is accepted and X-Forwarded-For contains
// advertised src address. // advertised src address.
func TestH2H1ProxyProtocolV1TCP4(t *testing.T) { func TestH2H1ProxyProtocolV1TCP4(t *testing.T) {
st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for", "--add-forwarded=for", "--forwarded-for=ip"}, t, func(w http.ResponseWriter, r *http.Request) { st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("X-Forwarded-For"), "192.168.0.2"; got != want { if got, want := r.Header.Get("X-Forwarded-For"), "192.168.0.2"; got != want {
t.Errorf("X-Forwarded-For: %v; want %v", got, want) t.Errorf("X-Forwarded-For: %v; want %v", got, want)
} }
if got, want := r.Header.Get("Forwarded"), "for=192.168.0.2"; got != want {
t.Errorf("Forwarded: %v; want %v", got, want)
}
}) })
defer st.Close() defer st.Close()
@@ -1174,13 +1044,10 @@ func TestH2H1ProxyProtocolV1TCP4(t *testing.T) {
// containing TCP6 entry is accepted and X-Forwarded-For contains // containing TCP6 entry is accepted and X-Forwarded-For contains
// advertised src address. // advertised src address.
func TestH2H1ProxyProtocolV1TCP6(t *testing.T) { func TestH2H1ProxyProtocolV1TCP6(t *testing.T) {
st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for", "--add-forwarded=for", "--forwarded-for=ip"}, t, func(w http.ResponseWriter, r *http.Request) { st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("X-Forwarded-For"), "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; got != want { if got, want := r.Header.Get("X-Forwarded-For"), "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; got != want {
t.Errorf("X-Forwarded-For: %v; want %v", got, want) t.Errorf("X-Forwarded-For: %v; want %v", got, want)
} }
if got, want := r.Header.Get("Forwarded"), `for="[2001:0db8:85a3:0000:0000:8a2e:0370:7334]"`; got != want {
t.Errorf("Forwarded: %v; want %v", got, want)
}
}) })
defer st.Close() defer st.Close()
@@ -1202,12 +1069,9 @@ func TestH2H1ProxyProtocolV1TCP6(t *testing.T) {
// TestH2H1ProxyProtocolV1Unknown tests PROXY protocol version 1 // TestH2H1ProxyProtocolV1Unknown tests PROXY protocol version 1
// containing UNKNOWN entry is accepted. // containing UNKNOWN entry is accepted.
func TestH2H1ProxyProtocolV1Unknown(t *testing.T) { func TestH2H1ProxyProtocolV1Unknown(t *testing.T) {
st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for", "--add-forwarded=for", "--forwarded-for=ip"}, t, func(w http.ResponseWriter, r *http.Request) { st := newServerTester([]string{"--accept-proxy-protocol", "--add-x-forwarded-for"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, notWant := r.Header.Get("X-Forwarded-For"), "192.168.0.2"; got == notWant { if got, notWant := r.Header.Get("X-Forwarded-For"), "192.168.0.2"; got == notWant {
t.Errorf("X-Forwarded-For: %v; want something else", got) t.Errorf("X-Forwarded-For: %v")
}
if got, notWant := r.Header.Get("Forwarded"), "for=192.168.0.2"; got == notWant {
t.Errorf("Forwarded: %v; want something else", got)
} }
}) })
defer st.Close() defer st.Close()
@@ -1585,175 +1449,6 @@ func TestH2H1HTTPSRedirectPort(t *testing.T) {
} }
} }
// TestH2H1Code204 tests that 204 response without content-length, and
// transfer-encoding is valid.
func TestH2H1Code204(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1Code204",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 204; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1Code204CL0 tests that 204 response with content-length: 0
// is allowed.
func TestH2H1Code204CL0(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()
bufrw.WriteString("HTTP/1.1 204\r\nContent-Length: 0\r\n\r\n")
bufrw.Flush()
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1Code204CL0",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 204; got != want {
t.Errorf("status = %v; want %v", got, want)
}
if got, found := res.header["Content-Length"]; found {
t.Errorf("Content-Length = %v, want nothing", got)
}
}
// TestH2H1Code204CLNonzero tests that 204 response with nonzero
// content-length is not allowed.
func TestH2H1Code204CLNonzero(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()
bufrw.WriteString("HTTP/1.1 204\r\nContent-Length: 1\r\n\r\n")
bufrw.Flush()
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1Code204CLNonzero",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 502; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1Code204TE tests that 204 response with transfer-encoding is
// not allowed.
func TestH2H1Code204TE(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
return
}
conn, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()
bufrw.WriteString("HTTP/1.1 204\r\nTransfer-Encoding: chunked\r\n\r\n")
bufrw.Flush()
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1Code204TE",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 502; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1AffinityCookie tests that affinity cookie is sent back in
// cleartext http.
func TestH2H1AffinityCookie(t *testing.T) {
st := newServerTester([]string{"--affinity-cookie"}, t, noopHandler)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1AffinityCookie",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
const pattern = `affinity=[0-9a-f]{8}; Path=/foo/bar`
validCookie := regexp.MustCompile(pattern)
if got := res.header.Get("Set-Cookie"); !validCookie.MatchString(got) {
t.Errorf("Set-Cookie: %v; want pattern %v", got, pattern)
}
}
// TestH2H1AffinityCookieTLS tests that affinity cookie is sent back
// in https.
func TestH2H1AffinityCookieTLS(t *testing.T) {
st := newServerTesterTLS([]string{"--affinity-cookie"}, t, noopHandler)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1AffinityCookieTLS",
scheme: "https",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
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)
}
}
// TestH2H1GracefulShutdown tests graceful shutdown. // TestH2H1GracefulShutdown tests graceful shutdown.
func TestH2H1GracefulShutdown(t *testing.T) { func TestH2H1GracefulShutdown(t *testing.T) {
st := newServerTester(nil, t, noopHandler) st := newServerTester(nil, t, noopHandler)
@@ -1958,105 +1653,6 @@ func TestH2H2TLSXfp(t *testing.T) {
} }
} }
// TestH2H2AddXfp tests that server appends :scheme to the existing
// x-forwarded-proto header field.
func TestH2H2AddXfp(t *testing.T) {
st := newServerTesterTLS([]string{"--http2-bridge", "--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
xfp := r.Header.Get("X-Forwarded-Proto")
if got, want := xfp, "foo, http"; got != want {
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2AddXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H2NoAddXfp tests that server does not append :scheme to the
// existing x-forwarded-proto header field.
func TestH2H2NoAddXfp(t *testing.T) {
st := newServerTesterTLS([]string{"--http2-bridge", "--no-add-x-forwarded-proto", "--no-strip-incoming-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
xfp := r.Header.Get("X-Forwarded-Proto")
if got, want := xfp, "foo"; got != want {
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2NoAddXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H2StripXfp tests that server strips incoming
// x-forwarded-proto header field.
func TestH2H2StripXfp(t *testing.T) {
st := newServerTesterTLS([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
xfp := r.Header.Get("X-Forwarded-Proto")
if got, want := xfp, "http"; got != want {
t.Errorf("X-Forwarded-Proto = %q; want %q", got, want)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2StripXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H2StripNoAddXfp tests that server strips incoming
// x-forwarded-proto header field, and does not add another.
func TestH2H2StripNoAddXfp(t *testing.T) {
st := newServerTesterTLS([]string{"--http2-bridge", "--no-add-x-forwarded-proto"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, found := r.Header["X-Forwarded-Proto"]; found {
t.Errorf("X-Forwarded-Proto = %q; want nothing", got)
}
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2StripNoAddXfp",
header: []hpack.HeaderField{
pair("x-forwarded-proto", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H2AddXff tests that server generates X-Forwarded-For header // TestH2H2AddXff tests that server generates X-Forwarded-For header
// field when forwarding request to backend. // field when forwarding request to backend.
func TestH2H2AddXff(t *testing.T) { func TestH2H2AddXff(t *testing.T) {
@@ -2365,26 +1961,6 @@ func TestH2H2DNS(t *testing.T) {
} }
} }
// TestH2H2Code204 tests that 204 response without content-length, and
// transfer-encoding is valid.
func TestH2H2Code204(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2Code204",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 204; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2APIBackendconfig exercise backendconfig API endpoint routine // TestH2APIBackendconfig exercise backendconfig API endpoint routine
// for successful case. // for successful case.
func TestH2APIBackendconfig(t *testing.T) { func TestH2APIBackendconfig(t *testing.T) {

View File

@@ -0,0 +1,664 @@
package nghttp2
import (
"encoding/json"
"github.com/tatsuhiro-t/spdy"
"golang.org/x/net/http2/hpack"
"net/http"
"testing"
)
// TestS3H1PlainGET tests whether simple SPDY GET request works.
func TestS3H1PlainGET(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, noopHandler)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1PlainGET",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
want := 200
if got := res.status; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestS3H1BadRequestCL tests that server rejects request whose
// content-length header field value does not match its request body
// size.
func TestS3H1BadRequestCL(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, noopHandler)
defer st.Close()
// we set content-length: 1024, but the actual request body is
// 3 bytes.
res, err := st.spdy(requestParam{
name: "TestS3H1BadRequestCL",
method: "POST",
header: []hpack.HeaderField{
pair("content-length", "1024"),
},
body: []byte("foo"),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
want := spdy.ProtocolError
if got := res.spdyRstErrCode; got != want {
t.Errorf("res.spdyRstErrCode = %v; want %v", got, want)
}
}
// TestS3H1MultipleRequestCL tests that server rejects request with
// multiple Content-Length request header fields.
func TestS3H1MultipleRequestCL(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward bad request")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1MultipleRequestCL",
header: []hpack.HeaderField{
pair("content-length", "1"),
pair("content-length", "1"),
},
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
want := 400
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestS3H1InvalidRequestCL tests that server rejects request with
// Content-Length which cannot be parsed as a number.
func TestS3H1InvalidRequestCL(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward bad request")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1InvalidRequestCL",
header: []hpack.HeaderField{
pair("content-length", ""),
},
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
want := 400
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestS3H1GenerateVia tests that server generates Via header field to and
// from backend server.
func TestS3H1GenerateVia(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("Via"), "1.1 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1GenerateVia",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.header.Get("Via"), "1.1 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
}
// TestS3H1AppendVia tests that server adds value to existing Via
// header field to and from backend server.
func TestS3H1AppendVia(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("Via"), "foo, 1.1 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
w.Header().Add("Via", "bar")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1AppendVia",
header: []hpack.HeaderField{
pair("via", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.header.Get("Via"), "bar, 1.1 nghttpx"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
}
// TestS3H1NoVia tests that server does not add value to existing Via
// header field to and from backend server.
func TestS3H1NoVia(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--no-via"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("Via"), "foo"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
w.Header().Add("Via", "bar")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1NoVia",
header: []hpack.HeaderField{
pair("via", "foo"),
},
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.header.Get("Via"), "bar"; got != want {
t.Errorf("Via: %v; want %v", got, want)
}
}
// TestS3H1HeaderFieldBuffer tests that request with header fields
// larger than configured buffer size is rejected.
func TestS3H1HeaderFieldBuffer(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--request-header-field-buffer=10"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("execution path should not be here")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1HeaderFieldBuffer",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.spdyRstErrCode, spdy.InternalError; got != want {
t.Errorf("res.spdyRstErrCode: %v; want %v", got, want)
}
}
// TestS3H1HeaderFields tests that request with header fields more
// than configured number is rejected.
func TestS3H1HeaderFields(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--max-request-header-fields=1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("execution path should not be here")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1HeaderFields",
// we have at least 5 pseudo-header fields sent, and
// that ensures that buffer limit exceeds.
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.spdyRstErrCode, spdy.InternalError; got != want {
t.Errorf("res.spdyRstErrCode: %v; want %v", got, want)
}
}
// TestS3H1InvalidMethod tests that server rejects invalid method with
// 501.
func TestS3H1InvalidMethod(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward this request")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1InvalidMethod",
method: "get",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 501; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestS3H1BadHost tests that server rejects request including bad
// character in :host header field.
func TestS3H1BadHost(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward this request")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1BadHost",
authority: `foo\bar`,
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 400; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestS3H1BadScheme tests that server rejects request including bad
// character in :scheme header field.
func TestS3H1BadScheme(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward this request")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1BadScheme",
scheme: `http*`,
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 400; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestS3H1ReqPhaseSetHeader tests mruby request phase hook
// modifies request header fields.
func TestS3H1ReqPhaseSetHeader(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/req-set-header.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("User-Agent"), "mruby"; got != want {
t.Errorf("User-Agent = %v; want %v", got, want)
}
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1ReqPhaseSetHeader",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestS3H1ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func TestS3H1ReqPhaseReturn(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1ReqPhaseReturn",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("status = %v; want %v", got, want)
}
hdtests := []struct {
k, v string
}{
{"content-length", "20"},
{"from", "mruby"},
}
for _, tt := range hdtests {
if got, want := res.header.Get(tt.k), tt.v; got != want {
t.Errorf("%v = %v; want %v", tt.k, got, want)
}
}
if got, want := string(res.body), "Hello World from req"; got != want {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestS3H1RespPhaseSetHeader tests mruby response phase hook modifies
// response header fields.
func TestS3H1RespPhaseSetHeader(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/resp-set-header.rb"}, t, noopHandler)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1RespPhaseSetHeader",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
if got, want := res.header.Get("alpha"), "bravo"; got != want {
t.Errorf("alpha = %v; want %v", got, want)
}
}
// TestS3H1RespPhaseReturn tests mruby response phase hook returns
// custom response.
func TestS3H1RespPhaseReturn(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/resp-return.rb"}, t, noopHandler)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1RespPhaseReturn",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("status = %v; want %v", got, want)
}
hdtests := []struct {
k, v string
}{
{"content-length", "21"},
{"from", "mruby"},
}
for _, tt := range hdtests {
if got, want := res.header.Get(tt.k), tt.v; got != want {
t.Errorf("%v = %v; want %v", tt.k, got, want)
}
}
if got, want := string(res.body), "Hello World from resp"; got != want {
t.Errorf("body = %v; want %v", got, want)
}
}
// // TestS3H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestS3H2ConnectFailure(t *testing.T) {
// st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
// defer st.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
// res, err := st.spdy(requestParam{
// name: "TestS3H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.spdy() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
// custom response.
func TestS3H2ReqPhaseReturn(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H2ReqPhaseReturn",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("status = %v; want %v", got, want)
}
hdtests := []struct {
k, v string
}{
{"content-length", "20"},
{"from", "mruby"},
}
for _, tt := range hdtests {
if got, want := res.header.Get(tt.k), tt.v; got != want {
t.Errorf("%v = %v; want %v", tt.k, got, want)
}
}
if got, want := string(res.body), "Hello World from req"; got != want {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestS3H2RespPhaseReturn tests mruby response phase hook returns
// custom response.
func TestS3H2RespPhaseReturn(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge", "--mruby-file=" + testDir + "/resp-return.rb"}, t, noopHandler)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H2RespPhaseReturn",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("status = %v; want %v", got, want)
}
hdtests := []struct {
k, v string
}{
{"content-length", "21"},
{"from", "mruby"},
}
for _, tt := range hdtests {
if got, want := res.header.Get(tt.k), tt.v; got != want {
t.Errorf("%v = %v; want %v", tt.k, got, want)
}
}
if got, want := string(res.body), "Hello World from resp"; got != want {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestS3APIBackendconfig exercise backendconfig API endpoint routine
// for successful case.
func TestS3APIBackendconfig(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APIBackendconfig",
path: "/api/v1beta1/backendconfig",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3APIBackendconfigQuery exercise backendconfig API endpoint
// routine with query.
func TestS3APIBackendconfigQuery(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APIBackendconfigQuery",
path: "/api/v1beta1/backendconfig?foo=bar",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3APIBackendconfigBadMethod exercise backendconfig API endpoint
// routine with bad method.
func TestS3APIBackendconfigBadMethod(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APIBackendconfigBadMethod",
path: "/api/v1beta1/backendconfig",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 405; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 405; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3APINotFound exercise backendconfig API endpoint routine when
// API endpoint is not found.
func TestS3APINotFound(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APINotFound",
path: "/api/notfound",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 404; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3Healthmon tests health monitor endpoint.
func TestS3Healthmon(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3011;healthmon"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3011)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3Healthmon",
path: "/alpha/bravo",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}
// TestS3ResponseBeforeRequestEnd tests the situation where response
// ends before request body finishes.
func TestS3ResponseBeforeRequestEnd(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("request should not be forwarded")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3ResponseBeforeRequestEnd",
noEndStream: true,
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}

View File

@@ -7,6 +7,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/tatsuhiro-t/go-nghttp2" "github.com/tatsuhiro-t/go-nghttp2"
"github.com/tatsuhiro-t/spdy"
"golang.org/x/net/http2" "golang.org/x/net/http2"
"golang.org/x/net/http2/hpack" "golang.org/x/net/http2/hpack"
"golang.org/x/net/websocket" "golang.org/x/net/websocket"
@@ -52,12 +53,14 @@ type serverTester struct {
h2PrefaceSent bool // HTTP/2 preface was sent in conn h2PrefaceSent bool // HTTP/2 preface was sent in conn
nextStreamID uint32 // next stream ID nextStreamID uint32 // next stream ID
fr *http2.Framer // HTTP/2 framer fr *http2.Framer // HTTP/2 framer
spdyFr *spdy.Framer // SPDY/3.1 framer
headerBlkBuf bytes.Buffer // buffer to store encoded header block headerBlkBuf bytes.Buffer // buffer to store encoded header block
enc *hpack.Encoder // HTTP/2 HPACK encoder enc *hpack.Encoder // HTTP/2 HPACK encoder
header http.Header // received header fields header http.Header // received header fields
dec *hpack.Decoder // HTTP/2 HPACK decoder dec *hpack.Decoder // HTTP/2 HPACK decoder
authority string // server's host:port authority string // server's host:port
frCh chan http2.Frame // used for incoming HTTP/2 frame frCh chan http2.Frame // used for incoming HTTP/2 frame
spdyFrCh chan spdy.Frame // used for incoming SPDY frame
errCh chan error errCh chan error
} }
@@ -98,7 +101,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
args := []string{} args := []string{}
var backendTLS, dns, externalDNS, acceptProxyProtocol, redirectIfNotTLS, affinityCookie, alpnH1 bool var backendTLS, dns, externalDNS, acceptProxyProtocol, redirectIfNotTLS bool
for _, k := range src_args { for _, k := range src_args {
switch k { switch k {
@@ -113,10 +116,6 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
acceptProxyProtocol = true acceptProxyProtocol = true
case "--redirect-if-not-tls": case "--redirect-if-not-tls":
redirectIfNotTLS = true redirectIfNotTLS = true
case "--affinity-cookie":
affinityCookie = true
case "--alpn-h1":
alpnH1 = true
default: default:
args = append(args, k) args = append(args, k)
} }
@@ -154,8 +153,8 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
if sep == -1 { if sep == -1 {
t.Fatalf("backendURL.Host %v does not contain separator ':'", backendURL.Host) t.Fatalf("backendURL.Host %v does not contain separator ':'", backendURL.Host)
} }
// We use awesome service nip.io. // We use awesome service xip.io.
b += fmt.Sprintf("%v.nip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:]) b += fmt.Sprintf("%v.xip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
} }
if backendTLS { if backendTLS {
@@ -169,10 +168,6 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
b += ";redirect-if-not-tls" b += ";redirect-if-not-tls"
} }
if affinityCookie {
b += ";affinity=cookie;affinity-cookie-name=affinity;affinity-cookie-path=/foo/bar"
}
noTLS := ";no-tls" noTLS := ";no-tls"
if frontendTLS { if frontendTLS {
noTLS = "" noTLS = ""
@@ -198,6 +193,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
nextStreamID: 1, nextStreamID: 1,
authority: authority, authority: authority,
frCh: make(chan http2.Frame), frCh: make(chan http2.Frame),
spdyFrCh: make(chan spdy.Frame),
errCh: make(chan error), errCh: make(chan error),
} }
@@ -222,11 +218,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
tlsConfig = clientConfig tlsConfig = clientConfig
} }
tlsConfig.InsecureSkipVerify = true tlsConfig.InsecureSkipVerify = true
if alpnH1 { tlsConfig.NextProtos = []string{"h2", "spdy/3.1"}
tlsConfig.NextProtos = []string{"http/1.1"}
} else {
tlsConfig.NextProtos = []string{"h2"}
}
conn, err = tls.Dial("tcp", authority, tlsConfig) conn, err = tls.Dial("tcp", authority, tlsConfig)
} else { } else {
conn, err = net.Dial("tcp", authority) conn, err = net.Dial("tcp", authority)
@@ -252,6 +244,12 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
} }
st.fr = http2.NewFramer(st.conn, st.conn) st.fr = http2.NewFramer(st.conn, st.conn)
spdyFr, err := spdy.NewFramer(st.conn, st.conn)
if err != nil {
st.Close()
st.t.Fatalf("Error spdy.NewFramer: %v", err)
}
st.spdyFr = spdyFr
st.enc = hpack.NewEncoder(&st.headerBlkBuf) st.enc = hpack.NewEncoder(&st.headerBlkBuf)
st.dec = hpack.NewDecoder(4096, func(f hpack.HeaderField) { st.dec = hpack.NewDecoder(4096, func(f hpack.HeaderField) {
st.header.Add(f.Name, f.Value) st.header.Add(f.Name, f.Value)
@@ -268,7 +266,7 @@ func (st *serverTester) Close() {
done := make(chan struct{}) done := make(chan struct{})
go func() { go func() {
st.cmd.Wait() st.cmd.Wait()
close(done) done <- struct{}{}
}() }()
st.cmd.Process.Signal(syscall.SIGQUIT) st.cmd.Process.Signal(syscall.SIGQUIT)
@@ -305,6 +303,26 @@ func (st *serverTester) readFrame() (http2.Frame, error) {
} }
} }
func (st *serverTester) readSpdyFrame() (spdy.Frame, error) {
go func() {
f, err := st.spdyFr.ReadFrame()
if err != nil {
st.errCh <- err
return
}
st.spdyFrCh <- f
}()
select {
case f := <-st.spdyFrCh:
return f, nil
case err := <-st.errCh:
return nil, err
case <-time.After(2 * time.Second):
return nil, errors.New("timeout waiting for frame")
}
}
type requestParam struct { type requestParam struct {
name string // name for this request to identify the request in log easily name string // name for this request to identify the request in log easily
streamID uint32 // stream ID, automatically assigned if 0 streamID uint32 // stream ID, automatically assigned if 0
@@ -445,6 +463,122 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
return res, nil return res, nil
} }
func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
res := &serverResponse{}
var id spdy.StreamId
if rp.streamID != 0 {
id = spdy.StreamId(rp.streamID)
if id >= spdy.StreamId(st.nextStreamID) && id%2 == 1 {
st.nextStreamID = uint32(id) + 2
}
} else {
id = spdy.StreamId(st.nextStreamID)
st.nextStreamID += 2
}
method := "GET"
if rp.method != "" {
method = rp.method
}
scheme := "http"
if rp.scheme != "" {
scheme = rp.scheme
}
host := st.authority
if rp.authority != "" {
host = rp.authority
}
path := "/"
if rp.path != "" {
path = rp.path
}
header := make(http.Header)
header.Add(":method", method)
header.Add(":scheme", scheme)
header.Add(":host", host)
header.Add(":path", path)
header.Add(":version", "HTTP/1.1")
header.Add("test-case", rp.name)
for _, h := range rp.header {
header.Add(h.Name, h.Value)
}
var synStreamFlags spdy.ControlFlags
if len(rp.body) == 0 && !rp.noEndStream {
synStreamFlags = spdy.ControlFlagFin
}
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
CFHeader: spdy.ControlFrameHeader{
Flags: synStreamFlags,
},
StreamId: id,
Headers: header,
}); err != nil {
return nil, err
}
if len(rp.body) != 0 {
var dataFlags spdy.DataFlags
if !rp.noEndStream {
dataFlags = spdy.DataFlagFin
}
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
StreamId: id,
Flags: dataFlags,
Data: rp.body,
}); err != nil {
return nil, err
}
}
loop:
for {
fr, err := st.readSpdyFrame()
if err != nil {
return res, err
}
switch f := fr.(type) {
case *spdy.SynReplyFrame:
if f.StreamId != id {
break
}
res.header = cloneHeader(f.Headers)
if _, err := fmt.Sscan(res.header.Get(":status"), &res.status); err != nil {
return res, fmt.Errorf("Error parsing status code: %v", err)
}
if f.CFHeader.Flags&spdy.ControlFlagFin != 0 {
break loop
}
case *spdy.DataFrame:
if f.StreamId != id {
break
}
res.body = append(res.body, f.Data...)
if f.Flags&spdy.DataFlagFin != 0 {
break loop
}
case *spdy.RstStreamFrame:
if f.StreamId != id {
break
}
res.spdyRstErrCode = f.Status
break loop
case *spdy.GoAwayFrame:
if f.Status == spdy.GoAwayOK {
break
}
res.spdyGoAwayErrCode = f.Status
break loop
}
}
return res, nil
}
func (st *serverTester) http2(rp requestParam) (*serverResponse, error) { func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
st.headerBlkBuf.Reset() st.headerBlkBuf.Reset()
st.header = make(http.Header) st.header = make(http.Header)
@@ -633,7 +767,9 @@ type serverResponse struct {
streamID uint32 // stream ID in HTTP/2 streamID uint32 // stream ID in HTTP/2
errCode http2.ErrCode // error code received in HTTP/2 RST_STREAM or GOAWAY errCode http2.ErrCode // error code received in HTTP/2 RST_STREAM or GOAWAY
connErr bool // true if HTTP/2 connection error connErr bool // true if HTTP/2 connection error
connClose bool // Connection: close is included in response header in HTTP/1 test spdyGoAwayErrCode spdy.GoAwayStatus // status code received in SPDY RST_STREAM
spdyRstErrCode spdy.RstStreamStatus // status code received in SPDY GOAWAY
connClose bool // Conection: close is included in response header in HTTP/1 test
reqHeader http.Header // http request header, currently only sotres pushed request header reqHeader http.Header // http request header, currently only sotres pushed request header
pushResponse []*serverResponse // pushed response pushResponse []*serverResponse // pushed response
} }

View File

@@ -44,12 +44,8 @@ set_target_properties(nghttp2 PROPERTIES
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION} VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden C_VISIBILITY_PRESET hidden
) )
target_include_directories(nghttp2 INTERFACE
"${CMAKE_CURRENT_BINARY_DIR}/includes"
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
)
if(HAVE_CUNIT OR ENABLE_STATIC_LIB) if(HAVE_CUNIT)
# Static library (for unittests because of symbol visibility) # Static library (for unittests because of symbol visibility)
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES}) add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
set_target_properties(nghttp2_static PROPERTIES set_target_properties(nghttp2_static PROPERTIES
@@ -58,10 +54,6 @@ if(HAVE_CUNIT OR ENABLE_STATIC_LIB)
ARCHIVE_OUTPUT_NAME nghttp2 ARCHIVE_OUTPUT_NAME nghttp2
) )
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB") target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
if(ENABLE_STATIC_LIB)
install(TARGETS nghttp2_static
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
endif() endif()
install(TARGETS nghttp2 install(TARGETS nghttp2

View File

@@ -28,12 +28,7 @@
/* Define WIN32 when build target is Win32 API (borrowed from /* Define WIN32 when build target is Win32 API (borrowed from
libcurl) */ libcurl) */
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32 #define WIN32
#endif
/* Compatibility for non-Clang compilers */
#ifndef __has_declspec_attribute
# define __has_declspec_attribute(x) 0
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@@ -45,9 +40,9 @@ extern "C" {
/* MSVC < 2013 does not have inttypes.h because it is not C99 /* MSVC < 2013 does not have inttypes.h because it is not C99
compliant. See compiler macros and version number in compliant. See compiler macros and version number in
https://sourceforge.net/p/predef/wiki/Compilers/ */ https://sourceforge.net/p/predef/wiki/Compilers/ */
# include <stdint.h> #include <stdint.h>
#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ #else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
# include <inttypes.h> #include <inttypes.h>
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ #endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
#include <sys/types.h> #include <sys/types.h>
#include <stdarg.h> #include <stdarg.h>
@@ -55,21 +50,20 @@ extern "C" {
#include <nghttp2/nghttp2ver.h> #include <nghttp2/nghttp2ver.h>
#ifdef NGHTTP2_STATICLIB #ifdef NGHTTP2_STATICLIB
# define NGHTTP2_EXTERN #define NGHTTP2_EXTERN
#elif defined(WIN32) || (__has_declspec_attribute(dllexport) && \ #elif defined(WIN32)
__has_declspec_attribute(dllimport)) #ifdef BUILDING_NGHTTP2
# ifdef BUILDING_NGHTTP2 #define NGHTTP2_EXTERN __declspec(dllexport)
# define NGHTTP2_EXTERN __declspec(dllexport) #else /* !BUILDING_NGHTTP2 */
# else /* !BUILDING_NGHTTP2 */ #define NGHTTP2_EXTERN __declspec(dllimport)
# define NGHTTP2_EXTERN __declspec(dllimport) #endif /* !BUILDING_NGHTTP2 */
# endif /* !BUILDING_NGHTTP2 */ #else /* !defined(WIN32) */
#else /* !defined(WIN32) */ #ifdef BUILDING_NGHTTP2
# ifdef BUILDING_NGHTTP2 #define NGHTTP2_EXTERN __attribute__((visibility("default")))
# define NGHTTP2_EXTERN __attribute__((visibility("default"))) #else /* !BUILDING_NGHTTP2 */
# else /* !BUILDING_NGHTTP2 */ #define NGHTTP2_EXTERN
# define NGHTTP2_EXTERN #endif /* !BUILDING_NGHTTP2 */
# endif /* !BUILDING_NGHTTP2 */ #endif /* !defined(WIN32) */
#endif /* !defined(WIN32) */
/** /**
* @macro * @macro
@@ -393,11 +387,6 @@ typedef enum {
* Indicates that a processing was canceled. * Indicates that a processing was canceled.
*/ */
NGHTTP2_ERR_CANCEL = -535, NGHTTP2_ERR_CANCEL = -535,
/**
* When a local endpoint expects to receive SETTINGS frame, it
* receives an other type of frame.
*/
NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
/** /**
* The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
* under unexpected condition and processing was terminated (e.g., * under unexpected condition and processing was terminated (e.g.,
@@ -480,15 +469,6 @@ NGHTTP2_EXTERN void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf);
*/ */
NGHTTP2_EXTERN nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf); NGHTTP2_EXTERN nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf);
/**
* @function
*
* Returns nonzero if the underlying buffer is statically allocated,
* and 0 otherwise. This can be useful for language bindings that wish
* to avoid creating duplicate strings for these buffers.
*/
NGHTTP2_EXTERN int nghttp2_rcbuf_is_static(const nghttp2_rcbuf *rcbuf);
/** /**
* @enum * @enum
* *
@@ -617,12 +597,7 @@ typedef enum {
* The ALTSVC frame, which is defined in `RFC 7383 * The ALTSVC frame, which is defined in `RFC 7383
* <https://tools.ietf.org/html/rfc7838#section-4>`_. * <https://tools.ietf.org/html/rfc7838#section-4>`_.
*/ */
NGHTTP2_ALTSVC = 0x0a, NGHTTP2_ALTSVC = 0x0a
/**
* The ORIGIN frame, which is defined by `RFC 8336
* <https://tools.ietf.org/html/rfc8336>`_.
*/
NGHTTP2_ORIGIN = 0x0c
} nghttp2_frame_type; } nghttp2_frame_type;
/** /**
@@ -686,12 +661,7 @@ typedef enum {
/** /**
* SETTINGS_MAX_HEADER_LIST_SIZE * SETTINGS_MAX_HEADER_LIST_SIZE
*/ */
NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x06, NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE = 0x06
/**
* SETTINGS_ENABLE_CONNECT_PROTOCOL
* (`RFC 8441 <https://tools.ietf.org/html/rfc8441>`_)
*/
NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL = 0x08
} nghttp2_settings_id; } nghttp2_settings_id;
/* Note: If we add SETTINGS, update the capacity of /* Note: If we add SETTINGS, update the capacity of
NGHTTP2_INBOUND_NUM_IV as well */ NGHTTP2_INBOUND_NUM_IV as well */
@@ -1771,12 +1741,11 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
* The parameter and behaviour are similar to * The parameter and behaviour are similar to
* :type:`nghttp2_on_header_callback`. The difference is that this * :type:`nghttp2_on_header_callback`. The difference is that this
* callback is only invoked when a invalid header name/value pair is * callback is only invoked when a invalid header name/value pair is
* received which is treated as stream error if this callback is not * received which is silently ignored if this callback is not set.
* set. Only invalid regular header field are passed to this * Only invalid regular header field are passed to this callback. In
* callback. In other words, invalid pseudo header field is not * other words, invalid pseudo header field is not passed to this
* passed to this callback. Also header fields which includes upper * callback. Also header fields which includes upper cased latter are
* cased latter are also treated as error without passing them to this * also treated as error without passing them to this callback.
* callback.
* *
* This callback is only considered if HTTP messaging validation is * This callback is only considered if HTTP messaging validation is
* turned on (which is on by default, see * turned on (which is on by default, see
@@ -1785,13 +1754,10 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
* With this callback, application inspects the incoming invalid * With this callback, application inspects the incoming invalid
* field, and it also can reset stream from this callback by returning * field, and it also can reset stream from this callback by returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
* error code is :enum:`NGHTTP2_PROTOCOL_ERROR`. To change the error * error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
* code, call `nghttp2_submit_rst_stream()` with the error code of * code, call `nghttp2_submit_rst_stream()` with the error code of
* choice in addition to returning * choice in addition to returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
*
* If 0 is returned, the header field is ignored, and the stream is
* not reset.
*/ */
typedef int (*nghttp2_on_invalid_header_callback)( typedef int (*nghttp2_on_invalid_header_callback)(
nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name,
@@ -2008,9 +1974,6 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
* of length |len|. |len| does not include the sentinel NULL * of length |len|. |len| does not include the sentinel NULL
* character. * character.
* *
* This function is deprecated. The new application should use
* :type:`nghttp2_error_callback2`.
*
* The format of error message may change between nghttp2 library * The format of error message may change between nghttp2 library
* versions. The application should not depend on the particular * versions. The application should not depend on the particular
* format. * format.
@@ -2027,33 +1990,6 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
size_t len, void *user_data); size_t len, void *user_data);
/**
* @functypedef
*
* Callback function invoked when library provides the error code, and
* message. This callback is solely for debugging purpose.
* |lib_error_code| is one of error code defined in
* :enum:`nghttp2_error`. The |msg| is typically NULL-terminated
* string of length |len|, and intended for human consumption. |len|
* does not include the sentinel NULL character.
*
* The format of error message may change between nghttp2 library
* versions. The application should not depend on the particular
* format.
*
* Normally, application should return 0 from this callback. If fatal
* error occurred while doing something in this callback, application
* should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* library will return immediately with return value
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value
* is returned from this callback, they are treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
* rely on this details.
*/
typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
int lib_error_code, const char *msg,
size_t len, void *user_data);
struct nghttp2_session_callbacks; struct nghttp2_session_callbacks;
/** /**
@@ -2318,30 +2254,10 @@ nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
* *
* Sets callback function invoked when library tells error message to * Sets callback function invoked when library tells error message to
* the application. * the application.
*
* This function is deprecated. The new application should use
* `nghttp2_session_callbacks_set_error_callback2()`.
*
* If both :type:`nghttp2_error_callback` and
* :type:`nghttp2_error_callback2` are set, the latter takes
* precedence.
*/ */
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback( NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback); nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback);
/**
* @function
*
* Sets callback function invoked when library tells error code, and
* message to the application.
*
* If both :type:`nghttp2_error_callback` and
* :type:`nghttp2_error_callback2` are set, the latter takes
* precedence.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
/** /**
* @functypedef * @functypedef
* *
@@ -2489,15 +2405,15 @@ nghttp2_option_set_no_auto_window_update(nghttp2_option *option, int val);
* *
* This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of * This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
* remote endpoint as if it is received in SETTINGS frame. Without * remote endpoint as if it is received in SETTINGS frame. Without
* specifying this option, the maximum number of outgoing concurrent * specifying this option, before the local endpoint receives
* streams is initially limited to 100 to avoid issues when the local * SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote
* endpoint submits lots of requests before receiving initial SETTINGS * endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may
* frame from the remote endpoint, since sending them at once to the * cause problem if local endpoint submits lots of requests initially
* remote endpoint could lead to rejection of some of the requests. * and sending them at once to the remote peer may lead to the
* This value will be overwritten when the local endpoint receives * rejection of some requests. Specifying this option to the sensible
* initial SETTINGS frame from the remote endpoint, either to the * value, say 100, may avoid this kind of issue. This value will be
* value advertised in SETTINGS_MAX_CONCURRENT_STREAMS or to the * overwritten if the local endpoint receives
* default value (unlimited) if none was advertised. * SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
*/ */
NGHTTP2_EXTERN void NGHTTP2_EXTERN void
nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option, nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option,
@@ -2532,10 +2448,7 @@ nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val);
* <https://tools.ietf.org/html/rfc7540#section-8>`_. See * <https://tools.ietf.org/html/rfc7540#section-8>`_. See
* :ref:`http-messaging` section for details. For those applications * :ref:`http-messaging` section for details. For those applications
* who use nghttp2 library as non-HTTP use, give nonzero to |val| to * who use nghttp2 library as non-HTTP use, give nonzero to |val| to
* disable this enforcement. Please note that disabling this feature * disable this enforcement.
* does not change the fundamental client and server model of HTTP.
* That is, even if the validation is disabled, only client can send
* requests.
*/ */
NGHTTP2_EXTERN void nghttp2_option_set_no_http_messaging(nghttp2_option *option, NGHTTP2_EXTERN void nghttp2_option_set_no_http_messaging(nghttp2_option *option,
int val); int val);
@@ -3097,16 +3010,6 @@ NGHTTP2_EXTERN int
nghttp2_session_set_stream_user_data(nghttp2_session *session, nghttp2_session_set_stream_user_data(nghttp2_session *session,
int32_t stream_id, void *stream_user_data); int32_t stream_id, void *stream_user_data);
/**
* @function
*
* Sets |user_data| to |session|, overwriting the existing user data
* specified in `nghttp2_session_client_new()`, or
* `nghttp2_session_server_new()`.
*/
NGHTTP2_EXTERN void nghttp2_session_set_user_data(nghttp2_session *session,
void *user_data);
/** /**
* @function * @function
* *
@@ -3813,13 +3716,10 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* .. warning:: * .. warning::
* *
* This function returns assigned stream ID if it succeeds. But * This function returns assigned stream ID if it succeeds. But
* that stream is not created yet. The application must not submit * that stream is not opened yet. The application must not submit
* frame to that stream ID before * frame to that stream ID before
* :type:`nghttp2_before_frame_send_callback` is called for this * :type:`nghttp2_before_frame_send_callback` is called for this
* frame. This means `nghttp2_session_get_stream_user_data()` does * frame.
* not work before the callback. But
* `nghttp2_session_set_stream_user_data()` handles this situation
* specially, and it can set data to a stream during this period.
* *
*/ */
NGHTTP2_EXTERN int32_t nghttp2_submit_request( NGHTTP2_EXTERN int32_t nghttp2_submit_request(
@@ -3902,8 +3802,9 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
* Submits trailer fields HEADERS against the stream |stream_id|. * Submits trailer fields HEADERS against the stream |stream_id|.
* *
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application must not include pseudo-header * |nvlen| elements. The application is responsible not to include
* fields (headers whose names starts with ":") in |nva|. * pseudo-header fields (header field whose name starts with ":") in
* |nva|.
* *
* This function creates copies of all name/value pairs in |nva|. It * This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in * also lower-cases all names in |nva|. The order of elements in
@@ -4535,7 +4436,8 @@ typedef struct {
* Submits ALTSVC frame. * Submits ALTSVC frame.
* *
* ALTSVC frame is a non-critical extension to HTTP/2, and defined in * ALTSVC frame is a non-critical extension to HTTP/2, and defined in
* `RFC 7383 <https://tools.ietf.org/html/rfc7838#section-4>`_. * is defined in `RFC 7383
* <https://tools.ietf.org/html/rfc7838#section-4>`_.
* *
* The |flags| is currently ignored and should be * The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`. * :enum:`NGHTTP2_FLAG_NONE`.
@@ -4569,81 +4471,6 @@ NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session,
const uint8_t *field_value, const uint8_t *field_value,
size_t field_value_len); size_t field_value_len);
/**
* @struct
*
* The single entry of an origin.
*/
typedef struct {
/**
* The pointer to origin. No validation is made against this field
* by the library. This is not necessarily NULL-terminated.
*/
uint8_t *origin;
/**
* The length of the |origin|.
*/
size_t origin_len;
} nghttp2_origin_entry;
/**
* @struct
*
* The payload of ORIGIN frame. ORIGIN frame is a non-critical
* extension to HTTP/2 and defined by `RFC 8336
* <https://tools.ietf.org/html/rfc8336>`_.
*
* If this frame is received, and
* `nghttp2_option_set_user_recv_extension_type()` is not set, and
* `nghttp2_option_set_builtin_recv_extension_type()` is set for
* :enum:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to
* this struct.
*
* It has the following members:
*/
typedef struct {
/**
* The number of origins contained in |ov|.
*/
size_t nov;
/**
* The pointer to the array of origins contained in ORIGIN frame.
*/
nghttp2_origin_entry *ov;
} nghttp2_ext_origin;
/**
* @function
*
* Submits ORIGIN frame.
*
* ORIGIN frame is a non-critical extension to HTTP/2 and defined by
* `RFC 8336 <https://tools.ietf.org/html/rfc8336>`_.
*
* The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`.
*
* The |ov| points to the array of origins. The |nov| specifies the
* number of origins included in |ov|. This function creates copies
* of all elements in |ov|.
*
* The ORIGIN frame is only usable by a server. If this function is
* invoked with client side session, this function returns
* :enum:`NGHTTP2_ERR_INVALID_STATE`.
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory
* :enum:`NGHTTP2_ERR_INVALID_STATE`
* The function is called from client side session.
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* There are too many origins, or an origin is too large to fit
* into a default frame payload.
*/
NGHTTP2_EXTERN int nghttp2_submit_origin(nghttp2_session *session,
uint8_t flags,
const nghttp2_origin_entry *ov,
size_t nov);
/** /**
* @function * @function
* *
@@ -4860,8 +4687,8 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
* *
* After this function returns, it is safe to delete the |nva|. * After this function returns, it is safe to delete the |nva|.
* *
* This function returns the number of bytes written to |buf| if it * This function returns 0 if it succeeds, or one of the following
* succeeds, or one of the following negative error codes: * negative error codes:
* *
* :enum:`NGHTTP2_ERR_NOMEM` * :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory. * Out of memory.
@@ -4892,8 +4719,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
* *
* After this function returns, it is safe to delete the |nva|. * After this function returns, it is safe to delete the |nva|.
* *
* This function returns the number of bytes written to |vec| if it * This function returns 0 if it succeeds, or one of the following
* succeeds, or one of the following negative error codes: * negative error codes:
* *
* :enum:`NGHTTP2_ERR_NOMEM` * :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory. * Out of memory.

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_BUF_H #define NGHTTP2_BUF_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -398,7 +398,7 @@ int nghttp2_bufs_advance(nghttp2_bufs *bufs);
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs); void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs);
/* /*
* Returns nonzero if bufs->cur->next is not empty. * Returns nonzero if bufs->cur->next is not emtpy.
*/ */
int nghttp2_bufs_next_present(nghttp2_bufs *bufs); int nghttp2_bufs_next_present(nghttp2_bufs *bufs);

View File

@@ -168,8 +168,3 @@ void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) { nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
cbs->error_callback = error_callback; cbs->error_callback = error_callback;
} }
void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
cbs->error_callback2 = error_callback2;
}

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_CALLBACKS_H #define NGHTTP2_CALLBACKS_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -119,7 +119,6 @@ struct nghttp2_session_callbacks {
nghttp2_unpack_extension_callback unpack_extension_callback; nghttp2_unpack_extension_callback unpack_extension_callback;
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback; nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback; nghttp2_error_callback error_callback;
nghttp2_error_callback2 error_callback2;
}; };
#endif /* NGHTTP2_CALLBACKS_H */ #endif /* NGHTTP2_CALLBACKS_H */

View File

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

View File

@@ -215,44 +215,11 @@ void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_ext_altsvc *altsvc; nghttp2_ext_altsvc *altsvc;
altsvc = frame->payload; altsvc = frame->payload;
if (altsvc == NULL) {
return;
}
/* We use the same buffer for altsvc->origin and /* We use the same buffer for altsvc->origin and
altsvc->field_value. */ altsvc->field_value. */
nghttp2_mem_free(mem, altsvc->origin); nghttp2_mem_free(mem, altsvc->origin);
} }
void nghttp2_frame_origin_init(nghttp2_extension *frame,
nghttp2_origin_entry *ov, size_t nov) {
nghttp2_ext_origin *origin;
size_t payloadlen = 0;
size_t i;
for (i = 0; i < nov; ++i) {
payloadlen += 2 + ov[i].origin_len;
}
nghttp2_frame_hd_init(&frame->hd, payloadlen, NGHTTP2_ORIGIN,
NGHTTP2_FLAG_NONE, 0);
origin = frame->payload;
origin->ov = ov;
origin->nov = nov;
}
void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_ext_origin *origin;
origin = frame->payload;
if (origin == NULL) {
return;
}
/* We use the same buffer for all resources pointed by the field of
origin directly or indirectly. */
nghttp2_mem_free(mem, origin->ov);
}
size_t nghttp2_frame_priority_len(uint8_t flags) { size_t nghttp2_frame_priority_len(uint8_t flags) {
if (flags & NGHTTP2_FLAG_PRIORITY) { if (flags & NGHTTP2_FLAG_PRIORITY) {
return NGHTTP2_PRIORITY_SPECLEN; return NGHTTP2_PRIORITY_SPECLEN;
@@ -705,9 +672,6 @@ int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
nghttp2_buf *buf; nghttp2_buf *buf;
nghttp2_ext_altsvc *altsvc; nghttp2_ext_altsvc *altsvc;
/* This is required with --disable-assert. */
(void)rv;
altsvc = frame->payload; altsvc = frame->payload;
buf = &bufs->head->buf; buf = &bufs->head->buf;
@@ -776,106 +740,6 @@ int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
return 0; return 0;
} }
int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *frame) {
nghttp2_buf *buf;
nghttp2_ext_origin *origin;
nghttp2_origin_entry *orig;
size_t i;
origin = frame->payload;
buf = &bufs->head->buf;
if (nghttp2_buf_avail(buf) < frame->hd.length) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}
buf->pos -= NGHTTP2_FRAME_HDLEN;
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
for (i = 0; i < origin->nov; ++i) {
orig = &origin->ov[i];
nghttp2_put_uint16be(buf->last, (uint16_t)orig->origin_len);
buf->last += 2;
buf->last = nghttp2_cpymem(buf->last, orig->origin, orig->origin_len);
}
assert(nghttp2_buf_len(buf) == NGHTTP2_FRAME_HDLEN + frame->hd.length);
return 0;
}
int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem) {
nghttp2_ext_origin *origin;
const uint8_t *p, *end;
uint8_t *dst;
size_t originlen;
nghttp2_origin_entry *ov;
size_t nov = 0;
size_t len = 0;
origin = frame->payload;
p = payload;
end = p + payloadlen;
for (; p != end;) {
if (end - p < 2) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}
originlen = nghttp2_get_uint16(p);
p += 2;
if (originlen == 0) {
continue;
}
if (originlen > (size_t)(end - p)) {
return NGHTTP2_ERR_FRAME_SIZE_ERROR;
}
p += originlen;
/* 1 for terminal NULL */
len += originlen + 1;
++nov;
}
if (nov == 0) {
origin->ov = NULL;
origin->nov = 0;
return 0;
}
len += nov * sizeof(nghttp2_origin_entry);
ov = nghttp2_mem_malloc(mem, len);
if (ov == NULL) {
return NGHTTP2_ERR_NOMEM;
}
origin->ov = ov;
origin->nov = nov;
dst = (uint8_t *)ov + nov * sizeof(nghttp2_origin_entry);
p = payload;
for (; p != end;) {
originlen = nghttp2_get_uint16(p);
p += 2;
if (originlen == 0) {
continue;
}
ov->origin = dst;
ov->origin_len = originlen;
dst = nghttp2_cpymem(dst, p, originlen);
*dst++ = '\0';
p += originlen;
++ov;
}
return 0;
}
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv, nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem) { size_t niv, nghttp2_mem *mem) {
nghttp2_settings_entry *iv_copy; nghttp2_settings_entry *iv_copy;
@@ -1050,11 +914,6 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv) {
break; break;
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
break; break;
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
if (iv[i].value != 0 && iv[i].value != 1) {
return 0;
}
break;
} }
} }
return 1; return 1;

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_FRAME_H #define NGHTTP2_FRAME_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -70,10 +70,7 @@
#define NGHTTP2_MAX_PADLEN 256 #define NGHTTP2_MAX_PADLEN 256
/* Union of extension frame payload */ /* Union of extension frame payload */
typedef union { typedef union { nghttp2_ext_altsvc altsvc; } nghttp2_ext_frame_payload;
nghttp2_ext_altsvc altsvc;
nghttp2_ext_origin origin;
} nghttp2_ext_frame_payload;
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd); void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
@@ -393,36 +390,6 @@ int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
const uint8_t *payload, const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem); size_t payloadlen, nghttp2_mem *mem);
/*
* Packs ORIGIN frame |frame| in wire frame format and store it in
* |bufs|.
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_FRAME_SIZE_ERROR
* The length of the frame is too large.
*/
int nghttp2_frame_pack_origin(nghttp2_bufs *bufs, nghttp2_extension *ext);
/*
* Unpacks ORIGIN wire format into |frame|. The |payload| of length
* |payloadlen| contains the frame payload.
*
* 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 payload is too small.
*/
int nghttp2_frame_unpack_origin_payload(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem);
/* /*
* Initializes HEADERS frame |frame| with given values. |frame| takes * Initializes HEADERS frame |frame| with given values. |frame| takes
* ownership of |nva|, so caller must not free it. If |stream_id| is * ownership of |nva|, so caller must not free it. If |stream_id| is
@@ -520,24 +487,6 @@ void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
*/ */
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem); void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
/*
* Initializes ORIGIN frame |frame| with given values. This function
* assumes that frame->payload points to nghttp2_ext_origin object.
* Also |ov| and the memory pointed by the field of its elements are
* allocated in single buffer, starting with |ov|. On success, this
* function takes ownership of |ov|, so caller must not free it.
*/
void nghttp2_frame_origin_init(nghttp2_extension *frame,
nghttp2_origin_entry *ov, size_t nov);
/*
* Frees up resources under |frame|. This function does not free
* nghttp2_ext_origin object pointed by frame->payload. This function
* only frees nghttp2_ext_origin.ov. Therefore, other fields must be
* allocated in the same buffer with ov.
*/
void nghttp2_frame_origin_free(nghttp2_extension *frame, nghttp2_mem *mem);
/* /*
* Returns the number of padding bytes after payload. The total * Returns the number of padding bytes after payload. The total
* padding length is given in the |padlen|. The returned value does * padding length is given in the |padlen|. The returned value does

View File

@@ -45,7 +45,7 @@
/* 3rd parameter is nghttp2_token value for header field name. We use /* 3rd parameter is nghttp2_token value for header field name. We use
first enum value if same header names are repeated (e.g., first enum value if same header names are repeated (e.g.,
:status). */ :status). */
static const nghttp2_hd_static_entry static_table[] = { static nghttp2_hd_static_entry static_table[] = {
MAKE_STATIC_ENT(":authority", "", 0, 3153725150u), MAKE_STATIC_ENT(":authority", "", 0, 3153725150u),
MAKE_STATIC_ENT(":method", "GET", 1, 695666056u), MAKE_STATIC_ENT(":method", "GET", 1, 695666056u),
MAKE_STATIC_ENT(":method", "POST", 1, 695666056u), MAKE_STATIC_ENT(":method", "POST", 1, 695666056u),
@@ -271,15 +271,6 @@ static int32_t lookup_token(const uint8_t *name, size_t namelen) {
break; break;
} }
break; break;
case 9:
switch (name[8]) {
case 'l':
if (memeq(":protoco", name, 8)) {
return NGHTTP2_TOKEN__PROTOCOL;
}
break;
}
break;
case 10: case 10:
switch (name[9]) { switch (name[9]) {
case 'e': case 'e':
@@ -671,9 +662,9 @@ static int hd_context_init(nghttp2_hd_context *context, nghttp2_mem *mem) {
context->mem = mem; context->mem = mem;
context->bad = 0; context->bad = 0;
context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE; context->hd_table_bufsize_max = NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE;
rv = hd_ringbuf_init( rv = hd_ringbuf_init(&context->hd_table, context->hd_table_bufsize_max /
&context->hd_table, NGHTTP2_HD_ENTRY_OVERHEAD,
context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem); mem);
if (rv != 0) { if (rv != 0) {
return rv; return rv;
} }
@@ -1168,7 +1159,7 @@ static search_result search_static_table(const nghttp2_nv *nv, int32_t token,
int name_only) { int name_only) {
search_result res = {token, 0}; search_result res = {token, 0};
int i; int i;
const nghttp2_hd_static_entry *ent; nghttp2_hd_static_entry *ent;
if (name_only) { if (name_only) {
return res; return res;
@@ -1193,7 +1184,7 @@ static search_result search_hd_table(nghttp2_hd_context *context,
int indexing_mode, nghttp2_hd_map *map, int indexing_mode, nghttp2_hd_map *map,
uint32_t hash) { uint32_t hash) {
search_result res = {-1, 0}; search_result res = {-1, 0};
const nghttp2_hd_entry *ent; nghttp2_hd_entry *ent;
int exact_match; int exact_match;
int name_only = indexing_mode == NGHTTP2_HD_NEVER_INDEXING; int name_only = indexing_mode == NGHTTP2_HD_NEVER_INDEXING;
@@ -1298,9 +1289,8 @@ nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t idx) {
return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH) return hd_ringbuf_get(&context->hd_table, idx - NGHTTP2_STATIC_TABLE_LENGTH)
->nv; ->nv;
} else { } else {
const nghttp2_hd_static_entry *ent = &static_table[idx]; nghttp2_hd_static_entry *ent = &static_table[idx];
nghttp2_hd_nv nv = {(nghttp2_rcbuf *)&ent->name, nghttp2_hd_nv nv = {&ent->name, &ent->value, ent->token,
(nghttp2_rcbuf *)&ent->value, ent->token,
NGHTTP2_NV_FLAG_NONE}; NGHTTP2_NV_FLAG_NONE};
return nv; return nv;
} }

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_HD_H #define NGHTTP2_HD_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -111,7 +111,6 @@ typedef enum {
NGHTTP2_TOKEN_KEEP_ALIVE, NGHTTP2_TOKEN_KEEP_ALIVE,
NGHTTP2_TOKEN_PROXY_CONNECTION, NGHTTP2_TOKEN_PROXY_CONNECTION,
NGHTTP2_TOKEN_UPGRADE, NGHTTP2_TOKEN_UPGRADE,
NGHTTP2_TOKEN__PROTOCOL,
} nghttp2_token; } nghttp2_token;
struct nghttp2_hd_entry; struct nghttp2_hd_entry;
@@ -212,9 +211,7 @@ typedef struct {
#define HD_MAP_SIZE 128 #define HD_MAP_SIZE 128
typedef struct { typedef struct { nghttp2_hd_entry *table[HD_MAP_SIZE]; } nghttp2_hd_map;
nghttp2_hd_entry *table[HD_MAP_SIZE];
} nghttp2_hd_map;
struct nghttp2_hd_deflater { struct nghttp2_hd_deflater {
nghttp2_hd_context ctx; nghttp2_hd_context ctx;
@@ -316,7 +313,7 @@ void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
* *
* This function expands |bufs| as necessary to store the result. If * This function expands |bufs| as necessary to store the result. If
* buffers is full and the process still requires more space, this * buffers is full and the process still requires more space, this
* function fails and returns NGHTTP2_ERR_HEADER_COMP. * funtion fails and returns NGHTTP2_ERR_HEADER_COMP.
* *
* After this function returns, it is safe to delete the |nva|. * After this function returns, it is safe to delete the |nva|.
* *

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_HD_HUFFMAN_H #define NGHTTP2_HD_HUFFMAN_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -322,9 +322,6 @@ const char *nghttp2_strerror(int error_code) {
return "Internal error"; return "Internal error";
case NGHTTP2_ERR_CANCEL: case NGHTTP2_ERR_CANCEL:
return "Cancel"; return "Cancel";
case NGHTTP2_ERR_SETTINGS_EXPECTED:
return "When a local endpoint expects to receive SETTINGS frame, it "
"receives an other type of frame";
case NGHTTP2_ERR_NOMEM: case NGHTTP2_ERR_NOMEM:
return "Out of memory"; return "Out of memory";
case NGHTTP2_ERR_CALLBACK_FAILURE: case NGHTTP2_ERR_CALLBACK_FAILURE:
@@ -340,7 +337,7 @@ const char *nghttp2_strerror(int error_code) {
} }
/* Generated by gennmchartbl.py */ /* Generated by gennmchartbl.py */
static const int VALID_HD_NAME_CHARS[] = { static int VALID_HD_NAME_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
@@ -428,7 +425,7 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) {
} }
/* Generated by genvchartbl.py */ /* Generated by genvchartbl.py */
static const int VALID_HD_VALUE_CHARS[] = { static int VALID_HD_VALUE_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */, 0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_HELPER_H #define NGHTTP2_HELPER_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <string.h> #include <string.h>

View File

@@ -113,7 +113,7 @@ static int check_path(nghttp2_stream *stream) {
} }
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv, static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
int trailer, int connect_protocol) { int trailer) {
if (nv->name->base[0] == ':') { if (nv->name->base[0] == ':') {
if (trailer || if (trailer ||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) { (stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
@@ -146,6 +146,10 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
} }
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_CONNECT; stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_CONNECT;
if (stream->http_flags &
(NGHTTP2_HTTP_FLAG__PATH | NGHTTP2_HTTP_FLAG__SCHEME)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
} }
break; break;
case 'S': case 'S':
@@ -158,6 +162,9 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
} }
break; break;
case NGHTTP2_TOKEN__PATH: case NGHTTP2_TOKEN__PATH:
if (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) { if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) {
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
} }
@@ -168,6 +175,9 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
} }
break; break;
case NGHTTP2_TOKEN__SCHEME: case NGHTTP2_TOKEN__SCHEME:
if (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) { if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) {
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
} }
@@ -176,15 +186,6 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP; stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
} }
break; break;
case NGHTTP2_TOKEN__PROTOCOL:
if (!connect_protocol) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PROTOCOL)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
case NGHTTP2_TOKEN_HOST: case NGHTTP2_TOKEN_HOST:
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG_HOST)) { if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG_HOST)) {
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
@@ -243,7 +244,7 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
} }
stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len); stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len);
if (stream->status_code == -1 || stream->status_code == 101) { if (stream->status_code == -1) {
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
} }
break; break;
@@ -264,7 +265,7 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
return NGHTTP2_ERR_REMOVE_HTTP_HEADER; return NGHTTP2_ERR_REMOVE_HTTP_HEADER;
} }
if (stream->status_code / 100 == 1 || if (stream->status_code / 100 == 1 ||
(stream->status_code / 100 == 2 && (stream->status_code == 200 &&
(stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT))) { (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT))) {
return NGHTTP2_ERR_HTTP_HEADER; return NGHTTP2_ERR_HTTP_HEADER;
} }
@@ -457,9 +458,7 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
} }
if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) { if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
return http_request_on_header(stream, nv, trailer, return http_request_on_header(stream, nv, trailer);
session->server &&
session->pending_enable_connect_protocol);
} }
return http_response_on_header(stream, nv, trailer); return http_response_on_header(stream, nv, trailer);
@@ -467,11 +466,8 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
int nghttp2_http_on_request_headers(nghttp2_stream *stream, int nghttp2_http_on_request_headers(nghttp2_stream *stream,
nghttp2_frame *frame) { nghttp2_frame *frame) {
if (!(stream->http_flags & NGHTTP2_HTTP_FLAG__PROTOCOL) && if (stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT) {
(stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT)) { if ((stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0) {
if ((stream->http_flags &
(NGHTTP2_HTTP_FLAG__SCHEME | NGHTTP2_HTTP_FLAG__PATH)) ||
(stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0) {
return -1; return -1;
} }
stream->content_length = -1; stream->content_length = -1;
@@ -482,11 +478,6 @@ int nghttp2_http_on_request_headers(nghttp2_stream *stream,
(NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) { (NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) {
return -1; return -1;
} }
if ((stream->http_flags & NGHTTP2_HTTP_FLAG__PROTOCOL) &&
((stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT) == 0 ||
(stream->http_flags & NGHTTP2_HTTP_FLAG__AUTHORITY) == 0)) {
return -1;
}
if (!check_path(stream)) { if (!check_path(stream)) {
return -1; return -1;
} }

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_HTTP_H #define NGHTTP2_HTTP_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_INT_H #define NGHTTP2_INT_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_MAP_H #define NGHTTP2_MAP_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_MEM_H #define NGHTTP2_MEM_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -26,15 +26,15 @@
#define NGHTTP2_NET_H #define NGHTTP2_NET_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#ifdef HAVE_ARPA_INET_H #ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h> #include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */ #endif /* HAVE_ARPA_INET_H */
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> #include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */ #endif /* HAVE_NETINET_IN_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -44,11 +44,11 @@
define inline functions for those function so that we don't have define inline functions for those function so that we don't have
dependeny on that lib. */ dependeny on that lib. */
# ifdef _MSC_VER #ifdef _MSC_VER
# define STIN static __inline #define STIN static __inline
# else #else
# define STIN static inline #define STIN static inline
# endif #endif
STIN uint32_t htonl(uint32_t hostlong) { STIN uint32_t htonl(uint32_t hostlong) {
uint32_t res; uint32_t res;

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_NPN_H #define NGHTTP2_NPN_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -86,10 +86,6 @@ void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES; option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC; option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC;
return; return;
case NGHTTP2_ORIGIN:
option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ORIGIN;
return;
default: default:
return; return;
} }

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_OPTION_H #define NGHTTP2_OPTION_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -86,9 +86,6 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
case NGHTTP2_ALTSVC: case NGHTTP2_ALTSVC:
nghttp2_frame_altsvc_free(&frame->ext, mem); nghttp2_frame_altsvc_free(&frame->ext, mem);
break; break;
case NGHTTP2_ORIGIN:
nghttp2_frame_origin_free(&frame->ext, mem);
break;
default: default:
assert(0); assert(0);
break; break;

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_OUTBOUND_ITEM_H #define NGHTTP2_OUTBOUND_ITEM_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -112,7 +112,7 @@ struct nghttp2_outbound_item {
nghttp2_ext_frame_payload ext_frame_payload; nghttp2_ext_frame_payload ext_frame_payload;
nghttp2_aux_data aux_data; nghttp2_aux_data aux_data;
/* The priority used in priority comparion. Smaller is served /* The priority used in priority comparion. Smaller is served
earlier. For PING, SETTINGS and non-DATA frames (excluding ealier. For PING, SETTINGS and non-DATA frames (excluding
response HEADERS frame) have dedicated cycle value defined above. response HEADERS frame) have dedicated cycle value defined above.
For DATA frame, cycle is computed by taking into account of For DATA frame, cycle is computed by taking into account of
effective weight and frame payload length previously sent, so effective weight and frame payload length previously sent, so

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_PQ_H #define NGHTTP2_PQ_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -35,16 +35,14 @@
/* Implementation of priority queue */ /* Implementation of priority queue */
typedef struct { typedef struct { size_t index; } nghttp2_pq_entry;
size_t index;
} nghttp2_pq_entry;
typedef struct { typedef struct {
/* The pointer to the pointer to the item stored */ /* The pointer to the pointer to the item stored */
nghttp2_pq_entry **q; nghttp2_pq_entry **q;
/* Memory allocator */ /* Memory allocator */
nghttp2_mem *mem; nghttp2_mem *mem;
/* The number of items stored */ /* The number of items sotred */
size_t length; size_t length;
/* The maximum number of items this pq can store. This is /* The maximum number of items this pq can store. This is
automatically extended when length is reached to this value. */ automatically extended when length is reached to this value. */
@@ -73,7 +71,7 @@ void nghttp2_pq_free(nghttp2_pq *pq);
/* /*
* Adds |item| to the priority queue |pq|. * Adds |item| to the priority queue |pq|.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeds, or one of the following
* negative error codes: * negative error codes:
* *
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_PRIORITY_SPEC_H #define NGHTTP2_PRIORITY_SPEC_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_QUEUE_H #define NGHTTP2_QUEUE_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include "config.h" #include "config.h"
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -36,9 +36,7 @@ typedef struct nghttp2_queue_cell {
struct nghttp2_queue_cell *next; struct nghttp2_queue_cell *next;
} nghttp2_queue_cell; } nghttp2_queue_cell;
typedef struct { typedef struct { nghttp2_queue_cell *front, *back; } nghttp2_queue;
nghttp2_queue_cell *front, *back;
} nghttp2_queue;
void nghttp2_queue_init(nghttp2_queue *queue); void nghttp2_queue_init(nghttp2_queue *queue);
void nghttp2_queue_free(nghttp2_queue *queue); void nghttp2_queue_free(nghttp2_queue *queue);

View File

@@ -96,7 +96,3 @@ nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf) {
nghttp2_vec res = {rcbuf->base, rcbuf->len}; nghttp2_vec res = {rcbuf->base, rcbuf->len};
return res; return res;
} }
int nghttp2_rcbuf_is_static(const nghttp2_rcbuf *rcbuf) {
return rcbuf->ref == -1;
}

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_RCBUF_H #define NGHTTP2_RCBUF_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_SESSION_H #define NGHTTP2_SESSION_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -61,8 +61,7 @@ typedef enum {
*/ */
typedef enum { typedef enum {
NGHTTP2_TYPEMASK_NONE = 0, NGHTTP2_TYPEMASK_NONE = 0,
NGHTTP2_TYPEMASK_ALTSVC = 1 << 0, NGHTTP2_TYPEMASK_ALTSVC = 1 << 0
NGHTTP2_TYPEMASK_ORIGIN = 1 << 1
} nghttp2_typemask; } nghttp2_typemask;
typedef enum { typedef enum {
@@ -122,7 +121,6 @@ typedef enum {
NGHTTP2_IB_IGN_DATA, NGHTTP2_IB_IGN_DATA,
NGHTTP2_IB_IGN_ALL, NGHTTP2_IB_IGN_ALL,
NGHTTP2_IB_READ_ALTSVC_PAYLOAD, NGHTTP2_IB_READ_ALTSVC_PAYLOAD,
NGHTTP2_IB_READ_ORIGIN_PAYLOAD,
NGHTTP2_IB_READ_EXTENSION_PAYLOAD NGHTTP2_IB_READ_EXTENSION_PAYLOAD
} nghttp2_inbound_state; } nghttp2_inbound_state;
@@ -164,7 +162,6 @@ typedef struct {
uint32_t initial_window_size; uint32_t initial_window_size;
uint32_t max_frame_size; uint32_t max_frame_size;
uint32_t max_header_list_size; uint32_t max_header_list_size;
uint32_t enable_connect_protocol;
} nghttp2_settings_storage; } nghttp2_settings_storage;
typedef enum { typedef enum {
@@ -304,10 +301,8 @@ struct nghttp2_session {
increased/decreased by submitting WINDOW_UPDATE. See increased/decreased by submitting WINDOW_UPDATE. See
nghttp2_submit_window_update(). */ nghttp2_submit_window_update(). */
int32_t local_window_size; int32_t local_window_size;
/* This flag is used to indicate that the local endpoint received initial /* Settings value received from the remote endpoint. We just use ID
SETTINGS frame from the remote endpoint. */ as index. The index = 0 is unused. */
uint8_t remote_settings_received;
/* Settings value received from the remote endpoint. */
nghttp2_settings_storage remote_settings; nghttp2_settings_storage remote_settings;
/* Settings value of the local endpoint. */ /* Settings value of the local endpoint. */
nghttp2_settings_storage local_settings; nghttp2_settings_storage local_settings;
@@ -316,18 +311,15 @@ struct nghttp2_session {
/* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this /* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this
to refuse the incoming stream if it exceeds this value. */ to refuse the incoming stream if it exceeds this value. */
uint32_t pending_local_max_concurrent_stream; uint32_t pending_local_max_concurrent_stream;
/* The bitwise OR of zero or more of nghttp2_typemask to indicate /* The bitwose OR of zero or more of nghttp2_typemask to indicate
that the default handling of extension frame is enabled. */ that the default handling of extension frame is enabled. */
uint32_t builtin_recv_ext_types; uint32_t builtin_recv_ext_types;
/* Unacked local ENABLE_PUSH value. We use this to refuse /* Unacked local ENABLE_PUSH value. We use this to refuse
PUSH_PROMISE before SETTINGS ACK is received. */ PUSH_PROMISE before SETTINGS ACK is received. */
uint8_t pending_enable_push; uint8_t pending_enable_push;
/* Unacked local ENABLE_CONNECT_PROTOCOL value. We use this to
accept :protocol header field before SETTINGS_ACK is received. */
uint8_t pending_enable_connect_protocol;
/* Nonzero if the session is server side. */ /* Nonzero if the session is server side. */
uint8_t server; uint8_t server;
/* Flags indicating GOAWAY is sent and/or received. The flags are /* Flags indicating GOAWAY is sent and/or recieved. The flags are
composed by bitwise OR-ing nghttp2_goaway_flag. */ composed by bitwise OR-ing nghttp2_goaway_flag. */
uint8_t goaway_flags; uint8_t goaway_flags;
/* This flag is used to reduce excessive queuing of WINDOW_UPDATE to /* This flag is used to reduce excessive queuing of WINDOW_UPDATE to
@@ -706,7 +698,7 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_CALLBACK_FAILURE * NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed. * The callback function failed.
* NGHTTP2_ERR_FLOODED * NGHTTP2_ERR_FLOODED
* There are too many items in outbound queue, and this is most * There are too many items in outbound queue, and this is most
* likely caused by misbehaviour of peer. * likely caused by misbehaviour of peer.
@@ -724,13 +716,13 @@ int nghttp2_session_on_ping_received(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_CALLBACK_FAILURE * NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed. * The callback function failed.
*/ */
int nghttp2_session_on_goaway_received(nghttp2_session *session, int nghttp2_session_on_goaway_received(nghttp2_session *session,
nghttp2_frame *frame); nghttp2_frame *frame);
/* /*
* Called when WINDOW_UPDATE is received, assuming |frame| is properly * Called when WINDOW_UPDATE is recieved, assuming |frame| is properly
* initialized. * initialized.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
@@ -739,37 +731,24 @@ int nghttp2_session_on_goaway_received(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_CALLBACK_FAILURE * NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed. * The callback function failed.
*/ */
int nghttp2_session_on_window_update_received(nghttp2_session *session, int nghttp2_session_on_window_update_received(nghttp2_session *session,
nghttp2_frame *frame); nghttp2_frame *frame);
/* /*
* Called when ALTSVC is received, assuming |frame| is properly * Called when ALTSVC is recieved, assuming |frame| is properly
* initialized. * initialized.
* *
* This function returns 0 if it succeeds, or one of the following * This function returns 0 if it succeeds, or one of the following
* negative error codes: * negative error codes:
* *
* NGHTTP2_ERR_CALLBACK_FAILURE * NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed. * The callback function failed.
*/ */
int nghttp2_session_on_altsvc_received(nghttp2_session *session, int nghttp2_session_on_altsvc_received(nghttp2_session *session,
nghttp2_frame *frame); nghttp2_frame *frame);
/*
* Called when ORIGIN is received, assuming |frame| is properly
* initialized.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed.
*/
int nghttp2_session_on_origin_received(nghttp2_session *session,
nghttp2_frame *frame);
/* /*
* Called when DATA is received, assuming |frame| is properly * Called when DATA is received, assuming |frame| is properly
* initialized. * initialized.
@@ -780,7 +759,7 @@ int nghttp2_session_on_origin_received(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM * NGHTTP2_ERR_NOMEM
* Out of memory. * Out of memory.
* NGHTTP2_ERR_CALLBACK_FAILURE * NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed. * The callback function failed.
*/ */
int nghttp2_session_on_data_received(nghttp2_session *session, int nghttp2_session_on_data_received(nghttp2_session *session,
nghttp2_frame *frame); nghttp2_frame *frame);

View File

@@ -366,9 +366,8 @@ static void check_queued(nghttp2_stream *stream) {
} }
} }
if (queued == 0) { if (queued == 0) {
fprintf(stderr, fprintf(stderr, "stream(%p)=%d, stream->queued == 1, and "
"stream(%p)=%d, stream->queued == 1, and " "!stream_active(), but no descendants is queued\n",
"!stream_active(), but no descendants is queued\n",
stream, stream->stream_id); stream, stream->stream_id);
assert(0); assert(0);
} }
@@ -379,10 +378,9 @@ static void check_queued(nghttp2_stream *stream) {
} }
} else { } else {
if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) { if (stream_active(stream) || !nghttp2_pq_empty(&stream->obq)) {
fprintf(stderr, fprintf(stderr, "stream(%p) = %d, stream->queued == 0, but "
"stream(%p) = %d, stream->queued == 0, but " "stream_active(stream) == %d and "
"stream_active(stream) == %d and " "nghttp2_pq_size(&stream->obq) = %zu\n",
"nghttp2_pq_size(&stream->obq) = %zu\n",
stream, stream->stream_id, stream_active(stream), stream, stream->stream_id, stream_active(stream),
nghttp2_pq_size(&stream->obq)); nghttp2_pq_size(&stream->obq));
assert(0); assert(0);

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_STREAM_H #define NGHTTP2_STREAM_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
@@ -130,8 +130,7 @@ typedef enum {
/* "http" or "https" scheme */ /* "http" or "https" scheme */
NGHTTP2_HTTP_FLAG_SCHEME_HTTP = 1 << 13, NGHTTP2_HTTP_FLAG_SCHEME_HTTP = 1 << 13,
/* set if final response is expected */ /* set if final response is expected */
NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE = 1 << 14, NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE = 1 << 14
NGHTTP2_HTTP_FLAG__PROTOCOL = 1 << 15,
} nghttp2_http_flag; } nghttp2_http_flag;
struct nghttp2_stream { struct nghttp2_stream {

View File

@@ -571,89 +571,6 @@ fail_item_malloc:
return rv; return rv;
} }
int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags,
const nghttp2_origin_entry *ov, size_t nov) {
nghttp2_mem *mem;
uint8_t *p;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
nghttp2_ext_origin *origin;
nghttp2_origin_entry *ov_copy;
size_t len = 0;
size_t i;
int rv;
(void)flags;
mem = &session->mem;
if (!session->server) {
return NGHTTP2_ERR_INVALID_STATE;
}
if (nov) {
for (i = 0; i < nov; ++i) {
len += ov[i].origin_len;
}
if (2 * nov + len > NGHTTP2_MAX_PAYLOADLEN) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
/* The last nov is added for terminal NULL character. */
ov_copy =
nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov);
if (ov_copy == NULL) {
return NGHTTP2_ERR_NOMEM;
}
p = (uint8_t *)ov_copy + nov * sizeof(nghttp2_origin_entry);
for (i = 0; i < nov; ++i) {
ov_copy[i].origin = p;
ov_copy[i].origin_len = ov[i].origin_len;
p = nghttp2_cpymem(p, ov[i].origin, ov[i].origin_len);
*p++ = '\0';
}
assert((size_t)(p - (uint8_t *)ov_copy) ==
nov * sizeof(nghttp2_origin_entry) + len + nov);
} else {
ov_copy = NULL;
}
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) {
rv = NGHTTP2_ERR_NOMEM;
goto fail_item_malloc;
}
nghttp2_outbound_item_init(item);
item->aux_data.ext.builtin = 1;
origin = &item->ext_frame_payload.origin;
frame = &item->frame;
frame->ext.payload = origin;
nghttp2_frame_origin_init(&frame->ext, ov_copy, nov);
rv = nghttp2_session_add_item(session, item);
if (rv != 0) {
nghttp2_frame_origin_free(&frame->ext, mem);
nghttp2_mem_free(mem, item);
return rv;
}
return 0;
fail_item_malloc:
free(ov_copy);
return rv;
}
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec, static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
const nghttp2_data_provider *data_prd) { const nghttp2_data_provider *data_prd) {
uint8_t flags = NGHTTP2_FLAG_NONE; uint8_t flags = NGHTTP2_FLAG_NONE;

View File

@@ -26,7 +26,7 @@
#define NGHTTP2_SUBMIT_H #define NGHTTP2_SUBMIT_H
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -23,7 +23,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> #include <config.h>
#endif /* HAVE_CONFIG_H */ #endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>

View File

@@ -1,948 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
# or '14' (for the C++14 standard).
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The third argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline support for the specified C++ standard is
# required and that the macro should error out if no mode with that
# support is found. If specified 'optional', then configuration proceeds
# regardless, after defining HAVE_CXX${VERSION} if and only if a
# supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 10
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
[$2], [noext], [],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
AC_LANG_PUSH([C++])dnl
ac_success=no
m4_if([$2], [noext], [], [dnl
if test x$ac_success = xno; then
for alternative in ${ax_cxx_compile_alternatives}; do
switch="-std=gnu++${alternative}"
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
fi])
m4_if([$2], [ext], [], [dnl
if test x$ac_success = xno; then
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
if test x$ac_success = xyes; then
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
fi
fi
if test x$ac_success = xno; then
HAVE_CXX$1=0
AC_MSG_NOTICE([No compiler with C++$1 support was found])
else
HAVE_CXX$1=1
AC_DEFINE(HAVE_CXX$1,1,
[define if the compiler supports basic C++$1 syntax])
fi
AC_SUBST(HAVE_CXX$1)
])
dnl Test body for checking C++11 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
namespace cxx11
{
namespace test_static_assert
{
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
}
namespace test_final_override
{
struct Base
{
virtual void f() {}
};
struct Derived : public Base
{
virtual void f() override {}
};
}
namespace test_double_right_angle_brackets
{
template < typename T >
struct check {};
typedef check<void> single_type;
typedef check<check<void>> double_type;
typedef check<check<check<void>>> triple_type;
typedef check<check<check<check<void>>>> quadruple_type;
}
namespace test_decltype
{
int
f()
{
int a = 1;
decltype(a) b = 2;
return a + b;
}
}
namespace test_type_deduction
{
template < typename T1, typename T2 >
struct is_same
{
static const bool value = false;
};
template < typename T >
struct is_same<T, T>
{
static const bool value = true;
};
template < typename T1, typename T2 >
auto
add(T1 a1, T2 a2) -> decltype(a1 + a2)
{
return a1 + a2;
}
int
test(const int c, volatile int v)
{
static_assert(is_same<int, decltype(0)>::value == true, "");
static_assert(is_same<int, decltype(c)>::value == false, "");
static_assert(is_same<int, decltype(v)>::value == false, "");
auto ac = c;
auto av = v;
auto sumi = ac + av + 'x';
auto sumf = ac + av + 1.0;
static_assert(is_same<int, decltype(ac)>::value == true, "");
static_assert(is_same<int, decltype(av)>::value == true, "");
static_assert(is_same<int, decltype(sumi)>::value == true, "");
static_assert(is_same<int, decltype(sumf)>::value == false, "");
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
return (sumf > 0.0) ? sumi : add(c, v);
}
}
namespace test_noexcept
{
int f() { return 0; }
int g() noexcept { return 0; }
static_assert(noexcept(f()) == false, "");
static_assert(noexcept(g()) == true, "");
}
namespace test_constexpr
{
template < typename CharT >
unsigned long constexpr
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
{
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
}
template < typename CharT >
unsigned long constexpr
strlen_c(const CharT *const s) noexcept
{
return strlen_c_r(s, 0UL);
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("1") == 1UL, "");
static_assert(strlen_c("example") == 7UL, "");
static_assert(strlen_c("another\0example") == 7UL, "");
}
namespace test_rvalue_references
{
template < int N >
struct answer
{
static constexpr int value = N;
};
answer<1> f(int&) { return answer<1>(); }
answer<2> f(const int&) { return answer<2>(); }
answer<3> f(int&&) { return answer<3>(); }
void
test()
{
int i = 0;
const int c = 0;
static_assert(decltype(f(i))::value == 1, "");
static_assert(decltype(f(c))::value == 2, "");
static_assert(decltype(f(0))::value == 3, "");
}
}
namespace test_uniform_initialization
{
struct test
{
static const int zero {};
static const int one {1};
};
static_assert(test::zero == 0, "");
static_assert(test::one == 1, "");
}
namespace test_lambdas
{
void
test1()
{
auto lambda1 = [](){};
auto lambda2 = lambda1;
lambda1();
lambda2();
}
int
test2()
{
auto a = [](int i, int j){ return i + j; }(1, 2);
auto b = []() -> int { return '0'; }();
auto c = [=](){ return a + b; }();
auto d = [&](){ return c; }();
auto e = [a, &b](int x) mutable {
const auto identity = [](int y){ return y; };
for (auto i = 0; i < a; ++i)
a += b--;
return x + identity(a + b);
}(0);
return a + b + c + d + e;
}
int
test3()
{
const auto nullary = [](){ return 0; };
const auto unary = [](int x){ return x; };
using nullary_t = decltype(nullary);
using unary_t = decltype(unary);
const auto higher1st = [](nullary_t f){ return f(); };
const auto higher2nd = [unary](nullary_t f1){
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
};
return higher1st(nullary) + higher2nd(nullary)(unary);
}
}
namespace test_variadic_templates
{
template <int...>
struct sum;
template <int N0, int... N1toN>
struct sum<N0, N1toN...>
{
static constexpr auto value = N0 + sum<N1toN...>::value;
};
template <>
struct sum<>
{
static constexpr auto value = 0;
};
static_assert(sum<>::value == 0, "");
static_assert(sum<1>::value == 1, "");
static_assert(sum<23>::value == 23, "");
static_assert(sum<1, 2>::value == 3, "");
static_assert(sum<5, 5, 11>::value == 21, "");
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
}
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
// because of this.
namespace test_template_alias_sfinae
{
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() { func<foo>(0); }
}
} // namespace cxx11
#endif // __cplusplus >= 201103L
]])
dnl Tests for new features in C++14
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
// If the compiler admits that it is not ready for C++14, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#else
namespace cxx14
{
namespace test_polymorphic_lambdas
{
int
test()
{
const auto lambda = [](auto&&... args){
const auto istiny = [](auto x){
return (sizeof(x) == 1UL) ? 1 : 0;
};
const int aretiny[] = { istiny(args)... };
return aretiny[0];
};
return lambda(1, 1L, 1.0f, '1');
}
}
namespace test_binary_literals
{
constexpr auto ivii = 0b0000000000101010;
static_assert(ivii == 42, "wrong value");
}
namespace test_generalized_constexpr
{
template < typename CharT >
constexpr unsigned long
strlen_c(const CharT *const s) noexcept
{
auto length = 0UL;
for (auto p = s; *p; ++p)
++length;
return length;
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("x") == 1UL, "");
static_assert(strlen_c("test") == 4UL, "");
static_assert(strlen_c("another\0test") == 7UL, "");
}
namespace test_lambda_init_capture
{
int
test()
{
auto x = 0;
const auto lambda1 = [a = x](int b){ return a + b; };
const auto lambda2 = [a = lambda1(x)](){ return a; };
return lambda2();
}
}
namespace test_digit_separators
{
constexpr auto ten_million = 100'000'000;
static_assert(ten_million == 100000000, "");
}
namespace test_return_type_deduction
{
auto f(int& x) { return x; }
decltype(auto) g(int& x) { return x; }
template < typename T1, typename T2 >
struct is_same
{
static constexpr auto value = false;
};
template < typename T >
struct is_same<T, T>
{
static constexpr auto value = true;
};
int
test()
{
auto x = 0;
static_assert(is_same<int, decltype(f(x))>::value, "");
static_assert(is_same<int&, decltype(g(x))>::value, "");
return x;
}
}
} // namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])

View File

@@ -0,0 +1,133 @@
# ============================================================================
# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
# ============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++11
# standard; if necessary, add switches to CXXFLAGS to enable support.
#
# The first argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The second argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline C++11 support is required and that the macro
# should error out if no mode with that support is found. If specified
# 'optional', then configuration proceeds regardless, after defining
# HAVE_CXX11 if and only if a supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);
auto d = a;
])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
m4_if([$1], [], [],
[$1], [ext], [],
[$1], [noext], [],
[m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
[$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
[$2], [optional], [ax_cxx_compile_cxx11_required=false],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
AC_LANG_PUSH([C++])dnl
ac_success=no
AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
ax_cv_cxx_compile_cxx11,
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[ax_cv_cxx_compile_cxx11=yes],
[ax_cv_cxx_compile_cxx11=no])])
if test x$ax_cv_cxx_compile_cxx11 = xyes; then
ac_success=yes
fi
m4_if([$1], [noext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=gnu++11 -std=gnu++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
m4_if([$1], [ext], [], [dnl
if test x$ac_success = xno; then
for switch in -std=c++11 -std=c++0x; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
$cachevar,
[ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXXFLAGS="$ac_save_CXXFLAGS"])
if eval test x\$$cachevar = xyes; then
CXXFLAGS="$CXXFLAGS $switch"
ac_success=yes
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx11_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
fi
else
if test x$ac_success = xno; then
HAVE_CXX11=0
AC_MSG_NOTICE([No compiler with C++11 support was found])
else
HAVE_CXX11=1
AC_DEFINE(HAVE_CXX11,1,
[define if the compiler supports basic C++11 syntax])
fi
AC_SUBST(HAVE_CXX11)
fi
])

View File

@@ -8,8 +8,11 @@ set_source_files_properties(${cxx_sources} PROPERTIES
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}") COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
include_directories( include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/includes" "${CMAKE_SOURCE_DIR}/lib/includes"
"${CMAKE_CURRENT_SOURCE_DIR}/../third-party" "${CMAKE_BINARY_DIR}/lib/includes"
"${CMAKE_SOURCE_DIR}/lib"
"${CMAKE_SOURCE_DIR}/src/includes"
"${CMAKE_SOURCE_DIR}/third-party"
${JEMALLOC_INCLUDE_DIRS} ${JEMALLOC_INCLUDE_DIRS}
${SPDYLAY_INCLUDE_DIRS} ${SPDYLAY_INCLUDE_DIRS}
@@ -45,7 +48,7 @@ if(ENABLE_APP)
set(NGHTTP_SOURCES set(NGHTTP_SOURCES
${HELPER_OBJECTS} ${HELPER_OBJECTS}
nghttp.cc nghttp.cc
tls.cc ssl.cc
) )
if(HAVE_LIBXML2) if(HAVE_LIBXML2)
list(APPEND NGHTTP_SOURCES HtmlParser.cc) list(APPEND NGHTTP_SOURCES HtmlParser.cc)
@@ -55,7 +58,7 @@ if(ENABLE_APP)
set(NGHTTPD_SOURCES set(NGHTTPD_SOURCES
${HELPER_OBJECTS} ${HELPER_OBJECTS}
nghttpd.cc nghttpd.cc
tls.cc ssl.cc
HttpServer.cc HttpServer.cc
) )
@@ -64,7 +67,7 @@ if(ENABLE_APP)
util.cc util.cc
http2.cc h2load.cc http2.cc h2load.cc
timegm.c timegm.c
tls.cc ssl.cc
h2load_http2_session.cc h2load_http2_session.cc
h2load_http1_session.cc h2load_http1_session.cc
) )
@@ -79,7 +82,7 @@ if(ENABLE_APP)
set(NGHTTPX_SRCS set(NGHTTPX_SRCS
util.cc http2.cc timegm.c util.cc http2.cc timegm.c
app_helper.cc app_helper.cc
tls.cc ssl.cc
shrpx_config.cc shrpx_config.cc
shrpx_accept_handler.cc shrpx_accept_handler.cc
shrpx_connection_handler.cc shrpx_connection_handler.cc
@@ -95,7 +98,7 @@ if(ENABLE_APP)
shrpx_log.cc shrpx_log.cc
shrpx_http.cc shrpx_http.cc
shrpx_io_control.cc shrpx_io_control.cc
shrpx_tls.cc shrpx_ssl.cc
shrpx_worker.cc shrpx_worker.cc
shrpx_log_config.cc shrpx_log_config.cc
shrpx_connect_blocker.cc shrpx_connect_blocker.cc
@@ -149,7 +152,7 @@ if(ENABLE_APP)
if(HAVE_CUNIT) if(HAVE_CUNIT)
set(NGHTTPX_UNITTEST_SOURCES set(NGHTTPX_UNITTEST_SOURCES
shrpx-unittest.cc shrpx-unittest.cc
shrpx_tls_test.cc shrpx_ssl_test.cc
shrpx_downstream_test.cc shrpx_downstream_test.cc
shrpx_config_test.cc shrpx_config_test.cc
shrpx_worker_test.cc shrpx_worker_test.cc
@@ -213,7 +216,7 @@ endif()
if(ENABLE_ASIO_LIB) if(ENABLE_ASIO_LIB)
set(NGHTTP2_ASIO_SOURCES set(NGHTTP2_ASIO_SOURCES
util.cc http2.cc util.cc http2.cc
tls.cc ssl.cc
timegm.c timegm.c
asio_common.cc asio_common.cc
asio_io_service_pool.cc asio_io_service_pool.cc
@@ -249,11 +252,6 @@ if(ENABLE_ASIO_LIB)
${OPENSSL_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
) )
target_include_directories(nghttp2_asio INTERFACE
"${CMAKE_CURRENT_BINARY_DIR}/../lib/includes"
"${CMAKE_CURRENT_SOURCE_DIR}/../lib/includes"
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
)
target_link_libraries(nghttp2_asio target_link_libraries(nghttp2_asio
nghttp2 nghttp2
${OPENSSL_LIBRARIES} ${OPENSSL_LIBRARIES}

View File

@@ -32,7 +32,7 @@
#ifdef HAVE_LIBXML2 #ifdef HAVE_LIBXML2
# include <libxml/HTMLparser.h> #include <libxml/HTMLparser.h>
#endif // HAVE_LIBXML2 #endif // HAVE_LIBXML2

View File

@@ -26,23 +26,23 @@
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H #endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H #ifdef HAVE_NETDB_H
# include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H #endif // HAVE_NETDB_H
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H #endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H #endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H #endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#ifdef HAVE_ARPA_INET_H #ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h> #include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H #endif // HAVE_ARPA_INET_H
#include <cassert> #include <cassert>
@@ -60,11 +60,11 @@
#include "app_helper.h" #include "app_helper.h"
#include "http2.h" #include "http2.h"
#include "util.h" #include "util.h"
#include "tls.h" #include "ssl.h"
#include "template.h" #include "template.h"
#ifndef O_BINARY #ifndef O_BINARY
# define O_BINARY (0) #define O_BINARY (0)
#endif // O_BINARY #endif // O_BINARY
namespace nghttp2 { namespace nghttp2 {
@@ -305,7 +305,7 @@ public:
} }
} }
auto handler = auto handler =
std::make_unique<Http2Handler>(this, fd, ssl, get_next_session_id()); make_unique<Http2Handler>(this, fd, ssl, get_next_session_id());
if (!ssl) { if (!ssl) {
if (handler->connection_made() != 0) { if (handler->connection_made() != 0) {
return; return;
@@ -358,11 +358,11 @@ public:
} }
FileEntry *cache_fd(const std::string &path, const FileEntry &ent) { FileEntry *cache_fd(const std::string &path, const FileEntry &ent) {
#ifdef HAVE_STD_MAP_EMPLACE #ifdef HAVE_STD_MAP_EMPLACE
auto rv = fd_cache_.emplace(path, std::make_unique<FileEntry>(ent)); auto rv = fd_cache_.emplace(path, make_unique<FileEntry>(ent));
#else // !HAVE_STD_MAP_EMPLACE #else // !HAVE_STD_MAP_EMPLACE
// for gcc-4.7 // for gcc-4.7
auto rv = fd_cache_.insert( auto rv =
std::make_pair(path, std::make_unique<FileEntry>(ent))); fd_cache_.insert(std::make_pair(path, make_unique<FileEntry>(ent)));
#endif // !HAVE_STD_MAP_EMPLACE #endif // !HAVE_STD_MAP_EMPLACE
auto &res = (*rv).second; auto &res = (*rv).second;
res->it = rv; res->it = rv;
@@ -877,7 +877,7 @@ int Http2Handler::connection_made() {
} }
} }
if (ssl_ && !nghttp2::tls::check_http2_requirement(ssl_)) { if (ssl_ && !nghttp2::ssl::check_http2_requirement(ssl_)) {
terminate_session(NGHTTP2_INADEQUATE_SECURITY); terminate_session(NGHTTP2_INADEQUATE_SECURITY);
} }
@@ -888,9 +888,7 @@ int Http2Handler::verify_npn_result() {
const unsigned char *next_proto = nullptr; const unsigned char *next_proto = nullptr;
unsigned int next_proto_len; unsigned int next_proto_len;
// Check the negotiated protocol in NPN or ALPN // Check the negotiated protocol in NPN or ALPN
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len); SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len);
#endif // !OPENSSL_NO_NEXTPROTONEG
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
if (next_proto) { if (next_proto) {
auto proto = StringRef{next_proto, next_proto_len}; auto proto = StringRef{next_proto, next_proto_len};
@@ -1023,7 +1021,7 @@ int Http2Handler::submit_push_promise(Stream *stream,
return promised_stream_id; return promised_stream_id;
} }
auto promised_stream = std::make_unique<Stream>(this, promised_stream_id); auto promised_stream = make_unique<Stream>(this, promised_stream_id);
auto &promised_header = promised_stream->header; auto &promised_header = promised_stream->header;
promised_header.method = StringRef::from_lit("GET"); promised_header.method = StringRef::from_lit("GET");
@@ -1477,7 +1475,7 @@ int on_begin_headers_callback(nghttp2_session *session,
return 0; return 0;
} }
auto stream = std::make_unique<Stream>(hd, frame->hd.stream_id); auto stream = make_unique<Stream>(hd, frame->hd.stream_id);
add_stream_read_timeout(stream.get()); add_stream_read_timeout(stream.get());
@@ -1751,8 +1749,8 @@ void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
callbacks, verbose_on_invalid_frame_recv_callback); callbacks, verbose_on_invalid_frame_recv_callback);
nghttp2_session_callbacks_set_error_callback2(callbacks, nghttp2_session_callbacks_set_error_callback(callbacks,
verbose_error_callback); verbose_error_callback);
} }
nghttp2_session_callbacks_set_on_data_chunk_recv_callback( nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
@@ -1781,7 +1779,7 @@ struct ClientInfo {
struct Worker { struct Worker {
std::unique_ptr<Sessions> sessions; std::unique_ptr<Sessions> sessions;
ev_async w; ev_async w;
// protects q // protectes q
std::mutex m; std::mutex m;
std::deque<ClientInfo> q; std::deque<ClientInfo> q;
}; };
@@ -1832,10 +1830,10 @@ public:
if (config_->verbose) { if (config_->verbose) {
std::cerr << "spawning thread #" << i << std::endl; std::cerr << "spawning thread #" << i << std::endl;
} }
auto worker = std::make_unique<Worker>(); auto worker = make_unique<Worker>();
auto loop = ev_loop_new(get_ev_loop_flags()); auto loop = ev_loop_new(get_ev_loop_flags());
worker->sessions = std::make_unique<Sessions>(sv, loop, config_, worker->sessions =
sessions_->get_ssl_ctx()); make_unique<Sessions>(sv, loop, config_, sessions_->get_ssl_ctx());
ev_async_init(&worker->w, worker_acceptcb); ev_async_init(&worker->w, worker_acceptcb);
worker->w.data = worker.get(); worker->w.data = worker.get();
ev_async_start(loop, &worker->w); ev_async_start(loop, &worker->w);
@@ -1984,7 +1982,6 @@ HttpServer::HttpServer(const Config *config) : config_(config) {
}; };
} }
#ifndef OPENSSL_NO_NEXTPROTONEG
namespace { namespace {
int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
void *arg) { void *arg) {
@@ -1994,7 +1991,6 @@ int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len,
return SSL_TLSEXT_ERR_OK; return SSL_TLSEXT_ERR_OK;
} }
} // namespace } // namespace
#endif // !OPENSSL_NO_NEXTPROTONEG
namespace { namespace {
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
@@ -2126,14 +2122,14 @@ int HttpServer::run() {
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
if (nghttp2::tls::ssl_ctx_set_proto_versions( if (nghttp2::ssl::ssl_ctx_set_proto_versions(
ssl_ctx, nghttp2::tls::NGHTTP2_TLS_MIN_VERSION, ssl_ctx, nghttp2::ssl::NGHTTP2_TLS_MIN_VERSION,
nghttp2::tls::NGHTTP2_TLS_MAX_VERSION) != 0) { nghttp2::ssl::NGHTTP2_TLS_MAX_VERSION) != 0) {
std::cerr << "Could not set TLS versions" << std::endl; std::cerr << "Could not set TLS versions" << std::endl;
return -1; return -1;
} }
if (SSL_CTX_set_cipher_list(ssl_ctx, tls::DEFAULT_CIPHER_LIST) == 0) { if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl; std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
return -1; return -1;
} }
@@ -2160,7 +2156,7 @@ int HttpServer::run() {
} }
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
EC_KEY_free(ecdh); EC_KEY_free(ecdh);
// #endif // OPENSSL_VERSION_NUBMER < 0x10002000L // #endif // OPENSSL_VERSION_NUBMER < 0x10002000L
#endif // OPENSSL_NO_EC #endif // OPENSSL_NO_EC
@@ -2201,17 +2197,14 @@ int HttpServer::run() {
return -1; return -1;
} }
if (config_->verify_client) { if (config_->verify_client) {
SSL_CTX_set_verify(ssl_ctx, SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE |
SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
verify_callback); verify_callback);
} }
next_proto = util::get_default_alpn(); next_proto = util::get_default_alpn();
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto); SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, &next_proto);
#endif // !OPENSSL_NO_NEXTPROTONEG
#if OPENSSL_VERSION_NUMBER >= 0x10002000L #if OPENSSL_VERSION_NUMBER >= 0x10002000L
// ALPN selection callback // ALPN selection callback
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this); SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);

View File

@@ -40,6 +40,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/lib \ -I$(top_srcdir)/lib \
-I$(top_srcdir)/src/includes \ -I$(top_srcdir)/src/includes \
-I$(top_srcdir)/third-party \ -I$(top_srcdir)/third-party \
@LIBSPDYLAY_CFLAGS@ \
@LIBXML2_CFLAGS@ \ @LIBXML2_CFLAGS@ \
@LIBEV_CFLAGS@ \ @LIBEV_CFLAGS@ \
@OPENSSL_CFLAGS@ \ @OPENSSL_CFLAGS@ \
@@ -51,6 +52,7 @@ AM_CPPFLAGS = \
LDADD = $(top_builddir)/lib/libnghttp2.la \ LDADD = $(top_builddir)/lib/libnghttp2.la \
$(top_builddir)/third-party/libhttp-parser.la \ $(top_builddir)/third-party/libhttp-parser.la \
@JEMALLOC_LIBS@ \ @JEMALLOC_LIBS@ \
@LIBSPDYLAY_LIBS@ \
@LIBXML2_LIBS@ \ @LIBXML2_LIBS@ \
@LIBEV_LIBS@ \ @LIBEV_LIBS@ \
@OPENSSL_LIBS@ \ @OPENSSL_LIBS@ \
@@ -79,10 +81,10 @@ endif # HAVE_LIBXML2
nghttp_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttp.cc nghttp.h \ nghttp_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttp.cc nghttp.h \
${HTML_PARSER_OBJECTS} ${HTML_PARSER_HFILES} \ ${HTML_PARSER_OBJECTS} ${HTML_PARSER_HFILES} \
tls.cc tls.h ssl.cc ssl.h
nghttpd_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttpd.cc \ nghttpd_SOURCES = ${HELPER_OBJECTS} ${HELPER_HFILES} nghttpd.cc \
tls.cc tls.h \ ssl.cc ssl.h \
HttpServer.cc HttpServer.h HttpServer.cc HttpServer.h
bin_PROGRAMS += h2load bin_PROGRAMS += h2load
@@ -90,15 +92,19 @@ bin_PROGRAMS += h2load
h2load_SOURCES = util.cc util.h \ h2load_SOURCES = util.cc util.h \
http2.cc http2.h h2load.cc h2load.h \ http2.cc http2.h h2load.cc h2load.h \
timegm.c timegm.h \ timegm.c timegm.h \
tls.cc tls.h \ ssl.cc ssl.h \
h2load_session.h \ h2load_session.h \
h2load_http2_session.cc h2load_http2_session.h \ h2load_http2_session.cc h2load_http2_session.h \
h2load_http1_session.cc h2load_http1_session.h h2load_http1_session.cc h2load_http1_session.h
if HAVE_SPDYLAY
h2load_SOURCES += h2load_spdy_session.cc h2load_spdy_session.h
endif # HAVE_SPDYLAY
NGHTTPX_SRCS = \ NGHTTPX_SRCS = \
util.cc util.h http2.cc http2.h timegm.c timegm.h base64.h \ util.cc util.h http2.cc http2.h timegm.c timegm.h base64.h \
app_helper.cc app_helper.h \ app_helper.cc app_helper.h \
tls.cc tls.h \ ssl.cc ssl.h \
shrpx_config.cc shrpx_config.h \ shrpx_config.cc shrpx_config.h \
shrpx_error.h \ shrpx_error.h \
shrpx_accept_handler.cc shrpx_accept_handler.h \ shrpx_accept_handler.cc shrpx_accept_handler.h \
@@ -116,7 +122,7 @@ NGHTTPX_SRCS = \
shrpx_log.cc shrpx_log.h \ shrpx_log.cc shrpx_log.h \
shrpx_http.cc shrpx_http.h \ shrpx_http.cc shrpx_http.h \
shrpx_io_control.cc shrpx_io_control.h \ shrpx_io_control.cc shrpx_io_control.h \
shrpx_tls.cc shrpx_tls.h \ shrpx_ssl.cc shrpx_ssl.h \
shrpx_worker.cc shrpx_worker.h \ shrpx_worker.cc shrpx_worker.h \
shrpx_log_config.cc shrpx_log_config.h \ shrpx_log_config.cc shrpx_log_config.h \
shrpx_connect_blocker.cc shrpx_connect_blocker.h \ shrpx_connect_blocker.cc shrpx_connect_blocker.h \
@@ -142,6 +148,10 @@ NGHTTPX_SRCS = \
buffer.h memchunk.h template.h allocator.h \ buffer.h memchunk.h template.h allocator.h \
xsi_strerror.c xsi_strerror.h xsi_strerror.c xsi_strerror.h
if HAVE_SPDYLAY
NGHTTPX_SRCS += shrpx_spdy_upstream.cc shrpx_spdy_upstream.h
endif # HAVE_SPDYLAY
if HAVE_MRUBY if HAVE_MRUBY
NGHTTPX_SRCS += \ NGHTTPX_SRCS += \
shrpx_mruby.cc shrpx_mruby.h \ shrpx_mruby.cc shrpx_mruby.h \
@@ -173,7 +183,7 @@ endif # HAVE_NEVERBLEED
if HAVE_CUNIT if HAVE_CUNIT
check_PROGRAMS += nghttpx-unittest check_PROGRAMS += nghttpx-unittest
nghttpx_unittest_SOURCES = shrpx-unittest.cc \ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
shrpx_tls_test.cc shrpx_tls_test.h \ shrpx_ssl_test.cc shrpx_ssl_test.h \
shrpx_downstream_test.cc shrpx_downstream_test.h \ shrpx_downstream_test.cc shrpx_downstream_test.h \
shrpx_config_test.cc shrpx_config_test.h \ shrpx_config_test.cc shrpx_config_test.h \
shrpx_worker_test.cc shrpx_worker_test.h \ shrpx_worker_test.cc shrpx_worker_test.h \
@@ -230,7 +240,7 @@ lib_LTLIBRARIES = libnghttp2_asio.la
libnghttp2_asio_la_SOURCES = \ libnghttp2_asio_la_SOURCES = \
util.cc util.h http2.cc http2.h \ util.cc util.h http2.cc http2.h \
tls.cc tls.h \ ssl.cc ssl.h \
ssl_compat.h \ ssl_compat.h \
timegm.c timegm.h \ timegm.c timegm.h \
asio_common.cc asio_common.h \ asio_common.cc asio_common.h \

View File

@@ -27,12 +27,9 @@
#include "nghttp2_config.h" #include "nghttp2_config.h"
#ifndef _WIN32 #include <sys/uio.h>
# include <sys/uio.h>
#endif // !_WIN32
#include <cassert> #include <cassert>
#include <utility>
#include "template.h" #include "template.h"
@@ -66,19 +63,25 @@ struct BlockAllocator {
~BlockAllocator() { reset(); } ~BlockAllocator() { reset(); }
BlockAllocator(BlockAllocator &&other) noexcept BlockAllocator(BlockAllocator &&other) noexcept
: retain{std::exchange(other.retain, nullptr)}, : retain(other.retain),
head{std::exchange(other.head, nullptr)}, head(other.head),
block_size(other.block_size), block_size(other.block_size),
isolation_threshold(other.isolation_threshold) {} isolation_threshold(other.isolation_threshold) {
other.retain = nullptr;
other.head = nullptr;
}
BlockAllocator &operator=(BlockAllocator &&other) noexcept { BlockAllocator &operator=(BlockAllocator &&other) noexcept {
reset(); reset();
retain = std::exchange(other.retain, nullptr); retain = other.retain;
head = std::exchange(other.head, nullptr); head = other.head;
block_size = other.block_size; block_size = other.block_size;
isolation_threshold = other.isolation_threshold; isolation_threshold = other.isolation_threshold;
other.retain = nullptr;
other.head = nullptr;
return *this; return *this;
} }
@@ -268,6 +271,6 @@ ByteRef make_byte_ref(BlockAllocator &alloc, size_t size) {
return {dst, size}; return {dst, size};
} }
} // namespace nghttp2 } // namespace aria2
#endif // ALLOCATOR_H #endif // ALLOCATOR_H

View File

@@ -24,19 +24,19 @@
*/ */
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h> #include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H #endif // HAVE_SYS_SOCKET_H
#ifdef HAVE_NETDB_H #ifdef HAVE_NETDB_H
# include <netdb.h> #include <netdb.h>
#endif // HAVE_NETDB_H #endif // HAVE_NETDB_H
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> #include <unistd.h>
#endif // HAVE_UNISTD_H #endif // HAVE_UNISTD_H
#ifdef HAVE_FCNTL_H #ifdef HAVE_FCNTL_H
# include <fcntl.h> #include <fcntl.h>
#endif // HAVE_FCNTL_H #endif // HAVE_FCNTL_H
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
# include <netinet/in.h> #include <netinet/in.h>
#endif // HAVE_NETINET_IN_H #endif // HAVE_NETINET_IN_H
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <poll.h> #include <poll.h>
@@ -77,8 +77,6 @@ const char *strsettingsid(int32_t id) {
return "SETTINGS_MAX_FRAME_SIZE"; return "SETTINGS_MAX_FRAME_SIZE";
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE: case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
return "SETTINGS_MAX_HEADER_LIST_SIZE"; return "SETTINGS_MAX_HEADER_LIST_SIZE";
case NGHTTP2_SETTINGS_ENABLE_CONNECT_PROTOCOL:
return "SETTINGS_ENABLE_CONNECT_PROTOCOL";
default: default:
return "UNKNOWN"; return "UNKNOWN";
} }
@@ -108,8 +106,6 @@ std::string strframetype(uint8_t type) {
return "WINDOW_UPDATE"; return "WINDOW_UPDATE";
case NGHTTP2_ALTSVC: case NGHTTP2_ALTSVC:
return "ALTSVC"; return "ALTSVC";
case NGHTTP2_ORIGIN:
return "ORIGIN";
} }
std::string s = "extension(0x"; std::string s = "extension(0x";
@@ -159,7 +155,7 @@ void print_nv(nghttp2_nv *nva, size_t nvlen) {
print_nv(nva); print_nv(nva);
} }
} }
} // namespace } // namelen
void print_timer() { void print_timer() {
auto millis = get_timer(); auto millis = get_timer();
@@ -331,9 +327,8 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
break; break;
case NGHTTP2_GOAWAY: case NGHTTP2_GOAWAY:
print_frame_attr_indent(); print_frame_attr_indent();
fprintf(outfile, fprintf(outfile, "(last_stream_id=%d, error_code=%s(0x%02x), "
"(last_stream_id=%d, error_code=%s(0x%02x), " "opaque_data(%u)=[%s])\n",
"opaque_data(%u)=[%s])\n",
frame->goaway.last_stream_id, frame->goaway.last_stream_id,
nghttp2_http2_strerror(frame->goaway.error_code), nghttp2_http2_strerror(frame->goaway.error_code),
frame->goaway.error_code, frame->goaway.error_code,
@@ -355,15 +350,6 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
static_cast<int>(altsvc->field_value_len), altsvc->field_value); static_cast<int>(altsvc->field_value_len), altsvc->field_value);
break; break;
} }
case NGHTTP2_ORIGIN: {
auto origin = static_cast<nghttp2_ext_origin *>(frame->ext.payload);
for (size_t i = 0; i < origin->nov; ++i) {
auto ent = &origin->ov[i];
print_frame_attr_indent();
fprintf(outfile, "[%.*s]\n", (int)ent->origin_len, ent->origin);
}
break;
}
default: default:
break; break;
} }
@@ -439,8 +425,8 @@ int verbose_on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
return 0; return 0;
} }
int verbose_error_callback(nghttp2_session *session, int lib_error_code, int verbose_error_callback(nghttp2_session *session, const char *msg,
const char *msg, size_t len, void *user_data) { size_t len, void *user_data) {
print_timer(); print_timer();
fprintf(outfile, " [ERROR] %.*s\n", (int)len, msg); fprintf(outfile, " [ERROR] %.*s\n", (int)len, msg);
fflush(outfile); fflush(outfile);

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