mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-07 18:48:54 +08:00
Compare commits
1 Commits
v1.18.x
...
hpack-8bit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
240a4057f3 |
@@ -1,94 +1,57 @@
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
AlignAfterOpenBracket: Align
|
ConstructorInitializerIndentWidth: 4
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignEscapedNewlinesLeft: false
|
AlignEscapedNewlinesLeft: false
|
||||||
AlignOperands: true
|
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortBlocksOnASingleLine: false
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
|
||||||
AllowShortFunctionsOnASingleLine: All
|
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
|
||||||
AlwaysBreakTemplateDeclarations: false
|
AlwaysBreakTemplateDeclarations: false
|
||||||
BinPackArguments: true
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
BinPackParameters: true
|
BreakBeforeBinaryOperators: false
|
||||||
BraceWrapping:
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: false
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: false
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterObjCDeclaration: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
IndentBraces: false
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
BreakAfterJavaFieldAnnotations: false
|
BinPackParameters: true
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
ConstructorInitializerIndentWidth: 4
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
DisableFormat: false
|
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
|
||||||
Priority: 2
|
|
||||||
- Regex: '^(<|"(gtest|isl|json)/)'
|
|
||||||
Priority: 3
|
|
||||||
- Regex: '.*'
|
|
||||||
Priority: 1
|
|
||||||
IncludeIsMainRegex: '$'
|
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
IndentWidth: 2
|
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
JavaScriptQuotes: Leave
|
IndentFunctionDeclarationAfterType: false
|
||||||
JavaScriptWrapImports: true
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
MacroBlockBegin: ''
|
|
||||||
MacroBlockEnd: ''
|
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
ObjCBlockIndentWidth: 2
|
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ObjCSpaceBeforeProtocolList: true
|
||||||
PenaltyBreakBeforeFirstCallParameter: 19
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
PenaltyBreakComment: 300
|
PenaltyBreakComment: 300
|
||||||
PenaltyBreakFirstLessLess: 120
|
|
||||||
PenaltyBreakString: 1000
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
ReflowComments: true
|
|
||||||
SortIncludes: false
|
|
||||||
SpaceAfterCStyleCast: false
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
SpacesInAngles: false
|
Cpp11BracedListStyle: true
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInSquareBrackets: false
|
|
||||||
Standard: Cpp11
|
Standard: Cpp11
|
||||||
|
IndentWidth: 2
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
DisableFormat: false
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
16
.gitignore
vendored
16
.gitignore
vendored
@@ -29,22 +29,6 @@ missing
|
|||||||
stamp-h1
|
stamp-h1
|
||||||
test-driver
|
test-driver
|
||||||
|
|
||||||
# cmake
|
|
||||||
CMakeCache.txt
|
|
||||||
CMakeFiles/
|
|
||||||
cmake_install.cmake
|
|
||||||
install_manifest.txt
|
|
||||||
CTestTestfile.cmake
|
|
||||||
build.ninja
|
|
||||||
rules.ninja
|
|
||||||
.ninja_deps
|
|
||||||
.ninja_log
|
|
||||||
lib*.so
|
|
||||||
lib*.so.*
|
|
||||||
lib*.a
|
|
||||||
# generated by "make test" with cmake
|
|
||||||
Testing/
|
|
||||||
|
|
||||||
# test logs generated by `make check`
|
# test logs generated by `make check`
|
||||||
*.log
|
*.log
|
||||||
*.trs
|
*.trs
|
||||||
|
|||||||
29
.travis.yml
29
.travis.yml
@@ -1,7 +1,3 @@
|
|||||||
env:
|
|
||||||
matrix:
|
|
||||||
- CI_BUILD=cmake
|
|
||||||
- CI_BUILD=autotools
|
|
||||||
language: cpp
|
language: cpp
|
||||||
compiler:
|
compiler:
|
||||||
- clang
|
- clang
|
||||||
@@ -11,7 +7,6 @@ addons:
|
|||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
- george-edison55-precise-backports
|
|
||||||
packages:
|
packages:
|
||||||
- g++-4.9
|
- g++-4.9
|
||||||
- libstdc++-4.9-dev
|
- libstdc++-4.9-dev
|
||||||
@@ -28,15 +23,11 @@ addons:
|
|||||||
- libevent-dev
|
- libevent-dev
|
||||||
- libjansson-dev
|
- libjansson-dev
|
||||||
- libjemalloc-dev
|
- libjemalloc-dev
|
||||||
- libc-ares-dev
|
|
||||||
- cmake
|
|
||||||
- cmake-data
|
|
||||||
before_install:
|
before_install:
|
||||||
- $CC --version
|
- $CC --version
|
||||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
|
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
|
||||||
- $CC --version
|
- $CC --version
|
||||||
- go version
|
- go version
|
||||||
- cmake --version
|
|
||||||
before_script:
|
before_script:
|
||||||
# First build spdylay, since integration tests require it.
|
# First build spdylay, since integration tests require it.
|
||||||
# spdylay is going to be built under third-party/spdylay
|
# spdylay is going to be built under third-party/spdylay
|
||||||
@@ -44,22 +35,18 @@ before_script:
|
|||||||
- git clone https://github.com/tatsuhiro-t/spdylay.git
|
- git clone https://github.com/tatsuhiro-t/spdylay.git
|
||||||
- cd spdylay
|
- cd spdylay
|
||||||
- autoreconf -i
|
- autoreconf -i
|
||||||
# Don't use ASAN for spdylay since failmalloc does not work with it.
|
|
||||||
- ./configure --disable-src --disable-examples
|
- ./configure --disable-src --disable-examples
|
||||||
- make check
|
- make check
|
||||||
- export SPDYLAY_HOME=$PWD
|
- export SPDYLAY_HOME=$PWD
|
||||||
- cd ../..
|
- cd ../..
|
||||||
# Now build nghttp2
|
# Now build nghttp2
|
||||||
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
|
- autoreconf -i
|
||||||
- git submodule update --init
|
- git submodule update --init
|
||||||
- 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
|
- ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"
|
||||||
- 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; fi
|
- make
|
||||||
- if [ "$CI_BUILD" = "cmake" ]; then make check; fi
|
- make check
|
||||||
# As of April, 23, 2016, golang http2 build fails, probably because
|
- cd integration-tests
|
||||||
# the default go version is too old.
|
- export GOPATH="$PWD/integration-tests/golang"
|
||||||
# - cd integration-tests
|
- make itprep-local
|
||||||
# - export GOPATH="$PWD/integration-tests/golang"
|
- make it-local
|
||||||
# - make itprep
|
|
||||||
# - make it
|
|
||||||
|
|||||||
90
AUTHORS
90
AUTHORS
@@ -1,89 +1 @@
|
|||||||
nghttp2 project was started as a fork of spdylay project [1]. Both
|
Tatsuhiro Tsujikawa <t-tujikawa at users dot sourceforge dot net>
|
||||||
projects were started by Tatsuhiro Tsujikawa, who is still the main
|
|
||||||
author of these projects. Meanwhile, we have many contributions, and
|
|
||||||
we are not here without them. We sincerely thank you to all who made
|
|
||||||
a contribution. Here is the all individuals/organizations who
|
|
||||||
contributed to nghttp2 and spdylay project at which we forked. These
|
|
||||||
names are retrieved from git commit log. If you have made a
|
|
||||||
contribution, but you are missing in the list, please let us know via
|
|
||||||
github issues [2].
|
|
||||||
|
|
||||||
[1] https://github.com/tatsuhiro-t/spdylay
|
|
||||||
[2] https://github.com/nghttp2/nghttp2/issues
|
|
||||||
|
|
||||||
--------
|
|
||||||
|
|
||||||
187j3x1
|
|
||||||
Alek Storm
|
|
||||||
Alex Nalivko
|
|
||||||
Alexis La Goutte
|
|
||||||
Anders Bakken
|
|
||||||
Andreas Pohl
|
|
||||||
Andy Davies
|
|
||||||
Ant Bryan
|
|
||||||
Bernard Spil
|
|
||||||
Brian Card
|
|
||||||
Brian Suh
|
|
||||||
Daniel Stenberg
|
|
||||||
Dave Reisner
|
|
||||||
David Beitey
|
|
||||||
David Weekly
|
|
||||||
Etienne Cimon
|
|
||||||
Fabian Möller
|
|
||||||
Fabian Wiesel
|
|
||||||
Gabi Davar
|
|
||||||
Google Inc.
|
|
||||||
Jacob Champion
|
|
||||||
Jan-E
|
|
||||||
Janusz Dziemidowicz
|
|
||||||
Jay Satiro
|
|
||||||
Jianqing Wang
|
|
||||||
Jim Morrison
|
|
||||||
José F. Calcerrada
|
|
||||||
Kamil Dudka
|
|
||||||
Kazuho Oku
|
|
||||||
Kenny (kang-yen) Peng
|
|
||||||
Kenny Peng
|
|
||||||
Kit Chan
|
|
||||||
Kyle Schomp
|
|
||||||
Lucas Pardue
|
|
||||||
MATSUMOTO Ryosuke
|
|
||||||
Matt Rudary
|
|
||||||
Mike Conlen
|
|
||||||
Mike Frysinger
|
|
||||||
Nicholas Hurley
|
|
||||||
Nora Shoemaker
|
|
||||||
Peeyush Aggarwal
|
|
||||||
Peter Wu
|
|
||||||
Piotr Sikora
|
|
||||||
Raul Gutierrez Segales
|
|
||||||
Remo E
|
|
||||||
Reza Tavakoli
|
|
||||||
Ross Smith II
|
|
||||||
Scott Mitchell
|
|
||||||
Stefan Eissing
|
|
||||||
Stephen Ludin
|
|
||||||
Sunpoet Po-Chuan Hsieh
|
|
||||||
Svante Signell
|
|
||||||
Syohei YOSHIDA
|
|
||||||
Tatsuhiko Kubo
|
|
||||||
Tatsuhiro Tsujikawa
|
|
||||||
Tom Harwood
|
|
||||||
Tomasz Buchert
|
|
||||||
Vernon Tang
|
|
||||||
Viacheslav Biriukov
|
|
||||||
Viktor Szépe
|
|
||||||
Wenfeng Liu
|
|
||||||
Xiaoguang Sun
|
|
||||||
Zhuoyun Wei
|
|
||||||
acesso
|
|
||||||
ayanamist
|
|
||||||
bxshi
|
|
||||||
dalf
|
|
||||||
es
|
|
||||||
fangdingjun
|
|
||||||
kumagi
|
|
||||||
mod-h2-dev
|
|
||||||
moparisthebest
|
|
||||||
snnn
|
|
||||||
yuuki-kodama
|
|
||||||
|
|||||||
526
CMakeLists.txt
526
CMakeLists.txt
@@ -1,526 +0,0 @@
|
|||||||
# nghttp2 - HTTP/2 C Library
|
|
||||||
#
|
|
||||||
# Copyright (c) 2012, 2013, 2014, 2015 Tatsuhiro Tsujikawa
|
|
||||||
# Copyright (c) 2016 Peter Wu <peter@lekensteyn.nl>
|
|
||||||
#
|
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
# a copy of this software and associated documentation files (the
|
|
||||||
# "Software"), to deal in the Software without restriction, including
|
|
||||||
# without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
# permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
# the following conditions:
|
|
||||||
#
|
|
||||||
# The above copyright notice and this permission notice shall be
|
|
||||||
# included in all copies or substantial portions of the Software.
|
|
||||||
#
|
|
||||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.0)
|
|
||||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
|
||||||
project(nghttp2 VERSION 1.18.1)
|
|
||||||
|
|
||||||
# See versioning rule:
|
|
||||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
|
||||||
set(LT_CURRENT 26)
|
|
||||||
set(LT_REVISION 3)
|
|
||||||
set(LT_AGE 12)
|
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
|
||||||
include(Version)
|
|
||||||
|
|
||||||
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
|
|
||||||
set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}")
|
|
||||||
set(PACKAGE_VERSION "${PROJECT_VERSION}")
|
|
||||||
HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH})
|
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
||||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE)
|
|
||||||
|
|
||||||
# Include "None" as option to disable any additional (optimization) flags,
|
|
||||||
# relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by
|
|
||||||
# default). These strings are presented in cmake-gui.
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
|
||||||
"None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
# For Python bindings and documentation
|
|
||||||
# (Must be called before PythonLibs for matching versions.)
|
|
||||||
find_package(PythonInterp)
|
|
||||||
|
|
||||||
# Auto-detection of features that can be toggled
|
|
||||||
find_package(OpenSSL 1.0.1)
|
|
||||||
find_package(Libev 4.11)
|
|
||||||
find_package(Libcares 1.7.5)
|
|
||||||
find_package(ZLIB 1.2.3)
|
|
||||||
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
|
|
||||||
set(ENABLE_APP_DEFAULT ON)
|
|
||||||
else()
|
|
||||||
set(ENABLE_APP_DEFAULT OFF)
|
|
||||||
endif()
|
|
||||||
find_package(Jansson 2.5)
|
|
||||||
set(ENABLE_HPACK_TOOLS_DEFAULT ${JANSSON_FOUND})
|
|
||||||
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
|
||||||
find_package(Libevent 2.0.8 COMPONENTS libevent openssl)
|
|
||||||
set(ENABLE_EXAMPLES_DEFAULT ${LIBEVENT_OPENSSL_FOUND})
|
|
||||||
find_package(Cython)
|
|
||||||
find_package(PythonLibs)
|
|
||||||
if(CYTHON_FOUND AND PYTHONLIBS_FOUND)
|
|
||||||
set(ENABLE_PYTHON_BINDINGS_DEFAULT ON)
|
|
||||||
else()
|
|
||||||
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package(LibXml2 2.7.7)
|
|
||||||
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
|
|
||||||
find_package(Jemalloc)
|
|
||||||
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
|
|
||||||
find_package(Spdylay 1.3.2)
|
|
||||||
set(WITH_SPDYLAY_DEFAULT ${SPDYLAY_FOUND})
|
|
||||||
|
|
||||||
include(CMakeOptions.txt)
|
|
||||||
|
|
||||||
if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_EXAMPLES OR
|
|
||||||
ENABLE_PYTHON_BINDINGS))
|
|
||||||
# Remember when disabled options are disabled for later diagnostics.
|
|
||||||
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1)
|
|
||||||
else()
|
|
||||||
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0)
|
|
||||||
endif()
|
|
||||||
if(ENABLE_LIB_ONLY)
|
|
||||||
set(ENABLE_APP OFF)
|
|
||||||
set(ENABLE_HPACK_TOOLS OFF)
|
|
||||||
set(ENABLE_EXAMPLES OFF)
|
|
||||||
set(ENABLE_PYTHON_BINDINGS OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Do not disable assertions based on CMAKE_BUILD_TYPE.
|
|
||||||
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
|
|
||||||
foreach(_lang C CXX)
|
|
||||||
string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
|
|
||||||
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" "" ${_var} "${${_var}}")
|
|
||||||
endforeach()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
#
|
|
||||||
# If we're running GCC or clang define _U_ to be "__attribute__((unused))"
|
|
||||||
# so we can use _U_ to flag unused function parameters and not get warnings
|
|
||||||
# about them. Otherwise, define _U_ to be an empty string so that _U_ used
|
|
||||||
# to flag an unused function parameters will compile with other compilers.
|
|
||||||
#
|
|
||||||
# XXX - similar hints for other compilers?
|
|
||||||
#
|
|
||||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
|
||||||
set(HINT_UNUSED_PARAM "__attribute__((unused))")
|
|
||||||
set(HINT_NORETURN "__attribute__((noreturn))")
|
|
||||||
else()
|
|
||||||
set(HINT_UNUSED_PARAM)
|
|
||||||
set(HINT_NORETURN)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(ExtractValidFlags)
|
|
||||||
foreach(_cxx1x_flag -std=c++11 -std=c++0x)
|
|
||||||
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
|
|
||||||
if(_cxx1x_flag_supported)
|
|
||||||
set(CXX1XCXXFLAGS ${_cxx1x_flag})
|
|
||||||
break()
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
include(CMakePushCheckState)
|
|
||||||
include(CheckCXXSourceCompiles)
|
|
||||||
cmake_push_check_state()
|
|
||||||
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
|
|
||||||
# Check that std::future is available.
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <vector>
|
|
||||||
#include <future>
|
|
||||||
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
|
|
||||||
# Check that std::map::emplace is available for g++-4.7.
|
|
||||||
check_cxx_source_compiles("
|
|
||||||
#include <map>
|
|
||||||
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
|
|
||||||
cmake_pop_check_state()
|
|
||||||
|
|
||||||
|
|
||||||
# Checks for libraries.
|
|
||||||
# Additional libraries required for programs under src directory.
|
|
||||||
set(APP_LIBRARIES)
|
|
||||||
|
|
||||||
if(ENABLE_PYTHON_BINDINGS)
|
|
||||||
if(NOT (CYTHON_FOUND AND PYTHONLIBS_FOUND))
|
|
||||||
message(FATAL_ERROR "python bindings were requested "
|
|
||||||
"(ENABLE_PYTHON_BINDINGS=1) but dependencies are not met.")
|
|
||||||
endif()
|
|
||||||
if(NOT PYTHON_VERSION_STRING STREQUAL PYTHONLIBS_VERSION_STRING)
|
|
||||||
message(FATAL_ERROR
|
|
||||||
"Python executable and library must have the same version!"
|
|
||||||
" Found Python ${PYTHON_VERSION_STRING} and"
|
|
||||||
" PythonLibs ${PYTHONLIBS_VERSION_STRING}"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_THREAD_PREFER_PTHREAD 1)
|
|
||||||
find_package(Threads)
|
|
||||||
if(CMAKE_USE_PTHREADS_INIT)
|
|
||||||
list(APPEND APP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
endif()
|
|
||||||
# XXX android and C++, is this still needed in cmake?
|
|
||||||
# case "$host" in
|
|
||||||
# *android*)
|
|
||||||
# android_build=yes
|
|
||||||
# # android does not need -pthread, but needs followng 3 libs for C++
|
|
||||||
# APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
|
|
||||||
|
|
||||||
# dl: openssl requires libdl when it is statically linked.
|
|
||||||
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
|
|
||||||
# APP_LIBRARIES if it is really specific to OpenSSL?
|
|
||||||
|
|
||||||
find_package(CUnit 2.1)
|
|
||||||
enable_testing()
|
|
||||||
set(HAVE_CUNIT ${CUNIT_FOUND})
|
|
||||||
if(HAVE_CUNIT)
|
|
||||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# openssl (for src)
|
|
||||||
set(HAVE_OPENSSL ${OPENSSL_FOUND})
|
|
||||||
if(OPENSSL_FOUND)
|
|
||||||
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
set(OPENSSL_INCLUDE_DIRS "")
|
|
||||||
set(OPENSSL_LIBRARIES "")
|
|
||||||
endif()
|
|
||||||
# libev (for src)
|
|
||||||
set(HAVE_LIBEV ${LIBEV_FOUND})
|
|
||||||
set(HAVE_ZLIB ${ZLIB_FOUND})
|
|
||||||
set(HAVE_LIBEVENT_OPENSSL ${LIBEVENT_FOUND})
|
|
||||||
if(LIBEVENT_FOUND)
|
|
||||||
# Must both link the core and openssl libraries.
|
|
||||||
set(LIBEVENT_OPENSSL_LIBRARIES ${LIBEVENT_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
# libc-ares (for src)
|
|
||||||
set(HAVE_LIBCARES ${LIBCARES_FOUND})
|
|
||||||
if(LIBCARES_FOUND)
|
|
||||||
set(LIBCARES_INCLUDE_DIRS ${LIBCARES_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
set(LIBCARES_INCLUDE_DIRS "")
|
|
||||||
set(LIBCARES_LIBRARIES "")
|
|
||||||
endif()
|
|
||||||
# jansson (for src/nghttp, src/deflatehd and src/inflatehd)
|
|
||||||
set(HAVE_JANSSON ${JANSSON_FOUND})
|
|
||||||
# libxml2 (for src/nghttp)
|
|
||||||
set(HAVE_LIBXML2 ${LIBXML2_FOUND})
|
|
||||||
if(LIBXML2_FOUND)
|
|
||||||
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
|
|
||||||
else()
|
|
||||||
set(LIBXML2_INCLUDE_DIRS "")
|
|
||||||
set(LIBXML2_LIBRARIES "")
|
|
||||||
endif()
|
|
||||||
# jemalloc
|
|
||||||
set(HAVE_JEMALLOC ${JEMALLOC_FOUND})
|
|
||||||
# spdylay (for src/nghttpx and src/h2load)
|
|
||||||
set(HAVE_SPDYLAY ${SPDYLAY_FOUND})
|
|
||||||
|
|
||||||
if(ENABLE_ASIO_LIB)
|
|
||||||
find_package(Boost 1.54.0 REQUIRED system thread)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
|
|
||||||
if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
|
|
||||||
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# HPACK tools requires jansson
|
|
||||||
if(ENABLE_HPACK_TOOLS AND NOT HAVE_JANSSON)
|
|
||||||
message(FATAL_ERROR "HPACK tools were requested (ENABLE_HPACK_TOOLS=1) but dependencies are not met.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# C++ library libnghttp2_asio
|
|
||||||
if(ENABLE_EXAMPLES AND NOT (OPENSSL_FOUND AND LIBEVENT_OPENSSL_FOUND))
|
|
||||||
message(FATAL_ERROR "examples were requested (ENABLE_EXAMPLES=1) but dependencies are not met.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# third-party http-parser only be built when needed
|
|
||||||
if(ENABLE_EXAMPLES OR ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_ASIO_LIB)
|
|
||||||
set(ENABLE_THIRD_PARTY 1)
|
|
||||||
# mruby (for src/nghttpx)
|
|
||||||
set(HAVE_MRUBY ${WITH_MRUBY})
|
|
||||||
set(HAVE_NEVERBLEED ${WITH_NEVERBLEED})
|
|
||||||
else()
|
|
||||||
set(HAVE_MRUBY 0)
|
|
||||||
set(HAVE_NEVERBLEED 0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Checks for header files.
|
|
||||||
include(CheckIncludeFile)
|
|
||||||
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
|
|
||||||
check_include_file("fcntl.h" HAVE_FCNTL_H)
|
|
||||||
check_include_file("inttypes.h" HAVE_INTTYPES_H)
|
|
||||||
check_include_file("limits.h" HAVE_LIMITS_H)
|
|
||||||
check_include_file("netdb.h" HAVE_NETDB_H)
|
|
||||||
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
|
|
||||||
check_include_file("pwd.h" HAVE_PWD_H)
|
|
||||||
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
|
|
||||||
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
|
|
||||||
check_include_file("syslog.h" HAVE_SYSLOG_H)
|
|
||||||
check_include_file("time.h" HAVE_TIME_H)
|
|
||||||
check_include_file("unistd.h" HAVE_UNISTD_H)
|
|
||||||
|
|
||||||
include(CheckTypeSize)
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
|
||||||
# AC_TYPE_SIZE_T
|
|
||||||
check_type_size("ssize_t" SIZEOF_SSIZE_T)
|
|
||||||
if(SIZEOF_SSIZE_T STREQUAL "")
|
|
||||||
# ssize_t is a signed type in POSIX storing at least -1.
|
|
||||||
# Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools).
|
|
||||||
set(ssize_t int)
|
|
||||||
endif()
|
|
||||||
# AC_TYPE_UINT8_T
|
|
||||||
# AC_TYPE_UINT16_T
|
|
||||||
# AC_TYPE_UINT32_T
|
|
||||||
# AC_TYPE_UINT64_T
|
|
||||||
# AC_TYPE_INT8_T
|
|
||||||
# AC_TYPE_INT16_T
|
|
||||||
# AC_TYPE_INT32_T
|
|
||||||
# AC_TYPE_INT64_T
|
|
||||||
# AC_TYPE_OFF_T
|
|
||||||
# AC_TYPE_PID_T
|
|
||||||
# AC_TYPE_UID_T
|
|
||||||
# XXX To support inline for crappy compilers, see https://cmake.org/Wiki/CMakeTestInline
|
|
||||||
# AC_C_INLINE
|
|
||||||
# XXX is AC_SYS_LARGEFILE still needed for modern systems?
|
|
||||||
# add_definitions(-D_FILE_OFFSET_BITS=64)
|
|
||||||
|
|
||||||
include(CheckStructHasMember)
|
|
||||||
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
|
|
||||||
|
|
||||||
# Check size of pointer to decide we need 8 bytes alignment adjustment.
|
|
||||||
check_type_size("int *" SIZEOF_INT_P)
|
|
||||||
check_type_size("time_t" SIZEOF_TIME_T)
|
|
||||||
|
|
||||||
# Checks for library functions.
|
|
||||||
include(CheckFunctionExists)
|
|
||||||
check_function_exists(_Exit HAVE__EXIT)
|
|
||||||
check_function_exists(accept4 HAVE_ACCEPT4)
|
|
||||||
|
|
||||||
include(CheckSymbolExists)
|
|
||||||
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
|
||||||
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
|
|
||||||
if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
|
|
||||||
# FreeBSD declares initgroups() in unistd.h
|
|
||||||
check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2)
|
|
||||||
if(HAVE_DECL_INITGROUPS2)
|
|
||||||
set(HAVE_DECL_INITGROUPS 1)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(WARNCFLAGS)
|
|
||||||
set(WARNCXXFLAGS)
|
|
||||||
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
|
||||||
if(ENABLE_WERROR)
|
|
||||||
set(WARNCFLAGS /WX)
|
|
||||||
set(WARNCXXFLAGS /WX)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
if(ENABLE_WERROR)
|
|
||||||
extract_valid_c_flags(WARNCFLAGS -Werror)
|
|
||||||
extract_valid_c_flags(WARNCXXFLAGS -Werror)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# For C compiler
|
|
||||||
extract_valid_c_flags(WARNCFLAGS
|
|
||||||
-Wall
|
|
||||||
-Wextra
|
|
||||||
-Wmissing-prototypes
|
|
||||||
-Wstrict-prototypes
|
|
||||||
-Wmissing-declarations
|
|
||||||
-Wpointer-arith
|
|
||||||
-Wdeclaration-after-statement
|
|
||||||
-Wformat-security
|
|
||||||
-Wwrite-strings
|
|
||||||
-Wshadow
|
|
||||||
-Winline
|
|
||||||
-Wnested-externs
|
|
||||||
-Wfloat-equal
|
|
||||||
-Wundef
|
|
||||||
-Wendif-labels
|
|
||||||
-Wempty-body
|
|
||||||
-Wcast-align
|
|
||||||
-Wclobbered
|
|
||||||
-Wvla
|
|
||||||
-Wpragmas
|
|
||||||
-Wunreachable-code
|
|
||||||
-Waddress
|
|
||||||
-Wattributes
|
|
||||||
-Wdiv-by-zero
|
|
||||||
-Wshorten-64-to-32
|
|
||||||
|
|
||||||
-Wconversion
|
|
||||||
-Wextended-offsetof
|
|
||||||
-Wformat-nonliteral
|
|
||||||
-Wlanguage-extension-token
|
|
||||||
-Wmissing-field-initializers
|
|
||||||
-Wmissing-noreturn
|
|
||||||
-Wmissing-variable-declarations
|
|
||||||
# Not used because we cannot change public structs
|
|
||||||
# -Wpadded
|
|
||||||
-Wsign-conversion
|
|
||||||
# Not used because this basically disallows default case
|
|
||||||
# -Wswitch-enum
|
|
||||||
-Wunreachable-code-break
|
|
||||||
-Wunused-macros
|
|
||||||
-Wunused-parameter
|
|
||||||
-Wredundant-decls
|
|
||||||
# Only work with Clang for the moment
|
|
||||||
-Wheader-guard
|
|
||||||
# This is required because we pass format string as "const char*.
|
|
||||||
-Wno-format-nonliteral
|
|
||||||
)
|
|
||||||
|
|
||||||
extract_valid_cxx_flags(WARNCXXFLAGS
|
|
||||||
# For C++ compiler
|
|
||||||
-Wall
|
|
||||||
-Wformat-security
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_DEBUG)
|
|
||||||
set(DEBUGBUILD 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Some platform does not have working std::future. We disable
|
|
||||||
# threading for those platforms.
|
|
||||||
if(NOT ENABLE_THREADS OR NOT HAVE_STD_FUTURE)
|
|
||||||
set(NOTHREADS 1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
|
||||||
configure_file(cmakeconfig.h.in config.h)
|
|
||||||
# autotools-compatible names
|
|
||||||
# Sphinx expects relative paths in the .rst files. Use the fact that the files
|
|
||||||
# below are all one directory level deep.
|
|
||||||
file(RELATIVE_PATH top_srcdir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
||||||
file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
||||||
set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
# libnghttp2.pc (pkg-config file)
|
|
||||||
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
|
|
||||||
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
|
||||||
set(VERSION "${PACKAGE_VERSION}")
|
|
||||||
# For init scripts and systemd service file (in contrib/)
|
|
||||||
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
|
|
||||||
set(sbindir "${CMAKE_INSTALL_FULL_SBINDIR}")
|
|
||||||
foreach(name
|
|
||||||
lib/libnghttp2.pc
|
|
||||||
lib/includes/nghttp2/nghttp2ver.h
|
|
||||||
src/libnghttp2_asio.pc
|
|
||||||
python/setup.py
|
|
||||||
integration-tests/config.go
|
|
||||||
integration-tests/setenv
|
|
||||||
doc/conf.py
|
|
||||||
doc/index.rst
|
|
||||||
doc/package_README.rst
|
|
||||||
doc/tutorial-client.rst
|
|
||||||
doc/tutorial-server.rst
|
|
||||||
doc/tutorial-hpack.rst
|
|
||||||
doc/nghttpx-howto.rst
|
|
||||||
doc/h2load-howto.rst
|
|
||||||
doc/libnghttp2_asio.rst
|
|
||||||
doc/python-apiref.rst
|
|
||||||
doc/building-android-binary.rst
|
|
||||||
doc/nghttp2.h.rst
|
|
||||||
doc/nghttp2ver.h.rst
|
|
||||||
doc/asio_http2.h.rst
|
|
||||||
doc/asio_http2_server.h.rst
|
|
||||||
doc/asio_http2_client.h.rst
|
|
||||||
doc/contribute.rst
|
|
||||||
)
|
|
||||||
configure_file("${name}.in" "${name}" @ONLY)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
include_directories(
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
|
||||||
)
|
|
||||||
# For use in src/CMakeLists.txt
|
|
||||||
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
|
|
||||||
|
|
||||||
install(FILES README.rst DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
|
||||||
|
|
||||||
add_subdirectory(lib)
|
|
||||||
#add_subdirectory(lib/includes)
|
|
||||||
add_subdirectory(third-party)
|
|
||||||
add_subdirectory(src)
|
|
||||||
#add_subdirectory(src/includes)
|
|
||||||
add_subdirectory(examples)
|
|
||||||
add_subdirectory(python)
|
|
||||||
add_subdirectory(tests)
|
|
||||||
#add_subdirectory(tests/testdata)
|
|
||||||
add_subdirectory(integration-tests)
|
|
||||||
add_subdirectory(doc)
|
|
||||||
add_subdirectory(contrib)
|
|
||||||
add_subdirectory(script)
|
|
||||||
|
|
||||||
|
|
||||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
|
|
||||||
message(STATUS "summary of build options:
|
|
||||||
|
|
||||||
Package version: ${VERSION}
|
|
||||||
Library version: ${LT_CURRENT}:${LT_REVISION}:${LT_AGE}
|
|
||||||
Install prefix: ${CMAKE_INSTALL_PREFIX}
|
|
||||||
Target system: ${CMAKE_SYSTEM_NAME}
|
|
||||||
Compiler:
|
|
||||||
Build type: ${CMAKE_BUILD_TYPE}
|
|
||||||
C compiler: ${CMAKE_C_COMPILER}
|
|
||||||
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
|
|
||||||
C++ compiler: ${CMAKE_CXX_COMPILER}
|
|
||||||
CXXFLAGS: ${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
|
|
||||||
WARNCFLAGS: ${WARNCFLAGS}
|
|
||||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
|
||||||
Python:
|
|
||||||
Python: ${PYTHON_EXECUTABLE}
|
|
||||||
PYTHON_VERSION: ${PYTHON_VERSION_STRING}
|
|
||||||
Library version:${PYTHONLIBS_VERSION_STRING}
|
|
||||||
Cython: ${CYTHON_EXECUTABLE}
|
|
||||||
Test:
|
|
||||||
CUnit: ${HAVE_CUNIT} (LIBS='${CUNIT_LIBRARIES}')
|
|
||||||
Failmalloc: ${ENABLE_FAILMALLOC}
|
|
||||||
Libs:
|
|
||||||
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
|
|
||||||
Libxml2: ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
|
|
||||||
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
|
|
||||||
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
|
|
||||||
Libevent(SSL): ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
|
|
||||||
Spdylay: ${HAVE_SPDYLAY} (LIBS='${SPDYLAY_LIBRARIES}')
|
|
||||||
Jansson: ${HAVE_JANSSON} (LIBS='${JANSSON_LIBRARIES}')
|
|
||||||
Jemalloc: ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
|
|
||||||
Zlib: ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
|
|
||||||
Boost::System: ${Boost_SYSTEM_LIBRARY}
|
|
||||||
Boost::Thread: ${Boost_THREAD_LIBRARY}
|
|
||||||
Third-party:
|
|
||||||
http-parser: ${ENABLE_THIRD_PARTY}
|
|
||||||
MRuby: ${HAVE_MRUBY}
|
|
||||||
Neverbleed: ${HAVE_NEVERBLEED}
|
|
||||||
Features:
|
|
||||||
Applications: ${ENABLE_APP}
|
|
||||||
HPACK tools: ${ENABLE_HPACK_TOOLS}
|
|
||||||
Libnghttp2_asio:${ENABLE_ASIO_LIB}
|
|
||||||
Examples: ${ENABLE_EXAMPLES}
|
|
||||||
Python bindings:${ENABLE_PYTHON_BINDINGS}
|
|
||||||
Threading: ${ENABLE_THREADS}
|
|
||||||
")
|
|
||||||
if(ENABLE_LIB_ONLY_DISABLED_OTHERS)
|
|
||||||
message("Only the library will be built. To build other components "
|
|
||||||
"(such as applications and examples), set ENABLE_LIB_ONLY=OFF.")
|
|
||||||
endif()
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Features that can be enabled for cmake (see CMakeLists.txt)
|
|
||||||
|
|
||||||
option(ENABLE_WERROR "Turn on compile time warnings")
|
|
||||||
option(ENABLE_DEBUG "Turn on debug output")
|
|
||||||
option(ENABLE_THREADS "Turn on threading in apps" ON)
|
|
||||||
option(ENABLE_APP "Build applications (nghttp, nghttpd, nghttpx and h2load)"
|
|
||||||
${ENABLE_APP_DEFAULT})
|
|
||||||
option(ENABLE_HPACK_TOOLS "Build HPACK tools"
|
|
||||||
${ENABLE_HPACK_TOOLS_DEFAULT})
|
|
||||||
option(ENABLE_ASIO_LIB "Build C++ libnghttp2_asio library")
|
|
||||||
option(ENABLE_EXAMPLES "Build examples"
|
|
||||||
${ENABLE_EXAMPLES_DEFAULT})
|
|
||||||
option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
|
|
||||||
${ENABLE_PYTHON_BINDINGS_DEFAULT})
|
|
||||||
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
|
|
||||||
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
|
|
||||||
|
|
||||||
option(WITH_LIBXML2 "Use libxml2"
|
|
||||||
${WITH_LIBXML2_DEFAULT})
|
|
||||||
option(WITH_JEMALLOC "Use jemalloc"
|
|
||||||
${WITH_JEMALLOC_DEFAULT})
|
|
||||||
option(WITH_SPDYLAY "Use spdylay"
|
|
||||||
${WITH_SPDYLAY_DEFAULT})
|
|
||||||
option(WITH_MRUBY "Use mruby")
|
|
||||||
option(WITH_NEVERBLEED "Use neverbleed")
|
|
||||||
|
|
||||||
# vim: ft=cmake:
|
|
||||||
1
COPYING
1
COPYING
@@ -1,7 +1,6 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
|
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
|
||||||
Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ RUN HOST=arm-linux-androideabi \
|
|||||||
make install
|
make install
|
||||||
|
|
||||||
WORKDIR /root/build
|
WORKDIR /root/build
|
||||||
RUN git clone https://github.com/nghttp2/nghttp2
|
RUN git clone https://github.com/tatsuhiro-t/nghttp2
|
||||||
WORKDIR /root/build/nghttp2
|
WORKDIR /root/build/nghttp2
|
||||||
RUN autoreconf -i && \
|
RUN autoreconf -i && \
|
||||||
./configure \
|
./configure \
|
||||||
|
|||||||
19
Makefile.am
19
Makefile.am
@@ -33,20 +33,7 @@ ACLOCAL_AMFLAGS = -I m4
|
|||||||
dist_doc_DATA = README.rst
|
dist_doc_DATA = README.rst
|
||||||
|
|
||||||
EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
|
EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
|
||||||
Dockerfile.android \
|
Dockerfile.android
|
||||||
cmakeconfig.h.in \
|
|
||||||
CMakeLists.txt \
|
|
||||||
CMakeOptions.txt \
|
|
||||||
cmake/FindSpdylay.cmake \
|
|
||||||
cmake/ExtractValidFlags.cmake \
|
|
||||||
cmake/FindJemalloc.cmake \
|
|
||||||
cmake/FindLibev.cmake \
|
|
||||||
cmake/FindCUnit.cmake \
|
|
||||||
cmake/Version.cmake \
|
|
||||||
cmake/FindCython.cmake \
|
|
||||||
cmake/FindLibevent.cmake \
|
|
||||||
cmake/FindJansson.cmake \
|
|
||||||
cmake/FindLibcares.cmake
|
|
||||||
|
|
||||||
.PHONY: clang-format
|
.PHONY: clang-format
|
||||||
|
|
||||||
@@ -56,6 +43,8 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
|
|||||||
clang-format:
|
clang-format:
|
||||||
CLANGFORMAT=`git config --get clangformat.binary`; \
|
CLANGFORMAT=`git config --get clangformat.binary`; \
|
||||||
test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
|
test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
|
||||||
$${CLANGFORMAT} -i lib/*.{c,h} lib/includes/nghttp2/*.h \
|
$${CLANGFORMAT} -i \
|
||||||
|
`ls lib/*.{c,h} | grep -v nghttp2_hd_huffman_data.c` \
|
||||||
|
lib/includes/nghttp2/*.h \
|
||||||
src/*.{c,cc,h} src/includes/nghttp2/*.h examples/*.{c,cc} \
|
src/*.{c,cc,h} src/includes/nghttp2/*.h examples/*.{c,cc} \
|
||||||
tests/*.{c,h}
|
tests/*.{c,h}
|
||||||
|
|||||||
221
README.rst
221
README.rst
@@ -58,19 +58,13 @@ To build the documentation, you need to install:
|
|||||||
|
|
||||||
* sphinx (http://sphinx-doc.org/)
|
* sphinx (http://sphinx-doc.org/)
|
||||||
|
|
||||||
If you need libnghttp2 (C library) only, then the above packages are
|
To build and run the application programs (``nghttp``, ``nghttpd`` and
|
||||||
all you need. Use ``--enable-lib-only`` to ensure that only
|
``nghttpx``) in the ``src`` directory, the following packages are
|
||||||
libnghttp2 is built. This avoids potential build error related to
|
required:
|
||||||
building bundled applications.
|
|
||||||
|
|
||||||
To build and run the application programs (``nghttp``, ``nghttpd``,
|
|
||||||
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
|
|
||||||
are required:
|
|
||||||
|
|
||||||
* OpenSSL >= 1.0.1
|
* OpenSSL >= 1.0.1
|
||||||
* libev >= 4.11
|
* libev >= 4.15
|
||||||
* zlib >= 1.2.3
|
* zlib >= 1.2.3
|
||||||
* libc-ares >= 1.7.5
|
|
||||||
|
|
||||||
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
|
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
|
||||||
@@ -110,17 +104,14 @@ The Python bindings require the following packages:
|
|||||||
* python >= 2.7
|
* python >= 2.7
|
||||||
* python-setuptools
|
* python-setuptools
|
||||||
|
|
||||||
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages:
|
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
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 cython python3-dev python-setuptools
|
libjemalloc-dev cython python3-dev python-setuptools
|
||||||
|
|
||||||
From Ubuntu 15.10, spdylay has been available as a package named
|
spdylay is not packaged in Ubuntu, so you need to build it yourself:
|
||||||
`libspdylay-dev`. For the earlier Ubuntu release, you need to build
|
http://tatsuhiro-t.github.io/spdylay/
|
||||||
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
|
||||||
@@ -146,11 +137,8 @@ Building from git
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Building from git is easy, but please be sure that at least autoconf 2.68 is
|
Building from git is easy, but please be sure that at least autoconf 2.68 is
|
||||||
used:
|
used::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ git submodule update --init
|
|
||||||
$ autoreconf -i
|
$ autoreconf -i
|
||||||
$ automake
|
$ automake
|
||||||
$ autoconf
|
$ autoconf
|
||||||
@@ -161,7 +149,8 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
To enable mruby support in nghttpx, and use ``--with-mruby``
|
To enable mruby support in nghttpx, run ``git submodule update
|
||||||
|
--init`` before running configure script, and use ``--with-mruby``
|
||||||
configure option.
|
configure option.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@@ -171,34 +160,6 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
|||||||
them from crashing. A patch is welcome to make multi threading work
|
them from crashing. A patch is welcome to make multi threading work
|
||||||
on Mac OS X platform.
|
on Mac OS X platform.
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
To compile the associated applications (nghttp, nghttpd, nghttpx
|
|
||||||
and h2load), you must use the ``--enable-app`` configure option and
|
|
||||||
ensure that the specified requirements above are met. Normally,
|
|
||||||
configure script checks required dependencies to build these
|
|
||||||
applications, and enable ``--enable-app`` automatically, so you
|
|
||||||
don't have to use it explicitly. But if you found that
|
|
||||||
applications were not built, then using ``--enable-app`` may find
|
|
||||||
that cause, such as the missing dependency.
|
|
||||||
|
|
||||||
Notes for building on Windows (MSVC)
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
The easiest way to build native Windows nghttp2 dll is use `cmake
|
|
||||||
<https://cmake.org/>`_. The free version of `Visual C++ Build Tools
|
|
||||||
<http://landinghub.visualstudio.com/visual-cpp-build-tools>`_ works
|
|
||||||
fine.
|
|
||||||
|
|
||||||
1. Install cmake for windows
|
|
||||||
2. Open "Visual C++ ... Native Build Tool Command Prompt", and inside
|
|
||||||
nghttp2 directly, run ``cmake``.
|
|
||||||
3. Then run ``cmake --build`` to build library.
|
|
||||||
4. nghttp2.dll, nghttp2.lib, nghttp2.exp are placed under lib directory.
|
|
||||||
|
|
||||||
Note that the above steps most likely produce nghttp2 library only.
|
|
||||||
No bundled applications are compiled.
|
|
||||||
|
|
||||||
Notes for building on Windows (Mingw/Cygwin)
|
Notes for building on Windows (Mingw/Cygwin)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
@@ -215,9 +176,7 @@ Secondly, you need to undefine the macro ``__STRICT_ANSI__``, if you
|
|||||||
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
|
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
|
||||||
available.
|
available.
|
||||||
|
|
||||||
the sample command like this:
|
the sample command like this::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ export CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
|
$ export CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
|
||||||
$ export CXXFLAGS=$CFLAGS
|
$ export CXXFLAGS=$CFLAGS
|
||||||
@@ -235,9 +194,7 @@ Building the documentation
|
|||||||
|
|
||||||
Documentation is still incomplete.
|
Documentation is still incomplete.
|
||||||
|
|
||||||
To build the documentation, run:
|
To build the documentation, run::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ make html
|
$ make html
|
||||||
|
|
||||||
@@ -266,16 +223,12 @@ its testing framework. We depend on the following libraries:
|
|||||||
* https://github.com/tatsuhiro-t/spdy
|
* 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::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ make itprep
|
$ make itprep
|
||||||
|
|
||||||
To run the tests, run the following command under
|
To run the tests, run the following command under
|
||||||
``integration-tests`` directory:
|
``integration-tests`` directory::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ make it
|
$ make it
|
||||||
|
|
||||||
@@ -396,9 +349,7 @@ nghttp - client
|
|||||||
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
|
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
|
||||||
|
|
||||||
It has verbose output mode for framing information. Here is sample
|
It has verbose output mode for framing information. Here is sample
|
||||||
output from ``nghttp`` client:
|
output from ``nghttp`` client::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ nghttp -nv https://nghttp2.org
|
$ nghttp -nv https://nghttp2.org
|
||||||
[ 0.190] Connected
|
[ 0.190] Connected
|
||||||
@@ -481,9 +432,7 @@ output from ``nghttp`` client:
|
|||||||
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
|
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
|
||||||
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
||||||
|
|
||||||
The HTTP Upgrade is performed like so:
|
The HTTP Upgrade is performed like so::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ nghttp -nvu http://nghttp2.org
|
$ nghttp -nvu http://nghttp2.org
|
||||||
[ 0.011] Connected
|
[ 0.011] Connected
|
||||||
@@ -579,9 +528,7 @@ The HTTP Upgrade is performed like so:
|
|||||||
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
||||||
|
|
||||||
Using the ``-s`` option, ``nghttp`` prints out some timing information for
|
Using the ``-s`` option, ``nghttp`` prints out some timing information for
|
||||||
requests, sorted by completion time:
|
requests, sorted by completion time::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ nghttp -nas https://nghttp2.org/
|
$ nghttp -nas https://nghttp2.org/
|
||||||
***** Statistics *****
|
***** Statistics *****
|
||||||
@@ -625,9 +572,7 @@ HTTP/2 connections. No HTTP Upgrade is supported.
|
|||||||
The ``-p`` option allows users to configure server push.
|
The ``-p`` option allows users to configure server push.
|
||||||
|
|
||||||
Just like ``nghttp``, it has a verbose output mode for framing
|
Just like ``nghttp``, it has a verbose output mode for framing
|
||||||
information. Here is sample output from ``nghttpd``:
|
information. Here is sample output from ``nghttpd``::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ nghttpd --no-tls -v 8080
|
$ nghttpd --no-tls -v 8080
|
||||||
IPv4: listen 0.0.0.0:8080
|
IPv4: listen 0.0.0.0:8080
|
||||||
@@ -690,14 +635,6 @@ nghttpx - proxy
|
|||||||
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.
|
||||||
|
|
||||||
We reworked ``nghttpx`` command-line interface, and as a result, there
|
|
||||||
are several incompatibles from 1.8.0 or earlier. This is necessary to
|
|
||||||
extend its capability, and secure the further feature enhancements in
|
|
||||||
the future release. Please read `Migration from nghttpx v1.8.0 or
|
|
||||||
earlier
|
|
||||||
<https://nghttp2.org/documentation/nghttpx-howto.html#migration-from-nghttpx-v1-8-0-or-earlier>`_
|
|
||||||
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
|
||||||
@@ -706,42 +643,46 @@ HTTP/2. ``nghttpx`` also offers the functionality to share session
|
|||||||
cache and ticket keys among multiple ``nghttpx`` instances via
|
cache and ticket keys among multiple ``nghttpx`` instances via
|
||||||
memcached.
|
memcached.
|
||||||
|
|
||||||
``nghttpx`` has 2 operation modes:
|
``nghttpx`` has several operational modes:
|
||||||
|
|
||||||
================== ====================== ================ =============
|
================== ============================ ============== =============
|
||||||
Mode option Frontend Backend Note
|
Mode option Frontend Backend Note
|
||||||
================== ====================== ================ =============
|
================== ============================ ============== =============
|
||||||
default mode HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
|
default mode HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 Reverse proxy
|
||||||
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
|
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 SPDY proxy
|
||||||
================== ====================== ================ =============
|
``--http2-bridge`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/2 (TLS)
|
||||||
|
``--client`` HTTP/2, HTTP/1.1 HTTP/2 (TLS)
|
||||||
|
``--client-proxy`` HTTP/2, HTTP/1.1 HTTP/2 (TLS) 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, SPDY 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
|
The default mode, ``--http2-proxy`` and ``--http2-bridge`` modes use
|
||||||
default. To disable encryption, use the ``no-tls`` keyword in
|
SSL/TLS in the frontend connection by default. To disable SSL/TLS,
|
||||||
``--frontend`` option. If encryption is disabled, SPDY is disabled in
|
use the ``--frontend-no-tls`` option. If that option is used, SPDY is
|
||||||
the frontend and incoming HTTP/1.1 connections can be upgraded to
|
disabled in the frontend and incoming HTTP/1.1 connections can be
|
||||||
HTTP/2 through HTTP Upgrade. On the other hard, backend connections
|
upgraded to HTTP/2 through HTTP Upgrade. In these modes, HTTP/1
|
||||||
are not encrypted by default. To encrypt backend connections, use
|
backend connections are cleartext by default. To enable TLS, use
|
||||||
``tls`` keyword in ``--backend`` option.
|
``--backend-http1-tls`` opiton.
|
||||||
|
|
||||||
|
The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use
|
||||||
|
SSL/TLS in the backend connection by default. To disable SSL/TLS, use
|
||||||
|
the ``--backend-no-tls`` 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``.
|
||||||
|
|
||||||
In the default mode, ``nghttpx`` works as reverse proxy to the backend
|
In the default mode, (without any of ``--http2-proxy``,
|
||||||
server:
|
``--http2-bridge``, ``--client-proxy`` and ``--client`` options),
|
||||||
|
``nghttpx`` works as reverse proxy to the backend server::
|
||||||
|
|
||||||
.. code-block:: text
|
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> 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 a so called secure proxy (aka
|
||||||
is so called secure HTTP/2 proxy (aka SPDY proxy):
|
SPDY proxy)::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
Client <-- (HTTP/2, SPDY, 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)
|
||||||
@@ -749,9 +690,9 @@ is so called secure HTTP/2 proxy (aka SPDY proxy):
|
|||||||
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.
|
||||||
|
|
||||||
At the time of this writing, both Chrome and Firefox support secure
|
At the time of this writing, Chrome is the only browser which supports
|
||||||
HTTP/2 proxy. One way to configure Chrome to use a secure proxy is to
|
secure proxy. One way to configure Chrome to use a secure proxy is
|
||||||
create a proxy.pac script like this:
|
to create a proxy.pac script like this:
|
||||||
|
|
||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
@@ -763,18 +704,42 @@ create a proxy.pac script like this:
|
|||||||
machine nghttpx is running on. Please note that Chrome requires a valid
|
machine nghttpx is running on. Please note that Chrome requires a valid
|
||||||
certificate for secure proxy.
|
certificate for secure proxy.
|
||||||
|
|
||||||
Then run Chrome with the following arguments:
|
Then run Chrome with the following arguments::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||||
|
|
||||||
The backend HTTP/2 connections can be tunneled through an HTTP proxy.
|
With ``--http2-bridge``, it accepts HTTP/2, SPDY and HTTP/1.1
|
||||||
The proxy is specified using ``--backend-http-proxy-uri``. The
|
connections and communicates with the backend in HTTP/2::
|
||||||
following figure illustrates how nghttpx talks to the outside HTTP/2
|
|
||||||
proxy through an HTTP proxy:
|
|
||||||
|
|
||||||
.. code-block:: text
|
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web or HTTP/2 Proxy etc
|
||||||
|
(e.g., nghttpx -s)
|
||||||
|
|
||||||
|
With ``--client-proxy``, it works as a forward proxy and expects
|
||||||
|
that the backend is an HTTP/2 proxy::
|
||||||
|
|
||||||
|
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> HTTP/2 Proxy
|
||||||
|
[forward proxy] (e.g., nghttpx -s)
|
||||||
|
|
||||||
|
The ``Client`` needs to be configured to use nghttpx as a forward
|
||||||
|
proxy. The frontend HTTP/1.1 connection can be upgraded to HTTP/2
|
||||||
|
through HTTP Upgrade. With the above configuration, one can use
|
||||||
|
HTTP/1.1 client to access and test their HTTP/2 servers.
|
||||||
|
|
||||||
|
With ``--client``, it works as a reverse proxy and expects that
|
||||||
|
the backend is an HTTP/2 Web server::
|
||||||
|
|
||||||
|
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web Server
|
||||||
|
[reverse proxy]
|
||||||
|
|
||||||
|
The frontend HTTP/1.1 connection can be upgraded to HTTP/2
|
||||||
|
through HTTP Upgrade.
|
||||||
|
|
||||||
|
For the operation modes which talk to the backend in HTTP/2 over
|
||||||
|
SSL/TLS, the backend connections can be tunneled through an HTTP proxy.
|
||||||
|
The proxy is specified using ``--backend-http-proxy-uri``. The
|
||||||
|
following figure illustrates the example of the ``--http2-bridge`` and
|
||||||
|
``--backend-http-proxy-uri`` options to talk to the outside HTTP/2
|
||||||
|
proxy through an HTTP proxy::
|
||||||
|
|
||||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
|
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
|
||||||
|
|
||||||
@@ -788,9 +753,7 @@ The ``h2load`` program is a benchmarking tool for HTTP/2 and SPDY.
|
|||||||
The SPDY support is enabled if the program was built with the spdylay
|
The SPDY support is enabled if the program was built with the spdylay
|
||||||
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
|
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::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ h2load -n100000 -c100 -m100 https://localhost:8443/
|
$ h2load -n100000 -c100 -m100 https://localhost:8443/
|
||||||
starting benchmark...
|
starting benchmark...
|
||||||
@@ -878,9 +841,7 @@ Example:
|
|||||||
With the ``-t`` option, the program can accept more familiar HTTP/1 style
|
With the ``-t`` option, the program can accept more familiar HTTP/1 style
|
||||||
header field blocks. Each header set is delimited by an empty line:
|
header field blocks. Each header set is delimited by an empty line:
|
||||||
|
|
||||||
Example:
|
Example::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
:method: GET
|
:method: GET
|
||||||
:scheme: https
|
:scheme: https
|
||||||
@@ -1376,7 +1337,7 @@ The extension module is called ``nghttp2``.
|
|||||||
determined by the ``configure`` script. If the detected Python version is not
|
determined by the ``configure`` script. If the detected Python version is not
|
||||||
what you expect, specify a path to Python executable in a ``PYTHON``
|
what you expect, specify a path to Python executable in a ``PYTHON``
|
||||||
variable as an argument to configure script (e.g., ``./configure
|
variable as an argument to configure script (e.g., ``./configure
|
||||||
PYTHON=/usr/bin/python3.5``).
|
PYTHON=/usr/bin/python3.4``).
|
||||||
|
|
||||||
The following example code illustrates basic usage of the HPACK compressor
|
The following example code illustrates basic usage of the HPACK compressor
|
||||||
and decompressor in Python:
|
and decompressor in Python:
|
||||||
@@ -1506,17 +1467,6 @@ See `Contribution Guidelines
|
|||||||
<https://nghttp2.org/documentation/contribute.html>`_ for more
|
<https://nghttp2.org/documentation/contribute.html>`_ for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
Reporting vulnerability
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
If you find a vulnerability in our software, please send the email to
|
|
||||||
"tatsuhiro.t at gmail dot com" about its details instead of submitting
|
|
||||||
issues on github issue page. It is a standard practice not to
|
|
||||||
disclose vulnerability information publicly until a fixed version is
|
|
||||||
released, or mitigation is worked out.
|
|
||||||
|
|
||||||
In the future, we may setup a dedicated mail address for this purpose.
|
|
||||||
|
|
||||||
Release schedule
|
Release schedule
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@@ -1529,8 +1479,3 @@ severe security bug fixes.
|
|||||||
|
|
||||||
We have no plan to break API compatibility changes involving soname
|
We have no plan to break API compatibility changes involving soname
|
||||||
bump, so MAJOR version will stay 1 for the foreseeable future.
|
bump, so MAJOR version will stay 1 for the foreseeable future.
|
||||||
|
|
||||||
License
|
|
||||||
-------
|
|
||||||
|
|
||||||
The MIT License
|
|
||||||
|
|||||||
@@ -39,8 +39,9 @@ PATH="$TOOLCHAIN"/bin:"$PATH"
|
|||||||
--without-libxml2 \
|
--without-libxml2 \
|
||||||
--disable-python-bindings \
|
--disable-python-bindings \
|
||||||
--disable-examples \
|
--disable-examples \
|
||||||
CC="$TOOLCHAIN"/bin/arm-linux-androideabi-gcc \
|
--enable-werror \
|
||||||
CXX="$TOOLCHAIN"/bin/arm-linux-androideabi-g++ \
|
CC="$TOOLCHAIN"/bin/clang \
|
||||||
|
CXX="$TOOLCHAIN"/bin/clang++ \
|
||||||
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
||||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||||
LDFLAGS="-fPIE -pie -L$PREFIX/lib"
|
LDFLAGS="-fPIE -pie -L$PREFIX/lib"
|
||||||
|
|||||||
53
appveyor.yml
53
appveyor.yml
@@ -1,53 +0,0 @@
|
|||||||
# Notes:
|
|
||||||
# - Minimal appveyor.yml file is an empty file. All sections are optional.
|
|
||||||
# - Indent each level of configuration with 2 spaces. Do not use tabs!
|
|
||||||
# - All section names are case-sensitive.
|
|
||||||
# - Section names should be unique on each level.
|
|
||||||
|
|
||||||
#---------------------------------#
|
|
||||||
# general configuration #
|
|
||||||
#---------------------------------#
|
|
||||||
|
|
||||||
# version format
|
|
||||||
#version: 0.10.{build}
|
|
||||||
|
|
||||||
# branches to build
|
|
||||||
branches:
|
|
||||||
# blacklist
|
|
||||||
except:
|
|
||||||
- gh-pages
|
|
||||||
|
|
||||||
# Do not build on tags (GitHub only)
|
|
||||||
skip_tags: true
|
|
||||||
|
|
||||||
#---------------------------------#
|
|
||||||
# environment configuration #
|
|
||||||
#---------------------------------#
|
|
||||||
|
|
||||||
os: Windows Server 2012
|
|
||||||
|
|
||||||
# scripts that run after cloning repository
|
|
||||||
install:
|
|
||||||
# install Win-Flex-Bison
|
|
||||||
#- cmd: cinst winflexbison -y
|
|
||||||
|
|
||||||
#---------------------------------#
|
|
||||||
# build configuration #
|
|
||||||
#---------------------------------#
|
|
||||||
|
|
||||||
# scripts to run before build
|
|
||||||
before_build:
|
|
||||||
- cmd: cmake .
|
|
||||||
|
|
||||||
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
|
|
||||||
# before_package:
|
|
||||||
|
|
||||||
# scripts to run after build
|
|
||||||
# after_build:
|
|
||||||
|
|
||||||
# to run your custom scripts instead of automatic MSBuild
|
|
||||||
build_script:
|
|
||||||
- cmd: cmake --build .
|
|
||||||
|
|
||||||
# to disable automatic builds
|
|
||||||
# build: off
|
|
||||||
52
author.py
52
author.py
@@ -1,52 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# script to extract commit author's name from standard input. The
|
|
||||||
# input should be <AUTHOR>:<EMAIL>, one per line.
|
|
||||||
# This script expects the input is created by git-log command:
|
|
||||||
#
|
|
||||||
# git log --format=%aN:%aE
|
|
||||||
#
|
|
||||||
# This script removes duplicates based on email address, breaking a
|
|
||||||
# tie with longer author name. Among the all author names extract the
|
|
||||||
# previous step, we remove duplicate by case-insensitive match.
|
|
||||||
#
|
|
||||||
# So we can do this in one line:
|
|
||||||
#
|
|
||||||
# git log --format=%aN:%aE | sort | uniq | ./author.py > authors
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
edict = {}
|
|
||||||
|
|
||||||
for line in sys.stdin:
|
|
||||||
author, email = line.strip().split(':', 1)
|
|
||||||
if email in edict:
|
|
||||||
an = edict[email]
|
|
||||||
if len(an) < len(author) or an > author:
|
|
||||||
sys.stderr.write(
|
|
||||||
'eliminated {} in favor of {}\n'.format(an, author))
|
|
||||||
edict[email] = author
|
|
||||||
else:
|
|
||||||
sys.stderr.write(
|
|
||||||
'eliminated {} in favor of {}\n'.format(author, an))
|
|
||||||
else:
|
|
||||||
edict[email] = author
|
|
||||||
|
|
||||||
names = list(sorted(edict.values()))
|
|
||||||
|
|
||||||
ndict = {}
|
|
||||||
|
|
||||||
for name in names:
|
|
||||||
lowname = name.lower()
|
|
||||||
if lowname in ndict:
|
|
||||||
an = ndict[lowname]
|
|
||||||
if an > name:
|
|
||||||
sys.stderr.write('eliminated {} in favor of {}\n'.format(an, name))
|
|
||||||
ndict[lowname] = name
|
|
||||||
else:
|
|
||||||
sys.stderr.write('eliminated {} in favor of {}\n'.format(name, an))
|
|
||||||
else:
|
|
||||||
ndict[lowname] = name
|
|
||||||
|
|
||||||
for name in sorted(ndict.values()):
|
|
||||||
print name
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
# Convenience function that checks the availability of certain
|
|
||||||
# C or C++ compiler flags and returns valid ones as a string.
|
|
||||||
|
|
||||||
include(CheckCCompilerFlag)
|
|
||||||
include(CheckCXXCompilerFlag)
|
|
||||||
|
|
||||||
function(extract_valid_c_flags varname)
|
|
||||||
set(valid_flags)
|
|
||||||
foreach(flag IN LISTS ARGN)
|
|
||||||
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
|
|
||||||
set(flag_var "C_FLAG_${flag_var}")
|
|
||||||
check_c_compiler_flag("${flag}" "${flag_var}")
|
|
||||||
if(${flag_var})
|
|
||||||
set(valid_flags "${valid_flags} ${flag}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
set(${varname} "${valid_flags}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(extract_valid_cxx_flags varname)
|
|
||||||
set(valid_flags)
|
|
||||||
foreach(flag IN LISTS ARGN)
|
|
||||||
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
|
|
||||||
set(flag_var "CXX_FLAG_${flag_var}")
|
|
||||||
check_cxx_compiler_flag("${flag}" "${flag_var}")
|
|
||||||
if(${flag_var})
|
|
||||||
set(valid_flags "${valid_flags} ${flag}")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
set(${varname} "${valid_flags}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# - Try to find cunit
|
|
||||||
# Once done this will define
|
|
||||||
# CUNIT_FOUND - System has cunit
|
|
||||||
# CUNIT_INCLUDE_DIRS - The cunit include directories
|
|
||||||
# CUNIT_LIBRARIES - The libraries needed to use cunit
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_check_modules(PC_CUNIT QUIET cunit)
|
|
||||||
|
|
||||||
find_path(CUNIT_INCLUDE_DIR
|
|
||||||
NAMES CUnit/CUnit.h
|
|
||||||
HINTS ${PC_CUNIT_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
find_library(CUNIT_LIBRARY
|
|
||||||
NAMES cunit
|
|
||||||
HINTS ${PC_CUNIT_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(CUNIT_INCLUDE_DIR)
|
|
||||||
set(_version_regex "^#define[ \t]+CU_VERSION[ \t]+\"([^\"]+)\".*")
|
|
||||||
file(STRINGS "${CUNIT_INCLUDE_DIR}/CUnit/CUnit.h"
|
|
||||||
CUNIT_VERSION REGEX "${_version_regex}")
|
|
||||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
|
||||||
CUNIT_VERSION "${CUNIT_VERSION}")
|
|
||||||
unset(_version_regex)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set CUNIT_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(CUnit REQUIRED_VARS
|
|
||||||
CUNIT_LIBRARY CUNIT_INCLUDE_DIR
|
|
||||||
VERSION_VAR CUNIT_VERSION)
|
|
||||||
|
|
||||||
if(CUNIT_FOUND)
|
|
||||||
set(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
|
|
||||||
set(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
# Find the Cython compiler.
|
|
||||||
#
|
|
||||||
# This code sets the following variables:
|
|
||||||
#
|
|
||||||
# CYTHON_EXECUTABLE
|
|
||||||
#
|
|
||||||
# See also UseCython.cmake
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2011 Kitware, Inc.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#=============================================================================
|
|
||||||
|
|
||||||
# Use the Cython executable that lives next to the Python executable
|
|
||||||
# if it is a local installation.
|
|
||||||
find_package( PythonInterp )
|
|
||||||
if( PYTHONINTERP_FOUND )
|
|
||||||
get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
|
|
||||||
find_program( CYTHON_EXECUTABLE
|
|
||||||
NAMES cython cython.bat cython3
|
|
||||||
HINTS ${_python_path}
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
find_program( CYTHON_EXECUTABLE
|
|
||||||
NAMES cython cython.bat cython3
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
include( FindPackageHandleStandardArgs )
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE )
|
|
||||||
|
|
||||||
mark_as_advanced( CYTHON_EXECUTABLE )
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# - Try to find jansson
|
|
||||||
# Once done this will define
|
|
||||||
# JANSSON_FOUND - System has jansson
|
|
||||||
# JANSSON_INCLUDE_DIRS - The jansson include directories
|
|
||||||
# JANSSON_LIBRARIES - The libraries needed to use jansson
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_check_modules(PC_JANSSON QUIET jansson)
|
|
||||||
|
|
||||||
find_path(JANSSON_INCLUDE_DIR
|
|
||||||
NAMES jansson.h
|
|
||||||
HINTS ${PC_JANSSON_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
find_library(JANSSON_LIBRARY
|
|
||||||
NAMES jansson
|
|
||||||
HINTS ${PC_JANSSON_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(JANSSON_INCLUDE_DIR)
|
|
||||||
set(_version_regex "^#define[ \t]+JANSSON_VERSION[ \t]+\"([^\"]+)\".*")
|
|
||||||
file(STRINGS "${JANSSON_INCLUDE_DIR}/jansson.h"
|
|
||||||
JANSSON_VERSION REGEX "${_version_regex}")
|
|
||||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
|
||||||
JANSSON_VERSION "${JANSSON_VERSION}")
|
|
||||||
unset(_version_regex)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set JANSSON_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(Jansson REQUIRED_VARS
|
|
||||||
JANSSON_LIBRARY JANSSON_INCLUDE_DIR
|
|
||||||
VERSION_VAR JANSSON_VERSION)
|
|
||||||
|
|
||||||
if(JANSSON_FOUND)
|
|
||||||
set(JANSSON_LIBRARIES ${JANSSON_LIBRARY})
|
|
||||||
set(JANSSON_INCLUDE_DIRS ${JANSSON_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(JANSSON_INCLUDE_DIR JANSSON_LIBRARY)
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# - Try to find jemalloc
|
|
||||||
# Once done this will define
|
|
||||||
# JEMALLOC_FOUND - System has jemalloc
|
|
||||||
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
|
|
||||||
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
|
|
||||||
|
|
||||||
find_path(JEMALLOC_INCLUDE_DIR
|
|
||||||
NAMES jemalloc/jemalloc.h
|
|
||||||
HINTS ${PC_JEMALLOC_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
find_library(JEMALLOC_LIBRARY
|
|
||||||
NAMES jemalloc
|
|
||||||
HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(JEMALLOC_INCLUDE_DIR)
|
|
||||||
set(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
|
|
||||||
file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc/jemalloc.h"
|
|
||||||
JEMALLOC_VERSION REGEX "${_version_regex}")
|
|
||||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
|
||||||
JEMALLOC_VERSION "${JEMALLOC_VERSION}")
|
|
||||||
unset(_version_regex)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(Jemalloc REQUIRED_VARS
|
|
||||||
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR
|
|
||||||
VERSION_VAR JEMALLOC_VERSION)
|
|
||||||
|
|
||||||
if(JEMALLOC_FOUND)
|
|
||||||
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
|
|
||||||
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# - Try to find libcares
|
|
||||||
# Once done this will define
|
|
||||||
# LIBCARES_FOUND - System has libcares
|
|
||||||
# LIBCARES_INCLUDE_DIRS - The libcares include directories
|
|
||||||
# LIBCARES_LIBRARIES - The libraries needed to use libcares
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_check_modules(PC_LIBCARES QUIET libcares)
|
|
||||||
|
|
||||||
find_path(LIBCARES_INCLUDE_DIR
|
|
||||||
NAMES ares.h
|
|
||||||
HINTS ${PC_LIBCARES_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
find_library(LIBCARES_LIBRARY
|
|
||||||
NAMES cares
|
|
||||||
HINTS ${PC_LIBCARES_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LIBCARES_INCLUDE_DIR)
|
|
||||||
set(_version_regex "^#define[ \t]+ARES_VERSION_STR[ \t]+\"([^\"]+)\".*")
|
|
||||||
file(STRINGS "${LIBCARES_INCLUDE_DIR}/ares_version.h"
|
|
||||||
LIBCARES_VERSION REGEX "${_version_regex}")
|
|
||||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
|
||||||
LIBCARES_VERSION "${LIBCARES_VERSION}")
|
|
||||||
unset(_version_regex)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set LIBCARES_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(Libcares REQUIRED_VARS
|
|
||||||
LIBCARES_LIBRARY LIBCARES_INCLUDE_DIR
|
|
||||||
VERSION_VAR LIBCARES_VERSION)
|
|
||||||
|
|
||||||
if(LIBCARES_FOUND)
|
|
||||||
set(LIBCARES_LIBRARIES ${LIBCARES_LIBRARY})
|
|
||||||
set(LIBCARES_INCLUDE_DIRS ${LIBCARES_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(LIBCARES_INCLUDE_DIR LIBCARES_LIBRARY)
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# - Try to find libev
|
|
||||||
# Once done this will define
|
|
||||||
# LIBEV_FOUND - System has libev
|
|
||||||
# LIBEV_INCLUDE_DIRS - The libev include directories
|
|
||||||
# LIBEV_LIBRARIES - The libraries needed to use libev
|
|
||||||
|
|
||||||
find_path(LIBEV_INCLUDE_DIR
|
|
||||||
NAMES ev.h
|
|
||||||
)
|
|
||||||
find_library(LIBEV_LIBRARY
|
|
||||||
NAMES ev
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LIBEV_INCLUDE_DIR)
|
|
||||||
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
|
|
||||||
LIBEV_VERSION_MAJOR REGEX "^#define[ \t]+EV_VERSION_MAJOR[ \t]+[0-9]+")
|
|
||||||
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
|
|
||||||
LIBEV_VERSION_MINOR REGEX "^#define[ \t]+EV_VERSION_MINOR[ \t]+[0-9]+")
|
|
||||||
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MAJOR "${LIBEV_VERSION_MAJOR}")
|
|
||||||
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MINOR "${LIBEV_VERSION_MINOR}")
|
|
||||||
set(LIBEV_VERSION "${LIBEV_VERSION_MAJOR}.${LIBEV_VERSION_MINOR}")
|
|
||||||
unset(LIBEV_VERSION_MINOR)
|
|
||||||
unset(LIBEV_VERSION_MAJOR)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set LIBEV_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(Libev REQUIRED_VARS
|
|
||||||
LIBEV_LIBRARY LIBEV_INCLUDE_DIR
|
|
||||||
VERSION_VAR LIBEV_VERSION)
|
|
||||||
|
|
||||||
if(LIBEV_FOUND)
|
|
||||||
set(LIBEV_LIBRARIES ${LIBEV_LIBRARY})
|
|
||||||
set(LIBEV_INCLUDE_DIRS ${LIBEV_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(LIBEV_INCLUDE_DIR LIBEV_LIBRARY)
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
# - Try to find libevent
|
|
||||||
#.rst
|
|
||||||
# FindLibevent
|
|
||||||
# ------------
|
|
||||||
#
|
|
||||||
# Find Libevent include directories and libraries. Invoke as::
|
|
||||||
#
|
|
||||||
# find_package(Libevent
|
|
||||||
# [version] [EXACT] # Minimum or exact version
|
|
||||||
# [REQUIRED] # Fail if Libevent is not found
|
|
||||||
# [COMPONENT <C>...]) # Libraries to look for
|
|
||||||
#
|
|
||||||
# Valid components are one or more of:: libevent core extra pthreads openssl.
|
|
||||||
# Note that 'libevent' contains both core and extra. You must specify one of
|
|
||||||
# them for the other components.
|
|
||||||
#
|
|
||||||
# This module will define the following variables::
|
|
||||||
#
|
|
||||||
# LIBEVENT_FOUND - True if headers and requested libraries were found
|
|
||||||
# LIBEVENT_INCLUDE_DIRS - Libevent include directories
|
|
||||||
# LIBEVENT_LIBRARIES - Libevent libraries to be linked
|
|
||||||
# LIBEVENT_<C>_FOUND - Component <C> was found (<C> is uppercase)
|
|
||||||
# LIBEVENT_<C>_LIBRARY - Library to be linked for Libevent component <C>.
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_check_modules(PC_LIBEVENT QUIET libevent)
|
|
||||||
|
|
||||||
# Look for the Libevent 2.0 or 1.4 headers
|
|
||||||
find_path(LIBEVENT_INCLUDE_DIR
|
|
||||||
NAMES
|
|
||||||
event2/event-config.h
|
|
||||||
event-config.h
|
|
||||||
HINTS
|
|
||||||
${PC_LIBEVENT_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LIBEVENT_INCLUDE_DIR)
|
|
||||||
set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
|
|
||||||
if(EXISTS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h")
|
|
||||||
# Libevent 2.0
|
|
||||||
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h"
|
|
||||||
LIBEVENT_VERSION REGEX "${_version_regex}")
|
|
||||||
else()
|
|
||||||
# Libevent 1.4
|
|
||||||
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h"
|
|
||||||
LIBEVENT_VERSION REGEX "${_version_regex}")
|
|
||||||
endif()
|
|
||||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
|
||||||
LIBEVENT_VERSION "${LIBEVENT_VERSION}")
|
|
||||||
unset(_version_regex)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(_LIBEVENT_REQUIRED_VARS)
|
|
||||||
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
|
|
||||||
set(_LIBEVENT_LIBNAME libevent)
|
|
||||||
# Note: compare two variables to avoid a CMP0054 policy warning
|
|
||||||
if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
|
|
||||||
set(_LIBEVENT_LIBNAME event)
|
|
||||||
else()
|
|
||||||
set(_LIBEVENT_LIBNAME "event_${COMPONENT}")
|
|
||||||
endif()
|
|
||||||
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
|
|
||||||
find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
|
|
||||||
NAMES ${_LIBEVENT_LIBNAME}
|
|
||||||
HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
|
|
||||||
set(Libevent_${COMPONENT}_FOUND 1)
|
|
||||||
endif()
|
|
||||||
list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
|
|
||||||
endforeach()
|
|
||||||
unset(_LIBEVENT_LIBNAME)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(Libevent REQUIRED_VARS
|
|
||||||
${_LIBEVENT_REQUIRED_VARS}
|
|
||||||
LIBEVENT_INCLUDE_DIR
|
|
||||||
VERSION_VAR LIBEVENT_VERSION
|
|
||||||
HANDLE_COMPONENTS)
|
|
||||||
|
|
||||||
if(LIBEVENT_FOUND)
|
|
||||||
set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
|
|
||||||
set(LIBEVENT_LIBRARIES)
|
|
||||||
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
|
|
||||||
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
|
|
||||||
list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
|
|
||||||
set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS})
|
|
||||||
unset(_LIBEVENT_REQUIRED_VARS)
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
# - Try to find spdylay
|
|
||||||
# Once done this will define
|
|
||||||
# SPDYLAY_FOUND - System has spdylay
|
|
||||||
# SPDYLAY_INCLUDE_DIRS - The spdylay include directories
|
|
||||||
# SPDYLAY_LIBRARIES - The libraries needed to use spdylay
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_check_modules(PC_SPDYLAY QUIET libspdylay)
|
|
||||||
|
|
||||||
find_path(SPDYLAY_INCLUDE_DIR
|
|
||||||
NAMES spdylay/spdylay.h
|
|
||||||
HINTS ${PC_SPDYLAY_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
find_library(SPDYLAY_LIBRARY
|
|
||||||
NAMES spdylay
|
|
||||||
HINTS ${PC_SPDYLAY_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(SPDYLAY_INCLUDE_DIR)
|
|
||||||
set(_version_regex "^#define[ \t]+SPDYLAY_VERSION[ \t]+\"([^\"]+)\".*")
|
|
||||||
file(STRINGS "${SPDYLAY_INCLUDE_DIR}/spdylay/spdylayver.h"
|
|
||||||
SPDYLAY_VERSION REGEX "${_version_regex}")
|
|
||||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
|
||||||
SPDYLAY_VERSION "${SPDYLAY_VERSION}")
|
|
||||||
unset(_version_regex)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set SPDYLAY_FOUND to TRUE
|
|
||||||
# if all listed variables are TRUE and the requested version matches.
|
|
||||||
find_package_handle_standard_args(Spdylay REQUIRED_VARS
|
|
||||||
SPDYLAY_LIBRARY SPDYLAY_INCLUDE_DIR
|
|
||||||
VERSION_VAR SPDYLAY_VERSION)
|
|
||||||
|
|
||||||
if(SPDYLAY_FOUND)
|
|
||||||
set(SPDYLAY_LIBRARIES ${SPDYLAY_LIBRARY})
|
|
||||||
set(SPDYLAY_INCLUDE_DIRS ${SPDYLAY_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced(SPDYLAY_INCLUDE_DIR SPDYLAY_LIBRARY)
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# Converts a version such as 1.2.255 to 0x0102ff
|
|
||||||
function(HexVersion version_hex_var major minor patch)
|
|
||||||
math(EXPR version_dec "${major} * 256 * 256 + ${minor} * 256 + ${patch}")
|
|
||||||
set(version_hex "0x")
|
|
||||||
foreach(i RANGE 5 0 -1)
|
|
||||||
math(EXPR num "(${version_dec} >> (4 * ${i})) & 15")
|
|
||||||
string(SUBSTRING "0123456789abcdef" ${num} 1 num_hex)
|
|
||||||
set(version_hex "${version_hex}${num_hex}")
|
|
||||||
endforeach()
|
|
||||||
set(${version_hex_var} "${version_hex}" PARENT_SCOPE)
|
|
||||||
endfunction()
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
|
|
||||||
/* Hint to the compiler that a function parameter is not used */
|
|
||||||
#define _U_ @HINT_UNUSED_PARAM@
|
|
||||||
|
|
||||||
/* Hint to the compiler that a function never returns */
|
|
||||||
#define NGHTTP2_NORETURN @HINT_NORETURN@
|
|
||||||
|
|
||||||
/* Define to `int' if <sys/types.h> does not define. */
|
|
||||||
#cmakedefine ssize_t @ssize_t@
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `std::map::emplace`. */
|
|
||||||
#cmakedefine HAVE_STD_MAP_EMPLACE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have `libjansson` library. */
|
|
||||||
#cmakedefine HAVE_JANSSON 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have `libxml2` library. */
|
|
||||||
#cmakedefine HAVE_LIBXML2 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have `spdylay` library. */
|
|
||||||
#cmakedefine HAVE_SPDYLAY 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have `mruby` library. */
|
|
||||||
#cmakedefine HAVE_MRUBY 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have `neverbleed` library. */
|
|
||||||
#cmakedefine HAVE_NEVERBLEED 1
|
|
||||||
|
|
||||||
/* sizeof(int *) */
|
|
||||||
#cmakedefine SIZEOF_INT_P @SIZEOF_INT_P@
|
|
||||||
|
|
||||||
/* sizeof(time_t) */
|
|
||||||
#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `_Exit` function. */
|
|
||||||
#cmakedefine HAVE__EXIT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `accept4` function. */
|
|
||||||
#cmakedefine HAVE_ACCEPT4 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `initgroups` function. */
|
|
||||||
#cmakedefine01 HAVE_DECL_INITGROUPS
|
|
||||||
|
|
||||||
/* Define to 1 to enable debug output. */
|
|
||||||
#cmakedefine DEBUGBUILD 1
|
|
||||||
|
|
||||||
/* Define to 1 if you want to disable threads. */
|
|
||||||
#cmakedefine NOTHREADS 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
|
||||||
#cmakedefine HAVE_ARPA_INET_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
|
||||||
#cmakedefine HAVE_FCNTL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
#cmakedefine HAVE_INTTYPES_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <limits.h> header file. */
|
|
||||||
#cmakedefine HAVE_LIMITS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <netdb.h> header file. */
|
|
||||||
#cmakedefine HAVE_NETDB_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
|
||||||
#cmakedefine HAVE_NETINET_IN_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <pwd.h> header file. */
|
|
||||||
#cmakedefine HAVE_PWD_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_SOCKET_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYS_TIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <syslog.h> header file. */
|
|
||||||
#cmakedefine HAVE_SYSLOG_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <time.h> header file. */
|
|
||||||
#cmakedefine HAVE_TIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#cmakedefine HAVE_UNISTD_H 1
|
|
||||||
128
configure.ac
128
configure.ac
@@ -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.18.1], [t-tujikawa@users.sourceforge.net])
|
AC_INIT([nghttp2], [1.8.0-DEV], [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])
|
||||||
@@ -40,13 +40,15 @@ AC_CANONICAL_TARGET
|
|||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
|
||||||
|
# AM_EXTRA_RECURSIVE_TARGETS requires automake 1.13 or higher
|
||||||
|
m4_ifdef([AM_EXTRA_RECURSIVE_TARGETS], [AM_EXTRA_RECURSIVE_TARGETS([it itprep])])
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
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, 26)
|
AC_SUBST(LT_CURRENT, 18)
|
||||||
AC_SUBST(LT_REVISION, 3)
|
AC_SUBST(LT_REVISION, 1)
|
||||||
AC_SUBST(LT_AGE, 12)
|
AC_SUBST(LT_AGE, 4)
|
||||||
|
|
||||||
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"`
|
||||||
@@ -74,7 +76,7 @@ AC_ARG_ENABLE([threads],
|
|||||||
|
|
||||||
AC_ARG_ENABLE([app],
|
AC_ARG_ENABLE([app],
|
||||||
[AS_HELP_STRING([--enable-app],
|
[AS_HELP_STRING([--enable-app],
|
||||||
[Build applications (nghttp, nghttpd, nghttpx and h2load) [default=check]])],
|
[Build applications (nghttp, nghttpd and nghttpx) [default=check]])],
|
||||||
[request_app=$enableval], [request_app=check])
|
[request_app=$enableval], [request_app=check])
|
||||||
|
|
||||||
AC_ARG_ENABLE([hpack-tools],
|
AC_ARG_ENABLE([hpack-tools],
|
||||||
@@ -183,8 +185,8 @@ if test "x$GCC" = "xyes" -o "x$CC" = "xclang" ; then
|
|||||||
AC_DEFINE([_U_], [__attribute__((unused))], [Hint to the compiler that a function parameters is not used])
|
AC_DEFINE([_U_], [__attribute__((unused))], [Hint to the compiler that a function parameters is not used])
|
||||||
AC_DEFINE([NGHTTP2_NORETURN], [__attribute__((noreturn))], [Hint to the compiler that a function never return])
|
AC_DEFINE([NGHTTP2_NORETURN], [__attribute__((noreturn))], [Hint to the compiler that a function never return])
|
||||||
else
|
else
|
||||||
AC_DEFINE([_U_], , [Hint to the compiler that a function parameter is not used])
|
AC_DEFINE([_U_], , [Hint to the compiler that a function parameters is not use AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
|
||||||
AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
|
d])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
save_CXXFLAGS="$CXXFLAGS"
|
save_CXXFLAGS="$CXXFLAGS"
|
||||||
@@ -234,41 +236,6 @@ std::map<int, int>().emplace(1, 2);
|
|||||||
[have_std_map_emplace=no
|
[have_std_map_emplace=no
|
||||||
AC_MSG_RESULT([no])])
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
# Check that std::atomic_* overloads for std::shared_ptr are
|
|
||||||
# available.
|
|
||||||
AC_MSG_CHECKING([whether std::atomic_* overloads for std::shared_ptr are available])
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <memory>
|
|
||||||
]],
|
|
||||||
[[
|
|
||||||
auto a = std::make_shared<int>(1000000007);
|
|
||||||
auto p = std::atomic_load(&a);
|
|
||||||
++*p;
|
|
||||||
std::atomic_store(&a, p);
|
|
||||||
]])],
|
|
||||||
[AC_DEFINE([HAVE_ATOMIC_STD_SHARED_PTR], [1],
|
|
||||||
[Define to 1 if you have the std::atomic_* overloads for std::shared_ptr.])
|
|
||||||
have_atomic_std_shared_ptr=yes
|
|
||||||
AC_MSG_RESULT([yes])],
|
|
||||||
[have_atomic_std_shared_ptr=no
|
|
||||||
AC_MSG_RESULT([no])])
|
|
||||||
|
|
||||||
# Check that thread_local storage specifier is available
|
|
||||||
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
|
||||||
,
|
|
||||||
[[
|
|
||||||
thread_local int a = 0;
|
|
||||||
(void)a;
|
|
||||||
]])],
|
|
||||||
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
|
|
||||||
[Define to 1 if you have thread_local storage specifier.])
|
|
||||||
have_thread_local=yes
|
|
||||||
AC_MSG_RESULT([yes])],
|
|
||||||
[have_Thread_local=no
|
|
||||||
AC_MSG_RESULT([no])])
|
|
||||||
|
|
||||||
CXXFLAGS=$save_CXXFLAGS
|
CXXFLAGS=$save_CXXFLAGS
|
||||||
|
|
||||||
AC_LANG_POP()
|
AC_LANG_POP()
|
||||||
@@ -281,7 +248,7 @@ TESTLDADD=
|
|||||||
# Additional libraries required for programs under src directory.
|
# Additional libraries required for programs under src directory.
|
||||||
APPLDFLAGS=
|
APPLDFLAGS=
|
||||||
|
|
||||||
case "$host_os" in
|
case "$host" in
|
||||||
*android*)
|
*android*)
|
||||||
android_build=yes
|
android_build=yes
|
||||||
# android does not need -pthread, but needs followng 3 libs for C++
|
# android does not need -pthread, but needs followng 3 libs for C++
|
||||||
@@ -293,12 +260,6 @@ case "$host_os" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "$host_os" in
|
|
||||||
*solaris*)
|
|
||||||
APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# zlib
|
# zlib
|
||||||
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
|
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
|
||||||
|
|
||||||
@@ -370,13 +331,6 @@ if test "x${have_openssl}" = "xno"; then
|
|||||||
AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
|
AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# c-ares (for src)
|
|
||||||
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.5], [have_libcares=yes],
|
|
||||||
[have_libcares=no])
|
|
||||||
if test "x${have_libcares}" = "xno"; then
|
|
||||||
AC_MSG_NOTICE($LIBCARES_PKG_ERRORS)
|
|
||||||
fi
|
|
||||||
|
|
||||||
# libevent_openssl (for examples)
|
# libevent_openssl (for examples)
|
||||||
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
||||||
PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
|
PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
|
||||||
@@ -396,12 +350,12 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# libxml2 (for src/nghttp)
|
# libxml2 (for src/nghttp)
|
||||||
PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.7.7],
|
have_libxml2=no
|
||||||
[have_libxml2=yes], [have_libxml2=no])
|
if test "x${request_libxml2}" != "xno"; then
|
||||||
if test "x${have_libxml2}" = "xyes"; then
|
AM_PATH_XML2(2.7.7, [have_libxml2=yes], [have_libxml2=no])
|
||||||
|
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.])
|
||||||
else
|
fi
|
||||||
AC_MSG_NOTICE($LIBXML2_PKG_ERRORS)
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x${request_libxml2}" = "xyes" &&
|
if test "x${request_libxml2}" = "xyes" &&
|
||||||
@@ -483,14 +437,13 @@ if test "x${request_asio_lib}" = "xyes"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL,
|
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL
|
||||||
# libev, and libc-ares.
|
# and libev
|
||||||
enable_app=no
|
enable_app=no
|
||||||
if test "x${request_app}" != "xno" &&
|
if test "x${request_app}" != "xno" &&
|
||||||
test "x${have_zlib}" = "xyes" &&
|
test "x${have_zlib}" = "xyes" &&
|
||||||
test "x${have_openssl}" = "xyes" &&
|
test "x${have_openssl}" = "xyes" &&
|
||||||
test "x${have_libev}" = "xyes" &&
|
test "x${have_libev}" = "xyes"; then
|
||||||
test "x${have_libcares}" = "xyes"; then
|
|
||||||
enable_app=yes
|
enable_app=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -645,26 +598,6 @@ AC_SYS_LARGEFILE
|
|||||||
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes],
|
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes],
|
||||||
[have_struct_tm_tm_gmtoff=no], [[#include <time.h>]])
|
[have_struct_tm_tm_gmtoff=no], [[#include <time.h>]])
|
||||||
|
|
||||||
AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
|
|
||||||
[AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN],[1],
|
|
||||||
[Define to 1 if struct sockaddr_in has sin_len member.])],
|
|
||||||
[],
|
|
||||||
[[
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
]])
|
|
||||||
|
|
||||||
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len],
|
|
||||||
[AC_DEFINE([HAVE_SOCKADDR_IN6_SIN6_LEN],[1],
|
|
||||||
[Define to 1 if struct sockaddr_in6 has sin6_len member.])],
|
|
||||||
[],
|
|
||||||
[[
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
]])
|
|
||||||
|
|
||||||
if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
|
if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
|
||||||
AC_DEFINE([HAVE_STRUCT_TM_TM_GMTOFF], [1],
|
AC_DEFINE([HAVE_STRUCT_TM_TM_GMTOFF], [1],
|
||||||
[Define to 1 if you have `struct tm.tm_gmtoff` member.])
|
[Define to 1 if you have `struct tm.tm_gmtoff` member.])
|
||||||
@@ -718,13 +651,15 @@ AC_CHECK_FUNC([timerfd_create],
|
|||||||
|
|
||||||
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
|
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
|
||||||
# cygwin disables initgroups due to feature test macro magic with our
|
# cygwin disables initgroups due to feature test macro magic with our
|
||||||
# configuration. FreeBSD declares initgroups() in unistd.h.
|
# configuration.
|
||||||
AC_CHECK_DECLS([initgroups], [], [], [[
|
AC_CHECK_DECLS([initgroups], [], [], [[#include <grp.h>]])
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
# Checks for epoll availability, primarily for examples/tiny-nghttpd
|
||||||
#endif
|
AX_HAVE_EPOLL([have_epoll=yes], [have_epoll=no])
|
||||||
#include <grp.h>
|
|
||||||
]])
|
AM_CONDITIONAL([ENABLE_TINY_NGHTTPD],
|
||||||
|
[ test "x${have_epoll}" = "xyes" &&
|
||||||
|
test "x${have_timerfd_create}" = "xyes"])
|
||||||
|
|
||||||
save_CFLAGS=$CFLAGS
|
save_CFLAGS=$CFLAGS
|
||||||
save_CXXFLAGS=$CXXFLAGS
|
save_CXXFLAGS=$CXXFLAGS
|
||||||
@@ -779,17 +714,12 @@ if test "x$werror" != "xno"; then
|
|||||||
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
|
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
|
||||||
# Only work with Clang for the moment
|
# Only work with Clang for the moment
|
||||||
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
|
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CFLAGS="$CFLAGS -Wsometimes-uninitialized"])
|
|
||||||
|
|
||||||
# This is required because we pass format string as "const char*.
|
|
||||||
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
|
|
||||||
|
|
||||||
# For C++ compiler
|
# For C++ compiler
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
|
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
|
||||||
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"])
|
|
||||||
AC_LANG_POP()
|
AC_LANG_POP()
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -886,7 +816,6 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
C preprocessor: ${CPP}
|
C preprocessor: ${CPP}
|
||||||
CPPFLAGS: ${CPPFLAGS}
|
CPPFLAGS: ${CPPFLAGS}
|
||||||
WARNCFLAGS: ${WARNCFLAGS}
|
WARNCFLAGS: ${WARNCFLAGS}
|
||||||
WARNCXXFLAGS: ${WARNCXXFLAGS}
|
|
||||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||||
EXTRACFLAG: ${EXTRACFLAG}
|
EXTRACFLAG: ${EXTRACFLAG}
|
||||||
LIBS: ${LIBS}
|
LIBS: ${LIBS}
|
||||||
@@ -906,9 +835,8 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
Failmalloc: ${enable_failmalloc}
|
Failmalloc: ${enable_failmalloc}
|
||||||
Libs:
|
Libs:
|
||||||
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
|
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
|
||||||
Libxml2: ${have_libxml2} (CFLAGS='${LIBXML2_CPPFLAGS}' LIBS='${LIBXML2_LIBS}')
|
Libxml2: ${have_libxml2} (CFLAGS='${XML_CPPFLAGS}' LIBS='${XML_LIBS}')
|
||||||
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}')
|
|
||||||
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}')
|
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}')
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
set(CONFIGFILES
|
|
||||||
nghttpx-init
|
|
||||||
nghttpx.service
|
|
||||||
nghttpx-upstart.conf
|
|
||||||
)
|
|
||||||
|
|
||||||
# Note that the execute permissions of nghttpx-init is preserved
|
|
||||||
foreach(name IN LISTS CONFIGFILES)
|
|
||||||
configure_file("${name}.in" "${name}" @ONLY)
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# set(EXTRA_DIST ${CONFIGFILES} nghttpx-logrotate tlsticketupdate.go)
|
|
||||||
@@ -23,24 +23,17 @@
|
|||||||
|
|
||||||
configfiles = nghttpx-init nghttpx.service nghttpx-upstart.conf
|
configfiles = nghttpx-init nghttpx.service nghttpx-upstart.conf
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = $(configfiles:%=%.in) nghttpx-logrotate tlsticketupdate.go
|
||||||
CMakeLists.txt \
|
|
||||||
$(configfiles:%=%.in) \
|
|
||||||
nghttpx-logrotate \
|
|
||||||
tlsticketupdate.go
|
|
||||||
|
|
||||||
edit = sed -e 's|@bindir[@]|$(bindir)|g'
|
edit = sed -e 's|@bindir[@]|$(bindir)|g'
|
||||||
|
|
||||||
nghttpx-init: $(srcdir)/nghttpx-init.in
|
nghttpx-init: %: $(srcdir)/%.in
|
||||||
rm -f $@ $@.tmp
|
rm -f $@ $@.tmp
|
||||||
$(edit) $< > $@.tmp
|
$(edit) $< > $@.tmp
|
||||||
chmod +x $@.tmp
|
chmod +x $@.tmp
|
||||||
mv $@.tmp $@
|
mv $@.tmp $@
|
||||||
|
|
||||||
nghttpx.service: $(srcdir)/nghttpx.service.in
|
nghttpx.service nghttpx-upstart.conf: %: $(srcdir)/%.in
|
||||||
$(edit) $< > $@
|
|
||||||
|
|
||||||
nghttpx-upstart.conf: $(srcdir)/nghttpx-upstart.conf.in
|
|
||||||
$(edit) $< > $@
|
$(edit) $< > $@
|
||||||
|
|
||||||
$(configfiles): Makefile
|
$(configfiles): Makefile
|
||||||
|
|||||||
@@ -1,352 +0,0 @@
|
|||||||
# Generated documents
|
|
||||||
set(APIDOCS
|
|
||||||
macros.rst
|
|
||||||
enums.rst
|
|
||||||
types.rst
|
|
||||||
nghttp2_check_header_name.rst
|
|
||||||
nghttp2_check_header_value.rst
|
|
||||||
nghttp2_hd_deflate_bound.rst
|
|
||||||
nghttp2_hd_deflate_change_table_size.rst
|
|
||||||
nghttp2_hd_deflate_del.rst
|
|
||||||
nghttp2_hd_deflate_get_dynamic_table_size.rst
|
|
||||||
nghttp2_hd_deflate_get_max_dynamic_table_size.rst
|
|
||||||
nghttp2_hd_deflate_get_num_table_entries.rst
|
|
||||||
nghttp2_hd_deflate_get_table_entry.rst
|
|
||||||
nghttp2_hd_deflate_hd.rst
|
|
||||||
nghttp2_hd_deflate_hd_vec.rst
|
|
||||||
nghttp2_hd_deflate_new.rst
|
|
||||||
nghttp2_hd_deflate_new2.rst
|
|
||||||
nghttp2_hd_inflate_change_table_size.rst
|
|
||||||
nghttp2_hd_inflate_del.rst
|
|
||||||
nghttp2_hd_inflate_end_headers.rst
|
|
||||||
nghttp2_hd_inflate_get_dynamic_table_size.rst
|
|
||||||
nghttp2_hd_inflate_get_max_dynamic_table_size.rst
|
|
||||||
nghttp2_hd_inflate_get_num_table_entries.rst
|
|
||||||
nghttp2_hd_inflate_get_table_entry.rst
|
|
||||||
nghttp2_hd_inflate_hd.rst
|
|
||||||
nghttp2_hd_inflate_hd2.rst
|
|
||||||
nghttp2_hd_inflate_new.rst
|
|
||||||
nghttp2_hd_inflate_new2.rst
|
|
||||||
nghttp2_http2_strerror.rst
|
|
||||||
nghttp2_is_fatal.rst
|
|
||||||
nghttp2_nv_compare_name.rst
|
|
||||||
nghttp2_option_del.rst
|
|
||||||
nghttp2_option_new.rst
|
|
||||||
nghttp2_option_set_builtin_recv_extension_type.rst
|
|
||||||
nghttp2_option_set_max_deflate_dynamic_table_size.rst
|
|
||||||
nghttp2_option_set_max_reserved_remote_streams.rst
|
|
||||||
nghttp2_option_set_max_send_header_block_length.rst
|
|
||||||
nghttp2_option_set_no_auto_ping_ack.rst
|
|
||||||
nghttp2_option_set_no_auto_window_update.rst
|
|
||||||
nghttp2_option_set_no_http_messaging.rst
|
|
||||||
nghttp2_option_set_no_recv_client_magic.rst
|
|
||||||
nghttp2_option_set_peer_max_concurrent_streams.rst
|
|
||||||
nghttp2_option_set_user_recv_extension_type.rst
|
|
||||||
nghttp2_pack_settings_payload.rst
|
|
||||||
nghttp2_priority_spec_check_default.rst
|
|
||||||
nghttp2_priority_spec_default_init.rst
|
|
||||||
nghttp2_priority_spec_init.rst
|
|
||||||
nghttp2_rcbuf_decref.rst
|
|
||||||
nghttp2_rcbuf_get_buf.rst
|
|
||||||
nghttp2_rcbuf_incref.rst
|
|
||||||
nghttp2_select_next_protocol.rst
|
|
||||||
nghttp2_session_callbacks_del.rst
|
|
||||||
nghttp2_session_callbacks_new.rst
|
|
||||||
nghttp2_session_callbacks_set_before_frame_send_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_data_source_read_length_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_error_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_data_chunk_recv_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_frame_recv_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_frame_send_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_header_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_header_callback2.rst
|
|
||||||
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_invalid_header_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst
|
|
||||||
nghttp2_session_callbacks_set_on_stream_close_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_pack_extension_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_recv_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_select_padding_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_send_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_send_data_callback.rst
|
|
||||||
nghttp2_session_callbacks_set_unpack_extension_callback.rst
|
|
||||||
nghttp2_session_change_stream_priority.rst
|
|
||||||
nghttp2_session_check_request_allowed.rst
|
|
||||||
nghttp2_session_check_server_session.rst
|
|
||||||
nghttp2_session_client_new.rst
|
|
||||||
nghttp2_session_client_new2.rst
|
|
||||||
nghttp2_session_client_new3.rst
|
|
||||||
nghttp2_session_consume.rst
|
|
||||||
nghttp2_session_consume_connection.rst
|
|
||||||
nghttp2_session_consume_stream.rst
|
|
||||||
nghttp2_session_create_idle_stream.rst
|
|
||||||
nghttp2_session_del.rst
|
|
||||||
nghttp2_session_find_stream.rst
|
|
||||||
nghttp2_session_get_effective_local_window_size.rst
|
|
||||||
nghttp2_session_get_effective_recv_data_length.rst
|
|
||||||
nghttp2_session_get_hd_deflate_dynamic_table_size.rst
|
|
||||||
nghttp2_session_get_hd_inflate_dynamic_table_size.rst
|
|
||||||
nghttp2_session_get_last_proc_stream_id.rst
|
|
||||||
nghttp2_session_get_local_settings.rst
|
|
||||||
nghttp2_session_get_local_window_size.rst
|
|
||||||
nghttp2_session_get_next_stream_id.rst
|
|
||||||
nghttp2_session_get_outbound_queue_size.rst
|
|
||||||
nghttp2_session_get_remote_settings.rst
|
|
||||||
nghttp2_session_get_remote_window_size.rst
|
|
||||||
nghttp2_session_get_root_stream.rst
|
|
||||||
nghttp2_session_get_stream_effective_local_window_size.rst
|
|
||||||
nghttp2_session_get_stream_effective_recv_data_length.rst
|
|
||||||
nghttp2_session_get_stream_local_close.rst
|
|
||||||
nghttp2_session_get_stream_local_window_size.rst
|
|
||||||
nghttp2_session_get_stream_remote_close.rst
|
|
||||||
nghttp2_session_get_stream_remote_window_size.rst
|
|
||||||
nghttp2_session_get_stream_user_data.rst
|
|
||||||
nghttp2_session_mem_recv.rst
|
|
||||||
nghttp2_session_mem_send.rst
|
|
||||||
nghttp2_session_recv.rst
|
|
||||||
nghttp2_session_resume_data.rst
|
|
||||||
nghttp2_session_send.rst
|
|
||||||
nghttp2_session_server_new.rst
|
|
||||||
nghttp2_session_server_new2.rst
|
|
||||||
nghttp2_session_server_new3.rst
|
|
||||||
nghttp2_session_set_local_window_size.rst
|
|
||||||
nghttp2_session_set_next_stream_id.rst
|
|
||||||
nghttp2_session_set_stream_user_data.rst
|
|
||||||
nghttp2_session_terminate_session.rst
|
|
||||||
nghttp2_session_terminate_session2.rst
|
|
||||||
nghttp2_session_upgrade.rst
|
|
||||||
nghttp2_session_upgrade2.rst
|
|
||||||
nghttp2_session_want_read.rst
|
|
||||||
nghttp2_session_want_write.rst
|
|
||||||
nghttp2_set_debug_vprintf_callback.rst
|
|
||||||
nghttp2_stream_get_first_child.rst
|
|
||||||
nghttp2_stream_get_next_sibling.rst
|
|
||||||
nghttp2_stream_get_parent.rst
|
|
||||||
nghttp2_stream_get_previous_sibling.rst
|
|
||||||
nghttp2_stream_get_state.rst
|
|
||||||
nghttp2_stream_get_sum_dependency_weight.rst
|
|
||||||
nghttp2_stream_get_weight.rst
|
|
||||||
nghttp2_strerror.rst
|
|
||||||
nghttp2_submit_altsvc.rst
|
|
||||||
nghttp2_submit_data.rst
|
|
||||||
nghttp2_submit_extension.rst
|
|
||||||
nghttp2_submit_goaway.rst
|
|
||||||
nghttp2_submit_headers.rst
|
|
||||||
nghttp2_submit_ping.rst
|
|
||||||
nghttp2_submit_priority.rst
|
|
||||||
nghttp2_submit_push_promise.rst
|
|
||||||
nghttp2_submit_request.rst
|
|
||||||
nghttp2_submit_response.rst
|
|
||||||
nghttp2_submit_rst_stream.rst
|
|
||||||
nghttp2_submit_settings.rst
|
|
||||||
nghttp2_submit_shutdown_notice.rst
|
|
||||||
nghttp2_submit_trailer.rst
|
|
||||||
nghttp2_submit_window_update.rst
|
|
||||||
nghttp2_version.rst
|
|
||||||
)
|
|
||||||
|
|
||||||
set(MAN_PAGES
|
|
||||||
nghttp.1
|
|
||||||
nghttpd.1
|
|
||||||
nghttpx.1
|
|
||||||
h2load.1
|
|
||||||
)
|
|
||||||
|
|
||||||
# Other .rst files from the source tree that need to be copied
|
|
||||||
# XXX move them to sources/ and create .in files?
|
|
||||||
set(RST_FILES
|
|
||||||
README.rst
|
|
||||||
programmers-guide.rst
|
|
||||||
nghttp.1.rst
|
|
||||||
nghttpd.1.rst
|
|
||||||
nghttpx.1.rst
|
|
||||||
h2load.1.rst
|
|
||||||
)
|
|
||||||
|
|
||||||
# XXX unused for now
|
|
||||||
set(EXTRA_DIST
|
|
||||||
mkapiref.py
|
|
||||||
${RST_FILES}
|
|
||||||
${APIDOCS}
|
|
||||||
sources/index.rst
|
|
||||||
sources/tutorial-client.rst
|
|
||||||
sources/tutorial-server.rst
|
|
||||||
sources/tutorial-hpack.rst
|
|
||||||
sources/nghttpx-howto.rst
|
|
||||||
sources/h2load-howto.rst
|
|
||||||
sources/libnghttp2_asio.rst
|
|
||||||
sources/python-apiref.rst
|
|
||||||
sources/building-android-binary.rst
|
|
||||||
sources/contribute.rst
|
|
||||||
_exts/sphinxcontrib/LICENSE.rubydomain
|
|
||||||
_exts/sphinxcontrib/__init__.py
|
|
||||||
_exts/sphinxcontrib/rubydomain.py
|
|
||||||
_themes/sphinx_rtd_theme/__init__.py
|
|
||||||
_themes/sphinx_rtd_theme/breadcrumbs.html
|
|
||||||
_themes/sphinx_rtd_theme/footer.html
|
|
||||||
_themes/sphinx_rtd_theme/layout.html
|
|
||||||
_themes/sphinx_rtd_theme/layout_old.html
|
|
||||||
_themes/sphinx_rtd_theme/search.html
|
|
||||||
_themes/sphinx_rtd_theme/searchbox.html
|
|
||||||
_themes/sphinx_rtd_theme/static/css/badge_only.css
|
|
||||||
_themes/sphinx_rtd_theme/static/css/theme.css
|
|
||||||
_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
|
|
||||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
|
|
||||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
|
|
||||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
|
|
||||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
|
|
||||||
_themes/sphinx_rtd_theme/static/js/theme.js
|
|
||||||
_themes/sphinx_rtd_theme/theme.conf
|
|
||||||
_themes/sphinx_rtd_theme/versions.html
|
|
||||||
${MAN_PAGES}
|
|
||||||
bash_completion/nghttp
|
|
||||||
bash_completion/nghttpd
|
|
||||||
bash_completion/nghttpx
|
|
||||||
bash_completion/h2load
|
|
||||||
)
|
|
||||||
|
|
||||||
# Based on Makefile for Sphinx documentation
|
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
|
||||||
set(SPHINXOPTS)
|
|
||||||
set(SPHINXBUILD sphinx-build)
|
|
||||||
set(PAPER)
|
|
||||||
set(BUILDDIR manual)
|
|
||||||
|
|
||||||
# Internal variables.
|
|
||||||
set(PAPEROPT_a4 -D latex_paper_size=a4)
|
|
||||||
set(PAPEROPT_letter -D latex_paper_size=letter)
|
|
||||||
set(ALLSPHINXOPTS -d ${BUILDDIR}/doctrees ${PAPEROPT_${PAPER}} ${SPHINXOPTS} .)
|
|
||||||
|
|
||||||
# "Please use `make <target>' where <target> is one of"
|
|
||||||
# " html to make standalone HTML files"
|
|
||||||
# " dirhtml to make HTML files named index.html in directories"
|
|
||||||
# " singlehtml to make a single large HTML file"
|
|
||||||
# " pickle to make pickle files"
|
|
||||||
# " json to make JSON files"
|
|
||||||
# " htmlhelp to make HTML files and a HTML help project"
|
|
||||||
# " qthelp to make HTML files and a qthelp project"
|
|
||||||
# " devhelp to make HTML files and a Devhelp project"
|
|
||||||
# " epub to make an epub"
|
|
||||||
# " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
|
||||||
# " latexpdf to make LaTeX files and run them through pdflatex"
|
|
||||||
# " text to make text files"
|
|
||||||
# " man to make manual pages"
|
|
||||||
# " changes to make an overview of all changed/added/deprecated items"
|
|
||||||
# " linkcheck to check all external links for integrity"
|
|
||||||
# " doctest to run all doctests embedded in the documentation (if enabled)"
|
|
||||||
|
|
||||||
|
|
||||||
# Copy files for out-of-tree builds
|
|
||||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
|
||||||
set(RST_BUILD_FILES)
|
|
||||||
foreach(rstfile IN LISTS RST_FILES)
|
|
||||||
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${rstfile}")
|
|
||||||
add_custom_command(OUTPUT "${outfile}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}" "${outfile}"
|
|
||||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}"
|
|
||||||
)
|
|
||||||
list(APPEND RST_BUILD_FILES "${outfile}")
|
|
||||||
endforeach()
|
|
||||||
else()
|
|
||||||
set(RST_BUILD_FILES "${RST_FILES}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(apiref_SOURCES
|
|
||||||
${CMAKE_BINARY_DIR}/lib/includes/nghttp2/nghttp2ver.h
|
|
||||||
${CMAKE_SOURCE_DIR}/lib/includes/nghttp2/nghttp2.h
|
|
||||||
)
|
|
||||||
# Generates apiref.rst and other files
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT
|
|
||||||
apiref.rst
|
|
||||||
${APIDOCS}
|
|
||||||
COMMAND
|
|
||||||
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkapiref.py"
|
|
||||||
apiref.rst macros.rst enums.rst types.rst .
|
|
||||||
${apiref_SOURCES}
|
|
||||||
DEPENDS
|
|
||||||
${RST_BUILD_FILES}
|
|
||||||
${apiref_SOURCES}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${BUILDDIR}")
|
|
||||||
|
|
||||||
# Invokes sphinx-build and prints the given messages when completed
|
|
||||||
function(sphinxbuild builder)
|
|
||||||
set(echo_commands)
|
|
||||||
foreach(message IN LISTS ARGN)
|
|
||||||
list(APPEND echo_commands COMMAND ${CMAKE_COMMAND} -E echo "${message}")
|
|
||||||
endforeach()
|
|
||||||
add_custom_target(${builder}
|
|
||||||
COMMAND "${SPHINXBUILD}" -b ${builder} ${ALLSPHINXOPTS} "${BUILDDIR}/${builder}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo
|
|
||||||
${echo_commands}
|
|
||||||
VERBATIM
|
|
||||||
DEPENDS apiref.rst
|
|
||||||
)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
foreach(builder html dirhtml singlehtml)
|
|
||||||
sphinxbuild(${builder}
|
|
||||||
"Build finished. The HTML pages are in ${BUILDDIR}/${builder}.")
|
|
||||||
endforeach()
|
|
||||||
sphinxbuild(pickle "Build finished; now you can process the pickle files.")
|
|
||||||
sphinxbuild(json "Build finished; now you can process the JSON files.")
|
|
||||||
sphinxbuild(htmlhelp
|
|
||||||
"Build finished; now you can run HTML Help Workshop with the"
|
|
||||||
".hhp project file in ${BUILDDIR}/htmlhelp."
|
|
||||||
)
|
|
||||||
sphinxbuild(qthelp
|
|
||||||
"Build finished; now you can run \"qcollectiongenerator\" with the"
|
|
||||||
".qhcp project file in ${BUILDDIR}/qthelp, like this:"
|
|
||||||
"# qcollectiongenerator ${BUILDDIR}/qthelp/nghttp2.qhcp"
|
|
||||||
"To view the help file:"
|
|
||||||
"# assistant -collectionFile ${BUILDDIR}/qthelp/nghttp2.qhc"
|
|
||||||
)
|
|
||||||
sphinxbuild(devhelp
|
|
||||||
"Build finished."
|
|
||||||
"To view the help file:"
|
|
||||||
"# mkdir -p ~/.local/share/devhelp/nghttp2"
|
|
||||||
"# ln -s ${BUILDDIR}/devhelp ~/.local/share/devhelp/nghttp2"
|
|
||||||
"# devhelp"
|
|
||||||
)
|
|
||||||
sphinxbuild(epub "Build finished. The epub file is in ${BUILDDIR}/epub.")
|
|
||||||
sphinxbuild(latex
|
|
||||||
"Build finished; the LaTeX files are in ${BUILDDIR}/latex."
|
|
||||||
"Run `make' in that directory to run these through (pdf)latex"
|
|
||||||
"(use `make latexpdf' here to do that automatically)."
|
|
||||||
)
|
|
||||||
|
|
||||||
# Invoke the Makefile generated by sphinx
|
|
||||||
add_custom_target(latexpdf
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "Running LaTeX files through pdflatex..."
|
|
||||||
COMMAND make -C "${BUILDDIR}/latex" all-pdf
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "pdflatex finished; the PDF files are in ${BUILDDIR}/latex."
|
|
||||||
DEPENDS latex
|
|
||||||
)
|
|
||||||
|
|
||||||
sphinxbuild(text "Build finished. The text files are in ${BUILDDIR}/text.")
|
|
||||||
sphinxbuild(man "Build finished. The manual pages are in ${BUILDDIR}/man.")
|
|
||||||
sphinxbuild(changes "The overview file is in ${BUILDDIR}/changes.")
|
|
||||||
sphinxbuild(linkcheck
|
|
||||||
"Link check complete; look for any errors in the above output"
|
|
||||||
"or in ${BUILDDIR}/linkcheck/output.txt."
|
|
||||||
)
|
|
||||||
sphinxbuild(doctest
|
|
||||||
"Testing of doctests in the sources finished, look at the"
|
|
||||||
"results in ${BUILDDIR}/doctest/output.txt."
|
|
||||||
)
|
|
||||||
|
|
||||||
foreach(_man_page IN LISTS MAN_PAGES)
|
|
||||||
install(FILES ${_man_page}
|
|
||||||
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
|
|
||||||
)
|
|
||||||
endforeach()
|
|
||||||
@@ -37,7 +37,6 @@ APIDOCS= \
|
|||||||
nghttp2_hd_deflate_get_num_table_entries.rst \
|
nghttp2_hd_deflate_get_num_table_entries.rst \
|
||||||
nghttp2_hd_deflate_get_table_entry.rst \
|
nghttp2_hd_deflate_get_table_entry.rst \
|
||||||
nghttp2_hd_deflate_hd.rst \
|
nghttp2_hd_deflate_hd.rst \
|
||||||
nghttp2_hd_deflate_hd_vec.rst \
|
|
||||||
nghttp2_hd_deflate_new.rst \
|
nghttp2_hd_deflate_new.rst \
|
||||||
nghttp2_hd_deflate_new2.rst \
|
nghttp2_hd_deflate_new2.rst \
|
||||||
nghttp2_hd_inflate_change_table_size.rst \
|
nghttp2_hd_inflate_change_table_size.rst \
|
||||||
@@ -48,59 +47,39 @@ APIDOCS= \
|
|||||||
nghttp2_hd_inflate_get_num_table_entries.rst \
|
nghttp2_hd_inflate_get_num_table_entries.rst \
|
||||||
nghttp2_hd_inflate_get_table_entry.rst \
|
nghttp2_hd_inflate_get_table_entry.rst \
|
||||||
nghttp2_hd_inflate_hd.rst \
|
nghttp2_hd_inflate_hd.rst \
|
||||||
nghttp2_hd_inflate_hd2.rst \
|
|
||||||
nghttp2_hd_inflate_new.rst \
|
nghttp2_hd_inflate_new.rst \
|
||||||
nghttp2_hd_inflate_new2.rst \
|
nghttp2_hd_inflate_new2.rst \
|
||||||
nghttp2_http2_strerror.rst \
|
|
||||||
nghttp2_is_fatal.rst \
|
nghttp2_is_fatal.rst \
|
||||||
nghttp2_nv_compare_name.rst \
|
nghttp2_nv_compare_name.rst \
|
||||||
nghttp2_option_del.rst \
|
nghttp2_option_del.rst \
|
||||||
nghttp2_option_new.rst \
|
nghttp2_option_new.rst \
|
||||||
nghttp2_option_set_builtin_recv_extension_type.rst \
|
|
||||||
nghttp2_option_set_max_deflate_dynamic_table_size.rst \
|
|
||||||
nghttp2_option_set_max_reserved_remote_streams.rst \
|
nghttp2_option_set_max_reserved_remote_streams.rst \
|
||||||
nghttp2_option_set_max_send_header_block_length.rst \
|
|
||||||
nghttp2_option_set_no_auto_ping_ack.rst \
|
|
||||||
nghttp2_option_set_no_auto_window_update.rst \
|
nghttp2_option_set_no_auto_window_update.rst \
|
||||||
nghttp2_option_set_no_http_messaging.rst \
|
nghttp2_option_set_no_http_messaging.rst \
|
||||||
nghttp2_option_set_no_recv_client_magic.rst \
|
nghttp2_option_set_no_recv_client_magic.rst \
|
||||||
nghttp2_option_set_peer_max_concurrent_streams.rst \
|
nghttp2_option_set_peer_max_concurrent_streams.rst \
|
||||||
nghttp2_option_set_user_recv_extension_type.rst \
|
|
||||||
nghttp2_pack_settings_payload.rst \
|
nghttp2_pack_settings_payload.rst \
|
||||||
nghttp2_priority_spec_check_default.rst \
|
nghttp2_priority_spec_check_default.rst \
|
||||||
nghttp2_priority_spec_default_init.rst \
|
nghttp2_priority_spec_default_init.rst \
|
||||||
nghttp2_priority_spec_init.rst \
|
nghttp2_priority_spec_init.rst \
|
||||||
nghttp2_rcbuf_decref.rst \
|
|
||||||
nghttp2_rcbuf_get_buf.rst \
|
|
||||||
nghttp2_rcbuf_incref.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_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 \
|
||||||
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst \
|
|
||||||
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst \
|
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
|
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
|
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_header_callback.rst \
|
nghttp2_session_callbacks_set_on_header_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_header_callback2.rst \
|
|
||||||
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
|
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_invalid_header_callback.rst \
|
|
||||||
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst \
|
|
||||||
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
||||||
nghttp2_session_callbacks_set_pack_extension_callback.rst \
|
|
||||||
nghttp2_session_callbacks_set_recv_callback.rst \
|
nghttp2_session_callbacks_set_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_select_padding_callback.rst \
|
nghttp2_session_callbacks_set_select_padding_callback.rst \
|
||||||
nghttp2_session_callbacks_set_send_callback.rst \
|
nghttp2_session_callbacks_set_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_send_data_callback.rst \
|
nghttp2_session_callbacks_set_send_data_callback.rst \
|
||||||
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
|
|
||||||
nghttp2_session_change_stream_priority.rst \
|
|
||||||
nghttp2_session_check_request_allowed.rst \
|
|
||||||
nghttp2_session_check_server_session.rst \
|
|
||||||
nghttp2_session_client_new.rst \
|
nghttp2_session_client_new.rst \
|
||||||
nghttp2_session_client_new2.rst \
|
nghttp2_session_client_new2.rst \
|
||||||
nghttp2_session_client_new3.rst \
|
nghttp2_session_client_new3.rst \
|
||||||
@@ -112,11 +91,7 @@ APIDOCS= \
|
|||||||
nghttp2_session_find_stream.rst \
|
nghttp2_session_find_stream.rst \
|
||||||
nghttp2_session_get_effective_local_window_size.rst \
|
nghttp2_session_get_effective_local_window_size.rst \
|
||||||
nghttp2_session_get_effective_recv_data_length.rst \
|
nghttp2_session_get_effective_recv_data_length.rst \
|
||||||
nghttp2_session_get_hd_deflate_dynamic_table_size.rst \
|
|
||||||
nghttp2_session_get_hd_inflate_dynamic_table_size.rst \
|
|
||||||
nghttp2_session_get_last_proc_stream_id.rst \
|
nghttp2_session_get_last_proc_stream_id.rst \
|
||||||
nghttp2_session_get_local_settings.rst \
|
|
||||||
nghttp2_session_get_local_window_size.rst \
|
|
||||||
nghttp2_session_get_next_stream_id.rst \
|
nghttp2_session_get_next_stream_id.rst \
|
||||||
nghttp2_session_get_outbound_queue_size.rst \
|
nghttp2_session_get_outbound_queue_size.rst \
|
||||||
nghttp2_session_get_remote_settings.rst \
|
nghttp2_session_get_remote_settings.rst \
|
||||||
@@ -125,19 +100,20 @@ APIDOCS= \
|
|||||||
nghttp2_session_get_stream_effective_local_window_size.rst \
|
nghttp2_session_get_stream_effective_local_window_size.rst \
|
||||||
nghttp2_session_get_stream_effective_recv_data_length.rst \
|
nghttp2_session_get_stream_effective_recv_data_length.rst \
|
||||||
nghttp2_session_get_stream_local_close.rst \
|
nghttp2_session_get_stream_local_close.rst \
|
||||||
nghttp2_session_get_stream_local_window_size.rst \
|
|
||||||
nghttp2_session_get_stream_remote_close.rst \
|
nghttp2_session_get_stream_remote_close.rst \
|
||||||
nghttp2_session_get_stream_remote_window_size.rst \
|
nghttp2_session_get_stream_remote_window_size.rst \
|
||||||
nghttp2_session_get_stream_user_data.rst \
|
nghttp2_session_get_stream_user_data.rst \
|
||||||
nghttp2_session_mem_recv.rst \
|
nghttp2_session_mem_recv.rst \
|
||||||
nghttp2_session_mem_send.rst \
|
nghttp2_session_mem_send.rst \
|
||||||
nghttp2_session_recv.rst \
|
nghttp2_session_recv.rst \
|
||||||
|
nghttp2_session_change_stream_priority.rst \
|
||||||
|
nghttp2_session_check_request_allowed.rst \
|
||||||
|
nghttp2_session_check_server_session.rst \
|
||||||
nghttp2_session_resume_data.rst \
|
nghttp2_session_resume_data.rst \
|
||||||
nghttp2_session_send.rst \
|
nghttp2_session_send.rst \
|
||||||
nghttp2_session_server_new.rst \
|
nghttp2_session_server_new.rst \
|
||||||
nghttp2_session_server_new2.rst \
|
nghttp2_session_server_new2.rst \
|
||||||
nghttp2_session_server_new3.rst \
|
nghttp2_session_server_new3.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_terminate_session.rst \
|
nghttp2_session_terminate_session.rst \
|
||||||
@@ -146,7 +122,6 @@ APIDOCS= \
|
|||||||
nghttp2_session_upgrade2.rst \
|
nghttp2_session_upgrade2.rst \
|
||||||
nghttp2_session_want_read.rst \
|
nghttp2_session_want_read.rst \
|
||||||
nghttp2_session_want_write.rst \
|
nghttp2_session_want_write.rst \
|
||||||
nghttp2_set_debug_vprintf_callback.rst \
|
|
||||||
nghttp2_stream_get_first_child.rst \
|
nghttp2_stream_get_first_child.rst \
|
||||||
nghttp2_stream_get_next_sibling.rst \
|
nghttp2_stream_get_next_sibling.rst \
|
||||||
nghttp2_stream_get_parent.rst \
|
nghttp2_stream_get_parent.rst \
|
||||||
@@ -155,9 +130,7 @@ APIDOCS= \
|
|||||||
nghttp2_stream_get_sum_dependency_weight.rst \
|
nghttp2_stream_get_sum_dependency_weight.rst \
|
||||||
nghttp2_stream_get_weight.rst \
|
nghttp2_stream_get_weight.rst \
|
||||||
nghttp2_strerror.rst \
|
nghttp2_strerror.rst \
|
||||||
nghttp2_submit_altsvc.rst \
|
|
||||||
nghttp2_submit_data.rst \
|
nghttp2_submit_data.rst \
|
||||||
nghttp2_submit_extension.rst \
|
|
||||||
nghttp2_submit_goaway.rst \
|
nghttp2_submit_goaway.rst \
|
||||||
nghttp2_submit_headers.rst \
|
nghttp2_submit_headers.rst \
|
||||||
nghttp2_submit_ping.rst \
|
nghttp2_submit_ping.rst \
|
||||||
@@ -172,19 +145,15 @@ APIDOCS= \
|
|||||||
nghttp2_submit_window_update.rst \
|
nghttp2_submit_window_update.rst \
|
||||||
nghttp2_version.rst
|
nghttp2_version.rst
|
||||||
|
|
||||||
RST_FILES = \
|
EXTRA_DIST = \
|
||||||
|
mkapiref.py \
|
||||||
README.rst \
|
README.rst \
|
||||||
programmers-guide.rst \
|
programmers-guide.rst \
|
||||||
|
$(APIDOCS) \
|
||||||
nghttp.1.rst \
|
nghttp.1.rst \
|
||||||
nghttpd.1.rst \
|
nghttpd.1.rst \
|
||||||
nghttpx.1.rst \
|
nghttpx.1.rst \
|
||||||
h2load.1.rst
|
h2load.1.rst \
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
CMakeLists.txt \
|
|
||||||
mkapiref.py \
|
|
||||||
$(RST_FILES) \
|
|
||||||
$(APIDOCS) \
|
|
||||||
sources/index.rst \
|
sources/index.rst \
|
||||||
sources/tutorial-client.rst \
|
sources/tutorial-client.rst \
|
||||||
sources/tutorial-server.rst \
|
sources/tutorial-server.rst \
|
||||||
@@ -258,15 +227,13 @@ help:
|
|||||||
|
|
||||||
apiref.rst: \
|
apiref.rst: \
|
||||||
$(top_builddir)/lib/includes/nghttp2/nghttp2ver.h \
|
$(top_builddir)/lib/includes/nghttp2/nghttp2ver.h \
|
||||||
$(top_srcdir)/lib/includes/nghttp2/nghttp2.h
|
$(top_builddir)/lib/includes/nghttp2/nghttp2.h
|
||||||
for i in $(RST_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
|
|
||||||
$(PYTHON) $(top_srcdir)/doc/mkapiref.py \
|
$(PYTHON) $(top_srcdir)/doc/mkapiref.py \
|
||||||
apiref.rst macros.rst enums.rst types.rst . $^
|
apiref.rst macros.rst enums.rst types.rst . $^
|
||||||
|
|
||||||
$(APIDOCS): apiref.rst
|
$(APIDOCS): apiref.rst
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
[ $(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)/*
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ from docutils import nodes
|
|||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx import version_info
|
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.locale import l_, _
|
from sphinx.locale import l_, _
|
||||||
from sphinx.domains import Domain, ObjType, Index
|
from sphinx.domains import Domain, ObjType, Index
|
||||||
@@ -232,8 +231,8 @@ class RubyObject(ObjectDescription):
|
|||||||
|
|
||||||
indextext = self.get_index_text(modname, name_cls)
|
indextext = self.get_index_text(modname, name_cls)
|
||||||
if indextext:
|
if indextext:
|
||||||
self.indexnode['entries'].append(
|
self.indexnode['entries'].append(('single', indextext,
|
||||||
_make_index('single', indextext, fullname, fullname))
|
fullname, fullname))
|
||||||
|
|
||||||
def before_content(self):
|
def before_content(self):
|
||||||
# needed for automatic qualification of members (reset in subclasses)
|
# needed for automatic qualification of members (reset in subclasses)
|
||||||
@@ -416,19 +415,11 @@ class RubyModule(Directive):
|
|||||||
# modindex currently
|
# modindex currently
|
||||||
if not noindex:
|
if not noindex:
|
||||||
indextext = _('%s (module)') % modname
|
indextext = _('%s (module)') % modname
|
||||||
inode = addnodes.index(entries=[_make_index(
|
inode = addnodes.index(entries=[('single', indextext,
|
||||||
'single', indextext, 'module-' + modname, modname)])
|
'module-' + modname, modname)])
|
||||||
ret.append(inode)
|
ret.append(inode)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def _make_index(entrytype, entryname, target, ignored, key=None):
|
|
||||||
# Sphinx 1.4 introduced backward incompatible changes, it now
|
|
||||||
# requires 5 tuples. Last one is categorization key. See
|
|
||||||
# http://www.sphinx-doc.org/en/stable/extdev/nodes.html#sphinx.addnodes.index
|
|
||||||
if version_info >= (1, 4, 0, '', 0):
|
|
||||||
return (entrytype, entryname, target, ignored, key)
|
|
||||||
else:
|
|
||||||
return (entrytype, entryname, target, ignored)
|
|
||||||
|
|
||||||
class RubyCurrentModule(Directive):
|
class RubyCurrentModule(Directive):
|
||||||
"""
|
"""
|
||||||
|
|||||||
1
doc/_themes/sphinx_rtd_theme/layout.html
vendored
1
doc/_themes/sphinx_rtd_theme/layout.html
vendored
@@ -81,7 +81,6 @@
|
|||||||
|
|
||||||
<body class="wy-body-for-nav" role="document">
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
{% block extrabody %} {% endblock %}
|
|
||||||
<div class="wy-grid-for-nav">
|
<div class="wy-grid-for-nav">
|
||||||
|
|
||||||
{# SIDE NAV, TOGGLES ON MOBILE #}
|
{# SIDE NAV, TOGGLES ON MOBILE #}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -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 --header ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --requests --base-uri --h1 --threads --npn-list --rate-period --data --version --connection-inactivity-timeout --timing-script-file --max-concurrent-streams --connection-active-timeout --input-file --header --window-bits --help ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
@@ -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 --header ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--no-push --verbose --no-dep --get-assets --har --header-table-size --multiply --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 --stat --header ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ _nghttpd()
|
|||||||
_get_comp_words_by_ref cur prev
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --encoder-header-table-size --padding --hexdump --max-concurrent-streams --no-tls --connection-window-bits --mime-types-file --no-content-length --workers --version --color --early-response --dh-param-file --trailer --address --window-bits --verify-client --help ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --padding --hexdump --max-concurrent-streams --no-tls --connection-window-bits --mime-types-file --no-content-length --workers --version --color --early-response --dh-param-file --trailer --address --window-bits --verify-client --help ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
@@ -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 --frontend-keep-alive-timeout --backend-request-buffer --max-request-header-fields --fastopen --tls-ticket-key-memcached --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 --stream-read-timeout --backend-connect-timeout --forwarded-for --accesslog-syslog --dns-cache-timeout --frontend-http2-read-timeout --listener-disable-timeout --ciphers --strip-incoming-x-forwarded-for --no-server-rewrite --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --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 --request-header-field-buffer --api-max-request-body --frontend-http2-decoder-dynamic-table-size --errorlog-file --frontend-http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend --server-name --insecure --backend-max-backoff --log-level --host-rewrite --tls-proto-list --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 --tls-session-cache-memcached --no-ocsp --frontend-http2-encoder-dynamic-table-size --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 --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 --accept-proxy-protocol --tls-dyn-rec-idle-timeout --frontend-http2-optimize-write-buffer-size --verify-client --backend-response-buffer --read-rate --backend-connections-per-frontend --strip-incoming-forwarded ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--worker-read-rate --frontend-no-tls --frontend-http2-dump-response-header --backend-http1-connections-per-frontend --tls-ticket-key-file --verify-client-cacert --include --max-response-header-fields --backend-request-buffer --max-request-header-fields --backend-http2-connection-window-bits --backend-tls-session-cache-per-worker --conf --worker-write-burst --npn-list --fetch-ocsp-response-file --no-http2-cipher-black-list --mruby-file --stream-read-timeout --tls-ticket-key-memcached --forwarded-for --accesslog-syslog --frontend-http2-read-timeout --listener-disable-timeout --frontend-http2-connection-window-bits --ciphers --strip-incoming-x-forwarded-for --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --backend-http1-connections-per-host --rlimit-nofile --tls-dyn-rec-warmup-threshold --no-via --ocsp-update-interval --backend-write-timeout --client --tls-ticket-key-memcached-max-retry --http2-no-cookie-crumbling --worker-read-burst --client-proxy --http2-bridge --accesslog-format --errorlog-syslog --request-header-field-buffer --errorlog-file --http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend-ipv4 --backend-ipv6 --backend --insecure --log-level --host-rewrite --tls-proto-list --backend-http2-connections-per-worker --tls-ticket-key-memcached-interval --dh-param-file --worker-frontend-connections --backend-http1-tls --syslog-facility --fastopen --no-location-rewrite --tls-session-cache-memcached --no-ocsp --backend-response-buffer --workers --add-forwarded --frontend-http2-window-bits --worker-write-rate --add-request-header --backend-tls-sni-field --subcert --help --frontend-frame-debug --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --user --add-x-forwarded-for --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --no-server-push --backend-http2-window-bits --response-header-field-buffer --padding --stream-write-timeout --cacert --forwarded-by --version --add-response-header --backend-read-timeout --frontend --accesslog-file --http2-proxy --backend-no-tls --client-private-key-file --client-cert-file --accept-proxy-protocol --tls-dyn-rec-idle-timeout --verify-client --read-rate --strip-incoming-forwarded ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import sys, os
|
|||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
#sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
sys.path.append(os.path.abspath('@top_srcdir@/doc/_exts'))
|
sys.path.append(os.path.abspath('_exts'))
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
30
doc/h2load.1
30
doc/h2load.1
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "H2LOAD" "1" "Jan 05, 2017" "1.18.1" "nghttp2"
|
.TH "H2LOAD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
h2load \- HTTP/2 benchmarking tool
|
h2load \- HTTP/2 benchmarking tool
|
||||||
.
|
.
|
||||||
@@ -138,9 +138,7 @@ Default: \fBh2c\fP
|
|||||||
.TP
|
.TP
|
||||||
.B \-d, \-\-data=<PATH>
|
.B \-d, \-\-data=<PATH>
|
||||||
Post FILE to server. The request method is changed to
|
Post FILE to server. The request method is changed to
|
||||||
POST. For http/1.1 connection, if \fI\%\-d\fP is used, the
|
POST.
|
||||||
maximum number of in\-flight pipelined requests is set to
|
|
||||||
1.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -151,7 +149,7 @@ representing the number of connections to be made per
|
|||||||
rate period. The maximum number of connections to be
|
rate period. The maximum number of connections to be
|
||||||
made is given in \fI\%\-c\fP option. This rate will be
|
made is given in \fI\%\-c\fP option. This rate will be
|
||||||
distributed among threads as evenly as possible. For
|
distributed among threads as evenly as possible. For
|
||||||
example, with \fI\%\-t\fP2 and \fI\%\-r\fP4, each thread gets 2
|
example, with \fB\-t2\fP and \fB\-r4\fP, 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
|
||||||
@@ -242,23 +240,6 @@ http/1.1 for both http and https URI.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-header\-table\-size=<SIZE>
|
|
||||||
Specify decoder header table size.
|
|
||||||
.sp
|
|
||||||
Default: \fB4K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-encoder\-header\-table\-size=<SIZE>
|
|
||||||
Specify encoder header table size. The decoder (server)
|
|
||||||
specifies the maximum dynamic table size it accepts.
|
|
||||||
Then the negotiated dynamic table size is the minimum of
|
|
||||||
this option value and the value which server specified.
|
|
||||||
.sp
|
|
||||||
Default: \fB4K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-v, \-\-verbose
|
.B \-v, \-\-verbose
|
||||||
Output debug information.
|
Output debug information.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -273,9 +254,6 @@ Display version information and exit.
|
|||||||
Display this help and exit.
|
Display this help and exit.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.sp
|
.sp
|
||||||
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
|
||||||
10 * 1024). Units are K, M and G (powers of 1024).
|
|
||||||
.sp
|
|
||||||
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
||||||
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
||||||
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
||||||
@@ -434,7 +412,7 @@ performance. To set smaller flow control window, use \fI\%\-w\fP and
|
|||||||
window size described in HTTP/2 and SPDY 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
|
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fInghttpx(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ 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.
|
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. For SPDY, if <N> is strictly less than 16,
|
(2**<N>)-1. For SPDY, if <N> is strictly less than 16,
|
||||||
this option is ignored. Otherwise 2\*\*<N> is used for
|
this option is ignored. Otherwise 2\*\*<N> is used for
|
||||||
SPDY.
|
SPDY.
|
||||||
|
|
||||||
@@ -108,9 +108,7 @@ OPTIONS
|
|||||||
.. option:: -d, --data=<PATH>
|
.. option:: -d, --data=<PATH>
|
||||||
|
|
||||||
Post FILE to server. The request method is changed to
|
Post FILE to server. The request method is changed to
|
||||||
POST. For http/1.1 connection, if :option:`-d` is used, the
|
POST.
|
||||||
maximum number of in-flight pipelined requests is set to
|
|
||||||
1.
|
|
||||||
|
|
||||||
.. option:: -r, --rate=<N>
|
.. option:: -r, --rate=<N>
|
||||||
|
|
||||||
@@ -120,7 +118,7 @@ OPTIONS
|
|||||||
rate period. The maximum number of connections to be
|
rate period. The maximum number of connections to be
|
||||||
made is given in :option:`-c` option. This rate will be
|
made is given in :option:`-c` option. This rate will be
|
||||||
distributed among threads as evenly as possible. For
|
distributed among threads as evenly as possible. For
|
||||||
example, with :option:`-t`\2 and :option:`-r`\4, each thread gets 2
|
example, with :option:`-t2` and :option:`\-r4`, 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
|
||||||
@@ -202,21 +200,6 @@ OPTIONS
|
|||||||
:option:`--no-tls-proto`\=http/1.1, which effectively force
|
:option:`--no-tls-proto`\=http/1.1, which effectively force
|
||||||
http/1.1 for both http and https URI.
|
http/1.1 for both http and https URI.
|
||||||
|
|
||||||
.. option:: --header-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify decoder header table size.
|
|
||||||
|
|
||||||
Default: ``4K``
|
|
||||||
|
|
||||||
.. option:: --encoder-header-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify encoder header table size. The decoder (server)
|
|
||||||
specifies the maximum dynamic table size it accepts.
|
|
||||||
Then the negotiated dynamic table size is the minimum of
|
|
||||||
this option value and the value which server specified.
|
|
||||||
|
|
||||||
Default: ``4K``
|
|
||||||
|
|
||||||
.. option:: -v, --verbose
|
.. option:: -v, --verbose
|
||||||
|
|
||||||
Output debug information.
|
Output debug information.
|
||||||
@@ -231,9 +214,6 @@ OPTIONS
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
|
||||||
10 * 1024). Units are K, M and G (powers of 1024).
|
|
||||||
|
|
||||||
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
||||||
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
||||||
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
||||||
|
|||||||
29
doc/nghttp.1
29
doc/nghttp.1
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "NGHTTP" "1" "Jan 05, 2017" "1.18.1" "nghttp2"
|
.TH "NGHTTP" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttp \- HTTP/2 client
|
nghttp \- HTTP/2 client
|
||||||
.
|
.
|
||||||
@@ -142,13 +142,10 @@ HTTP upgrade request is performed with OPTIONS method.
|
|||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-p, \-\-weight=<WEIGHT>
|
.B \-p, \-\-weight=<WEIGHT>
|
||||||
Sets weight of given URI. This option can be used
|
Sets priority group weight. The valid value range is
|
||||||
multiple times, and N\-th \fI\%\-p\fP option sets weight of N\-th
|
|
||||||
URI in the command line. If the number of \fI\%\-p\fP option is
|
|
||||||
less than the number of URI, the last \fI\%\-p\fP option value is
|
|
||||||
repeated. If there is no \fI\%\-p\fP option, default weight, 16,
|
|
||||||
is assumed. The valid value range is
|
|
||||||
[1, 256], inclusive.
|
[1, 256], inclusive.
|
||||||
|
.sp
|
||||||
|
Default: \fB16\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -170,14 +167,6 @@ multiple header table size change.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-encoder\-header\-table\-size=<SIZE>
|
|
||||||
Specify encoder header table size. The decoder (server)
|
|
||||||
specifies the maximum dynamic table size it accepts.
|
|
||||||
Then the negotiated dynamic table size is the minimum of
|
|
||||||
this option value and the value which server specified.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-b, \-\-padding=<N>
|
.B \-b, \-\-padding=<N>
|
||||||
Add at most <N> bytes to a frame payload as padding.
|
Add at most <N> bytes to a frame payload as padding.
|
||||||
Specify 0 to disable padding.
|
Specify 0 to disable padding.
|
||||||
@@ -228,14 +217,6 @@ accepts.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-expect\-continue
|
|
||||||
Perform an Expect/Continue handshake: wait to send DATA
|
|
||||||
(up to a short timeout) until the server sends a 100
|
|
||||||
Continue interim response. This option is ignored unless
|
|
||||||
combined with the \fI\%\-d\fP option.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-version
|
.B \-\-version
|
||||||
Display version information and exit.
|
Display version information and exit.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -311,7 +292,7 @@ stream 11 with the weight 12. The other resources (e.g., icon) depend
|
|||||||
on stream 11 with the weight 2.
|
on stream 11 with the weight 2.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
\fBnghttpd(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
\fInghttpd(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -107,14 +107,11 @@ OPTIONS
|
|||||||
|
|
||||||
.. option:: -p, --weight=<WEIGHT>
|
.. option:: -p, --weight=<WEIGHT>
|
||||||
|
|
||||||
Sets weight of given URI. This option can be used
|
Sets priority group weight. The valid value range is
|
||||||
multiple times, and N-th :option:`-p` option sets weight of N-th
|
|
||||||
URI in the command line. If the number of :option:`-p` option is
|
|
||||||
less than the number of URI, the last :option:`-p` option value is
|
|
||||||
repeated. If there is no :option:`-p` option, default weight, 16,
|
|
||||||
is assumed. The valid value range is
|
|
||||||
[1, 256], inclusive.
|
[1, 256], inclusive.
|
||||||
|
|
||||||
|
Default: ``16``
|
||||||
|
|
||||||
.. option:: -M, --peer-max-concurrent-streams=<N>
|
.. option:: -M, --peer-max-concurrent-streams=<N>
|
||||||
|
|
||||||
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
|
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||||
@@ -131,13 +128,6 @@ OPTIONS
|
|||||||
frame payload before the last value, to simulate
|
frame payload before the last value, to simulate
|
||||||
multiple header table size change.
|
multiple header table size change.
|
||||||
|
|
||||||
.. option:: --encoder-header-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify encoder header table size. The decoder (server)
|
|
||||||
specifies the maximum dynamic table size it accepts.
|
|
||||||
Then the negotiated dynamic table size is the minimum of
|
|
||||||
this option value and the value which server specified.
|
|
||||||
|
|
||||||
.. option:: -b, --padding=<N>
|
.. option:: -b, --padding=<N>
|
||||||
|
|
||||||
Add at most <N> bytes to a frame payload as padding.
|
Add at most <N> bytes to a frame payload as padding.
|
||||||
@@ -179,13 +169,6 @@ OPTIONS
|
|||||||
The number of concurrent pushed streams this client
|
The number of concurrent pushed streams this client
|
||||||
accepts.
|
accepts.
|
||||||
|
|
||||||
.. option:: --expect-continue
|
|
||||||
|
|
||||||
Perform an Expect/Continue handshake: wait to send DATA
|
|
||||||
(up to a short timeout) until the server sends a 100
|
|
||||||
Continue interim response. This option is ignored unless
|
|
||||||
combined with the :option:`-d` option.
|
|
||||||
|
|
||||||
.. option:: --version
|
.. option:: --version
|
||||||
|
|
||||||
Display version information and exit.
|
Display version information and exit.
|
||||||
@@ -218,9 +201,7 @@ implementation.
|
|||||||
|
|
||||||
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
||||||
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
||||||
tree:
|
tree::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
+-----+
|
+-----+
|
||||||
|id=0 |
|
|id=0 |
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ implementation.
|
|||||||
|
|
||||||
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
||||||
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
||||||
tree:
|
tree::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
+-----+
|
+-----+
|
||||||
|id=0 |
|
|id=0 |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "NGHTTPD" "1" "Jan 05, 2017" "1.18.1" "nghttp2"
|
.TH "NGHTTPD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttpd \- HTTP/2 server
|
nghttpd \- HTTP/2 server
|
||||||
.
|
.
|
||||||
@@ -99,14 +99,6 @@ Specify decoder header table size.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-encoder\-header\-table\-size=<SIZE>
|
|
||||||
Specify encoder header table size. The decoder (client)
|
|
||||||
specifies the maximum dynamic table size it accepts.
|
|
||||||
Then the negotiated dynamic table size is the minimum of
|
|
||||||
this option value and the value which client specified.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-color
|
.B \-\-color
|
||||||
Force colored log output.
|
Force colored log output.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -217,7 +209,7 @@ The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
|||||||
10 * 1024). Units are K, M and G (powers of 1024).
|
10 * 1024). Units are K, M and G (powers of 1024).
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
\fBnghttp(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
\fInghttp(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -70,13 +70,6 @@ OPTIONS
|
|||||||
|
|
||||||
Specify decoder header table size.
|
Specify decoder header table size.
|
||||||
|
|
||||||
.. option:: --encoder-header-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify encoder header table size. The decoder (client)
|
|
||||||
specifies the maximum dynamic table size it accepts.
|
|
||||||
Then the negotiated dynamic table size is the minimum of
|
|
||||||
this option value and the value which client specified.
|
|
||||||
|
|
||||||
.. option:: --color
|
.. option:: --color
|
||||||
|
|
||||||
Force colored log output.
|
Force colored log output.
|
||||||
|
|||||||
800
doc/nghttpx.1
800
doc/nghttpx.1
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
163
doc/nghttpx.h2r
163
doc/nghttpx.h2r
@@ -41,33 +41,6 @@ FILES
|
|||||||
:option:`--conf` option cannot be used in the configuration file and
|
:option:`--conf` option cannot be used in the configuration file and
|
||||||
will be ignored if specified.
|
will be ignored if specified.
|
||||||
|
|
||||||
Error log
|
|
||||||
Error log is written to stderr by default. It can be configured
|
|
||||||
using :option:`--errorlog-file`. The format of log message is as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
<datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
|
|
||||||
|
|
||||||
<datetime>
|
|
||||||
It is a conbination of date and time when the log is written. It
|
|
||||||
is in ISO 8601 format.
|
|
||||||
|
|
||||||
<master-pid>
|
|
||||||
It is a master process ID.
|
|
||||||
|
|
||||||
<current-pid>
|
|
||||||
It is a process ID which writes this log.
|
|
||||||
|
|
||||||
<thread-id>
|
|
||||||
It is a thread ID which writes this log. It would be unique
|
|
||||||
within <current-pid>.
|
|
||||||
|
|
||||||
<filename> and <line>
|
|
||||||
They are source file name, and line number which produce this log.
|
|
||||||
|
|
||||||
<msg>
|
|
||||||
It is a log message body.
|
|
||||||
|
|
||||||
SIGNALS
|
SIGNALS
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -76,9 +49,6 @@ SIGQUIT
|
|||||||
accepting connection. After all connections are handled, nghttpx
|
accepting connection. After all connections are handled, nghttpx
|
||||||
exits.
|
exits.
|
||||||
|
|
||||||
SIGHUP
|
|
||||||
Reload configuration file given in :option:`--conf`.
|
|
||||||
|
|
||||||
SIGUSR1
|
SIGUSR1
|
||||||
Reopen log files.
|
Reopen log files.
|
||||||
|
|
||||||
@@ -86,11 +56,7 @@ SIGUSR2
|
|||||||
Fork and execute nghttpx. It will execute the binary in the same
|
Fork and execute nghttpx. It will execute the binary in the same
|
||||||
path with same command-line arguments and environment variables.
|
path with same command-line arguments and environment variables.
|
||||||
After new process comes up, sending SIGQUIT to the original process
|
After new process comes up, sending SIGQUIT to the original process
|
||||||
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
|
to perform hot swapping.
|
||||||
and SIGHUP is that former is usually used to execute new binary, and
|
|
||||||
the master process is newly spawned. On the other hand, the latter
|
|
||||||
just reloads configuration file, and the same master process
|
|
||||||
continues to exist.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@@ -119,7 +85,7 @@ backend server and extracts URI-reference with parameter
|
|||||||
and pushes those URIs to the frontend client. Here is a sample Link
|
and pushes those URIs to the frontend client. Here is a sample Link
|
||||||
header field to initiate server push:
|
header field to initiate server push:
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: http
|
||||||
|
|
||||||
Link: </fonts/font.woff>; rel=preload
|
Link: </fonts/font.woff>; rel=preload
|
||||||
Link: </css/theme.css>; rel=preload
|
Link: </css/theme.css>; rel=preload
|
||||||
@@ -132,12 +98,12 @@ Currently, the following restriction is applied for server push:
|
|||||||
This limitation may be loosened in the future release.
|
This limitation may be loosened in the future release.
|
||||||
|
|
||||||
nghttpx also supports server push if both frontend and backend are
|
nghttpx also supports server push if both frontend and backend are
|
||||||
HTTP/2 in default mode. In this case, in addition to server push via
|
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
|
||||||
Link header field, server push from backend is forwarded to frontend
|
In this case, in addition to server push via Link header field, server
|
||||||
HTTP/2 session.
|
push from backend is relayed to frontend HTTP/2 session.
|
||||||
|
|
||||||
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
|
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
|
||||||
used.
|
:option:`--client-proxy` is used.
|
||||||
|
|
||||||
UNIX DOMAIN SOCKET
|
UNIX DOMAIN SOCKET
|
||||||
------------------
|
------------------
|
||||||
@@ -184,10 +150,6 @@ insert serialized session data to memcached with
|
|||||||
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.
|
||||||
|
|
||||||
By default, connections to memcached server are not encrypted. To
|
|
||||||
enable encryption, use ``tls`` keyword in
|
|
||||||
:option:`--tls-session-cache-memcached` option.
|
|
||||||
|
|
||||||
TLS SESSION TICKET RESUMPTION
|
TLS SESSION TICKET RESUMPTION
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -227,33 +189,11 @@ used, LEN must be 48. If
|
|||||||
keys. The key appeared first is used as encryption key. All the
|
keys. The key appeared first is used as encryption key. All the
|
||||||
remaining keys are used as decryption only.
|
remaining keys are used as decryption only.
|
||||||
|
|
||||||
By default, connections to memcached server are not encrypted. To
|
|
||||||
enable encryption, use ``tls`` keyword in
|
|
||||||
:option:`--tls-ticket-key-memcached` option.
|
|
||||||
|
|
||||||
If :option:`--tls-ticket-key-file` is given, encryption key is read
|
If :option:`--tls-ticket-key-file` is given, encryption key is read
|
||||||
from the given file. In this case, nghttpx does not rotate key
|
from the given file. In this case, nghttpx does not rotate key
|
||||||
automatically. To rotate key, one has to restart nghttpx (see
|
automatically. To rotate key, one has to restart nghttpx (see
|
||||||
SIGNALS).
|
SIGNALS).
|
||||||
|
|
||||||
CERTIFICATE TRANSPARENCY
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
nghttpx supports TLS ``signed_certificate_timestamp`` extension (`RFC
|
|
||||||
6962 <https://tools.ietf.org/html/rfc6962>`_). The relevant options
|
|
||||||
are :option:`--tls-sct-dir` and ``sct-dir`` parameter in
|
|
||||||
:option:`--subcert`. They takes a directory, and nghttpx reads all
|
|
||||||
files whose extension is ``.sct`` under the directory. The ``*.sct``
|
|
||||||
files are encoded as ``SignedCertificateTimestamp`` struct described
|
|
||||||
in `section 3.2 of RFC 69662
|
|
||||||
<https://tools.ietf.org/html/rfc6962#section-3.2>`_. This format is
|
|
||||||
the same one used by `nginx-ct
|
|
||||||
<https://github.com/grahamedgecombe/nginx-ct>`_ and `mod_ssl_ct
|
|
||||||
<https://httpd.apache.org/docs/trunk/mod/mod_ssl_ct.html>`_.
|
|
||||||
`ct-submit <https://github.com/grahamedgecombe/ct-submit>`_ can be
|
|
||||||
used to submit certificates to log servers, and obtain the
|
|
||||||
``SignedCertificateTimestamp`` struct which can be used with nghttpx.
|
|
||||||
|
|
||||||
MRUBY SCRIPTING
|
MRUBY SCRIPTING
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@@ -317,28 +257,7 @@ respectively.
|
|||||||
|
|
||||||
.. rb:attr_reader:: remote_addr
|
.. rb:attr_reader:: remote_addr
|
||||||
|
|
||||||
Return IP address of a remote client. If connection is made
|
Return IP address of a remote client.
|
||||||
via UNIX domain socket, this returns the string "localhost".
|
|
||||||
|
|
||||||
.. rb:attr_reader:: server_addr
|
|
||||||
|
|
||||||
Return address of server that accepted the connection. This
|
|
||||||
is a string which specified in :option:`--frontend` option,
|
|
||||||
excluding port number, and not a resolved IP address. For
|
|
||||||
UNIX domain socket, this is a path to UNIX domain socket.
|
|
||||||
|
|
||||||
.. rb:attr_reader:: server_port
|
|
||||||
|
|
||||||
Return port number of the server frontend which accepted the
|
|
||||||
connection from client.
|
|
||||||
|
|
||||||
.. rb:attr_reader:: tls_used
|
|
||||||
|
|
||||||
Return true if TLS is used on the connection.
|
|
||||||
|
|
||||||
.. rb:attr_reader:: tls_sni
|
|
||||||
|
|
||||||
Return the TLS SNI value which client sent in this connection.
|
|
||||||
|
|
||||||
.. rb:class:: Request
|
.. rb:class:: Request
|
||||||
|
|
||||||
@@ -374,13 +293,7 @@ respectively.
|
|||||||
|
|
||||||
Request path, including query component (i.e., /index.html).
|
Request path, including query component (i.e., /index.html).
|
||||||
On assignment, copy of given value is assigned. The path does
|
On assignment, copy of given value is assigned. The path does
|
||||||
not include authority component of URI. This may include
|
not include authority component of URI.
|
||||||
query component. nghttpx makes certain normalization for
|
|
||||||
path. It decodes percent-encoding for unreserved characters
|
|
||||||
(see https://tools.ietf.org/html/rfc3986#section-2.3), and
|
|
||||||
resolves ".." and ".". But it may leave characters which
|
|
||||||
should be percent-encoded as is. So be careful when comparing
|
|
||||||
path against desired string.
|
|
||||||
|
|
||||||
.. rb:attr_reader:: headers
|
.. rb:attr_reader:: headers
|
||||||
|
|
||||||
@@ -407,7 +320,7 @@ respectively.
|
|||||||
|
|
||||||
Clear all existing request header fields.
|
Clear all existing request header fields.
|
||||||
|
|
||||||
.. rb:method:: push(uri)
|
.. rb:method:: push uri
|
||||||
|
|
||||||
Initiate to push resource identified by *uri*. Only HTTP/2
|
Initiate to push resource identified by *uri*. Only HTTP/2
|
||||||
protocol supports this feature. For the other protocols, this
|
protocol supports this feature. For the other protocols, this
|
||||||
@@ -518,62 +431,6 @@ addresses:
|
|||||||
|
|
||||||
App.new
|
App.new
|
||||||
|
|
||||||
API ENDPOINTS
|
|
||||||
-------------
|
|
||||||
|
|
||||||
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
|
|
||||||
default, API endpoint is disabled. To enable it, add a dedicated
|
|
||||||
frontend for API using :option:`--frontend` option with "api"
|
|
||||||
parameter. All requests which come from this frontend address, will
|
|
||||||
be treated as API request.
|
|
||||||
|
|
||||||
The response is normally JSON dictionary, and at least includes the
|
|
||||||
following keys:
|
|
||||||
|
|
||||||
status
|
|
||||||
The status of the request processing. The following values are
|
|
||||||
defined:
|
|
||||||
|
|
||||||
Success
|
|
||||||
The request was successful.
|
|
||||||
|
|
||||||
Failure
|
|
||||||
The request was failed. No change has been made.
|
|
||||||
|
|
||||||
code
|
|
||||||
HTTP status code
|
|
||||||
|
|
||||||
We wrote "normally", since nghttpx may return ordinal HTML response in
|
|
||||||
some cases where the error has occurred before reaching API endpoint
|
|
||||||
(e.g., header field is too large).
|
|
||||||
|
|
||||||
The following section describes available API endpoints.
|
|
||||||
|
|
||||||
PUT /api/v1beta1/backendconfig
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This API replaces the current backend server settings with the
|
|
||||||
requested ones. The request method should be PUT, but POST is also
|
|
||||||
acceptable. The request body must be nghttpx configuration file
|
|
||||||
format. For configuration file format, see `FILES`_ section. The
|
|
||||||
line separator inside the request body must be single LF (0x0A).
|
|
||||||
Currently, only :option:`backend <--backend>` option is parsed, the
|
|
||||||
others are simply ignored. The semantics of this API is replace the
|
|
||||||
current backend with the backend options in request body. Describe
|
|
||||||
the desired set of backend severs, and nghttpx makes it happen. If
|
|
||||||
there is no :option:`backend <--backend>` option is found in request
|
|
||||||
body, the current set of backend is replaced with the :option:`backend
|
|
||||||
<--backend>` option's default value, which is ``127.0.0.1,80``.
|
|
||||||
|
|
||||||
The replacement is done instantly without breaking existing
|
|
||||||
connections or requests. It also avoids any process creation as is
|
|
||||||
the case with hot swapping with signals.
|
|
||||||
|
|
||||||
The one limitation is that only numeric IP address is allowd in
|
|
||||||
:option:`backend <--backend>` in request body unless "dns" parameter
|
|
||||||
is used while non numeric hostname is allowed in command-line or
|
|
||||||
configuration file is read using :option:`--conf`.
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@@ -1,79 +1,6 @@
|
|||||||
Programmers' Guide
|
Programmers' Guide
|
||||||
==================
|
==================
|
||||||
|
|
||||||
Architecture
|
|
||||||
------------
|
|
||||||
|
|
||||||
The most notable point in nghttp2 library architecture is it does not
|
|
||||||
perform any I/O. nghttp2 only performs HTTP/2 protocol stuff based on
|
|
||||||
input byte strings. It will calls callback functions set by
|
|
||||||
applications while processing input. The output of nghttp2 is just
|
|
||||||
byte string. An application is responsible to send these output to
|
|
||||||
the remote peer. The callback functions may be called while producing
|
|
||||||
output.
|
|
||||||
|
|
||||||
Not doing I/O makes embedding nghttp2 library in the existing code
|
|
||||||
base very easy. Usually, the existing applications have its own I/O
|
|
||||||
event loops. It is very hard to use nghttp2 in that situation if
|
|
||||||
nghttp2 does its own I/O. It also makes light weight language wrapper
|
|
||||||
for nghttp2 easy with the same reason. The down side is that an
|
|
||||||
application author has to write more code to write complete
|
|
||||||
application using nghttp2. This is especially true for simple "toy"
|
|
||||||
application. For the real applications, however, this is not the
|
|
||||||
case. This is because you probably want to support HTTP/1 which
|
|
||||||
nghttp2 does not provide, and to do that, you will need to write your
|
|
||||||
own HTTP/1 stack or use existing third-party library, and bind them
|
|
||||||
together with nghttp2 and I/O event loop. In this point, not
|
|
||||||
performing I/O in nghttp2 has more point than doing it.
|
|
||||||
|
|
||||||
The primary object that an application uses is :type:`nghttp2_session`
|
|
||||||
object, which is opaque struct and its details are hidden in order to
|
|
||||||
ensure the upgrading its internal architecture without breaking the
|
|
||||||
backward compatibility. An application can set callbacks to
|
|
||||||
:type:`nghttp2_session` object through the dedicated object and
|
|
||||||
functions, and it also interacts with it via many API function calls.
|
|
||||||
|
|
||||||
An application can create as many :type:`nghttp2_session` object as it
|
|
||||||
wants. But single :type:`nghttp2_session` object must be used by a
|
|
||||||
single thread at the same time. This is not so hard to enforce since
|
|
||||||
most event-based architecture applications use is single thread per
|
|
||||||
core, and handling one connection I/O is done by single thread.
|
|
||||||
|
|
||||||
To feed input to :type:`nghttp2_session` object, one can use
|
|
||||||
`nghttp2_session_recv()` or `nghttp2_session_mem_recv()` functions.
|
|
||||||
They behave similarly, and the difference is that
|
|
||||||
`nghttp2_session_recv()` will use :type:`nghttp2_read_callback` to get
|
|
||||||
input. On the other hand, `nghttp2_session_mem_recv()` will take
|
|
||||||
input as its parameter. If in doubt, use `nghttp2_session_mem_recv()`
|
|
||||||
since it is simpler, and could be faster since it avoids calling
|
|
||||||
callback function.
|
|
||||||
|
|
||||||
To get output from :type:`nghttp2_session` object, one can use
|
|
||||||
`nghttp2_session_send()` or `nghttp2_session_mem_send()`. The
|
|
||||||
difference between them is that the former uses
|
|
||||||
:type:`nghttp2_send_callback` to pass output to an application. On
|
|
||||||
the other hand, the latter returns the output to the caller. If in
|
|
||||||
doubt, use `nghttp2_session_mem_send()` since it is simpler. But
|
|
||||||
`nghttp2_session_send()` might be easier to use if the output buffer
|
|
||||||
an application has is fixed sized.
|
|
||||||
|
|
||||||
In general, an application should call `nghttp2_session_mem_send()`
|
|
||||||
when it gets input from underlying connection. Since there is great
|
|
||||||
chance to get something pushed into transmission queue while the call
|
|
||||||
of `nghttp2_session_mem_send()`, it is recommended to call
|
|
||||||
`nghttp2_session_mem_recv()` after `nghttp2_session_mem_send()`.
|
|
||||||
|
|
||||||
There is a question when we are safe to close HTTP/2 session without
|
|
||||||
waiting for the closure of underlying connection. We offer 2 API
|
|
||||||
calls for this: `nghttp2_session_want_read()` and
|
|
||||||
`nghttp2_session_want_write()`. If they both return 0, application
|
|
||||||
can destroy :type:`nghttp2_session`, and then close the underlying
|
|
||||||
connection. But make sure that the buffered output has been
|
|
||||||
transmitted to the peer before closing the connection when
|
|
||||||
`nghttp2_session_mem_send()` is used, since
|
|
||||||
`nghttp2_session_want_write()` does not take into account the
|
|
||||||
transmission of the buffered data outside of :type:`nghttp2_session`.
|
|
||||||
|
|
||||||
Includes
|
Includes
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -173,308 +100,6 @@ parsed as 64 bit signed integer. The sum of data length in the
|
|||||||
following DATA frames must match with the number in "Content-Length"
|
following DATA frames must match with the number in "Content-Length"
|
||||||
header field if it is present (this does not include padding bytes).
|
header field if it is present (this does not include padding bytes).
|
||||||
|
|
||||||
RFC 7230 says that server must not send "Content-Length" in any
|
|
||||||
response with 1xx, and 204 status code. It also says that
|
|
||||||
"Content-Length" is not allowed in any response with 200 status code
|
|
||||||
to a CONNECT request. nghttp2 enforces them as well.
|
|
||||||
|
|
||||||
Any deviation results in stream error of type PROTOCOL_ERROR. If
|
Any deviation results in stream error of type PROTOCOL_ERROR. If
|
||||||
error is found in PUSH_PROMISE frame, stream error is raised against
|
error is found in PUSH_PROMISE frame, stream error is raised against
|
||||||
promised stream.
|
promised stream.
|
||||||
|
|
||||||
The order of transmission of the HTTP/2 frames
|
|
||||||
----------------------------------------------
|
|
||||||
|
|
||||||
This section describes the internals of libnghttp2 about the
|
|
||||||
scheduling of transmission of HTTP/2 frames. This is pretty much
|
|
||||||
internal stuff, so the details could change in the future versions of
|
|
||||||
the library.
|
|
||||||
|
|
||||||
libnghttp2 categorizes HTTP/2 frames into 4 categories: urgent,
|
|
||||||
regular, syn_stream, and data in the order of higher priority.
|
|
||||||
|
|
||||||
The urgent category includes PING and SETTINGS. They are sent with
|
|
||||||
highest priority. The order inside the category is FIFO.
|
|
||||||
|
|
||||||
The regular category includes frames other than PING, SETTINGS, DATA,
|
|
||||||
and HEADERS which does not create stream (which counts toward
|
|
||||||
concurrent stream limit). The order inside the category is FIFO.
|
|
||||||
|
|
||||||
The syn_stream category includes HEADERS frame which creates stream,
|
|
||||||
that counts toward the concurrent stream limit.
|
|
||||||
|
|
||||||
The data category includes DATA frame, and the scheduling among DATA
|
|
||||||
frames are determined by HTTP/2 dependency tree.
|
|
||||||
|
|
||||||
If the application wants to send frames in the specific order, and the
|
|
||||||
default transmission order does not fit, it has to schedule frames by
|
|
||||||
itself using the callbacks (e.g.,
|
|
||||||
:type:`nghttp2_on_frame_send_callback`).
|
|
||||||
|
|
||||||
RST_STREAM has special side effect when it is submitted by
|
|
||||||
`nghttp2_submit_rst_stream()`. It cancels all pending HEADERS and
|
|
||||||
DATA frames whose stream ID matches the one in the RST_STREAM frame.
|
|
||||||
This may cause unexpected behaviour for the application in some cases.
|
|
||||||
For example, suppose that application wants to send RST_STREAM after
|
|
||||||
sending response HEADERS and DATA. Because of the reason we mentioned
|
|
||||||
above, the following code does not work:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_submit_response(...)
|
|
||||||
nghttp2_submit_rst_stream(...)
|
|
||||||
|
|
||||||
RST_STREAM cancels HEADERS (and DATA), and just RST_STREAM is sent.
|
|
||||||
The correct way is use :type:`nghttp2_on_frame_send_callback`, and
|
|
||||||
after HEADERS and DATA frames are sent, issue
|
|
||||||
`nghttp2_submit_rst_stream()`. FYI,
|
|
||||||
:type:`nghttp2_on_frame_not_send_callback` tells you why frames are
|
|
||||||
not sent.
|
|
||||||
|
|
||||||
Implement user defined HTTP/2 non-critical extensions
|
|
||||||
-----------------------------------------------------
|
|
||||||
|
|
||||||
As of nghttp2 v1.8.0, we have added HTTP/2 non-critical extension
|
|
||||||
framework, which lets application send and receive user defined custom
|
|
||||||
HTTP/2 non-critical extension frames. nghttp2 also offers built-in
|
|
||||||
functionality to send and receive official HTTP/2 extension frames
|
|
||||||
(e.g., ALTSVC frame). For these built-in handler, refer to the next
|
|
||||||
section.
|
|
||||||
|
|
||||||
To send extension frame, use `nghttp2_submit_extension()`, and
|
|
||||||
implement :type:`nghttp2_pack_extension_callback`. The callback
|
|
||||||
implements how to encode data into wire format. The callback must be
|
|
||||||
set to :type:`nghttp2_session_callbacks` using
|
|
||||||
`nghttp2_session_callbacks_set_pack_extension_callback()`.
|
|
||||||
|
|
||||||
For example, we will illustrate how to send `ALTSVC
|
|
||||||
<https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-14>`_ frame.
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char *origin;
|
|
||||||
const char *field;
|
|
||||||
} alt_svc;
|
|
||||||
|
|
||||||
ssize_t pack_extension_callback(nghttp2_session *session, uint8_t *buf,
|
|
||||||
size_t len, const nghttp2_frame *frame,
|
|
||||||
void *user_data) {
|
|
||||||
const alt_svc *altsvc = (const alt_svc *)frame->ext.payload;
|
|
||||||
size_t originlen = strlen(altsvc->origin);
|
|
||||||
size_t fieldlen = strlen(altsvc->field);
|
|
||||||
|
|
||||||
uint8_t *p;
|
|
||||||
|
|
||||||
if (len < 2 + originlen + fieldlen || originlen > 0xffff) {
|
|
||||||
return NGHTTP2_ERR_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = buf;
|
|
||||||
*p++ = originlen >> 8;
|
|
||||||
*p++ = originlen & 0xff;
|
|
||||||
memcpy(p, altsvc->origin, originlen);
|
|
||||||
p += originlen;
|
|
||||||
memcpy(p, altsvc->field, fieldlen);
|
|
||||||
p += fieldlen;
|
|
||||||
|
|
||||||
return p - buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
This implements :type:`nghttp2_pack_extension_callback`. We have to
|
|
||||||
set this callback to :type:`nghttp2_session_callbacks`:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_session_callbacks_set_pack_extension_callback(
|
|
||||||
callbacks, pack_extension_callback);
|
|
||||||
|
|
||||||
To send ALTSVC frame, call `nghttp2_submit_extension()`:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
static const alt_svc altsvc = {"example.com", "h2=\":8000\""};
|
|
||||||
|
|
||||||
nghttp2_submit_extension(session, 0xa, NGHTTP2_FLAG_NONE, 0,
|
|
||||||
(void *)&altsvc);
|
|
||||||
|
|
||||||
Notice that ALTSVC is use frame type ``0xa``.
|
|
||||||
|
|
||||||
To receive extension frames, implement 2 callbacks:
|
|
||||||
:type:`nghttp2_unpack_extension_callback` and
|
|
||||||
:type:`nghttp2_on_extension_chunk_recv_callback`.
|
|
||||||
:type:`nghttp2_unpack_extension_callback` implements the way how to
|
|
||||||
decode wire format. :type:`nghttp2_on_extension_chunk_recv_callback`
|
|
||||||
implements how to buffer the incoming extension payload. These
|
|
||||||
callbacks must be set using
|
|
||||||
`nghttp2_session_callbacks_set_unpack_extension_callback()` and
|
|
||||||
`nghttp2_session_callbacks_set_on_extension_chunk_recv_callback()`
|
|
||||||
respectively. The application also must tell the library which
|
|
||||||
extension frame type it is willing to receive using
|
|
||||||
`nghttp2_option_set_user_recv_extension_type()`. Note that the
|
|
||||||
application has to create :type:`nghttp2_option` object for that
|
|
||||||
purpose, and initialize session with it.
|
|
||||||
|
|
||||||
We use ALTSVC again to illustrate how to receive extension frames. We
|
|
||||||
use different ``alt_svc`` struct than the previous one.
|
|
||||||
|
|
||||||
First implement 2 callbacks. We store incoming ALTSVC payload to
|
|
||||||
global variable ``altsvc_buffer``. Don't do this in production code
|
|
||||||
since this is not thread safe:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const uint8_t *origin;
|
|
||||||
size_t originlen;
|
|
||||||
const uint8_t *field;
|
|
||||||
size_t fieldlen;
|
|
||||||
} alt_svc;
|
|
||||||
|
|
||||||
/* buffers incoming ALTSVC payload */
|
|
||||||
uint8_t altsvc_buffer[4096];
|
|
||||||
/* The length of byte written to altsvc_buffer */
|
|
||||||
size_t altsvc_bufferlen = 0;
|
|
||||||
|
|
||||||
int on_extension_chunk_recv_callback(nghttp2_session *session,
|
|
||||||
const nghttp2_frame_hd *hd,
|
|
||||||
const uint8_t *data, size_t len,
|
|
||||||
void *user_data) {
|
|
||||||
if (sizeof(altsvc_buffer) < altsvc_bufferlen + len) {
|
|
||||||
altsvc_bufferlen = 0;
|
|
||||||
return NGHTTP2_ERR_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(altsvc_buffer + altsvc_bufferlen, data, len);
|
|
||||||
altsvc_bufferlen += len;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int unpack_extension_callback(nghttp2_session *session, void **payload,
|
|
||||||
const nghttp2_frame_hd *hd, void *user_data) {
|
|
||||||
uint8_t *origin, *field;
|
|
||||||
size_t originlen, fieldlen;
|
|
||||||
uint8_t *p, *end;
|
|
||||||
alt_svc *altsvc;
|
|
||||||
|
|
||||||
if (altsvc_bufferlen < 2) {
|
|
||||||
altsvc_bufferlen = 0;
|
|
||||||
return NGHTTP2_ERR_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = altsvc_buffer;
|
|
||||||
end = altsvc_buffer + altsvc_bufferlen;
|
|
||||||
|
|
||||||
originlen = ((*p) << 8) + *(p + 1);
|
|
||||||
p += 2;
|
|
||||||
|
|
||||||
if (p + originlen > end) {
|
|
||||||
altsvc_bufferlen = 0;
|
|
||||||
return NGHTTP2_ERR_CANCEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
origin = p;
|
|
||||||
field = p + originlen;
|
|
||||||
fieldlen = end - field;
|
|
||||||
|
|
||||||
altsvc = (alt_svc *)malloc(sizeof(alt_svc));
|
|
||||||
altsvc->origin = origin;
|
|
||||||
altsvc->originlen = originlen;
|
|
||||||
altsvc->field = field;
|
|
||||||
altsvc->fieldlen = fieldlen;
|
|
||||||
|
|
||||||
*payload = altsvc;
|
|
||||||
|
|
||||||
altsvc_bufferlen = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set these callbacks to :type:`nghttp2_session_callbacks`:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
|
|
||||||
callbacks, on_extension_chunk_recv_callback);
|
|
||||||
|
|
||||||
nghttp2_session_callbacks_set_unpack_extension_callback(
|
|
||||||
callbacks, unpack_extension_callback);
|
|
||||||
|
|
||||||
|
|
||||||
In ``unpack_extension_callback`` above, we set unpacked ``alt_svc``
|
|
||||||
object to ``*payload``. nghttp2 library then, calls
|
|
||||||
:type:`nghttp2_on_frame_recv_callback`, and ``*payload`` will be
|
|
||||||
available as ``frame->ext.payload``:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
int on_frame_recv_callback(nghttp2_session *session,
|
|
||||||
const nghttp2_frame *frame, void *user_data) {
|
|
||||||
|
|
||||||
switch (frame->hd.type) {
|
|
||||||
...
|
|
||||||
case 0xa: {
|
|
||||||
alt_svc *altsvc = (alt_svc *)frame->ext.payload;
|
|
||||||
fprintf(stderr, "ALTSVC frame received\n");
|
|
||||||
fprintf(stderr, " origin: %.*s\n", (int)altsvc->originlen, altsvc->origin);
|
|
||||||
fprintf(stderr, " field : %.*s\n", (int)altsvc->fieldlen, altsvc->field);
|
|
||||||
free(altsvc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Finally, application should set the extension frame types it is
|
|
||||||
willing to receive:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_option_set_user_recv_extension_type(option, 0xa);
|
|
||||||
|
|
||||||
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
|
|
||||||
its creation:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_session_client_new2(&session, callbacks, user_data, option);
|
|
||||||
|
|
||||||
How to use built-in HTTP/2 extension frame handlers
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
In the previous section, we talked about the user defined HTTP/2
|
|
||||||
extension frames. In this section, we talk about HTTP/2 extension
|
|
||||||
frame support built into nghttp2 library.
|
|
||||||
|
|
||||||
As of this writing, nghttp2 supports ALTSVC extension frame. To send
|
|
||||||
ALTSVC frame, use `nghttp2_submit_altsvc()` function.
|
|
||||||
|
|
||||||
To receive ALTSVC frame through built-in functionality, application
|
|
||||||
has to use `nghttp2_option_set_builtin_recv_extension_type()` to
|
|
||||||
indicate the willingness of receiving ALTSVC frame:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
|
|
||||||
|
|
||||||
This is very similar to the case when we used to receive user defined
|
|
||||||
frames.
|
|
||||||
|
|
||||||
If the same frame type is set using
|
|
||||||
`nghttp2_option_set_builtin_recv_extension_type()` and
|
|
||||||
`nghttp2_option_set_user_recv_extension_type()`, the latter takes
|
|
||||||
precedence. Application can implement its own frame handler rather
|
|
||||||
than using built-in handler.
|
|
||||||
|
|
||||||
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
|
|
||||||
its creation, like so:
|
|
||||||
|
|
||||||
.. code-block:: c
|
|
||||||
|
|
||||||
nghttp2_session_client_new2(&session, callbacks, user_data, option);
|
|
||||||
|
|
||||||
When ALTSVC is received, :type:`nghttp2_on_frame_recv_callback` will
|
|
||||||
be called as usual.
|
|
||||||
|
|
||||||
|
|||||||
@@ -17,22 +17,24 @@ installed in the following way. First, let us introduce
|
|||||||
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
|
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
|
||||||
for ``ANDROID_HOME``. For example, to install toolchain under
|
for ``ANDROID_HOME``. For example, to install toolchain under
|
||||||
``$ANDROID_HOME/toolchain``, do this in the the directory where NDK is
|
``$ANDROID_HOME/toolchain``, do this in the the directory where NDK is
|
||||||
unpacked:
|
unpacked::
|
||||||
|
|
||||||
.. code-block:: text
|
$ build/tools/make-standalone-toolchain.sh \
|
||||||
|
--install-dir=$ANDROID_HOME/toolchain \
|
||||||
|
--toolchain=arm-linux-androideabi-4.9 \
|
||||||
|
--llvm-version=3.5 \
|
||||||
|
--platform=android-16
|
||||||
|
|
||||||
$ build/tools/make_standalone_toolchain.py \
|
The additional flag ``--system=linux-x86_64`` may be required if you
|
||||||
--arch arm --api 16 --stl gnustl
|
are using x86_64 system.
|
||||||
--install-dir $ANDROID_HOME/toolchain
|
|
||||||
|
|
||||||
The API level (``--api``) is not important here because we don't use
|
The platform level is not important here because we don't use Android
|
||||||
Android specific C/C++ API.
|
specific C/C++ API.
|
||||||
|
|
||||||
The dependent libraries, such as OpenSSL, libev, and c-ares should be
|
The dependent libraries, such as OpenSSL and libev should be built
|
||||||
built with the toolchain and installed under
|
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
|
||||||
``$ANDROID_HOME/usr/local``. We recommend to build these libraries as
|
We recommend to build these libraries as static library to make the
|
||||||
static library to make the deployment easier. libxml2 support is
|
deployment easier. libxml2 support is currently disabled.
|
||||||
currently disabled.
|
|
||||||
|
|
||||||
Although zlib comes with Android NDK, it seems not to be a part of
|
Although zlib comes with Android NDK, it seems not to be a part of
|
||||||
public API, so we have to built it for our own. That also provides us
|
public API, so we have to built it for our own. That also provides us
|
||||||
@@ -43,9 +45,7 @@ spdylay as well.
|
|||||||
|
|
||||||
Before running ``android-config`` and ``android-make``,
|
Before running ``android-config`` and ``android-make``,
|
||||||
``ANDROID_HOME`` environment variable must be set to point to the
|
``ANDROID_HOME`` environment variable must be set to point to the
|
||||||
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``:
|
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
|
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
|
||||||
|
|
||||||
@@ -97,26 +97,6 @@ patch, to configure libev, use the following script:
|
|||||||
|
|
||||||
And run ``make install`` to build and install.
|
And run ``make install`` to build and install.
|
||||||
|
|
||||||
To configure c-ares, use the following script:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
if [ -z "$ANDROID_HOME" ]; then
|
|
||||||
echo 'No $ANDROID_HOME specified.'
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
PREFIX=$ANDROID_HOME/usr/local
|
|
||||||
TOOLCHAIN=$ANDROID_HOME/toolchain
|
|
||||||
PATH=$TOOLCHAIN/bin:$PATH
|
|
||||||
|
|
||||||
./configure \
|
|
||||||
--host=arm-linux-androideabi \
|
|
||||||
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
|
||||||
--prefix=$PREFIX \
|
|
||||||
--disable-shared
|
|
||||||
|
|
||||||
To configure zlib, use the following script:
|
To configure zlib, use the following script:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
@@ -179,8 +159,6 @@ then ``android-make`` to compile nghttp2 source files.
|
|||||||
|
|
||||||
If all went well, application binaries, such as nghttpx, are created
|
If all went well, application binaries, such as nghttpx, are created
|
||||||
under src directory. Strip debugging information from the binary
|
under src directory. Strip debugging information from the binary
|
||||||
using the following command:
|
using the following command::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ arm-linux-androideabi-strip src/nghttpx
|
$ arm-linux-androideabi-strip src/nghttpx
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ 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 which comes with
|
between versions, we currently use clang-format which comes with
|
||||||
clang-3.9.
|
clang-3.6.
|
||||||
|
|
||||||
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.
|
||||||
@@ -35,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-3.9 in debian), either add it to PATH variable or
|
clang-format-diff-3.6 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.
|
||||||
|
|||||||
@@ -1,43 +1,33 @@
|
|||||||
.. program:: h2load
|
|
||||||
|
|
||||||
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. If
|
h2load is benchmarking tool for HTTP/2 and HTTP/1.1. If built with
|
||||||
built with spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it
|
spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it also
|
||||||
also supports SPDY protocol. It supports SSL/TLS and clear text for
|
supports SPDY protocol. It supports SSL/TLS and clear text for all
|
||||||
all supported protocols.
|
supported protocols.
|
||||||
|
|
||||||
Compiling from source
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
h2load is compiled alongside nghttp2 and requires that the
|
|
||||||
``--enable-apps`` flag is passed to ``./configure`` and `required
|
|
||||||
dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are
|
|
||||||
available during compilation. For details on compiling, see `nghttp2:
|
|
||||||
Building from Git
|
|
||||||
<https://github.com/nghttp2/nghttp2#building-from-git>`_.
|
|
||||||
|
|
||||||
Basic Usage
|
Basic Usage
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
In order to set benchmark settings, specify following 3 options.
|
In order to set benchmark settings, specify following 3 options.
|
||||||
|
|
||||||
:option:`-n`
|
``-n``
|
||||||
The number of total requests. Default: 1
|
The number of total requests. Default: 1
|
||||||
|
|
||||||
:option:`-c`
|
``-c``
|
||||||
The number of concurrent clients. Default: 1
|
The number of concurrent clients. Default: 1
|
||||||
|
|
||||||
:option:`-m`
|
``-m``
|
||||||
The max concurrent streams to issue per client. Default: 1
|
The max concurrent streams to issue per client.
|
||||||
|
If ``auto`` is given, the number of given URIs is used.
|
||||||
|
Default: ``auto``
|
||||||
|
|
||||||
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
|
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
|
||||||
You can set specific protocols in :option:`--npn-list` option. For
|
You can set specific protocols in ``--npn-list`` option. For
|
||||||
cleartext connection, the default protocol is HTTP/2. To change the
|
cleartext connection, the default protocol is HTTP/2. To change the
|
||||||
protocol in cleartext connection, use :option:`--no-tls-proto` option.
|
protocol in cleartext connection, use ``--no-tls-proto`` option. For
|
||||||
For convenience, :option:`--h1` option forces HTTP/1.1 for both
|
convenience, ``--h1`` option forces HTTP/1.1 for both cleartext and
|
||||||
cleartext and SSL/TLS connections.
|
SSL/TLS connections.
|
||||||
|
|
||||||
Here is a command-line to perform benchmark to URI \https://localhost
|
Here is a command-line to perform benchmark to URI \https://localhost
|
||||||
using total 100000 requests, 100 concurrent clients and 10 max
|
using total 100000 requests, 100 concurrent clients and 10 max
|
||||||
@@ -72,11 +62,11 @@ benchmarking results. By default, h2load uses large enough flow
|
|||||||
control window, which effectively disables flow control. To adjust
|
control window, which effectively disables flow control. To adjust
|
||||||
receiver flow control window size, there are following options:
|
receiver flow control window size, there are following options:
|
||||||
|
|
||||||
:option:`-w`
|
``-w``
|
||||||
Sets the stream level initial window size to
|
Sets the stream level initial window size to
|
||||||
(2**<N>)-1. For SPDY, 2**<N> is used instead.
|
(2**<N>)-1. For SPDY, 2**<N> is used instead.
|
||||||
|
|
||||||
:option:`-W`
|
``-W``
|
||||||
Sets the connection level initial window size to
|
Sets the connection level initial window size to
|
||||||
(2**<N>)-1. For SPDY, if <N> is strictly less
|
(2**<N>)-1. For SPDY, if <N> is strictly less
|
||||||
than 16, this option is ignored. Otherwise
|
than 16, this option is ignored. Otherwise
|
||||||
@@ -86,17 +76,17 @@ Multi-Threading
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
Sometimes benchmarking client itself becomes a bottleneck. To remedy
|
Sometimes benchmarking client itself becomes a bottleneck. To remedy
|
||||||
this situation, use :option:`-t` option to specify the number of native
|
this situation, use ``-t`` option to specify the number of native
|
||||||
thread to use.
|
thread to use.
|
||||||
|
|
||||||
:option:`-t`
|
``-t``
|
||||||
The number of native threads. Default: 1
|
The number of native threads. Default: 1
|
||||||
|
|
||||||
Selecting protocol for clear text
|
Selecting protocol for clear text
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
By default, if \http:// URI is given, HTTP/2 protocol is used. To
|
By default, if \http:// URI is given, HTTP/2 protocol is used. To
|
||||||
change the protocol to use for clear text, use :option:`-p` option.
|
change the protocol to use for clear text, use ``-p`` option.
|
||||||
|
|
||||||
Multiple URIs
|
Multiple URIs
|
||||||
-------------
|
-------------
|
||||||
@@ -107,12 +97,3 @@ If multiple URIs are specified, they are used in round robin manner.
|
|||||||
|
|
||||||
Please note that h2load uses scheme, host and port in the first URI
|
Please note that h2load uses scheme, host and port in the first URI
|
||||||
and ignores those parts in the rest of the URIs.
|
and ignores those parts in the rest of the URIs.
|
||||||
|
|
||||||
UNIX domain socket
|
|
||||||
------------------
|
|
||||||
|
|
||||||
To request against UNIX domain socket, use :option:`--base-uri`, and
|
|
||||||
specify ``unix:`` followed by the path to UNIX domain socket. For
|
|
||||||
example, if UNIX domain socket is ``/tmp/nghttpx.sock``, use
|
|
||||||
``--base-uri=unix:/tmp/nghttpx.sock``. h2load uses scheme, host and
|
|
||||||
port in the first URI in command-line or input file.
|
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ nghttp2 - HTTP/2 C Library
|
|||||||
|
|
||||||
This is an implementation of Hypertext Transfer Protocol version 2.
|
This is an implementation of Hypertext Transfer Protocol version 2.
|
||||||
|
|
||||||
The project is hosted at `github.com/nghttp2/nghttp2
|
The project is hosted at `github.com/tatsuhiro-t/nghttp2 <https://github.com/tatsuhiro-t/nghttp2>`_.
|
||||||
<https://github.com/nghttp2/nghttp2>`_.
|
|
||||||
|
|
||||||
Contents:
|
Contents:
|
||||||
|
|
||||||
@@ -37,18 +36,17 @@ Contents:
|
|||||||
asio_http2_server.h
|
asio_http2_server.h
|
||||||
asio_http2_client.h
|
asio_http2_client.h
|
||||||
asio_http2.h
|
asio_http2.h
|
||||||
Source <https://github.com/nghttp2/nghttp2>
|
Source <https://github.com/tatsuhiro-t/nghttp2>
|
||||||
Issues <https://github.com/nghttp2/nghttp2/issues>
|
Issues <https://github.com/tatsuhiro-t/nghttp2/issues>
|
||||||
nghttp2.org <https://nghttp2.org/>
|
nghttp2.org <https://nghttp2.org/>
|
||||||
|
|
||||||
Released Versions
|
Released Versions
|
||||||
=================
|
=================
|
||||||
|
|
||||||
https://github.com/nghttp2/nghttp2/releases
|
https://github.com/tatsuhiro-t/nghttp2/releases
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
* HTTP/2 https://tools.ietf.org/html/rfc7540
|
* HTTP/2 https://tools.ietf.org/html/rfc7540
|
||||||
* HPACK https://tools.ietf.org/html/rfc7541
|
* HPACK https://tools.ietf.org/html/rfc7541
|
||||||
* HTTP Alternative Services https://tools.ietf.org/html/rfc7838
|
|
||||||
|
|||||||
@@ -1,101 +1,79 @@
|
|||||||
.. program:: nghttpx
|
|
||||||
|
|
||||||
nghttpx - HTTP/2 proxy - HOW-TO
|
nghttpx - HTTP/2 proxy - HOW-TO
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
:doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and
|
nghttpx is a proxy translating protocols between HTTP/2 and other
|
||||||
other protocols (e.g., HTTP/1, SPDY). It operates in several modes
|
protocols (e.g., HTTP/1, SPDY). It operates in several modes and each
|
||||||
and each mode may require additional programs to work with. This
|
mode may require additional programs to work with. This article
|
||||||
article describes each operation mode and explains the intended
|
describes each operation mode and explains the intended use-cases. It
|
||||||
use-cases. It also covers some useful options later.
|
also covers some useful options later.
|
||||||
|
|
||||||
Default mode
|
Default mode
|
||||||
------------
|
------------
|
||||||
|
|
||||||
If nghttpx is invoked without :option:`--http2-proxy`, it operates in
|
If nghttpx is invoked without any ``-s``, ``-p`` and ``--client``, it
|
||||||
default mode. In this mode, it works as reverse proxy (gateway) for
|
operates in default mode. In this mode, nghttpx frontend listens for
|
||||||
both HTTP/2 and HTTP/1 clients to backend servers. This is also known
|
HTTP/2 requests and translates them to HTTP/1 requests. Thus it works
|
||||||
as "HTTP/2 router". If nghttpx is linked with spdylay library and
|
as reverse proxy (gateway) for HTTP/2 clients to HTTP/1 web server.
|
||||||
frontend connection is SSL/TLS, the frontend also supports SPDY
|
This is also known as "HTTP/2 router". HTTP/1 requests are also
|
||||||
protocol.
|
supported in frontend as a fallback. 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, this mode's frontend connection is encrypted using
|
||||||
server's private key and certificate must be supplied to the command
|
SSL/TLS. So server's private key and certificate must be supplied to
|
||||||
line (or through configuration file). In this case, the frontend
|
the command line (or through configuration file). In this case, the
|
||||||
protocol selection will be done via ALPN or NPN.
|
frontend protocol selection will be done via ALPN or NPN.
|
||||||
|
|
||||||
To turn off encryption on frontend connection, use ``no-tls`` keyword
|
With ``--frontend-no-tls`` option, user can turn off SSL/TLS in
|
||||||
in :option:`--frontend` option. In this case, SPDY protocol is not
|
frontend connection. In this case, SPDY protocol is not available
|
||||||
available even if spdylay library is liked to nghttpx. HTTP/2 and
|
even if spdylay library is liked to nghttpx. HTTP/2 and HTTP/1 are
|
||||||
HTTP/1 are available on the frontend, and an HTTP/1 connection can be
|
available on the frontend and a HTTP/1 connection can be upgraded to
|
||||||
upgraded to HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by
|
HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by sending
|
||||||
sending HTTP/2 connection preface is also supported.
|
HTTP/2 connection preface is also supported.
|
||||||
|
|
||||||
nghttpx can listen on multiple frontend addresses. This is achieved
|
By default, backend HTTP/1 connections are not encrypted. To enable
|
||||||
by using multiple :option:`--frontend` options. For each frontend
|
TLS on HTTP/1 backend connections, use ``--backend-http1-tls`` option.
|
||||||
address, TLS can be enabled or disabled.
|
This applies to all mode whose backend connections are HTTP/1.
|
||||||
|
|
||||||
By default, backend connections are not encrypted. To enable TLS
|
The backend is supposed to be HTTP/1 Web server. For example, to make
|
||||||
encryption on backend connections, use ``tls`` keyword in
|
|
||||||
:option:`--backend` option. Using patterns and ``proto`` keyword in
|
|
||||||
:option:`--backend` option, backend application protocol can be
|
|
||||||
specified per host/request path pattern. It means that you can use
|
|
||||||
both HTTP/2 and HTTP/1 in backend connections at the same time. Note
|
|
||||||
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`
|
|
||||||
explicitly.
|
|
||||||
|
|
||||||
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 request at port
|
backend HTTP/1 web server is configured to listen to HTTP/1 request at
|
||||||
8080 in the same host, run nghttpx command-line like this:
|
port 8080 in the same host, run nghttpx command-line like this::
|
||||||
|
|
||||||
.. 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 HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
|
Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
|
||||||
example, you can send GET request to the server using nghttp:
|
example, you can send GET request to the server using nghttp::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ nghttp -nv https://localhost:8443/
|
$ nghttp -nv https://localhost:8443/
|
||||||
|
|
||||||
HTTP/2 proxy mode
|
HTTP/2 proxy mode
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
|
If nghttpx is invoked with ``-s`` option, it operates in HTTP/2 proxy
|
||||||
:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
|
mode. The supported protocols in frontend and backend connections are
|
||||||
protocols in frontend and backend connections are the same in `default
|
the same in `default mode`_. The difference is that this mode acts
|
||||||
mode`_. The difference is that this mode acts like forward proxy and
|
like forward proxy and assumes the backend is HTTP/1 proxy server
|
||||||
assumes the backend is HTTP proxy server (e.g., Squid, Apache Traffic
|
(e.g., squid, traffic server). So HTTP/1 request must include
|
||||||
Server). HTTP/1 request must include absolute URI in request line.
|
absolute URI in request line.
|
||||||
|
|
||||||
By default, frontend connection is encrypted. So this mode is also
|
By default, frontend connection is encrypted. So this mode is also
|
||||||
called secure proxy. If nghttpx is linked with spdylay, it supports
|
called secure proxy. If nghttpx is linked with spdylay, it supports
|
||||||
SPDY protocols and it works as so called SPDY proxy.
|
SPDY protocols and it works as so called SPDY proxy.
|
||||||
|
|
||||||
To turn off encryption on frontend connection, use ``no-tls`` keyword
|
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
|
||||||
in :option:`--frontend` option.
|
connection, so the connection gets insecure.
|
||||||
|
|
||||||
The backend must be HTTP proxy server. nghttpx supports multiple
|
The backend must be HTTP/1 proxy server. nghttpx supports multiple
|
||||||
backend server addresses. It translates incoming requests to HTTP
|
backend server addresses. It translates incoming requests to HTTP/1
|
||||||
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
|
||||||
server and caching contents.
|
server and caching contents.
|
||||||
|
|
||||||
The backend connection is not encrypted by default. To enable
|
|
||||||
encryption, use ``tls`` keyword in :option:`--backend` option. The
|
|
||||||
default backend protocol is HTTP/1.1. To use HTTP/2 in backend
|
|
||||||
connection, use :option:`--backend` option, and specify ``h2`` in
|
|
||||||
``proto`` keyword explicitly.
|
|
||||||
|
|
||||||
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/1 proxy server is configured to listen
|
||||||
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
|
to HTTP/1 request at port 8080 in the same host, run nghttpx
|
||||||
like this:
|
command-line like this::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||||
|
|
||||||
@@ -118,78 +96,152 @@ Chromium require valid certificate for secure proxy.
|
|||||||
For Firefox, open Preference window and select Advanced then click
|
For Firefox, open Preference window and select Advanced then click
|
||||||
Network tab. Clicking Connection Settings button will show the
|
Network tab. Clicking Connection Settings button will show the
|
||||||
dialog. Select "Automatic proxy configuration URL" and enter the path
|
dialog. Select "Automatic proxy configuration URL" and enter the path
|
||||||
to proxy.pac file, something like this:
|
to proxy.pac file, something like this::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
file:///path/to/proxy.pac
|
file:///path/to/proxy.pac
|
||||||
|
|
||||||
For Chromium, use following command-line:
|
For Chromium, use following command-line::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||||
|
|
||||||
As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
|
As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
|
||||||
requires to be configured as forward proxy. Here is the minimum
|
requires to be configured as forward proxy. Here is the minimum
|
||||||
configuration items to edit:
|
configuration items to edit::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
CONFIG proxy.config.reverse_proxy.enabled INT 0
|
CONFIG proxy.config.reverse_proxy.enabled INT 0
|
||||||
CONFIG proxy.config.url_remap.remap_required INT 0
|
CONFIG proxy.config.url_remap.remap_required INT 0
|
||||||
|
|
||||||
Consult Traffic server `documentation
|
Consult Traffic server `documentation
|
||||||
<http://trafficserver.readthedocs.org/en/latest/admin-guide/configuration/transparent-forward-proxying.en.html>`_
|
<https://docs.trafficserver.apache.org/en/latest/admin/forward-proxy.en.html>`_
|
||||||
to know how to configure traffic server as forward proxy and its
|
to know how to configure traffic server as forward proxy and its
|
||||||
security implications.
|
security implications.
|
||||||
|
|
||||||
ALPN support
|
Client mode
|
||||||
------------
|
-----------
|
||||||
|
|
||||||
ALPN support requires OpenSSL >= 1.0.2.
|
If nghttpx is invoked with ``--client`` option, it operates in client
|
||||||
|
mode. In this mode, nghttpx listens for plain, unencrypted HTTP/2 and
|
||||||
|
HTTP/1 requests and translates them to encrypted HTTP/2 requests to
|
||||||
|
the backend. User cannot enable SSL/TLS in frontend connection.
|
||||||
|
|
||||||
Disable frontend SSL/TLS
|
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
|
||||||
------------------------
|
Upgrade. To disable SSL/TLS in backend connection, use
|
||||||
|
``--backend-no-tls`` option.
|
||||||
|
|
||||||
The frontend connections are encrypted with SSL/TLS by default. To
|
By default, the number of backend HTTP/2 connections per worker
|
||||||
turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend`
|
(thread) is determined by number of ``-b`` option. To adjust this
|
||||||
option. If this option is used, the private key and certificate are
|
value, use ``--backend-http2-connections-per-worker`` option.
|
||||||
not required to run nghttpx.
|
|
||||||
|
|
||||||
Enable backend SSL/TLS
|
The backend server is supporsed to be a HTTP/2 web server (e.g.,
|
||||||
----------------------
|
nghttpd). The one use-case of this mode is utilize existing HTTP/1
|
||||||
|
clients to test HTTP/2 deployment. Suppose that HTTP/2 web server
|
||||||
|
listens to port 80 without encryption. Then run nghttpx as client
|
||||||
|
mode to access to that web server::
|
||||||
|
|
||||||
The backend connections are not encrypted by default. To enable
|
$ nghttpx --client -f127.0.0.1,8080 -b127.0.0.1,80 --backend-no-tls
|
||||||
SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option.
|
|
||||||
|
|
||||||
Enable SSL/TLS on memcached connection
|
.. note::
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
By default, memcached connection is not encrypted. To enable
|
You may need ``-k`` option if HTTP/2 server enables SSL/TLS and
|
||||||
encryption, use ``tls`` keyword in
|
its certificate is self-signed. But please note that it is
|
||||||
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
|
insecure.
|
||||||
:option:`--tls-session-cache-memcached` for TLS session cache.
|
|
||||||
|
|
||||||
Specifying additional server certificates
|
Then you can use curl to access HTTP/2 server via nghttpx::
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
nghttpx accepts additional server private key and certificate pairs
|
$ curl http://localhost:8080/
|
||||||
using :option:`--subcert` option. It can be used multiple times.
|
|
||||||
|
Client proxy mode
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
If nghttpx is invoked with ``-p`` option, it operates in client proxy
|
||||||
|
mode. This mode behaves like `client mode`_, but it works like
|
||||||
|
forward proxy. So HTTP/1 request must include absolute URI in request
|
||||||
|
line.
|
||||||
|
|
||||||
|
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
|
||||||
|
Upgrade. To disable SSL/TLS in backend connection, use
|
||||||
|
``--backend-no-tls`` option.
|
||||||
|
|
||||||
|
By default, the number of backend HTTP/2 connections per worker
|
||||||
|
(thread) is determined by number of ``-b`` option. To adjust this
|
||||||
|
value, use ``--backend-http2-connections-per-worker`` option.
|
||||||
|
|
||||||
|
The backend server must be a HTTP/2 proxy. You can use nghttpx in
|
||||||
|
`HTTP/2 proxy mode`_ as backend server. The one use-case of this mode
|
||||||
|
is utilize existing HTTP/1 clients to test HTTP/2 connections between
|
||||||
|
2 proxies. The another use-case is use this mode to aggregate local
|
||||||
|
HTTP/1 connections to one HTTP/2 backend encrypted connection. This
|
||||||
|
makes HTTP/1 clients which does not support secure proxy can use
|
||||||
|
secure HTTP/2 proxy via nghttpx client mode.
|
||||||
|
|
||||||
|
Suppose that HTTP/2 proxy listens to port 8443, just like we saw in
|
||||||
|
`HTTP/2 proxy mode`_. To run nghttpx in client proxy mode to access
|
||||||
|
that server, invoke nghttpx like this::
|
||||||
|
|
||||||
|
$ nghttpx -p -f127.0.0.1,8080 -b127.0.0.1,8443
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You may need ``-k`` option if HTTP/2 server's certificate is
|
||||||
|
self-signed. But please note that it is insecure.
|
||||||
|
|
||||||
|
Then you can use curl to issue HTTP request via HTTP/2 proxy::
|
||||||
|
|
||||||
|
$ curl --http-proxy=http://localhost:8080 http://www.google.com/
|
||||||
|
|
||||||
|
You can configure web browser to use localhost:8080 as forward
|
||||||
|
proxy.
|
||||||
|
|
||||||
|
HTTP/2 bridge mode
|
||||||
|
------------------
|
||||||
|
|
||||||
|
If nghttpx is invoked with ``--http2-bridge`` option, it operates in
|
||||||
|
HTTP/2 bridge mode. The supported protocols in frontend connections
|
||||||
|
are the same in `default mode`_. The protocol in backend is HTTP/2
|
||||||
|
only.
|
||||||
|
|
||||||
|
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
|
||||||
|
connection, so the connection gets insecure. To disable SSL/TLS in
|
||||||
|
backend connection, use ``--backend-no-tls`` option.
|
||||||
|
|
||||||
|
By default, the number of backend HTTP/2 connections per worker
|
||||||
|
(thread) is determined by number of ``-b`` option. To adjust this
|
||||||
|
value, use ``--backend-http2-connections-per-worker`` option.
|
||||||
|
|
||||||
|
The backend server is supporsed to be a HTTP/2 web server or HTTP/2
|
||||||
|
proxy. If backend server is HTTP/2 proxy, use
|
||||||
|
``--no-location-rewrite`` and ``--no-host-rewrite`` options to disable
|
||||||
|
rewriting location, host and :authority header field.
|
||||||
|
|
||||||
|
The use-case of this mode is aggregate the incoming connections to one
|
||||||
|
HTTP/2 connection. One backend HTTP/2 connection is created per
|
||||||
|
worker (thread).
|
||||||
|
|
||||||
|
Disable SSL/TLS
|
||||||
|
---------------
|
||||||
|
|
||||||
|
In `default mode`_, `HTTP/2 proxy mode`_ and `HTTP/2 bridge mode`_,
|
||||||
|
frontend connections are encrypted with SSL/TLS by default. To turn
|
||||||
|
off SSL/TLS, use ``--frontend-no-tls`` option. If this option is
|
||||||
|
used, the private key and certificate are not required to run nghttpx.
|
||||||
|
|
||||||
|
In `client mode`_, `client proxy mode`_ and `HTTP/2 bridge mode`_,
|
||||||
|
backend connections are encrypted with SSL/TLS by default. To turn
|
||||||
|
off SSL/TLS, use ``--backend-no-tls`` option.
|
||||||
|
|
||||||
Specifying additional CA certificate
|
Specifying additional CA certificate
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
By default, nghttpx tries to read CA certificate from system. But
|
By default, nghttpx tries to read CA certificate from system. But
|
||||||
depending on the system you use, this may fail or is not supported.
|
depending on the system you use, this may fail or is not supported.
|
||||||
To specify CA certificate manually, use :option:`--cacert` option.
|
To specify CA certificate manually, use ``--cacert`` option. The
|
||||||
The specified file must be PEM format and can contain multiple
|
specified file must be PEM format and can contain multiple
|
||||||
certificates.
|
certificates.
|
||||||
|
|
||||||
By default, nghttpx validates server's certificate. If you want to
|
By default, nghttpx validates server's certificate. If you want to
|
||||||
turn off this validation, knowing this is really insecure and what you
|
turn off this validation, knowing this is really insecure and what you
|
||||||
are doing, you can use :option:`--insecure` option to disable
|
are doing, you can use ``-k`` option to disable certificate
|
||||||
certificate validation.
|
validation.
|
||||||
|
|
||||||
Read/write rate limit
|
Read/write rate limit
|
||||||
---------------------
|
---------------------
|
||||||
@@ -198,9 +250,9 @@ nghttpx supports transfer rate limiting on frontend connections. You
|
|||||||
can do rate limit per frontend connection for reading and writing
|
can do rate limit per frontend connection for reading and writing
|
||||||
individually.
|
individually.
|
||||||
|
|
||||||
To perform rate limit for reading, use :option:`--read-rate` and
|
To perform rate limit for reading, use ``--read-rate`` and
|
||||||
:option:`--read-burst` options. For writing, use
|
``--read-burst`` options. For writing, use ``--write-rate`` and
|
||||||
:option:`--write-rate` and :option:`--write-burst`.
|
``--write-burst``.
|
||||||
|
|
||||||
Please note that rate limit is performed on top of TCP and nothing to
|
Please note that rate limit is performed on top of TCP and nothing to
|
||||||
do with HTTP/2 flow control.
|
do with HTTP/2 flow control.
|
||||||
@@ -211,17 +263,17 @@ Rewriting location header field
|
|||||||
nghttpx automatically rewrites location response header field if the
|
nghttpx automatically rewrites location response header field if the
|
||||||
following all conditions satisfy:
|
following all conditions satisfy:
|
||||||
|
|
||||||
* In the default mode (:option:`--http2-proxy` is not used)
|
* URI in location header field is not absolute URI or is not https URI.
|
||||||
* :option:`--no-location-rewrite` is not used
|
|
||||||
* URI in location header field is an absolute URI
|
|
||||||
* URI in location header field includes non empty host component.
|
* URI in location header field includes non empty host component.
|
||||||
* host (without port) in URI in location header field must match the
|
* host (without port) in URI in location header field must match the
|
||||||
host appearing in ``:authority`` or ``host`` header field.
|
host appearing in :authority or host header field.
|
||||||
|
|
||||||
When rewrite happens, URI scheme is replaced with the ones used in
|
When rewrite happens, URI scheme and port are replaced with the ones
|
||||||
frontend, and authority is replaced with which appears in
|
used in frontend, and host is replaced with which appears in
|
||||||
``:authority``, or ``host`` request header field. ``:authority``
|
:authority or host request header field. :authority header field has
|
||||||
header field has precedence over ``host``.
|
precedence. If the above conditions are not met with the host value
|
||||||
|
in :authority header field, rewrite is retried with the value in host
|
||||||
|
header field.
|
||||||
|
|
||||||
Hot swapping
|
Hot swapping
|
||||||
------------
|
------------
|
||||||
@@ -236,191 +288,20 @@ all existing frontend connections are done, the current process will
|
|||||||
exit. At this point, only new nghttpx process exists and serves
|
exit. At this point, only new nghttpx process exists and serves
|
||||||
incoming requests.
|
incoming requests.
|
||||||
|
|
||||||
If you want to just reload configuration file without executing new
|
|
||||||
binary, send SIGHUP to nghttpx master process.
|
|
||||||
|
|
||||||
Re-opening log files
|
Re-opening log files
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
When rotating log files, it is desirable to re-open log files after
|
When rotating log files, it is desirable to re-open log files after
|
||||||
log rotation daemon renamed existing log files. To tell nghttpx to
|
log rotation daemon renamed existing log files. To tell nghttpx to
|
||||||
re-open log files, send USR1 signal to nghttpx process. It will
|
re-open log files, send USR1 signal to nghttpx process. It will
|
||||||
re-open files specified by :option:`--accesslog-file` and
|
re-open files specified by ``--accesslog-file`` and
|
||||||
:option:`--errorlog-file` options.
|
``--errorlog-file`` options.
|
||||||
|
|
||||||
Multiple frontend addresses
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
nghttpx can listen on multiple frontend addresses. To specify them,
|
|
||||||
just use :option:`--frontend` (or its shorthand :option:`-f`) option
|
|
||||||
repeatedly. TLS can be enabled or disabled per frontend address
|
|
||||||
basis. For example, to listen on port 443 with TLS enabled, and on
|
|
||||||
port 80 without TLS:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
frontend=*,443
|
|
||||||
frontend=*,80;no-tls
|
|
||||||
|
|
||||||
|
|
||||||
Multiple backend addresses
|
Multiple backend addresses
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
nghttpx supports multiple backend addresses. To specify them, just
|
nghttpx supports multiple backend addresses. To specify them, just
|
||||||
use :option:`--backend` (or its shorthand :option:`-b`) option
|
use ``-b`` option repeatedly. For example, to use backend1:8080 and
|
||||||
repeatedly. For example, to use ``192.168.0.10:8080`` and
|
backend2:8080, use command-line like this: ``-bbackend1,8080
|
||||||
``192.168.0.11:8080``, use command-line like this:
|
-bbackend2,8080``. For HTTP/2 backend, see also
|
||||||
``-b192.168.0.10,8080 -b192.168.0.11,8080``. In configuration file,
|
``--backend-http2-connections-per-worker`` option.
|
||||||
this looks like:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=192.168.0.10,8080
|
|
||||||
backend=192.168.0.11,8008
|
|
||||||
|
|
||||||
nghttpx can route request to different backend according to request
|
|
||||||
host and path. For example, to route request destined to host
|
|
||||||
``doc.example.com`` to backend server ``docserv:3000``, you can write
|
|
||||||
like so:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=docserv,3000;doc.example.com/
|
|
||||||
|
|
||||||
When you write this option in command-line, you should enclose
|
|
||||||
argument with single or double quotes, since the character ``;`` has a
|
|
||||||
special meaning in shell.
|
|
||||||
|
|
||||||
To route, request to request path whose prefix is ``/foo`` to backend
|
|
||||||
server ``[::1]:8080``, you can write like so:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=::1,8080;/foo
|
|
||||||
|
|
||||||
Of course, you can specify both host and request path at the same
|
|
||||||
time:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=192.168.0.10,8080;example.com/foo
|
|
||||||
|
|
||||||
We can use ``*`` in the left most position of host to achieve wildcard
|
|
||||||
suffix match. If ``*`` is the left most character, then the remaining
|
|
||||||
string should match the request host suffix. ``*`` must match at
|
|
||||||
least one character. For example, ``*.example.com`` matches
|
|
||||||
``www.example.com`` and ``dev.example.com``, and does not match
|
|
||||||
``example.com`` and ``nghttp2.org``. The exact match (without ``*``)
|
|
||||||
always takes precedence over wildcard match.
|
|
||||||
|
|
||||||
One important thing you have to remember is that we have to specify
|
|
||||||
default routing pattern for so called "catch all" pattern. To write
|
|
||||||
"catch all" pattern, just specify backend server address, without
|
|
||||||
pattern.
|
|
||||||
|
|
||||||
Usually, host is the value of ``Host`` header field. In HTTP/2, the
|
|
||||||
value of ``:authority`` pseudo header field is used.
|
|
||||||
|
|
||||||
When you write multiple backend addresses sharing the same routing
|
|
||||||
pattern, they are used as load balancing. For example, to use 2
|
|
||||||
servers ``serv1:3000`` and ``serv2:3000`` for request host
|
|
||||||
``example.com`` and path ``/myservice``, you can write like so:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=serv1,3000;example.com/myservice
|
|
||||||
backend=serv2,3000;example.com/myservice
|
|
||||||
|
|
||||||
You can also specify backend application protocol in
|
|
||||||
:option:`--backend` option using ``proto`` keyword after pattern.
|
|
||||||
Utilizing this allows ngttpx to route certain request to HTTP/2, other
|
|
||||||
requests to HTTP/1. For example, to route requests to ``/ws/`` in
|
|
||||||
backend HTTP/1.1 connection, and use backend HTTP/2 for other
|
|
||||||
requests, do this:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=serv1,3000;/;proto=h2
|
|
||||||
backend=serv1,3000;/ws/;proto=http/1.1
|
|
||||||
|
|
||||||
The default backend protocol is HTTP/1.1.
|
|
||||||
|
|
||||||
TLS can be enabled per pattern basis:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=serv1,8443;/;proto=h2;tls
|
|
||||||
backend=serv2,8080;/ws/;proto=http/1.1
|
|
||||||
|
|
||||||
In the above case, connection to serv1 will be encrypted by TLS. On
|
|
||||||
the other hand, connection to serv2 will not be encrypted by TLS.
|
|
||||||
|
|
||||||
Dynamic hostname lookup
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
By default, nghttpx performs backend hostname lookup at start up, or
|
|
||||||
configuration reload, and keeps using them in its entire session. To
|
|
||||||
make nghttpx perform hostname lookup dynamically, use ``dns``
|
|
||||||
parameter in :option:`--backend` option, like so:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=foo.example.com;;dns
|
|
||||||
|
|
||||||
nghttpx will cache resolved addresses for certain period of time. To
|
|
||||||
change this cache period, use :option:`--dns-cache-timeout`.
|
|
||||||
|
|
||||||
Migration from nghttpx v1.8.0 or earlier
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
As of nghttpx 1.9.0, ``--frontend-no-tls`` and ``--backend-no-tls``
|
|
||||||
have been removed.
|
|
||||||
|
|
||||||
To disable encryption on frontend connection, use ``no-tls`` keyword
|
|
||||||
in :option:`--frontend` potion:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
frontend=*,3000;no-tls
|
|
||||||
|
|
||||||
The TLS encryption is now disabled on backend connection in all modes
|
|
||||||
by default. To enable encryption on backend connection, use ``tls``
|
|
||||||
keyword in :option:`--backend` option:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=127.0.0.1,8080;tls
|
|
||||||
|
|
||||||
As of nghttpx 1.9.0, ``--http2-bridge``, ``--client`` and
|
|
||||||
``--client-proxy`` options have been removed. These functionality can
|
|
||||||
be used using combinations of options.
|
|
||||||
|
|
||||||
Use following option instead of ``--http2-bridge``:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
backend=<ADDR>,<PORT>;;proto=h2;tls
|
|
||||||
|
|
||||||
Use following options instead of ``--client``:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
frontend=<ADDR>,<PORT>;no-tls
|
|
||||||
backend=<ADDR>,<PORT>;;proto=h2;tls
|
|
||||||
|
|
||||||
Use following options instead of ``--client-proxy``:
|
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
http2-proxy=yes
|
|
||||||
frontend=<ADDR>,<PORT>;no-tls
|
|
||||||
backend=<ADDR>,<PORT>;;proto=h2;tls
|
|
||||||
|
|
||||||
We also removed ``--backend-http2-connections-per-worker`` option. It
|
|
||||||
was present because previously the number of backend h2 connection was
|
|
||||||
statically configured, and defaulted to 1. Now the number of backend
|
|
||||||
h2 connection is increased on demand. We know the maximum number of
|
|
||||||
concurrent streams per connection. When we push as many request as
|
|
||||||
the maximum concurrency to the one connection, we create another new
|
|
||||||
connection so that we can distribute load and avoid delay the request
|
|
||||||
processing. This is done automatically without any configuration.
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ The extension module is called ``nghttp2``.
|
|||||||
determined by configure script. If the detected Python version is not
|
determined by configure script. If the detected Python version is not
|
||||||
what you expect, specify a path to Python executable in ``PYTHON``
|
what you expect, specify a path to Python executable in ``PYTHON``
|
||||||
variable as an argument to configure script (e.g., ``./configure
|
variable as an argument to configure script (e.g., ``./configure
|
||||||
PYTHON=/usr/bin/python3.5``).
|
PYTHON=/usr/bin/python3.4``).
|
||||||
|
|
||||||
HPACK API
|
HPACK API
|
||||||
---------
|
---------
|
||||||
@@ -136,15 +136,13 @@ HTTP/2 servers
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
We use :py:mod:`asyncio` for HTTP/2 server classes, and ALPN.
|
We use :py:mod:`asyncio` for HTTP/2 server classes. Therefore,
|
||||||
Therefore, Python 3.5 or later is required to use these objects.
|
Python 3.4 or later is required to use these objects. To
|
||||||
To explicitly configure nghttp2 build to use Python 3.5, specify
|
explicitly configure nghttp2 build to use Python 3.4, specify the
|
||||||
the ``PYTHON`` variable to the path to Python 3.5 executable when
|
``PYTHON`` variable to the path to Python 3.4 executable when
|
||||||
invoking configure script like this:
|
invoking configure script like this::
|
||||||
|
|
||||||
.. code-block:: text
|
$ ./configure PYTHON=/usr/bin/python3.4
|
||||||
|
|
||||||
$ ./configure PYTHON=/usr/bin/python3.5
|
|
||||||
|
|
||||||
.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
|
.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ the end of this page. It also resides in the examples directory in
|
|||||||
the archive or repository.
|
the archive or repository.
|
||||||
|
|
||||||
This simple client takes a single HTTPS URI and retrieves the resource
|
This simple client takes a single HTTPS URI and retrieves the resource
|
||||||
at the URI. The synopsis is:
|
at the URI. The synopsis is::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ libevent-client HTTPS_URI
|
$ libevent-client HTTPS_URI
|
||||||
|
|
||||||
@@ -33,17 +31,6 @@ protocol the library supports::
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
If you are following TLS related RFC, you know that NPN is not the
|
|
||||||
standardized way to negotiate HTTP/2. NPN itself is not event
|
|
||||||
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
|
|
||||||
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
|
|
||||||
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
|
|
||||||
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
|
|
||||||
ALPN support depending on OpenSSL version. OpenSSL's ALPN
|
|
||||||
implementation does not require callback function like the above. But
|
|
||||||
we have to instruct OpenSSL SSL_CTX to use ALPN, which we'll talk
|
|
||||||
about soon.
|
|
||||||
|
|
||||||
The callback is added to the SSL_CTX object using
|
The callback is added to the SSL_CTX object using
|
||||||
``SSL_CTX_set_next_proto_select_cb()``::
|
``SSL_CTX_set_next_proto_select_cb()``::
|
||||||
|
|
||||||
@@ -59,18 +46,9 @@ The callback is added to the SSL_CTX object using
|
|||||||
SSL_OP_NO_COMPRESSION |
|
SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||||
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);
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
Here we see ``SSL_CTX_get_alpn_protos()`` function call. We instructs
|
|
||||||
OpenSSL to notify the server that we support h2, ALPN identifier for
|
|
||||||
HTTP/2.
|
|
||||||
|
|
||||||
The example client defines a couple of structs:
|
The example client defines a couple of structs:
|
||||||
|
|
||||||
We define and use a ``http2_session_data`` structure to store data
|
We define and use a ``http2_session_data`` structure to store data
|
||||||
@@ -146,27 +124,7 @@ underlying network socket::
|
|||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
int fd = bufferevent_getfd(bev);
|
int fd = bufferevent_getfd(bev);
|
||||||
int val = 1;
|
int val = 1;
|
||||||
const unsigned char *alpn = NULL;
|
|
||||||
unsigned int alpnlen = 0;
|
|
||||||
SSL *ssl;
|
|
||||||
|
|
||||||
fprintf(stderr, "Connected\n");
|
fprintf(stderr, "Connected\n");
|
||||||
|
|
||||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
|
||||||
|
|
||||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
if (alpn == NULL) {
|
|
||||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
|
||||||
}
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
|
||||||
fprintf(stderr, "h2 is not negotiated\n");
|
|
||||||
delete_http2_session_data(session_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
send_client_connection_header(session_data);
|
send_client_connection_header(session_data);
|
||||||
@@ -186,9 +144,6 @@ underlying network socket::
|
|||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Here we validate that HTTP/2 is negotiated, and if not, drop
|
|
||||||
connection.
|
|
||||||
|
|
||||||
For ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and ``BEV_EVENT_TIMEOUT``
|
For ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and ``BEV_EVENT_TIMEOUT``
|
||||||
events, we just simply tear down the connection.
|
events, we just simply tear down the connection.
|
||||||
|
|
||||||
|
|||||||
@@ -78,16 +78,15 @@ header data. To initialize the object, use
|
|||||||
|
|
||||||
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
|
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
|
||||||
|
|
||||||
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
|
To inflate header data, use `nghttp2_hd_inflate_hd()`::
|
||||||
|
|
||||||
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||||
nghttp2_nv *nv_out, int *inflate_flags,
|
nghttp2_nv *nv_out, int *inflate_flags,
|
||||||
const uint8_t *in, size_t inlen,
|
uint8_t *in, size_t inlen, int in_final);
|
||||||
int in_final);
|
|
||||||
|
|
||||||
`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a
|
`nghttp2_hd_inflate_hd()` reads a stream of bytes and outputs a single
|
||||||
single header field at a time. Multiple calls are normally required to
|
header field at a time. Multiple calls are normally required to read a
|
||||||
read a full stream of bytes and output all of the header fields.
|
full stream of bytes and output all of the header fields.
|
||||||
|
|
||||||
The *inflater* is the inflater object initialized above. The *nv_out*
|
The *inflater* is the inflater object initialized above. The *nv_out*
|
||||||
is a pointer to a :type:`nghttp2_nv` into which one header field may
|
is a pointer to a :type:`nghttp2_nv` into which one header field may
|
||||||
@@ -119,7 +118,11 @@ If *in_final* is zero and the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag is
|
|||||||
not set, it indicates that all given data was processed. The caller
|
not set, it indicates that all given data was processed. The caller
|
||||||
is required to pass additional data.
|
is required to pass additional data.
|
||||||
|
|
||||||
Example usage of `nghttp2_hd_inflate_hd2()` is shown in the
|
It is important to note that the function may produce one or more
|
||||||
|
header fields even if *inlen* is 0 when *in_final* is nonzero, due to
|
||||||
|
differential encoding.
|
||||||
|
|
||||||
|
Example usage of `nghttp2_hd_inflate_hd()` is shown in the
|
||||||
`inflate_header_block()` function in `deflate.c`_.
|
`inflate_header_block()` function in `deflate.c`_.
|
||||||
|
|
||||||
Finally, to delete a :type:`nghttp2_hd_inflater` object, use
|
Finally, to delete a :type:`nghttp2_hd_inflater` object, use
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ archive or repository.
|
|||||||
|
|
||||||
This simple server takes 3 arguments: The port number to listen on,
|
This simple server takes 3 arguments: The port number to listen on,
|
||||||
the path to your SSL/TLS private key file, and the path to your
|
the path to your SSL/TLS private key file, and the path to your
|
||||||
certificate file. The synopsis is:
|
certificate file. The synopsis is::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ libevent-server PORT /path/to/server.key /path/to/server.crt
|
$ libevent-server PORT /path/to/server.key /path/to/server.crt
|
||||||
|
|
||||||
@@ -27,17 +25,7 @@ application protocols the server supports to a client. In this
|
|||||||
example program, when creating the ``SSL_CTX`` object, we store the
|
example program, when creating the ``SSL_CTX`` object, we store the
|
||||||
application protocol name in the wire format of NPN in a statically
|
application protocol name in the wire format of NPN in a statically
|
||||||
allocated buffer. This is safe because we only create one ``SSL_CTX``
|
allocated buffer. This is safe because we only create one ``SSL_CTX``
|
||||||
object in the program's entire lifetime.
|
object in the program's entire lifetime::
|
||||||
|
|
||||||
If you are following TLS related RFC, you know that NPN is not the
|
|
||||||
standardized way to negotiate HTTP/2. NPN itself is not even
|
|
||||||
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
|
|
||||||
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
|
|
||||||
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
|
|
||||||
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
|
|
||||||
ALPN support depending on OpenSSL version. In ALPN, client sends the
|
|
||||||
list of supported application protocols, and server selects one of
|
|
||||||
them. We provide the callback for it::
|
|
||||||
|
|
||||||
static unsigned char next_proto_list[256];
|
static unsigned char next_proto_list[256];
|
||||||
static size_t next_proto_list_len;
|
static size_t next_proto_list_len;
|
||||||
@@ -49,22 +37,6 @@ them. We provide the callback for it::
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
|
|
||||||
unsigned char *outlen, const unsigned char *in,
|
|
||||||
unsigned int inlen, void *arg _U_) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
|
|
||||||
|
|
||||||
if (rv != 1) {
|
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
|
||||||
}
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
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) {
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
EC_KEY *ecdh;
|
EC_KEY *ecdh;
|
||||||
@@ -79,11 +51,6 @@ them. We provide the callback for it::
|
|||||||
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||||
|
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,11 +64,6 @@ OpenSSL implementation, we just assign the pointer to the NPN buffers
|
|||||||
we filled in earlier. The NPN callback function is set to the
|
we filled in earlier. The NPN callback function is set to the
|
||||||
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
|
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
|
||||||
|
|
||||||
In ``alpn_select_proto_cb()``, we use `nghttp2_select_next_protocol()`
|
|
||||||
to select application protocol. The `nghttp2_select_next_protocol()`
|
|
||||||
returns 1 only if it selected h2 (ALPN identifier for HTTP/2), and out
|
|
||||||
parameters were assigned accordingly.
|
|
||||||
|
|
||||||
Next, let's take a look at the main structures used by the example
|
Next, let's take a look at the main structures used by the example
|
||||||
application:
|
application:
|
||||||
|
|
||||||
@@ -205,31 +167,11 @@ underlying network socket::
|
|||||||
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
||||||
http2_session_data *session_data = (http2_session_data *)ptr;
|
http2_session_data *session_data = (http2_session_data *)ptr;
|
||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
const unsigned char *alpn = NULL;
|
|
||||||
unsigned int alpnlen = 0;
|
|
||||||
SSL *ssl;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
||||||
|
|
||||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
|
||||||
|
|
||||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
if (alpn == NULL) {
|
|
||||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
|
||||||
}
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
|
||||||
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
|
|
||||||
delete_http2_session_data(session_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
|
|
||||||
if (send_server_connection_header(session_data) != 0 ||
|
if (send_server_connection_header(session_data) != 0) {
|
||||||
session_send(session_data) != 0) {
|
|
||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -246,9 +188,6 @@ underlying network socket::
|
|||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Here we validate that HTTP/2 is negotiated, and if not, drop
|
|
||||||
connection.
|
|
||||||
|
|
||||||
For the ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and
|
For the ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and
|
||||||
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
|
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
|
||||||
The ``delete_http2_session_data()`` function destroys the
|
The ``delete_http2_session_data()`` function destroys the
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
if(ENABLE_EXAMPLES)
|
|
||||||
file(GLOB c_sources *.c)
|
|
||||||
set_source_files_properties(${c_sources} PROPERTIES
|
|
||||||
COMPILE_FLAGS "${WARNCFLAGS}")
|
|
||||||
file(GLOB cxx_sources *.cc)
|
|
||||||
set_source_files_properties(${cxx_sources} PROPERTIES
|
|
||||||
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
|
|
||||||
|
|
||||||
include_directories(
|
|
||||||
${CMAKE_SOURCE_DIR}
|
|
||||||
${CMAKE_SOURCE_DIR}/lib/includes
|
|
||||||
${CMAKE_BINARY_DIR}/lib/includes
|
|
||||||
${CMAKE_SOURCE_DIR}/src/includes
|
|
||||||
${CMAKE_SOURCE_DIR}/third-party
|
|
||||||
|
|
||||||
${LIBEVENT_INCLUDE_DIRS}
|
|
||||||
${OPENSSL_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
link_libraries(
|
|
||||||
nghttp2
|
|
||||||
${LIBEVENT_OPENSSL_LIBRARIES}
|
|
||||||
${OPENSSL_LIBRARIES}
|
|
||||||
${APP_LIBRARIES}
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(client client.c $<TARGET_OBJECTS:http-parser>)
|
|
||||||
add_executable(libevent-client libevent-client.c $<TARGET_OBJECTS:http-parser>)
|
|
||||||
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:http-parser>)
|
|
||||||
add_executable(deflate deflate.c $<TARGET_OBJECTS:http-parser>)
|
|
||||||
|
|
||||||
if(ENABLE_ASIO_LIB)
|
|
||||||
foreach(name asio-sv asio-sv2 asio-cl asio-cl2)
|
|
||||||
add_executable(${name} ${name}.cc $<TARGET_OBJECTS:http-parser>)
|
|
||||||
target_include_directories(${name} PRIVATE
|
|
||||||
${OPENSSL_INCLUDE_DIRS}
|
|
||||||
${Boost_INCLUDE_DIRS}
|
|
||||||
)
|
|
||||||
target_link_libraries(${name}
|
|
||||||
nghttp2
|
|
||||||
nghttp2_asio
|
|
||||||
${JEMALLOC_LIBRARIES}
|
|
||||||
${OPENSSL_LIBRARIES}
|
|
||||||
${Boost_LIBRARIES}
|
|
||||||
${APP_LIBRARIES}
|
|
||||||
)
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
@@ -21,8 +21,6 @@
|
|||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
EXTRA_DIST = CMakeLists.txt
|
|
||||||
|
|
||||||
if ENABLE_EXAMPLES
|
if ENABLE_EXAMPLES
|
||||||
|
|
||||||
AM_CFLAGS = $(WARNCFLAGS)
|
AM_CFLAGS = $(WARNCFLAGS)
|
||||||
@@ -51,6 +49,14 @@ libevent_server_SOURCES = libevent-server.c
|
|||||||
|
|
||||||
deflate_SOURCES = deflate.c
|
deflate_SOURCES = deflate.c
|
||||||
|
|
||||||
|
if ENABLE_TINY_NGHTTPD
|
||||||
|
|
||||||
|
noinst_PROGRAMS += tiny-nghttpd
|
||||||
|
|
||||||
|
tiny_nghttpd_SOURCES = tiny-nghttpd.c
|
||||||
|
|
||||||
|
endif # ENABLE_TINY_NGHTTPD
|
||||||
|
|
||||||
if ENABLE_ASIO_LIB
|
if ENABLE_ASIO_LIB
|
||||||
|
|
||||||
noinst_PROGRAMS += asio-sv asio-sv2 asio-cl asio-cl2
|
noinst_PROGRAMS += asio-sv asio-sv2 asio-cl asio-cl2
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ enum { IO_NONE, WANT_READ, WANT_WRITE };
|
|||||||
|
|
||||||
#define MAKE_NV(NAME, VALUE) \
|
#define MAKE_NV(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_NV_CS(NAME, VALUE) \
|
#define MAKE_NV_CS(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
|
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,9 +219,9 @@ static int on_frame_send_callback(nghttp2_session *session,
|
|||||||
const nghttp2_nv *nva = frame->headers.nva;
|
const nghttp2_nv *nva = frame->headers.nva;
|
||||||
printf("[INFO] C ----------------------------> S (HEADERS)\n");
|
printf("[INFO] C ----------------------------> S (HEADERS)\n");
|
||||||
for (i = 0; i < frame->headers.nvlen; ++i) {
|
for (i = 0; i < frame->headers.nvlen; ++i) {
|
||||||
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
||||||
printf(": ");
|
printf(": ");
|
||||||
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,9 +249,9 @@ static int on_frame_recv_callback(nghttp2_session *session,
|
|||||||
if (req) {
|
if (req) {
|
||||||
printf("[INFO] C <---------------------------- S (HEADERS)\n");
|
printf("[INFO] C <---------------------------- S (HEADERS)\n");
|
||||||
for (i = 0; i < frame->headers.nvlen; ++i) {
|
for (i = 0; i < frame->headers.nvlen; ++i) {
|
||||||
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
||||||
printf(": ");
|
printf(": ");
|
||||||
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,6 +289,8 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_OUTLEN 4096
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The implementation of nghttp2_on_data_chunk_recv_callback type. We
|
* The implementation of nghttp2_on_data_chunk_recv_callback type. We
|
||||||
* use this function to print the received response body.
|
* use this function to print the received response body.
|
||||||
@@ -457,10 +459,9 @@ static void ctl_poll(struct pollfd *pollfd, struct Connection *connection) {
|
|||||||
static void submit_request(struct Connection *connection, struct Request *req) {
|
static void submit_request(struct Connection *connection, struct Request *req) {
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
/* Make sure that the last item is NULL */
|
/* Make sure that the last item is NULL */
|
||||||
const nghttp2_nv nva[] = {MAKE_NV(":method", "GET"),
|
const nghttp2_nv nva[] = {
|
||||||
MAKE_NV_CS(":path", req->path),
|
MAKE_NV(":method", "GET"), MAKE_NV_CS(":path", req->path),
|
||||||
MAKE_NV(":scheme", "https"),
|
MAKE_NV(":scheme", "https"), MAKE_NV_CS(":authority", req->hostport),
|
||||||
MAKE_NV_CS(":authority", req->hostport),
|
|
||||||
MAKE_NV("accept", "*/*"),
|
MAKE_NV("accept", "*/*"),
|
||||||
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
|
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
|
||||||
|
|
||||||
@@ -563,11 +564,7 @@ static void fetch_uri(const struct URI *uri) {
|
|||||||
diec("nghttp2_session_client_new", rv);
|
diec("nghttp2_session_client_new", rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
|
nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
|
||||||
|
|
||||||
if (rv != 0) {
|
|
||||||
diec("nghttp2_submit_settings", rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Submit the HTTP request to the outbound queue. */
|
/* Submit the HTTP request to the outbound queue. */
|
||||||
submit_request(&connection, &req);
|
submit_request(&connection, &req);
|
||||||
@@ -696,6 +693,9 @@ int main(int argc, char **argv) {
|
|||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, 0);
|
sigaction(SIGPIPE, &act, 0);
|
||||||
|
|
||||||
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
|
OPENSSL_config(NULL);
|
||||||
|
#endif /* OPENSSL_IS_BORINGSSL */
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#define MAKE_NV(K, V) \
|
#define MAKE_NV(K, V) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
|
(uint8_t *) K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +109,9 @@ static void deflate(nghttp2_hd_deflater *deflater,
|
|||||||
printf("Input (%zu byte(s)):\n\n", sum);
|
printf("Input (%zu byte(s)):\n\n", sum);
|
||||||
|
|
||||||
for (i = 0; i < nvlen; ++i) {
|
for (i = 0; i < nvlen; ++i) {
|
||||||
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
||||||
printf(": ");
|
printf(": ");
|
||||||
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,9 +186,9 @@ int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
|
|||||||
inlen -= proclen;
|
inlen -= proclen;
|
||||||
|
|
||||||
if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
|
if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
|
||||||
fwrite(nv.name, 1, nv.namelen, stderr);
|
fwrite(nv.name, nv.namelen, 1, stderr);
|
||||||
fprintf(stderr, ": ");
|
fprintf(stderr, ": ");
|
||||||
fwrite(nv.value, 1, nv.valuelen, stderr);
|
fwrite(nv.value, nv.valuelen, 1, stderr);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ static void delete_http2_session_data(http2_session_data *session_data) {
|
|||||||
|
|
||||||
static void print_header(FILE *f, const uint8_t *name, size_t namelen,
|
static void print_header(FILE *f, const uint8_t *name, size_t namelen,
|
||||||
const uint8_t *value, size_t valuelen) {
|
const uint8_t *value, size_t valuelen) {
|
||||||
fwrite(name, 1, namelen, f);
|
fwrite(name, namelen, 1, f);
|
||||||
fprintf(f, ": ");
|
fprintf(f, ": ");
|
||||||
fwrite(value, 1, valuelen, f);
|
fwrite(value, valuelen, 1, f);
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ static int on_data_chunk_recv_callback(nghttp2_session *session _U_,
|
|||||||
void *user_data) {
|
void *user_data) {
|
||||||
http2_session_data *session_data = (http2_session_data *)user_data;
|
http2_session_data *session_data = (http2_session_data *)user_data;
|
||||||
if (session_data->stream_data->stream_id == stream_id) {
|
if (session_data->stream_data->stream_id == stream_id) {
|
||||||
fwrite(data, 1, len, stdout);
|
fwrite(data, len, 1, stdout);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -322,11 +322,6 @@ static SSL_CTX *create_ssl_ctx(void) {
|
|||||||
SSL_OP_NO_COMPRESSION |
|
SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||||
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);
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,13 +378,13 @@ static void send_client_connection_header(http2_session_data *session_data) {
|
|||||||
|
|
||||||
#define MAKE_NV(NAME, VALUE, VALUELEN) \
|
#define MAKE_NV(NAME, VALUE, VALUELEN) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
|
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_NV2(NAME, VALUE) \
|
#define MAKE_NV2(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,27 +475,7 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
|
|||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
int fd = bufferevent_getfd(bev);
|
int fd = bufferevent_getfd(bev);
|
||||||
int val = 1;
|
int val = 1;
|
||||||
const unsigned char *alpn = NULL;
|
|
||||||
unsigned int alpnlen = 0;
|
|
||||||
SSL *ssl;
|
|
||||||
|
|
||||||
fprintf(stderr, "Connected\n");
|
fprintf(stderr, "Connected\n");
|
||||||
|
|
||||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
|
||||||
|
|
||||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
if (alpn == NULL) {
|
|
||||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
|
||||||
}
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
|
||||||
fprintf(stderr, "h2 is not negotiated\n");
|
|
||||||
delete_http2_session_data(session_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
send_client_connection_header(session_data);
|
send_client_connection_header(session_data);
|
||||||
@@ -594,6 +569,9 @@ int main(int argc, char **argv) {
|
|||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, NULL);
|
sigaction(SIGPIPE, &act, NULL);
|
||||||
|
|
||||||
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
|
OPENSSL_config(NULL);
|
||||||
|
#endif /* OPENSSL_IS_BORINGSSL */
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
#define MAKE_NV(NAME, VALUE) \
|
#define MAKE_NV(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,22 +116,6 @@ static int next_proto_cb(SSL *s _U_, const unsigned char **data,
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
|
|
||||||
unsigned char *outlen, const unsigned char *in,
|
|
||||||
unsigned int inlen, void *arg _U_) {
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
|
|
||||||
|
|
||||||
if (rv != 1) {
|
|
||||||
return SSL_TLSEXT_ERR_NOACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SSL_TLSEXT_ERR_OK;
|
|
||||||
}
|
|
||||||
#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) {
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
@@ -168,11 +152,6 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
|||||||
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||||
|
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,31 +640,11 @@ static void writecb(struct bufferevent *bev, void *ptr) {
|
|||||||
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
||||||
http2_session_data *session_data = (http2_session_data *)ptr;
|
http2_session_data *session_data = (http2_session_data *)ptr;
|
||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
const unsigned char *alpn = NULL;
|
|
||||||
unsigned int alpnlen = 0;
|
|
||||||
SSL *ssl;
|
|
||||||
|
|
||||||
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
||||||
|
|
||||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
|
||||||
|
|
||||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
if (alpn == NULL) {
|
|
||||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
|
||||||
}
|
|
||||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
|
||||||
|
|
||||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
|
||||||
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
|
|
||||||
delete_http2_session_data(session_data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
|
|
||||||
if (send_server_connection_header(session_data) != 0 ||
|
if (send_server_connection_header(session_data) != 0) {
|
||||||
session_send(session_data) != 0) {
|
|
||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -781,6 +740,9 @@ int main(int argc, char **argv) {
|
|||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, NULL);
|
sigaction(SIGPIPE, &act, NULL);
|
||||||
|
|
||||||
|
#ifndef OPENSSL_IS_BORINGSSL
|
||||||
|
OPENSSL_config(NULL);
|
||||||
|
#endif /* OPENSSL_IS_BORINGSSL */
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
|
|||||||
1344
examples/tiny-nghttpd.c
Normal file
1344
examples/tiny-nghttpd.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,6 @@ def build_header(headers):
|
|||||||
c = k[-1]
|
c = k[-1]
|
||||||
if c not in ent:
|
if c not in ent:
|
||||||
ent[c] = []
|
ent[c] = []
|
||||||
if k not in ent[c]:
|
|
||||||
ent[c].append(k)
|
ent[c].append(k)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
@@ -107,7 +106,7 @@ def gen_enum():
|
|||||||
|
|
||||||
def gen_index_header():
|
def gen_index_header():
|
||||||
print '''\
|
print '''\
|
||||||
static int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
static inline int lookup_token(const uint8_t *name, size_t namelen) {
|
||||||
switch (namelen) {'''
|
switch (namelen) {'''
|
||||||
b = build_header(HEADERS)
|
b = build_header(HEADERS)
|
||||||
for size in sorted(b.keys()):
|
for size in sorted(b.keys()):
|
||||||
@@ -122,7 +121,7 @@ static int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
|||||||
case '{}':'''.format(c)
|
case '{}':'''.format(c)
|
||||||
for k in headers:
|
for k in headers:
|
||||||
print '''\
|
print '''\
|
||||||
if (memeq("{}", name, {})) {{
|
if (lstreq("{}", name, {})) {{
|
||||||
return {};
|
return {};
|
||||||
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
|
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
|
||||||
print '''\
|
print '''\
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ OPTIONS = [
|
|||||||
"tls-ticket-key-cipher",
|
"tls-ticket-key-cipher",
|
||||||
"host-rewrite",
|
"host-rewrite",
|
||||||
"tls-session-cache-memcached",
|
"tls-session-cache-memcached",
|
||||||
"tls-session-cache-memcached-tls",
|
|
||||||
"tls-ticket-key-memcached",
|
"tls-ticket-key-memcached",
|
||||||
"tls-ticket-key-memcached-interval",
|
"tls-ticket-key-memcached-interval",
|
||||||
"tls-ticket-key-memcached-max-retry",
|
"tls-ticket-key-memcached-max-retry",
|
||||||
@@ -115,44 +114,7 @@ OPTIONS = [
|
|||||||
"max-header-fields",
|
"max-header-fields",
|
||||||
"no-http2-cipher-black-list",
|
"no-http2-cipher-black-list",
|
||||||
"backend-http1-tls",
|
"backend-http1-tls",
|
||||||
"tls-session-cache-memcached-cert-file",
|
"backend-tls-session-cache-per-worker"
|
||||||
"tls-session-cache-memcached-private-key-file",
|
|
||||||
"tls-session-cache-memcached-address-family",
|
|
||||||
"tls-ticket-key-memcached-tls",
|
|
||||||
"tls-ticket-key-memcached-cert-file",
|
|
||||||
"tls-ticket-key-memcached-private-key-file",
|
|
||||||
"tls-ticket-key-memcached-address-family",
|
|
||||||
"backend-address-family",
|
|
||||||
"frontend-http2-max-concurrent-streams",
|
|
||||||
"backend-http2-max-concurrent-streams",
|
|
||||||
"backend-connections-per-frontend",
|
|
||||||
"backend-tls",
|
|
||||||
"backend-connections-per-host",
|
|
||||||
"error-page",
|
|
||||||
"no-kqueue",
|
|
||||||
"frontend-http2-settings-timeout",
|
|
||||||
"backend-http2-settings-timeout",
|
|
||||||
"api-max-request-body",
|
|
||||||
"backend-max-backoff",
|
|
||||||
"server-name",
|
|
||||||
"no-server-rewrite",
|
|
||||||
"frontend-http2-optimize-write-buffer-size",
|
|
||||||
"frontend-http2-optimize-window-size",
|
|
||||||
"frontend-http2-window-size",
|
|
||||||
"frontend-http2-connection-window-size",
|
|
||||||
"backend-http2-window-size",
|
|
||||||
"backend-http2-connection-window-size",
|
|
||||||
"frontend-http2-encoder-dynamic-table-size",
|
|
||||||
"frontend-http2-decoder-dynamic-table-size",
|
|
||||||
"backend-http2-encoder-dynamic-table-size",
|
|
||||||
"backend-http2-decoder-dynamic-table-size",
|
|
||||||
"ecdh-curves",
|
|
||||||
"tls-sct-dir",
|
|
||||||
"backend-connect-timeout",
|
|
||||||
"dns-cache-timeout",
|
|
||||||
"dns-lookup-timeout",
|
|
||||||
"dns-max-try",
|
|
||||||
"frontend-keep-alive-timeout",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
@@ -171,8 +133,6 @@ LOGVARS = [
|
|||||||
"ssl_protocol",
|
"ssl_protocol",
|
||||||
"ssl_session_id",
|
"ssl_session_id",
|
||||||
"ssl_session_reused",
|
"ssl_session_reused",
|
||||||
"backend_host",
|
|
||||||
"backend_port",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
10
help2rst.py
10
help2rst.py
@@ -160,15 +160,13 @@ DESCRIPTION
|
|||||||
print(line.strip())
|
print(line.strip())
|
||||||
|
|
||||||
def format_text(text):
|
def format_text(text):
|
||||||
# escape *, but don't escape * if it is used as bullet list.
|
# escape *
|
||||||
m = re.match(r'^\s*\*\s+', text)
|
if len(text) > len(arg_indent):
|
||||||
if m:
|
text = text[:len(arg_indent) + 1] + re.sub(r'\*', r'\*', text[len(arg_indent) + 1:])
|
||||||
text = text[:len(m.group(0))] + re.sub(r'\*', r'\*', text[len(m.group(0)):])
|
|
||||||
else:
|
else:
|
||||||
text = re.sub(r'\*', r'\*', text)
|
text = re.sub(r'\*', r'\*', text)
|
||||||
# markup option reference
|
# markup option reference
|
||||||
text = re.sub(r'(^|\s)(-[a-zA-Z0-9]|--[a-zA-Z0-9-]+)',
|
text = re.sub(r'(^|\s)(-[a-zA-Z0-9-]+)', r'\1:option:`\2`', text)
|
||||||
r'\1:option:`\2`', text)
|
|
||||||
# sphinx does not like markup like ':option:`-f`='. We need
|
# sphinx does not like markup like ':option:`-f`='. We need
|
||||||
# backslash between ` and =.
|
# backslash between ` and =.
|
||||||
text = re.sub(r'(:option:`.*?`)(\S)', r'\1\\\2', text)
|
text = re.sub(r'(:option:`.*?`)(\S)', r'\1\\\2', text)
|
||||||
|
|||||||
1
integration-tests/.gitignore
vendored
1
integration-tests/.gitignore
vendored
@@ -1,3 +1,2 @@
|
|||||||
# generated files
|
# generated files
|
||||||
config.go
|
config.go
|
||||||
setenv
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
set(GO_FILES
|
|
||||||
nghttpx_http1_test.go
|
|
||||||
nghttpx_http2_test.go
|
|
||||||
nghttpx_spdy_test.go
|
|
||||||
server_tester.go
|
|
||||||
)
|
|
||||||
|
|
||||||
# XXX unused
|
|
||||||
set(EXTRA_DIST
|
|
||||||
${GO_FILES}
|
|
||||||
server.key
|
|
||||||
server.crt
|
|
||||||
alt-server.key
|
|
||||||
alt-server.crt
|
|
||||||
setenv
|
|
||||||
req-set-header.rb
|
|
||||||
resp-set-header.rb
|
|
||||||
req-return.rb
|
|
||||||
resp-return.rb
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_target(itprep
|
|
||||||
COMMAND go get -d -v golang.org/x/net/http2
|
|
||||||
COMMAND go get -d -v github.com/tatsuhiro-t/go-nghttp2
|
|
||||||
COMMAND go get -d -v github.com/tatsuhiro-t/spdy
|
|
||||||
COMMAND go get -d -v golang.org/x/net/websocket
|
|
||||||
)
|
|
||||||
|
|
||||||
# 'go test' requires both config.go and the test files in the same directory.
|
|
||||||
# For out-of-tree builds, config.go is normally not placed next to the source
|
|
||||||
# files, so copy the tests to the build directory as a workaround.
|
|
||||||
set(GO_BUILD_FILES)
|
|
||||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
|
||||||
foreach(gofile IN LISTS GO_FILES)
|
|
||||||
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${gofile}")
|
|
||||||
add_custom_command(OUTPUT "${outfile}"
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${gofile}" "${outfile}"
|
|
||||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${gofile}"
|
|
||||||
)
|
|
||||||
list(APPEND GO_BUILD_FILES "${outfile}")
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_target(it
|
|
||||||
COMMAND sh setenv go test -v
|
|
||||||
DEPENDS ${GO_BUILD_FILES}
|
|
||||||
)
|
|
||||||
@@ -21,15 +21,11 @@
|
|||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
GO_FILES = \
|
EXTRA_DIST = \
|
||||||
nghttpx_http1_test.go \
|
nghttpx_http1_test.go \
|
||||||
nghttpx_http2_test.go \
|
nghttpx_http2_test.go \
|
||||||
nghttpx_spdy_test.go \
|
nghttpx_spdy_test.go \
|
||||||
server_tester.go
|
server_tester.go \
|
||||||
|
|
||||||
EXTRA_DIST = \
|
|
||||||
CMakeLists.txt \
|
|
||||||
$(GO_FILES) \
|
|
||||||
server.key \
|
server.key \
|
||||||
server.crt \
|
server.crt \
|
||||||
alt-server.key \
|
alt-server.key \
|
||||||
@@ -40,12 +36,11 @@ EXTRA_DIST = \
|
|||||||
req-return.rb \
|
req-return.rb \
|
||||||
resp-return.rb
|
resp-return.rb
|
||||||
|
|
||||||
itprep:
|
itprep-local:
|
||||||
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 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-local:
|
||||||
for i in $(GO_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
|
|
||||||
sh setenv go test -v
|
sh setenv go test -v
|
||||||
|
|||||||
@@ -2,5 +2,4 @@ package nghttp2
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
buildDir = "@top_builddir@"
|
buildDir = "@top_builddir@"
|
||||||
sourceDir = "@top_srcdir@"
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package nghttp2
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
@@ -104,26 +103,26 @@ Content-Length: 0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // TestH1H1ConnectFailure tests that server handles the situation that
|
// TestH1H1ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/1 backend failed.
|
// connection attempt to HTTP/1 backend failed.
|
||||||
// func TestH1H1ConnectFailure(t *testing.T) {
|
func TestH1H1ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(nil, t, noopHandler)
|
||||||
// defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
// // shutdown backend server to simulate backend connect failure
|
// shutdown backend server to simulate backend connect failure
|
||||||
// st.ts.Close()
|
st.ts.Close()
|
||||||
|
|
||||||
// res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
// name: "TestH1H1ConnectFailure",
|
name: "TestH1H1ConnectFailure",
|
||||||
// })
|
})
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("Error st.http1() = %v", err)
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
// }
|
}
|
||||||
// want := 503
|
want := 503
|
||||||
// if got := res.status; got != want {
|
if got := res.status; got != want {
|
||||||
// t.Errorf("status: %v; want %v", got, want)
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TestH1H1GracefulShutdown tests graceful shutdown.
|
// TestH1H1GracefulShutdown tests graceful shutdown.
|
||||||
func TestH1H1GracefulShutdown(t *testing.T) {
|
func TestH1H1GracefulShutdown(t *testing.T) {
|
||||||
@@ -160,9 +159,8 @@ func TestH1H1GracefulShutdown(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
want := io.EOF
|
want := io.EOF
|
||||||
b := make([]byte, 256)
|
if _, err := st.conn.Read(nil); 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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,26 +531,26 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // TestH1H2ConnectFailure tests that server handles the situation that
|
// TestH1H2ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/2 backend failed.
|
// connection attempt to HTTP/2 backend failed.
|
||||||
// func TestH1H2ConnectFailure(t *testing.T) {
|
func TestH1H2ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||||
// defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
// // simulate backend connect attempt failure
|
// simulate backend connect attempt failure
|
||||||
// st.ts.Close()
|
st.ts.Close()
|
||||||
|
|
||||||
// res, err := st.http1(requestParam{
|
res, err := st.http1(requestParam{
|
||||||
// name: "TestH1H2ConnectFailure",
|
name: "TestH1H2ConnectFailure",
|
||||||
// })
|
})
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("Error st.http1() = %v", err)
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
// }
|
}
|
||||||
// want := 503
|
want := 503
|
||||||
// if got := res.status; got != want {
|
if got := res.status; got != want {
|
||||||
// t.Errorf("status: %v; want %v", got, want)
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TestH1H2NoHost tests that server rejects request without Host
|
// TestH1H2NoHost tests that server rejects request without Host
|
||||||
// header field for HTTP/2 backend.
|
// header field for HTTP/2 backend.
|
||||||
@@ -795,221 +793,3 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %v; want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH1H2TE tests that "te: trailers" header is forwarded to HTTP/2
|
|
||||||
// backend server by stripping other encodings.
|
|
||||||
func TestH1H2TE(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if got, want := r.Header.Get("te"), "trailers"; got != want {
|
|
||||||
t.Errorf("te: %v; want %v", got, want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
|
||||||
name: "TestH1H2TE",
|
|
||||||
header: []hpack.HeaderField{
|
|
||||||
pair("te", "foo,trailers,bar"),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH1APIBackendconfig exercise backendconfig API endpoint routine
|
|
||||||
// for successful case.
|
|
||||||
func TestH1APIBackendconfig(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
|
||||||
name: "TestH1APIBackendconfig",
|
|
||||||
path: "/api/v1beta1/backendconfig",
|
|
||||||
method: "PUT",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http1() = %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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH1APIBackendconfigQuery exercise backendconfig API endpoint
|
|
||||||
// routine with query.
|
|
||||||
func TestH1APIBackendconfigQuery(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
|
||||||
name: "TestH1APIBackendconfigQuery",
|
|
||||||
path: "/api/v1beta1/backendconfig?foo=bar",
|
|
||||||
method: "PUT",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http1() = %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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH1APIBackendconfigBadMethod exercise backendconfig API endpoint
|
|
||||||
// routine with bad method.
|
|
||||||
func TestH1APIBackendconfigBadMethod(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
|
||||||
name: "TestH1APIBackendconfigBadMethod",
|
|
||||||
path: "/api/v1beta1/backendconfig",
|
|
||||||
method: "GET",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http1() = %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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH1APINotFound exercise backendconfig API endpoint routine when
|
|
||||||
// API endpoint is not found.
|
|
||||||
func TestH1APINotFound(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
|
||||||
name: "TestH1APINotFound",
|
|
||||||
path: "/api/notfound",
|
|
||||||
method: "GET",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http1() = %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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH1Healthmon tests health monitor endpoint.
|
|
||||||
func TestH1Healthmon(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3011)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
|
||||||
name: "TestH1Healthmon",
|
|
||||||
path: "/alpha/bravo",
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http1() = %v", err)
|
|
||||||
}
|
|
||||||
if got, want := res.status, 200; got != want {
|
|
||||||
t.Errorf("res.status: %v; want %v", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH1ResponseBeforeRequestEnd tests the situation where response
|
|
||||||
// ends before request body finishes.
|
|
||||||
func TestH1ResponseBeforeRequestEnd(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatal("request should not be forwarded")
|
|
||||||
})
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, fmt.Sprintf(`POST / HTTP/1.1
|
|
||||||
Host: %v
|
|
||||||
Test-Case: TestH1ResponseBeforeRequestEnd
|
|
||||||
Content-Length: 1000000
|
|
||||||
|
|
||||||
`, st.authority)); err != nil {
|
|
||||||
t.Fatalf("Error io.WriteString() = %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error http.ReadResponse() = %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if got, want := resp.StatusCode, 404; got != want {
|
|
||||||
t.Errorf("status: %v; want %v", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package nghttp2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
@@ -569,26 +568,26 @@ func TestH2H1InvalidRequestCL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // TestH2H1ConnectFailure tests that server handles the situation that
|
// TestH2H1ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/1 backend failed.
|
// connection attempt to HTTP/1 backend failed.
|
||||||
// func TestH2H1ConnectFailure(t *testing.T) {
|
func TestH2H1ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(nil, t, noopHandler)
|
||||||
// defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
// // shutdown backend server to simulate backend connect failure
|
// shutdown backend server to simulate backend connect failure
|
||||||
// st.ts.Close()
|
st.ts.Close()
|
||||||
|
|
||||||
// res, err := st.http2(requestParam{
|
res, err := st.http2(requestParam{
|
||||||
// name: "TestH2H1ConnectFailure",
|
name: "TestH2H1ConnectFailure",
|
||||||
// })
|
})
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("Error st.http2() = %v", err)
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
// }
|
}
|
||||||
// want := 503
|
want := 503
|
||||||
// if got := res.status; got != want {
|
if got := res.status; got != want {
|
||||||
// t.Errorf("status: %v; want %v", got, want)
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TestH2H1InvalidMethod tests that server rejects invalid method with
|
// TestH2H1InvalidMethod tests that server rejects invalid method with
|
||||||
// 501.
|
// 501.
|
||||||
@@ -1369,42 +1368,6 @@ func TestH2H1ProxyProtocolV1InvalidID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH2H1ExternalDNS tests that DNS resolution using external DNS
|
|
||||||
// with HTTP/1 backend works.
|
|
||||||
func TestH2H1ExternalDNS(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--external-dns"}, t, noopHandler)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2H1ExternalDNS",
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2H1DNS tests that DNS resolution without external DNS with
|
|
||||||
// HTTP/1 backend works.
|
|
||||||
func TestH2H1DNS(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--dns"}, t, noopHandler)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2H1DNS",
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
||||||
@@ -1523,26 +1486,26 @@ func TestH2H2InvalidResponseCL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // TestH2H2ConnectFailure tests that server handles the situation that
|
// TestH2H2ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/2 backend failed.
|
// connection attempt to HTTP/2 backend failed.
|
||||||
// func TestH2H2ConnectFailure(t *testing.T) {
|
func TestH2H2ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||||
// defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
// // simulate backend connect attempt failure
|
// simulate backend connect attempt failure
|
||||||
// st.ts.Close()
|
st.ts.Close()
|
||||||
|
|
||||||
// res, err := st.http2(requestParam{
|
res, err := st.http2(requestParam{
|
||||||
// name: "TestH2H2ConnectFailure",
|
name: "TestH2H2ConnectFailure",
|
||||||
// })
|
})
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("Error st.http2() = %v", err)
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
// }
|
}
|
||||||
// want := 503
|
want := 503
|
||||||
// if got := res.status; got != want {
|
if got := res.status; got != want {
|
||||||
// t.Errorf("status: %v; want %v", got, want)
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TestH2H2HostRewrite tests that server rewrites host header field
|
// TestH2H2HostRewrite tests that server rewrites host header field
|
||||||
func TestH2H2HostRewrite(t *testing.T) {
|
func TestH2H2HostRewrite(t *testing.T) {
|
||||||
@@ -1880,226 +1843,3 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %v; want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH2H2ExternalDNS tests that DNS resolution using external DNS
|
|
||||||
// with HTTP/2 backend works.
|
|
||||||
func TestH2H2ExternalDNS(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--http2-bridge", "--external-dns"}, t, noopHandler)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2H2ExternalDNS",
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2H2DNS tests that DNS resolution without external DNS with
|
|
||||||
// HTTP/2 backend works.
|
|
||||||
func TestH2H2DNS(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--http2-bridge", "--dns"}, t, noopHandler)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2H2DNS",
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2APIBackendconfig exercise backendconfig API endpoint routine
|
|
||||||
// for successful case.
|
|
||||||
func TestH2APIBackendconfig(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2APIBackendconfig",
|
|
||||||
path: "/api/v1beta1/backendconfig",
|
|
||||||
method: "PUT",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2APIBackendconfigQuery exercise backendconfig API endpoint
|
|
||||||
// routine with query.
|
|
||||||
func TestH2APIBackendconfigQuery(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2APIBackendconfigQuery",
|
|
||||||
path: "/api/v1beta1/backendconfig?foo=bar",
|
|
||||||
method: "PUT",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2APIBackendconfigBadMethod exercise backendconfig API endpoint
|
|
||||||
// routine with bad method.
|
|
||||||
func TestH2APIBackendconfigBadMethod(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2APIBackendconfigBadMethod",
|
|
||||||
path: "/api/v1beta1/backendconfig",
|
|
||||||
method: "GET",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http2() = %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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2APINotFound exercise backendconfig API endpoint routine when
|
|
||||||
// API endpoint is not found.
|
|
||||||
func TestH2APINotFound(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3010)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2APINotFound",
|
|
||||||
path: "/api/notfound",
|
|
||||||
method: "GET",
|
|
||||||
body: []byte(`# comment
|
|
||||||
backend=127.0.0.1,3011
|
|
||||||
|
|
||||||
`),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http2() = %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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2Healthmon tests health monitor endpoint.
|
|
||||||
func TestH2Healthmon(t *testing.T) {
|
|
||||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
t.Fatalf("request should not be forwarded")
|
|
||||||
}, 3011)
|
|
||||||
defer st.Close()
|
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
|
||||||
name: "TestH2Healthmon",
|
|
||||||
path: "/alpha/bravo",
|
|
||||||
})
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestH2ResponseBeforeRequestEnd tests the situation where response
|
|
||||||
// ends before request body finishes.
|
|
||||||
func TestH2ResponseBeforeRequestEnd(t *testing.T) {
|
|
||||||
st := newServerTester([]string{"--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.http2(requestParam{
|
|
||||||
name: "TestH2ResponseBeforeRequestEnd",
|
|
||||||
noEndStream: true,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Error st.http2() = %v", err)
|
|
||||||
}
|
|
||||||
if got, want := res.status, 404; got != want {
|
|
||||||
t.Errorf("res.status: %v; want %v", got, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package nghttp2
|
package nghttp2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"github.com/tatsuhiro-t/spdy"
|
"github.com/tatsuhiro-t/spdy"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -385,26 +384,26 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // TestS3H2ConnectFailure tests that server handles the situation that
|
// TestS3H2ConnectFailure tests that server handles the situation that
|
||||||
// // connection attempt to HTTP/2 backend failed.
|
// connection attempt to HTTP/2 backend failed.
|
||||||
// func TestS3H2ConnectFailure(t *testing.T) {
|
func TestS3H2ConnectFailure(t *testing.T) {
|
||||||
// st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
|
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
|
||||||
// defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
// // simulate backend connect attempt failure
|
// simulate backend connect attempt failure
|
||||||
// st.ts.Close()
|
st.ts.Close()
|
||||||
|
|
||||||
// res, err := st.spdy(requestParam{
|
res, err := st.spdy(requestParam{
|
||||||
// name: "TestS3H2ConnectFailure",
|
name: "TestS3H2ConnectFailure",
|
||||||
// })
|
})
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("Error st.spdy() = %v", err)
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
// }
|
}
|
||||||
// want := 503
|
want := 503
|
||||||
// if got := res.status; got != want {
|
if got := res.status; got != want {
|
||||||
// t.Errorf("status: %v; want %v", got, want)
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
|
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
|
||||||
// custom response.
|
// custom response.
|
||||||
@@ -475,190 +474,3 @@ func TestS3H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"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"
|
||||||
|
"github.com/tatsuhiro-t/go-nghttp2"
|
||||||
|
"github.com/tatsuhiro-t/spdy"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -29,8 +29,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
serverBin = buildDir + "/src/nghttpx"
|
serverBin = buildDir + "/src/nghttpx"
|
||||||
serverPort = 3009
|
serverPort = 3009
|
||||||
testDir = sourceDir + "/integration-tests"
|
testDir = buildDir + "/integration-tests"
|
||||||
logDir = buildDir + "/integration-tests"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func pair(name, value string) hpack.HeaderField {
|
func pair(name, value string) hpack.HeaderField {
|
||||||
@@ -66,54 +65,34 @@ type serverTester struct {
|
|||||||
// newServerTester creates test context for plain TCP frontend
|
// newServerTester creates test context for plain TCP frontend
|
||||||
// connection.
|
// connection.
|
||||||
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
|
return newServerTesterInternal(args, t, handler, false, nil)
|
||||||
}
|
|
||||||
|
|
||||||
func newServerTesterConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
|
|
||||||
return newServerTesterInternal(args, t, handler, false, port, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServerTesterHandler(args []string, t *testing.T, handler http.Handler) *serverTester {
|
func newServerTesterHandler(args []string, t *testing.T, handler http.Handler) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
|
return newServerTesterInternal(args, t, handler, false, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newServerTester creates test context for TLS frontend connection.
|
// newServerTester creates test context for TLS frontend connection.
|
||||||
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, true, serverPort, nil)
|
return newServerTesterInternal(args, t, handler, true, nil)
|
||||||
}
|
|
||||||
|
|
||||||
func newServerTesterTLSConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
|
|
||||||
return newServerTesterInternal(args, t, handler, true, port, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newServerTester creates test context for TLS frontend connection
|
// newServerTester creates test context for TLS frontend connection
|
||||||
// with given clientConfig
|
// with given clientConfig
|
||||||
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
|
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, true, serverPort, clientConfig)
|
return newServerTesterInternal(args, t, handler, true, clientConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newServerTesterInternal creates test context. If frontendTLS is
|
// newServerTesterInternal creates test context. If frontendTLS is
|
||||||
// true, set up TLS frontend connection. connectPort is the server
|
// true, set up TLS frontend connection.
|
||||||
// side port where client connection is made.
|
func newServerTesterInternal(args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
|
||||||
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, connectPort int, clientConfig *tls.Config) *serverTester {
|
|
||||||
ts := httptest.NewUnstartedServer(handler)
|
ts := httptest.NewUnstartedServer(handler)
|
||||||
|
|
||||||
args := []string{}
|
|
||||||
|
|
||||||
backendTLS := false
|
backendTLS := false
|
||||||
dns := false
|
for _, k := range args {
|
||||||
externalDNS := false
|
|
||||||
for _, k := range src_args {
|
|
||||||
switch k {
|
switch k {
|
||||||
case "--http2-bridge":
|
case "--http2-bridge":
|
||||||
backendTLS = true
|
backendTLS = true
|
||||||
case "--dns":
|
|
||||||
dns = true
|
|
||||||
case "--external-dns":
|
|
||||||
dns = true
|
|
||||||
externalDNS = true
|
|
||||||
default:
|
|
||||||
args = append(args, k)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if backendTLS {
|
if backendTLS {
|
||||||
@@ -122,7 +101,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
// NextProtos separately for ts.TLS. NextProtos set
|
// NextProtos separately for ts.TLS. NextProtos set
|
||||||
// in nghttp2.ConfigureServer is effectively ignored.
|
// in nghttp2.ConfigureServer is effectively ignored.
|
||||||
ts.TLS = new(tls.Config)
|
ts.TLS = new(tls.Config)
|
||||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
|
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2-14")
|
||||||
ts.StartTLS()
|
ts.StartTLS()
|
||||||
args = append(args, "-k")
|
args = append(args, "-k")
|
||||||
} else {
|
} else {
|
||||||
@@ -132,6 +111,8 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
if frontendTLS {
|
if frontendTLS {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
||||||
|
} else {
|
||||||
|
args = append(args, "--frontend-no-tls")
|
||||||
}
|
}
|
||||||
|
|
||||||
backendURL, err := url.Parse(ts.URL)
|
backendURL, err := url.Parse(ts.URL)
|
||||||
@@ -141,34 +122,11 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
|
|
||||||
// URL.Host looks like "127.0.0.1:8080", but we want
|
// URL.Host looks like "127.0.0.1:8080", but we want
|
||||||
// "127.0.0.1,8080"
|
// "127.0.0.1,8080"
|
||||||
b := "-b"
|
b := "-b" + strings.Replace(backendURL.Host, ":", ",", -1)
|
||||||
if !externalDNS {
|
args = append(args, fmt.Sprintf("-f127.0.0.1,%v", serverPort), b,
|
||||||
b += fmt.Sprintf("%v;", strings.Replace(backendURL.Host, ":", ",", -1))
|
"--errorlog-file="+testDir+"/log.txt", "-LINFO")
|
||||||
} else {
|
|
||||||
sep := strings.LastIndex(backendURL.Host, ":")
|
|
||||||
if sep == -1 {
|
|
||||||
t.Fatalf("backendURL.Host %v does not contain separator ':'", backendURL.Host)
|
|
||||||
}
|
|
||||||
// We use awesome service xip.io.
|
|
||||||
b += fmt.Sprintf("%v.xip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
|
|
||||||
}
|
|
||||||
|
|
||||||
if backendTLS {
|
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)
|
||||||
b += ";proto=h2;tls"
|
|
||||||
}
|
|
||||||
if dns {
|
|
||||||
b += ";dns"
|
|
||||||
}
|
|
||||||
|
|
||||||
noTLS := "no-tls"
|
|
||||||
if frontendTLS {
|
|
||||||
noTLS = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
|
|
||||||
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
|
||||||
|
|
||||||
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
|
|
||||||
|
|
||||||
st := &serverTester{
|
st := &serverTester{
|
||||||
cmd: exec.Command(serverBin, args...),
|
cmd: exec.Command(serverBin, args...),
|
||||||
@@ -190,8 +148,6 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
|
|
||||||
retry := 0
|
retry := 0
|
||||||
for {
|
for {
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
|
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
var err error
|
var err error
|
||||||
if frontendTLS {
|
if frontendTLS {
|
||||||
@@ -202,7 +158,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
tlsConfig = clientConfig
|
tlsConfig = clientConfig
|
||||||
}
|
}
|
||||||
tlsConfig.InsecureSkipVerify = true
|
tlsConfig.InsecureSkipVerify = true
|
||||||
tlsConfig.NextProtos = []string{"h2", "spdy/3.1"}
|
tlsConfig.NextProtos = []string{"h2-14", "spdy/3.1"}
|
||||||
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)
|
||||||
@@ -213,6 +169,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
st.Close()
|
st.Close()
|
||||||
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
|
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
|
||||||
}
|
}
|
||||||
|
time.Sleep(150 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if frontendTLS {
|
if frontendTLS {
|
||||||
@@ -318,7 +275,6 @@ type requestParam struct {
|
|||||||
body []byte // request body
|
body []byte // request body
|
||||||
trailer []hpack.HeaderField // trailer part
|
trailer []hpack.HeaderField // trailer part
|
||||||
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
|
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
|
||||||
noEndStream bool // true if END_STREAM should not be sent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrapper for request body to set trailer part
|
// wrapper for request body to set trailer part
|
||||||
@@ -402,9 +358,8 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
|
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
|
||||||
}
|
}
|
||||||
u.Path = ""
|
u.Path = rp.path
|
||||||
u.RawQuery = ""
|
reqURL = u.String()
|
||||||
reqURL = u.String() + rp.path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(method, reqURL, body)
|
req, err := http.NewRequest(method, reqURL, body)
|
||||||
@@ -493,7 +448,7 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var synStreamFlags spdy.ControlFlags
|
var synStreamFlags spdy.ControlFlags
|
||||||
if len(rp.body) == 0 && !rp.noEndStream {
|
if len(rp.body) == 0 {
|
||||||
synStreamFlags = spdy.ControlFlagFin
|
synStreamFlags = spdy.ControlFlagFin
|
||||||
}
|
}
|
||||||
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
|
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
|
||||||
@@ -507,13 +462,9 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(rp.body) != 0 {
|
if len(rp.body) != 0 {
|
||||||
var dataFlags spdy.DataFlags
|
|
||||||
if !rp.noEndStream {
|
|
||||||
dataFlags = spdy.DataFlagFin
|
|
||||||
}
|
|
||||||
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
|
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
|
||||||
StreamId: id,
|
StreamId: id,
|
||||||
Flags: dataFlags,
|
Flags: spdy.DataFlagFin,
|
||||||
Data: rp.body,
|
Data: rp.body,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -626,7 +577,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
|||||||
|
|
||||||
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
||||||
StreamID: id,
|
StreamID: id,
|
||||||
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0 && !rp.noEndStream,
|
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
|
||||||
EndHeaders: true,
|
EndHeaders: true,
|
||||||
BlockFragment: st.headerBlkBuf.Bytes(),
|
BlockFragment: st.headerBlkBuf.Bytes(),
|
||||||
})
|
})
|
||||||
@@ -636,7 +587,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
|||||||
|
|
||||||
if len(rp.body) != 0 {
|
if len(rp.body) != 0 {
|
||||||
// TODO we assume rp.body fits in 1 frame
|
// TODO we assume rp.body fits in 1 frame
|
||||||
if err := st.fr.WriteData(id, len(rp.trailer) == 0 && !rp.noEndStream, rp.body); err != nil {
|
if err := st.fr.WriteData(id, len(rp.trailer) == 0, rp.body); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -783,8 +734,3 @@ func cloneHeader(h http.Header) http.Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func noopHandler(w http.ResponseWriter, r *http.Request) {}
|
func noopHandler(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
type APIResponse struct {
|
|
||||||
Status string `json:"status,omitempty"`
|
|
||||||
Code int `json:"code,omitempty"`
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
libdir="@abs_top_builddir@/lib"
|
|
||||||
if [ -d "$libdir/.libs" ]; then
|
|
||||||
libdir="$libdir/.libs"
|
|
||||||
fi
|
|
||||||
|
|
||||||
export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
|
export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
|
||||||
export CGO_LDFLAGS="-L$libdir"
|
export CGO_LDFLAGS="-L@abs_top_builddir@/lib/.libs"
|
||||||
export LD_LIBRARY_PATH="$libdir"
|
export LD_LIBRARY_PATH="@abs_top_builddir@/lib/.libs"
|
||||||
export GODEBUG=cgocheck=0
|
|
||||||
"$@"
|
"$@"
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
add_subdirectory(includes)
|
|
||||||
|
|
||||||
include_directories(
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/includes"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_definitions(-DBUILDING_NGHTTP2)
|
|
||||||
|
|
||||||
set(NGHTTP2_SOURCES
|
|
||||||
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
|
|
||||||
nghttp2_frame.c
|
|
||||||
nghttp2_buf.c
|
|
||||||
nghttp2_stream.c nghttp2_outbound_item.c
|
|
||||||
nghttp2_session.c nghttp2_submit.c
|
|
||||||
nghttp2_helper.c
|
|
||||||
nghttp2_npn.c
|
|
||||||
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
|
|
||||||
nghttp2_version.c
|
|
||||||
nghttp2_priority_spec.c
|
|
||||||
nghttp2_option.c
|
|
||||||
nghttp2_callbacks.c
|
|
||||||
nghttp2_mem.c
|
|
||||||
nghttp2_http.c
|
|
||||||
nghttp2_rcbuf.c
|
|
||||||
nghttp2_debug.c
|
|
||||||
)
|
|
||||||
|
|
||||||
set(NGHTTP2_RES "")
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
configure_file(
|
|
||||||
version.rc.in
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
|
||||||
@ONLY)
|
|
||||||
|
|
||||||
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Public shared library
|
|
||||||
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
|
|
||||||
set_target_properties(nghttp2 PROPERTIES
|
|
||||||
COMPILE_FLAGS "${WARNCFLAGS}"
|
|
||||||
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
|
||||||
C_VISIBILITY_PRESET hidden
|
|
||||||
)
|
|
||||||
|
|
||||||
if(HAVE_CUNIT)
|
|
||||||
# Static library (for unittests because of symbol visibility)
|
|
||||||
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
|
|
||||||
set_target_properties(nghttp2_static PROPERTIES
|
|
||||||
COMPILE_FLAGS "${WARNCFLAGS}"
|
|
||||||
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
|
||||||
ARCHIVE_OUTPUT_NAME nghttp2
|
|
||||||
)
|
|
||||||
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(TARGETS nghttp2
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
|
||||||
@@ -22,7 +22,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.
|
||||||
SUBDIRS = includes
|
SUBDIRS = includes
|
||||||
|
|
||||||
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
|
EXTRA_DIST = Makefile.msvc
|
||||||
|
|
||||||
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
||||||
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
||||||
@@ -47,9 +47,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
|||||||
nghttp2_option.c \
|
nghttp2_option.c \
|
||||||
nghttp2_callbacks.c \
|
nghttp2_callbacks.c \
|
||||||
nghttp2_mem.c \
|
nghttp2_mem.c \
|
||||||
nghttp2_http.c \
|
nghttp2_http.c
|
||||||
nghttp2_rcbuf.c \
|
|
||||||
nghttp2_debug.c
|
|
||||||
|
|
||||||
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||||
nghttp2_frame.h \
|
nghttp2_frame.h \
|
||||||
@@ -63,9 +61,7 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
|||||||
nghttp2_option.h \
|
nghttp2_option.h \
|
||||||
nghttp2_callbacks.h \
|
nghttp2_callbacks.h \
|
||||||
nghttp2_mem.h \
|
nghttp2_mem.h \
|
||||||
nghttp2_http.h \
|
nghttp2_http.h
|
||||||
nghttp2_rcbuf.h \
|
|
||||||
nghttp2_debug.h
|
|
||||||
|
|
||||||
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
||||||
libnghttp2_la_LDFLAGS = -no-undefined \
|
libnghttp2_la_LDFLAGS = -no-undefined \
|
||||||
|
|||||||
@@ -12,16 +12,16 @@
|
|||||||
#
|
#
|
||||||
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||||
|
|
||||||
USE_CYTHON := 0
|
USE_CYTHON := 1
|
||||||
#USE_CYTHON := 1
|
#USE_CYTHON := 0
|
||||||
|
|
||||||
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -e 's/-DEV//g' -e 's/], //g')
|
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -r -e 's/(-DEV)?], //g')
|
||||||
_VERSION := $(subst ., ,$(_VERSION))
|
_VERSION := $(subst ., ,$(_VERSION))
|
||||||
VER_MAJOR := $(word 1,$(_VERSION))
|
VER_MAJOR := $(word 1,$(_VERSION))
|
||||||
VER_MINOR := $(word 2,$(_VERSION))
|
VER_MINOR := $(word 2,$(_VERSION))
|
||||||
VER_MICRO := $(word 3,$(_VERSION))
|
VER_MICRO := $(word 3,$(_VERSION))
|
||||||
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO)
|
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO)
|
||||||
VERSION_NUM := (($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO))
|
VERSION_NUM := ($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO)
|
||||||
|
|
||||||
GENERATED := 'Generated by $(realpath Makefile.MSVC)'
|
GENERATED := 'Generated by $(realpath Makefile.MSVC)'
|
||||||
|
|
||||||
@@ -90,8 +90,7 @@ NGHTTP2_SRC := nghttp2_pq.c \
|
|||||||
nghttp2_option.c \
|
nghttp2_option.c \
|
||||||
nghttp2_callbacks.c \
|
nghttp2_callbacks.c \
|
||||||
nghttp2_mem.c \
|
nghttp2_mem.c \
|
||||||
nghttp2_http.c \
|
nghttp2_http.c
|
||||||
nghttp2_rcbuf.c
|
|
||||||
|
|
||||||
NGHTTP2_OBJ_R := $(addprefix $(OBJ_DIR)/r_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
NGHTTP2_OBJ_R := $(addprefix $(OBJ_DIR)/r_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
||||||
NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
||||||
@@ -102,7 +101,7 @@ NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
|||||||
clean_nghttp2_pyd_0 clean_nghttp2_pyd_1
|
clean_nghttp2_pyd_0 clean_nghttp2_pyd_1
|
||||||
|
|
||||||
|
|
||||||
all: intro includes/nghttp2/nghttp2ver.h $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
|
all: intro $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
|
||||||
@echo 'Welcome to NgHTTP2 (release + debug).'
|
@echo 'Welcome to NgHTTP2 (release + debug).'
|
||||||
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
|
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
|
||||||
|
|
||||||
@@ -194,17 +193,17 @@ $(OBJ_DIR)/d_%.obj: %.c $(THIS_MAKEFILE)
|
|||||||
@echo
|
@echo
|
||||||
|
|
||||||
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
||||||
$(RC) -D_RELEASE -Fo $@ $<
|
$(RC) -nologo -D_RELEASE -Fo $@ $<
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
||||||
$(RC) -D_DEBUG -Fo $@ $<
|
$(RC) -nologo -D_DEBUG -Fo $@ $<
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
|
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
|
||||||
sed < includes/nghttp2/nghttp2ver.h.in \
|
sed < includes/nghttp2/nghttp2ver.h.in \
|
||||||
-e 's/@PACKAGE_VERSION@/$(VERSION)/g' \
|
-e 's/@PACKAGE_VERSION@/$(VERSION)/g' \
|
||||||
-e 's/@PACKAGE_VERSION_NUM@/$(VERSION_NUM)/g' > $@
|
-e 's/@PACKAGE_VERSION_NUM@/($(VERSION_NUM))/g' > $@
|
||||||
touch --reference=includes/nghttp2/nghttp2ver.h.in $@
|
touch --reference=includes/nghttp2/nghttp2ver.h.in $@
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
install(FILES
|
|
||||||
nghttp2/nghttp2.h
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/nghttp2/nghttp2ver.h"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nghttp2")
|
|
||||||
@@ -20,7 +20,4 @@
|
|||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
EXTRA_DIST = CMakeLists.txt
|
|
||||||
|
|
||||||
nobase_include_HEADERS = nghttp2/nghttp2.h nghttp2/nghttp2ver.h
|
nobase_include_HEADERS = nghttp2/nghttp2.h nghttp2/nghttp2ver.h
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "nghttp2_helper.h"
|
#include "nghttp2_helper.h"
|
||||||
#include "nghttp2_debug.h"
|
|
||||||
|
|
||||||
void nghttp2_buf_init(nghttp2_buf *buf) {
|
void nghttp2_buf_init(nghttp2_buf *buf) {
|
||||||
buf->begin = NULL;
|
buf->begin = NULL;
|
||||||
@@ -224,54 +223,13 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
|
||||||
size_t veclen, nghttp2_mem *mem) {
|
|
||||||
size_t i = 0;
|
|
||||||
nghttp2_buf_chain *cur_chain;
|
|
||||||
nghttp2_buf_chain *head_chain;
|
|
||||||
nghttp2_buf_chain **dst_chain = &head_chain;
|
|
||||||
|
|
||||||
if (veclen == 0) {
|
|
||||||
return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
head_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain) * veclen);
|
|
||||||
if (head_chain == NULL) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < veclen; ++i) {
|
|
||||||
cur_chain = &head_chain[i];
|
|
||||||
cur_chain->next = NULL;
|
|
||||||
nghttp2_buf_wrap_init(&cur_chain->buf, vec[i].base, vec[i].len);
|
|
||||||
|
|
||||||
*dst_chain = cur_chain;
|
|
||||||
dst_chain = &cur_chain->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
bufs->mem = mem;
|
|
||||||
bufs->offset = 0;
|
|
||||||
|
|
||||||
bufs->head = head_chain;
|
|
||||||
bufs->cur = bufs->head;
|
|
||||||
|
|
||||||
/* We don't use chunk_length since no allocation is expected. */
|
|
||||||
bufs->chunk_length = 0;
|
|
||||||
bufs->chunk_used = veclen;
|
|
||||||
bufs->max_chunk = veclen;
|
|
||||||
bufs->chunk_keep = veclen;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
|
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
|
||||||
if (bufs == NULL) {
|
if (bufs == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bufs->head) {
|
|
||||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||||
}
|
bufs->head = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
||||||
@@ -298,6 +256,12 @@ size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t bufs_avail(nghttp2_bufs *bufs) {
|
||||||
|
return nghttp2_buf_avail(&bufs->cur->buf) +
|
||||||
|
(bufs->chunk_length - bufs->offset) *
|
||||||
|
(bufs->max_chunk - bufs->chunk_used);
|
||||||
|
}
|
||||||
|
|
||||||
static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
||||||
int rv;
|
int rv;
|
||||||
nghttp2_buf_chain *chain;
|
nghttp2_buf_chain *chain;
|
||||||
@@ -317,8 +281,9 @@ static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
DEBUGF(fprintf(stderr,
|
||||||
bufs->chunk_length, bufs, bufs->chunk_used);
|
"new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
||||||
|
bufs->chunk_length, bufs, bufs->chunk_used));
|
||||||
|
|
||||||
++bufs->chunk_used;
|
++bufs->chunk_used;
|
||||||
|
|
||||||
@@ -336,6 +301,10 @@ int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) {
|
|||||||
nghttp2_buf *buf;
|
nghttp2_buf *buf;
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
|
|
||||||
|
if (bufs_avail(bufs) < len) {
|
||||||
|
return NGHTTP2_ERR_BUFFER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
p = data;
|
p = data;
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ typedef struct {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes the |buf|. No memory is allocated in this function. Use
|
* Initializes the |buf|. No memory is allocated in this function. Use
|
||||||
* nghttp2_buf_reserve() to allocate memory.
|
* nghttp2_buf_reserve() or nghttp2_buf_reserve2() to allocate memory.
|
||||||
*/
|
*/
|
||||||
void nghttp2_buf_init(nghttp2_buf *buf);
|
void nghttp2_buf_init(nghttp2_buf *buf);
|
||||||
|
|
||||||
@@ -138,9 +138,7 @@ typedef struct {
|
|||||||
nghttp2_buf_chain *cur;
|
nghttp2_buf_chain *cur;
|
||||||
/* Memory allocator */
|
/* Memory allocator */
|
||||||
nghttp2_mem *mem;
|
nghttp2_mem *mem;
|
||||||
/* The buffer capacity of each buf. This field may be 0 if
|
/* The buffer capacity of each buf */
|
||||||
nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
|
|
||||||
functions. */
|
|
||||||
size_t chunk_length;
|
size_t chunk_length;
|
||||||
/* The maximum number of nghttp2_buf_chain */
|
/* The maximum number of nghttp2_buf_chain */
|
||||||
size_t max_chunk;
|
size_t max_chunk;
|
||||||
@@ -199,13 +197,10 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
|||||||
/*
|
/*
|
||||||
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
||||||
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
||||||
* is fixed and no extra chunk buffer is allocated. In other
|
* is fixed and no allocate extra chunk buffer is allocated. In other
|
||||||
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
||||||
* for |bufs|, use nghttp2_bufs_wrap_free().
|
* for |bufs|, use nghttp2_bufs_wrap_free().
|
||||||
*
|
*
|
||||||
* Don't use the function which performs allocation, such as
|
|
||||||
* nghttp2_bufs_realloc().
|
|
||||||
*
|
|
||||||
* 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:
|
||||||
*
|
*
|
||||||
@@ -215,25 +210,6 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
|||||||
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||||
nghttp2_mem *mem);
|
nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
|
||||||
* Initializes |bufs| using supplied |veclen| size of buf vector
|
|
||||||
* |vec|. The number of buffers is fixed and no extra chunk buffer is
|
|
||||||
* allocated. In other words, max_chunk = chunk_keep = |in_len|. To
|
|
||||||
* free the resource allocated for |bufs|, use
|
|
||||||
* nghttp2_bufs_wrap_free().
|
|
||||||
*
|
|
||||||
* Don't use the function which performs allocation, such as
|
|
||||||
* nghttp2_bufs_realloc().
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
*/
|
|
||||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
|
||||||
size_t veclen, nghttp2_mem *mem);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frees any related resource to the |bufs|. This function does not
|
* Frees any related resource to the |bufs|. This function does not
|
||||||
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||||
@@ -336,8 +312,8 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copies all data stored in |bufs| to the contiguous buffer. This
|
* Copies all data stored in |bufs| to the contagious buffer. This
|
||||||
* function allocates the contiguous memory to store all data in
|
* function allocates the contagious memory to store all data in
|
||||||
* |bufs| and assigns it to |*out|.
|
* |bufs| and assigns it to |*out|.
|
||||||
*
|
*
|
||||||
* The contents of |bufs| is left unchanged.
|
* The contents of |bufs| is left unchanged.
|
||||||
@@ -405,7 +381,7 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
|||||||
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the total buffer length of |bufs|.
|
* Returns the buffer length of |bufs|.
|
||||||
*/
|
*/
|
||||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||||
|
|
||||||
|
|||||||
@@ -104,24 +104,6 @@ void nghttp2_session_callbacks_set_on_header_callback(
|
|||||||
cbs->on_header_callback = on_header_callback;
|
cbs->on_header_callback = on_header_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_on_header_callback2(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_on_header_callback2 on_header_callback2) {
|
|
||||||
cbs->on_header_callback2 = on_header_callback2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_on_invalid_header_callback(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_on_invalid_header_callback on_invalid_header_callback) {
|
|
||||||
cbs->on_invalid_header_callback = on_invalid_header_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) {
|
|
||||||
cbs->on_invalid_header_callback2 = on_invalid_header_callback2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_select_padding_callback(
|
void nghttp2_session_callbacks_set_select_padding_callback(
|
||||||
nghttp2_session_callbacks *cbs,
|
nghttp2_session_callbacks *cbs,
|
||||||
nghttp2_select_padding_callback select_padding_callback) {
|
nghttp2_select_padding_callback select_padding_callback) {
|
||||||
@@ -145,26 +127,3 @@ void nghttp2_session_callbacks_set_send_data_callback(
|
|||||||
nghttp2_send_data_callback send_data_callback) {
|
nghttp2_send_data_callback send_data_callback) {
|
||||||
cbs->send_data_callback = send_data_callback;
|
cbs->send_data_callback = send_data_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_pack_extension_callback(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_pack_extension_callback pack_extension_callback) {
|
|
||||||
cbs->pack_extension_callback = pack_extension_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_unpack_extension_callback(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_unpack_extension_callback unpack_extension_callback) {
|
|
||||||
cbs->unpack_extension_callback = unpack_extension_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) {
|
|
||||||
cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_session_callbacks_set_error_callback(
|
|
||||||
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
|
|
||||||
cbs->error_callback = error_callback;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -91,14 +91,6 @@ struct nghttp2_session_callbacks {
|
|||||||
* received.
|
* received.
|
||||||
*/
|
*/
|
||||||
nghttp2_on_header_callback on_header_callback;
|
nghttp2_on_header_callback on_header_callback;
|
||||||
nghttp2_on_header_callback2 on_header_callback2;
|
|
||||||
/**
|
|
||||||
* Callback function invoked when a invalid header name/value pair
|
|
||||||
* is received which is silently ignored if these callbacks are not
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
nghttp2_on_invalid_header_callback on_invalid_header_callback;
|
|
||||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
|
|
||||||
/**
|
/**
|
||||||
* Callback function invoked when the library asks application how
|
* Callback function invoked when the library asks application how
|
||||||
* many padding bytes are required for the transmission of the given
|
* many padding bytes are required for the transmission of the given
|
||||||
@@ -115,10 +107,6 @@ struct nghttp2_session_callbacks {
|
|||||||
*/
|
*/
|
||||||
nghttp2_on_begin_frame_callback on_begin_frame_callback;
|
nghttp2_on_begin_frame_callback on_begin_frame_callback;
|
||||||
nghttp2_send_data_callback send_data_callback;
|
nghttp2_send_data_callback send_data_callback;
|
||||||
nghttp2_pack_extension_callback pack_extension_callback;
|
|
||||||
nghttp2_unpack_extension_callback unpack_extension_callback;
|
|
||||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
|
||||||
nghttp2_error_callback error_callback;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NGHTTP2_CALLBACKS_H */
|
#endif /* NGHTTP2_CALLBACKS_H */
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* nghttp2 - HTTP/2 C Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "nghttp2_debug.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
|
|
||||||
static void nghttp2_default_debug_vfprintf_callback(const char *fmt,
|
|
||||||
va_list args) {
|
|
||||||
vfprintf(stderr, fmt, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static nghttp2_debug_vprintf_callback static_debug_vprintf_callback =
|
|
||||||
nghttp2_default_debug_vfprintf_callback;
|
|
||||||
|
|
||||||
void nghttp2_debug_vprintf(const char *format, ...) {
|
|
||||||
if (static_debug_vprintf_callback) {
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
static_debug_vprintf_callback(format, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_set_debug_vprintf_callback(
|
|
||||||
nghttp2_debug_vprintf_callback debug_vprintf_callback) {
|
|
||||||
static_debug_vprintf_callback = debug_vprintf_callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !DEBUGBUILD */
|
|
||||||
|
|
||||||
void nghttp2_set_debug_vprintf_callback(
|
|
||||||
nghttp2_debug_vprintf_callback debug_vprintf_callback _U_) {}
|
|
||||||
|
|
||||||
#endif /* !DEBUGBUILD */
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* nghttp2 - HTTP/2 C Library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
* a copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be
|
|
||||||
* included in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef NGHTTP2_DEBUG_H
|
|
||||||
#define NGHTTP2_DEBUG_H
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <config.h>
|
|
||||||
#endif /* HAVE_CONFIG_H */
|
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
|
||||||
#define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
|
|
||||||
void nghttp2_debug_vprintf(const char *format, ...);
|
|
||||||
#else
|
|
||||||
#define DEBUGF(...) \
|
|
||||||
do { \
|
|
||||||
} while (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* NGHTTP2_DEBUG_H */
|
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
#include "nghttp2_helper.h"
|
#include "nghttp2_helper.h"
|
||||||
#include "nghttp2_net.h"
|
#include "nghttp2_net.h"
|
||||||
#include "nghttp2_priority_spec.h"
|
#include "nghttp2_priority_spec.h"
|
||||||
#include "nghttp2_debug.h"
|
|
||||||
|
|
||||||
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) {
|
||||||
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
|
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
|
||||||
@@ -185,39 +184,6 @@ void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
|
|||||||
|
|
||||||
void nghttp2_frame_data_free(nghttp2_data *frame _U_) {}
|
void nghttp2_frame_data_free(nghttp2_data *frame _U_) {}
|
||||||
|
|
||||||
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
|
||||||
uint8_t flags, int32_t stream_id,
|
|
||||||
void *payload) {
|
|
||||||
nghttp2_frame_hd_init(&frame->hd, 0, type, flags, stream_id);
|
|
||||||
frame->payload = payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_frame_extension_free(nghttp2_extension *frame _U_) {}
|
|
||||||
|
|
||||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
|
||||||
uint8_t *origin, size_t origin_len,
|
|
||||||
uint8_t *field_value, size_t field_value_len) {
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
|
|
||||||
nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
|
|
||||||
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
|
|
||||||
|
|
||||||
altsvc = frame->payload;
|
|
||||||
altsvc->origin = origin;
|
|
||||||
altsvc->origin_len = origin_len;
|
|
||||||
altsvc->field_value = field_value;
|
|
||||||
altsvc->field_value_len = field_value_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
|
|
||||||
altsvc = frame->payload;
|
|
||||||
/* We use the same buffer for altsvc->origin and
|
|
||||||
altsvc->field_value. */
|
|
||||||
nghttp2_mem_free(mem, altsvc->origin);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -253,7 +219,8 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
|||||||
hd = *frame_hd;
|
hd = *frame_hd;
|
||||||
hd.length = nghttp2_buf_len(buf);
|
hd.length = nghttp2_buf_len(buf);
|
||||||
|
|
||||||
DEBUGF("send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n", hd.length);
|
DEBUGF(fprintf(stderr, "send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n",
|
||||||
|
hd.length));
|
||||||
|
|
||||||
/* We have multiple frame buffers, which means one or more
|
/* We have multiple frame buffers, which means one or more
|
||||||
CONTINUATION frame is involved. Remove END_HEADERS flag from the
|
CONTINUATION frame is involved. Remove END_HEADERS flag from the
|
||||||
@@ -278,7 +245,8 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
|||||||
|
|
||||||
hd.length = nghttp2_buf_len(buf);
|
hd.length = nghttp2_buf_len(buf);
|
||||||
|
|
||||||
DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length);
|
DEBUGF(fprintf(stderr, "send: int CONTINUATION, payloadlen=%zu\n",
|
||||||
|
hd.length));
|
||||||
|
|
||||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||||
@@ -289,7 +257,8 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
|||||||
/* Set END_HEADERS flag for last CONTINUATION */
|
/* Set END_HEADERS flag for last CONTINUATION */
|
||||||
hd.flags = NGHTTP2_FLAG_END_HEADERS;
|
hd.flags = NGHTTP2_FLAG_END_HEADERS;
|
||||||
|
|
||||||
DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length);
|
DEBUGF(fprintf(stderr, "send: last CONTINUATION, payloadlen=%zu\n",
|
||||||
|
hd.length));
|
||||||
|
|
||||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||||
@@ -461,11 +430,25 @@ size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
|
|||||||
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
|
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||||
nghttp2_settings_entry *iv,
|
nghttp2_settings_entry *iv,
|
||||||
size_t niv) {
|
size_t niv, nghttp2_mem *mem) {
|
||||||
frame->iv = iv;
|
size_t payloadlen = niv * sizeof(nghttp2_settings_entry);
|
||||||
|
|
||||||
|
if (niv == 0) {
|
||||||
|
frame->iv = NULL;
|
||||||
|
} else {
|
||||||
|
frame->iv = nghttp2_mem_malloc(mem, payloadlen);
|
||||||
|
|
||||||
|
if (frame->iv == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(frame->iv, iv, payloadlen);
|
||||||
|
}
|
||||||
|
|
||||||
frame->niv = niv;
|
frame->niv = niv;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
||||||
@@ -676,79 +659,6 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
|||||||
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
|
|
||||||
int rv;
|
|
||||||
nghttp2_buf *buf;
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
|
|
||||||
altsvc = frame->payload;
|
|
||||||
|
|
||||||
buf = &bufs->head->buf;
|
|
||||||
|
|
||||||
assert(nghttp2_buf_avail(buf) >=
|
|
||||||
2 + altsvc->origin_len + altsvc->field_value_len);
|
|
||||||
|
|
||||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
|
||||||
|
|
||||||
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
|
|
||||||
|
|
||||||
nghttp2_put_uint16be(buf->last, (uint16_t)altsvc->origin_len);
|
|
||||||
buf->last += 2;
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
|
|
||||||
|
|
||||||
assert(rv == 0);
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
|
|
||||||
|
|
||||||
assert(rv == 0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
|
||||||
size_t origin_len, uint8_t *payload,
|
|
||||||
size_t payloadlen) {
|
|
||||||
nghttp2_ext_altsvc *altsvc;
|
|
||||||
uint8_t *p;
|
|
||||||
|
|
||||||
altsvc = frame->payload;
|
|
||||||
p = payload;
|
|
||||||
|
|
||||||
altsvc->origin = p;
|
|
||||||
|
|
||||||
p += origin_len;
|
|
||||||
|
|
||||||
altsvc->origin_len = origin_len;
|
|
||||||
|
|
||||||
altsvc->field_value = p;
|
|
||||||
altsvc->field_value_len = (size_t)(payload + payloadlen - p);
|
|
||||||
}
|
|
||||||
|
|
||||||
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
|
|
||||||
const uint8_t *payload,
|
|
||||||
size_t payloadlen, nghttp2_mem *mem) {
|
|
||||||
uint8_t *buf;
|
|
||||||
size_t origin_len;
|
|
||||||
|
|
||||||
if (payloadlen < 2) {
|
|
||||||
return NGHTTP2_FRAME_SIZE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
origin_len = nghttp2_get_uint16(payload);
|
|
||||||
|
|
||||||
buf = nghttp2_mem_malloc(mem, payloadlen - 2);
|
|
||||||
if (!buf) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_cpymem(buf, payload + 2, payloadlen - 2);
|
|
||||||
|
|
||||||
nghttp2_frame_unpack_altsvc_payload(frame, origin_len, buf, payloadlen - 2);
|
|
||||||
|
|
||||||
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;
|
||||||
@@ -869,9 +779,7 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
|||||||
p->name = nva[i].name;
|
p->name = nva[i].name;
|
||||||
p->namelen = nva[i].namelen;
|
p->namelen = nva[i].namelen;
|
||||||
} else {
|
} else {
|
||||||
if (nva[i].namelen) {
|
|
||||||
memcpy(data, nva[i].name, nva[i].namelen);
|
memcpy(data, nva[i].name, nva[i].namelen);
|
||||||
}
|
|
||||||
p->name = data;
|
p->name = data;
|
||||||
p->namelen = nva[i].namelen;
|
p->namelen = nva[i].namelen;
|
||||||
data[p->namelen] = '\0';
|
data[p->namelen] = '\0';
|
||||||
@@ -883,9 +791,7 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
|||||||
p->value = nva[i].value;
|
p->value = nva[i].value;
|
||||||
p->valuelen = nva[i].valuelen;
|
p->valuelen = nva[i].valuelen;
|
||||||
} else {
|
} else {
|
||||||
if (nva[i].valuelen) {
|
|
||||||
memcpy(data, nva[i].value, nva[i].valuelen);
|
memcpy(data, nva[i].value, nva[i].valuelen);
|
||||||
}
|
|
||||||
p->value = data;
|
p->value = data;
|
||||||
p->valuelen = nva[i].valuelen;
|
p->valuelen = nva[i].valuelen;
|
||||||
data[p->valuelen] = '\0';
|
data[p->valuelen] = '\0';
|
||||||
@@ -932,7 +838,7 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
|
|||||||
size_t trail_padlen;
|
size_t trail_padlen;
|
||||||
size_t newlen;
|
size_t newlen;
|
||||||
|
|
||||||
DEBUGF("send: padlen=%zu, shift left 1 bytes\n", padlen);
|
DEBUGF(fprintf(stderr, "send: padlen=%zu, shift left 1 bytes\n", padlen));
|
||||||
|
|
||||||
memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
|
memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
|
||||||
|
|
||||||
@@ -962,7 +868,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|||||||
nghttp2_buf *buf;
|
nghttp2_buf *buf;
|
||||||
|
|
||||||
if (padlen == 0) {
|
if (padlen == 0) {
|
||||||
DEBUGF("send: padlen = 0, nothing to do\n");
|
DEBUGF(fprintf(stderr, "send: padlen = 0, nothing to do\n"));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -996,7 +902,8 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|||||||
hd->length += padlen;
|
hd->length += padlen;
|
||||||
hd->flags |= NGHTTP2_FLAG_PADDED;
|
hd->flags |= NGHTTP2_FLAG_PADDED;
|
||||||
|
|
||||||
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
|
DEBUGF(fprintf(stderr, "send: final payloadlen=%zu, padlen=%zu\n", hd->length,
|
||||||
|
padlen));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,12 +52,14 @@
|
|||||||
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
||||||
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
||||||
|
|
||||||
|
/* Number of inbound buffer */
|
||||||
|
#define NGHTTP2_FRAMEBUF_MAX_NUM 5
|
||||||
|
|
||||||
/* The default length of DATA frame payload. */
|
/* The default length of DATA frame payload. */
|
||||||
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
||||||
|
|
||||||
/* Maximum headers block size to send, calculated using
|
/* Maximum headers payload length, calculated in compressed form.
|
||||||
nghttp2_hd_deflate_bound(). This is the default value, and can be
|
This applies to transmission only. */
|
||||||
overridden by nghttp2_option_set_max_send_header_block_size(). */
|
|
||||||
#define NGHTTP2_MAX_HEADERSLEN 65536
|
#define NGHTTP2_MAX_HEADERSLEN 65536
|
||||||
|
|
||||||
/* The number of bytes for each SETTINGS entry */
|
/* The number of bytes for each SETTINGS entry */
|
||||||
@@ -70,7 +72,7 @@
|
|||||||
#define NGHTTP2_MAX_PADLEN 256
|
#define NGHTTP2_MAX_PADLEN 256
|
||||||
|
|
||||||
/* Union of extension frame payload */
|
/* Union of extension frame payload */
|
||||||
typedef union { nghttp2_ext_altsvc altsvc; } nghttp2_ext_frame_payload;
|
typedef union { int dummy; } 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);
|
||||||
|
|
||||||
@@ -213,12 +215,18 @@ void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
|||||||
const uint8_t *payload);
|
const uint8_t *payload);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes payload of frame->settings. The |frame| takes
|
* Makes a copy of |iv| in frame->settings.iv. The |niv| is assigned
|
||||||
* ownership of |iv|.
|
* to frame->settings.niv.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||||
nghttp2_settings_entry *iv,
|
nghttp2_settings_entry *iv,
|
||||||
size_t niv);
|
size_t niv, nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
|
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
|
||||||
@@ -359,45 +367,6 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
|||||||
const uint8_t *payload,
|
const uint8_t *payload,
|
||||||
size_t payloadlen);
|
size_t payloadlen);
|
||||||
|
|
||||||
/*
|
|
||||||
* Packs ALTSVC 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 always succeeds and returns 0.
|
|
||||||
*/
|
|
||||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unpacks ALTSVC wire format into |frame|. The |payload| of
|
|
||||||
* |payloadlen| bytes contains frame payload. This function assumes
|
|
||||||
* that frame->payload points to the nghttp2_ext_altsvc object.
|
|
||||||
*
|
|
||||||
* This function always succeeds and returns 0.
|
|
||||||
*/
|
|
||||||
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
|
||||||
size_t origin_len, uint8_t *payload,
|
|
||||||
size_t payloadlen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Unpacks ALTSVC wire format into |frame|. This function only exists
|
|
||||||
* for unit test. After allocating buffer for fields, this function
|
|
||||||
* internally calls nghttp2_frame_unpack_altsvc_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_altsvc_payload2(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
|
||||||
@@ -470,31 +439,6 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
|
|||||||
|
|
||||||
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
||||||
|
|
||||||
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
|
||||||
uint8_t flags, int32_t stream_id,
|
|
||||||
void *payload);
|
|
||||||
|
|
||||||
void nghttp2_frame_extension_free(nghttp2_extension *frame);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initializes ALTSVC frame |frame| with given values. This function
|
|
||||||
* assumes that frame->payload points to nghttp2_ext_altsvc object.
|
|
||||||
* Also |origin| and |field_value| are allocated in single buffer,
|
|
||||||
* starting |origin|. On success, this function takes ownership of
|
|
||||||
* |origin|, so caller must not free it.
|
|
||||||
*/
|
|
||||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
|
||||||
uint8_t *origin, size_t origin_len,
|
|
||||||
uint8_t *field_value, size_t field_value_len);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Frees up resources under |frame|. This function does not free
|
|
||||||
* nghttp2_ext_altsvc object pointed by frame->payload. This function
|
|
||||||
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
|
|
||||||
* other fields must be allocated in the same buffer with origin.
|
|
||||||
*/
|
|
||||||
void nghttp2_frame_altsvc_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
|
||||||
|
|||||||
1125
lib/nghttp2_hd.c
1125
lib/nghttp2_hd.c
File diff suppressed because it is too large
Load Diff
134
lib/nghttp2_hd.h
134
lib/nghttp2_hd.h
@@ -34,7 +34,6 @@
|
|||||||
#include "nghttp2_hd_huffman.h"
|
#include "nghttp2_hd_huffman.h"
|
||||||
#include "nghttp2_buf.h"
|
#include "nghttp2_buf.h"
|
||||||
#include "nghttp2_mem.h"
|
#include "nghttp2_mem.h"
|
||||||
#include "nghttp2_rcbuf.h"
|
|
||||||
|
|
||||||
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
||||||
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
||||||
@@ -110,32 +109,28 @@ typedef enum {
|
|||||||
NGHTTP2_TOKEN_CONNECTION,
|
NGHTTP2_TOKEN_CONNECTION,
|
||||||
NGHTTP2_TOKEN_KEEP_ALIVE,
|
NGHTTP2_TOKEN_KEEP_ALIVE,
|
||||||
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
||||||
NGHTTP2_TOKEN_UPGRADE,
|
NGHTTP2_TOKEN_UPGRADE
|
||||||
} nghttp2_token;
|
} nghttp2_token;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NGHTTP2_HD_FLAG_NONE = 0,
|
||||||
|
/* Indicates name was dynamically allocated and must be freed */
|
||||||
|
NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
|
||||||
|
/* Indicates value was dynamically allocated and must be freed */
|
||||||
|
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
|
||||||
|
/* Indicates that the name was gifted to the entry and no copying
|
||||||
|
necessary. */
|
||||||
|
NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 2,
|
||||||
|
/* Indicates that the value was gifted to the entry and no copying
|
||||||
|
necessary. */
|
||||||
|
NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 3
|
||||||
|
} nghttp2_hd_flags;
|
||||||
|
|
||||||
struct nghttp2_hd_entry;
|
struct nghttp2_hd_entry;
|
||||||
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
|
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* The buffer containing header field name. NULL-termination is
|
|
||||||
guaranteed. */
|
|
||||||
nghttp2_rcbuf *name;
|
|
||||||
/* The buffer containing header field value. NULL-termination is
|
|
||||||
guaranteed. */
|
|
||||||
nghttp2_rcbuf *value;
|
|
||||||
/* nghttp2_token value for name. It could be -1 if we have no token
|
|
||||||
for that header field name. */
|
|
||||||
int32_t token;
|
|
||||||
/* Bitwise OR of one or more of nghttp2_nv_flag. */
|
|
||||||
uint8_t flags;
|
|
||||||
} nghttp2_hd_nv;
|
|
||||||
|
|
||||||
struct nghttp2_hd_entry {
|
struct nghttp2_hd_entry {
|
||||||
/* The header field name/value pair */
|
nghttp2_nv nv;
|
||||||
nghttp2_hd_nv nv;
|
|
||||||
/* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
|
|
||||||
APIs to keep backward compatibility. */
|
|
||||||
nghttp2_nv cnv;
|
|
||||||
/* The next entry which shares same bucket in hash table. */
|
/* The next entry which shares same bucket in hash table. */
|
||||||
nghttp2_hd_entry *next;
|
nghttp2_hd_entry *next;
|
||||||
/* The sequence number. We will increment it by one whenever we
|
/* The sequence number. We will increment it by one whenever we
|
||||||
@@ -143,17 +138,14 @@ struct nghttp2_hd_entry {
|
|||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
/* The hash value for header name (nv.name). */
|
/* The hash value for header name (nv.name). */
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
|
/* nghttp2_token value for nv.name. It could be -1 if we have no
|
||||||
|
token for that header field name. */
|
||||||
|
int token;
|
||||||
|
/* Reference count */
|
||||||
|
uint8_t ref;
|
||||||
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The entry used for static header table. */
|
|
||||||
typedef struct {
|
|
||||||
nghttp2_rcbuf name;
|
|
||||||
nghttp2_rcbuf value;
|
|
||||||
nghttp2_nv cnv;
|
|
||||||
int32_t token;
|
|
||||||
uint32_t hash;
|
|
||||||
} nghttp2_hd_static_entry;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
nghttp2_hd_entry **buffer;
|
nghttp2_hd_entry **buffer;
|
||||||
size_t mask;
|
size_t mask;
|
||||||
@@ -227,18 +219,24 @@ struct nghttp2_hd_deflater {
|
|||||||
|
|
||||||
struct nghttp2_hd_inflater {
|
struct nghttp2_hd_inflater {
|
||||||
nghttp2_hd_context ctx;
|
nghttp2_hd_context ctx;
|
||||||
|
/* header buffer */
|
||||||
|
nghttp2_bufs nvbufs;
|
||||||
/* Stores current state of huffman decoding */
|
/* Stores current state of huffman decoding */
|
||||||
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
||||||
/* header buffer */
|
/* Pointer to the nghttp2_hd_entry which is used current header
|
||||||
nghttp2_buf namebuf, valuebuf;
|
emission. This is required because in some cases the
|
||||||
nghttp2_rcbuf *namercbuf, *valuercbuf;
|
ent_keep->ref == 0 and we have to keep track of it. */
|
||||||
/* Pointer to the name/value pair which are used in the current
|
nghttp2_hd_entry *ent_keep;
|
||||||
header emission. */
|
/* Pointer to the name/value pair buffer which is used in the
|
||||||
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
|
current header emission. */
|
||||||
|
uint8_t *nv_keep;
|
||||||
/* The number of bytes to read */
|
/* The number of bytes to read */
|
||||||
size_t left;
|
size_t left;
|
||||||
/* The index in indexed repr or indexed name */
|
/* The index in indexed repr or indexed name */
|
||||||
size_t index;
|
size_t index;
|
||||||
|
/* The length of new name encoded in literal. For huffman encoded
|
||||||
|
string, this is the length after it is decoded. */
|
||||||
|
size_t newnamelen;
|
||||||
/* The maximum header table size the inflater supports. This is the
|
/* The maximum header table size the inflater supports. This is the
|
||||||
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
||||||
size_t settings_hd_table_bufsize_max;
|
size_t settings_hd_table_bufsize_max;
|
||||||
@@ -258,16 +256,24 @@ struct nghttp2_hd_inflater {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes the |ent| members. The reference counts of nv->name
|
* Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
|
||||||
* and nv->value are increased by one for each.
|
* set in the |flags|, the content pointed by the |name| with length
|
||||||
|
* |namelen| is copied. Likewise, if NGHTTP2_HD_FLAG_VALUE_ALLOC bit
|
||||||
|
* set in the |flags|, the content pointed by the |value| with length
|
||||||
|
* |valuelen| is copied. The |token| is enum number looked up by
|
||||||
|
* |name|. It could be -1 if we don't have that enum value.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
|
int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags, uint8_t *name,
|
||||||
|
size_t namelen, uint8_t *value, size_t valuelen,
|
||||||
|
int token, nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent, nghttp2_mem *mem);
|
||||||
* This function decreases the reference counts of nv->name and
|
|
||||||
* nv->value.
|
|
||||||
*/
|
|
||||||
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes |deflater| for deflating name/values pairs.
|
* Initializes |deflater| for deflating name/values pairs.
|
||||||
@@ -288,7 +294,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
|||||||
/*
|
/*
|
||||||
* Initializes |deflater| for deflating name/values pairs.
|
* Initializes |deflater| for deflating name/values pairs.
|
||||||
*
|
*
|
||||||
* The encoder only uses up to |max_deflate_dynamic_table_size| bytes
|
* The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
|
||||||
* for header table even if the larger value is specified later in
|
* for header table even if the larger value is specified later in
|
||||||
* nghttp2_hd_change_table_size().
|
* nghttp2_hd_change_table_size().
|
||||||
*
|
*
|
||||||
@@ -299,7 +305,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
|||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
size_t max_deflate_dynamic_table_size,
|
size_t deflate_hd_table_bufsize_max,
|
||||||
nghttp2_mem *mem);
|
nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -348,14 +354,16 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
|
|||||||
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
|
* Similar to nghttp2_hd_inflate_hd(), but this takes additional
|
||||||
* instead of nghttp2_nv as output parameter |nv_out|. Other than
|
* output parameter |token|. On successful header emission, it
|
||||||
* that return values and semantics are the same as
|
* contains nghttp2_token value for nv_out->name. It could be -1 if
|
||||||
* nghttp2_hd_inflate_hd().
|
* we don't have enum value for the name. Other than that return
|
||||||
|
* values and semantics are the same as nghttp2_hd_inflate_hd().
|
||||||
*/
|
*/
|
||||||
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
|
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
||||||
nghttp2_hd_nv *nv_out, int *inflate_flags,
|
nghttp2_nv *nv_out, int *inflate_flags,
|
||||||
const uint8_t *in, size_t inlen, int in_final);
|
int *token, uint8_t *in, size_t inlen,
|
||||||
|
int in_final);
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
@@ -369,10 +377,11 @@ int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
|||||||
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
nghttp2_hd_entry *nghttp2_hd_table_get(nghttp2_hd_context *context,
|
||||||
|
size_t index);
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
|
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
|
||||||
uint32_t initial, size_t shift, uint8_t *in,
|
uint32_t initial, size_t shift, uint8_t *in,
|
||||||
uint8_t *last, size_t prefix);
|
uint8_t *last, size_t prefix);
|
||||||
|
|
||||||
@@ -407,11 +416,12 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
|||||||
/*
|
/*
|
||||||
* Decodes the given data |src| with length |srclen|. The |ctx| must
|
* Decodes the given data |src| with length |srclen|. The |ctx| must
|
||||||
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
|
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
|
||||||
* will be written to |buf|. This function assumes that |buf| has the
|
* will be added to |dest|. This function may expand |dest| as
|
||||||
* enough room to store the decoded byte string.
|
* needed. The caller is responsible to release the memory of |dest|
|
||||||
|
* by calling nghttp2_bufs_free().
|
||||||
*
|
*
|
||||||
* The caller must set the |fin| to nonzero if the given input is the
|
* The caller must set the |final| to nonzero if the given input is
|
||||||
* final block.
|
* the final block.
|
||||||
*
|
*
|
||||||
* This function returns the number of read bytes from the |in|.
|
* This function returns the number of read bytes from the |in|.
|
||||||
*
|
*
|
||||||
@@ -420,11 +430,13 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
|||||||
*
|
*
|
||||||
* NGHTTP2_ERR_NOMEM
|
* NGHTTP2_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
|
* NGHTTP2_ERR_BUFFER_ERROR
|
||||||
|
* Maximum buffer capacity size exceeded.
|
||||||
* NGHTTP2_ERR_HEADER_COMP
|
* NGHTTP2_ERR_HEADER_COMP
|
||||||
* Decoding process has failed.
|
* Decoding process has failed.
|
||||||
*/
|
*/
|
||||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||||
nghttp2_buf *buf, const uint8_t *src,
|
nghttp2_bufs *bufs, const uint8_t *src,
|
||||||
size_t srclen, int fin);
|
size_t srclen, int final);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_H */
|
#endif /* NGHTTP2_HD_H */
|
||||||
|
|||||||
@@ -64,44 +64,15 @@ static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr,
|
|||||||
code <<= 8 - (nbits & 0x7);
|
code <<= 8 - (nbits & 0x7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we lose at most 3 bytes, but it is not critical in practice */
|
||||||
if (*avail_ptr < (nbits + 7) / 8) {
|
if (*avail_ptr < (nbits + 7) / 8) {
|
||||||
/* slow path */
|
rv = nghttp2_bufs_advance(bufs);
|
||||||
if (nbits > 24) {
|
|
||||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 24));
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
nbits -= 8;
|
|
||||||
}
|
|
||||||
if (nbits > 16) {
|
|
||||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 16));
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
nbits -= 8;
|
|
||||||
}
|
|
||||||
if (nbits > 8) {
|
|
||||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 8));
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
nbits -= 8;
|
|
||||||
}
|
|
||||||
if (nbits == 8) {
|
|
||||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)code);
|
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
||||||
return 8;
|
/* we assume that we at least 3 buffer space available */
|
||||||
}
|
assert(*avail_ptr >= 3);
|
||||||
|
|
||||||
rv = nghttp2_bufs_addb_hold(bufs, (uint8_t)code);
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
|
||||||
return (ssize_t)(8 - nbits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fast path, since most code is less than 8 */
|
/* fast path, since most code is less than 8 */
|
||||||
@@ -195,30 +166,47 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
|
|||||||
ctx->accept = 1;
|
ctx->accept = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use macro to make the code simpler..., but error case is tricky.
|
||||||
|
We spent most of the CPU in decoding, so we are doing this
|
||||||
|
thing. */
|
||||||
|
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
|
||||||
|
do { \
|
||||||
|
if ((avail)) { \
|
||||||
|
nghttp2_bufs_fast_addb((bufs), (sym)); \
|
||||||
|
--(avail); \
|
||||||
|
} else { \
|
||||||
|
rv = nghttp2_bufs_addb((bufs), (sym)); \
|
||||||
|
if (rv != 0) { \
|
||||||
|
return rv; \
|
||||||
|
} \
|
||||||
|
(avail) = nghttp2_bufs_cur_avail((bufs)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||||
nghttp2_buf *buf, const uint8_t *src,
|
nghttp2_bufs *bufs, const uint8_t *src,
|
||||||
size_t srclen, int final) {
|
size_t srclen, int final) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int rv;
|
||||||
|
size_t avail;
|
||||||
|
|
||||||
|
avail = nghttp2_bufs_cur_avail(bufs);
|
||||||
|
|
||||||
/* We use the decoding algorithm described in
|
/* We use the decoding algorithm described in
|
||||||
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
||||||
for (i = 0; i < srclen; ++i) {
|
for (i = 0; i < srclen; ++i) {
|
||||||
const nghttp2_huff_decode *t;
|
const nghttp2_huff_decode *t;
|
||||||
|
|
||||||
t = &huff_decode_table[ctx->state][src[i] >> 4];
|
t = &huff_decode_table[ctx->state][src[i]];
|
||||||
if (t->flags & NGHTTP2_HUFF_FAIL) {
|
if (t->flags & NGHTTP2_HUFF_FAIL) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
if (t->flags & NGHTTP2_HUFF_SYM1) {
|
||||||
*buf->last++ = t->sym;
|
/* this is macro, and may return from this function on error */
|
||||||
|
hd_huff_decode_sym_emit(bufs, t->sym[0], avail);
|
||||||
|
if (t->flags & NGHTTP2_HUFF_SYM2) {
|
||||||
|
hd_huff_decode_sym_emit(bufs, t->sym[1], avail);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = &huff_decode_table[t->state][src[i] & 0xf];
|
|
||||||
if (t->flags & NGHTTP2_HUFF_FAIL) {
|
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
|
||||||
}
|
|
||||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
|
||||||
*buf->last++ = t->sym;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->state = t->state;
|
ctx->state = t->state;
|
||||||
|
|||||||
@@ -35,10 +35,12 @@ typedef enum {
|
|||||||
/* FSA accepts this state as the end of huffman encoding
|
/* FSA accepts this state as the end of huffman encoding
|
||||||
sequence. */
|
sequence. */
|
||||||
NGHTTP2_HUFF_ACCEPTED = 1,
|
NGHTTP2_HUFF_ACCEPTED = 1,
|
||||||
/* This state emits symbol */
|
/* This state emits 1st symbol */
|
||||||
NGHTTP2_HUFF_SYM = (1 << 1),
|
NGHTTP2_HUFF_SYM1 = (1 << 1),
|
||||||
|
/* This state emits 2nd symbol */
|
||||||
|
NGHTTP2_HUFF_SYM2 = (1 << 2),
|
||||||
/* If state machine reaches this state, decoding fails. */
|
/* If state machine reaches this state, decoding fails. */
|
||||||
NGHTTP2_HUFF_FAIL = (1 << 2)
|
NGHTTP2_HUFF_FAIL = (1 << 3)
|
||||||
} nghttp2_huff_decode_flag;
|
} nghttp2_huff_decode_flag;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -49,11 +51,15 @@ typedef struct {
|
|||||||
uint8_t state;
|
uint8_t state;
|
||||||
/* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
|
/* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
/* symbol if NGHTTP2_HUFF_SYM flag set */
|
/* symbols if NGHTTP2_HUFF_SYM1 and optionally NGHTTP2_HUFF_SYM2
|
||||||
uint8_t sym;
|
flag set. If NGHTTP2_HUFF_SYM1 is set, sym[0] has the 1st
|
||||||
|
symbol. Additionally, NGHTTP2_HUFF_SYM2 is set, sym[1] has the
|
||||||
|
2nd symbol. Since maximum huffman code is 5 bits, we may get at
|
||||||
|
most 2 symbols in one transition. */
|
||||||
|
uint8_t sym[2];
|
||||||
} nghttp2_huff_decode;
|
} nghttp2_huff_decode;
|
||||||
|
|
||||||
typedef nghttp2_huff_decode huff_decode_table_type[16];
|
typedef nghttp2_huff_decode huff_decode_table_type[256];
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Current huffman decoding state. We stripped leaf nodes, so the
|
/* Current huffman decoding state. We stripped leaf nodes, so the
|
||||||
@@ -72,6 +78,6 @@ typedef struct {
|
|||||||
} nghttp2_huff_sym;
|
} nghttp2_huff_sym;
|
||||||
|
|
||||||
extern const nghttp2_huff_sym huff_sym_table[];
|
extern const nghttp2_huff_sym huff_sym_table[];
|
||||||
extern const nghttp2_huff_decode huff_decode_table[][16];
|
extern const nghttp2_huff_decode huff_decode_table[][256];
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_HUFFMAN_H */
|
#endif /* NGHTTP2_HD_HUFFMAN_H */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -189,8 +189,8 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
|||||||
account it in *delta_ptr. */
|
account it in *delta_ptr. */
|
||||||
*recv_window_size_ptr = recv_reduction_delta;
|
*recv_window_size_ptr = recv_reduction_delta;
|
||||||
}
|
}
|
||||||
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
/* recv_reduction_delta must be paied from *delta_ptr, since it
|
||||||
added in window size reduction (see below). */
|
was added in window size reduction (see below). */
|
||||||
*delta_ptr -= recv_reduction_delta;
|
*delta_ptr -= recv_reduction_delta;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -213,38 +213,6 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
|
||||||
int32_t *recv_window_size_ptr,
|
|
||||||
int32_t *recv_reduction_ptr,
|
|
||||||
int32_t *delta_ptr) {
|
|
||||||
int32_t recv_reduction_delta;
|
|
||||||
int32_t delta;
|
|
||||||
|
|
||||||
delta = *delta_ptr;
|
|
||||||
|
|
||||||
assert(delta >= 0);
|
|
||||||
|
|
||||||
/* The delta size is strictly more than received bytes. Increase
|
|
||||||
local_window_size by that difference |delta|. */
|
|
||||||
if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
|
|
||||||
return NGHTTP2_ERR_FLOW_CONTROL;
|
|
||||||
}
|
|
||||||
|
|
||||||
*local_window_size_ptr += delta;
|
|
||||||
/* If there is recv_reduction due to earlier window_size
|
|
||||||
reduction, we have to adjust it too. */
|
|
||||||
recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
|
|
||||||
*recv_reduction_ptr -= recv_reduction_delta;
|
|
||||||
|
|
||||||
*recv_window_size_ptr += recv_reduction_delta;
|
|
||||||
|
|
||||||
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
|
||||||
added in window size reduction (see below). */
|
|
||||||
*delta_ptr -= recv_reduction_delta;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nghttp2_should_send_window_update(int32_t local_window_size,
|
int nghttp2_should_send_window_update(int32_t local_window_size,
|
||||||
int32_t recv_window_size) {
|
int32_t recv_window_size) {
|
||||||
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
|
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
|
||||||
@@ -320,8 +288,6 @@ const char *nghttp2_strerror(int error_code) {
|
|||||||
return "Stream was refused";
|
return "Stream was refused";
|
||||||
case NGHTTP2_ERR_INTERNAL:
|
case NGHTTP2_ERR_INTERNAL:
|
||||||
return "Internal error";
|
return "Internal error";
|
||||||
case NGHTTP2_ERR_CANCEL:
|
|
||||||
return "Cancel";
|
|
||||||
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:
|
||||||
@@ -338,70 +304,58 @@ const char *nghttp2_strerror(int error_code) {
|
|||||||
|
|
||||||
/* Generated by gennmchartbl.py */
|
/* Generated by gennmchartbl.py */
|
||||||
static 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 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
|
||||||
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
|
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
||||||
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
||||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
||||||
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
|
||||||
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||||
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
|
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */,
|
||||||
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
|
||||||
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
|
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
||||||
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
|
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
|
||||||
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
|
||||||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
|
||||||
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
|
0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
|
||||||
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
|
0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
||||||
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
|
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
|
||||||
0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
|
0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
|
||||||
0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
|
0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */,
|
||||||
0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||||
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
|
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
||||||
0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
|
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
||||||
0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
|
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
||||||
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
|
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||||
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */,
|
||||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
|
||||||
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
|
||||||
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||||
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
|
||||||
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
|
||||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
|
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
|
||||||
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
|
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||||
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
|
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
|
||||||
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
|
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
|
||||||
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
|
||||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
|
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||||
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
|
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
|
||||||
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
|
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
|
||||||
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
|
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
|
||||||
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
|
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
|
||||||
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
|
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
|
||||||
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
|
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
|
||||||
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
|
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
||||||
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
|
||||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
|
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
|
||||||
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
|
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
|
||||||
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
|
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
||||||
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
|
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
|
||||||
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
|
||||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
|
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
|
||||||
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
|
0 /* 0xff */
|
||||||
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
|
|
||||||
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
|
|
||||||
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
|
||||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
|
|
||||||
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
|
|
||||||
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
|
|
||||||
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
|
|
||||||
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
|
||||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
|
|
||||||
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
|
|
||||||
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
|
|
||||||
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
||||||
@@ -426,70 +380,58 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
|||||||
|
|
||||||
/* Generated by genvchartbl.py */
|
/* Generated by genvchartbl.py */
|
||||||
static 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 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 1 /* HT */,
|
||||||
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
|
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
||||||
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
||||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
||||||
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 1 /* " */,
|
||||||
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||||
1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
|
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
|
||||||
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
|
||||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
|
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
||||||
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
|
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||||
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */,
|
||||||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
|
||||||
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
|
||||||
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
|
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||||
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
|
||||||
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
|
||||||
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
1 /* Z */, 1 /* [ */, 1 /* \ */, 1 /* ] */, 1 /* ^ */,
|
||||||
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
|
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
||||||
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
|
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
||||||
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
|
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
||||||
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
|
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||||
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */,
|
||||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
1 /* } */, 1 /* ~ */, 0 /* DEL */, 1 /* 0x80 */, 1 /* 0x81 */,
|
||||||
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
1 /* 0x82 */, 1 /* 0x83 */, 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */,
|
||||||
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
1 /* 0x87 */, 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
||||||
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, 1 /* 0x90 */,
|
||||||
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, 1 /* 0x94 */, 1 /* 0x95 */,
|
||||||
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
|
1 /* 0x96 */, 1 /* 0x97 */, 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */,
|
||||||
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
|
1 /* 0x9b */, 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
||||||
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
|
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, 1 /* 0xa4 */,
|
||||||
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
|
1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, 1 /* 0xa8 */, 1 /* 0xa9 */,
|
||||||
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
1 /* 0xaa */, 1 /* 0xab */, 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */,
|
||||||
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
|
1 /* 0xaf */, 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
||||||
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
|
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, 1 /* 0xb8 */,
|
||||||
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
|
1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, 1 /* 0xbc */, 1 /* 0xbd */,
|
||||||
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
|
1 /* 0xbe */, 1 /* 0xbf */, 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */,
|
||||||
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
1 /* 0xc3 */, 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
||||||
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
|
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, 1 /* 0xcc */,
|
||||||
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
|
1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, 1 /* 0xd0 */, 1 /* 0xd1 */,
|
||||||
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
|
1 /* 0xd2 */, 1 /* 0xd3 */, 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */,
|
||||||
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
|
1 /* 0xd7 */, 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
|
||||||
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, 1 /* 0xe0 */,
|
||||||
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
|
1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, 1 /* 0xe4 */, 1 /* 0xe5 */,
|
||||||
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
|
1 /* 0xe6 */, 1 /* 0xe7 */, 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */,
|
||||||
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
|
1 /* 0xeb */, 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
|
||||||
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
|
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, 1 /* 0xf4 */,
|
||||||
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, 1 /* 0xf8 */, 1 /* 0xf9 */,
|
||||||
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
|
1 /* 0xfa */, 1 /* 0xfb */, 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */,
|
||||||
1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
|
1 /* 0xff */
|
||||||
1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
|
|
||||||
1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
|
|
||||||
1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
|
|
||||||
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
|
|
||||||
1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
|
|
||||||
1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
|
|
||||||
1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
|
|
||||||
1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
|
|
||||||
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
|
|
||||||
1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
|
|
||||||
1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
|
|
||||||
1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
||||||
@@ -503,46 +445,7 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
|
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
|
||||||
if (len == 0) {
|
|
||||||
return dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dest, src, len);
|
memcpy(dest, src, len);
|
||||||
|
|
||||||
return dest + len;
|
return dest + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *nghttp2_http2_strerror(uint32_t error_code) {
|
|
||||||
switch (error_code) {
|
|
||||||
case NGHTTP2_NO_ERROR:
|
|
||||||
return "NO_ERROR";
|
|
||||||
case NGHTTP2_PROTOCOL_ERROR:
|
|
||||||
return "PROTOCOL_ERROR";
|
|
||||||
case NGHTTP2_INTERNAL_ERROR:
|
|
||||||
return "INTERNAL_ERROR";
|
|
||||||
case NGHTTP2_FLOW_CONTROL_ERROR:
|
|
||||||
return "FLOW_CONTROL_ERROR";
|
|
||||||
case NGHTTP2_SETTINGS_TIMEOUT:
|
|
||||||
return "SETTINGS_TIMEOUT";
|
|
||||||
case NGHTTP2_STREAM_CLOSED:
|
|
||||||
return "STREAM_CLOSED";
|
|
||||||
case NGHTTP2_FRAME_SIZE_ERROR:
|
|
||||||
return "FRAME_SIZE_ERROR";
|
|
||||||
case NGHTTP2_REFUSED_STREAM:
|
|
||||||
return "REFUSED_STREAM";
|
|
||||||
case NGHTTP2_CANCEL:
|
|
||||||
return "CANCEL";
|
|
||||||
case NGHTTP2_COMPRESSION_ERROR:
|
|
||||||
return "COMPRESSION_ERROR";
|
|
||||||
case NGHTTP2_CONNECT_ERROR:
|
|
||||||
return "CONNECT_ERROR";
|
|
||||||
case NGHTTP2_ENHANCE_YOUR_CALM:
|
|
||||||
return "ENHANCE_YOUR_CALM";
|
|
||||||
case NGHTTP2_INADEQUATE_SECURITY:
|
|
||||||
return "INADEQUATE_SECURITY";
|
|
||||||
case NGHTTP2_HTTP_1_1_REQUIRED:
|
|
||||||
return "HTTP_1_1_REQUIRED";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -89,22 +89,6 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
|||||||
int32_t *recv_reduction_ptr,
|
int32_t *recv_reduction_ptr,
|
||||||
int32_t *delta_ptr);
|
int32_t *delta_ptr);
|
||||||
|
|
||||||
/*
|
|
||||||
* This function works like nghttp2_adjust_local_window_size(). The
|
|
||||||
* difference is that this function assumes *delta_ptr >= 0, and
|
|
||||||
* *recv_window_size_ptr is not decreased by *delta_ptr.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_FLOW_CONTROL
|
|
||||||
* local_window_size overflow or gets negative.
|
|
||||||
*/
|
|
||||||
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
|
||||||
int32_t *recv_window_size_ptr,
|
|
||||||
int32_t *recv_reduction_ptr,
|
|
||||||
int32_t *delta_ptr);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
||||||
* be sent.
|
* be sent.
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ static int lws(const uint8_t *s, size_t n) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
|
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_nv *nv,
|
||||||
int flag) {
|
int flag) {
|
||||||
if (stream->http_flags & flag) {
|
if (stream->http_flags & flag) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (lws(nv->value->base, nv->value->len)) {
|
if (lws(nv->value, nv->valuelen)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
stream->http_flags = (uint16_t)(stream->http_flags | flag);
|
stream->http_flags = (uint16_t)(stream->http_flags | flag);
|
||||||
@@ -112,16 +112,16 @@ static int check_path(nghttp2_stream *stream) {
|
|||||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||||
int trailer) {
|
int token, int trailer) {
|
||||||
if (nv->name->base[0] == ':') {
|
if (nv->name[0] == ':') {
|
||||||
if (trailer ||
|
if (trailer ||
|
||||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (nv->token) {
|
switch (token) {
|
||||||
case NGHTTP2_TOKEN__AUTHORITY:
|
case NGHTTP2_TOKEN__AUTHORITY:
|
||||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
@@ -131,16 +131,16 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
switch (nv->value->len) {
|
switch (nv->valuelen) {
|
||||||
case 4:
|
case 4:
|
||||||
if (lstreq("HEAD", nv->value->base, nv->value->len)) {
|
if (lstreq("HEAD", nv->value, nv->valuelen)) {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
switch (nv->value->base[6]) {
|
switch (nv->value[6]) {
|
||||||
case 'T':
|
case 'T':
|
||||||
if (lstreq("CONNECT", nv->value->base, nv->value->len)) {
|
if (lstreq("CONNECT", nv->value, nv->valuelen)) {
|
||||||
if (stream->stream_id % 2 == 0) {
|
if (stream->stream_id % 2 == 0) {
|
||||||
/* we won't allow CONNECT for push */
|
/* we won't allow CONNECT for push */
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
@@ -153,7 +153,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
if (lstreq("OPTIONS", nv->value->base, nv->value->len)) {
|
if (lstreq("OPTIONS", nv->value, nv->valuelen)) {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -168,9 +168,9 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
if (nv->value->base[0] == '/') {
|
if (nv->value[0] == '/') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
|
||||||
} else if (nv->value->len == 1 && nv->value->base[0] == '*') {
|
} else if (nv->valuelen == 1 && nv->value[0] == '*') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -181,8 +181,8 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) ||
|
if ((nv->valuelen == 4 && memieq("http", nv->value, 4)) ||
|
||||||
(nv->value->len == 5 && memieq("https", nv->value->base, 5))) {
|
(nv->valuelen == 5 && memieq("https", nv->value, 5))) {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -195,7 +195,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
if (stream->content_length != -1) {
|
if (stream->content_length != -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
stream->content_length = parse_uint(nv->value->base, nv->value->len);
|
stream->content_length = parse_uint(nv->value, nv->valuelen);
|
||||||
if (stream->content_length == -1) {
|
if (stream->content_length == -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
@@ -209,70 +209,51 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
case NGHTTP2_TOKEN_UPGRADE:
|
case NGHTTP2_TOKEN_UPGRADE:
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
case NGHTTP2_TOKEN_TE:
|
case NGHTTP2_TOKEN_TE:
|
||||||
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
|
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (nv->name->base[0] == ':') {
|
if (nv->name[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv->name->base[0] != ':') {
|
if (nv->name[0] != ':') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||||
int trailer) {
|
int token, int trailer) {
|
||||||
if (nv->name->base[0] == ':') {
|
if (nv->name[0] == ':') {
|
||||||
if (trailer ||
|
if (trailer ||
|
||||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (nv->token) {
|
switch (token) {
|
||||||
case NGHTTP2_TOKEN__STATUS: {
|
case NGHTTP2_TOKEN__STATUS: {
|
||||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
if (nv->value->len != 3) {
|
if (nv->valuelen != 3) {
|
||||||
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, nv->valuelen);
|
||||||
if (stream->status_code == -1) {
|
if (stream->status_code == -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NGHTTP2_TOKEN_CONTENT_LENGTH: {
|
case NGHTTP2_TOKEN_CONTENT_LENGTH: {
|
||||||
if (stream->status_code == 204) {
|
|
||||||
/* content-length header field in 204 response is prohibited by
|
|
||||||
RFC 7230. But some widely used servers send content-length:
|
|
||||||
0. Until they get fixed, we ignore it. */
|
|
||||||
if (stream->content_length != -1) {
|
|
||||||
/* Found multiple content-length field */
|
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
|
||||||
}
|
|
||||||
if (!lstrieq("0", nv->value->base, nv->value->len)) {
|
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
|
||||||
}
|
|
||||||
stream->content_length = 0;
|
|
||||||
return NGHTTP2_ERR_REMOVE_HTTP_HEADER;
|
|
||||||
}
|
|
||||||
if (stream->status_code / 100 == 1 ||
|
|
||||||
(stream->status_code == 200 &&
|
|
||||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT))) {
|
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
|
||||||
}
|
|
||||||
if (stream->content_length != -1) {
|
if (stream->content_length != -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
stream->content_length = parse_uint(nv->value->base, nv->value->len);
|
stream->content_length = parse_uint(nv->value, nv->valuelen);
|
||||||
if (stream->content_length == -1) {
|
if (stream->content_length == -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
@@ -286,17 +267,17 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
case NGHTTP2_TOKEN_UPGRADE:
|
case NGHTTP2_TOKEN_UPGRADE:
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
case NGHTTP2_TOKEN_TE:
|
case NGHTTP2_TOKEN_TE:
|
||||||
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
|
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (nv->name->base[0] == ':') {
|
if (nv->name[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv->name->base[0] != ':') {
|
if (nv->name[0] != ':') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,70 +286,58 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
|||||||
|
|
||||||
/* Generated by genauthroitychartbl.py */
|
/* Generated by genauthroitychartbl.py */
|
||||||
static char VALID_AUTHORITY_CHARS[] = {
|
static char VALID_AUTHORITY_CHARS[] = {
|
||||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
||||||
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
|
||||||
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
|
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
||||||
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
||||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
||||||
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
|
||||||
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
0 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||||
0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */,
|
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
|
||||||
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
|
||||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
|
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
||||||
1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
|
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||||
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 1 /* @ */,
|
||||||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
|
||||||
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
|
||||||
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
|
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||||
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
|
||||||
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
|
||||||
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 0 /* ^ */,
|
||||||
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
|
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
||||||
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
|
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
||||||
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
|
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
||||||
0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */,
|
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||||
0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
|
||||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
|
||||||
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
|
||||||
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||||
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
|
||||||
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
|
||||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
|
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
|
||||||
0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
|
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||||
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
|
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
|
||||||
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
|
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
|
||||||
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
|
||||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
|
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||||
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
|
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
|
||||||
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
|
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
|
||||||
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
|
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
|
||||||
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
|
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
|
||||||
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
|
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
|
||||||
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
|
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
|
||||||
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
|
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
||||||
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
|
||||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
|
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
|
||||||
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
|
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
|
||||||
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
|
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
||||||
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
|
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
|
||||||
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
|
||||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
|
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
|
||||||
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
|
0 /* 0xff */
|
||||||
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
|
|
||||||
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
|
|
||||||
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
|
||||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
|
|
||||||
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
|
|
||||||
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
|
|
||||||
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
|
|
||||||
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
|
||||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
|
|
||||||
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
|
|
||||||
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
|
|
||||||
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int check_authority(const uint8_t *value, size_t len) {
|
static int check_authority(const uint8_t *value, size_t len) {
|
||||||
@@ -406,7 +375,7 @@ static int check_scheme(const uint8_t *value, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||||
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
nghttp2_frame *frame, nghttp2_nv *nv, int token,
|
||||||
int trailer) {
|
int trailer) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@@ -417,14 +386,14 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|||||||
this, we may disrupt many web sites and/or libraries. So we
|
this, we may disrupt many web sites and/or libraries. So we
|
||||||
become conservative here, and just ignore those illegal regular
|
become conservative here, and just ignore those illegal regular
|
||||||
headers. */
|
headers. */
|
||||||
if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) {
|
if (!nghttp2_check_header_name(nv->name, nv->namelen)) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if (nv->name->len > 0 && nv->name->base[0] == ':') {
|
if (nv->namelen > 0 && nv->name[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
/* header field name must be lower-cased without exception */
|
/* header field name must be lower-cased without exception */
|
||||||
for (i = 0; i < nv->name->len; ++i) {
|
for (i = 0; i < nv->namelen; ++i) {
|
||||||
uint8_t c = nv->name->base[i];
|
uint8_t c = nv->name[i];
|
||||||
if ('A' <= c && c <= 'Z') {
|
if ('A' <= c && c <= 'Z') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
@@ -436,18 +405,17 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|||||||
return NGHTTP2_ERR_IGN_HTTP_HEADER;
|
return NGHTTP2_ERR_IGN_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
|
if (token == NGHTTP2_TOKEN__AUTHORITY || token == NGHTTP2_TOKEN_HOST) {
|
||||||
nv->token == NGHTTP2_TOKEN_HOST) {
|
rv = check_authority(nv->value, nv->valuelen);
|
||||||
rv = check_authority(nv->value->base, nv->value->len);
|
} else if (token == NGHTTP2_TOKEN__SCHEME) {
|
||||||
} else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
|
rv = check_scheme(nv->value, nv->valuelen);
|
||||||
rv = check_scheme(nv->value->base, nv->value->len);
|
|
||||||
} else {
|
} else {
|
||||||
rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
|
rv = nghttp2_check_header_value(nv->value, nv->valuelen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
assert(nv->name->len > 0);
|
assert(nv->namelen > 0);
|
||||||
if (nv->name->base[0] == ':') {
|
if (nv->name[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
/* When ignoring regular headers, we set this flag so that we
|
/* When ignoring regular headers, we set this flag so that we
|
||||||
@@ -458,10 +426,10 @@ 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, token, trailer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return http_response_on_header(stream, nv, trailer);
|
return http_response_on_header(stream, nv, token, trailer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_http_on_request_headers(nghttp2_stream *stream,
|
int nghttp2_http_on_request_headers(nghttp2_stream *stream,
|
||||||
|
|||||||
@@ -36,7 +36,8 @@
|
|||||||
/*
|
/*
|
||||||
* This function is called when HTTP header field |nv| in |frame| is
|
* This function is called when HTTP header field |nv| in |frame| is
|
||||||
* received for |stream|. This function will validate |nv| against
|
* received for |stream|. This function will validate |nv| against
|
||||||
* the current state of stream.
|
* the current state of stream. The |token| is nghttp2_token value
|
||||||
|
* for nv->name, or -1 if we don't have enum value for the name.
|
||||||
*
|
*
|
||||||
* 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:
|
||||||
@@ -48,7 +49,7 @@
|
|||||||
* if it was not received because of compatibility reasons.
|
* if it was not received because of compatibility reasons.
|
||||||
*/
|
*/
|
||||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||||
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
nghttp2_frame *frame, nghttp2_nv *nv, int token,
|
||||||
int trailer);
|
int trailer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -29,10 +29,16 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
|
||||||
|
|
||||||
/* Macros, types and constants for internal use */
|
/* Macros, types and constants for internal use */
|
||||||
|
|
||||||
|
#ifdef DEBUGBUILD
|
||||||
|
#define DEBUGF(x) x
|
||||||
|
#else
|
||||||
|
#define DEBUGF(x) \
|
||||||
|
do { \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
||||||
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
||||||
|
|
||||||
@@ -46,13 +52,7 @@ typedef enum {
|
|||||||
* Invalid HTTP header field was received but it can be treated as
|
* Invalid HTTP header field was received but it can be treated as
|
||||||
* if it was not received because of compatibility reasons.
|
* if it was not received because of compatibility reasons.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_ERR_IGN_HTTP_HEADER = -105,
|
NGHTTP2_ERR_IGN_HTTP_HEADER = -105
|
||||||
/*
|
|
||||||
* Invalid HTTP header field was received, and it is ignored.
|
|
||||||
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
|
|
||||||
* nghttp2_on_invalid_header_callback.
|
|
||||||
*/
|
|
||||||
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
|
|
||||||
} nghttp2_internal_error;
|
} nghttp2_internal_error;
|
||||||
|
|
||||||
#endif /* NGHTTP2_INT_H */
|
#endif /* NGHTTP2_INT_H */
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user