mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-08 02:58:53 +08:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b71996d98 | ||
|
|
e92cc26792 | ||
|
|
82d9ffa1ad |
@@ -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
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ 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
|
||||||
@@ -51,13 +50,15 @@ before_script:
|
|||||||
# Now build nghttp2
|
# Now build nghttp2
|
||||||
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
|
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
|
||||||
- git submodule update --init
|
- git submodule update --init
|
||||||
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay" CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address; fi
|
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"; fi
|
||||||
- if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DSPDYLAY_INCLUDE_DIR="$SPDYLAY_HOME/lib/includes" -DSPDYLAY_LIBRARY="$SPDYLAY_HOME/lib/.libs/libspdylay.so"; fi
|
- 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:
|
||||||
|
- make
|
||||||
- make check
|
- make check
|
||||||
|
- cd integration-tests
|
||||||
# As of April, 23, 2016, golang http2 build fails, probably because
|
# As of April, 23, 2016, golang http2 build fails, probably because
|
||||||
# the default go version is too old.
|
# the default go version is too old.
|
||||||
# - cd integration-tests
|
|
||||||
# - export GOPATH="$PWD/integration-tests/golang"
|
# - export GOPATH="$PWD/integration-tests/golang"
|
||||||
# - make itprep
|
# - make itprep
|
||||||
# - make it
|
# - make it
|
||||||
|
|||||||
2
AUTHORS
2
AUTHORS
@@ -32,7 +32,6 @@ Etienne Cimon
|
|||||||
Fabian Möller
|
Fabian Möller
|
||||||
Fabian Wiesel
|
Fabian Wiesel
|
||||||
Gabi Davar
|
Gabi Davar
|
||||||
Google Inc.
|
|
||||||
Jacob Champion
|
Jacob Champion
|
||||||
Jan-E
|
Jan-E
|
||||||
Janusz Dziemidowicz
|
Janusz Dziemidowicz
|
||||||
@@ -72,7 +71,6 @@ Tomasz Buchert
|
|||||||
Vernon Tang
|
Vernon Tang
|
||||||
Viacheslav Biriukov
|
Viacheslav Biriukov
|
||||||
Viktor Szépe
|
Viktor Szépe
|
||||||
Wenfeng Liu
|
|
||||||
Xiaoguang Sun
|
Xiaoguang Sun
|
||||||
Zhuoyun Wei
|
Zhuoyun Wei
|
||||||
acesso
|
acesso
|
||||||
|
|||||||
@@ -24,15 +24,15 @@
|
|||||||
|
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||||
project(nghttp2 VERSION 1.16.1)
|
project(nghttp2 VERSION 1.11.1)
|
||||||
|
|
||||||
# See versioning rule:
|
# See versioning rule:
|
||||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
set(LT_CURRENT 26)
|
set(LT_CURRENT 22)
|
||||||
set(LT_REVISION 1)
|
set(LT_REVISION 0)
|
||||||
set(LT_AGE 12)
|
set(LT_AGE 8)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
include(Version)
|
include(Version)
|
||||||
|
|
||||||
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
|
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
|
||||||
@@ -408,10 +408,10 @@ configure_file(cmakeconfig.h.in config.h)
|
|||||||
# autotools-compatible names
|
# autotools-compatible names
|
||||||
# Sphinx expects relative paths in the .rst files. Use the fact that the files
|
# Sphinx expects relative paths in the .rst files. Use the fact that the files
|
||||||
# below are all one directory level deep.
|
# 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_srcdir "${CMAKE_BINARY_DIR}/dir" "${CMAKE_SOURCE_DIR}")
|
||||||
file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}")
|
file(RELATIVE_PATH top_builddir "${CMAKE_BINARY_DIR}/dir" "${CMAKE_BINARY_DIR}")
|
||||||
set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
set(abs_top_srcdir "${CMAKE_SOURCE_DIR}")
|
||||||
set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
|
set(abs_top_builddir "${CMAKE_BINARY_DIR}")
|
||||||
# libnghttp2.pc (pkg-config file)
|
# libnghttp2.pc (pkg-config file)
|
||||||
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
||||||
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
|
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
|
||||||
@@ -450,7 +450,7 @@ foreach(name
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
"${CMAKE_BINARY_DIR}" # for config.h
|
||||||
)
|
)
|
||||||
# For use in src/CMakeLists.txt
|
# For use in src/CMakeLists.txt
|
||||||
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
|
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
|
||||||
|
|||||||
40
README.rst
40
README.rst
@@ -58,11 +58,6 @@ 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
|
|
||||||
all you need. Use ``--enable-lib-only`` to ensure that only
|
|
||||||
libnghttp2 is built. This avoids potential build error related to
|
|
||||||
building bundled applications.
|
|
||||||
|
|
||||||
To build and run the application programs (``nghttp``, ``nghttpd``,
|
To build and run the application programs (``nghttp``, ``nghttpd``,
|
||||||
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
|
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
|
||||||
are required:
|
are required:
|
||||||
@@ -181,23 +176,6 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
|||||||
applications were not built, then using ``--enable-app`` may find
|
applications were not built, then using ``--enable-app`` may find
|
||||||
that cause, such as the missing dependency.
|
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)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
@@ -1375,7 +1353,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:
|
||||||
@@ -1505,17 +1483,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
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@@ -1528,8 +1495,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"
|
||||||
|
|||||||
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
|
|
||||||
54
configure.ac
54
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.16.1], [t-tujikawa@users.sourceforge.net])
|
AC_INIT([nghttp2], [1.11.1], [t-tujikawa@users.sourceforge.net])
|
||||||
AC_CONFIG_AUX_DIR([.])
|
AC_CONFIG_AUX_DIR([.])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
@@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
|||||||
|
|
||||||
dnl See versioning rule:
|
dnl See versioning rule:
|
||||||
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
AC_SUBST(LT_CURRENT, 26)
|
AC_SUBST(LT_CURRENT, 22)
|
||||||
AC_SUBST(LT_REVISION, 1)
|
AC_SUBST(LT_REVISION, 0)
|
||||||
AC_SUBST(LT_AGE, 12)
|
AC_SUBST(LT_AGE, 8)
|
||||||
|
|
||||||
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"`
|
||||||
@@ -234,41 +234,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 +246,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 +258,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])
|
||||||
|
|
||||||
@@ -761,7 +720,6 @@ 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*.
|
# This is required because we pass format string as "const char*.
|
||||||
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
|
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
|
||||||
@@ -771,7 +729,6 @@ if test "x$werror" != "xno"; then
|
|||||||
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
|
||||||
|
|
||||||
@@ -868,7 +825,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}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ set(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
|
||||||
@@ -24,7 +23,6 @@ set(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_http2_strerror.rst
|
||||||
@@ -33,9 +31,7 @@ set(APIDOCS
|
|||||||
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_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_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
|
||||||
@@ -58,15 +54,13 @@ set(APIDOCS
|
|||||||
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_extension_chunk_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_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_pack_extension_callback.rst
|
||||||
nghttp2_session_callbacks_set_recv_callback.rst
|
nghttp2_session_callbacks_set_recv_callback.rst
|
||||||
@@ -74,9 +68,6 @@ set(APIDOCS
|
|||||||
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_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
|
||||||
@@ -88,11 +79,7 @@ set(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
|
||||||
@@ -101,19 +88,20 @@ set(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
|
||||||
@@ -122,7 +110,6 @@ set(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
|
||||||
|
|||||||
@@ -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 \
|
||||||
@@ -57,9 +56,7 @@ APIDOCS= \
|
|||||||
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_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_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 \
|
||||||
@@ -89,8 +86,6 @@ APIDOCS= \
|
|||||||
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_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_pack_extension_callback.rst \
|
||||||
nghttp2_session_callbacks_set_recv_callback.rst \
|
nghttp2_session_callbacks_set_recv_callback.rst \
|
||||||
@@ -98,9 +93,6 @@ APIDOCS= \
|
|||||||
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_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 +104,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 +113,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 +135,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 \
|
||||||
|
|||||||
@@ -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):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -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 --expect-continue --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 --backend-request-buffer --max-request-header-fields --fastopen --tls-ticket-key-memcached --conf --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --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 --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 --include --frontend-http2-dump-response-header --tls-ticket-key-file --verify-client-cacert --max-response-header-fields --backend-request-buffer --max-request-header-fields --backend-http2-connection-window-bits --conf --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --no-server-push --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 --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 --http2-no-cookie-crumbling --worker-read-burst --dh-param-file --accesslog-format --errorlog-syslog --request-header-field-buffer --errorlog-file --frontend-http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend --insecure --log-level --host-rewrite --tls-proto-list --tls-ticket-key-memcached-interval --frontend-http2-setting-timeout --worker-frontend-connections --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-http2-settings-timeout --subcert --no-kqueue --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 --backend-connections-per-host --backend-http2-window-bits --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 --version --add-response-header --backend-read-timeout --frontend --accesslog-file --http2-proxy --client-private-key-file --client-cert-file --accept-proxy-protocol --tls-dyn-rec-idle-timeout --verify-client --read-rate --backend-connections-per-frontend --strip-incoming-forwarded ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
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" "Nov 13, 2016" "1.16.1" "nghttp2"
|
.TH "H2LOAD" "1" "May 29, 2016" "1.11.1" "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
|
||||||
|
|||||||
21
doc/nghttp.1
21
doc/nghttp.1
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "NGHTTP" "1" "Nov 13, 2016" "1.16.1" "nghttp2"
|
.TH "NGHTTP" "1" "May 29, 2016" "1.11.1" "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.
|
||||||
@@ -311,7 +300,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.
|
||||||
@@ -218,9 +208,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" "Nov 13, 2016" "1.16.1" "nghttp2"
|
.TH "NGHTTPD" "1" "May 29, 2016" "1.11.1" "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.
|
||||||
|
|||||||
311
doc/nghttpx.1
311
doc/nghttpx.1
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "NGHTTPX" "1" "Nov 13, 2016" "1.16.1" "nghttp2"
|
.TH "NGHTTPX" "1" "May 29, 2016" "1.11.1" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttpx \- HTTP/2 proxy
|
nghttpx \- HTTP/2 proxy
|
||||||
.
|
.
|
||||||
@@ -55,7 +55,7 @@ The options are categorized into several groups.
|
|||||||
.SS Connections
|
.SS Connections
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
|
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;PARAM]...]
|
||||||
Set backend host and port. The multiple backend
|
Set backend host and port. The multiple backend
|
||||||
addresses are accepted by repeating this option. UNIX
|
addresses are accepted by repeating this option. UNIX
|
||||||
domain socket can be specified by prefixing path name
|
domain socket can be specified by prefixing path name
|
||||||
@@ -120,13 +120,12 @@ together forming load balancing group.
|
|||||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||||
The parameters are delimited by ";". The available
|
The parameters are delimited by ";". The available
|
||||||
parameters are: "proto=<PROTO>", "tls",
|
parameters are: "proto=<PROTO>", "tls",
|
||||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
|
"sni=<SNI_HOST>", "fall=<N>", and "rise=<N>". The
|
||||||
"affinity=<METHOD>". The parameter consists of keyword,
|
parameter consists of keyword, and optionally followed
|
||||||
and optionally followed by "=" and value. For example,
|
by "=" and value. For example, the parameter "proto=h2"
|
||||||
the parameter "proto=h2" consists of the keyword "proto"
|
consists of the keyword "proto" and value "h2". The
|
||||||
and value "h2". The parameter "tls" consists of the
|
parameter "tls" consists of the keyword "tls" without
|
||||||
keyword "tls" without value. Each parameter is
|
value. Each parameter is described as follows.
|
||||||
described as follows.
|
|
||||||
.sp
|
.sp
|
||||||
The backend application protocol can be specified using
|
The backend application protocol can be specified using
|
||||||
optional "proto" parameter, and in the form of
|
optional "proto" parameter, and in the form of
|
||||||
@@ -161,20 +160,6 @@ eligible for load balancing target. If <N> is 0, a
|
|||||||
backend is permanently offline, once it goes in that
|
backend is permanently offline, once it goes in that
|
||||||
state, and this is the default behaviour.
|
state, and this is the default behaviour.
|
||||||
.sp
|
.sp
|
||||||
The session affinity is enabled using
|
|
||||||
"affinity=<METHOD>" parameter. If "ip" is given in
|
|
||||||
<METHOD>, client IP based session affinity is enabled.
|
|
||||||
If "none" is given in <METHOD>, session affinity is
|
|
||||||
disabled, and this is the default. The session affinity
|
|
||||||
is enabled per <PATTERN>. If at least one backend has
|
|
||||||
"affinity" parameter, and its <METHOD> is not "none",
|
|
||||||
session affinity is enabled for all backend servers
|
|
||||||
sharing the same <PATTERN>. It is advised to set
|
|
||||||
"affinity" parameter to all backend explicitly if
|
|
||||||
session affinity is desired. The session affinity may
|
|
||||||
break if one of the backend gets unreachable, or backend
|
|
||||||
settings are reloaded or replaced by API.
|
|
||||||
.sp
|
|
||||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||||
not contain these characters. Since ";" has special
|
not contain these characters. Since ";" has special
|
||||||
meaning in shell, the option value must be quoted.
|
meaning in shell, the option value must be quoted.
|
||||||
@@ -183,7 +168,7 @@ Default: \fB127.0.0.1,80\fP
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
|
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[;no\-tls]
|
||||||
Set frontend host and port. If <HOST> is \(aq*\(aq, it
|
Set frontend host and port. If <HOST> is \(aq*\(aq, it
|
||||||
assumes all addresses including both IPv4 and IPv6.
|
assumes all addresses including both IPv4 and IPv6.
|
||||||
UNIX domain socket can be specified by prefixing path
|
UNIX domain socket can be specified by prefixing path
|
||||||
@@ -191,25 +176,9 @@ name with "unix:" (e.g., unix:/var/run/nghttpx.sock).
|
|||||||
This option can be used multiple times to listen to
|
This option can be used multiple times to listen to
|
||||||
multiple addresses.
|
multiple addresses.
|
||||||
.sp
|
.sp
|
||||||
This option can take 0 or more parameters, which are
|
|
||||||
described below. Note that "api" and "healthmon"
|
|
||||||
parameters are mutually exclusive.
|
|
||||||
.sp
|
|
||||||
Optionally, TLS can be disabled by specifying "no\-tls"
|
Optionally, TLS can be disabled by specifying "no\-tls"
|
||||||
parameter. TLS is enabled by default.
|
parameter. TLS is enabled by default.
|
||||||
.sp
|
.sp
|
||||||
To make this frontend as API endpoint, specify "api"
|
|
||||||
parameter. This is disabled by default. It is
|
|
||||||
important to limit the access to the API frontend.
|
|
||||||
Otherwise, someone may change the backend server, and
|
|
||||||
break your services, or expose confidential information
|
|
||||||
to the outside the world.
|
|
||||||
.sp
|
|
||||||
To make this frontend as health monitor endpoint,
|
|
||||||
specify "healthmon" parameter. This is disabled by
|
|
||||||
default. Any requests which come through this address
|
|
||||||
are replied with 200 HTTP status, without no body.
|
|
||||||
.sp
|
|
||||||
Default: \fB*,3000\fP
|
Default: \fB*,3000\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
@@ -456,14 +425,6 @@ Default: \fB30s\fP
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-backend\-connect\-timeout=<DURATION>
|
|
||||||
Specify timeout before establishing TCP connection to
|
|
||||||
backend.
|
|
||||||
.sp
|
|
||||||
Default: \fB30s\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-backend\-keep\-alive\-timeout=<DURATION>
|
.B \-\-backend\-keep\-alive\-timeout=<DURATION>
|
||||||
Specify keep\-alive timeout for backend connection.
|
Specify keep\-alive timeout for backend connection.
|
||||||
.sp
|
.sp
|
||||||
@@ -494,20 +455,6 @@ backend server.
|
|||||||
.sp
|
.sp
|
||||||
Default: \fB10s\fP
|
Default: \fB10s\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-backend\-max\-backoff=<DURATION>
|
|
||||||
Specify maximum backoff interval. This is used when
|
|
||||||
doing health check against offline backend (see "fail"
|
|
||||||
parameter in \fI\%\-\-backend\fP option). It is also used to
|
|
||||||
limit the maximum interval to temporarily disable
|
|
||||||
backend when nghttpx failed to connect to it. These
|
|
||||||
intervals are calculated using exponential backoff, and
|
|
||||||
consecutive failed attempts increase the interval. This
|
|
||||||
option caps its maximum value.
|
|
||||||
.sp
|
|
||||||
Default: \fB2m\fP
|
|
||||||
.UNINDENT
|
|
||||||
.SS SSL/TLS
|
.SS SSL/TLS
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -517,17 +464,6 @@ described in OpenSSL ciphers(1).
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-ecdh\-curves=<LIST>
|
|
||||||
Set supported curve list for frontend connections.
|
|
||||||
<LIST> is a colon separated list of curve NID or names
|
|
||||||
in the preference order. The supported curves depend on
|
|
||||||
the linked OpenSSL library. This function requires
|
|
||||||
OpenSSL >= 1.0.2.
|
|
||||||
.sp
|
|
||||||
Default: \fBX25519:P\-256:P\-384:P\-521\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-k, \-\-insecure
|
.B \-k, \-\-insecure
|
||||||
Don\(aqt verify backend server\(aqs certificate if TLS is
|
Don\(aqt verify backend server\(aqs certificate if TLS is
|
||||||
enabled for backend connections.
|
enabled for backend connections.
|
||||||
@@ -550,21 +486,12 @@ password protected it\(aqll be requested interactively.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
|
.B \-\-subcert=<KEYPATH>:<CERTPATH>
|
||||||
Specify additional certificate and private key file.
|
Specify additional certificate and private key file.
|
||||||
nghttpx will choose certificates based on the hostname
|
nghttpx will choose certificates based on the hostname
|
||||||
indicated by client using TLS SNI extension. This
|
indicated by client using TLS SNI extension. This
|
||||||
option can be used multiple times. To make OCSP
|
option can be used multiple times. To make OCSP
|
||||||
stapling work, <CERTPATH> must be absolute path.
|
stapling work, <CERTPATH> must be absolute path.
|
||||||
.sp
|
|
||||||
Additional parameter can be specified in <PARAM>. The
|
|
||||||
available <PARAM> is "sct\-dir=<DIR>".
|
|
||||||
.sp
|
|
||||||
"sct\-dir=<DIR>" specifies the path to directory which
|
|
||||||
contains *.sct files for TLS
|
|
||||||
signed_certificate_timestamp extension (RFC 6962). This
|
|
||||||
feature requires OpenSSL >= 1.0.2. See also
|
|
||||||
\fI\%\-\-tls\-sct\-dir\fP option.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -807,18 +734,6 @@ Allow black listed cipher suite on HTTP/2 connection.
|
|||||||
See \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for
|
See \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for
|
||||||
the complete HTTP/2 cipher suites black list.
|
the complete HTTP/2 cipher suites black list.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-tls\-sct\-dir=<DIR>
|
|
||||||
Specifies the directory where *.sct files exist. All
|
|
||||||
*.sct files in <DIR> are read, and sent as
|
|
||||||
extension_data of TLS signed_certificate_timestamp (RFC
|
|
||||||
6962) to client. These *.sct files are for the
|
|
||||||
certificate specified in positional command\-line
|
|
||||||
argument <CERT>, or certificate option in configuration
|
|
||||||
file. For additional certificates, use \fI\%\-\-subcert\fP
|
|
||||||
option. This option requires OpenSSL >= 1.0.2.
|
|
||||||
.UNINDENT
|
|
||||||
.SS HTTP/2 and SPDY
|
.SS HTTP/2 and SPDY
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -840,36 +755,37 @@ Default: \fB100\fP
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-frontend\-http2\-window\-size=<SIZE>
|
.B \-\-frontend\-http2\-window\-bits=<N>
|
||||||
Sets the per\-stream initial window size of HTTP/2 and
|
Sets the per\-stream initial window size of HTTP/2 SPDY
|
||||||
SPDY frontend connection.
|
frontend connection. For HTTP/2, the size is 2**<N>\-1.
|
||||||
|
For SPDY, the size is 2**<N>.
|
||||||
.sp
|
.sp
|
||||||
Default: \fB65535\fP
|
Default: \fB16\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-frontend\-http2\-connection\-window\-size=<SIZE>
|
.B \-\-frontend\-http2\-connection\-window\-bits=<N>
|
||||||
Sets the per\-connection window size of HTTP/2 and SPDY
|
Sets the per\-connection window size of HTTP/2 and SPDY
|
||||||
frontend connection. For SPDY connection, the value
|
frontend connection. For HTTP/2, the size is
|
||||||
less than 64KiB is rounded up to 64KiB.
|
2**<N>\-1. For SPDY, the size is 2**<N>.
|
||||||
.sp
|
.sp
|
||||||
Default: \fB65535\fP
|
Default: \fB16\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-backend\-http2\-window\-size=<SIZE>
|
.B \-\-backend\-http2\-window\-bits=<N>
|
||||||
Sets the initial window size of HTTP/2 backend
|
Sets the initial window size of HTTP/2 backend
|
||||||
connection.
|
connection to 2**<N>\-1.
|
||||||
.sp
|
.sp
|
||||||
Default: \fB65535\fP
|
Default: \fB16\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-backend\-http2\-connection\-window\-size=<SIZE>
|
.B \-\-backend\-http2\-connection\-window\-bits=<N>
|
||||||
Sets the per\-connection window size of HTTP/2 backend
|
Sets the per\-connection window size of HTTP/2 backend
|
||||||
connection.
|
connection to 2**<N>\-1.
|
||||||
.sp
|
.sp
|
||||||
Default: \fB2147483647\fP
|
Default: \fB30\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -895,71 +811,6 @@ backend session is relayed to frontend, and server push
|
|||||||
via Link header field is also supported. SPDY frontend
|
via Link header field is also supported. SPDY frontend
|
||||||
does not support server push.
|
does not support server push.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-frontend\-http2\-optimize\-write\-buffer\-size
|
|
||||||
(Experimental) Enable write buffer size optimization in
|
|
||||||
frontend HTTP/2 TLS connection. This optimization aims
|
|
||||||
to reduce write buffer size so that it only contains
|
|
||||||
bytes which can send immediately. This makes server
|
|
||||||
more responsive to prioritized HTTP/2 stream because the
|
|
||||||
buffering of lower priority stream is reduced. This
|
|
||||||
option is only effective on recent Linux platform.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-frontend\-http2\-optimize\-window\-size
|
|
||||||
(Experimental) Automatically tune connection level
|
|
||||||
window size of frontend HTTP/2 TLS connection. If this
|
|
||||||
feature is enabled, connection window size starts with
|
|
||||||
the default window size, 65535 bytes. nghttpx
|
|
||||||
automatically adjusts connection window size based on
|
|
||||||
TCP receiving window size. The maximum window size is
|
|
||||||
capped by the value specified by
|
|
||||||
\fI\%\-\-frontend\-http2\-connection\-window\-size\fP\&. Since the
|
|
||||||
stream is subject to stream level window size, it should
|
|
||||||
be adjusted using \fI\%\-\-frontend\-http2\-window\-size\fP option as
|
|
||||||
well. This option is only effective on recent Linux
|
|
||||||
platform.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-frontend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
|
|
||||||
Specify the maximum dynamic table size of HPACK encoder
|
|
||||||
in the frontend HTTP/2 connection. 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.
|
|
||||||
.sp
|
|
||||||
Default: \fB4K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-frontend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
|
|
||||||
Specify the maximum dynamic table size of HPACK decoder
|
|
||||||
in the frontend HTTP/2 connection.
|
|
||||||
.sp
|
|
||||||
Default: \fB4K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-backend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
|
|
||||||
Specify the maximum dynamic table size of HPACK encoder
|
|
||||||
in the backend HTTP/2 connection. The decoder (backend)
|
|
||||||
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 backend specified.
|
|
||||||
.sp
|
|
||||||
Default: \fB4K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-backend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
|
|
||||||
Specify the maximum dynamic table size of HPACK decoder
|
|
||||||
in the backend HTTP/2 connection.
|
|
||||||
.sp
|
|
||||||
Default: \fB4K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.SS Mode
|
.SS Mode
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -1042,12 +893,6 @@ $ssl_session_id: session ID for SSL/TLS connection.
|
|||||||
.IP \(bu 2
|
.IP \(bu 2
|
||||||
$ssl_session_reused: "r" if SSL/TLS session was
|
$ssl_session_reused: "r" if SSL/TLS session was
|
||||||
reused. Otherwise, "."
|
reused. Otherwise, "."
|
||||||
.IP \(bu 2
|
|
||||||
$backend_host: backend host used to fulfill the
|
|
||||||
request. "\-" if backend host is not available.
|
|
||||||
.IP \(bu 2
|
|
||||||
$backend_port: backend port used to fulfill the
|
|
||||||
request. "\-" if backend host is not available.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.sp
|
.sp
|
||||||
The variable can be enclosed by "{" and "}" for
|
The variable can be enclosed by "{" and "}" for
|
||||||
@@ -1233,28 +1078,6 @@ originally generates HTTP error status code <CODE>.
|
|||||||
HTTP status code. If error status code comes from
|
HTTP status code. If error status code comes from
|
||||||
backend server, the custom error pages are not used.
|
backend server, the custom error pages are not used.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-server\-name=<NAME>
|
|
||||||
Change server response header field value to <NAME>.
|
|
||||||
.sp
|
|
||||||
Default: \fBnghttpx nghttp2/1.16.1\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-no\-server\-rewrite
|
|
||||||
Don\(aqt rewrite server header field in default mode. When
|
|
||||||
\fI\%\-\-http2\-proxy\fP is used, these headers will not be altered
|
|
||||||
regardless of this option.
|
|
||||||
.UNINDENT
|
|
||||||
.SS API
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-api\-max\-request\-body=<SIZE>
|
|
||||||
Set the maximum size of request body for API request.
|
|
||||||
.sp
|
|
||||||
Default: \fB16K\fP
|
|
||||||
.UNINDENT
|
|
||||||
.SS Debug
|
.SS Debug
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -1402,9 +1225,6 @@ Shutdown gracefully. First accept pending connections and stop
|
|||||||
accepting connection. After all connections are handled, nghttpx
|
accepting connection. After all connections are handled, nghttpx
|
||||||
exits.
|
exits.
|
||||||
.TP
|
.TP
|
||||||
.B SIGHUP
|
|
||||||
Reload configuration file given in \fI\%\-\-conf\fP\&.
|
|
||||||
.TP
|
|
||||||
.B SIGUSR1
|
.B SIGUSR1
|
||||||
Reopen log files.
|
Reopen log files.
|
||||||
.TP
|
.TP
|
||||||
@@ -1412,11 +1232,7 @@ Reopen log files.
|
|||||||
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.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.sp
|
.sp
|
||||||
\fBNOTE:\fP
|
\fBNOTE:\fP
|
||||||
@@ -1565,19 +1381,6 @@ If \fI\%\-\-tls\-ticket\-key\-file\fP 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).
|
||||||
.SH CERTIFICATE TRANSPARENCY
|
|
||||||
.sp
|
|
||||||
nghttpx supports TLS \fBsigned_certificate_timestamp\fP extension (\fI\%RFC
|
|
||||||
6962\fP). The relevant options
|
|
||||||
are \fI\%\-\-tls\-sct\-dir\fP and \fBsct\-dir\fP parameter in
|
|
||||||
\fI\%\-\-subcert\fP\&. They takes a directory, and nghttpx reads all
|
|
||||||
files whose extension is \fB\&.sct\fP under the directory. The \fB*.sct\fP
|
|
||||||
files are encoded as \fBSignedCertificateTimestamp\fP struct described
|
|
||||||
in \fI\%section 3.2 of RFC 69662\fP\&. This format is
|
|
||||||
the same one used by \fI\%nginx\-ct\fP and \fI\%mod_ssl_ct\fP\&.
|
|
||||||
\fI\%ct\-submit\fP can be
|
|
||||||
used to submit certificates to log servers, and obtain the
|
|
||||||
\fBSignedCertificateTimestamp\fP struct which can be used with nghttpx.
|
|
||||||
.SH MRUBY SCRIPTING
|
.SH MRUBY SCRIPTING
|
||||||
.sp
|
.sp
|
||||||
\fBWARNING:\fP
|
\fBWARNING:\fP
|
||||||
@@ -1669,11 +1472,6 @@ connection from client.
|
|||||||
.B attribute [R] tls_used
|
.B attribute [R] tls_used
|
||||||
Return true if TLS is used on the connection.
|
Return true if TLS is used on the connection.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 7.0
|
|
||||||
.TP
|
|
||||||
.B attribute [R] tls_sni
|
|
||||||
Return the TLS SNI value which client sent in this connection.
|
|
||||||
.UNINDENT
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -1884,64 +1682,9 @@ App.new
|
|||||||
.fi
|
.fi
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.SH API ENDPOINTS
|
|
||||||
.sp
|
|
||||||
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 \fI\%\-\-frontend\fP option with "api"
|
|
||||||
parameter. All requests which come from this frontend address, will
|
|
||||||
be treated as API request.
|
|
||||||
.sp
|
|
||||||
The response is normally JSON dictionary, and at least includes the
|
|
||||||
following keys:
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B status
|
|
||||||
The status of the request processing. The following values are
|
|
||||||
defined:
|
|
||||||
.INDENT 7.0
|
|
||||||
.TP
|
|
||||||
.B Success
|
|
||||||
The request was successful.
|
|
||||||
.TP
|
|
||||||
.B Failure
|
|
||||||
The request was failed. No change has been made.
|
|
||||||
.UNINDENT
|
|
||||||
.TP
|
|
||||||
.B code
|
|
||||||
HTTP status code
|
|
||||||
.UNINDENT
|
|
||||||
.sp
|
|
||||||
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).
|
|
||||||
.sp
|
|
||||||
The following section describes available API endpoints.
|
|
||||||
.SS PUT /api/v1beta1/backendconfig
|
|
||||||
.sp
|
|
||||||
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 \fI\%FILES\fP section. The
|
|
||||||
line separator inside the request body must be single LF (0x0A).
|
|
||||||
Currently, only \fI\%backend\fP 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 \fI\%backend\fP option is found in request
|
|
||||||
body, the current set of backend is replaced with the \fI\%backend\fP option\(aqs default value, which is \fB127.0.0.1,80\fP\&.
|
|
||||||
.sp
|
|
||||||
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.
|
|
||||||
.sp
|
|
||||||
The one limitation is that only numeric IP address is allowd in
|
|
||||||
\fI\%backend\fP in request body while non numeric
|
|
||||||
hostname is allowed in command\-line or configuration file is read
|
|
||||||
using \fI\%\-\-conf\fP\&.
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBh2load(1)\fP
|
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fIh2load(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ The options are categorized into several groups.
|
|||||||
Connections
|
Connections
|
||||||
~~~~~~~~~~~
|
~~~~~~~~~~~
|
||||||
|
|
||||||
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
|
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;PARAM]...]
|
||||||
|
|
||||||
|
|
||||||
Set backend host and port. The multiple backend
|
Set backend host and port. The multiple backend
|
||||||
@@ -70,7 +70,7 @@ Connections
|
|||||||
|
|
||||||
Host can include "\*" in the left most position to
|
Host can include "\*" in the left most position to
|
||||||
indicate wildcard match (only suffix match is done).
|
indicate wildcard match (only suffix match is done).
|
||||||
The "\*" must match at least one character. For example,
|
The "*" must match at least one character. For example,
|
||||||
host pattern "\*.nghttp2.org" matches against
|
host pattern "\*.nghttp2.org" matches against
|
||||||
"www.nghttp2.org" and "git.ngttp2.org", but does not
|
"www.nghttp2.org" and "git.ngttp2.org", but does not
|
||||||
match against "nghttp2.org". The exact hosts match
|
match against "nghttp2.org". The exact hosts match
|
||||||
@@ -104,13 +104,12 @@ Connections
|
|||||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||||
The parameters are delimited by ";". The available
|
The parameters are delimited by ";". The available
|
||||||
parameters are: "proto=<PROTO>", "tls",
|
parameters are: "proto=<PROTO>", "tls",
|
||||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
|
"sni=<SNI_HOST>", "fall=<N>", and "rise=<N>". The
|
||||||
"affinity=<METHOD>". The parameter consists of keyword,
|
parameter consists of keyword, and optionally followed
|
||||||
and optionally followed by "=" and value. For example,
|
by "=" and value. For example, the parameter "proto=h2"
|
||||||
the parameter "proto=h2" consists of the keyword "proto"
|
consists of the keyword "proto" and value "h2". The
|
||||||
and value "h2". The parameter "tls" consists of the
|
parameter "tls" consists of the keyword "tls" without
|
||||||
keyword "tls" without value. Each parameter is
|
value. Each parameter is described as follows.
|
||||||
described as follows.
|
|
||||||
|
|
||||||
The backend application protocol can be specified using
|
The backend application protocol can be specified using
|
||||||
optional "proto" parameter, and in the form of
|
optional "proto" parameter, and in the form of
|
||||||
@@ -145,20 +144,6 @@ Connections
|
|||||||
backend is permanently offline, once it goes in that
|
backend is permanently offline, once it goes in that
|
||||||
state, and this is the default behaviour.
|
state, and this is the default behaviour.
|
||||||
|
|
||||||
The session affinity is enabled using
|
|
||||||
"affinity=<METHOD>" parameter. If "ip" is given in
|
|
||||||
<METHOD>, client IP based session affinity is enabled.
|
|
||||||
If "none" is given in <METHOD>, session affinity is
|
|
||||||
disabled, and this is the default. The session affinity
|
|
||||||
is enabled per <PATTERN>. If at least one backend has
|
|
||||||
"affinity" parameter, and its <METHOD> is not "none",
|
|
||||||
session affinity is enabled for all backend servers
|
|
||||||
sharing the same <PATTERN>. It is advised to set
|
|
||||||
"affinity" parameter to all backend explicitly if
|
|
||||||
session affinity is desired. The session affinity may
|
|
||||||
break if one of the backend gets unreachable, or backend
|
|
||||||
settings are reloaded or replaced by API.
|
|
||||||
|
|
||||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||||
not contain these characters. Since ";" has special
|
not contain these characters. Since ";" has special
|
||||||
meaning in shell, the option value must be quoted.
|
meaning in shell, the option value must be quoted.
|
||||||
@@ -166,7 +151,7 @@ Connections
|
|||||||
|
|
||||||
Default: ``127.0.0.1,80``
|
Default: ``127.0.0.1,80``
|
||||||
|
|
||||||
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
|
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[;no-tls]
|
||||||
|
|
||||||
Set frontend host and port. If <HOST> is '\*', it
|
Set frontend host and port. If <HOST> is '\*', it
|
||||||
assumes all addresses including both IPv4 and IPv6.
|
assumes all addresses including both IPv4 and IPv6.
|
||||||
@@ -175,25 +160,9 @@ Connections
|
|||||||
This option can be used multiple times to listen to
|
This option can be used multiple times to listen to
|
||||||
multiple addresses.
|
multiple addresses.
|
||||||
|
|
||||||
This option can take 0 or more parameters, which are
|
|
||||||
described below. Note that "api" and "healthmon"
|
|
||||||
parameters are mutually exclusive.
|
|
||||||
|
|
||||||
Optionally, TLS can be disabled by specifying "no-tls"
|
Optionally, TLS can be disabled by specifying "no-tls"
|
||||||
parameter. TLS is enabled by default.
|
parameter. TLS is enabled by default.
|
||||||
|
|
||||||
To make this frontend as API endpoint, specify "api"
|
|
||||||
parameter. This is disabled by default. It is
|
|
||||||
important to limit the access to the API frontend.
|
|
||||||
Otherwise, someone may change the backend server, and
|
|
||||||
break your services, or expose confidential information
|
|
||||||
to the outside the world.
|
|
||||||
|
|
||||||
To make this frontend as health monitor endpoint,
|
|
||||||
specify "healthmon" parameter. This is disabled by
|
|
||||||
default. Any requests which come through this address
|
|
||||||
are replied with 200 HTTP status, without no body.
|
|
||||||
|
|
||||||
|
|
||||||
Default: ``*,3000``
|
Default: ``*,3000``
|
||||||
|
|
||||||
@@ -417,13 +386,6 @@ Timeout
|
|||||||
|
|
||||||
Default: ``30s``
|
Default: ``30s``
|
||||||
|
|
||||||
.. option:: --backend-connect-timeout=<DURATION>
|
|
||||||
|
|
||||||
Specify timeout before establishing TCP connection to
|
|
||||||
backend.
|
|
||||||
|
|
||||||
Default: ``30s``
|
|
||||||
|
|
||||||
.. option:: --backend-keep-alive-timeout=<DURATION>
|
.. option:: --backend-keep-alive-timeout=<DURATION>
|
||||||
|
|
||||||
Specify keep-alive timeout for backend connection.
|
Specify keep-alive timeout for backend connection.
|
||||||
@@ -452,19 +414,6 @@ Timeout
|
|||||||
|
|
||||||
Default: ``10s``
|
Default: ``10s``
|
||||||
|
|
||||||
.. option:: --backend-max-backoff=<DURATION>
|
|
||||||
|
|
||||||
Specify maximum backoff interval. This is used when
|
|
||||||
doing health check against offline backend (see "fail"
|
|
||||||
parameter in :option:`--backend` option). It is also used to
|
|
||||||
limit the maximum interval to temporarily disable
|
|
||||||
backend when nghttpx failed to connect to it. These
|
|
||||||
intervals are calculated using exponential backoff, and
|
|
||||||
consecutive failed attempts increase the interval. This
|
|
||||||
option caps its maximum value.
|
|
||||||
|
|
||||||
Default: ``2m``
|
|
||||||
|
|
||||||
|
|
||||||
SSL/TLS
|
SSL/TLS
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
@@ -474,16 +423,6 @@ SSL/TLS
|
|||||||
Set allowed cipher list. The format of the string is
|
Set allowed cipher list. The format of the string is
|
||||||
described in OpenSSL ciphers(1).
|
described in OpenSSL ciphers(1).
|
||||||
|
|
||||||
.. option:: --ecdh-curves=<LIST>
|
|
||||||
|
|
||||||
Set supported curve list for frontend connections.
|
|
||||||
<LIST> is a colon separated list of curve NID or names
|
|
||||||
in the preference order. The supported curves depend on
|
|
||||||
the linked OpenSSL library. This function requires
|
|
||||||
OpenSSL >= 1.0.2.
|
|
||||||
|
|
||||||
Default: ``X25519:P-256:P-384:P-521``
|
|
||||||
|
|
||||||
.. option:: -k, --insecure
|
.. option:: -k, --insecure
|
||||||
|
|
||||||
Don't verify backend server's certificate if TLS is
|
Don't verify backend server's certificate if TLS is
|
||||||
@@ -503,7 +442,7 @@ SSL/TLS
|
|||||||
private key. If none is given and the private key is
|
private key. If none is given and the private key is
|
||||||
password protected it'll be requested interactively.
|
password protected it'll be requested interactively.
|
||||||
|
|
||||||
.. option:: --subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
|
.. option:: --subcert=<KEYPATH>:<CERTPATH>
|
||||||
|
|
||||||
Specify additional certificate and private key file.
|
Specify additional certificate and private key file.
|
||||||
nghttpx will choose certificates based on the hostname
|
nghttpx will choose certificates based on the hostname
|
||||||
@@ -511,15 +450,6 @@ SSL/TLS
|
|||||||
option can be used multiple times. To make OCSP
|
option can be used multiple times. To make OCSP
|
||||||
stapling work, <CERTPATH> must be absolute path.
|
stapling work, <CERTPATH> must be absolute path.
|
||||||
|
|
||||||
Additional parameter can be specified in <PARAM>. The
|
|
||||||
available <PARAM> is "sct-dir=<DIR>".
|
|
||||||
|
|
||||||
"sct-dir=<DIR>" specifies the path to directory which
|
|
||||||
contains \*.sct files for TLS
|
|
||||||
signed_certificate_timestamp extension (RFC 6962). This
|
|
||||||
feature requires OpenSSL >= 1.0.2. See also
|
|
||||||
:option:`--tls-sct-dir` option.
|
|
||||||
|
|
||||||
.. option:: --dh-param-file=<PATH>
|
.. option:: --dh-param-file=<PATH>
|
||||||
|
|
||||||
Path to file that contains DH parameters in PEM format.
|
Path to file that contains DH parameters in PEM format.
|
||||||
@@ -735,17 +665,6 @@ SSL/TLS
|
|||||||
See https://tools.ietf.org/html/rfc7540#appendix-A for
|
See https://tools.ietf.org/html/rfc7540#appendix-A for
|
||||||
the complete HTTP/2 cipher suites black list.
|
the complete HTTP/2 cipher suites black list.
|
||||||
|
|
||||||
.. option:: --tls-sct-dir=<DIR>
|
|
||||||
|
|
||||||
Specifies the directory where \*.sct files exist. All
|
|
||||||
\*.sct files in <DIR> are read, and sent as
|
|
||||||
extension_data of TLS signed_certificate_timestamp (RFC
|
|
||||||
6962) to client. These \*.sct files are for the
|
|
||||||
certificate specified in positional command-line
|
|
||||||
argument <CERT>, or certificate option in configuration
|
|
||||||
file. For additional certificates, use :option:`--subcert`
|
|
||||||
option. This option requires OpenSSL >= 1.0.2.
|
|
||||||
|
|
||||||
|
|
||||||
HTTP/2 and SPDY
|
HTTP/2 and SPDY
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
@@ -766,34 +685,35 @@ HTTP/2 and SPDY
|
|||||||
|
|
||||||
Default: ``100``
|
Default: ``100``
|
||||||
|
|
||||||
.. option:: --frontend-http2-window-size=<SIZE>
|
.. option:: --frontend-http2-window-bits=<N>
|
||||||
|
|
||||||
Sets the per-stream initial window size of HTTP/2 and
|
Sets the per-stream initial window size of HTTP/2 SPDY
|
||||||
SPDY frontend connection.
|
frontend connection. For HTTP/2, the size is 2\*\*<N>-1.
|
||||||
|
For SPDY, the size is 2\*\*<N>.
|
||||||
|
|
||||||
Default: ``65535``
|
Default: ``16``
|
||||||
|
|
||||||
.. option:: --frontend-http2-connection-window-size=<SIZE>
|
.. option:: --frontend-http2-connection-window-bits=<N>
|
||||||
|
|
||||||
Sets the per-connection window size of HTTP/2 and SPDY
|
Sets the per-connection window size of HTTP/2 and SPDY
|
||||||
frontend connection. For SPDY connection, the value
|
frontend connection. For HTTP/2, the size is
|
||||||
less than 64KiB is rounded up to 64KiB.
|
2**<N>-1. For SPDY, the size is 2\*\*<N>.
|
||||||
|
|
||||||
Default: ``65535``
|
Default: ``16``
|
||||||
|
|
||||||
.. option:: --backend-http2-window-size=<SIZE>
|
.. option:: --backend-http2-window-bits=<N>
|
||||||
|
|
||||||
Sets the initial window size of HTTP/2 backend
|
Sets the initial window size of HTTP/2 backend
|
||||||
connection.
|
connection to 2\*\*<N>-1.
|
||||||
|
|
||||||
Default: ``65535``
|
Default: ``16``
|
||||||
|
|
||||||
.. option:: --backend-http2-connection-window-size=<SIZE>
|
.. option:: --backend-http2-connection-window-bits=<N>
|
||||||
|
|
||||||
Sets the per-connection window size of HTTP/2 backend
|
Sets the per-connection window size of HTTP/2 backend
|
||||||
connection.
|
connection to 2\*\*<N>-1.
|
||||||
|
|
||||||
Default: ``2147483647``
|
Default: ``30``
|
||||||
|
|
||||||
.. option:: --http2-no-cookie-crumbling
|
.. option:: --http2-no-cookie-crumbling
|
||||||
|
|
||||||
@@ -816,65 +736,6 @@ HTTP/2 and SPDY
|
|||||||
via Link header field is also supported. SPDY frontend
|
via Link header field is also supported. SPDY frontend
|
||||||
does not support server push.
|
does not support server push.
|
||||||
|
|
||||||
.. option:: --frontend-http2-optimize-write-buffer-size
|
|
||||||
|
|
||||||
(Experimental) Enable write buffer size optimization in
|
|
||||||
frontend HTTP/2 TLS connection. This optimization aims
|
|
||||||
to reduce write buffer size so that it only contains
|
|
||||||
bytes which can send immediately. This makes server
|
|
||||||
more responsive to prioritized HTTP/2 stream because the
|
|
||||||
buffering of lower priority stream is reduced. This
|
|
||||||
option is only effective on recent Linux platform.
|
|
||||||
|
|
||||||
.. option:: --frontend-http2-optimize-window-size
|
|
||||||
|
|
||||||
(Experimental) Automatically tune connection level
|
|
||||||
window size of frontend HTTP/2 TLS connection. If this
|
|
||||||
feature is enabled, connection window size starts with
|
|
||||||
the default window size, 65535 bytes. nghttpx
|
|
||||||
automatically adjusts connection window size based on
|
|
||||||
TCP receiving window size. The maximum window size is
|
|
||||||
capped by the value specified by
|
|
||||||
:option:`--frontend-http2-connection-window-size`\. Since the
|
|
||||||
stream is subject to stream level window size, it should
|
|
||||||
be adjusted using :option:`--frontend-http2-window-size` option as
|
|
||||||
well. This option is only effective on recent Linux
|
|
||||||
platform.
|
|
||||||
|
|
||||||
.. option:: --frontend-http2-encoder-dynamic-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify the maximum dynamic table size of HPACK encoder
|
|
||||||
in the frontend HTTP/2 connection. 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.
|
|
||||||
|
|
||||||
Default: ``4K``
|
|
||||||
|
|
||||||
.. option:: --frontend-http2-decoder-dynamic-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify the maximum dynamic table size of HPACK decoder
|
|
||||||
in the frontend HTTP/2 connection.
|
|
||||||
|
|
||||||
Default: ``4K``
|
|
||||||
|
|
||||||
.. option:: --backend-http2-encoder-dynamic-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify the maximum dynamic table size of HPACK encoder
|
|
||||||
in the backend HTTP/2 connection. The decoder (backend)
|
|
||||||
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 backend specified.
|
|
||||||
|
|
||||||
Default: ``4K``
|
|
||||||
|
|
||||||
.. option:: --backend-http2-decoder-dynamic-table-size=<SIZE>
|
|
||||||
|
|
||||||
Specify the maximum dynamic table size of HPACK decoder
|
|
||||||
in the backend HTTP/2 connection.
|
|
||||||
|
|
||||||
Default: ``4K``
|
|
||||||
|
|
||||||
|
|
||||||
Mode
|
Mode
|
||||||
~~~~
|
~~~~
|
||||||
@@ -942,10 +803,6 @@ Logging
|
|||||||
* $ssl_session_id: session ID for SSL/TLS connection.
|
* $ssl_session_id: session ID for SSL/TLS connection.
|
||||||
* $ssl_session_reused: "r" if SSL/TLS session was
|
* $ssl_session_reused: "r" if SSL/TLS session was
|
||||||
reused. Otherwise, "."
|
reused. Otherwise, "."
|
||||||
* $backend_host: backend host used to fulfill the
|
|
||||||
request. "-" if backend host is not available.
|
|
||||||
* $backend_port: backend port used to fulfill the
|
|
||||||
request. "-" if backend host is not available.
|
|
||||||
|
|
||||||
The variable can be enclosed by "{" and "}" for
|
The variable can be enclosed by "{" and "}" for
|
||||||
disambiguation (e.g., ${remote_addr}).
|
disambiguation (e.g., ${remote_addr}).
|
||||||
@@ -1110,32 +967,10 @@ HTTP
|
|||||||
Set file path to custom error page served when nghttpx
|
Set file path to custom error page served when nghttpx
|
||||||
originally generates HTTP error status code <CODE>.
|
originally generates HTTP error status code <CODE>.
|
||||||
<CODE> must be greater than or equal to 400, and at most
|
<CODE> must be greater than or equal to 400, and at most
|
||||||
599. If "\*" is used instead of <CODE>, it matches all
|
599. If "*" is used instead of <CODE>, it matches all
|
||||||
HTTP status code. If error status code comes from
|
HTTP status code. If error status code comes from
|
||||||
backend server, the custom error pages are not used.
|
backend server, the custom error pages are not used.
|
||||||
|
|
||||||
.. option:: --server-name=<NAME>
|
|
||||||
|
|
||||||
Change server response header field value to <NAME>.
|
|
||||||
|
|
||||||
Default: ``nghttpx nghttp2/1.16.1``
|
|
||||||
|
|
||||||
.. option:: --no-server-rewrite
|
|
||||||
|
|
||||||
Don't rewrite server header field in default mode. When
|
|
||||||
:option:`--http2-proxy` is used, these headers will not be altered
|
|
||||||
regardless of this option.
|
|
||||||
|
|
||||||
|
|
||||||
API
|
|
||||||
~~~
|
|
||||||
|
|
||||||
.. option:: --api-max-request-body=<SIZE>
|
|
||||||
|
|
||||||
Set the maximum size of request body for API request.
|
|
||||||
|
|
||||||
Default: ``16K``
|
|
||||||
|
|
||||||
|
|
||||||
Debug
|
Debug
|
||||||
~~~~~
|
~~~~~
|
||||||
@@ -1274,9 +1109,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.
|
||||||
|
|
||||||
@@ -1284,11 +1116,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::
|
||||||
|
|
||||||
@@ -1317,7 +1145,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
|
||||||
@@ -1434,24 +1262,6 @@ 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
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@@ -1534,10 +1344,6 @@ respectively.
|
|||||||
|
|
||||||
Return true if TLS is used on the connection.
|
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
|
||||||
|
|
||||||
Object to represent request from client. The modification to
|
Object to represent request from client. The modification to
|
||||||
@@ -1716,62 +1522,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 while non numeric
|
|
||||||
hostname is allowed in command-line or configuration file is read
|
|
||||||
using :option:`--conf`.
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@@ -49,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.
|
||||||
|
|
||||||
@@ -59,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::
|
||||||
|
|
||||||
@@ -92,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
|
||||||
@@ -209,24 +202,6 @@ 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
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@@ -309,10 +284,6 @@ respectively.
|
|||||||
|
|
||||||
Return true if TLS is used on the connection.
|
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
|
||||||
|
|
||||||
Object to represent request from client. The modification to
|
Object to represent request from client. The modification to
|
||||||
@@ -491,62 +462,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 while non numeric
|
|
||||||
hostname is allowed in command-line or configuration file is read
|
|
||||||
using :option:`--conf`.
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ functions, and it also interacts with it via many API function calls.
|
|||||||
An application can create as many :type:`nghttp2_session` object as it
|
An application can create as many :type:`nghttp2_session` object as it
|
||||||
wants. But single :type:`nghttp2_session` object must be used by a
|
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
|
single thread at the same time. This is not so hard to enforce since
|
||||||
most event-based architecture applications use is single thread per
|
most event-based architecture applicatons use is single thread per
|
||||||
core, and handling one connection I/O is done by single thread.
|
core, and handling one connection I/O is done by single thread.
|
||||||
|
|
||||||
To feed input to :type:`nghttp2_session` object, one can use
|
To feed input to :type:`nghttp2_session` object, one can use
|
||||||
@@ -177,55 +177,6 @@ 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
|
Implement user defined HTTP/2 non-critical extensions
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -17,16 +17,19 @@ 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 and libev should be built
|
The dependent libraries, such as OpenSSL and libev should be built
|
||||||
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
|
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
|
||||||
@@ -42,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
|
||||||
|
|
||||||
@@ -132,24 +133,24 @@ To configure spdylay, use the following script:
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
if [ -z "$ANDROID_HOME" ]; then
|
if [ -z "$ANDROID_HOME" ]; then
|
||||||
echo 'No $ANDROID_HOME specified.'
|
echo 'No $ANDROID_HOME specified.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$ANDROID_HOME/usr/local
|
PREFIX=$ANDROID_HOME/usr/local
|
||||||
TOOLCHAIN=$ANDROID_HOME/toolchain
|
TOOLCHAIN=$ANDROID_HOME/toolchain
|
||||||
PATH=$TOOLCHAIN/bin:$PATH
|
PATH=$TOOLCHAIN/bin:$PATH
|
||||||
|
|
||||||
./configure \
|
./configure \
|
||||||
--disable-shared \
|
--disable-shared \
|
||||||
--host=arm-linux-androideabi \
|
--host=arm-linux-androideabi \
|
||||||
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
||||||
--prefix=$PREFIX \
|
--prefix=$PREFIX \
|
||||||
--without-libxml2 \
|
--without-libxml2 \
|
||||||
--disable-src \
|
--disable-src \
|
||||||
--disable-examples \
|
--disable-examples \
|
||||||
CPPFLAGS="-I$PREFIX/include" \
|
CPPFLAGS="-I$PREFIX/include" \
|
||||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||||
LDFLAGS="-L$PREFIX/lib"
|
LDFLAGS="-L$PREFIX/lib"
|
||||||
|
|
||||||
And run ``make install`` to build and install.
|
And run ``make install`` to build and install.
|
||||||
|
|
||||||
@@ -158,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.
|
||||||
|
|||||||
@@ -48,16 +48,12 @@ explicitly.
|
|||||||
The backend is supposed to be Web server. For example, to make
|
The backend is supposed to be Web server. For example, to make
|
||||||
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
|
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
|
||||||
backend Web server is configured to listen to HTTP request at port
|
backend Web server is configured to listen to HTTP request at port
|
||||||
8080 in the same host, run nghttpx command-line like this:
|
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/
|
||||||
|
|
||||||
@@ -93,9 +89,7 @@ connection, use :option:`--backend` option, and specify ``h2`` in
|
|||||||
For example, to make nghttpx listen to encrypted HTTP/2 requests at
|
For example, to make nghttpx listen to encrypted HTTP/2 requests at
|
||||||
port 8443, and a backend HTTP proxy server is configured to listen to
|
port 8443, and a backend HTTP proxy server is configured to listen to
|
||||||
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
|
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
|
||||||
like this:
|
like this::
|
||||||
|
|
||||||
.. code-block:: text
|
|
||||||
|
|
||||||
$ 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
|
||||||
|
|
||||||
@@ -124,17 +118,13 @@ to proxy.pac file, something like this:
|
|||||||
|
|
||||||
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
|
||||||
@@ -144,11 +134,6 @@ Consult Traffic server `documentation
|
|||||||
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
|
|
||||||
------------
|
|
||||||
|
|
||||||
ALPN support requires OpenSSL >= 1.0.2.
|
|
||||||
|
|
||||||
Disable frontend SSL/TLS
|
Disable frontend SSL/TLS
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
@@ -167,9 +152,9 @@ Enable SSL/TLS on memcached connection
|
|||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
By default, memcached connection is not encrypted. To enable
|
By default, memcached connection is not encrypted. To enable
|
||||||
encryption, use ``tls`` keyword in
|
encryption, use :option:`--tls-ticket-key-memcached-tls` for TLS
|
||||||
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
|
ticket key, and use :option:`--tls-session-cache-memcached-tls` for
|
||||||
:option:`--tls-session-cache-memcached` for TLS session cache.
|
TLS session cache.
|
||||||
|
|
||||||
Specifying additional server certificates
|
Specifying additional server certificates
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
@@ -211,17 +196,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,9 +221,6 @@ 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
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -457,12 +457,11 @@ 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)};
|
|
||||||
|
|
||||||
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
|
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
|
||||||
sizeof(nva) / sizeof(nva[0]), NULL, req);
|
sizeof(nva) / sizeof(nva[0]), NULL, req);
|
||||||
@@ -563,11 +562,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 +691,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();
|
||||||
|
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ 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 int32_t 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 '''\
|
||||||
|
|||||||
@@ -132,23 +132,6 @@ OPTIONS = [
|
|||||||
"no-kqueue",
|
"no-kqueue",
|
||||||
"frontend-http2-settings-timeout",
|
"frontend-http2-settings-timeout",
|
||||||
"backend-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",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
@@ -167,8 +150,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)
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,197 +793,3 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %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"
|
||||||
@@ -1844,190 +1843,3 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %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"
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -66,36 +66,27 @@ 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(src_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{}
|
args := []string{}
|
||||||
@@ -147,7 +138,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
|||||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
|
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
|
||||||
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
||||||
|
|
||||||
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
|
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)
|
||||||
|
|
||||||
st := &serverTester{
|
st := &serverTester{
|
||||||
cmd: exec.Command(serverBin, args...),
|
cmd: exec.Command(serverBin, args...),
|
||||||
@@ -169,8 +160,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 {
|
||||||
@@ -181,7 +170,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)
|
||||||
@@ -192,6 +181,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 {
|
||||||
@@ -297,7 +287,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
|
||||||
@@ -381,9 +370,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)
|
||||||
@@ -472,7 +460,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{
|
||||||
@@ -486,13 +474,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
|
||||||
@@ -605,7 +589,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(),
|
||||||
})
|
})
|
||||||
@@ -615,7 +599,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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -762,8 +746,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"`
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ set(NGHTTP2_SOURCES
|
|||||||
nghttp2_mem.c
|
nghttp2_mem.c
|
||||||
nghttp2_http.c
|
nghttp2_http.c
|
||||||
nghttp2_rcbuf.c
|
nghttp2_rcbuf.c
|
||||||
nghttp2_debug.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Public shared library
|
# Public shared library
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
|||||||
nghttp2_callbacks.c \
|
nghttp2_callbacks.c \
|
||||||
nghttp2_mem.c \
|
nghttp2_mem.c \
|
||||||
nghttp2_http.c \
|
nghttp2_http.c \
|
||||||
nghttp2_rcbuf.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 \
|
||||||
@@ -64,8 +63,7 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
|||||||
nghttp2_callbacks.h \
|
nghttp2_callbacks.h \
|
||||||
nghttp2_mem.h \
|
nghttp2_mem.h \
|
||||||
nghttp2_http.h \
|
nghttp2_http.h \
|
||||||
nghttp2_rcbuf.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 \
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ extern "C" {
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#include <nghttp2/nghttp2ver.h>
|
#include <nghttp2/nghttp2ver.h>
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* @macro
|
* @macro
|
||||||
*
|
*
|
||||||
* The serialized form of ALPN protocol identifier this library
|
* The seriazlied form of ALPN protocol identifier this library
|
||||||
* supports. Notice that first byte is the length of following
|
* supports. Notice that first byte is the length of following
|
||||||
* protocol identifier. This is the same wire format of `TLS ALPN
|
* protocol identifier. This is the same wire format of `TLS ALPN
|
||||||
* extension <https://tools.ietf.org/html/rfc7301>`_. This is useful
|
* extension <https://tools.ietf.org/html/rfc7301>`_. This is useful
|
||||||
@@ -669,10 +668,6 @@ typedef enum {
|
|||||||
/**
|
/**
|
||||||
* @macro
|
* @macro
|
||||||
*
|
*
|
||||||
* .. warning::
|
|
||||||
*
|
|
||||||
* Deprecated. The initial max concurrent streams is 0xffffffffu.
|
|
||||||
*
|
|
||||||
* Default maximum number of incoming concurrent streams. Use
|
* Default maximum number of incoming concurrent streams. Use
|
||||||
* `nghttp2_submit_settings()` with
|
* `nghttp2_submit_settings()` with
|
||||||
* :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
|
* :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
|
||||||
@@ -861,13 +856,8 @@ typedef enum {
|
|||||||
* achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
|
* achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
|
||||||
* any data in this invocation. The library removes DATA frame from
|
* any data in this invocation. The library removes DATA frame from
|
||||||
* the outgoing queue temporarily. To move back deferred DATA frame
|
* the outgoing queue temporarily. To move back deferred DATA frame
|
||||||
* to outgoing queue, call `nghttp2_session_resume_data()`.
|
* to outgoing queue, call `nghttp2_session_resume_data()`. In case
|
||||||
*
|
* of error, there are 2 choices. Returning
|
||||||
* If the application just wants to return from
|
|
||||||
* `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
|
|
||||||
* sending anything, return :enum:`NGHTTP2_ERR_PAUSE`.
|
|
||||||
*
|
|
||||||
* In case of error, there are 2 choices. Returning
|
|
||||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
|
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
|
||||||
* by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. If a
|
* by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. If a
|
||||||
* different error code is desirable, use
|
* different error code is desirable, use
|
||||||
@@ -1464,19 +1454,9 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
|
|||||||
* `nghttp2_session_server_new()`.
|
* `nghttp2_session_server_new()`.
|
||||||
*
|
*
|
||||||
* The implementation of this function must return 0 if it succeeds.
|
* The implementation of this function must return 0 if it succeeds.
|
||||||
* It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the
|
* If nonzero is returned, it is treated as fatal error and
|
||||||
* transmission of the given frame.
|
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
|
||||||
*
|
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
|
||||||
* If there is a fatal error while executing this callback, the
|
|
||||||
* implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
|
|
||||||
* which makes `nghttp2_session_send()` and
|
|
||||||
* `nghttp2_session_mem_send()` functions immediately return
|
|
||||||
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
|
|
||||||
*
|
|
||||||
* If the other value is returned, it is treated as if
|
|
||||||
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. But the
|
|
||||||
* implementation should not rely on this since the library may define
|
|
||||||
* new return value to extend its capability.
|
|
||||||
*
|
*
|
||||||
* To set this callback to :type:`nghttp2_session_callbacks`, use
|
* To set this callback to :type:`nghttp2_session_callbacks`, use
|
||||||
* `nghttp2_session_callbacks_set_before_frame_send_callback()`.
|
* `nghttp2_session_callbacks_set_before_frame_send_callback()`.
|
||||||
@@ -1727,69 +1707,6 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
|
|||||||
nghttp2_rcbuf *value, uint8_t flags,
|
nghttp2_rcbuf *value, uint8_t flags,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
||||||
/**
|
|
||||||
* @functypedef
|
|
||||||
*
|
|
||||||
* Callback function invoked when a invalid header name/value pair is
|
|
||||||
* received for the |frame|.
|
|
||||||
*
|
|
||||||
* The parameter and behaviour are similar to
|
|
||||||
* :type:`nghttp2_on_header_callback`. The difference is that this
|
|
||||||
* callback is only invoked when a invalid header name/value pair is
|
|
||||||
* received which is silently ignored if this callback is not set.
|
|
||||||
* Only invalid regular header field are passed to this callback. In
|
|
||||||
* other words, invalid pseudo header field is not passed to this
|
|
||||||
* callback. Also header fields which includes upper cased latter are
|
|
||||||
* also treated as error without passing them to this callback.
|
|
||||||
*
|
|
||||||
* This callback is only considered if HTTP messaging validation is
|
|
||||||
* turned on (which is on by default, see
|
|
||||||
* `nghttp2_option_set_no_http_messaging()`).
|
|
||||||
*
|
|
||||||
* With this callback, application inspects the incoming invalid
|
|
||||||
* field, and it also can reset stream from this callback by returning
|
|
||||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
|
|
||||||
* error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
|
|
||||||
* code, call `nghttp2_submit_rst_stream()` with the error code of
|
|
||||||
* choice in addition to returning
|
|
||||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
|
|
||||||
*/
|
|
||||||
typedef int (*nghttp2_on_invalid_header_callback)(
|
|
||||||
nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name,
|
|
||||||
size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags,
|
|
||||||
void *user_data);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @functypedef
|
|
||||||
*
|
|
||||||
* Callback function invoked when a invalid header name/value pair is
|
|
||||||
* received for the |frame|.
|
|
||||||
*
|
|
||||||
* The parameter and behaviour are similar to
|
|
||||||
* :type:`nghttp2_on_header_callback2`. The difference is that this
|
|
||||||
* callback is only invoked when a invalid header name/value pair is
|
|
||||||
* received which is silently ignored if this callback is not set.
|
|
||||||
* Only invalid regular header field are passed to this callback. In
|
|
||||||
* other words, invalid pseudo header field is not passed to this
|
|
||||||
* callback. Also header fields which includes upper cased latter are
|
|
||||||
* also treated as error without passing them to this callback.
|
|
||||||
*
|
|
||||||
* This callback is only considered if HTTP messaging validation is
|
|
||||||
* turned on (which is on by default, see
|
|
||||||
* `nghttp2_option_set_no_http_messaging()`).
|
|
||||||
*
|
|
||||||
* With this callback, application inspects the incoming invalid
|
|
||||||
* field, and it also can reset stream from this callback by returning
|
|
||||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
|
|
||||||
* error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
|
|
||||||
* code, call `nghttp2_submit_rst_stream()` with the error code of
|
|
||||||
* choice in addition to returning
|
|
||||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
|
|
||||||
*/
|
|
||||||
typedef int (*nghttp2_on_invalid_header_callback2)(
|
|
||||||
nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
|
|
||||||
nghttp2_rcbuf *value, uint8_t flags, void *user_data);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @functypedef
|
* @functypedef
|
||||||
*
|
*
|
||||||
@@ -2148,29 +2065,6 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
|
|||||||
nghttp2_session_callbacks *cbs,
|
nghttp2_session_callbacks *cbs,
|
||||||
nghttp2_on_header_callback2 on_header_callback2);
|
nghttp2_on_header_callback2 on_header_callback2);
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Sets callback function invoked when a invalid header name/value
|
|
||||||
* pair is received. If both
|
|
||||||
* `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
|
|
||||||
* `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
|
|
||||||
* used to set callbacks, the latter takes the precedence.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_on_invalid_header_callback on_invalid_header_callback);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Sets callback function invoked when a invalid header name/value
|
|
||||||
* pair is received.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
|
||||||
nghttp2_session_callbacks *cbs,
|
|
||||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
@@ -2518,34 +2412,6 @@ nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
|
|||||||
NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
|
NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
|
||||||
int val);
|
int val);
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* This option sets the maximum length of header block (a set of
|
|
||||||
* header fields per one HEADERS frame) to send. The length of a
|
|
||||||
* given set of header fields is calculated using
|
|
||||||
* `nghttp2_hd_deflate_bound()`. The default value is 64KiB. If
|
|
||||||
* application attempts to send header fields larger than this limit,
|
|
||||||
* the transmission of the frame fails with error code
|
|
||||||
* :enum:`NGHTTP2_ERR_FRAME_SIZE_ERROR`.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN void
|
|
||||||
nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
|
|
||||||
size_t val);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* This option sets the maximum dynamic table size for deflating
|
|
||||||
* header fields. The default value is 4KiB. In HTTP/2, receiver of
|
|
||||||
* deflated header block can specify maximum dynamic table size. The
|
|
||||||
* actual maximum size is the minimum of the size receiver specified
|
|
||||||
* and this option value.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN void
|
|
||||||
nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
|
|
||||||
size_t val);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
@@ -2738,20 +2604,14 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
|
|||||||
*
|
*
|
||||||
* 6. :type:`nghttp2_before_frame_send_callback` is invoked.
|
* 6. :type:`nghttp2_before_frame_send_callback` is invoked.
|
||||||
*
|
*
|
||||||
* 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from
|
* 7. :type:`nghttp2_send_callback` is invoked one or more times to
|
||||||
* :type:`nghttp2_before_frame_send_callback`, the current frame
|
|
||||||
* transmission is canceled, and
|
|
||||||
* :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort
|
|
||||||
* the following steps.
|
|
||||||
*
|
|
||||||
* 8. :type:`nghttp2_send_callback` is invoked one or more times to
|
|
||||||
* send the frame.
|
* send the frame.
|
||||||
*
|
*
|
||||||
* 9. :type:`nghttp2_on_frame_send_callback` is invoked.
|
* 8. :type:`nghttp2_on_frame_send_callback` is invoked.
|
||||||
*
|
*
|
||||||
* 10. If the transmission of the frame triggers closure of the
|
* 9. If the transmission of the frame triggers closure of the stream,
|
||||||
* stream, the stream is closed and
|
* the stream is closed and
|
||||||
* :type:`nghttp2_on_stream_close_callback` is invoked.
|
* :type:`nghttp2_on_stream_close_callback` is invoked.
|
||||||
*
|
*
|
||||||
* 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:
|
||||||
@@ -2802,8 +2662,8 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
|
|||||||
* buffer up small chunks of data as necessary to avoid this
|
* buffer up small chunks of data as necessary to avoid this
|
||||||
* situation.
|
* situation.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
|
NGHTTP2_EXTERN ssize_t
|
||||||
const uint8_t **data_ptr);
|
nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -2843,13 +2703,12 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
|
|||||||
* taken. If the frame is either HEADERS or PUSH_PROMISE,
|
* taken. If the frame is either HEADERS or PUSH_PROMISE,
|
||||||
* :type:`nghttp2_on_begin_headers_callback` is invoked. Then
|
* :type:`nghttp2_on_begin_headers_callback` is invoked. Then
|
||||||
* :type:`nghttp2_on_header_callback` is invoked for each header
|
* :type:`nghttp2_on_header_callback` is invoked for each header
|
||||||
* name/value pair. For invalid header field,
|
* name/value pair. After all name/value pairs are emitted
|
||||||
* :type:`nghttp2_on_invalid_header_callback` is called. After
|
* successfully, :type:`nghttp2_on_frame_recv_callback` is
|
||||||
* all name/value pairs are emitted successfully,
|
* invoked. For other frames,
|
||||||
* :type:`nghttp2_on_frame_recv_callback` is invoked. For other
|
* :type:`nghttp2_on_frame_recv_callback` is invoked. If the
|
||||||
* frames, :type:`nghttp2_on_frame_recv_callback` is invoked.
|
* reception of the frame triggers the closure of the stream,
|
||||||
* If the reception of the frame triggers the closure of the
|
* :type:`nghttp2_on_stream_close_callback` is invoked.
|
||||||
* stream, :type:`nghttp2_on_stream_close_callback` is invoked.
|
|
||||||
*
|
*
|
||||||
* 3. If the received frame is unpacked but is interpreted as
|
* 3. If the received frame is unpacked but is interpreted as
|
||||||
* invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is
|
* invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is
|
||||||
@@ -3018,8 +2877,9 @@ nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
|
|||||||
*
|
*
|
||||||
* This function returns -1 if it fails.
|
* This function returns -1 if it fails.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length(
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session *session, int32_t stream_id);
|
nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session,
|
||||||
|
int32_t stream_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -3029,32 +2889,11 @@ NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length(
|
|||||||
* `nghttp2_submit_window_update()`. This function takes into account
|
* `nghttp2_submit_window_update()`. This function takes into account
|
||||||
* that and returns effective window size.
|
* that and returns effective window size.
|
||||||
*
|
*
|
||||||
* This function does not take into account the amount of received
|
|
||||||
* data from the remote endpoint. Use
|
|
||||||
* `nghttp2_session_get_stream_local_window_size()` to know the amount
|
|
||||||
* of data the remote endpoint can send without receiving stream level
|
|
||||||
* WINDOW_UPDATE frame. Note that each stream is still subject to the
|
|
||||||
* connection level flow control.
|
|
||||||
*
|
|
||||||
* This function returns -1 if it fails.
|
* This function returns -1 if it fails.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size(
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session *session, int32_t stream_id);
|
nghttp2_session_get_stream_effective_local_window_size(nghttp2_session *session,
|
||||||
|
int32_t stream_id);
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Returns the amount of flow-controlled payload (e.g., DATA) that the
|
|
||||||
* remote endpoint can send without receiving stream level
|
|
||||||
* WINDOW_UPDATE frame. It is also subject to the connection level
|
|
||||||
* flow control. So the actual amount of data to send is
|
|
||||||
* min(`nghttp2_session_get_stream_local_window_size()`,
|
|
||||||
* `nghttp2_session_get_local_window_size()`).
|
|
||||||
*
|
|
||||||
* This function returns -1 if it fails.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size(
|
|
||||||
nghttp2_session *session, int32_t stream_id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -3081,32 +2920,11 @@ nghttp2_session_get_effective_recv_data_length(nghttp2_session *session);
|
|||||||
* `nghttp2_submit_window_update()`. This function takes into account
|
* `nghttp2_submit_window_update()`. This function takes into account
|
||||||
* that and returns effective window size.
|
* that and returns effective window size.
|
||||||
*
|
*
|
||||||
* This function does not take into account the amount of received
|
|
||||||
* data from the remote endpoint. Use
|
|
||||||
* `nghttp2_session_get_local_window_size()` to know the amount of
|
|
||||||
* data the remote endpoint can send without receiving
|
|
||||||
* connection-level WINDOW_UPDATE frame. Note that each stream is
|
|
||||||
* still subject to the stream level flow control.
|
|
||||||
*
|
|
||||||
* This function returns -1 if it fails.
|
* This function returns -1 if it fails.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
|
nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Returns the amount of flow-controlled payload (e.g., DATA) that the
|
|
||||||
* remote endpoint can send without receiving connection level
|
|
||||||
* WINDOW_UPDATE frame. Note that each stream is still subject to the
|
|
||||||
* stream level flow control (see
|
|
||||||
* `nghttp2_session_get_stream_local_window_size()`).
|
|
||||||
*
|
|
||||||
* This function returns -1 if it fails.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN int32_t
|
|
||||||
nghttp2_session_get_local_window_size(nghttp2_session *session);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
@@ -3121,8 +2939,9 @@ nghttp2_session_get_local_window_size(nghttp2_session *session);
|
|||||||
*
|
*
|
||||||
* This function returns -1 if it fails.
|
* This function returns -1 if it fails.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size(
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session *session, int32_t stream_id);
|
nghttp2_session_get_stream_remote_window_size(nghttp2_session *session,
|
||||||
|
int32_t stream_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -3154,24 +2973,6 @@ NGHTTP2_EXTERN int
|
|||||||
nghttp2_session_get_stream_remote_close(nghttp2_session *session,
|
nghttp2_session_get_stream_remote_close(nghttp2_session *session,
|
||||||
int32_t stream_id);
|
int32_t stream_id);
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Returns the current dynamic table size of HPACK inflater, including
|
|
||||||
* the overhead 32 bytes per entry described in RFC 7541.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN size_t
|
|
||||||
nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Returns the current dynamic table size of HPACK deflater including
|
|
||||||
* the overhead 32 bytes per entry described in RFC 7541.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN size_t
|
|
||||||
nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
@@ -3275,18 +3076,9 @@ NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session);
|
|||||||
* The |id| must be one of values defined in
|
* The |id| must be one of values defined in
|
||||||
* :enum:`nghttp2_settings_id`.
|
* :enum:`nghttp2_settings_id`.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings(
|
NGHTTP2_EXTERN uint32_t
|
||||||
nghttp2_session *session, nghttp2_settings_id id);
|
nghttp2_session_get_remote_settings(nghttp2_session *session,
|
||||||
|
nghttp2_settings_id id);
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Returns the value of SETTINGS |id| of local endpoint acknowledged
|
|
||||||
* by the remote endpoint. The |id| must be one of the values defined
|
|
||||||
* in :enum:`nghttp2_settings_id`.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
|
|
||||||
nghttp2_session *session, nghttp2_settings_id id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -3581,8 +3373,9 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
|
|||||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||||
* The provided |buflen| size is too small to hold the output.
|
* The provided |buflen| size is too small to hold the output.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
|
NGHTTP2_EXTERN ssize_t
|
||||||
uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
|
nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
|
||||||
|
const nghttp2_settings_entry *iv, size_t niv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -3707,10 +3500,12 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
|
|||||||
* frame.
|
* frame.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_submit_request(
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session *session, const nghttp2_priority_spec *pri_spec,
|
nghttp2_submit_request(nghttp2_session *session,
|
||||||
const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd,
|
const nghttp2_priority_spec *pri_spec,
|
||||||
void *stream_user_data);
|
const nghttp2_nv *nva, size_t nvlen,
|
||||||
|
const nghttp2_data_provider *data_prd,
|
||||||
|
void *stream_user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -3788,8 +3583,8 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
|
|||||||
*
|
*
|
||||||
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
|
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
|
||||||
* |nvlen| elements. The application is responsible not to include
|
* |nvlen| elements. The application is responsible not to include
|
||||||
* pseudo-header fields (header field whose name starts with ":") in
|
* required pseudo-header fields (header field whose name starts with
|
||||||
* |nva|.
|
* ":") in |nva|.
|
||||||
*
|
*
|
||||||
* This function creates copies of all name/value pairs in |nva|. It
|
* This function creates copies of all name/value pairs in |nva|. It
|
||||||
* also lower-cases all names in |nva|. The order of elements in
|
* also lower-cases all names in |nva|. The order of elements in
|
||||||
@@ -3804,20 +3599,20 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
|
|||||||
* :type:`nghttp2_on_frame_not_send_callback` is called.
|
* :type:`nghttp2_on_frame_not_send_callback` is called.
|
||||||
*
|
*
|
||||||
* For server, trailer fields must follow response HEADERS or response
|
* For server, trailer fields must follow response HEADERS or response
|
||||||
* DATA without END_STREAM flat set. The library does not enforce
|
* DATA with END_STREAM flag set. The library does not enforce this
|
||||||
* this requirement, and applications should do this for themselves.
|
* requirement, and applications should do this for themselves. If
|
||||||
* If `nghttp2_submit_trailer()` is called before any response HEADERS
|
* `nghttp2_submit_trailer()` is called before any response HEADERS
|
||||||
* submission (usually by `nghttp2_submit_response()`), the content of
|
* submission (usually by `nghttp2_submit_response()`), the content of
|
||||||
* |nva| will be sent as response headers, which will result in error.
|
* |nva| will be sent as response headers, which will result in error.
|
||||||
*
|
*
|
||||||
* This function has the same effect with `nghttp2_submit_headers()`,
|
* This function has the same effect with `nghttp2_submit_headers()`,
|
||||||
* with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
|
* with flags = :enum:`NGHTTP2_FLAG_END_HEADERS` and both pri_spec and
|
||||||
* stream_user_data to NULL.
|
* stream_user_data to NULL.
|
||||||
*
|
*
|
||||||
* To submit trailer fields after `nghttp2_submit_response()` is
|
* To submit trailer fields after `nghttp2_submit_response()` is
|
||||||
* called, the application has to specify
|
* called, the application has to specify
|
||||||
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
|
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`. In
|
||||||
* Inside of :type:`nghttp2_data_source_read_callback`, when setting
|
* side :type:`nghttp2_data_source_read_callback`, when setting
|
||||||
* :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
|
* :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
|
||||||
* :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`. After that, the
|
* :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`. After that, the
|
||||||
* application can send trailer fields using
|
* application can send trailer fields using
|
||||||
@@ -3925,10 +3720,11 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
|
|||||||
* frame.
|
* frame.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session *session, uint8_t flags, int32_t stream_id,
|
nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
|
||||||
const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen,
|
int32_t stream_id, const nghttp2_priority_spec *pri_spec,
|
||||||
void *stream_user_data);
|
const nghttp2_nv *nva, size_t nvlen,
|
||||||
|
void *stream_user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -4136,9 +3932,10 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
|
|||||||
* is called for this frame.
|
* is called for this frame.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_session *session, uint8_t flags, int32_t stream_id,
|
nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
|
||||||
const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data);
|
int32_t stream_id, const nghttp2_nv *nva,
|
||||||
|
size_t nvlen, void *promised_stream_user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -4274,17 +4071,14 @@ nghttp2_session_check_server_session(nghttp2_session *session);
|
|||||||
* that value as window_size_increment is queued. If the
|
* that value as window_size_increment is queued. If the
|
||||||
* |window_size_increment| is larger than the received bytes from the
|
* |window_size_increment| is larger than the received bytes from the
|
||||||
* remote endpoint, the local window size is increased by that
|
* remote endpoint, the local window size is increased by that
|
||||||
* difference. If the sole purpose is to increase the local window
|
* difference.
|
||||||
* size, consider to use `nghttp2_session_set_local_window_size()`.
|
|
||||||
*
|
*
|
||||||
* If the |window_size_increment| is negative, the local window size
|
* If the |window_size_increment| is negative, the local window size
|
||||||
* is decreased by -|window_size_increment|. If automatic
|
* is decreased by -|window_size_increment|. If automatic
|
||||||
* WINDOW_UPDATE is enabled
|
* WINDOW_UPDATE is enabled
|
||||||
* (`nghttp2_option_set_no_auto_window_update()`), and the library
|
* (`nghttp2_option_set_no_auto_window_update()`), and the library
|
||||||
* decided that the WINDOW_UPDATE should be submitted, then
|
* decided that the WINDOW_UPDATE should be submitted, then
|
||||||
* WINDOW_UPDATE is queued with the current received bytes count. If
|
* WINDOW_UPDATE is queued with the current received bytes count.
|
||||||
* the sole purpose is to decrease the local window size, consider to
|
|
||||||
* use `nghttp2_session_set_local_window_size()`.
|
|
||||||
*
|
*
|
||||||
* If the |window_size_increment| is 0, the function does nothing and
|
* If the |window_size_increment| is 0, the function does nothing and
|
||||||
* returns 0.
|
* returns 0.
|
||||||
@@ -4302,44 +4096,6 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
|
|||||||
int32_t stream_id,
|
int32_t stream_id,
|
||||||
int32_t window_size_increment);
|
int32_t window_size_increment);
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Set local window size (local endpoints's window size) to the given
|
|
||||||
* |window_size| for the given stream denoted by |stream_id|. To
|
|
||||||
* change connection level window size, specify 0 to |stream_id|. To
|
|
||||||
* increase window size, this function may submit WINDOW_UPDATE frame
|
|
||||||
* to transmission queue.
|
|
||||||
*
|
|
||||||
* The |flags| is currently ignored and should be
|
|
||||||
* :enum:`NGHTTP2_FLAG_NONE`.
|
|
||||||
*
|
|
||||||
* This sounds similar to `nghttp2_submit_window_update()`, but there
|
|
||||||
* are 2 differences. The first difference is that this function
|
|
||||||
* takes the absolute value of window size to set, rather than the
|
|
||||||
* delta. To change the window size, this may be easier to use since
|
|
||||||
* the application just declares the intended window size, rather than
|
|
||||||
* calculating delta. The second difference is that
|
|
||||||
* `nghttp2_submit_window_update()` affects the received bytes count
|
|
||||||
* which has not acked yet. By the specification of
|
|
||||||
* `nghttp2_submit_window_update()`, to strictly increase the local
|
|
||||||
* window size, we have to submit delta including all received bytes
|
|
||||||
* count, which might not be desirable in some cases. On the other
|
|
||||||
* hand, this function does not affect the received bytes count. It
|
|
||||||
* just sets the local window size to the given value.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
|
|
||||||
* The |stream_id| is negative.
|
|
||||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
|
||||||
* Out of memory.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN int
|
|
||||||
nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
|
|
||||||
int32_t stream_id, int32_t window_size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
@@ -4586,7 +4342,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
|||||||
*
|
*
|
||||||
* Initializes |*deflater_ptr| for deflating name/values pairs.
|
* Initializes |*deflater_ptr| for deflating name/values pairs.
|
||||||
*
|
*
|
||||||
* The |max_deflate_dynamic_table_size| is the upper bound of header
|
* The |deflate_hd_table_bufsize_max| is the upper bound of header
|
||||||
* table size the deflater will use.
|
* table size the deflater will use.
|
||||||
*
|
*
|
||||||
* If this function fails, |*deflater_ptr| is left untouched.
|
* If this function fails, |*deflater_ptr| is left untouched.
|
||||||
@@ -4597,9 +4353,8 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
|||||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int
|
NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||||
nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
size_t deflate_hd_table_bufsize_max);
|
||||||
size_t max_deflate_dynamic_table_size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -4616,10 +4371,9 @@ nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
|||||||
* The library code does not refer to |mem| pointer after this
|
* The library code does not refer to |mem| pointer after this
|
||||||
* function returns, so the application can safely free it.
|
* function returns, so the application can safely free it.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int
|
NGHTTP2_EXTERN int nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
|
||||||
nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
|
size_t deflate_hd_table_bufsize_max,
|
||||||
size_t max_deflate_dynamic_table_size,
|
nghttp2_mem *mem);
|
||||||
nghttp2_mem *mem);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -4632,18 +4386,18 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
|||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
* Changes header table size of the |deflater| to
|
* Changes header table size of the |deflater| to
|
||||||
* |settings_max_dynamic_table_size| bytes. This may trigger eviction
|
* |settings_hd_table_bufsize_max| bytes. This may trigger eviction
|
||||||
* in the dynamic table.
|
* in the dynamic table.
|
||||||
*
|
*
|
||||||
* The |settings_max_dynamic_table_size| should be the value received
|
* The |settings_hd_table_bufsize_max| should be the value received in
|
||||||
* in SETTINGS_HEADER_TABLE_SIZE.
|
* SETTINGS_HEADER_TABLE_SIZE.
|
||||||
*
|
*
|
||||||
* The deflater never uses more memory than
|
* The deflater never uses more memory than
|
||||||
* ``max_deflate_dynamic_table_size`` bytes specified in
|
* ``deflate_hd_table_bufsize_max`` bytes specified in
|
||||||
* `nghttp2_hd_deflate_new()`. Therefore, if
|
* `nghttp2_hd_deflate_new()`. Therefore, if
|
||||||
* |settings_max_dynamic_table_size| >
|
* |settings_hd_table_bufsize_max| > ``deflate_hd_table_bufsize_max``,
|
||||||
* ``max_deflate_dynamic_table_size``, resulting maximum table size
|
* resulting maximum table size becomes
|
||||||
* becomes ``max_deflate_dynamic_table_size``.
|
* ``deflate_hd_table_bufsize_max``.
|
||||||
*
|
*
|
||||||
* 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:
|
||||||
@@ -4653,7 +4407,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
|||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int
|
NGHTTP2_EXTERN int
|
||||||
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||||
size_t settings_max_dynamic_table_size);
|
size_t settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -4682,43 +4436,9 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
|||||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||||
* The provided |buflen| size is too small to hold the output.
|
* The provided |buflen| size is too small to hold the output.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
NGHTTP2_EXTERN ssize_t
|
||||||
uint8_t *buf, size_t buflen,
|
nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
|
||||||
const nghttp2_nv *nva,
|
size_t buflen, const nghttp2_nv *nva, size_t nvlen);
|
||||||
size_t nvlen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
|
||||||
* the |veclen| size of buf vector |vec|. The each size of buffer
|
|
||||||
* must be set in len field of :type:`nghttp2_vec`. If and only if
|
|
||||||
* one chunk is filled up completely, next chunk will be used. If
|
|
||||||
* |vec| is not large enough to store the deflated header block, this
|
|
||||||
* function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
|
|
||||||
* should use `nghttp2_hd_deflate_bound()` to know the upper bound of
|
|
||||||
* buffer size required to deflate given header name/value pairs.
|
|
||||||
*
|
|
||||||
* Once this function fails, subsequent call of this function always
|
|
||||||
* returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
|
|
||||||
*
|
|
||||||
* After this function returns, it is safe to delete the |nva|.
|
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
|
||||||
* Out of memory.
|
|
||||||
* :enum:`NGHTTP2_ERR_HEADER_COMP`
|
|
||||||
* Deflation process has failed.
|
|
||||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
|
||||||
* The provided |buflen| size is too small to hold the output.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
|
|
||||||
const nghttp2_vec *vec,
|
|
||||||
size_t veclen,
|
|
||||||
const nghttp2_nv *nva,
|
|
||||||
size_t nvlen);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -4827,8 +4547,8 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
|
|||||||
* Changes header table size in the |inflater|. This may trigger
|
* Changes header table size in the |inflater|. This may trigger
|
||||||
* eviction in the dynamic table.
|
* eviction in the dynamic table.
|
||||||
*
|
*
|
||||||
* The |settings_max_dynamic_table_size| should be the value
|
* The |settings_hd_table_bufsize_max| should be the value transmitted
|
||||||
* transmitted in SETTINGS_HEADER_TABLE_SIZE.
|
* in SETTINGS_HEADER_TABLE_SIZE.
|
||||||
*
|
*
|
||||||
* This function must not be called while header block is being
|
* This function must not be called while header block is being
|
||||||
* inflated. In other words, this function must be called after
|
* inflated. In other words, this function must be called after
|
||||||
@@ -4849,7 +4569,7 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
|
|||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN int
|
NGHTTP2_EXTERN int
|
||||||
nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
||||||
size_t settings_max_dynamic_table_size);
|
size_t settings_hd_table_bufsize_max);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum
|
* @enum
|
||||||
@@ -4972,14 +4692,10 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
|||||||
*
|
*
|
||||||
* The application should call this function repeatedly until the
|
* The application should call this function repeatedly until the
|
||||||
* ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
|
* ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
|
||||||
* return value is non-negative. If that happens, all given input
|
* return value is non-negative. This means the all input values are
|
||||||
* data (|inlen| bytes) are processed successfully. Then the
|
* processed successfully. Then the application must call
|
||||||
* application must call `nghttp2_hd_inflate_end_headers()` to prepare
|
* `nghttp2_hd_inflate_end_headers()` to prepare for the next header
|
||||||
* for the next header block input.
|
* block input.
|
||||||
*
|
|
||||||
* In other words, if |in_final| is nonzero, and this function returns
|
|
||||||
* |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is
|
|
||||||
* set in |*inflate_flags|.
|
|
||||||
*
|
*
|
||||||
* The caller can feed complete compressed header block. It also can
|
* The caller can feed complete compressed header block. It also can
|
||||||
* feed it in several chunks. The caller must set |in_final| to
|
* feed it in several chunks. The caller must set |in_final| to
|
||||||
@@ -5038,11 +4754,10 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
NGHTTP2_EXTERN ssize_t
|
||||||
nghttp2_nv *nv_out,
|
nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out,
|
||||||
int *inflate_flags,
|
int *inflate_flags, const uint8_t *in, size_t inlen,
|
||||||
const uint8_t *in, size_t inlen,
|
int in_final);
|
||||||
int in_final);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
@@ -5232,42 +4947,6 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
|
|||||||
NGHTTP2_EXTERN int32_t
|
NGHTTP2_EXTERN int32_t
|
||||||
nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
|
nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
|
||||||
|
|
||||||
/**
|
|
||||||
* @functypedef
|
|
||||||
*
|
|
||||||
* Callback function invoked when the library outputs debug logging.
|
|
||||||
* The function is called with arguments suitable for ``vfprintf(3)``
|
|
||||||
*
|
|
||||||
* The debug output is only enabled if the library is built with
|
|
||||||
* ``DEBUGBUILD`` macro defined.
|
|
||||||
*/
|
|
||||||
typedef void (*nghttp2_debug_vprintf_callback)(const char *format,
|
|
||||||
va_list args);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* Sets a debug output callback called by the library when built with
|
|
||||||
* ``DEBUGBUILD`` macro defined. If this option is not used, debug
|
|
||||||
* log is written into standard error output.
|
|
||||||
*
|
|
||||||
* For builds without ``DEBUGBUILD`` macro defined, this function is
|
|
||||||
* noop.
|
|
||||||
*
|
|
||||||
* Note that building with ``DEBUGBUILD`` may cause significant
|
|
||||||
* performance penalty to libnghttp2 because of extra processing. It
|
|
||||||
* should be used for debugging purpose only.
|
|
||||||
*
|
|
||||||
* .. Warning::
|
|
||||||
*
|
|
||||||
* Building with ``DEBUGBUILD`` may cause significant performance
|
|
||||||
* penalty to libnghttp2 because of extra processing. It should be
|
|
||||||
* used for debugging purpose only. We write this two times because
|
|
||||||
* this is important.
|
|
||||||
*/
|
|
||||||
NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback(
|
|
||||||
nghttp2_debug_vprintf_callback debug_vprintf_callback);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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().
|
||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -110,18 +110,6 @@ void nghttp2_session_callbacks_set_on_header_callback2(
|
|||||||
cbs->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) {
|
||||||
|
|||||||
@@ -92,13 +92,6 @@ struct nghttp2_session_callbacks {
|
|||||||
*/
|
*/
|
||||||
nghttp2_on_header_callback on_header_callback;
|
nghttp2_on_header_callback on_header_callback;
|
||||||
nghttp2_on_header_callback2 on_header_callback2;
|
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
|
||||||
|
|||||||
@@ -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));
|
||||||
@@ -253,7 +252,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 +278,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 +290,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);
|
||||||
@@ -928,7 +930,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);
|
||||||
|
|
||||||
@@ -958,7 +960,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;
|
||||||
}
|
}
|
||||||
@@ -992,7 +994,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 */
|
||||||
|
|||||||
439
lib/nghttp2_hd.c
439
lib/nghttp2_hd.c
File diff suppressed because it is too large
Load Diff
@@ -288,7 +288,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 +299,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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -372,7 +372,7 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
|||||||
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
nghttp2_hd_nv 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);
|
||||||
|
|
||||||
@@ -410,8 +410,8 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
|||||||
* will be written to |buf|. This function assumes that |buf| has the
|
* will be written to |buf|. This function assumes that |buf| has the
|
||||||
* enough room to store the decoded byte string.
|
* enough room to store the decoded byte string.
|
||||||
*
|
*
|
||||||
* 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|.
|
||||||
*
|
*
|
||||||
@@ -425,6 +425,6 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
|||||||
*/
|
*/
|
||||||
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_buf *buf, 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) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_bufs_addb_hold(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 (ssize_t)(8 - nbits);
|
/* we assume that we at least 3 buffer space available */
|
||||||
|
assert(*avail_ptr >= 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fast path, since most code is less than 8 */
|
/* fast path, since most code is less than 8 */
|
||||||
|
|||||||
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;
|
||||||
@@ -338,70 +306,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 +382,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) {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -286,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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ void nghttp2_mem_free(nghttp2_mem *mem, void *ptr) {
|
|||||||
mem->free(ptr, mem->mem_user_data);
|
mem->free(ptr, mem->mem_user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data) {
|
void nghttp2_mem_free2(nghttp2_free free, void *ptr, void *mem_user_data) {
|
||||||
free_func(ptr, mem_user_data);
|
free(ptr, mem_user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) {
|
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) {
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ nghttp2_mem *nghttp2_mem_default(void);
|
|||||||
|mem|. */
|
|mem|. */
|
||||||
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
|
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
|
||||||
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
|
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
|
||||||
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
|
void nghttp2_mem_free2(nghttp2_free free, void *ptr, void *mem_user_data);
|
||||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
||||||
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ static int select_next_protocol(unsigned char **out, unsigned char *outlen,
|
|||||||
const unsigned char *in, unsigned int inlen,
|
const unsigned char *in, unsigned int inlen,
|
||||||
const char *key, unsigned int keylen) {
|
const char *key, unsigned int keylen) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) {
|
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in [i] + 1)) {
|
||||||
if (memcmp(&in[i], key, keylen) == 0) {
|
if (memcmp(&in[i], key, keylen) == 0) {
|
||||||
*out = (unsigned char *)&in[i + 1];
|
*out = (unsigned char *)&in[i + 1];
|
||||||
*outlen = in[i];
|
*outlen = in[i];
|
||||||
|
|||||||
@@ -95,15 +95,3 @@ void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) {
|
|||||||
option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK;
|
option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK;
|
||||||
option->no_auto_ping_ack = val;
|
option->no_auto_ping_ack = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
|
|
||||||
size_t val) {
|
|
||||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH;
|
|
||||||
option->max_send_header_block_length = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
|
|
||||||
size_t val) {
|
|
||||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE;
|
|
||||||
option->max_deflate_dynamic_table_size = val;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -62,23 +62,13 @@ typedef enum {
|
|||||||
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
||||||
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
|
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
|
||||||
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
|
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
|
||||||
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
|
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7
|
||||||
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
|
|
||||||
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
|
|
||||||
} nghttp2_option_flag;
|
} nghttp2_option_flag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct to store option values for nghttp2_session.
|
* Struct to store option values for nghttp2_session.
|
||||||
*/
|
*/
|
||||||
struct nghttp2_option {
|
struct nghttp2_option {
|
||||||
/**
|
|
||||||
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
|
||||||
*/
|
|
||||||
size_t max_send_header_block_length;
|
|
||||||
/**
|
|
||||||
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
|
|
||||||
*/
|
|
||||||
size_t max_deflate_dynamic_table_size;
|
|
||||||
/**
|
/**
|
||||||
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
||||||
* are specified.
|
* are specified.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -97,9 +97,6 @@ typedef struct {
|
|||||||
these frames in this number, it is considered suspicious. */
|
these frames in this number, it is considered suspicious. */
|
||||||
#define NGHTTP2_MAX_OBQ_FLOOD_ITEM 10000
|
#define NGHTTP2_MAX_OBQ_FLOOD_ITEM 10000
|
||||||
|
|
||||||
/* The default value of maximum number of concurrent streams. */
|
|
||||||
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
|
|
||||||
|
|
||||||
/* Internal state when receiving incoming frame */
|
/* Internal state when receiving incoming frame */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* Receiving frame header */
|
/* Receiving frame header */
|
||||||
@@ -259,9 +256,6 @@ struct nghttp2_session {
|
|||||||
size_t nvbuflen;
|
size_t nvbuflen;
|
||||||
/* Counter for detecting flooding in outbound queue */
|
/* Counter for detecting flooding in outbound queue */
|
||||||
size_t obq_flood_counter_;
|
size_t obq_flood_counter_;
|
||||||
/* The maximum length of header block to send. Calculated by the
|
|
||||||
same way as nghttp2_hd_deflate_bound() does. */
|
|
||||||
size_t max_send_header_block_length;
|
|
||||||
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
|
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
|
||||||
uint32_t next_stream_id;
|
uint32_t next_stream_id;
|
||||||
/* The last stream ID this session initiated. For client session,
|
/* The last stream ID this session initiated. For client session,
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "nghttp2_session.h"
|
#include "nghttp2_session.h"
|
||||||
#include "nghttp2_helper.h"
|
#include "nghttp2_helper.h"
|
||||||
#include "nghttp2_debug.h"
|
|
||||||
|
|
||||||
/* Maximum distance between any two stream's cycle in the same
|
/* Maximum distance between any two stream's cycle in the same
|
||||||
prirority queue. Imagine stream A's cycle is A, and stream B's
|
prirority queue. Imagine stream A's cycle is A, and stream B's
|
||||||
@@ -153,11 +152,11 @@ static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
|
|||||||
stream_next_cycle(stream, dep_stream->descendant_last_cycle);
|
stream_next_cycle(stream, dep_stream->descendant_last_cycle);
|
||||||
stream->seq = dep_stream->descendant_next_seq++;
|
stream->seq = dep_stream->descendant_next_seq++;
|
||||||
|
|
||||||
DEBUGF("stream: stream=%d obq push cycle=%d\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: stream=%d obq push cycle=%d\n",
|
||||||
stream->cycle);
|
stream->stream_id, stream->cycle));
|
||||||
|
|
||||||
DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: push stream %d to stream %d\n",
|
||||||
dep_stream->stream_id);
|
stream->stream_id, dep_stream->stream_id));
|
||||||
|
|
||||||
rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
@@ -184,8 +183,8 @@ static void stream_obq_remove(nghttp2_stream *stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
|
for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
|
||||||
DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d\n",
|
||||||
dep_stream->stream_id);
|
stream->stream_id, dep_stream->stream_id));
|
||||||
|
|
||||||
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
|
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
|
||||||
|
|
||||||
@@ -215,8 +214,8 @@ static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d (move)\n",
|
||||||
src->stream_id);
|
stream->stream_id, src->stream_id));
|
||||||
|
|
||||||
nghttp2_pq_remove(&src->obq, &stream->pq_entry);
|
nghttp2_pq_remove(&src->obq, &stream->pq_entry);
|
||||||
stream->queued = 0;
|
stream->queued = 0;
|
||||||
@@ -239,8 +238,8 @@ void nghttp2_stream_reschedule(nghttp2_stream *stream) {
|
|||||||
|
|
||||||
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
||||||
|
|
||||||
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
|
||||||
stream->cycle);
|
stream->stream_id, stream->cycle));
|
||||||
|
|
||||||
dep_stream->last_writelen = stream->last_writelen;
|
dep_stream->last_writelen = stream->last_writelen;
|
||||||
}
|
}
|
||||||
@@ -299,8 +298,8 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
|
|||||||
|
|
||||||
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
||||||
|
|
||||||
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
|
||||||
stream->cycle);
|
stream->stream_id, stream->cycle));
|
||||||
}
|
}
|
||||||
|
|
||||||
static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
|
static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
|
||||||
@@ -482,7 +481,8 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
|
|||||||
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
|
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
|
||||||
assert(stream->item == NULL);
|
assert(stream->item == NULL);
|
||||||
|
|
||||||
DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
|
DEBUGF(fprintf(stderr, "stream: stream=%d attach item=%p\n",
|
||||||
|
stream->stream_id, item));
|
||||||
|
|
||||||
stream->item = item;
|
stream->item = item;
|
||||||
|
|
||||||
@@ -500,7 +500,8 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_stream_detach_item(nghttp2_stream *stream) {
|
int nghttp2_stream_detach_item(nghttp2_stream *stream) {
|
||||||
DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item);
|
DEBUGF(fprintf(stderr, "stream: stream=%d detach item=%p\n",
|
||||||
|
stream->stream_id, stream->item));
|
||||||
|
|
||||||
stream->item = NULL;
|
stream->item = NULL;
|
||||||
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
|
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
|
||||||
@@ -511,8 +512,8 @@ int nghttp2_stream_detach_item(nghttp2_stream *stream) {
|
|||||||
int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
|
int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
|
||||||
assert(stream->item);
|
assert(stream->item);
|
||||||
|
|
||||||
DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: stream=%d defer item=%p cause=%02x\n",
|
||||||
stream->item, flags);
|
stream->stream_id, stream->item, flags));
|
||||||
|
|
||||||
stream->flags |= flags;
|
stream->flags |= flags;
|
||||||
|
|
||||||
@@ -522,8 +523,8 @@ int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
|
|||||||
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
|
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
|
||||||
assert(stream->item);
|
assert(stream->item);
|
||||||
|
|
||||||
DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
|
DEBUGF(fprintf(stderr, "stream: stream=%d resume item=%p flags=%02x\n",
|
||||||
stream->item, flags);
|
stream->stream_id, stream->item, flags));
|
||||||
|
|
||||||
stream->flags = (uint8_t)(stream->flags & ~flags);
|
stream->flags = (uint8_t)(stream->flags & ~flags);
|
||||||
|
|
||||||
@@ -592,8 +593,9 @@ int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
|
|||||||
nghttp2_stream *si;
|
nghttp2_stream *si;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
|
DEBUGF(fprintf(stderr,
|
||||||
dep_stream->stream_id, stream, stream->stream_id);
|
"stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n",
|
||||||
|
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||||
|
|
||||||
stream->sum_dep_weight = dep_stream->sum_dep_weight;
|
stream->sum_dep_weight = dep_stream->sum_dep_weight;
|
||||||
dep_stream->sum_dep_weight = stream->weight;
|
dep_stream->sum_dep_weight = stream->weight;
|
||||||
@@ -738,8 +740,8 @@ static void unlink_dep(nghttp2_stream *stream) {
|
|||||||
|
|
||||||
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
|
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
|
||||||
nghttp2_stream *stream) {
|
nghttp2_stream *stream) {
|
||||||
DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
|
DEBUGF(fprintf(stderr, "stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n",
|
||||||
dep_stream->stream_id, stream, stream->stream_id);
|
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||||
|
|
||||||
dep_stream->sum_dep_weight += stream->weight;
|
dep_stream->sum_dep_weight += stream->weight;
|
||||||
|
|
||||||
@@ -757,7 +759,8 @@ int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
|
|||||||
int32_t sum_dep_weight_delta;
|
int32_t sum_dep_weight_delta;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
|
DEBUGF(fprintf(stderr, "stream: dep_remove stream(%p)=%d\n", stream,
|
||||||
|
stream->stream_id));
|
||||||
|
|
||||||
/* Distribute weight of |stream| to direct descendants */
|
/* Distribute weight of |stream| to direct descendants */
|
||||||
sum_dep_weight_delta = -stream->weight;
|
sum_dep_weight_delta = -stream->weight;
|
||||||
@@ -810,8 +813,9 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
|
|||||||
nghttp2_stream *si;
|
nghttp2_stream *si;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
|
DEBUGF(fprintf(stderr, "stream: dep_insert_subtree dep_stream(%p)=%d "
|
||||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
|
"stream(%p)=%d\n",
|
||||||
|
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||||
|
|
||||||
stream->sum_dep_weight += dep_stream->sum_dep_weight;
|
stream->sum_dep_weight += dep_stream->sum_dep_weight;
|
||||||
dep_stream->sum_dep_weight = stream->weight;
|
dep_stream->sum_dep_weight = stream->weight;
|
||||||
@@ -858,8 +862,9 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
|||||||
nghttp2_stream *stream) {
|
nghttp2_stream *stream) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
|
DEBUGF(fprintf(stderr, "stream: dep_add_subtree dep_stream(%p)=%d "
|
||||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
|
"stream(%p)=%d\n",
|
||||||
|
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||||
|
|
||||||
dep_stream->sum_dep_weight += stream->weight;
|
dep_stream->sum_dep_weight += stream->weight;
|
||||||
|
|
||||||
@@ -884,8 +889,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
|||||||
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
|
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
|
||||||
nghttp2_stream *next, *dep_prev;
|
nghttp2_stream *next, *dep_prev;
|
||||||
|
|
||||||
DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
|
DEBUGF(fprintf(stderr, "stream: dep_remove_subtree stream(%p)=%d\n", stream,
|
||||||
stream->stream_id);
|
stream->stream_id));
|
||||||
|
|
||||||
assert(stream->dep_prev);
|
assert(stream->dep_prev);
|
||||||
|
|
||||||
|
|||||||
@@ -410,75 +410,6 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_session_set_local_window_size(nghttp2_session *session,
|
|
||||||
uint8_t flags, int32_t stream_id,
|
|
||||||
int32_t window_size) {
|
|
||||||
int32_t window_size_increment;
|
|
||||||
nghttp2_stream *stream;
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
if (window_size < 0) {
|
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
flags = 0;
|
|
||||||
|
|
||||||
if (stream_id == 0) {
|
|
||||||
window_size_increment = window_size - session->local_window_size;
|
|
||||||
|
|
||||||
if (window_size_increment == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window_size_increment < 0) {
|
|
||||||
return nghttp2_adjust_local_window_size(
|
|
||||||
&session->local_window_size, &session->recv_window_size,
|
|
||||||
&session->recv_reduction, &window_size_increment);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_increase_local_window_size(
|
|
||||||
&session->local_window_size, &session->recv_window_size,
|
|
||||||
&session->recv_reduction, &window_size_increment);
|
|
||||||
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
stream = nghttp2_session_get_stream(session, stream_id);
|
|
||||||
|
|
||||||
if (stream == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
window_size_increment = window_size - stream->local_window_size;
|
|
||||||
|
|
||||||
if (window_size_increment == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window_size_increment < 0) {
|
|
||||||
return nghttp2_adjust_local_window_size(
|
|
||||||
&stream->local_window_size, &stream->recv_window_size,
|
|
||||||
&stream->recv_reduction, &window_size_increment);
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = nghttp2_increase_local_window_size(
|
|
||||||
&stream->local_window_size, &stream->recv_window_size,
|
|
||||||
&stream->recv_reduction, &window_size_increment);
|
|
||||||
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window_size_increment > 0) {
|
|
||||||
return nghttp2_session_add_window_update(session, flags, stream_id,
|
|
||||||
window_size_increment);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
|
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
|
||||||
int32_t stream_id, const uint8_t *origin,
|
int32_t stream_id, const uint8_t *origin,
|
||||||
size_t origin_len, const uint8_t *field_value,
|
size_t origin_len, const uint8_t *field_value,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ if [ -z "$CLANGFORMATDIFF" ]; then
|
|||||||
CLANGFORMATDIFF=clang-format-diff.py
|
CLANGFORMATDIFF=clang-format-diff.py
|
||||||
fi
|
fi
|
||||||
|
|
||||||
errors=`git diff-index --cached --diff-filter=ACMR -p HEAD lib src examples tests | $CLANGFORMATDIFF -p1`
|
errors=`git diff-index --cached --diff-filter=ACMR -p HEAD -- | $CLANGFORMATDIFF -p1`
|
||||||
|
|
||||||
if [ -n "$errors" ]; then
|
if [ -n "$errors" ]; then
|
||||||
echo "$errors"
|
echo "$errors"
|
||||||
|
|||||||
@@ -260,7 +260,6 @@ try:
|
|||||||
import email.utils
|
import email.utils
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
import ssl as tls
|
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
except ImportError:
|
except ImportError:
|
||||||
asyncio = None
|
asyncio = None
|
||||||
@@ -295,25 +294,6 @@ def wrap_body(body):
|
|||||||
# string and flag.
|
# string and flag.
|
||||||
return body
|
return body
|
||||||
|
|
||||||
def negotiated_protocol(ssl_obj):
|
|
||||||
protocol = ssl_obj.selected_alpn_protocol()
|
|
||||||
if protocol:
|
|
||||||
logging.info('alpn, protocol:%s', protocol)
|
|
||||||
return protocol
|
|
||||||
|
|
||||||
protocol = ssl_obj.selected_npn_protocol()
|
|
||||||
if protocol:
|
|
||||||
logging.info('npn, protocol:%s', protocol)
|
|
||||||
return protocol
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def set_application_protocol(ssl_ctx):
|
|
||||||
app_protos = [cnghttp2.NGHTTP2_PROTO_VERSION_ID.decode('utf-8')]
|
|
||||||
ssl_ctx.set_npn_protocols(app_protos)
|
|
||||||
if tls.HAS_ALPN:
|
|
||||||
ssl_ctx.set_alpn_protocols(app_protos)
|
|
||||||
|
|
||||||
cdef _get_stream_user_data(cnghttp2.nghttp2_session *session,
|
cdef _get_stream_user_data(cnghttp2.nghttp2_session *session,
|
||||||
int32_t stream_id):
|
int32_t stream_id):
|
||||||
cdef void *stream_user_data
|
cdef void *stream_user_data
|
||||||
@@ -922,8 +902,6 @@ cdef class _HTTP2SessionCore(_HTTP2SessionCoreBase):
|
|||||||
return promised_handler
|
return promised_handler
|
||||||
|
|
||||||
def connection_lost(self):
|
def connection_lost(self):
|
||||||
self._stop_settings_timer()
|
|
||||||
|
|
||||||
for handler in self.handlers:
|
for handler in self.handlers:
|
||||||
handler.on_close(cnghttp2.NGHTTP2_INTERNAL_ERROR)
|
handler.on_close(cnghttp2.NGHTTP2_INTERNAL_ERROR)
|
||||||
self.handlers = set()
|
self.handlers = set()
|
||||||
@@ -1306,8 +1284,8 @@ if asyncio:
|
|||||||
logging.info('failed to set tcp-nodelay: %s', str(e))
|
logging.info('failed to set tcp-nodelay: %s', str(e))
|
||||||
ssl_ctx = self.transport.get_extra_info('sslcontext')
|
ssl_ctx = self.transport.get_extra_info('sslcontext')
|
||||||
if ssl_ctx:
|
if ssl_ctx:
|
||||||
ssl_obj = self.transport.get_extra_info('ssl_object')
|
protocol = sock.selected_npn_protocol()
|
||||||
protocol = negotiated_protocol(ssl_obj)
|
logging.info('npn, protocol:%s', protocol)
|
||||||
if protocol is None or protocol.encode('utf-8') != \
|
if protocol is None or protocol.encode('utf-8') != \
|
||||||
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
||||||
self.transport.abort()
|
self.transport.abort()
|
||||||
@@ -1368,7 +1346,8 @@ if asyncio:
|
|||||||
self.loop = asyncio.get_event_loop()
|
self.loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
if ssl:
|
if ssl:
|
||||||
set_application_protocol(ssl)
|
ssl.set_npn_protocols([cnghttp2.NGHTTP2_PROTO_VERSION_ID\
|
||||||
|
.decode('utf-8')])
|
||||||
|
|
||||||
coro = self.loop.create_server(session_factory,
|
coro = self.loop.create_server(session_factory,
|
||||||
host=address[0], port=address[1],
|
host=address[0], port=address[1],
|
||||||
@@ -1537,8 +1516,8 @@ if asyncio:
|
|||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||||
ssl_ctx = self.transport.get_extra_info('sslcontext')
|
ssl_ctx = self.transport.get_extra_info('sslcontext')
|
||||||
if ssl_ctx:
|
if ssl_ctx:
|
||||||
ssl_obj = self.transport.get_extra_info('ssl_object')
|
protocol = sock.selected_npn_protocol()
|
||||||
protocol = negotiated_protocol(ssl_obj)
|
logging.info('npn, protocol:%s', protocol)
|
||||||
if protocol is None or protocol.encode('utf-8') != \
|
if protocol is None or protocol.encode('utf-8') != \
|
||||||
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
||||||
self.transport.abort()
|
self.transport.abort()
|
||||||
@@ -1615,7 +1594,8 @@ if asyncio:
|
|||||||
return self.session
|
return self.session
|
||||||
|
|
||||||
if ssl:
|
if ssl:
|
||||||
set_application_protocol(ssl)
|
ssl.set_npn_protocols([cnghttp2.NGHTTP2_PROTO_VERSION_ID\
|
||||||
|
.decode('utf-8')])
|
||||||
|
|
||||||
self.loop = loop
|
self.loop = loop
|
||||||
if not self.loop:
|
if not self.loop:
|
||||||
|
|||||||
@@ -109,10 +109,6 @@ if(ENABLE_APP)
|
|||||||
shrpx_worker_process.cc
|
shrpx_worker_process.cc
|
||||||
shrpx_signal.cc
|
shrpx_signal.cc
|
||||||
shrpx_router.cc
|
shrpx_router.cc
|
||||||
shrpx_api_downstream_connection.cc
|
|
||||||
shrpx_health_monitor_downstream_connection.cc
|
|
||||||
shrpx_exec.cc
|
|
||||||
xsi_strerror.c
|
|
||||||
)
|
)
|
||||||
if(HAVE_SPDYLAY)
|
if(HAVE_SPDYLAY)
|
||||||
list(APPEND NGHTTPX_SRCS
|
list(APPEND NGHTTPX_SRCS
|
||||||
@@ -152,7 +148,6 @@ if(ENABLE_APP)
|
|||||||
shrpx_config_test.cc
|
shrpx_config_test.cc
|
||||||
shrpx_worker_test.cc
|
shrpx_worker_test.cc
|
||||||
shrpx_http_test.cc
|
shrpx_http_test.cc
|
||||||
shrpx_router_test.cc
|
|
||||||
http2_test.cc
|
http2_test.cc
|
||||||
util_test.cc
|
util_test.cc
|
||||||
nghttp2_gzip_test.c
|
nghttp2_gzip_test.c
|
||||||
@@ -168,7 +163,7 @@ if(ENABLE_APP)
|
|||||||
)
|
)
|
||||||
target_include_directories(nghttpx-unittest PRIVATE ${CUNIT_INCLUDE_DIRS})
|
target_include_directories(nghttpx-unittest PRIVATE ${CUNIT_INCLUDE_DIRS})
|
||||||
target_compile_definitions(nghttpx-unittest
|
target_compile_definitions(nghttpx-unittest
|
||||||
PRIVATE "-DNGHTTP2_SRC_DIR=\"${CMAKE_SOURCE_DIR}/src\""
|
PRIVATE "-DNGHTTP2_TESTS_DIR=\"${CMAKE_SOURCE_DIR}/tests\""
|
||||||
)
|
)
|
||||||
target_link_libraries(nghttpx-unittest nghttpx_static ${CUNIT_LIBRARIES})
|
target_link_libraries(nghttpx-unittest nghttpx_static ${CUNIT_LIBRARIES})
|
||||||
if(HAVE_MRUBY)
|
if(HAVE_MRUBY)
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ Config::Config()
|
|||||||
num_worker(1),
|
num_worker(1),
|
||||||
max_concurrent_streams(100),
|
max_concurrent_streams(100),
|
||||||
header_table_size(-1),
|
header_table_size(-1),
|
||||||
encoder_header_table_size(-1),
|
|
||||||
window_bits(-1),
|
window_bits(-1),
|
||||||
connection_window_bits(-1),
|
connection_window_bits(-1),
|
||||||
port(0),
|
port(0),
|
||||||
@@ -232,7 +231,6 @@ public:
|
|||||||
config_(config),
|
config_(config),
|
||||||
ssl_ctx_(ssl_ctx),
|
ssl_ctx_(ssl_ctx),
|
||||||
callbacks_(nullptr),
|
callbacks_(nullptr),
|
||||||
option_(nullptr),
|
|
||||||
next_session_id_(1),
|
next_session_id_(1),
|
||||||
tstamp_cached_(ev_now(loop)),
|
tstamp_cached_(ev_now(loop)),
|
||||||
cached_date_(util::http_date(tstamp_cached_)) {
|
cached_date_(util::http_date(tstamp_cached_)) {
|
||||||
@@ -240,13 +238,6 @@ public:
|
|||||||
|
|
||||||
fill_callback(callbacks_, config_);
|
fill_callback(callbacks_, config_);
|
||||||
|
|
||||||
nghttp2_option_new(&option_);
|
|
||||||
|
|
||||||
if (config_->encoder_header_table_size != -1) {
|
|
||||||
nghttp2_option_set_max_deflate_dynamic_table_size(
|
|
||||||
option_, config_->encoder_header_table_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
||||||
release_fd_timer_.data = this;
|
release_fd_timer_.data = this;
|
||||||
}
|
}
|
||||||
@@ -255,7 +246,6 @@ public:
|
|||||||
for (auto handler : handlers_) {
|
for (auto handler : handlers_) {
|
||||||
delete handler;
|
delete handler;
|
||||||
}
|
}
|
||||||
nghttp2_option_del(option_);
|
|
||||||
nghttp2_session_callbacks_del(callbacks_);
|
nghttp2_session_callbacks_del(callbacks_);
|
||||||
}
|
}
|
||||||
void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
|
void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
|
||||||
@@ -293,7 +283,6 @@ public:
|
|||||||
return session_id;
|
return session_id;
|
||||||
}
|
}
|
||||||
const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
|
const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
|
||||||
const nghttp2_option *get_option() const { return option_; }
|
|
||||||
void accept_connection(int fd) {
|
void accept_connection(int fd) {
|
||||||
util::make_socket_nodelay(fd);
|
util::make_socket_nodelay(fd);
|
||||||
SSL *ssl = nullptr;
|
SSL *ssl = nullptr;
|
||||||
@@ -419,7 +408,6 @@ private:
|
|||||||
const Config *config_;
|
const Config *config_;
|
||||||
SSL_CTX *ssl_ctx_;
|
SSL_CTX *ssl_ctx_;
|
||||||
nghttp2_session_callbacks *callbacks_;
|
nghttp2_session_callbacks *callbacks_;
|
||||||
nghttp2_option *option_;
|
|
||||||
ev_timer release_fd_timer_;
|
ev_timer release_fd_timer_;
|
||||||
int64_t next_session_id_;
|
int64_t next_session_id_;
|
||||||
ev_tstamp tstamp_cached_;
|
ev_tstamp tstamp_cached_;
|
||||||
@@ -837,8 +825,7 @@ int Http2Handler::on_write() { return write_(*this); }
|
|||||||
int Http2Handler::connection_made() {
|
int Http2Handler::connection_made() {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = nghttp2_session_server_new2(&session_, sessions_->get_callbacks(), this,
|
r = nghttp2_session_server_new(&session_, sessions_->get_callbacks(), this);
|
||||||
sessions_->get_option());
|
|
||||||
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return r;
|
return r;
|
||||||
@@ -869,9 +856,10 @@ int Http2Handler::connection_made() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (config->connection_window_bits != -1) {
|
if (config->connection_window_bits != -1) {
|
||||||
r = nghttp2_session_set_local_window_size(
|
r = nghttp2_submit_window_update(
|
||||||
session_, NGHTTP2_FLAG_NONE, 0,
|
session_, NGHTTP2_FLAG_NONE, 0,
|
||||||
(1 << config->connection_window_bits) - 1);
|
(1 << config->connection_window_bits) - 1 -
|
||||||
|
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@@ -1301,7 +1289,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
p = std::copy(std::begin(htdocs), std::end(htdocs), p);
|
p = std::copy(std::begin(htdocs), std::end(htdocs), p);
|
||||||
p = std::copy(std::begin(path), std::end(path), p);
|
p = std::copy(std::begin(path), std::end(path), p);
|
||||||
if (trailing_slash) {
|
if (trailing_slash) {
|
||||||
std::copy(std::begin(DEFAULT_HTML), std::end(DEFAULT_HTML), p);
|
p = std::copy(std::begin(DEFAULT_HTML), std::end(DEFAULT_HTML), p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2082,7 +2070,7 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
|||||||
std::cout << "[ALPN] client offers:" << std::endl;
|
std::cout << "[ALPN] client offers:" << std::endl;
|
||||||
}
|
}
|
||||||
if (config->verbose) {
|
if (config->verbose) {
|
||||||
for (unsigned int i = 0; i < inlen; i += in[i] + 1) {
|
for (unsigned int i = 0; i < inlen; i += in [i] + 1) {
|
||||||
std::cout << " * ";
|
std::cout << " * ";
|
||||||
std::cout.write(reinterpret_cast<const char *>(&in[i + 1]), in[i]);
|
std::cout.write(reinterpret_cast<const char *>(&in[i + 1]), in[i]);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ struct Config {
|
|||||||
size_t num_worker;
|
size_t num_worker;
|
||||||
size_t max_concurrent_streams;
|
size_t max_concurrent_streams;
|
||||||
ssize_t header_table_size;
|
ssize_t header_table_size;
|
||||||
ssize_t encoder_header_table_size;
|
|
||||||
int window_bits;
|
int window_bits;
|
||||||
int connection_window_bits;
|
int connection_window_bits;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
|
|||||||
@@ -22,10 +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 = \
|
EXTRA_DIST = CMakeLists.txt
|
||||||
CMakeLists.txt \
|
|
||||||
test.example.com.pem \
|
|
||||||
test.nghttp2.org.pem
|
|
||||||
|
|
||||||
bin_PROGRAMS =
|
bin_PROGRAMS =
|
||||||
check_PROGRAMS =
|
check_PROGRAMS =
|
||||||
@@ -135,12 +132,7 @@ NGHTTPX_SRCS = \
|
|||||||
shrpx_process.h \
|
shrpx_process.h \
|
||||||
shrpx_signal.cc shrpx_signal.h \
|
shrpx_signal.cc shrpx_signal.h \
|
||||||
shrpx_router.cc shrpx_router.h \
|
shrpx_router.cc shrpx_router.h \
|
||||||
shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
|
buffer.h memchunk.h template.h allocator.h
|
||||||
shrpx_health_monitor_downstream_connection.cc \
|
|
||||||
shrpx_health_monitor_downstream_connection.h \
|
|
||||||
shrpx_exec.cc shrpx_exec.h \
|
|
||||||
buffer.h memchunk.h template.h allocator.h \
|
|
||||||
xsi_strerror.c xsi_strerror.h
|
|
||||||
|
|
||||||
if HAVE_SPDYLAY
|
if HAVE_SPDYLAY
|
||||||
NGHTTPX_SRCS += shrpx_spdy_upstream.cc shrpx_spdy_upstream.h
|
NGHTTPX_SRCS += shrpx_spdy_upstream.cc shrpx_spdy_upstream.h
|
||||||
@@ -182,7 +174,6 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
|
|||||||
shrpx_config_test.cc shrpx_config_test.h \
|
shrpx_config_test.cc shrpx_config_test.h \
|
||||||
shrpx_worker_test.cc shrpx_worker_test.h \
|
shrpx_worker_test.cc shrpx_worker_test.h \
|
||||||
shrpx_http_test.cc shrpx_http_test.h \
|
shrpx_http_test.cc shrpx_http_test.h \
|
||||||
shrpx_router_test.cc shrpx_router_test.h \
|
|
||||||
http2_test.cc http2_test.h \
|
http2_test.cc http2_test.h \
|
||||||
util_test.cc util_test.h \
|
util_test.cc util_test.h \
|
||||||
nghttp2_gzip_test.c nghttp2_gzip_test.h \
|
nghttp2_gzip_test.c nghttp2_gzip_test.h \
|
||||||
@@ -192,7 +183,7 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
|
|||||||
template_test.cc template_test.h \
|
template_test.cc template_test.h \
|
||||||
base64_test.cc base64_test.h
|
base64_test.cc base64_test.h
|
||||||
nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS} \
|
nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS} \
|
||||||
-DNGHTTP2_SRC_DIR=\"$(top_srcdir)/src\"
|
-DNGHTTP2_TESTS_DIR=\"$(top_srcdir)/tests\"
|
||||||
nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @CUNIT_LIBS@ @TESTLDADD@
|
nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @CUNIT_LIBS@ @TESTLDADD@
|
||||||
|
|
||||||
if HAVE_MRUBY
|
if HAVE_MRUBY
|
||||||
|
|||||||
127
src/allocator.h
127
src/allocator.h
@@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
@@ -47,58 +45,29 @@ struct MemBlock {
|
|||||||
|
|
||||||
// BlockAllocator allocates memory block with given size at once, and
|
// BlockAllocator allocates memory block with given size at once, and
|
||||||
// cuts the region from it when allocation is requested. If the
|
// cuts the region from it when allocation is requested. If the
|
||||||
// requested size is larger than given threshold (plus small internal
|
// requested size is larger than given threshold, it will be allocated
|
||||||
// overhead), it will be allocated in a distinct buffer on demand.
|
// in a distinct buffer on demand.
|
||||||
// The |isolation_threshold| must be less than or equal to
|
|
||||||
// |block_size|.
|
|
||||||
struct BlockAllocator {
|
struct BlockAllocator {
|
||||||
BlockAllocator(size_t block_size, size_t isolation_threshold)
|
BlockAllocator(size_t block_size, size_t isolation_threshold)
|
||||||
: retain(nullptr),
|
: retain(nullptr),
|
||||||
head(nullptr),
|
head(nullptr),
|
||||||
block_size(block_size),
|
block_size(block_size),
|
||||||
isolation_threshold(std::min(block_size, isolation_threshold)) {
|
isolation_threshold(std::min(block_size, isolation_threshold)) {}
|
||||||
assert(isolation_threshold <= block_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
~BlockAllocator() { reset(); }
|
~BlockAllocator() {
|
||||||
|
|
||||||
BlockAllocator(BlockAllocator &&other) noexcept
|
|
||||||
: retain(other.retain),
|
|
||||||
head(other.head),
|
|
||||||
block_size(other.block_size),
|
|
||||||
isolation_threshold(other.isolation_threshold) {
|
|
||||||
other.retain = nullptr;
|
|
||||||
other.head = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockAllocator &operator=(BlockAllocator &&other) noexcept {
|
|
||||||
reset();
|
|
||||||
|
|
||||||
retain = other.retain;
|
|
||||||
head = other.head;
|
|
||||||
block_size = other.block_size;
|
|
||||||
isolation_threshold = other.isolation_threshold;
|
|
||||||
|
|
||||||
other.retain = nullptr;
|
|
||||||
other.head = nullptr;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockAllocator(const BlockAllocator &) = delete;
|
|
||||||
BlockAllocator &operator=(const BlockAllocator &) = delete;
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
for (auto mb = retain; mb;) {
|
for (auto mb = retain; mb;) {
|
||||||
auto next = mb->next;
|
auto next = mb->next;
|
||||||
delete[] reinterpret_cast<uint8_t *>(mb);
|
delete[] reinterpret_cast<uint8_t *>(mb);
|
||||||
mb = next;
|
mb = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
retain = nullptr;
|
|
||||||
head = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockAllocator(BlockAllocator &&) = default;
|
||||||
|
BlockAllocator &operator=(BlockAllocator &&) = default;
|
||||||
|
|
||||||
|
BlockAllocator(const BlockAllocator &) = delete;
|
||||||
|
BlockAllocator &operator=(const BlockAllocator &) = delete;
|
||||||
|
|
||||||
MemBlock *alloc_mem_block(size_t size) {
|
MemBlock *alloc_mem_block(size_t size) {
|
||||||
auto block = new uint8_t[sizeof(MemBlock) + size];
|
auto block = new uint8_t[sizeof(MemBlock) + size];
|
||||||
auto mb = reinterpret_cast<MemBlock *>(block);
|
auto mb = reinterpret_cast<MemBlock *>(block);
|
||||||
@@ -111,60 +80,20 @@ struct BlockAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *alloc(size_t size) {
|
void *alloc(size_t size) {
|
||||||
if (size + sizeof(size_t) >= isolation_threshold) {
|
if (size >= isolation_threshold) {
|
||||||
auto len = std::max(static_cast<size_t>(16), size);
|
auto mb = alloc_mem_block(size);
|
||||||
// We will store the allocated size in size_t field.
|
|
||||||
auto mb = alloc_mem_block(len + sizeof(size_t));
|
|
||||||
auto sp = reinterpret_cast<size_t *>(mb->begin);
|
|
||||||
*sp = len;
|
|
||||||
mb->last = mb->end;
|
mb->last = mb->end;
|
||||||
return mb->begin + sizeof(size_t);
|
return mb->begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!head ||
|
if (!head || head->end - head->last < static_cast<ssize_t>(size)) {
|
||||||
head->end - head->last < static_cast<ssize_t>(size + sizeof(size_t))) {
|
|
||||||
head = alloc_mem_block(block_size);
|
head = alloc_mem_block(block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We will store the allocated size in size_t field.
|
auto res = head->last;
|
||||||
auto res = head->last + sizeof(size_t);
|
|
||||||
auto sp = reinterpret_cast<size_t *>(head->last);
|
|
||||||
*sp = size;
|
|
||||||
|
|
||||||
head->last = reinterpret_cast<uint8_t *>(
|
head->last = reinterpret_cast<uint8_t *>(
|
||||||
(reinterpret_cast<intptr_t>(res + size) + 0xf) & ~0xf);
|
(reinterpret_cast<intptr_t>(head->last + size) + 0xf) & ~0xf);
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns allocated size for memory pointed by |ptr|. We assume
|
|
||||||
// that |ptr| was returned from alloc() or realloc().
|
|
||||||
size_t get_alloc_length(void *ptr) {
|
|
||||||
return *reinterpret_cast<size_t *>(static_cast<uint8_t *>(ptr) -
|
|
||||||
sizeof(size_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocates memory of at least |size| bytes. If |ptr| is nullptr,
|
|
||||||
// this is equivalent to alloc(size). If |ptr| is not nullptr,
|
|
||||||
// obtain the allocated size for |ptr|, assuming that |ptr| was
|
|
||||||
// returned from alloc() or realloc(). If the allocated size is
|
|
||||||
// greater than or equal to size, |ptr| is returned. Otherwise,
|
|
||||||
// allocates at least |size| bytes of memory, and the original
|
|
||||||
// content pointed by |ptr| is copied to the newly allocated memory.
|
|
||||||
void *realloc(void *ptr, size_t size) {
|
|
||||||
if (!ptr) {
|
|
||||||
return alloc(size);
|
|
||||||
}
|
|
||||||
auto alloclen = get_alloc_length(ptr);
|
|
||||||
auto p = reinterpret_cast<uint8_t *>(ptr);
|
|
||||||
if (size <= alloclen) {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto nalloclen = std::max(size + 1, alloclen * 2);
|
|
||||||
|
|
||||||
auto res = alloc(nalloclen);
|
|
||||||
std::copy_n(p, alloclen, static_cast<uint8_t *>(res));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -232,30 +161,6 @@ StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) {
|
|||||||
return StringRef{dst, len};
|
return StringRef{dst, len};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the string which is the concatenation of |value| and |args|
|
|
||||||
// in the given order. The resulting string will be NULL-terminated.
|
|
||||||
// This function assumes that the pointer value value.c_str() was
|
|
||||||
// obtained from alloc.alloc() or alloc.realloc(), and attempts to use
|
|
||||||
// unused memory region by using alloc.realloc(). If value is empty,
|
|
||||||
// then just call concat_string_ref().
|
|
||||||
template <typename BlockAllocator, typename... Args>
|
|
||||||
StringRef realloc_concat_string_ref(BlockAllocator &alloc,
|
|
||||||
const StringRef &value, Args &&... args) {
|
|
||||||
if (value.empty()) {
|
|
||||||
return concat_string_ref(alloc, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto len =
|
|
||||||
value.size() + concat_string_ref_count(0, std::forward<Args>(args)...);
|
|
||||||
auto dst = static_cast<uint8_t *>(
|
|
||||||
alloc.realloc(const_cast<uint8_t *>(value.byte()), len + 1));
|
|
||||||
auto p = dst + value.size();
|
|
||||||
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
return StringRef{dst, len};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ByteRef {
|
struct ByteRef {
|
||||||
// The pointer to the beginning of the buffer.
|
// The pointer to the beginning of the buffer.
|
||||||
uint8_t *base;
|
uint8_t *base;
|
||||||
|
|||||||
@@ -334,8 +334,7 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
|
|||||||
frame->goaway.error_code,
|
frame->goaway.error_code,
|
||||||
static_cast<unsigned int>(frame->goaway.opaque_data_len),
|
static_cast<unsigned int>(frame->goaway.opaque_data_len),
|
||||||
util::ascii_dump(frame->goaway.opaque_data,
|
util::ascii_dump(frame->goaway.opaque_data,
|
||||||
frame->goaway.opaque_data_len)
|
frame->goaway.opaque_data_len).c_str());
|
||||||
.c_str());
|
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_WINDOW_UPDATE:
|
case NGHTTP2_WINDOW_UPDATE:
|
||||||
print_frame_attr_indent();
|
print_frame_attr_indent();
|
||||||
|
|||||||
@@ -373,8 +373,9 @@ bool session_impl::setup_session() {
|
|||||||
{NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, window_size}}};
|
{NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, window_size}}};
|
||||||
nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, iv.data(), iv.size());
|
nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, iv.data(), iv.size());
|
||||||
// increase connection window size up to window_size
|
// increase connection window size up to window_size
|
||||||
nghttp2_session_set_local_window_size(session_, NGHTTP2_FLAG_NONE, 0,
|
nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0,
|
||||||
window_size);
|
window_size -
|
||||||
|
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +504,7 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto nva = std::vector<nghttp2_nv>();
|
auto nva = std::vector<nghttp2_nv>();
|
||||||
nva.reserve(4 + h.size());
|
nva.reserve(3 + h.size());
|
||||||
nva.push_back(http2::make_nv_ls(":method", method));
|
nva.push_back(http2::make_nv_ls(":method", method));
|
||||||
nva.push_back(http2::make_nv_ls(":scheme", uref.scheme));
|
nva.push_back(http2::make_nv_ls(":scheme", uref.scheme));
|
||||||
nva.push_back(http2::make_nv_ls(":path", path));
|
nva.push_back(http2::make_nv_ls(":path", path));
|
||||||
@@ -521,13 +522,13 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
|||||||
if (cb) {
|
if (cb) {
|
||||||
strm->request().impl().on_read(std::move(cb));
|
strm->request().impl().on_read(std::move(cb));
|
||||||
prd.source.ptr = strm.get();
|
prd.source.ptr = strm.get();
|
||||||
prd.read_callback = [](nghttp2_session *session, int32_t stream_id,
|
prd.read_callback =
|
||||||
uint8_t *buf, size_t length, uint32_t *data_flags,
|
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
|
||||||
nghttp2_data_source *source,
|
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
|
||||||
void *user_data) -> ssize_t {
|
void *user_data) -> ssize_t {
|
||||||
auto strm = static_cast<stream *>(source->ptr);
|
auto strm = static_cast<stream *>(source->ptr);
|
||||||
return strm->request().impl().call_on_read(buf, length, data_flags);
|
return strm->request().impl().call_on_read(buf, length, data_flags);
|
||||||
};
|
};
|
||||||
prdptr = &prd;
|
prdptr = &prd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,12 +74,10 @@ public:
|
|||||||
|
|
||||||
virtual void start_connect(tcp::resolver::iterator endpoint_it) = 0;
|
virtual void start_connect(tcp::resolver::iterator endpoint_it) = 0;
|
||||||
virtual tcp::socket &socket() = 0;
|
virtual tcp::socket &socket() = 0;
|
||||||
virtual void read_socket(
|
virtual void read_socket(std::function<
|
||||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
|
||||||
h) = 0;
|
virtual void write_socket(std::function<
|
||||||
virtual void write_socket(
|
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
|
||||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
|
||||||
h) = 0;
|
|
||||||
virtual void shutdown_socket() = 0;
|
virtual void shutdown_socket() = 0;
|
||||||
|
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|||||||
@@ -44,12 +44,10 @@ public:
|
|||||||
|
|
||||||
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
||||||
virtual tcp::socket &socket();
|
virtual tcp::socket &socket();
|
||||||
virtual void read_socket(
|
virtual void read_socket(std::function<
|
||||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||||
h);
|
virtual void write_socket(std::function<
|
||||||
virtual void write_socket(
|
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
|
||||||
h);
|
|
||||||
virtual void shutdown_socket();
|
virtual void shutdown_socket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -47,12 +47,10 @@ public:
|
|||||||
|
|
||||||
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
||||||
virtual tcp::socket &socket();
|
virtual tcp::socket &socket();
|
||||||
virtual void read_socket(
|
virtual void read_socket(std::function<
|
||||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||||
h);
|
virtual void write_socket(std::function<
|
||||||
virtual void write_socket(
|
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
|
||||||
h);
|
|
||||||
virtual void shutdown_socket();
|
virtual void shutdown_socket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -113,22 +113,22 @@ generator_cb file_generator(const std::string &path) {
|
|||||||
generator_cb file_generator_from_fd(int fd) {
|
generator_cb file_generator_from_fd(int fd) {
|
||||||
auto d = defer_shared(close, fd);
|
auto d = defer_shared(close, fd);
|
||||||
|
|
||||||
return [fd, d](uint8_t *buf, size_t len,
|
return [fd, d](uint8_t *buf, size_t len, uint32_t *data_flags)
|
||||||
uint32_t *data_flags) -> generator_cb::result_type {
|
-> generator_cb::result_type {
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
while ((n = read(fd, buf, len)) == -1 && errno == EINTR)
|
while ((n = read(fd, buf, len)) == -1 && errno == EINTR)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
|
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_path(const std::string &path) { return util::check_path(path); }
|
bool check_path(const std::string &path) { return util::check_path(path); }
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void io_service_pool::run(bool asynchronous) {
|
|||||||
// Create a pool of threads to run all of the io_services.
|
// Create a pool of threads to run all of the io_services.
|
||||||
for (std::size_t i = 0; i < io_services_.size(); ++i) {
|
for (std::size_t i = 0; i < io_services_.size(); ++i) {
|
||||||
futures_.push_back(std::async(std::launch::async,
|
futures_.push_back(std::async(std::launch::async,
|
||||||
(size_t(boost::asio::io_service::*)(void)) &
|
(size_t (boost::asio::io_service::*)(void)) &
|
||||||
boost::asio::io_service::run,
|
boost::asio::io_service::run,
|
||||||
io_services_[i]));
|
io_services_[i]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,8 +130,8 @@ void server::start_accept(boost::asio::ssl::context &tls_context,
|
|||||||
|
|
||||||
acceptor.async_accept(
|
acceptor.async_accept(
|
||||||
new_connection->socket().lowest_layer(),
|
new_connection->socket().lowest_layer(),
|
||||||
[this, &tls_context, &acceptor, &mux,
|
[this, &tls_context, &acceptor, &mux, new_connection](
|
||||||
new_connection](const boost::system::error_code &e) {
|
const boost::system::error_code &e) {
|
||||||
if (!e) {
|
if (!e) {
|
||||||
new_connection->socket().lowest_layer().set_option(
|
new_connection->socket().lowest_layer().set_option(
|
||||||
tcp::no_delay(true));
|
tcp::no_delay(true));
|
||||||
|
|||||||
@@ -245,7 +245,6 @@ http2_handler::http2_handler(boost::asio::io_service &io_service,
|
|||||||
buf_(nullptr),
|
buf_(nullptr),
|
||||||
buflen_(0),
|
buflen_(0),
|
||||||
inside_callback_(false),
|
inside_callback_(false),
|
||||||
write_signaled_(false),
|
|
||||||
tstamp_cached_(time(nullptr)),
|
tstamp_cached_(time(nullptr)),
|
||||||
formatted_date_(util::http_date(tstamp_cached_)) {}
|
formatted_date_(util::http_date(tstamp_cached_)) {}
|
||||||
|
|
||||||
@@ -346,13 +345,13 @@ int http2_handler::start_response(stream &strm) {
|
|||||||
auto &req = strm.request().impl();
|
auto &req = strm.request().impl();
|
||||||
if (::nghttp2::http2::expect_response_body(req.method(), res.status_code())) {
|
if (::nghttp2::http2::expect_response_body(req.method(), res.status_code())) {
|
||||||
prd.source.ptr = &strm;
|
prd.source.ptr = &strm;
|
||||||
prd.read_callback = [](nghttp2_session *session, int32_t stream_id,
|
prd.read_callback =
|
||||||
uint8_t *buf, size_t length, uint32_t *data_flags,
|
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
|
||||||
nghttp2_data_source *source,
|
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
|
||||||
void *user_data) -> ssize_t {
|
void *user_data) -> ssize_t {
|
||||||
auto &strm = *static_cast<stream *>(source->ptr);
|
auto &strm = *static_cast<stream *>(source->ptr);
|
||||||
return strm.response().impl().call_read(buf, length, data_flags);
|
return strm.response().impl().call_read(buf, length, data_flags);
|
||||||
};
|
};
|
||||||
prd_ptr = &prd;
|
prd_ptr = &prd;
|
||||||
}
|
}
|
||||||
rv = nghttp2_submit_response(session_, strm.get_stream_id(), nva.data(),
|
rv = nghttp2_submit_response(session_, strm.get_stream_id(), nva.data(),
|
||||||
@@ -404,17 +403,12 @@ void http2_handler::stream_error(int32_t stream_id, uint32_t error_code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void http2_handler::signal_write() {
|
void http2_handler::signal_write() {
|
||||||
if (!inside_callback_ && !write_signaled_) {
|
if (!inside_callback_) {
|
||||||
write_signaled_ = true;
|
initiate_write();
|
||||||
auto self = shared_from_this();
|
|
||||||
io_service_.post([self]() { self->initiate_write(); });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void http2_handler::initiate_write() {
|
void http2_handler::initiate_write() { writefun_(); }
|
||||||
write_signaled_ = false;
|
|
||||||
writefun_();
|
|
||||||
}
|
|
||||||
|
|
||||||
void http2_handler::resume(stream &strm) {
|
void http2_handler::resume(stream &strm) {
|
||||||
nghttp2_session_resume_data(session_, strm.get_stream_id());
|
nghttp2_session_resume_data(session_, strm.get_stream_id());
|
||||||
|
|||||||
@@ -160,9 +160,6 @@ private:
|
|||||||
const uint8_t *buf_;
|
const uint8_t *buf_;
|
||||||
std::size_t buflen_;
|
std::size_t buflen_;
|
||||||
bool inside_callback_;
|
bool inside_callback_;
|
||||||
// true if we have pending on_write call. This avoids repeated call
|
|
||||||
// of io_service::post.
|
|
||||||
bool write_signaled_;
|
|
||||||
time_t tstamp_cached_;
|
time_t tstamp_cached_;
|
||||||
std::string formatted_date_;
|
std::string formatted_date_;
|
||||||
};
|
};
|
||||||
|
|||||||
56
src/base64.h
56
src/base64.h
@@ -29,9 +29,6 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "template.h"
|
|
||||||
#include "allocator.h"
|
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
namespace base64 {
|
namespace base64 {
|
||||||
@@ -90,8 +87,7 @@ InputIt next_decode_input(InputIt first, InputIt last, const int *tbl) {
|
|||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIt, typename OutputIt>
|
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
||||||
OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
|
||||||
static constexpr int INDEX_TABLE[] = {
|
static constexpr int INDEX_TABLE[] = {
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
@@ -108,29 +104,37 @@ OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
|||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1};
|
-1, -1, -1, -1};
|
||||||
assert(std::distance(first, last) % 4 == 0);
|
auto len = last - first;
|
||||||
auto p = d_first;
|
if (len % 4 != 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::string res;
|
||||||
|
res.resize(len / 4 * 3);
|
||||||
|
|
||||||
|
auto p = std::begin(res);
|
||||||
for (; first != last;) {
|
for (; first != last;) {
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
for (int i = 1; i <= 4; ++i, ++first) {
|
for (int i = 1; i <= 4; ++i, ++first) {
|
||||||
auto idx = INDEX_TABLE[static_cast<size_t>(*first)];
|
auto idx = INDEX_TABLE[static_cast<size_t>(*first)];
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
if (i <= 2) {
|
if (i <= 2) {
|
||||||
return d_first;
|
return "";
|
||||||
}
|
}
|
||||||
if (i == 3) {
|
if (i == 3) {
|
||||||
if (*first == '=' && *(first + 1) == '=' && first + 2 == last) {
|
if (*first == '=' && *(first + 1) == '=' && first + 2 == last) {
|
||||||
*p++ = n >> 16;
|
*p++ = n >> 16;
|
||||||
return p;
|
res.resize(p - std::begin(res));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
return d_first;
|
return "";
|
||||||
}
|
}
|
||||||
if (*first == '=' && first + 1 == last) {
|
if (*first == '=' && first + 1 == last) {
|
||||||
*p++ = n >> 16;
|
*p++ = n >> 16;
|
||||||
*p++ = n >> 8 & 0xffu;
|
*p++ = n >> 8 & 0xffu;
|
||||||
return p;
|
res.resize(p - std::begin(res));
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
return d_first;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
n += idx << (24 - i * 6);
|
n += idx << (24 - i * 6);
|
||||||
@@ -141,37 +145,9 @@ OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
|||||||
*p++ = n & 0xffu;
|
*p++ = n & 0xffu;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
|
||||||
auto len = std::distance(first, last);
|
|
||||||
if (len % 4 != 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::string res;
|
|
||||||
res.resize(len / 4 * 3);
|
|
||||||
|
|
||||||
res.erase(decode(first, last, std::begin(res)), std::end(res));
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIt>
|
|
||||||
StringRef decode(BlockAllocator &balloc, InputIt first, InputIt last) {
|
|
||||||
auto len = std::distance(first, last);
|
|
||||||
if (len % 4 != 0) {
|
|
||||||
return StringRef::from_lit("");
|
|
||||||
}
|
|
||||||
auto iov = make_byte_ref(balloc, len / 4 * 3 + 1);
|
|
||||||
auto p = iov.base;
|
|
||||||
|
|
||||||
p = decode(first, last, p);
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
return StringRef{iov.base, p};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace base64
|
} // namespace base64
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|||||||
@@ -59,40 +59,31 @@ void test_base64_encode(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void test_base64_decode(void) {
|
void test_base64_decode(void) {
|
||||||
BlockAllocator balloc(4096, 4096);
|
|
||||||
{
|
{
|
||||||
std::string in = "/w==";
|
std::string in = "/w==";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("\xff" == out);
|
CU_ASSERT("\xff" == out);
|
||||||
CU_ASSERT("\xff" == base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string in = "//4=";
|
std::string in = "//4=";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("\xff\xfe" == out);
|
CU_ASSERT("\xff\xfe" == out);
|
||||||
CU_ASSERT("\xff\xfe" ==
|
|
||||||
base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string in = "//79";
|
std::string in = "//79";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("\xff\xfe\xfd" == out);
|
CU_ASSERT("\xff\xfe\xfd" == out);
|
||||||
CU_ASSERT("\xff\xfe\xfd" ==
|
|
||||||
base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string in = "//79/A==";
|
std::string in = "//79/A==";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("\xff\xfe\xfd\xfc" == out);
|
CU_ASSERT("\xff\xfe\xfd\xfc" == out);
|
||||||
CU_ASSERT("\xff\xfe\xfd\xfc" ==
|
|
||||||
base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// we check the number of valid input must be multiples of 4
|
// we check the number of valid input must be multiples of 4
|
||||||
std::string in = "//79=";
|
std::string in = "//79=";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("" == out);
|
CU_ASSERT("" == out);
|
||||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// ending invalid character at the boundary of multiples of 4 is
|
// ending invalid character at the boundary of multiples of 4 is
|
||||||
@@ -100,21 +91,18 @@ void test_base64_decode(void) {
|
|||||||
std::string in = "bmdodHRw\n";
|
std::string in = "bmdodHRw\n";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("" == out);
|
CU_ASSERT("" == out);
|
||||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// after seeing '=', subsequent input must be also '='.
|
// after seeing '=', subsequent input must be also '='.
|
||||||
std::string in = "//79/A=A";
|
std::string in = "//79/A=A";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("" == out);
|
CU_ASSERT("" == out);
|
||||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// additional '=' at the end is bad
|
// additional '=' at the end is bad
|
||||||
std::string in = "//79/A======";
|
std::string in = "//79/A======";
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
auto out = base64::decode(std::begin(in), std::end(in));
|
||||||
CU_ASSERT("" == out);
|
CU_ASSERT("" == out);
|
||||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"signing": {
|
|
||||||
"default": {
|
|
||||||
"expiry": "87600h"
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"server": {
|
|
||||||
"expiry": "87600h",
|
|
||||||
"usages": [
|
|
||||||
"signing",
|
|
||||||
"key encipherment",
|
|
||||||
"server auth"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIEpQIBAAKCAQEA1kVkF8QSUwW/HV9EFRPSMoiOVmYwB8vqKDtT0d6MFiKAM8/Y
|
|
||||||
JFUq2uKlUydgT4IPE7PATvVcIj3GtL9XzPhscqYO/S0Y7scyTE2VAPmtz+StPWf2
|
|
||||||
wZ1IQR09HrnDTc44KvYGZpefBZkD9UjbmJ9a1ZmJjJiMr3hTnKE/sxZ2+dMsnMZX
|
|
||||||
N822cfaHyTN+T0+Tyw5vBBboCDsZzxmf+9FFIDJNs3NL34cR8EZRhpfaegapH8bt
|
|
||||||
OJ+D+RZ2kg7E/YYkGcS6NodvTjSUFCFHpWjHCfTFhn/owBIAooCdWorh6dc8Q72l
|
|
||||||
AodwNLXS8uuPgPqM5s4Cz57m7Zgs4OilNmIdawIDAQABAoIBAQCwqLtygLye6KD+
|
|
||||||
RXorapEmCsJX5553/x6Klwdvg+25ni5XCWjp47IWj0DBQzi7tL5bfxrxvod8z7QR
|
|
||||||
d6SbIMLA77px8Ima7G7CzEAqcrBkM+TFOP8P+G4HCWVH/N5SOtDCUt9KHH4Grna9
|
|
||||||
95jdx5yreRAX8/oh/bHp9GRBcicbpwYMVWOnjTE2seEUYQOpdpYdP4bOPUvAju0l
|
|
||||||
mwmy2/dDGmbibktN3sdHEhDodKu+Znv7nFZo0jzhlyoXse653WcvaQeZZYuojvSe
|
|
||||||
Sr92DvPp7UaYrb4KvT7ujXiPavSV2m/4EmGtyqevUf2dZ6sfMXZjmXsjWz9txhWp
|
|
||||||
4BgbHyHRAoGBAPqyuNj2CDD3FE7N3Hxyba8d+ZtsVUNawjq2gwOvT9NLsMstOGyH
|
|
||||||
OCc1v4W6Sq4w1wo4nIJyY8kNZwtReaTHOPZlDgBhVvk/x8eLBu+QTMRyocRt1LoD
|
|
||||||
8HyKxWSAnYTtCh/GUEQ37amIqvOJ5GNL+25WDzevLa5kMYWG743uxEupAoGBANrN
|
|
||||||
c/fVxepvP0GISlLpL3aZCFGAjMrq3xUYcf/w4wPoMq6AdpIPeRVBmJ1/Uqw1FkV8
|
|
||||||
NRKJNPE2YcMuv8iMeQlacoPd34KT9ob80EYVlMwAkeC0NK+FfiM/UteR0wB49gmi
|
|
||||||
ugX9YlJytOP9aUgPvEGT6l+XtgGC44W1TQWe62zzAoGBAKZenNU+0UjNb6isbToZ
|
|
||||||
Jjkkh1Vhm2PLg0I7hM6ZNTxf6r+rDtrXEajTvnocmxrmRo796r+W8immv09/jl6P
|
|
||||||
53l8rsIJ1xIqBYai+MNa29cyy6/zw0x++MVtwnlj8SUZubJEhVgAVbRAglKEnBBZ
|
|
||||||
iE48xnSJyKMG0uZuGePzJEmhAoGBAIOHJcNBumum3DuklikpC+MbMyjrQbdpYRjp
|
|
||||||
TP4x7AWZO34ysxQyQPNKL1feBfCHKRA0DiNKX4zwx+vw2lDQQKIiwNwMMCPqljOn
|
|
||||||
HfxDVOMdJJQTP+iTMrQ1iLMVceXC0QQR0glvu/8b/SlgWD19WAmDxUwZgst9xw/F
|
|
||||||
YLuUQKmJAoGAREeTugd4hc0U/YV/BQQjSCLhl11EtVry/oQMHj8KZpIJhP7tj8lw
|
|
||||||
hSE0+z04oMhiTeq55PYKQkTo5l6V4PW0zfpEwlKEEm0erab1G9Ddh7us47XFcKLl
|
|
||||||
Rmk192EVZ0lQuzftsYv7dzRLiAR7yDFXwD1ELIK/uPkwBtu7wtHlq+M=
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE REQUEST-----
|
|
||||||
MIICwjCCAaoCAQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
|
|
||||||
ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMOY2Eu
|
|
||||||
bmdodHRwMi5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWRWQX
|
|
||||||
xBJTBb8dX0QVE9IyiI5WZjAHy+ooO1PR3owWIoAzz9gkVSra4qVTJ2BPgg8Ts8BO
|
|
||||||
9VwiPca0v1fM+Gxypg79LRjuxzJMTZUA+a3P5K09Z/bBnUhBHT0eucNNzjgq9gZm
|
|
||||||
l58FmQP1SNuYn1rVmYmMmIyveFOcoT+zFnb50yycxlc3zbZx9ofJM35PT5PLDm8E
|
|
||||||
FugIOxnPGZ/70UUgMk2zc0vfhxHwRlGGl9p6Bqkfxu04n4P5FnaSDsT9hiQZxLo2
|
|
||||||
h29ONJQUIUelaMcJ9MWGf+jAEgCigJ1aiuHp1zxDvaUCh3A0tdLy64+A+ozmzgLP
|
|
||||||
nubtmCzg6KU2Yh1rAgMBAAGgHzAdBgkqhkiG9w0BCQ4xEDAOMAwGA1UdEwQFMAMB
|
|
||||||
Af8wDQYJKoZIhvcNAQELBQADggEBACI5v8GbOXKv38h9/tuGEwJ9uxpYEljgGt8h
|
|
||||||
QL5lwfEifh/7A8b39b9JEzWk5hnMRCOb8J6Jc3/6nmVgtKkQ+Mceupqpwsp1gT/v
|
|
||||||
uUoAkJE03Iuja9zLhHmy74oZ7LWOQrZ1T7Z0eGQ+5u+LBZiPKnKxmkLCQoUPTbc4
|
|
||||||
NQ9BbKhr8OaoJ4DDvJnszcL7to6kih7SkdoNZsq4zB0/ai/cPhvoVgkYfbLH2++D
|
|
||||||
Tcs7TqU2L7gKzqXUtHeAKM2y81ewL7QTrcYzgiW86s3NmquxZG5pq0mjD+P4BYLc
|
|
||||||
MOdnCxKbBuE/1R29pa6+JKgc46jOa2yRgv5+8rXkkpu53Ke3FGc=
|
|
||||||
-----END CERTIFICATE REQUEST-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
"CN": "ca.nghttp2.org",
|
|
||||||
"key": {
|
|
||||||
"algo": "rsa",
|
|
||||||
"size": 2048
|
|
||||||
},
|
|
||||||
"ca": {
|
|
||||||
"expiry": "87600h"
|
|
||||||
},
|
|
||||||
"names": [
|
|
||||||
{
|
|
||||||
"C": "AU",
|
|
||||||
"ST": "Some-State",
|
|
||||||
"O": "Internet Widgits Pty Ltd"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDrTCCApWgAwIBAgIUe4dvx8haIjsT3ZpNCMrl62Xk6E0wDQYJKoZIhvcNAQEL
|
|
||||||
BQAwXjELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoT
|
|
||||||
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEXMBUGA1UEAxMOY2EubmdodHRwMi5v
|
|
||||||
cmcwHhcNMTYwNjI1MDkzMzAwWhcNMjYwNjIzMDkzMzAwWjBeMQswCQYDVQQGEwJB
|
|
||||||
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
|
|
||||||
cyBQdHkgTHRkMRcwFQYDVQQDEw5jYS5uZ2h0dHAyLm9yZzCCASIwDQYJKoZIhvcN
|
|
||||||
AQEBBQADggEPADCCAQoCggEBANZFZBfEElMFvx1fRBUT0jKIjlZmMAfL6ig7U9He
|
|
||||||
jBYigDPP2CRVKtripVMnYE+CDxOzwE71XCI9xrS/V8z4bHKmDv0tGO7HMkxNlQD5
|
|
||||||
rc/krT1n9sGdSEEdPR65w03OOCr2BmaXnwWZA/VI25ifWtWZiYyYjK94U5yhP7MW
|
|
||||||
dvnTLJzGVzfNtnH2h8kzfk9Pk8sObwQW6Ag7Gc8Zn/vRRSAyTbNzS9+HEfBGUYaX
|
|
||||||
2noGqR/G7Tifg/kWdpIOxP2GJBnEujaHb040lBQhR6Voxwn0xYZ/6MASAKKAnVqK
|
|
||||||
4enXPEO9pQKHcDS10vLrj4D6jObOAs+e5u2YLODopTZiHWsCAwEAAaNjMGEwDgYD
|
|
||||||
VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNA5xVR1Zcax
|
|
||||||
RJL9VC6pzuLmvduGMB8GA1UdIwQYMBaAFNA5xVR1ZcaxRJL9VC6pzuLmvduGMA0G
|
|
||||||
CSqGSIb3DQEBCwUAA4IBAQCmdVfn/hUyEdvkKG7svg5d8o6BENOj8695KtWmzJjK
|
|
||||||
zxH8J5Vy3mn89XrHQ+BOYXCDPyhs0aDS8aq3Z+HY0n9z1oAicyGzlVwZQQNX3YId
|
|
||||||
Y2vcf7qu/2ATm/1S+mebE1/EXMUlWISKKUYXjggCwFgjDhH87Ai+A8MKScVdmqgL
|
|
||||||
Hf+fRSzH3ToW7BCXlRl5bPAq2g+v1ALYc8wU9cT1MYm4dqAXh870LGFyUpaSWmFr
|
|
||||||
TtX1DXBTgLp62syNlDthAvGigYFDtCa4cDM2vdTD9wpec2V9EKpfVqiRDDuYjUVX
|
|
||||||
UXl27MvkNWnEBKCIoNv5abWXpZVG2zQdEMmUOkVuAXUC
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -181,9 +181,7 @@ static int deflate_hd_json(json_t *obj, nghttp2_hd_deflater *deflater,
|
|||||||
static nghttp2_hd_deflater *init_deflater() {
|
static nghttp2_hd_deflater *init_deflater() {
|
||||||
nghttp2_hd_deflater *deflater;
|
nghttp2_hd_deflater *deflater;
|
||||||
nghttp2_hd_deflate_new(&deflater, config.deflate_table_size);
|
nghttp2_hd_deflate_new(&deflater, config.deflate_table_size);
|
||||||
if (config.table_size != NGHTTP2_DEFAULT_HEADER_TABLE_SIZE) {
|
nghttp2_hd_deflate_change_table_size(deflater, config.table_size);
|
||||||
nghttp2_hd_deflate_change_table_size(deflater, config.table_size);
|
|
||||||
}
|
|
||||||
return deflater;
|
return deflater;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,8 +367,7 @@ OPTIONS:
|
|||||||
buffer.
|
buffer.
|
||||||
Default: 4096
|
Default: 4096
|
||||||
-d, --dump-header-table
|
-d, --dump-header-table
|
||||||
Output dynamic header table.)"
|
Output dynamic header table.)" << std::endl;
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
|
|||||||
275
src/h2load.cc
275
src/h2load.cc
@@ -92,8 +92,6 @@ Config::Config()
|
|||||||
conn_active_timeout(0.),
|
conn_active_timeout(0.),
|
||||||
conn_inactivity_timeout(0.),
|
conn_inactivity_timeout(0.),
|
||||||
no_tls_proto(PROTO_HTTP2),
|
no_tls_proto(PROTO_HTTP2),
|
||||||
header_table_size(4_k),
|
|
||||||
encoder_header_table_size(4_k),
|
|
||||||
data_fd(-1),
|
data_fd(-1),
|
||||||
port(0),
|
port(0),
|
||||||
default_port(0),
|
default_port(0),
|
||||||
@@ -271,7 +269,7 @@ bool check_stop_client_request_timeout(Client *client, ev_timer *w) {
|
|||||||
auto nreq = client->req_todo - client->req_started;
|
auto nreq = client->req_todo - client->req_started;
|
||||||
|
|
||||||
if (nreq == 0 ||
|
if (nreq == 0 ||
|
||||||
client->streams.size() >= client->session->max_concurrent_streams()) {
|
client->streams.size() >= (size_t)config.max_concurrent_streams) {
|
||||||
// no more requests to make, stop timer
|
// no more requests to make, stop timer
|
||||||
ev_timer_stop(client->worker->loop, w);
|
ev_timer_stop(client->worker->loop, w);
|
||||||
return true;
|
return true;
|
||||||
@@ -320,8 +318,7 @@ void client_request_timeout_cb(struct ev_loop *loop, ev_timer *w, int revents) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Client::Client(uint32_t id, Worker *worker, size_t req_todo)
|
Client::Client(uint32_t id, Worker *worker, size_t req_todo)
|
||||||
: wb(&worker->mcpool),
|
: cstat{},
|
||||||
cstat{},
|
|
||||||
worker(worker),
|
worker(worker),
|
||||||
ssl(nullptr),
|
ssl(nullptr),
|
||||||
next_addr(config.addrs),
|
next_addr(config.addrs),
|
||||||
@@ -333,8 +330,7 @@ Client::Client(uint32_t id, Worker *worker, size_t req_todo)
|
|||||||
req_done(0),
|
req_done(0),
|
||||||
id(id),
|
id(id),
|
||||||
fd(-1),
|
fd(-1),
|
||||||
new_connection_requested(false),
|
new_connection_requested(false) {
|
||||||
final(false) {
|
|
||||||
ev_io_init(&wev, writecb, 0, EV_WRITE);
|
ev_io_init(&wev, writecb, 0, EV_WRITE);
|
||||||
ev_io_init(&rev, readcb, 0, EV_READ);
|
ev_io_init(&rev, readcb, 0, EV_READ);
|
||||||
|
|
||||||
@@ -522,8 +518,6 @@ void Client::disconnect() {
|
|||||||
close(fd);
|
close(fd);
|
||||||
fd = -1;
|
fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
final = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::submit_request() {
|
int Client::submit_request() {
|
||||||
@@ -866,7 +860,7 @@ int Client::connection_made() {
|
|||||||
|
|
||||||
if (!config.timing_script) {
|
if (!config.timing_script) {
|
||||||
auto nreq =
|
auto nreq =
|
||||||
std::min(req_todo - req_started, session->max_concurrent_streams());
|
std::min(req_todo - req_started, (size_t)config.max_concurrent_streams);
|
||||||
for (; nreq > 0; --nreq) {
|
for (; nreq > 0; --nreq) {
|
||||||
if (submit_request() != 0) {
|
if (submit_request() != 0) {
|
||||||
process_request_failure();
|
process_request_failure();
|
||||||
@@ -913,10 +907,6 @@ int Client::on_read(const uint8_t *data, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Client::on_write() {
|
int Client::on_write() {
|
||||||
if (wb.rleft() >= BACKOFF_WRITE_BUFFER_THRES) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->on_write() != 0) {
|
if (session->on_write() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -950,32 +940,28 @@ int Client::read_clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Client::write_clear() {
|
int Client::write_clear() {
|
||||||
std::array<struct iovec, 2> iov;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (wb.rleft() > 0) {
|
||||||
|
ssize_t nwrite;
|
||||||
|
while ((nwrite = write(fd, wb.pos, wb.rleft())) == -1 && errno == EINTR)
|
||||||
|
;
|
||||||
|
if (nwrite == -1) {
|
||||||
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
|
ev_io_start(worker->loop, &wev);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
wb.drain(nwrite);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wb.reset();
|
||||||
if (on_write() != 0) {
|
if (on_write() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (wb.rleft() == 0) {
|
||||||
auto iovcnt = wb.riovec(iov.data(), iov.size());
|
|
||||||
|
|
||||||
if (iovcnt == 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t nwrite;
|
|
||||||
while ((nwrite = writev(fd, iov.data(), iovcnt)) == -1 && errno == EINTR)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (nwrite == -1) {
|
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
||||||
ev_io_start(worker->loop, &wev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
wb.drain(nwrite);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ev_io_stop(worker->loop, &wev);
|
ev_io_stop(worker->loop, &wev);
|
||||||
@@ -1068,36 +1054,35 @@ int Client::read_tls() {
|
|||||||
int Client::write_tls() {
|
int Client::write_tls() {
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
struct iovec iov;
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if (wb.rleft() > 0) {
|
||||||
|
auto rv = SSL_write(ssl, wb.pos, wb.rleft());
|
||||||
|
|
||||||
|
if (rv <= 0) {
|
||||||
|
auto err = SSL_get_error(ssl, rv);
|
||||||
|
switch (err) {
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
// renegotiation started
|
||||||
|
return -1;
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
ev_io_start(worker->loop, &wev);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wb.drain(rv);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wb.reset();
|
||||||
if (on_write() != 0) {
|
if (on_write() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (wb.rleft() == 0) {
|
||||||
auto iovcnt = wb.riovec(&iov, 1);
|
|
||||||
|
|
||||||
if (iovcnt == 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rv = SSL_write(ssl, iov.iov_base, iov.iov_len);
|
|
||||||
|
|
||||||
if (rv <= 0) {
|
|
||||||
auto err = SSL_get_error(ssl, rv);
|
|
||||||
switch (err) {
|
|
||||||
case SSL_ERROR_WANT_READ:
|
|
||||||
// renegotiation started
|
|
||||||
return -1;
|
|
||||||
case SSL_ERROR_WANT_WRITE:
|
|
||||||
ev_io_start(worker->loop, &wev);
|
|
||||||
return 0;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wb.drain(rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ev_io_stop(worker->loop, &wev);
|
ev_io_stop(worker->loop, &wev);
|
||||||
@@ -1339,8 +1324,7 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
|||||||
}
|
}
|
||||||
request_times.push_back(
|
request_times.push_back(
|
||||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||||
req_stat.stream_close_time - req_stat.request_time)
|
req_stat.stream_close_time - req_stat.request_time).count());
|
||||||
.count());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &stat = w->stats;
|
const auto &stat = w->stats;
|
||||||
@@ -1349,8 +1333,7 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
|||||||
if (recorded(cstat.client_start_time) &&
|
if (recorded(cstat.client_start_time) &&
|
||||||
recorded(cstat.client_end_time)) {
|
recorded(cstat.client_end_time)) {
|
||||||
auto t = std::chrono::duration_cast<std::chrono::duration<double>>(
|
auto t = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||||
cstat.client_end_time - cstat.client_start_time)
|
cstat.client_end_time - cstat.client_start_time).count();
|
||||||
.count();
|
|
||||||
if (t > 1e-9) {
|
if (t > 1e-9) {
|
||||||
rps_values.push_back(cstat.req_success / t);
|
rps_values.push_back(cstat.req_success / t);
|
||||||
}
|
}
|
||||||
@@ -1364,8 +1347,7 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
|||||||
|
|
||||||
connect_times.push_back(
|
connect_times.push_back(
|
||||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||||
cstat.connect_time - cstat.connect_start_time)
|
cstat.connect_time - cstat.connect_start_time).count());
|
||||||
.count());
|
|
||||||
|
|
||||||
if (!recorded(cstat.ttfb)) {
|
if (!recorded(cstat.ttfb)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -1373,8 +1355,7 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
|||||||
|
|
||||||
ttfb_times.push_back(
|
ttfb_times.push_back(
|
||||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||||
cstat.ttfb - cstat.connect_start_time)
|
cstat.ttfb - cstat.connect_start_time).count());
|
||||||
.count());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1591,27 +1572,6 @@ std::unique_ptr<Worker> create_worker(uint32_t id, SSL_CTX *ssl_ctx,
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
|
||||||
int parse_header_table_size(uint32_t &dst, const char *opt,
|
|
||||||
const char *optarg) {
|
|
||||||
auto n = util::parse_uint_with_unit(optarg);
|
|
||||||
if (n == -1) {
|
|
||||||
std::cerr << "--" << opt << ": Bad option value: " << optarg << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (n > std::numeric_limits<uint32_t>::max()) {
|
|
||||||
std::cerr << "--" << opt
|
|
||||||
<< ": Value too large. It should be less than or equal to "
|
|
||||||
<< std::numeric_limits<uint32_t>::max() << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst = n;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void print_version(std::ostream &out) {
|
void print_version(std::ostream &out) {
|
||||||
out << "h2load nghttp2/" NGHTTP2_VERSION << std::endl;
|
out << "h2load nghttp2/" NGHTTP2_VERSION << std::endl;
|
||||||
@@ -1621,8 +1581,7 @@ void print_version(std::ostream &out) {
|
|||||||
namespace {
|
namespace {
|
||||||
void print_usage(std::ostream &out) {
|
void print_usage(std::ostream &out) {
|
||||||
out << R"(Usage: h2load [OPTIONS]... [URI]...
|
out << R"(Usage: h2load [OPTIONS]... [URI]...
|
||||||
benchmarking tool for HTTP/2 and SPDY server)"
|
benchmarking tool for HTTP/2 and SPDY server)" << std::endl;
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1654,17 +1613,14 @@ Options:
|
|||||||
with --timing-script-file option, this option specifies
|
with --timing-script-file option, this option specifies
|
||||||
the number of requests each client performs rather than
|
the number of requests each client performs rather than
|
||||||
the number of requests across all clients.
|
the number of requests across all clients.
|
||||||
Default: )"
|
Default: )" << config.nreqs << R"(
|
||||||
<< config.nreqs << R"(
|
|
||||||
-c, --clients=<N>
|
-c, --clients=<N>
|
||||||
Number of concurrent clients. With -r option, this
|
Number of concurrent clients. With -r option, this
|
||||||
specifies the maximum number of connections to be made.
|
specifies the maximum number of connections to be made.
|
||||||
Default: )"
|
Default: )" << config.nclients << R"(
|
||||||
<< config.nclients << R"(
|
|
||||||
-t, --threads=<N>
|
-t, --threads=<N>
|
||||||
Number of native threads.
|
Number of native threads.
|
||||||
Default: )"
|
Default: )" << config.nthreads << R"(
|
||||||
<< config.nthreads << R"(
|
|
||||||
-i, --input-file=<PATH>
|
-i, --input-file=<PATH>
|
||||||
Path of a file with multiple URIs are separated by EOLs.
|
Path of a file with multiple URIs are separated by EOLs.
|
||||||
This option will disable URIs getting from command-line.
|
This option will disable URIs getting from command-line.
|
||||||
@@ -1683,15 +1639,13 @@ Options:
|
|||||||
-w, --window-bits=<N>
|
-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: )"
|
Default: )" << config.window_bits << R"(
|
||||||
<< config.window_bits << R"(
|
|
||||||
-W, --connection-window-bits=<N>
|
-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.
|
||||||
Default: )"
|
Default: )" << config.connection_window_bits << R"(
|
||||||
<< config.connection_window_bits << R"(
|
|
||||||
-H, --header=<HEADER>
|
-H, --header=<HEADER>
|
||||||
Add/Override a header to the requests.
|
Add/Override a header to the requests.
|
||||||
--ciphers=<SUITE>
|
--ciphers=<SUITE>
|
||||||
@@ -1709,15 +1663,11 @@ Options:
|
|||||||
Available protocols: )";
|
Available protocols: )";
|
||||||
#endif // !HAVE_SPDYLAY
|
#endif // !HAVE_SPDYLAY
|
||||||
out << NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"( and
|
out << NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"( and
|
||||||
)"
|
)" << NGHTTP2_H1_1 << R"(
|
||||||
<< NGHTTP2_H1_1 << R"(
|
Default: )" << NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"(
|
||||||
Default: )"
|
|
||||||
<< NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"(
|
|
||||||
-d, --data=<PATH>
|
-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 -d is used, the
|
POST.
|
||||||
maximum number of in-flight pipelined requests is set to
|
|
||||||
1.
|
|
||||||
-r, --rate=<N>
|
-r, --rate=<N>
|
||||||
Specifies the fixed rate at which connections are
|
Specifies the fixed rate at which connections are
|
||||||
created. The rate must be a positive integer,
|
created. The rate must be a positive integer,
|
||||||
@@ -1786,22 +1736,10 @@ Options:
|
|||||||
NPN. The parameter must be delimited by a single comma
|
NPN. The parameter must be delimited by a single comma
|
||||||
only and any white spaces are treated as a part of
|
only and any white spaces are treated as a part of
|
||||||
protocol string.
|
protocol string.
|
||||||
Default: )"
|
Default: )" << DEFAULT_NPN_LIST << R"(
|
||||||
<< DEFAULT_NPN_LIST << R"(
|
|
||||||
--h1 Short hand for --npn-list=http/1.1
|
--h1 Short hand for --npn-list=http/1.1
|
||||||
--no-tls-proto=http/1.1, which effectively force
|
--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.
|
||||||
--header-table-size=<SIZE>
|
|
||||||
Specify decoder header table size.
|
|
||||||
Default: )"
|
|
||||||
<< util::utos_unit(config.header_table_size) << R"(
|
|
||||||
--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: )"
|
|
||||||
<< util::utos_unit(config.encoder_header_table_size) << R"(
|
|
||||||
-v, --verbose
|
-v, --verbose
|
||||||
Output debug information.
|
Output debug information.
|
||||||
--version Display version information and exit.
|
--version Display version information and exit.
|
||||||
@@ -1809,14 +1747,10 @@ 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
|
||||||
is omitted, a second is used as unit.)"
|
is omitted, a second is used as unit.)" << std::endl;
|
||||||
<< std::endl;
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1854,8 +1788,6 @@ int main(int argc, char **argv) {
|
|||||||
{"npn-list", required_argument, &flag, 4},
|
{"npn-list", required_argument, &flag, 4},
|
||||||
{"rate-period", required_argument, &flag, 5},
|
{"rate-period", required_argument, &flag, 5},
|
||||||
{"h1", no_argument, &flag, 6},
|
{"h1", no_argument, &flag, 6},
|
||||||
{"header-table-size", required_argument, &flag, 7},
|
|
||||||
{"encoder-header-table-size", required_argument, &flag, 8},
|
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
auto c = getopt_long(argc, argv, "hvW:c:d:m:n:p:t:w:H:i:r:T:N:B:",
|
auto c = getopt_long(argc, argv, "hvW:c:d:m:n:p:t:w:H:i:r:T:N:B:",
|
||||||
@@ -2056,20 +1988,6 @@ int main(int argc, char **argv) {
|
|||||||
util::parse_config_str_list(StringRef::from_lit("http/1.1"));
|
util::parse_config_str_list(StringRef::from_lit("http/1.1"));
|
||||||
config.no_tls_proto = Config::PROTO_HTTP1_1;
|
config.no_tls_proto = Config::PROTO_HTTP1_1;
|
||||||
break;
|
break;
|
||||||
case 7:
|
|
||||||
// --header-table-size
|
|
||||||
if (parse_header_table_size(config.header_table_size,
|
|
||||||
"header-table-size", optarg) != 0) {
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
// --encoder-header-table-size
|
|
||||||
if (parse_header_table_size(config.encoder_header_table_size,
|
|
||||||
"encoder-header-table-size", optarg) != 0) {
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -2137,8 +2055,7 @@ int main(int argc, char **argv) {
|
|||||||
if (config.nreqs > uris.size()) {
|
if (config.nreqs > uris.size()) {
|
||||||
std::cerr << "-n: the number of requests must be less than or equal "
|
std::cerr << "-n: the number of requests must be less than or equal "
|
||||||
"to the number of timing script entries. Setting number "
|
"to the number of timing script entries. Setting number "
|
||||||
"of requests to "
|
"of requests to " << uris.size() << std::endl;
|
||||||
<< uris.size() << std::endl;
|
|
||||||
|
|
||||||
config.nreqs = uris.size();
|
config.nreqs = uris.size();
|
||||||
}
|
}
|
||||||
@@ -2188,8 +2105,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (config.nclients < config.nthreads) {
|
if (config.nclients < config.nthreads) {
|
||||||
std::cerr << "-c, -t: the number of clients must be greater than or equal "
|
std::cerr << "-c, -t: the number of clients must be greater than or equal "
|
||||||
"to the number of threads."
|
"to the number of threads." << std::endl;
|
||||||
<< std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2202,8 +2118,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (config.rate > config.nclients) {
|
if (config.rate > config.nclients) {
|
||||||
std::cerr << "-r, -c: the connection rate must be smaller than or equal "
|
std::cerr << "-r, -c: the connection rate must be smaller than or equal "
|
||||||
"to the number of clients."
|
"to the number of clients." << std::endl;
|
||||||
<< std::endl;
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2299,11 +2214,6 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string content_length_str;
|
|
||||||
if (config.data_fd != -1) {
|
|
||||||
content_length_str = util::utos(config.data_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto method_it =
|
auto method_it =
|
||||||
std::find_if(std::begin(shared_nva), std::end(shared_nva),
|
std::find_if(std::begin(shared_nva), std::end(shared_nva),
|
||||||
[](const Header &nv) { return nv.name == ":method"; });
|
[](const Header &nv) { return nv.name == ":method"; });
|
||||||
@@ -2334,20 +2244,14 @@ int main(int argc, char **argv) {
|
|||||||
h1req += nv.value;
|
h1req += nv.value;
|
||||||
h1req += "\r\n";
|
h1req += "\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!content_length_str.empty()) {
|
|
||||||
h1req += "Content-Length: ";
|
|
||||||
h1req += content_length_str;
|
|
||||||
h1req += "\r\n";
|
|
||||||
}
|
|
||||||
h1req += "\r\n";
|
h1req += "\r\n";
|
||||||
|
|
||||||
config.h1reqs.push_back(std::move(h1req));
|
config.h1reqs.push_back(std::move(h1req));
|
||||||
|
|
||||||
// For nghttp2
|
// For nghttp2
|
||||||
std::vector<nghttp2_nv> nva;
|
std::vector<nghttp2_nv> nva;
|
||||||
// 2 for :path, and possible content-length
|
// 1 for :path
|
||||||
nva.reserve(2 + shared_nva.size());
|
nva.reserve(1 + shared_nva.size());
|
||||||
|
|
||||||
nva.push_back(http2::make_nv_ls(":path", req));
|
nva.push_back(http2::make_nv_ls(":path", req));
|
||||||
|
|
||||||
@@ -2355,18 +2259,12 @@ int main(int argc, char **argv) {
|
|||||||
nva.push_back(http2::make_nv(nv.name, nv.value, false));
|
nva.push_back(http2::make_nv(nv.name, nv.value, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!content_length_str.empty()) {
|
|
||||||
nva.push_back(http2::make_nv(StringRef::from_lit("content-length"),
|
|
||||||
StringRef{content_length_str}));
|
|
||||||
}
|
|
||||||
|
|
||||||
config.nva.push_back(std::move(nva));
|
config.nva.push_back(std::move(nva));
|
||||||
|
|
||||||
// For spdylay
|
// For spdylay
|
||||||
std::vector<const char *> cva;
|
std::vector<const char *> cva;
|
||||||
// 3 for :path, :version, and possible content-length, 1 for
|
// 2 for :path and :version, 1 for terminal nullptr
|
||||||
// terminal nullptr
|
cva.reserve(2 * (2 + shared_nva.size()) + 1);
|
||||||
cva.reserve(2 * (3 + shared_nva.size()) + 1);
|
|
||||||
|
|
||||||
cva.push_back(":path");
|
cva.push_back(":path");
|
||||||
cva.push_back(req.c_str());
|
cva.push_back(req.c_str());
|
||||||
@@ -2381,12 +2279,6 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
cva.push_back(":version");
|
cva.push_back(":version");
|
||||||
cva.push_back("HTTP/1.1");
|
cva.push_back("HTTP/1.1");
|
||||||
|
|
||||||
if (!content_length_str.empty()) {
|
|
||||||
cva.push_back("content-length");
|
|
||||||
cva.push_back(content_length_str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
cva.push_back(nullptr);
|
cva.push_back(nullptr);
|
||||||
|
|
||||||
config.nv.push_back(std::move(cva));
|
config.nv.push_back(std::move(cva));
|
||||||
@@ -2550,29 +2442,26 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::fixed << std::setprecision(2) << R"(
|
std::cout << std::fixed << std::setprecision(2) << R"(
|
||||||
finished in )"
|
finished in )" << util::format_duration(duration) << ", " << rps << " req/s, "
|
||||||
<< util::format_duration(duration) << ", " << rps << " req/s, "
|
|
||||||
<< util::utos_funit(bps) << R"(B/s
|
<< util::utos_funit(bps) << R"(B/s
|
||||||
requests: )" << stats.req_todo
|
requests: )" << stats.req_todo << " total, " << stats.req_started
|
||||||
<< " total, " << stats.req_started << " started, " << stats.req_done
|
<< " started, " << stats.req_done << " done, "
|
||||||
<< " done, " << stats.req_status_success << " succeeded, "
|
<< stats.req_status_success << " succeeded, " << stats.req_failed
|
||||||
<< stats.req_failed << " failed, " << stats.req_error
|
<< " failed, " << stats.req_error << " errored, "
|
||||||
<< " errored, " << stats.req_timedout << R"( timeout
|
<< stats.req_timedout << R"( timeout
|
||||||
status codes: )"
|
status codes: )" << stats.status[2] << " 2xx, " << stats.status[3] << " 3xx, "
|
||||||
<< stats.status[2] << " 2xx, " << stats.status[3] << " 3xx, "
|
|
||||||
<< stats.status[4] << " 4xx, " << stats.status[5] << R"( 5xx
|
<< stats.status[4] << " 4xx, " << stats.status[5] << R"( 5xx
|
||||||
traffic: )" << util::utos_funit(stats.bytes_total)
|
traffic: )" << util::utos_funit(stats.bytes_total) << "B (" << stats.bytes_total
|
||||||
<< "B (" << stats.bytes_total << ") total, "
|
<< ") total, " << util::utos_funit(stats.bytes_head) << "B ("
|
||||||
<< util::utos_funit(stats.bytes_head) << "B (" << stats.bytes_head
|
<< stats.bytes_head << ") headers (space savings "
|
||||||
<< ") headers (space savings " << header_space_savings * 100
|
<< header_space_savings * 100 << "%), "
|
||||||
<< "%), " << util::utos_funit(stats.bytes_body) << "B ("
|
<< util::utos_funit(stats.bytes_body) << "B (" << stats.bytes_body
|
||||||
<< stats.bytes_body << R"() data
|
<< R"() data
|
||||||
min max mean sd +/- sd
|
min max mean sd +/- sd
|
||||||
time for request: )"
|
time for request: )" << std::setw(10) << util::format_duration(ts.request.min)
|
||||||
<< std::setw(10) << util::format_duration(ts.request.min) << " "
|
<< " " << std::setw(10) << util::format_duration(ts.request.max)
|
||||||
<< std::setw(10) << util::format_duration(ts.request.max) << " "
|
<< " " << std::setw(10) << util::format_duration(ts.request.mean)
|
||||||
<< std::setw(10) << util::format_duration(ts.request.mean) << " "
|
<< " " << std::setw(10) << util::format_duration(ts.request.sd)
|
||||||
<< std::setw(10) << util::format_duration(ts.request.sd)
|
|
||||||
<< std::setw(9) << util::dtos(ts.request.within_sd) << "%"
|
<< std::setw(9) << util::dtos(ts.request.within_sd) << "%"
|
||||||
<< "\ntime for connect: " << std::setw(10)
|
<< "\ntime for connect: " << std::setw(10)
|
||||||
<< util::format_duration(ts.connect.min) << " " << std::setw(10)
|
<< util::format_duration(ts.connect.min) << " " << std::setw(10)
|
||||||
|
|||||||
12
src/h2load.h
12
src/h2load.h
@@ -50,15 +50,13 @@
|
|||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
#include "http2.h"
|
#include "http2.h"
|
||||||
#include "memchunk.h"
|
#include "buffer.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
|
||||||
using namespace nghttp2;
|
using namespace nghttp2;
|
||||||
|
|
||||||
namespace h2load {
|
namespace h2load {
|
||||||
|
|
||||||
constexpr auto BACKOFF_WRITE_BUFFER_THRES = 16_k;
|
|
||||||
|
|
||||||
class Session;
|
class Session;
|
||||||
struct Worker;
|
struct Worker;
|
||||||
|
|
||||||
@@ -96,8 +94,6 @@ struct Config {
|
|||||||
PROTO_SPDY3_1,
|
PROTO_SPDY3_1,
|
||||||
PROTO_HTTP1_1
|
PROTO_HTTP1_1
|
||||||
} no_tls_proto;
|
} no_tls_proto;
|
||||||
uint32_t header_table_size;
|
|
||||||
uint32_t encoder_header_table_size;
|
|
||||||
// file descriptor for upload data
|
// file descriptor for upload data
|
||||||
int data_fd;
|
int data_fd;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
@@ -229,7 +225,6 @@ struct Sampling {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Worker {
|
struct Worker {
|
||||||
MemchunkPool mcpool;
|
|
||||||
Stats stats;
|
Stats stats;
|
||||||
Sampling request_times_smp;
|
Sampling request_times_smp;
|
||||||
Sampling client_smp;
|
Sampling client_smp;
|
||||||
@@ -272,7 +267,6 @@ struct Stream {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Client {
|
struct Client {
|
||||||
DefaultMemchunks wb;
|
|
||||||
std::unordered_map<int32_t, Stream> streams;
|
std::unordered_map<int32_t, Stream> streams;
|
||||||
ClientStat cstat;
|
ClientStat cstat;
|
||||||
std::unique_ptr<Session> session;
|
std::unique_ptr<Session> session;
|
||||||
@@ -299,13 +293,11 @@ struct Client {
|
|||||||
// The client id per worker
|
// The client id per worker
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
int fd;
|
int fd;
|
||||||
|
Buffer<64_k> wb;
|
||||||
ev_timer conn_active_watcher;
|
ev_timer conn_active_watcher;
|
||||||
ev_timer conn_inactivity_watcher;
|
ev_timer conn_inactivity_watcher;
|
||||||
std::string selected_proto;
|
std::string selected_proto;
|
||||||
bool new_connection_requested;
|
bool new_connection_requested;
|
||||||
// true if the current connection will be closed, and no more new
|
|
||||||
// request cannot be processed.
|
|
||||||
bool final;
|
|
||||||
|
|
||||||
enum { ERR_CONNECT_FAIL = -100 };
|
enum { ERR_CONNECT_FAIL = -100 };
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace {
|
|||||||
int htp_msg_begincb(http_parser *htp) {
|
int htp_msg_begincb(http_parser *htp) {
|
||||||
auto session = static_cast<Http1Session *>(htp->data);
|
auto session = static_cast<Http1Session *>(htp->data);
|
||||||
|
|
||||||
if (session->stream_resp_counter_ > session->stream_req_counter_) {
|
if (session->stream_resp_counter_ >= session->stream_req_counter_) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,21 +82,16 @@ int htp_msg_completecb(http_parser *htp) {
|
|||||||
auto session = static_cast<Http1Session *>(htp->data);
|
auto session = static_cast<Http1Session *>(htp->data);
|
||||||
auto client = session->get_client();
|
auto client = session->get_client();
|
||||||
|
|
||||||
client->final = http_should_keep_alive(htp) == 0;
|
auto final = http_should_keep_alive(htp) == 0;
|
||||||
auto req_stat = client->get_req_stat(session->stream_resp_counter_);
|
auto req_stat = client->get_req_stat(session->stream_resp_counter_);
|
||||||
|
|
||||||
assert(req_stat);
|
assert(req_stat);
|
||||||
|
|
||||||
auto config = client->worker->config;
|
client->on_stream_close(session->stream_resp_counter_, true, final);
|
||||||
if (req_stat->data_offset >= config->data_length) {
|
|
||||||
client->on_stream_close(session->stream_resp_counter_, true, client->final);
|
|
||||||
}
|
|
||||||
|
|
||||||
session->stream_resp_counter_ += 2;
|
session->stream_resp_counter_ += 2;
|
||||||
|
|
||||||
if (client->final) {
|
if (final) {
|
||||||
session->stream_req_counter_ = session->stream_resp_counter_;
|
|
||||||
|
|
||||||
http_parser_pause(htp, 1);
|
http_parser_pause(htp, 1);
|
||||||
// Connection is going down. If we have still request to do,
|
// Connection is going down. If we have still request to do,
|
||||||
// create new connection and keep on doing the job.
|
// create new connection and keep on doing the job.
|
||||||
@@ -174,16 +169,12 @@ int Http1Session::submit_request() {
|
|||||||
auto req_stat = client_->get_req_stat(stream_req_counter_);
|
auto req_stat = client_->get_req_stat(stream_req_counter_);
|
||||||
|
|
||||||
client_->record_request_time(req_stat);
|
client_->record_request_time(req_stat);
|
||||||
client_->wb.append(req);
|
client_->wb.write(req.c_str(), req.size());
|
||||||
|
|
||||||
if (config->data_fd == -1 || config->data_length == 0) {
|
// increment for next request
|
||||||
// increment for next request
|
stream_req_counter_ += 2;
|
||||||
stream_req_counter_ += 2;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return on_write();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http1Session::on_read(const uint8_t *data, size_t len) {
|
int Http1Session::on_read(const uint8_t *data, size_t len) {
|
||||||
@@ -215,51 +206,6 @@ int Http1Session::on_write() {
|
|||||||
if (complete_) {
|
if (complete_) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto config = client_->worker->config;
|
|
||||||
auto req_stat = client_->get_req_stat(stream_req_counter_);
|
|
||||||
if (!req_stat) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req_stat->data_offset < config->data_length) {
|
|
||||||
auto req_stat = client_->get_req_stat(stream_req_counter_);
|
|
||||||
auto &wb = client_->wb;
|
|
||||||
|
|
||||||
// TODO unfortunately, wb has no interface to use with read(2)
|
|
||||||
// family functions.
|
|
||||||
std::array<uint8_t, 16_k> buf;
|
|
||||||
|
|
||||||
ssize_t nread;
|
|
||||||
while ((nread = pread(config->data_fd, buf.data(), buf.size(),
|
|
||||||
req_stat->data_offset)) == -1 &&
|
|
||||||
errno == EINTR)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (nread == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
req_stat->data_offset += nread;
|
|
||||||
|
|
||||||
wb.append(buf.data(), nread);
|
|
||||||
|
|
||||||
if (client_->worker->config->verbose) {
|
|
||||||
std::cout << "[send " << nread << " byte(s)]" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req_stat->data_offset == config->data_length) {
|
|
||||||
// increment for next request
|
|
||||||
stream_req_counter_ += 2;
|
|
||||||
|
|
||||||
if (stream_resp_counter_ == stream_req_counter_) {
|
|
||||||
// Response has already been received
|
|
||||||
client_->on_stream_close(stream_resp_counter_ - 2, true,
|
|
||||||
client_->final);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,10 +213,4 @@ void Http1Session::terminate() { complete_ = true; }
|
|||||||
|
|
||||||
Client *Http1Session::get_client() { return client_; }
|
Client *Http1Session::get_client() { return client_; }
|
||||||
|
|
||||||
size_t Http1Session::max_concurrent_streams() {
|
|
||||||
auto config = client_->worker->config;
|
|
||||||
|
|
||||||
return config->data_fd == -1 ? config->max_concurrent_streams : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace h2load
|
} // namespace h2load
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user