Compare commits

..

1 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
240a4057f3 HPACK huffman decode: Process 8 bits at a time 2016-02-08 23:34:15 +09:00
321 changed files with 77902 additions and 34965 deletions

View File

@@ -1,94 +1,57 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
ConstructorInitializerIndentWidth: 4
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
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
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
BinPackParameters: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: 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
IndentWidth: 2
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Cpp11BracedListStyle: true
Standard: Cpp11
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
...

16
.gitignore vendored
View File

@@ -29,22 +29,6 @@ missing
stamp-h1
test-driver
# cmake
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
install_manifest.txt
CTestTestfile.cmake
build.ninja
rules.ninja
.ninja_deps
.ninja_log
lib*.so
lib*.so.*
lib*.a
# generated by "make test" with cmake
Testing/
# test logs generated by `make check`
*.log
*.trs

View File

@@ -1,7 +1,3 @@
env:
matrix:
- CI_BUILD=cmake
- CI_BUILD=autotools
language: cpp
compiler:
- clang
@@ -11,7 +7,6 @@ addons:
apt:
sources:
- ubuntu-toolchain-r-test
- george-edison55-precise-backports
packages:
- g++-4.9
- libstdc++-4.9-dev
@@ -28,15 +23,11 @@ addons:
- libevent-dev
- libjansson-dev
- libjemalloc-dev
- libc-ares-dev
- cmake
- cmake-data
before_install:
- $CC --version
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
- $CC --version
- go version
- cmake --version
before_script:
# First build spdylay, since integration tests require it.
# spdylay is going to be built under third-party/spdylay
@@ -44,22 +35,18 @@ before_script:
- git clone https://github.com/tatsuhiro-t/spdylay.git
- cd spdylay
- autoreconf -i
# Don't use ASAN for spdylay since failmalloc does not work with it.
- ./configure --disable-src --disable-examples
- make check
- export SPDYLAY_HOME=$PWD
- cd ../..
# Now build nghttp2
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
- autoreconf -i
- 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" = "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
- ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"
script:
- if [ "$CI_BUILD" = "autotools" ]; then make distcheck; fi
- if [ "$CI_BUILD" = "cmake" ]; then make check; fi
# As of April, 23, 2016, golang http2 build fails, probably because
# the default go version is too old.
# - cd integration-tests
# - export GOPATH="$PWD/integration-tests/golang"
# - make itprep
# - make it
- make
- make check
- cd integration-tests
- export GOPATH="$PWD/integration-tests/golang"
- make itprep-local
- make it-local

90
AUTHORS
View File

@@ -1,89 +1 @@
nghttp2 project was started as a fork of spdylay project [1]. Both
projects were started by Tatsuhiro Tsujikawa, who is still the main
author of these projects. Meanwhile, we have many contributions, and
we are not here without them. We sincerely thank you to all who made
a contribution. Here is the all individuals/organizations who
contributed to nghttp2 and spdylay project at which we forked. These
names are retrieved from git commit log. If you have made a
contribution, but you are missing in the list, please let us know via
github issues [2].
[1] https://github.com/tatsuhiro-t/spdylay
[2] https://github.com/nghttp2/nghttp2/issues
--------
187j3x1
Alek Storm
Alex Nalivko
Alexis La Goutte
Anders Bakken
Andreas Pohl
Andy Davies
Ant Bryan
Bernard Spil
Brian Card
Brian Suh
Daniel Stenberg
Dave Reisner
David Beitey
David Weekly
Etienne Cimon
Fabian Möller
Fabian Wiesel
Gabi Davar
Google Inc.
Jacob Champion
Jan-E
Janusz Dziemidowicz
Jay Satiro
Jianqing Wang
Jim Morrison
José F. Calcerrada
Kamil Dudka
Kazuho Oku
Kenny (kang-yen) Peng
Kenny Peng
Kit Chan
Kyle Schomp
Lucas Pardue
MATSUMOTO Ryosuke
Matt Rudary
Mike Conlen
Mike Frysinger
Nicholas Hurley
Nora Shoemaker
Peeyush Aggarwal
Peter Wu
Piotr Sikora
Raul Gutierrez Segales
Remo E
Reza Tavakoli
Ross Smith II
Scott Mitchell
Stefan Eissing
Stephen Ludin
Sunpoet Po-Chuan Hsieh
Svante Signell
Syohei YOSHIDA
Tatsuhiko Kubo
Tatsuhiro Tsujikawa
Tom Harwood
Tomasz Buchert
Vernon Tang
Viacheslav Biriukov
Viktor Szépe
Wenfeng Liu
Xiaoguang Sun
Zhuoyun Wei
acesso
ayanamist
bxshi
dalf
es
fangdingjun
kumagi
mod-h2-dev
moparisthebest
snnn
yuuki-kodama
Tatsuhiro Tsujikawa <t-tujikawa at users dot sourceforge dot net>

View File

@@ -1,526 +0,0 @@
# nghttp2 - HTTP/2 C Library
#
# Copyright (c) 2012, 2013, 2014, 2015 Tatsuhiro Tsujikawa
# Copyright (c) 2016 Peter Wu <peter@lekensteyn.nl>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cmake_minimum_required(VERSION 3.0)
# XXX using 1.8.90 instead of 1.9.0-DEV
project(nghttp2 VERSION 1.18.1)
# See versioning rule:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
set(LT_CURRENT 26)
set(LT_REVISION 3)
set(LT_AGE 12)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Version)
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}")
set(PACKAGE_VERSION "${PROJECT_VERSION}")
HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH})
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE)
# Include "None" as option to disable any additional (optimization) flags,
# relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by
# default). These strings are presented in cmake-gui.
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
include(GNUInstallDirs)
# For Python bindings and documentation
# (Must be called before PythonLibs for matching versions.)
find_package(PythonInterp)
# Auto-detection of features that can be toggled
find_package(OpenSSL 1.0.1)
find_package(Libev 4.11)
find_package(Libcares 1.7.5)
find_package(ZLIB 1.2.3)
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
set(ENABLE_APP_DEFAULT ON)
else()
set(ENABLE_APP_DEFAULT OFF)
endif()
find_package(Jansson 2.5)
set(ENABLE_HPACK_TOOLS_DEFAULT ${JANSSON_FOUND})
# 2.0.8 is required because we use evconnlistener_set_error_cb()
find_package(Libevent 2.0.8 COMPONENTS libevent openssl)
set(ENABLE_EXAMPLES_DEFAULT ${LIBEVENT_OPENSSL_FOUND})
find_package(Cython)
find_package(PythonLibs)
if(CYTHON_FOUND AND PYTHONLIBS_FOUND)
set(ENABLE_PYTHON_BINDINGS_DEFAULT ON)
else()
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
endif()
find_package(LibXml2 2.7.7)
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
find_package(Jemalloc)
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
find_package(Spdylay 1.3.2)
set(WITH_SPDYLAY_DEFAULT ${SPDYLAY_FOUND})
include(CMakeOptions.txt)
if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_EXAMPLES OR
ENABLE_PYTHON_BINDINGS))
# Remember when disabled options are disabled for later diagnostics.
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1)
else()
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0)
endif()
if(ENABLE_LIB_ONLY)
set(ENABLE_APP OFF)
set(ENABLE_HPACK_TOOLS OFF)
set(ENABLE_EXAMPLES OFF)
set(ENABLE_PYTHON_BINDINGS OFF)
endif()
# Do not disable assertions based on CMAKE_BUILD_TYPE.
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
foreach(_lang C CXX)
string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" "" ${_var} "${${_var}}")
endforeach()
endforeach()
#
# If we're running GCC or clang define _U_ to be "__attribute__((unused))"
# so we can use _U_ to flag unused function parameters and not get warnings
# about them. Otherwise, define _U_ to be an empty string so that _U_ used
# to flag an unused function parameters will compile with other compilers.
#
# XXX - similar hints for other compilers?
#
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(HINT_UNUSED_PARAM "__attribute__((unused))")
set(HINT_NORETURN "__attribute__((noreturn))")
else()
set(HINT_UNUSED_PARAM)
set(HINT_NORETURN)
endif()
include(ExtractValidFlags)
foreach(_cxx1x_flag -std=c++11 -std=c++0x)
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
if(_cxx1x_flag_supported)
set(CXX1XCXXFLAGS ${_cxx1x_flag})
break()
endif()
endforeach()
include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
cmake_push_check_state()
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
# Check that std::future is available.
check_cxx_source_compiles("
#include <vector>
#include <future>
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
# Check that std::map::emplace is available for g++-4.7.
check_cxx_source_compiles("
#include <map>
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
cmake_pop_check_state()
# Checks for libraries.
# Additional libraries required for programs under src directory.
set(APP_LIBRARIES)
if(ENABLE_PYTHON_BINDINGS)
if(NOT (CYTHON_FOUND AND PYTHONLIBS_FOUND))
message(FATAL_ERROR "python bindings were requested "
"(ENABLE_PYTHON_BINDINGS=1) but dependencies are not met.")
endif()
if(NOT PYTHON_VERSION_STRING STREQUAL PYTHONLIBS_VERSION_STRING)
message(FATAL_ERROR
"Python executable and library must have the same version!"
" Found Python ${PYTHON_VERSION_STRING} and"
" PythonLibs ${PYTHONLIBS_VERSION_STRING}"
)
endif()
endif()
set(CMAKE_THREAD_PREFER_PTHREAD 1)
find_package(Threads)
if(CMAKE_USE_PTHREADS_INIT)
list(APPEND APP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
# XXX android and C++, is this still needed in cmake?
# case "$host" in
# *android*)
# android_build=yes
# # android does not need -pthread, but needs followng 3 libs for C++
# APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
# dl: openssl requires libdl when it is statically linked.
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
# APP_LIBRARIES if it is really specific to OpenSSL?
find_package(CUnit 2.1)
enable_testing()
set(HAVE_CUNIT ${CUNIT_FOUND})
if(HAVE_CUNIT)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
endif()
# openssl (for src)
set(HAVE_OPENSSL ${OPENSSL_FOUND})
if(OPENSSL_FOUND)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
else()
set(OPENSSL_INCLUDE_DIRS "")
set(OPENSSL_LIBRARIES "")
endif()
# libev (for src)
set(HAVE_LIBEV ${LIBEV_FOUND})
set(HAVE_ZLIB ${ZLIB_FOUND})
set(HAVE_LIBEVENT_OPENSSL ${LIBEVENT_FOUND})
if(LIBEVENT_FOUND)
# Must both link the core and openssl libraries.
set(LIBEVENT_OPENSSL_LIBRARIES ${LIBEVENT_LIBRARIES})
endif()
# libc-ares (for src)
set(HAVE_LIBCARES ${LIBCARES_FOUND})
if(LIBCARES_FOUND)
set(LIBCARES_INCLUDE_DIRS ${LIBCARES_INCLUDE_DIR})
else()
set(LIBCARES_INCLUDE_DIRS "")
set(LIBCARES_LIBRARIES "")
endif()
# jansson (for src/nghttp, src/deflatehd and src/inflatehd)
set(HAVE_JANSSON ${JANSSON_FOUND})
# libxml2 (for src/nghttp)
set(HAVE_LIBXML2 ${LIBXML2_FOUND})
if(LIBXML2_FOUND)
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
else()
set(LIBXML2_INCLUDE_DIRS "")
set(LIBXML2_LIBRARIES "")
endif()
# jemalloc
set(HAVE_JEMALLOC ${JEMALLOC_FOUND})
# spdylay (for src/nghttpx and src/h2load)
set(HAVE_SPDYLAY ${SPDYLAY_FOUND})
if(ENABLE_ASIO_LIB)
find_package(Boost 1.54.0 REQUIRED system thread)
endif()
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
endif()
# HPACK tools requires jansson
if(ENABLE_HPACK_TOOLS AND NOT HAVE_JANSSON)
message(FATAL_ERROR "HPACK tools were requested (ENABLE_HPACK_TOOLS=1) but dependencies are not met.")
endif()
# C++ library libnghttp2_asio
if(ENABLE_EXAMPLES AND NOT (OPENSSL_FOUND AND LIBEVENT_OPENSSL_FOUND))
message(FATAL_ERROR "examples were requested (ENABLE_EXAMPLES=1) but dependencies are not met.")
endif()
# third-party http-parser only be built when needed
if(ENABLE_EXAMPLES OR ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_ASIO_LIB)
set(ENABLE_THIRD_PARTY 1)
# mruby (for src/nghttpx)
set(HAVE_MRUBY ${WITH_MRUBY})
set(HAVE_NEVERBLEED ${WITH_NEVERBLEED})
else()
set(HAVE_MRUBY 0)
set(HAVE_NEVERBLEED 0)
endif()
# Checks for header files.
include(CheckIncludeFile)
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
check_include_file("inttypes.h" HAVE_INTTYPES_H)
check_include_file("limits.h" HAVE_LIMITS_H)
check_include_file("netdb.h" HAVE_NETDB_H)
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file("pwd.h" HAVE_PWD_H)
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
check_include_file("syslog.h" HAVE_SYSLOG_H)
check_include_file("time.h" HAVE_TIME_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
include(CheckTypeSize)
# Checks for typedefs, structures, and compiler characteristics.
# AC_TYPE_SIZE_T
check_type_size("ssize_t" SIZEOF_SSIZE_T)
if(SIZEOF_SSIZE_T STREQUAL "")
# ssize_t is a signed type in POSIX storing at least -1.
# Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools).
set(ssize_t int)
endif()
# AC_TYPE_UINT8_T
# AC_TYPE_UINT16_T
# AC_TYPE_UINT32_T
# AC_TYPE_UINT64_T
# AC_TYPE_INT8_T
# AC_TYPE_INT16_T
# AC_TYPE_INT32_T
# AC_TYPE_INT64_T
# AC_TYPE_OFF_T
# AC_TYPE_PID_T
# AC_TYPE_UID_T
# XXX To support inline for crappy compilers, see https://cmake.org/Wiki/CMakeTestInline
# AC_C_INLINE
# XXX is AC_SYS_LARGEFILE still needed for modern systems?
# add_definitions(-D_FILE_OFFSET_BITS=64)
include(CheckStructHasMember)
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
# Check size of pointer to decide we need 8 bytes alignment adjustment.
check_type_size("int *" SIZEOF_INT_P)
check_type_size("time_t" SIZEOF_TIME_T)
# Checks for library functions.
include(CheckFunctionExists)
check_function_exists(_Exit HAVE__EXIT)
check_function_exists(accept4 HAVE_ACCEPT4)
include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin?
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
# FreeBSD declares initgroups() in unistd.h
check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2)
if(HAVE_DECL_INITGROUPS2)
set(HAVE_DECL_INITGROUPS 1)
endif()
endif()
set(WARNCFLAGS)
set(WARNCXXFLAGS)
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
if(ENABLE_WERROR)
set(WARNCFLAGS /WX)
set(WARNCXXFLAGS /WX)
endif()
else()
if(ENABLE_WERROR)
extract_valid_c_flags(WARNCFLAGS -Werror)
extract_valid_c_flags(WARNCXXFLAGS -Werror)
endif()
# For C compiler
extract_valid_c_flags(WARNCFLAGS
-Wall
-Wextra
-Wmissing-prototypes
-Wstrict-prototypes
-Wmissing-declarations
-Wpointer-arith
-Wdeclaration-after-statement
-Wformat-security
-Wwrite-strings
-Wshadow
-Winline
-Wnested-externs
-Wfloat-equal
-Wundef
-Wendif-labels
-Wempty-body
-Wcast-align
-Wclobbered
-Wvla
-Wpragmas
-Wunreachable-code
-Waddress
-Wattributes
-Wdiv-by-zero
-Wshorten-64-to-32
-Wconversion
-Wextended-offsetof
-Wformat-nonliteral
-Wlanguage-extension-token
-Wmissing-field-initializers
-Wmissing-noreturn
-Wmissing-variable-declarations
# Not used because we cannot change public structs
# -Wpadded
-Wsign-conversion
# Not used because this basically disallows default case
# -Wswitch-enum
-Wunreachable-code-break
-Wunused-macros
-Wunused-parameter
-Wredundant-decls
# Only work with Clang for the moment
-Wheader-guard
# This is required because we pass format string as "const char*.
-Wno-format-nonliteral
)
extract_valid_cxx_flags(WARNCXXFLAGS
# For C++ compiler
-Wall
-Wformat-security
)
endif()
if(ENABLE_DEBUG)
set(DEBUGBUILD 1)
endif()
# Some platform does not have working std::future. We disable
# threading for those platforms.
if(NOT ENABLE_THREADS OR NOT HAVE_STD_FUTURE)
set(NOTHREADS 1)
endif()
add_definitions(-DHAVE_CONFIG_H)
configure_file(cmakeconfig.h.in config.h)
# autotools-compatible names
# Sphinx expects relative paths in the .rst files. Use the fact that the files
# below are all one directory level deep.
file(RELATIVE_PATH top_srcdir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}")
file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}")
set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
# libnghttp2.pc (pkg-config file)
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
set(VERSION "${PACKAGE_VERSION}")
# For init scripts and systemd service file (in contrib/)
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
set(sbindir "${CMAKE_INSTALL_FULL_SBINDIR}")
foreach(name
lib/libnghttp2.pc
lib/includes/nghttp2/nghttp2ver.h
src/libnghttp2_asio.pc
python/setup.py
integration-tests/config.go
integration-tests/setenv
doc/conf.py
doc/index.rst
doc/package_README.rst
doc/tutorial-client.rst
doc/tutorial-server.rst
doc/tutorial-hpack.rst
doc/nghttpx-howto.rst
doc/h2load-howto.rst
doc/libnghttp2_asio.rst
doc/python-apiref.rst
doc/building-android-binary.rst
doc/nghttp2.h.rst
doc/nghttp2ver.h.rst
doc/asio_http2.h.rst
doc/asio_http2_server.h.rst
doc/asio_http2_client.h.rst
doc/contribute.rst
)
configure_file("${name}.in" "${name}" @ONLY)
endforeach()
include_directories(
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
)
# For use in src/CMakeLists.txt
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
install(FILES README.rst DESTINATION "${CMAKE_INSTALL_DOCDIR}")
add_subdirectory(lib)
#add_subdirectory(lib/includes)
add_subdirectory(third-party)
add_subdirectory(src)
#add_subdirectory(src/includes)
add_subdirectory(examples)
add_subdirectory(python)
add_subdirectory(tests)
#add_subdirectory(tests/testdata)
add_subdirectory(integration-tests)
add_subdirectory(doc)
add_subdirectory(contrib)
add_subdirectory(script)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
message(STATUS "summary of build options:
Package version: ${VERSION}
Library version: ${LT_CURRENT}:${LT_REVISION}:${LT_AGE}
Install prefix: ${CMAKE_INSTALL_PREFIX}
Target system: ${CMAKE_SYSTEM_NAME}
Compiler:
Build type: ${CMAKE_BUILD_TYPE}
C compiler: ${CMAKE_C_COMPILER}
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
C++ compiler: ${CMAKE_CXX_COMPILER}
CXXFLAGS: ${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
WARNCFLAGS: ${WARNCFLAGS}
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
Python:
Python: ${PYTHON_EXECUTABLE}
PYTHON_VERSION: ${PYTHON_VERSION_STRING}
Library version:${PYTHONLIBS_VERSION_STRING}
Cython: ${CYTHON_EXECUTABLE}
Test:
CUnit: ${HAVE_CUNIT} (LIBS='${CUNIT_LIBRARIES}')
Failmalloc: ${ENABLE_FAILMALLOC}
Libs:
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
Libxml2: ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
Libevent(SSL): ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
Spdylay: ${HAVE_SPDYLAY} (LIBS='${SPDYLAY_LIBRARIES}')
Jansson: ${HAVE_JANSSON} (LIBS='${JANSSON_LIBRARIES}')
Jemalloc: ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
Zlib: ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
Boost::System: ${Boost_SYSTEM_LIBRARY}
Boost::Thread: ${Boost_THREAD_LIBRARY}
Third-party:
http-parser: ${ENABLE_THIRD_PARTY}
MRuby: ${HAVE_MRUBY}
Neverbleed: ${HAVE_NEVERBLEED}
Features:
Applications: ${ENABLE_APP}
HPACK tools: ${ENABLE_HPACK_TOOLS}
Libnghttp2_asio:${ENABLE_ASIO_LIB}
Examples: ${ENABLE_EXAMPLES}
Python bindings:${ENABLE_PYTHON_BINDINGS}
Threading: ${ENABLE_THREADS}
")
if(ENABLE_LIB_ONLY_DISABLED_OTHERS)
message("Only the library will be built. To build other components "
"(such as applications and examples), set ENABLE_LIB_ONLY=OFF.")
endif()

View File

@@ -1,27 +0,0 @@
# Features that can be enabled for cmake (see CMakeLists.txt)
option(ENABLE_WERROR "Turn on compile time warnings")
option(ENABLE_DEBUG "Turn on debug output")
option(ENABLE_THREADS "Turn on threading in apps" ON)
option(ENABLE_APP "Build applications (nghttp, nghttpd, nghttpx and h2load)"
${ENABLE_APP_DEFAULT})
option(ENABLE_HPACK_TOOLS "Build HPACK tools"
${ENABLE_HPACK_TOOLS_DEFAULT})
option(ENABLE_ASIO_LIB "Build C++ libnghttp2_asio library")
option(ENABLE_EXAMPLES "Build examples"
${ENABLE_EXAMPLES_DEFAULT})
option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
${ENABLE_PYTHON_BINDINGS_DEFAULT})
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
option(WITH_LIBXML2 "Use libxml2"
${WITH_LIBXML2_DEFAULT})
option(WITH_JEMALLOC "Use jemalloc"
${WITH_JEMALLOC_DEFAULT})
option(WITH_SPDYLAY "Use spdylay"
${WITH_SPDYLAY_DEFAULT})
option(WITH_MRUBY "Use mruby")
option(WITH_NEVERBLEED "Use neverbleed")
# vim: ft=cmake:

View File

@@ -1,7 +1,6 @@
The MIT License
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -106,7 +106,7 @@ RUN HOST=arm-linux-androideabi \
make install
WORKDIR /root/build
RUN git clone https://github.com/nghttp2/nghttp2
RUN git clone https://github.com/tatsuhiro-t/nghttp2
WORKDIR /root/build/nghttp2
RUN autoreconf -i && \
./configure \

View File

@@ -33,20 +33,7 @@ ACLOCAL_AMFLAGS = -I m4
dist_doc_DATA = README.rst
EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
Dockerfile.android \
cmakeconfig.h.in \
CMakeLists.txt \
CMakeOptions.txt \
cmake/FindSpdylay.cmake \
cmake/ExtractValidFlags.cmake \
cmake/FindJemalloc.cmake \
cmake/FindLibev.cmake \
cmake/FindCUnit.cmake \
cmake/Version.cmake \
cmake/FindCython.cmake \
cmake/FindLibevent.cmake \
cmake/FindJansson.cmake \
cmake/FindLibcares.cmake
Dockerfile.android
.PHONY: clang-format
@@ -56,6 +43,8 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
clang-format:
CLANGFORMAT=`git config --get clangformat.binary`; \
test -z $${CLANGFORMAT} && CLANGFORMAT="clang-format"; \
$${CLANGFORMAT} -i lib/*.{c,h} lib/includes/nghttp2/*.h \
$${CLANGFORMAT} -i \
`ls lib/*.{c,h} | grep -v nghttp2_hd_huffman_data.c` \
lib/includes/nghttp2/*.h \
src/*.{c,cc,h} src/includes/nghttp2/*.h examples/*.{c,cc} \
tests/*.{c,h}

View File

@@ -58,19 +58,13 @@ To build the documentation, you need to install:
* 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``,
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
are required:
To build and run the application programs (``nghttp``, ``nghttpd`` and
``nghttpx``) in the ``src`` directory, the following packages are
required:
* OpenSSL >= 1.0.1
* libev >= 4.11
* libev >= 4.15
* zlib >= 1.2.3
* libc-ares >= 1.7.5
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more
@@ -110,17 +104,14 @@ The Python bindings require the following packages:
* python >= 2.7
* python-setuptools
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages:
.. code-block:: text
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages::
sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
libc-ares-dev libjemalloc-dev cython python3-dev python-setuptools
libjemalloc-dev cython python3-dev python-setuptools
From Ubuntu 15.10, spdylay has been available as a package named
`libspdylay-dev`. For the earlier Ubuntu release, you need to build
it yourself: http://tatsuhiro-t.github.io/spdylay/
spdylay is not packaged in Ubuntu, so you need to build it yourself:
http://tatsuhiro-t.github.io/spdylay/
To enable mruby support for nghttpx, `mruby
<https://github.com/mruby/mruby>`_ is required. We need to build
@@ -146,11 +137,8 @@ Building from git
-----------------
Building from git is easy, but please be sure that at least autoconf 2.68 is
used:
used::
.. code-block:: text
$ git submodule update --init
$ autoreconf -i
$ automake
$ autoconf
@@ -161,7 +149,8 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
.. note::
To enable mruby support in nghttpx, and use ``--with-mruby``
To enable mruby support in nghttpx, run ``git submodule update
--init`` before running configure script, and use ``--with-mruby``
configure option.
.. note::
@@ -171,34 +160,6 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
them from crashing. A patch is welcome to make multi threading work
on Mac OS X platform.
.. note::
To compile the associated applications (nghttp, nghttpd, nghttpx
and h2load), you must use the ``--enable-app`` configure option and
ensure that the specified requirements above are met. Normally,
configure script checks required dependencies to build these
applications, and enable ``--enable-app`` automatically, so you
don't have to use it explicitly. But if you found that
applications were not built, then using ``--enable-app`` may find
that cause, such as the missing dependency.
Notes for building on Windows (MSVC)
------------------------------------
The easiest way to build native Windows nghttp2 dll is use `cmake
<https://cmake.org/>`_. The free version of `Visual C++ Build Tools
<http://landinghub.visualstudio.com/visual-cpp-build-tools>`_ works
fine.
1. Install cmake for windows
2. Open "Visual C++ ... Native Build Tool Command Prompt", and inside
nghttp2 directly, run ``cmake``.
3. Then run ``cmake --build`` to build library.
4. nghttp2.dll, nghttp2.lib, nghttp2.exp are placed under lib directory.
Note that the above steps most likely produce nghttp2 library only.
No bundled applications are compiled.
Notes for building on Windows (Mingw/Cygwin)
--------------------------------------------
@@ -215,9 +176,7 @@ Secondly, you need to undefine the macro ``__STRICT_ANSI__``, if you
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
available.
the sample command like this:
.. code-block:: text
the sample command like this::
$ export CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
$ export CXXFLAGS=$CFLAGS
@@ -235,9 +194,7 @@ Building the documentation
Documentation is still incomplete.
To build the documentation, run:
.. code-block:: text
To build the documentation, run::
$ make html
@@ -266,16 +223,12 @@ its testing framework. We depend on the following libraries:
* https://github.com/tatsuhiro-t/spdy
To download the above packages, after settings ``GOPATH``, run the
following command under ``integration-tests`` directory:
.. code-block:: text
following command under ``integration-tests`` directory::
$ make itprep
To run the tests, run the following command under
``integration-tests`` directory:
.. code-block:: text
``integration-tests`` directory::
$ make it
@@ -396,9 +349,7 @@ nghttp - client
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
It has verbose output mode for framing information. Here is sample
output from ``nghttp`` client:
.. code-block:: text
output from ``nghttp`` client::
$ nghttp -nv https://nghttp2.org
[ 0.190] Connected
@@ -481,9 +432,7 @@ output from ``nghttp`` client:
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
The HTTP Upgrade is performed like so:
.. code-block:: text
The HTTP Upgrade is performed like so::
$ nghttp -nvu http://nghttp2.org
[ 0.011] Connected
@@ -579,9 +528,7 @@ The HTTP Upgrade is performed like so:
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
Using the ``-s`` option, ``nghttp`` prints out some timing information for
requests, sorted by completion time:
.. code-block:: text
requests, sorted by completion time::
$ nghttp -nas https://nghttp2.org/
***** Statistics *****
@@ -625,9 +572,7 @@ HTTP/2 connections. No HTTP Upgrade is supported.
The ``-p`` option allows users to configure server push.
Just like ``nghttp``, it has a verbose output mode for framing
information. Here is sample output from ``nghttpd``:
.. code-block:: text
information. Here is sample output from ``nghttpd``::
$ nghttpd --no-tls -v 8080
IPv4: listen 0.0.0.0:8080
@@ -690,14 +635,6 @@ nghttpx - proxy
HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
push.
We reworked ``nghttpx`` command-line interface, and as a result, there
are several incompatibles from 1.8.0 or earlier. This is necessary to
extend its capability, and secure the further feature enhancements in
the future release. Please read `Migration from nghttpx v1.8.0 or
earlier
<https://nghttp2.org/documentation/nghttpx-howto.html#migration-from-nghttpx-v1-8-0-or-earlier>`_
to know how to migrate from earlier releases.
``nghttpx`` implements `important performance-oriented features
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
session IDs, session tickets (with automatic key rotation), OCSP
@@ -706,42 +643,46 @@ HTTP/2. ``nghttpx`` also offers the functionality to share session
cache and ticket keys among multiple ``nghttpx`` instances via
memcached.
``nghttpx`` has 2 operation modes:
``nghttpx`` has several operational modes:
================== ====================== ================ =============
Mode option Frontend Backend Note
================== ====================== ================ =============
default mode HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
================== ====================== ================ =============
================== ============================ ============== =============
Mode option Frontend Backend Note
================== ============================ ============== =============
default mode HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 Reverse proxy
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 SPDY proxy
``--http2-bridge`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/2 (TLS)
``--client`` HTTP/2, HTTP/1.1 HTTP/2 (TLS)
``--client-proxy`` HTTP/2, HTTP/1.1 HTTP/2 (TLS) Forward proxy
================== ============================ ============== =============
The interesting mode at the moment is the default mode. It works like
a reverse proxy and listens for HTTP/2, SPDY and HTTP/1.1 and can be
deployed as a SSL/TLS terminator for existing web server.
In all modes, the frontend connections are encrypted by SSL/TLS by
default. To disable encryption, use the ``no-tls`` keyword in
``--frontend`` option. If encryption is disabled, SPDY is disabled in
the frontend and incoming HTTP/1.1 connections can be upgraded to
HTTP/2 through HTTP Upgrade. On the other hard, backend connections
are not encrypted by default. To encrypt backend connections, use
``tls`` keyword in ``--backend`` option.
The default mode, ``--http2-proxy`` and ``--http2-bridge`` modes use
SSL/TLS in the frontend connection by default. To disable SSL/TLS,
use the ``--frontend-no-tls`` option. If that option is used, SPDY is
disabled in the frontend and incoming HTTP/1.1 connections can be
upgraded to HTTP/2 through HTTP Upgrade. In these modes, HTTP/1
backend connections are cleartext by default. To enable TLS, use
``--backend-http1-tls`` opiton.
The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use
SSL/TLS in the backend connection by default. To disable SSL/TLS, use
the ``--backend-no-tls`` option.
``nghttpx`` supports a configuration file. See the ``--conf`` option and
sample configuration file ``nghttpx.conf.sample``.
In the default mode, ``nghttpx`` works as reverse proxy to the backend
server:
In the default mode, (without any of ``--http2-proxy``,
``--http2-bridge``, ``--client-proxy`` and ``--client`` options),
``nghttpx`` works as reverse proxy to the backend server::
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Web Server
[reverse proxy]
With the ``--http2-proxy`` option, it works as forward proxy, and it
is so called secure HTTP/2 proxy (aka SPDY proxy):
.. code-block:: text
With the ``--http2-proxy`` option, it works as a so called secure proxy (aka
SPDY proxy)::
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
[secure proxy] (e.g., Squid, ATS)
@@ -749,9 +690,9 @@ is so called secure HTTP/2 proxy (aka SPDY proxy):
The ``Client`` in the above example needs to be configured to use
``nghttpx`` as secure proxy.
At the time of this writing, both Chrome and Firefox support secure
HTTP/2 proxy. One way to configure Chrome to use a secure proxy is to
create a proxy.pac script like this:
At the time of this writing, Chrome is the only browser which supports
secure proxy. One way to configure Chrome to use a secure proxy is
to create a proxy.pac script like this:
.. code-block:: javascript
@@ -763,18 +704,42 @@ create a proxy.pac script like this:
machine nghttpx is running on. Please note that Chrome requires a valid
certificate for secure proxy.
Then run Chrome with the following arguments:
.. code-block:: text
Then run Chrome with the following arguments::
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
The backend HTTP/2 connections can be tunneled through an HTTP proxy.
The proxy is specified using ``--backend-http-proxy-uri``. The
following figure illustrates how nghttpx talks to the outside HTTP/2
proxy through an HTTP proxy:
With ``--http2-bridge``, it accepts HTTP/2, SPDY and HTTP/1.1
connections and communicates with the backend in HTTP/2::
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web or HTTP/2 Proxy etc
(e.g., nghttpx -s)
With ``--client-proxy``, it works as a forward proxy and expects
that the backend is an HTTP/2 proxy::
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> HTTP/2 Proxy
[forward proxy] (e.g., nghttpx -s)
The ``Client`` needs to be configured to use nghttpx as a forward
proxy. The frontend HTTP/1.1 connection can be upgraded to HTTP/2
through HTTP Upgrade. With the above configuration, one can use
HTTP/1.1 client to access and test their HTTP/2 servers.
With ``--client``, it works as a reverse proxy and expects that
the backend is an HTTP/2 Web server::
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web Server
[reverse proxy]
The frontend HTTP/1.1 connection can be upgraded to HTTP/2
through HTTP Upgrade.
For the operation modes which talk to the backend in HTTP/2 over
SSL/TLS, the backend connections can be tunneled through an HTTP proxy.
The proxy is specified using ``--backend-http-proxy-uri``. The
following figure illustrates the example of the ``--http2-bridge`` and
``--backend-http-proxy-uri`` options to talk to the outside HTTP/2
proxy through an HTTP proxy::
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
@@ -788,9 +753,7 @@ The ``h2load`` program is a benchmarking tool for HTTP/2 and SPDY.
The SPDY support is enabled if the program was built with the spdylay
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
(https://github.com/lighttpd/weighttp). The typical usage is as
follows:
.. code-block:: text
follows::
$ h2load -n100000 -c100 -m100 https://localhost:8443/
starting benchmark...
@@ -878,9 +841,7 @@ Example:
With the ``-t`` option, the program can accept more familiar HTTP/1 style
header field blocks. Each header set is delimited by an empty line:
Example:
.. code-block:: text
Example::
:method: GET
:scheme: https
@@ -1376,7 +1337,7 @@ The extension module is called ``nghttp2``.
determined by the ``configure`` script. If the detected Python version is not
what you expect, specify a path to Python executable in a ``PYTHON``
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
and decompressor in Python:
@@ -1506,17 +1467,6 @@ See `Contribution Guidelines
<https://nghttp2.org/documentation/contribute.html>`_ for more
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
----------------
@@ -1529,8 +1479,3 @@ severe security bug fixes.
We have no plan to break API compatibility changes involving soname
bump, so MAJOR version will stay 1 for the foreseeable future.
License
-------
The MIT License

View File

@@ -39,8 +39,9 @@ PATH="$TOOLCHAIN"/bin:"$PATH"
--without-libxml2 \
--disable-python-bindings \
--disable-examples \
CC="$TOOLCHAIN"/bin/arm-linux-androideabi-gcc \
CXX="$TOOLCHAIN"/bin/arm-linux-androideabi-g++ \
--enable-werror \
CC="$TOOLCHAIN"/bin/clang \
CXX="$TOOLCHAIN"/bin/clang++ \
CPPFLAGS="-fPIE -I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-fPIE -pie -L$PREFIX/lib"

View File

@@ -1,53 +0,0 @@
# Notes:
# - Minimal appveyor.yml file is an empty file. All sections are optional.
# - Indent each level of configuration with 2 spaces. Do not use tabs!
# - All section names are case-sensitive.
# - Section names should be unique on each level.
#---------------------------------#
# general configuration #
#---------------------------------#
# version format
#version: 0.10.{build}
# branches to build
branches:
# blacklist
except:
- gh-pages
# Do not build on tags (GitHub only)
skip_tags: true
#---------------------------------#
# environment configuration #
#---------------------------------#
os: Windows Server 2012
# scripts that run after cloning repository
install:
# install Win-Flex-Bison
#- cmd: cinst winflexbison -y
#---------------------------------#
# build configuration #
#---------------------------------#
# scripts to run before build
before_build:
- cmd: cmake .
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
# before_package:
# scripts to run after build
# after_build:
# to run your custom scripts instead of automatic MSBuild
build_script:
- cmd: cmake --build .
# to disable automatic builds
# build: off

View File

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

View File

@@ -1,31 +0,0 @@
# Convenience function that checks the availability of certain
# C or C++ compiler flags and returns valid ones as a string.
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
function(extract_valid_c_flags varname)
set(valid_flags)
foreach(flag IN LISTS ARGN)
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
set(flag_var "C_FLAG_${flag_var}")
check_c_compiler_flag("${flag}" "${flag_var}")
if(${flag_var})
set(valid_flags "${valid_flags} ${flag}")
endif()
endforeach()
set(${varname} "${valid_flags}" PARENT_SCOPE)
endfunction()
function(extract_valid_cxx_flags varname)
set(valid_flags)
foreach(flag IN LISTS ARGN)
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
set(flag_var "CXX_FLAG_${flag_var}")
check_cxx_compiler_flag("${flag}" "${flag_var}")
if(${flag_var})
set(valid_flags "${valid_flags} ${flag}")
endif()
endforeach()
set(${varname} "${valid_flags}" PARENT_SCOPE)
endfunction()

View File

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

View File

@@ -1,44 +0,0 @@
# Find the Cython compiler.
#
# This code sets the following variables:
#
# CYTHON_EXECUTABLE
#
# See also UseCython.cmake
#=============================================================================
# Copyright 2011 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Use the Cython executable that lives next to the Python executable
# if it is a local installation.
find_package( PythonInterp )
if( PYTHONINTERP_FOUND )
get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
HINTS ${_python_path}
)
else()
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
)
endif()
include( FindPackageHandleStandardArgs )
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE )
mark_as_advanced( CYTHON_EXECUTABLE )

View File

@@ -1,40 +0,0 @@
# - Try to find jansson
# Once done this will define
# JANSSON_FOUND - System has jansson
# JANSSON_INCLUDE_DIRS - The jansson include directories
# JANSSON_LIBRARIES - The libraries needed to use jansson
find_package(PkgConfig QUIET)
pkg_check_modules(PC_JANSSON QUIET jansson)
find_path(JANSSON_INCLUDE_DIR
NAMES jansson.h
HINTS ${PC_JANSSON_INCLUDE_DIRS}
)
find_library(JANSSON_LIBRARY
NAMES jansson
HINTS ${PC_JANSSON_LIBRARY_DIRS}
)
if(JANSSON_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+JANSSON_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${JANSSON_INCLUDE_DIR}/jansson.h"
JANSSON_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
JANSSON_VERSION "${JANSSON_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JANSSON_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Jansson REQUIRED_VARS
JANSSON_LIBRARY JANSSON_INCLUDE_DIR
VERSION_VAR JANSSON_VERSION)
if(JANSSON_FOUND)
set(JANSSON_LIBRARIES ${JANSSON_LIBRARY})
set(JANSSON_INCLUDE_DIRS ${JANSSON_INCLUDE_DIR})
endif()
mark_as_advanced(JANSSON_INCLUDE_DIR JANSSON_LIBRARY)

View File

@@ -1,40 +0,0 @@
# - Try to find jemalloc
# Once done this will define
# JEMALLOC_FOUND - System has jemalloc
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
find_package(PkgConfig QUIET)
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
find_path(JEMALLOC_INCLUDE_DIR
NAMES jemalloc/jemalloc.h
HINTS ${PC_JEMALLOC_INCLUDE_DIRS}
)
find_library(JEMALLOC_LIBRARY
NAMES jemalloc
HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
)
if(JEMALLOC_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc/jemalloc.h"
JEMALLOC_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
JEMALLOC_VERSION "${JEMALLOC_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Jemalloc REQUIRED_VARS
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR
VERSION_VAR JEMALLOC_VERSION)
if(JEMALLOC_FOUND)
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
endif()
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)

View File

@@ -1,40 +0,0 @@
# - Try to find libcares
# Once done this will define
# LIBCARES_FOUND - System has libcares
# LIBCARES_INCLUDE_DIRS - The libcares include directories
# LIBCARES_LIBRARIES - The libraries needed to use libcares
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBCARES QUIET libcares)
find_path(LIBCARES_INCLUDE_DIR
NAMES ares.h
HINTS ${PC_LIBCARES_INCLUDE_DIRS}
)
find_library(LIBCARES_LIBRARY
NAMES cares
HINTS ${PC_LIBCARES_LIBRARY_DIRS}
)
if(LIBCARES_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+ARES_VERSION_STR[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBCARES_INCLUDE_DIR}/ares_version.h"
LIBCARES_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBCARES_VERSION "${LIBCARES_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBCARES_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libcares REQUIRED_VARS
LIBCARES_LIBRARY LIBCARES_INCLUDE_DIR
VERSION_VAR LIBCARES_VERSION)
if(LIBCARES_FOUND)
set(LIBCARES_LIBRARIES ${LIBCARES_LIBRARY})
set(LIBCARES_INCLUDE_DIRS ${LIBCARES_INCLUDE_DIR})
endif()
mark_as_advanced(LIBCARES_INCLUDE_DIR LIBCARES_LIBRARY)

View File

@@ -1,38 +0,0 @@
# - Try to find libev
# Once done this will define
# LIBEV_FOUND - System has libev
# LIBEV_INCLUDE_DIRS - The libev include directories
# LIBEV_LIBRARIES - The libraries needed to use libev
find_path(LIBEV_INCLUDE_DIR
NAMES ev.h
)
find_library(LIBEV_LIBRARY
NAMES ev
)
if(LIBEV_INCLUDE_DIR)
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
LIBEV_VERSION_MAJOR REGEX "^#define[ \t]+EV_VERSION_MAJOR[ \t]+[0-9]+")
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
LIBEV_VERSION_MINOR REGEX "^#define[ \t]+EV_VERSION_MINOR[ \t]+[0-9]+")
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MAJOR "${LIBEV_VERSION_MAJOR}")
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MINOR "${LIBEV_VERSION_MINOR}")
set(LIBEV_VERSION "${LIBEV_VERSION_MAJOR}.${LIBEV_VERSION_MINOR}")
unset(LIBEV_VERSION_MINOR)
unset(LIBEV_VERSION_MAJOR)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEV_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libev REQUIRED_VARS
LIBEV_LIBRARY LIBEV_INCLUDE_DIR
VERSION_VAR LIBEV_VERSION)
if(LIBEV_FOUND)
set(LIBEV_LIBRARIES ${LIBEV_LIBRARY})
set(LIBEV_INCLUDE_DIRS ${LIBEV_INCLUDE_DIR})
endif()
mark_as_advanced(LIBEV_INCLUDE_DIR LIBEV_LIBRARY)

View File

@@ -1,94 +0,0 @@
# - Try to find libevent
#.rst
# FindLibevent
# ------------
#
# Find Libevent include directories and libraries. Invoke as::
#
# find_package(Libevent
# [version] [EXACT] # Minimum or exact version
# [REQUIRED] # Fail if Libevent is not found
# [COMPONENT <C>...]) # Libraries to look for
#
# Valid components are one or more of:: libevent core extra pthreads openssl.
# Note that 'libevent' contains both core and extra. You must specify one of
# them for the other components.
#
# This module will define the following variables::
#
# LIBEVENT_FOUND - True if headers and requested libraries were found
# LIBEVENT_INCLUDE_DIRS - Libevent include directories
# LIBEVENT_LIBRARIES - Libevent libraries to be linked
# LIBEVENT_<C>_FOUND - Component <C> was found (<C> is uppercase)
# LIBEVENT_<C>_LIBRARY - Library to be linked for Libevent component <C>.
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBEVENT QUIET libevent)
# Look for the Libevent 2.0 or 1.4 headers
find_path(LIBEVENT_INCLUDE_DIR
NAMES
event2/event-config.h
event-config.h
HINTS
${PC_LIBEVENT_INCLUDE_DIRS}
)
if(LIBEVENT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
if(EXISTS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h")
# Libevent 2.0
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
else()
# Libevent 1.4
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
endif()
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBEVENT_VERSION "${LIBEVENT_VERSION}")
unset(_version_regex)
endif()
set(_LIBEVENT_REQUIRED_VARS)
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
set(_LIBEVENT_LIBNAME libevent)
# Note: compare two variables to avoid a CMP0054 policy warning
if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
set(_LIBEVENT_LIBNAME event)
else()
set(_LIBEVENT_LIBNAME "event_${COMPONENT}")
endif()
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
NAMES ${_LIBEVENT_LIBNAME}
HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
)
if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
set(Libevent_${COMPONENT}_FOUND 1)
endif()
list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
endforeach()
unset(_LIBEVENT_LIBNAME)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libevent REQUIRED_VARS
${_LIBEVENT_REQUIRED_VARS}
LIBEVENT_INCLUDE_DIR
VERSION_VAR LIBEVENT_VERSION
HANDLE_COMPONENTS)
if(LIBEVENT_FOUND)
set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
set(LIBEVENT_LIBRARIES)
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
endforeach()
endif()
mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS})
unset(_LIBEVENT_REQUIRED_VARS)

View File

@@ -1,40 +0,0 @@
# - Try to find spdylay
# Once done this will define
# SPDYLAY_FOUND - System has spdylay
# SPDYLAY_INCLUDE_DIRS - The spdylay include directories
# SPDYLAY_LIBRARIES - The libraries needed to use spdylay
find_package(PkgConfig QUIET)
pkg_check_modules(PC_SPDYLAY QUIET libspdylay)
find_path(SPDYLAY_INCLUDE_DIR
NAMES spdylay/spdylay.h
HINTS ${PC_SPDYLAY_INCLUDE_DIRS}
)
find_library(SPDYLAY_LIBRARY
NAMES spdylay
HINTS ${PC_SPDYLAY_LIBRARY_DIRS}
)
if(SPDYLAY_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+SPDYLAY_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${SPDYLAY_INCLUDE_DIR}/spdylay/spdylayver.h"
SPDYLAY_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
SPDYLAY_VERSION "${SPDYLAY_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set SPDYLAY_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Spdylay REQUIRED_VARS
SPDYLAY_LIBRARY SPDYLAY_INCLUDE_DIR
VERSION_VAR SPDYLAY_VERSION)
if(SPDYLAY_FOUND)
set(SPDYLAY_LIBRARIES ${SPDYLAY_LIBRARY})
set(SPDYLAY_INCLUDE_DIRS ${SPDYLAY_INCLUDE_DIR})
endif()
mark_as_advanced(SPDYLAY_INCLUDE_DIR SPDYLAY_LIBRARY)

View File

@@ -1,11 +0,0 @@
# Converts a version such as 1.2.255 to 0x0102ff
function(HexVersion version_hex_var major minor patch)
math(EXPR version_dec "${major} * 256 * 256 + ${minor} * 256 + ${patch}")
set(version_hex "0x")
foreach(i RANGE 5 0 -1)
math(EXPR num "(${version_dec} >> (4 * ${i})) & 15")
string(SUBSTRING "0123456789abcdef" ${num} 1 num_hex)
set(version_hex "${version_hex}${num_hex}")
endforeach()
set(${version_hex_var} "${version_hex}" PARENT_SCOPE)
endfunction()

View File

@@ -1,84 +0,0 @@
/* Hint to the compiler that a function parameter is not used */
#define _U_ @HINT_UNUSED_PARAM@
/* Hint to the compiler that a function never returns */
#define NGHTTP2_NORETURN @HINT_NORETURN@
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine ssize_t @ssize_t@
/* Define to 1 if you have the `std::map::emplace`. */
#cmakedefine HAVE_STD_MAP_EMPLACE 1
/* Define to 1 if you have `libjansson` library. */
#cmakedefine HAVE_JANSSON 1
/* Define to 1 if you have `libxml2` library. */
#cmakedefine HAVE_LIBXML2 1
/* Define to 1 if you have `spdylay` library. */
#cmakedefine HAVE_SPDYLAY 1
/* Define to 1 if you have `mruby` library. */
#cmakedefine HAVE_MRUBY 1
/* Define to 1 if you have `neverbleed` library. */
#cmakedefine HAVE_NEVERBLEED 1
/* sizeof(int *) */
#cmakedefine SIZEOF_INT_P @SIZEOF_INT_P@
/* sizeof(time_t) */
#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
/* Define to 1 if you have the `_Exit` function. */
#cmakedefine HAVE__EXIT 1
/* Define to 1 if you have the `accept4` function. */
#cmakedefine HAVE_ACCEPT4 1
/* Define to 1 if you have the `initgroups` function. */
#cmakedefine01 HAVE_DECL_INITGROUPS
/* Define to 1 to enable debug output. */
#cmakedefine DEBUGBUILD 1
/* Define to 1 if you want to disable threads. */
#cmakedefine NOTHREADS 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
/* Define to 1 if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <syslog.h> header file. */
#cmakedefine HAVE_SYSLOG_H 1
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1

View File

@@ -25,7 +25,7 @@ dnl Do not change user variables!
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
AC_PREREQ(2.61)
AC_INIT([nghttp2], [1.18.1], [t-tujikawa@users.sourceforge.net])
AC_INIT([nghttp2], [1.8.0-DEV], [t-tujikawa@users.sourceforge.net])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
@@ -40,13 +40,15 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects])
# AM_EXTRA_RECURSIVE_TARGETS requires automake 1.13 or higher
m4_ifdef([AM_EXTRA_RECURSIVE_TARGETS], [AM_EXTRA_RECURSIVE_TARGETS([it itprep])])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl See versioning rule:
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
AC_SUBST(LT_CURRENT, 26)
AC_SUBST(LT_REVISION, 3)
AC_SUBST(LT_AGE, 12)
AC_SUBST(LT_CURRENT, 18)
AC_SUBST(LT_REVISION, 1)
AC_SUBST(LT_AGE, 4)
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"`
@@ -74,7 +76,7 @@ AC_ARG_ENABLE([threads],
AC_ARG_ENABLE([app],
[AS_HELP_STRING([--enable-app],
[Build applications (nghttp, nghttpd, nghttpx and h2load) [default=check]])],
[Build applications (nghttp, nghttpd and nghttpx) [default=check]])],
[request_app=$enableval], [request_app=check])
AC_ARG_ENABLE([hpack-tools],
@@ -183,8 +185,8 @@ if test "x$GCC" = "xyes" -o "x$CC" = "xclang" ; then
AC_DEFINE([_U_], [__attribute__((unused))], [Hint to the compiler that a function parameters is not used])
AC_DEFINE([NGHTTP2_NORETURN], [__attribute__((noreturn))], [Hint to the compiler that a function never return])
else
AC_DEFINE([_U_], , [Hint to the compiler that a function parameter is not used])
AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
AC_DEFINE([_U_], , [Hint to the compiler that a function parameters is not use AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
d])
fi
save_CXXFLAGS="$CXXFLAGS"
@@ -234,41 +236,6 @@ std::map<int, int>().emplace(1, 2);
[have_std_map_emplace=no
AC_MSG_RESULT([no])])
# Check that std::atomic_* overloads for std::shared_ptr are
# available.
AC_MSG_CHECKING([whether std::atomic_* overloads for std::shared_ptr are available])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <memory>
]],
[[
auto a = std::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
AC_LANG_POP()
@@ -281,7 +248,7 @@ TESTLDADD=
# Additional libraries required for programs under src directory.
APPLDFLAGS=
case "$host_os" in
case "$host" in
*android*)
android_build=yes
# android does not need -pthread, but needs followng 3 libs for C++
@@ -293,12 +260,6 @@ case "$host_os" in
;;
esac
case "$host_os" in
*solaris*)
APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
;;
esac
# zlib
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
@@ -370,13 +331,6 @@ if test "x${have_openssl}" = "xno"; then
AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
fi
# c-ares (for src)
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.5], [have_libcares=yes],
[have_libcares=no])
if test "x${have_libcares}" = "xno"; then
AC_MSG_NOTICE($LIBCARES_PKG_ERRORS)
fi
# libevent_openssl (for examples)
# 2.0.8 is required because we use evconnlistener_set_error_cb()
PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
@@ -396,12 +350,12 @@ else
fi
# libxml2 (for src/nghttp)
PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.7.7],
[have_libxml2=yes], [have_libxml2=no])
if test "x${have_libxml2}" = "xyes"; then
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
else
AC_MSG_NOTICE($LIBXML2_PKG_ERRORS)
have_libxml2=no
if test "x${request_libxml2}" != "xno"; then
AM_PATH_XML2(2.7.7, [have_libxml2=yes], [have_libxml2=no])
if test "x${have_libxml2}" = "xyes"; then
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
fi
fi
if test "x${request_libxml2}" = "xyes" &&
@@ -483,14 +437,13 @@ if test "x${request_asio_lib}" = "xyes"; then
fi
fi
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL,
# libev, and libc-ares.
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL
# and libev
enable_app=no
if test "x${request_app}" != "xno" &&
test "x${have_zlib}" = "xyes" &&
test "x${have_openssl}" = "xyes" &&
test "x${have_libev}" = "xyes" &&
test "x${have_libcares}" = "xyes"; then
test "x${have_libev}" = "xyes"; then
enable_app=yes
fi
@@ -645,26 +598,6 @@ AC_SYS_LARGEFILE
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes],
[have_struct_tm_tm_gmtoff=no], [[#include <time.h>]])
AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
[AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN],[1],
[Define to 1 if struct sockaddr_in has sin_len member.])],
[],
[[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]])
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len],
[AC_DEFINE([HAVE_SOCKADDR_IN6_SIN6_LEN],[1],
[Define to 1 if struct sockaddr_in6 has sin6_len member.])],
[],
[[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
]])
if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
AC_DEFINE([HAVE_STRUCT_TM_TM_GMTOFF], [1],
[Define to 1 if you have `struct tm.tm_gmtoff` member.])
@@ -718,13 +651,15 @@ AC_CHECK_FUNC([timerfd_create],
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
# cygwin disables initgroups due to feature test macro magic with our
# configuration. FreeBSD declares initgroups() in unistd.h.
AC_CHECK_DECLS([initgroups], [], [], [[
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <grp.h>
]])
# configuration.
AC_CHECK_DECLS([initgroups], [], [], [[#include <grp.h>]])
# Checks for epoll availability, primarily for examples/tiny-nghttpd
AX_HAVE_EPOLL([have_epoll=yes], [have_epoll=no])
AM_CONDITIONAL([ENABLE_TINY_NGHTTPD],
[ test "x${have_epoll}" = "xyes" &&
test "x${have_timerfd_create}" = "xyes"])
save_CFLAGS=$CFLAGS
save_CXXFLAGS=$CXXFLAGS
@@ -779,17 +714,12 @@ if test "x$werror" != "xno"; then
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
# Only work with Clang for the moment
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CFLAGS="$CFLAGS -Wsometimes-uninitialized"])
# This is required because we pass format string as "const char*.
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
# For C++ compiler
AC_LANG_PUSH(C++)
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
AC_LANG_POP()
fi
@@ -886,7 +816,6 @@ AC_MSG_NOTICE([summary of build options:
C preprocessor: ${CPP}
CPPFLAGS: ${CPPFLAGS}
WARNCFLAGS: ${WARNCFLAGS}
WARNCXXFLAGS: ${WARNCXXFLAGS}
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
EXTRACFLAG: ${EXTRACFLAG}
LIBS: ${LIBS}
@@ -906,9 +835,8 @@ AC_MSG_NOTICE([summary of build options:
Failmalloc: ${enable_failmalloc}
Libs:
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
Libxml2: ${have_libxml2} (CFLAGS='${LIBXML2_CPPFLAGS}' LIBS='${LIBXML2_LIBS}')
Libxml2: ${have_libxml2} (CFLAGS='${XML_CPPFLAGS}' LIBS='${XML_LIBS}')
Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
Libc-ares ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
Spdylay: ${have_spdylay} (CFLAGS='${LIBSPDYLAY_CFLAGS}' LIBS='${LIBSPDYLAY_LIBS}')
Jansson: ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}')

View File

@@ -1,12 +0,0 @@
set(CONFIGFILES
nghttpx-init
nghttpx.service
nghttpx-upstart.conf
)
# Note that the execute permissions of nghttpx-init is preserved
foreach(name IN LISTS CONFIGFILES)
configure_file("${name}.in" "${name}" @ONLY)
endforeach()
# set(EXTRA_DIST ${CONFIGFILES} nghttpx-logrotate tlsticketupdate.go)

View File

@@ -23,24 +23,17 @@
configfiles = nghttpx-init nghttpx.service nghttpx-upstart.conf
EXTRA_DIST = \
CMakeLists.txt \
$(configfiles:%=%.in) \
nghttpx-logrotate \
tlsticketupdate.go
EXTRA_DIST = $(configfiles:%=%.in) nghttpx-logrotate tlsticketupdate.go
edit = sed -e 's|@bindir[@]|$(bindir)|g'
nghttpx-init: $(srcdir)/nghttpx-init.in
nghttpx-init: %: $(srcdir)/%.in
rm -f $@ $@.tmp
$(edit) $< > $@.tmp
chmod +x $@.tmp
mv $@.tmp $@
nghttpx.service: $(srcdir)/nghttpx.service.in
$(edit) $< > $@
nghttpx-upstart.conf: $(srcdir)/nghttpx-upstart.conf.in
nghttpx.service nghttpx-upstart.conf: %: $(srcdir)/%.in
$(edit) $< > $@
$(configfiles): Makefile

View File

@@ -1,352 +0,0 @@
# Generated documents
set(APIDOCS
macros.rst
enums.rst
types.rst
nghttp2_check_header_name.rst
nghttp2_check_header_value.rst
nghttp2_hd_deflate_bound.rst
nghttp2_hd_deflate_change_table_size.rst
nghttp2_hd_deflate_del.rst
nghttp2_hd_deflate_get_dynamic_table_size.rst
nghttp2_hd_deflate_get_max_dynamic_table_size.rst
nghttp2_hd_deflate_get_num_table_entries.rst
nghttp2_hd_deflate_get_table_entry.rst
nghttp2_hd_deflate_hd.rst
nghttp2_hd_deflate_hd_vec.rst
nghttp2_hd_deflate_new.rst
nghttp2_hd_deflate_new2.rst
nghttp2_hd_inflate_change_table_size.rst
nghttp2_hd_inflate_del.rst
nghttp2_hd_inflate_end_headers.rst
nghttp2_hd_inflate_get_dynamic_table_size.rst
nghttp2_hd_inflate_get_max_dynamic_table_size.rst
nghttp2_hd_inflate_get_num_table_entries.rst
nghttp2_hd_inflate_get_table_entry.rst
nghttp2_hd_inflate_hd.rst
nghttp2_hd_inflate_hd2.rst
nghttp2_hd_inflate_new.rst
nghttp2_hd_inflate_new2.rst
nghttp2_http2_strerror.rst
nghttp2_is_fatal.rst
nghttp2_nv_compare_name.rst
nghttp2_option_del.rst
nghttp2_option_new.rst
nghttp2_option_set_builtin_recv_extension_type.rst
nghttp2_option_set_max_deflate_dynamic_table_size.rst
nghttp2_option_set_max_reserved_remote_streams.rst
nghttp2_option_set_max_send_header_block_length.rst
nghttp2_option_set_no_auto_ping_ack.rst
nghttp2_option_set_no_auto_window_update.rst
nghttp2_option_set_no_http_messaging.rst
nghttp2_option_set_no_recv_client_magic.rst
nghttp2_option_set_peer_max_concurrent_streams.rst
nghttp2_option_set_user_recv_extension_type.rst
nghttp2_pack_settings_payload.rst
nghttp2_priority_spec_check_default.rst
nghttp2_priority_spec_default_init.rst
nghttp2_priority_spec_init.rst
nghttp2_rcbuf_decref.rst
nghttp2_rcbuf_get_buf.rst
nghttp2_rcbuf_incref.rst
nghttp2_select_next_protocol.rst
nghttp2_session_callbacks_del.rst
nghttp2_session_callbacks_new.rst
nghttp2_session_callbacks_set_before_frame_send_callback.rst
nghttp2_session_callbacks_set_data_source_read_length_callback.rst
nghttp2_session_callbacks_set_error_callback.rst
nghttp2_session_callbacks_set_on_begin_frame_callback.rst
nghttp2_session_callbacks_set_on_begin_headers_callback.rst
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst
nghttp2_session_callbacks_set_on_frame_recv_callback.rst
nghttp2_session_callbacks_set_on_frame_send_callback.rst
nghttp2_session_callbacks_set_on_header_callback.rst
nghttp2_session_callbacks_set_on_header_callback2.rst
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst
nghttp2_session_callbacks_set_on_invalid_header_callback.rst
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst
nghttp2_session_callbacks_set_on_stream_close_callback.rst
nghttp2_session_callbacks_set_pack_extension_callback.rst
nghttp2_session_callbacks_set_recv_callback.rst
nghttp2_session_callbacks_set_select_padding_callback.rst
nghttp2_session_callbacks_set_send_callback.rst
nghttp2_session_callbacks_set_send_data_callback.rst
nghttp2_session_callbacks_set_unpack_extension_callback.rst
nghttp2_session_change_stream_priority.rst
nghttp2_session_check_request_allowed.rst
nghttp2_session_check_server_session.rst
nghttp2_session_client_new.rst
nghttp2_session_client_new2.rst
nghttp2_session_client_new3.rst
nghttp2_session_consume.rst
nghttp2_session_consume_connection.rst
nghttp2_session_consume_stream.rst
nghttp2_session_create_idle_stream.rst
nghttp2_session_del.rst
nghttp2_session_find_stream.rst
nghttp2_session_get_effective_local_window_size.rst
nghttp2_session_get_effective_recv_data_length.rst
nghttp2_session_get_hd_deflate_dynamic_table_size.rst
nghttp2_session_get_hd_inflate_dynamic_table_size.rst
nghttp2_session_get_last_proc_stream_id.rst
nghttp2_session_get_local_settings.rst
nghttp2_session_get_local_window_size.rst
nghttp2_session_get_next_stream_id.rst
nghttp2_session_get_outbound_queue_size.rst
nghttp2_session_get_remote_settings.rst
nghttp2_session_get_remote_window_size.rst
nghttp2_session_get_root_stream.rst
nghttp2_session_get_stream_effective_local_window_size.rst
nghttp2_session_get_stream_effective_recv_data_length.rst
nghttp2_session_get_stream_local_close.rst
nghttp2_session_get_stream_local_window_size.rst
nghttp2_session_get_stream_remote_close.rst
nghttp2_session_get_stream_remote_window_size.rst
nghttp2_session_get_stream_user_data.rst
nghttp2_session_mem_recv.rst
nghttp2_session_mem_send.rst
nghttp2_session_recv.rst
nghttp2_session_resume_data.rst
nghttp2_session_send.rst
nghttp2_session_server_new.rst
nghttp2_session_server_new2.rst
nghttp2_session_server_new3.rst
nghttp2_session_set_local_window_size.rst
nghttp2_session_set_next_stream_id.rst
nghttp2_session_set_stream_user_data.rst
nghttp2_session_terminate_session.rst
nghttp2_session_terminate_session2.rst
nghttp2_session_upgrade.rst
nghttp2_session_upgrade2.rst
nghttp2_session_want_read.rst
nghttp2_session_want_write.rst
nghttp2_set_debug_vprintf_callback.rst
nghttp2_stream_get_first_child.rst
nghttp2_stream_get_next_sibling.rst
nghttp2_stream_get_parent.rst
nghttp2_stream_get_previous_sibling.rst
nghttp2_stream_get_state.rst
nghttp2_stream_get_sum_dependency_weight.rst
nghttp2_stream_get_weight.rst
nghttp2_strerror.rst
nghttp2_submit_altsvc.rst
nghttp2_submit_data.rst
nghttp2_submit_extension.rst
nghttp2_submit_goaway.rst
nghttp2_submit_headers.rst
nghttp2_submit_ping.rst
nghttp2_submit_priority.rst
nghttp2_submit_push_promise.rst
nghttp2_submit_request.rst
nghttp2_submit_response.rst
nghttp2_submit_rst_stream.rst
nghttp2_submit_settings.rst
nghttp2_submit_shutdown_notice.rst
nghttp2_submit_trailer.rst
nghttp2_submit_window_update.rst
nghttp2_version.rst
)
set(MAN_PAGES
nghttp.1
nghttpd.1
nghttpx.1
h2load.1
)
# Other .rst files from the source tree that need to be copied
# XXX move them to sources/ and create .in files?
set(RST_FILES
README.rst
programmers-guide.rst
nghttp.1.rst
nghttpd.1.rst
nghttpx.1.rst
h2load.1.rst
)
# XXX unused for now
set(EXTRA_DIST
mkapiref.py
${RST_FILES}
${APIDOCS}
sources/index.rst
sources/tutorial-client.rst
sources/tutorial-server.rst
sources/tutorial-hpack.rst
sources/nghttpx-howto.rst
sources/h2load-howto.rst
sources/libnghttp2_asio.rst
sources/python-apiref.rst
sources/building-android-binary.rst
sources/contribute.rst
_exts/sphinxcontrib/LICENSE.rubydomain
_exts/sphinxcontrib/__init__.py
_exts/sphinxcontrib/rubydomain.py
_themes/sphinx_rtd_theme/__init__.py
_themes/sphinx_rtd_theme/breadcrumbs.html
_themes/sphinx_rtd_theme/footer.html
_themes/sphinx_rtd_theme/layout.html
_themes/sphinx_rtd_theme/layout_old.html
_themes/sphinx_rtd_theme/search.html
_themes/sphinx_rtd_theme/searchbox.html
_themes/sphinx_rtd_theme/static/css/badge_only.css
_themes/sphinx_rtd_theme/static/css/theme.css
_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
_themes/sphinx_rtd_theme/static/js/theme.js
_themes/sphinx_rtd_theme/theme.conf
_themes/sphinx_rtd_theme/versions.html
${MAN_PAGES}
bash_completion/nghttp
bash_completion/nghttpd
bash_completion/nghttpx
bash_completion/h2load
)
# Based on Makefile for Sphinx documentation
# You can set these variables from the command line.
set(SPHINXOPTS)
set(SPHINXBUILD sphinx-build)
set(PAPER)
set(BUILDDIR manual)
# Internal variables.
set(PAPEROPT_a4 -D latex_paper_size=a4)
set(PAPEROPT_letter -D latex_paper_size=letter)
set(ALLSPHINXOPTS -d ${BUILDDIR}/doctrees ${PAPEROPT_${PAPER}} ${SPHINXOPTS} .)
# "Please use `make <target>' where <target> is one of"
# " html to make standalone HTML files"
# " dirhtml to make HTML files named index.html in directories"
# " singlehtml to make a single large HTML file"
# " pickle to make pickle files"
# " json to make JSON files"
# " htmlhelp to make HTML files and a HTML help project"
# " qthelp to make HTML files and a qthelp project"
# " devhelp to make HTML files and a Devhelp project"
# " epub to make an epub"
# " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
# " latexpdf to make LaTeX files and run them through pdflatex"
# " text to make text files"
# " man to make manual pages"
# " changes to make an overview of all changed/added/deprecated items"
# " linkcheck to check all external links for integrity"
# " doctest to run all doctests embedded in the documentation (if enabled)"
# Copy files for out-of-tree builds
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
set(RST_BUILD_FILES)
foreach(rstfile IN LISTS RST_FILES)
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${rstfile}")
add_custom_command(OUTPUT "${outfile}"
COMMAND ${CMAKE_COMMAND} -E copy
"${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}" "${outfile}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}"
)
list(APPEND RST_BUILD_FILES "${outfile}")
endforeach()
else()
set(RST_BUILD_FILES "${RST_FILES}")
endif()
set(apiref_SOURCES
${CMAKE_BINARY_DIR}/lib/includes/nghttp2/nghttp2ver.h
${CMAKE_SOURCE_DIR}/lib/includes/nghttp2/nghttp2.h
)
# Generates apiref.rst and other files
add_custom_command(
OUTPUT
apiref.rst
${APIDOCS}
COMMAND
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkapiref.py"
apiref.rst macros.rst enums.rst types.rst .
${apiref_SOURCES}
DEPENDS
${RST_BUILD_FILES}
${apiref_SOURCES}
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${BUILDDIR}")
# Invokes sphinx-build and prints the given messages when completed
function(sphinxbuild builder)
set(echo_commands)
foreach(message IN LISTS ARGN)
list(APPEND echo_commands COMMAND ${CMAKE_COMMAND} -E echo "${message}")
endforeach()
add_custom_target(${builder}
COMMAND "${SPHINXBUILD}" -b ${builder} ${ALLSPHINXOPTS} "${BUILDDIR}/${builder}"
COMMAND ${CMAKE_COMMAND} -E echo
${echo_commands}
VERBATIM
DEPENDS apiref.rst
)
endfunction()
foreach(builder html dirhtml singlehtml)
sphinxbuild(${builder}
"Build finished. The HTML pages are in ${BUILDDIR}/${builder}.")
endforeach()
sphinxbuild(pickle "Build finished; now you can process the pickle files.")
sphinxbuild(json "Build finished; now you can process the JSON files.")
sphinxbuild(htmlhelp
"Build finished; now you can run HTML Help Workshop with the"
".hhp project file in ${BUILDDIR}/htmlhelp."
)
sphinxbuild(qthelp
"Build finished; now you can run \"qcollectiongenerator\" with the"
".qhcp project file in ${BUILDDIR}/qthelp, like this:"
"# qcollectiongenerator ${BUILDDIR}/qthelp/nghttp2.qhcp"
"To view the help file:"
"# assistant -collectionFile ${BUILDDIR}/qthelp/nghttp2.qhc"
)
sphinxbuild(devhelp
"Build finished."
"To view the help file:"
"# mkdir -p ~/.local/share/devhelp/nghttp2"
"# ln -s ${BUILDDIR}/devhelp ~/.local/share/devhelp/nghttp2"
"# devhelp"
)
sphinxbuild(epub "Build finished. The epub file is in ${BUILDDIR}/epub.")
sphinxbuild(latex
"Build finished; the LaTeX files are in ${BUILDDIR}/latex."
"Run `make' in that directory to run these through (pdf)latex"
"(use `make latexpdf' here to do that automatically)."
)
# Invoke the Makefile generated by sphinx
add_custom_target(latexpdf
COMMAND ${CMAKE_COMMAND} -E echo "Running LaTeX files through pdflatex..."
COMMAND make -C "${BUILDDIR}/latex" all-pdf
COMMAND ${CMAKE_COMMAND} -E echo "pdflatex finished; the PDF files are in ${BUILDDIR}/latex."
DEPENDS latex
)
sphinxbuild(text "Build finished. The text files are in ${BUILDDIR}/text.")
sphinxbuild(man "Build finished. The manual pages are in ${BUILDDIR}/man.")
sphinxbuild(changes "The overview file is in ${BUILDDIR}/changes.")
sphinxbuild(linkcheck
"Link check complete; look for any errors in the above output"
"or in ${BUILDDIR}/linkcheck/output.txt."
)
sphinxbuild(doctest
"Testing of doctests in the sources finished, look at the"
"results in ${BUILDDIR}/doctest/output.txt."
)
foreach(_man_page IN LISTS MAN_PAGES)
install(FILES ${_man_page}
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
)
endforeach()

View File

@@ -37,7 +37,6 @@ APIDOCS= \
nghttp2_hd_deflate_get_num_table_entries.rst \
nghttp2_hd_deflate_get_table_entry.rst \
nghttp2_hd_deflate_hd.rst \
nghttp2_hd_deflate_hd_vec.rst \
nghttp2_hd_deflate_new.rst \
nghttp2_hd_deflate_new2.rst \
nghttp2_hd_inflate_change_table_size.rst \
@@ -48,59 +47,39 @@ APIDOCS= \
nghttp2_hd_inflate_get_num_table_entries.rst \
nghttp2_hd_inflate_get_table_entry.rst \
nghttp2_hd_inflate_hd.rst \
nghttp2_hd_inflate_hd2.rst \
nghttp2_hd_inflate_new.rst \
nghttp2_hd_inflate_new2.rst \
nghttp2_http2_strerror.rst \
nghttp2_is_fatal.rst \
nghttp2_nv_compare_name.rst \
nghttp2_option_del.rst \
nghttp2_option_new.rst \
nghttp2_option_set_builtin_recv_extension_type.rst \
nghttp2_option_set_max_deflate_dynamic_table_size.rst \
nghttp2_option_set_max_reserved_remote_streams.rst \
nghttp2_option_set_max_send_header_block_length.rst \
nghttp2_option_set_no_auto_ping_ack.rst \
nghttp2_option_set_no_auto_window_update.rst \
nghttp2_option_set_no_http_messaging.rst \
nghttp2_option_set_no_recv_client_magic.rst \
nghttp2_option_set_peer_max_concurrent_streams.rst \
nghttp2_option_set_user_recv_extension_type.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
nghttp2_priority_spec_init.rst \
nghttp2_rcbuf_decref.rst \
nghttp2_rcbuf_get_buf.rst \
nghttp2_rcbuf_incref.rst \
nghttp2_select_next_protocol.rst \
nghttp2_session_callbacks_del.rst \
nghttp2_session_callbacks_new.rst \
nghttp2_session_callbacks_set_before_frame_send_callback.rst \
nghttp2_session_callbacks_set_data_source_read_length_callback.rst \
nghttp2_session_callbacks_set_error_callback.rst \
nghttp2_session_callbacks_set_on_begin_frame_callback.rst \
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst \
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst \
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
nghttp2_session_callbacks_set_on_header_callback.rst \
nghttp2_session_callbacks_set_on_header_callback2.rst \
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
nghttp2_session_callbacks_set_on_invalid_header_callback.rst \
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst \
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback.rst \
nghttp2_session_callbacks_set_recv_callback.rst \
nghttp2_session_callbacks_set_select_padding_callback.rst \
nghttp2_session_callbacks_set_send_callback.rst \
nghttp2_session_callbacks_set_send_data_callback.rst \
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
nghttp2_session_change_stream_priority.rst \
nghttp2_session_check_request_allowed.rst \
nghttp2_session_check_server_session.rst \
nghttp2_session_client_new.rst \
nghttp2_session_client_new2.rst \
nghttp2_session_client_new3.rst \
@@ -112,11 +91,7 @@ APIDOCS= \
nghttp2_session_find_stream.rst \
nghttp2_session_get_effective_local_window_size.rst \
nghttp2_session_get_effective_recv_data_length.rst \
nghttp2_session_get_hd_deflate_dynamic_table_size.rst \
nghttp2_session_get_hd_inflate_dynamic_table_size.rst \
nghttp2_session_get_last_proc_stream_id.rst \
nghttp2_session_get_local_settings.rst \
nghttp2_session_get_local_window_size.rst \
nghttp2_session_get_next_stream_id.rst \
nghttp2_session_get_outbound_queue_size.rst \
nghttp2_session_get_remote_settings.rst \
@@ -125,19 +100,20 @@ APIDOCS= \
nghttp2_session_get_stream_effective_local_window_size.rst \
nghttp2_session_get_stream_effective_recv_data_length.rst \
nghttp2_session_get_stream_local_close.rst \
nghttp2_session_get_stream_local_window_size.rst \
nghttp2_session_get_stream_remote_close.rst \
nghttp2_session_get_stream_remote_window_size.rst \
nghttp2_session_get_stream_user_data.rst \
nghttp2_session_mem_recv.rst \
nghttp2_session_mem_send.rst \
nghttp2_session_recv.rst \
nghttp2_session_change_stream_priority.rst \
nghttp2_session_check_request_allowed.rst \
nghttp2_session_check_server_session.rst \
nghttp2_session_resume_data.rst \
nghttp2_session_send.rst \
nghttp2_session_server_new.rst \
nghttp2_session_server_new2.rst \
nghttp2_session_server_new3.rst \
nghttp2_session_set_local_window_size.rst \
nghttp2_session_set_next_stream_id.rst \
nghttp2_session_set_stream_user_data.rst \
nghttp2_session_terminate_session.rst \
@@ -146,7 +122,6 @@ APIDOCS= \
nghttp2_session_upgrade2.rst \
nghttp2_session_want_read.rst \
nghttp2_session_want_write.rst \
nghttp2_set_debug_vprintf_callback.rst \
nghttp2_stream_get_first_child.rst \
nghttp2_stream_get_next_sibling.rst \
nghttp2_stream_get_parent.rst \
@@ -155,9 +130,7 @@ APIDOCS= \
nghttp2_stream_get_sum_dependency_weight.rst \
nghttp2_stream_get_weight.rst \
nghttp2_strerror.rst \
nghttp2_submit_altsvc.rst \
nghttp2_submit_data.rst \
nghttp2_submit_extension.rst \
nghttp2_submit_goaway.rst \
nghttp2_submit_headers.rst \
nghttp2_submit_ping.rst \
@@ -172,19 +145,15 @@ APIDOCS= \
nghttp2_submit_window_update.rst \
nghttp2_version.rst
RST_FILES = \
EXTRA_DIST = \
mkapiref.py \
README.rst \
programmers-guide.rst \
$(APIDOCS) \
nghttp.1.rst \
nghttpd.1.rst \
nghttpx.1.rst \
h2load.1.rst
EXTRA_DIST = \
CMakeLists.txt \
mkapiref.py \
$(RST_FILES) \
$(APIDOCS) \
h2load.1.rst \
sources/index.rst \
sources/tutorial-client.rst \
sources/tutorial-server.rst \
@@ -258,15 +227,13 @@ help:
apiref.rst: \
$(top_builddir)/lib/includes/nghttp2/nghttp2ver.h \
$(top_srcdir)/lib/includes/nghttp2/nghttp2.h
for i in $(RST_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
$(top_builddir)/lib/includes/nghttp2/nghttp2.h
$(PYTHON) $(top_srcdir)/doc/mkapiref.py \
apiref.rst macros.rst enums.rst types.rst . $^
$(APIDOCS): apiref.rst
clean-local:
[ $(srcdir) = $(builddir) ] || for i in $(RST_FILES); do [ -e $(builddir)/$$i ] && rm -f $(builddir)/$$i; done
-rm -f apiref.rst
-rm -f $(APIDOCS)
-rm -rf $(BUILDDIR)/*

View File

@@ -15,7 +15,6 @@ from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes
from sphinx import version_info
from sphinx.roles import XRefRole
from sphinx.locale import l_, _
from sphinx.domains import Domain, ObjType, Index
@@ -232,8 +231,8 @@ class RubyObject(ObjectDescription):
indextext = self.get_index_text(modname, name_cls)
if indextext:
self.indexnode['entries'].append(
_make_index('single', indextext, fullname, fullname))
self.indexnode['entries'].append(('single', indextext,
fullname, fullname))
def before_content(self):
# needed for automatic qualification of members (reset in subclasses)
@@ -416,19 +415,11 @@ class RubyModule(Directive):
# modindex currently
if not noindex:
indextext = _('%s (module)') % modname
inode = addnodes.index(entries=[_make_index(
'single', indextext, 'module-' + modname, modname)])
inode = addnodes.index(entries=[('single', indextext,
'module-' + modname, modname)])
ret.append(inode)
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):
"""

View File

@@ -81,7 +81,6 @@
<body class="wy-body-for-nav" role="document">
{% block extrabody %} {% endblock %}
<div class="wy-grid-for-nav">
{# SIDE NAV, TOGGLES ON MOBILE #}

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,7 @@ _h2load()
_get_comp_words_by_ref cur prev
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

View File

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

View File

@@ -8,7 +8,7 @@ _nghttpd()
_get_comp_words_by_ref cur prev
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

View File

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

View File

@@ -41,7 +41,7 @@ import sys, os
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.append(os.path.abspath('@top_srcdir@/doc/_exts'))
sys.path.append(os.path.abspath('_exts'))
# -- General configuration -----------------------------------------------------

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "H2LOAD" "1" "Jan 05, 2017" "1.18.1" "nghttp2"
.TH "H2LOAD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.SH NAME
h2load \- HTTP/2 benchmarking tool
.
@@ -138,9 +138,7 @@ Default: \fBh2c\fP
.TP
.B \-d, \-\-data=<PATH>
Post FILE to server. The request method is changed to
POST. For http/1.1 connection, if \fI\%\-d\fP is used, the
maximum number of in\-flight pipelined requests is set to
1.
POST.
.UNINDENT
.INDENT 0.0
.TP
@@ -151,7 +149,7 @@ representing the number of connections to be made per
rate period. The maximum number of connections to be
made is given in \fI\%\-c\fP option. This rate will be
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
will run as it normally does, creating connections at
whatever variable rate it wants. The default value for
@@ -242,23 +240,6 @@ http/1.1 for both http and https URI.
.UNINDENT
.INDENT 0.0
.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
Output debug information.
.UNINDENT
@@ -273,9 +254,6 @@ Display version information and exit.
Display this help and exit.
.UNINDENT
.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
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
(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.
.SH SEE ALSO
.sp
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fInghttpx(1)\fP
.SH AUTHOR
Tatsuhiro Tsujikawa
.SH COPYRIGHT

View File

@@ -74,14 +74,14 @@ OPTIONS
.. option:: -w, --window-bits=<N>
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``
.. option:: -W, --connection-window-bits=<N>
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
SPDY.
@@ -108,9 +108,7 @@ OPTIONS
.. option:: -d, --data=<PATH>
Post FILE to server. The request method is changed to
POST. For http/1.1 connection, if :option:`-d` is used, the
maximum number of in-flight pipelined requests is set to
1.
POST.
.. option:: -r, --rate=<N>
@@ -120,7 +118,7 @@ OPTIONS
rate period. The maximum number of connections to be
made is given in :option:`-c` option. This rate will be
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
will run as it normally does, creating connections at
whatever variable rate it wants. The default value for
@@ -202,21 +200,6 @@ OPTIONS
:option:`--no-tls-proto`\=http/1.1, which effectively force
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
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
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
(hours, minutes, seconds and milliseconds, respectively). If a unit

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTP" "1" "Jan 05, 2017" "1.18.1" "nghttp2"
.TH "NGHTTP" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.SH NAME
nghttp \- HTTP/2 client
.
@@ -142,13 +142,10 @@ HTTP upgrade request is performed with OPTIONS method.
.INDENT 0.0
.TP
.B \-p, \-\-weight=<WEIGHT>
Sets weight of given URI. This option can be used
multiple times, and N\-th \fI\%\-p\fP option sets weight of N\-th
URI in the command line. If the number of \fI\%\-p\fP option is
less than the number of URI, the last \fI\%\-p\fP option value is
repeated. If there is no \fI\%\-p\fP option, default weight, 16,
is assumed. The valid value range is
Sets priority group weight. The valid value range is
[1, 256], inclusive.
.sp
Default: \fB16\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -170,14 +167,6 @@ multiple header table size change.
.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.
.UNINDENT
.INDENT 0.0
.TP
.B \-b, \-\-padding=<N>
Add at most <N> bytes to a frame payload as padding.
Specify 0 to disable padding.
@@ -228,14 +217,6 @@ accepts.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-expect\-continue
Perform an Expect/Continue handshake: wait to send DATA
(up to a short timeout) until the server sends a 100
Continue interim response. This option is ignored unless
combined with the \fI\%\-d\fP option.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-version
Display version information and exit.
.UNINDENT
@@ -311,7 +292,7 @@ stream 11 with the weight 12. The other resources (e.g., icon) depend
on stream 11 with the weight 2.
.SH SEE ALSO
.sp
\fBnghttpd(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
\fInghttpd(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
.SH AUTHOR
Tatsuhiro Tsujikawa
.SH COPYRIGHT

View File

@@ -107,14 +107,11 @@ OPTIONS
.. option:: -p, --weight=<WEIGHT>
Sets weight of given URI. This option can be used
multiple times, and N-th :option:`-p` option sets weight of N-th
URI in the command line. If the number of :option:`-p` option is
less than the number of URI, the last :option:`-p` option value is
repeated. If there is no :option:`-p` option, default weight, 16,
is assumed. The valid value range is
Sets priority group weight. The valid value range is
[1, 256], inclusive.
Default: ``16``
.. option:: -M, --peer-max-concurrent-streams=<N>
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
@@ -131,13 +128,6 @@ OPTIONS
frame payload before the last value, to simulate
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>
Add at most <N> bytes to a frame payload as padding.
@@ -179,13 +169,6 @@ OPTIONS
The number of concurrent pushed streams this client
accepts.
.. option:: --expect-continue
Perform an Expect/Continue handshake: wait to send DATA
(up to a short timeout) until the server sends a 100
Continue interim response. This option is ignored unless
combined with the :option:`-d` option.
.. option:: --version
Display version information and exit.
@@ -218,9 +201,7 @@ implementation.
When connection is established, nghttp sends 5 PRIORITY frames to idle
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
tree:
.. code-block:: text
tree::
+-----+
|id=0 |

View File

@@ -12,9 +12,7 @@ implementation.
When connection is established, nghttp sends 5 PRIORITY frames to idle
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
tree:
.. code-block:: text
tree::
+-----+
|id=0 |

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPD" "1" "Jan 05, 2017" "1.18.1" "nghttp2"
.TH "NGHTTPD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.SH NAME
nghttpd \- HTTP/2 server
.
@@ -99,14 +99,6 @@ Specify decoder header table size.
.UNINDENT
.INDENT 0.0
.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
Force colored log output.
.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).
.SH SEE ALSO
.sp
\fBnghttp(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
\fInghttp(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
.SH AUTHOR
Tatsuhiro Tsujikawa
.SH COPYRIGHT

View File

@@ -70,13 +70,6 @@ OPTIONS
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
Force colored log output.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -41,33 +41,6 @@ FILES
:option:`--conf` option cannot be used in the configuration file and
will be ignored if specified.
Error log
Error log is written to stderr by default. It can be configured
using :option:`--errorlog-file`. The format of log message is as
follows:
<datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
<datetime>
It is a conbination of date and time when the log is written. It
is in ISO 8601 format.
<master-pid>
It is a master process ID.
<current-pid>
It is a process ID which writes this log.
<thread-id>
It is a thread ID which writes this log. It would be unique
within <current-pid>.
<filename> and <line>
They are source file name, and line number which produce this log.
<msg>
It is a log message body.
SIGNALS
-------
@@ -76,9 +49,6 @@ SIGQUIT
accepting connection. After all connections are handled, nghttpx
exits.
SIGHUP
Reload configuration file given in :option:`--conf`.
SIGUSR1
Reopen log files.
@@ -86,11 +56,7 @@ SIGUSR2
Fork and execute nghttpx. It will execute the binary in the same
path with same command-line arguments and environment variables.
After new process comes up, sending SIGQUIT to the original process
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
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.
to perform hot swapping.
.. note::
@@ -119,7 +85,7 @@ backend server and extracts URI-reference with parameter
and pushes those URIs to the frontend client. Here is a sample Link
header field to initiate server push:
.. code-block:: text
.. code-block:: http
Link: </fonts/font.woff>; rel=preload
Link: </css/theme.css>; rel=preload
@@ -132,12 +98,12 @@ Currently, the following restriction is applied for server push:
This limitation may be loosened in the future release.
nghttpx also supports server push if both frontend and backend are
HTTP/2 in default mode. In this case, in addition to server push via
Link header field, server push from backend is forwarded to frontend
HTTP/2 session.
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
In this case, in addition to server push via Link header field, server
push from backend is relayed to frontend HTTP/2 session.
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
used.
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
:option:`--client-proxy` is used.
UNIX DOMAIN SOCKET
------------------
@@ -184,10 +150,6 @@ insert serialized session data to memcached with
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -227,33 +189,11 @@ used, LEN must be 48. If
keys. The key appeared first is used as encryption key. All the
remaining keys are used as decryption only.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached` option.
If :option:`--tls-ticket-key-file` is given, encryption key is read
from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
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
---------------
@@ -317,28 +257,7 @@ respectively.
.. rb:attr_reader:: remote_addr
Return IP address of a remote client. If connection is made
via UNIX domain socket, this returns the string "localhost".
.. rb:attr_reader:: server_addr
Return address of server that accepted the connection. This
is a string which specified in :option:`--frontend` option,
excluding port number, and not a resolved IP address. For
UNIX domain socket, this is a path to UNIX domain socket.
.. rb:attr_reader:: server_port
Return port number of the server frontend which accepted the
connection from client.
.. rb:attr_reader:: tls_used
Return true if TLS is used on the connection.
.. rb:attr_reader:: tls_sni
Return the TLS SNI value which client sent in this connection.
Return IP address of a remote client.
.. rb:class:: Request
@@ -374,13 +293,7 @@ respectively.
Request path, including query component (i.e., /index.html).
On assignment, copy of given value is assigned. The path does
not include authority component of URI. This may include
query component. nghttpx makes certain normalization for
path. It decodes percent-encoding for unreserved characters
(see https://tools.ietf.org/html/rfc3986#section-2.3), and
resolves ".." and ".". But it may leave characters which
should be percent-encoded as is. So be careful when comparing
path against desired string.
not include authority component of URI.
.. rb:attr_reader:: headers
@@ -407,7 +320,7 @@ respectively.
Clear all existing request header fields.
.. rb:method:: push(uri)
.. rb:method:: push uri
Initiate to push resource identified by *uri*. Only HTTP/2
protocol supports this feature. For the other protocols, this
@@ -518,62 +431,6 @@ addresses:
App.new
API ENDPOINTS
-------------
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
default, API endpoint is disabled. To enable it, add a dedicated
frontend for API using :option:`--frontend` option with "api"
parameter. All requests which come from this frontend address, will
be treated as API request.
The response is normally JSON dictionary, and at least includes the
following keys:
status
The status of the request processing. The following values are
defined:
Success
The request was successful.
Failure
The request was failed. No change has been made.
code
HTTP status code
We wrote "normally", since nghttpx may return ordinal HTML response in
some cases where the error has occurred before reaching API endpoint
(e.g., header field is too large).
The following section describes available API endpoints.
PUT /api/v1beta1/backendconfig
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This API replaces the current backend server settings with the
requested ones. The request method should be PUT, but POST is also
acceptable. The request body must be nghttpx configuration file
format. For configuration file format, see `FILES`_ section. The
line separator inside the request body must be single LF (0x0A).
Currently, only :option:`backend <--backend>` option is parsed, the
others are simply ignored. The semantics of this API is replace the
current backend with the backend options in request body. Describe
the desired set of backend severs, and nghttpx makes it happen. If
there is no :option:`backend <--backend>` option is found in request
body, the current set of backend is replaced with the :option:`backend
<--backend>` option's default value, which is ``127.0.0.1,80``.
The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is
the case with hot swapping with signals.
The one limitation is that only numeric IP address is allowd in
:option:`backend <--backend>` in request body unless "dns" parameter
is used while non numeric hostname is allowed in command-line or
configuration file is read using :option:`--conf`.
SEE ALSO
--------

View File

@@ -1,79 +1,6 @@
Programmers' Guide
==================
Architecture
------------
The most notable point in nghttp2 library architecture is it does not
perform any I/O. nghttp2 only performs HTTP/2 protocol stuff based on
input byte strings. It will calls callback functions set by
applications while processing input. The output of nghttp2 is just
byte string. An application is responsible to send these output to
the remote peer. The callback functions may be called while producing
output.
Not doing I/O makes embedding nghttp2 library in the existing code
base very easy. Usually, the existing applications have its own I/O
event loops. It is very hard to use nghttp2 in that situation if
nghttp2 does its own I/O. It also makes light weight language wrapper
for nghttp2 easy with the same reason. The down side is that an
application author has to write more code to write complete
application using nghttp2. This is especially true for simple "toy"
application. For the real applications, however, this is not the
case. This is because you probably want to support HTTP/1 which
nghttp2 does not provide, and to do that, you will need to write your
own HTTP/1 stack or use existing third-party library, and bind them
together with nghttp2 and I/O event loop. In this point, not
performing I/O in nghttp2 has more point than doing it.
The primary object that an application uses is :type:`nghttp2_session`
object, which is opaque struct and its details are hidden in order to
ensure the upgrading its internal architecture without breaking the
backward compatibility. An application can set callbacks to
:type:`nghttp2_session` object through the dedicated object and
functions, and it also interacts with it via many API function calls.
An application can create as many :type:`nghttp2_session` object as it
wants. But single :type:`nghttp2_session` object must be used by a
single thread at the same time. This is not so hard to enforce since
most event-based architecture applications use is single thread per
core, and handling one connection I/O is done by single thread.
To feed input to :type:`nghttp2_session` object, one can use
`nghttp2_session_recv()` or `nghttp2_session_mem_recv()` functions.
They behave similarly, and the difference is that
`nghttp2_session_recv()` will use :type:`nghttp2_read_callback` to get
input. On the other hand, `nghttp2_session_mem_recv()` will take
input as its parameter. If in doubt, use `nghttp2_session_mem_recv()`
since it is simpler, and could be faster since it avoids calling
callback function.
To get output from :type:`nghttp2_session` object, one can use
`nghttp2_session_send()` or `nghttp2_session_mem_send()`. The
difference between them is that the former uses
:type:`nghttp2_send_callback` to pass output to an application. On
the other hand, the latter returns the output to the caller. If in
doubt, use `nghttp2_session_mem_send()` since it is simpler. But
`nghttp2_session_send()` might be easier to use if the output buffer
an application has is fixed sized.
In general, an application should call `nghttp2_session_mem_send()`
when it gets input from underlying connection. Since there is great
chance to get something pushed into transmission queue while the call
of `nghttp2_session_mem_send()`, it is recommended to call
`nghttp2_session_mem_recv()` after `nghttp2_session_mem_send()`.
There is a question when we are safe to close HTTP/2 session without
waiting for the closure of underlying connection. We offer 2 API
calls for this: `nghttp2_session_want_read()` and
`nghttp2_session_want_write()`. If they both return 0, application
can destroy :type:`nghttp2_session`, and then close the underlying
connection. But make sure that the buffered output has been
transmitted to the peer before closing the connection when
`nghttp2_session_mem_send()` is used, since
`nghttp2_session_want_write()` does not take into account the
transmission of the buffered data outside of :type:`nghttp2_session`.
Includes
--------
@@ -173,308 +100,6 @@ parsed as 64 bit signed integer. The sum of data length in the
following DATA frames must match with the number in "Content-Length"
header field if it is present (this does not include padding bytes).
RFC 7230 says that server must not send "Content-Length" in any
response with 1xx, and 204 status code. It also says that
"Content-Length" is not allowed in any response with 200 status code
to a CONNECT request. nghttp2 enforces them as well.
Any deviation results in stream error of type PROTOCOL_ERROR. If
error is found in PUSH_PROMISE frame, stream error is raised against
promised stream.
The order of transmission of the HTTP/2 frames
----------------------------------------------
This section describes the internals of libnghttp2 about the
scheduling of transmission of HTTP/2 frames. This is pretty much
internal stuff, so the details could change in the future versions of
the library.
libnghttp2 categorizes HTTP/2 frames into 4 categories: urgent,
regular, syn_stream, and data in the order of higher priority.
The urgent category includes PING and SETTINGS. They are sent with
highest priority. The order inside the category is FIFO.
The regular category includes frames other than PING, SETTINGS, DATA,
and HEADERS which does not create stream (which counts toward
concurrent stream limit). The order inside the category is FIFO.
The syn_stream category includes HEADERS frame which creates stream,
that counts toward the concurrent stream limit.
The data category includes DATA frame, and the scheduling among DATA
frames are determined by HTTP/2 dependency tree.
If the application wants to send frames in the specific order, and the
default transmission order does not fit, it has to schedule frames by
itself using the callbacks (e.g.,
:type:`nghttp2_on_frame_send_callback`).
RST_STREAM has special side effect when it is submitted by
`nghttp2_submit_rst_stream()`. It cancels all pending HEADERS and
DATA frames whose stream ID matches the one in the RST_STREAM frame.
This may cause unexpected behaviour for the application in some cases.
For example, suppose that application wants to send RST_STREAM after
sending response HEADERS and DATA. Because of the reason we mentioned
above, the following code does not work:
.. code-block:: c
nghttp2_submit_response(...)
nghttp2_submit_rst_stream(...)
RST_STREAM cancels HEADERS (and DATA), and just RST_STREAM is sent.
The correct way is use :type:`nghttp2_on_frame_send_callback`, and
after HEADERS and DATA frames are sent, issue
`nghttp2_submit_rst_stream()`. FYI,
:type:`nghttp2_on_frame_not_send_callback` tells you why frames are
not sent.
Implement user defined HTTP/2 non-critical extensions
-----------------------------------------------------
As of nghttp2 v1.8.0, we have added HTTP/2 non-critical extension
framework, which lets application send and receive user defined custom
HTTP/2 non-critical extension frames. nghttp2 also offers built-in
functionality to send and receive official HTTP/2 extension frames
(e.g., ALTSVC frame). For these built-in handler, refer to the next
section.
To send extension frame, use `nghttp2_submit_extension()`, and
implement :type:`nghttp2_pack_extension_callback`. The callback
implements how to encode data into wire format. The callback must be
set to :type:`nghttp2_session_callbacks` using
`nghttp2_session_callbacks_set_pack_extension_callback()`.
For example, we will illustrate how to send `ALTSVC
<https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-14>`_ frame.
.. code-block:: c
typedef struct {
const char *origin;
const char *field;
} alt_svc;
ssize_t pack_extension_callback(nghttp2_session *session, uint8_t *buf,
size_t len, const nghttp2_frame *frame,
void *user_data) {
const alt_svc *altsvc = (const alt_svc *)frame->ext.payload;
size_t originlen = strlen(altsvc->origin);
size_t fieldlen = strlen(altsvc->field);
uint8_t *p;
if (len < 2 + originlen + fieldlen || originlen > 0xffff) {
return NGHTTP2_ERR_CANCEL;
}
p = buf;
*p++ = originlen >> 8;
*p++ = originlen & 0xff;
memcpy(p, altsvc->origin, originlen);
p += originlen;
memcpy(p, altsvc->field, fieldlen);
p += fieldlen;
return p - buf;
}
This implements :type:`nghttp2_pack_extension_callback`. We have to
set this callback to :type:`nghttp2_session_callbacks`:
.. code-block:: c
nghttp2_session_callbacks_set_pack_extension_callback(
callbacks, pack_extension_callback);
To send ALTSVC frame, call `nghttp2_submit_extension()`:
.. code-block:: c
static const alt_svc altsvc = {"example.com", "h2=\":8000\""};
nghttp2_submit_extension(session, 0xa, NGHTTP2_FLAG_NONE, 0,
(void *)&altsvc);
Notice that ALTSVC is use frame type ``0xa``.
To receive extension frames, implement 2 callbacks:
:type:`nghttp2_unpack_extension_callback` and
:type:`nghttp2_on_extension_chunk_recv_callback`.
:type:`nghttp2_unpack_extension_callback` implements the way how to
decode wire format. :type:`nghttp2_on_extension_chunk_recv_callback`
implements how to buffer the incoming extension payload. These
callbacks must be set using
`nghttp2_session_callbacks_set_unpack_extension_callback()` and
`nghttp2_session_callbacks_set_on_extension_chunk_recv_callback()`
respectively. The application also must tell the library which
extension frame type it is willing to receive using
`nghttp2_option_set_user_recv_extension_type()`. Note that the
application has to create :type:`nghttp2_option` object for that
purpose, and initialize session with it.
We use ALTSVC again to illustrate how to receive extension frames. We
use different ``alt_svc`` struct than the previous one.
First implement 2 callbacks. We store incoming ALTSVC payload to
global variable ``altsvc_buffer``. Don't do this in production code
since this is not thread safe:
.. code-block:: c
typedef struct {
const uint8_t *origin;
size_t originlen;
const uint8_t *field;
size_t fieldlen;
} alt_svc;
/* buffers incoming ALTSVC payload */
uint8_t altsvc_buffer[4096];
/* The length of byte written to altsvc_buffer */
size_t altsvc_bufferlen = 0;
int on_extension_chunk_recv_callback(nghttp2_session *session,
const nghttp2_frame_hd *hd,
const uint8_t *data, size_t len,
void *user_data) {
if (sizeof(altsvc_buffer) < altsvc_bufferlen + len) {
altsvc_bufferlen = 0;
return NGHTTP2_ERR_CANCEL;
}
memcpy(altsvc_buffer + altsvc_bufferlen, data, len);
altsvc_bufferlen += len;
return 0;
}
int unpack_extension_callback(nghttp2_session *session, void **payload,
const nghttp2_frame_hd *hd, void *user_data) {
uint8_t *origin, *field;
size_t originlen, fieldlen;
uint8_t *p, *end;
alt_svc *altsvc;
if (altsvc_bufferlen < 2) {
altsvc_bufferlen = 0;
return NGHTTP2_ERR_CANCEL;
}
p = altsvc_buffer;
end = altsvc_buffer + altsvc_bufferlen;
originlen = ((*p) << 8) + *(p + 1);
p += 2;
if (p + originlen > end) {
altsvc_bufferlen = 0;
return NGHTTP2_ERR_CANCEL;
}
origin = p;
field = p + originlen;
fieldlen = end - field;
altsvc = (alt_svc *)malloc(sizeof(alt_svc));
altsvc->origin = origin;
altsvc->originlen = originlen;
altsvc->field = field;
altsvc->fieldlen = fieldlen;
*payload = altsvc;
altsvc_bufferlen = 0;
return 0;
}
Set these callbacks to :type:`nghttp2_session_callbacks`:
.. code-block:: c
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
callbacks, on_extension_chunk_recv_callback);
nghttp2_session_callbacks_set_unpack_extension_callback(
callbacks, unpack_extension_callback);
In ``unpack_extension_callback`` above, we set unpacked ``alt_svc``
object to ``*payload``. nghttp2 library then, calls
:type:`nghttp2_on_frame_recv_callback`, and ``*payload`` will be
available as ``frame->ext.payload``:
.. code-block:: c
int on_frame_recv_callback(nghttp2_session *session,
const nghttp2_frame *frame, void *user_data) {
switch (frame->hd.type) {
...
case 0xa: {
alt_svc *altsvc = (alt_svc *)frame->ext.payload;
fprintf(stderr, "ALTSVC frame received\n");
fprintf(stderr, " origin: %.*s\n", (int)altsvc->originlen, altsvc->origin);
fprintf(stderr, " field : %.*s\n", (int)altsvc->fieldlen, altsvc->field);
free(altsvc);
break;
}
}
return 0;
}
Finally, application should set the extension frame types it is
willing to receive:
.. code-block:: c
nghttp2_option_set_user_recv_extension_type(option, 0xa);
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
its creation:
.. code-block:: c
nghttp2_session_client_new2(&session, callbacks, user_data, option);
How to use built-in HTTP/2 extension frame handlers
---------------------------------------------------
In the previous section, we talked about the user defined HTTP/2
extension frames. In this section, we talk about HTTP/2 extension
frame support built into nghttp2 library.
As of this writing, nghttp2 supports ALTSVC extension frame. To send
ALTSVC frame, use `nghttp2_submit_altsvc()` function.
To receive ALTSVC frame through built-in functionality, application
has to use `nghttp2_option_set_builtin_recv_extension_type()` to
indicate the willingness of receiving ALTSVC frame:
.. code-block:: c
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
This is very similar to the case when we used to receive user defined
frames.
If the same frame type is set using
`nghttp2_option_set_builtin_recv_extension_type()` and
`nghttp2_option_set_user_recv_extension_type()`, the latter takes
precedence. Application can implement its own frame handler rather
than using built-in handler.
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
its creation, like so:
.. code-block:: c
nghttp2_session_client_new2(&session, callbacks, user_data, option);
When ALTSVC is received, :type:`nghttp2_on_frame_recv_callback` will
be called as usual.

View File

@@ -17,22 +17,24 @@ installed in the following way. First, let us introduce
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
for ``ANDROID_HOME``. For example, to install toolchain under
``$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 \
--arch arm --api 16 --stl gnustl
--install-dir $ANDROID_HOME/toolchain
The additional flag ``--system=linux-x86_64`` may be required if you
are using x86_64 system.
The API level (``--api``) is not important here because we don't use
Android specific C/C++ API.
The platform level is not important here because we don't use Android
specific C/C++ API.
The dependent libraries, such as OpenSSL, libev, and c-ares should be
built with the toolchain and installed under
``$ANDROID_HOME/usr/local``. We recommend to build these libraries as
static library to make the deployment easier. libxml2 support is
currently disabled.
The dependent libraries, such as OpenSSL and libev should be built
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
We recommend to build these libraries as static library to make the
deployment easier. libxml2 support is currently disabled.
Although zlib comes with Android NDK, it seems not to be a part of
public API, so we have to built it for our own. That also provides us
@@ -43,9 +45,7 @@ spdylay as well.
Before running ``android-config`` and ``android-make``,
``ANDROID_HOME`` environment variable must be set to point to the
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``:
.. code-block:: text
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``::
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
@@ -97,26 +97,6 @@ patch, to configure libev, use the following script:
And run ``make install`` to build and install.
To configure c-ares, use the following script:
.. code-block:: sh
#!/bin/sh -e
if [ -z "$ANDROID_HOME" ]; then
echo 'No $ANDROID_HOME specified.'
exit 1
fi
PREFIX=$ANDROID_HOME/usr/local
TOOLCHAIN=$ANDROID_HOME/toolchain
PATH=$TOOLCHAIN/bin:$PATH
./configure \
--host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
--disable-shared
To configure zlib, use the following script:
.. code-block:: sh
@@ -153,24 +133,24 @@ To configure spdylay, use the following script:
#!/bin/sh -e
if [ -z "$ANDROID_HOME" ]; then
echo 'No $ANDROID_HOME specified.'
exit 1
echo 'No $ANDROID_HOME specified.'
exit 1
fi
PREFIX=$ANDROID_HOME/usr/local
TOOLCHAIN=$ANDROID_HOME/toolchain
PATH=$TOOLCHAIN/bin:$PATH
./configure \
--disable-shared \
--host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
--without-libxml2 \
--disable-src \
--disable-examples \
CPPFLAGS="-I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-L$PREFIX/lib"
--disable-shared \
--host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
--without-libxml2 \
--disable-src \
--disable-examples \
CPPFLAGS="-I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-L$PREFIX/lib"
And run ``make install`` to build and install.
@@ -179,8 +159,6 @@ then ``android-make`` to compile nghttp2 source files.
If all went well, application binaries, such as nghttpx, are created
under src directory. Strip debugging information from the binary
using the following command:
.. code-block:: text
using the following command::
$ arm-linux-androideabi-strip src/nghttpx

View File

@@ -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
directory. Since clang-format produces slightly different results
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
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
uses clang-format-diff.py to detect any style errors. If it is not in
your PATH or it exists under different name (e.g.,
clang-format-diff-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.
For emacs users, integrating clang-format to emacs is very easy.

View File

@@ -1,43 +1,33 @@
.. program:: h2load
h2load - HTTP/2 benchmarking tool - HOW-TO
==========================================
:doc:`h2load.1` is benchmarking tool for HTTP/2 and HTTP/1.1. If
built with spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it
also supports SPDY protocol. It supports SSL/TLS and clear text for
all supported protocols.
Compiling from source
---------------------
h2load is compiled alongside nghttp2 and requires that the
``--enable-apps`` flag is passed to ``./configure`` and `required
dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are
available during compilation. For details on compiling, see `nghttp2:
Building from Git
<https://github.com/nghttp2/nghttp2#building-from-git>`_.
h2load is benchmarking tool for HTTP/2 and HTTP/1.1. If built with
spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it also
supports SPDY protocol. It supports SSL/TLS and clear text for all
supported protocols.
Basic Usage
-----------
In order to set benchmark settings, specify following 3 options.
:option:`-n`
``-n``
The number of total requests. Default: 1
:option:`-c`
``-c``
The number of concurrent clients. Default: 1
:option:`-m`
The max concurrent streams to issue per client. Default: 1
``-m``
The max concurrent streams to issue per client.
If ``auto`` is given, the number of given URIs is used.
Default: ``auto``
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
You can set specific protocols in :option:`--npn-list` option. For
You can set specific protocols in ``--npn-list`` option. For
cleartext connection, the default protocol is HTTP/2. To change the
protocol in cleartext connection, use :option:`--no-tls-proto` option.
For convenience, :option:`--h1` option forces HTTP/1.1 for both
cleartext and SSL/TLS connections.
protocol in cleartext connection, use ``--no-tls-proto`` option. For
convenience, ``--h1`` option forces HTTP/1.1 for both cleartext and
SSL/TLS connections.
Here is a command-line to perform benchmark to URI \https://localhost
using total 100000 requests, 100 concurrent clients and 10 max
@@ -72,11 +62,11 @@ benchmarking results. By default, h2load uses large enough flow
control window, which effectively disables flow control. To adjust
receiver flow control window size, there are following options:
:option:`-w`
``-w``
Sets the stream level initial window size to
(2**<N>)-1. For SPDY, 2**<N> is used instead.
:option:`-W`
``-W``
Sets the connection level initial window size to
(2**<N>)-1. For SPDY, if <N> is strictly less
than 16, this option is ignored. Otherwise
@@ -86,17 +76,17 @@ Multi-Threading
---------------
Sometimes benchmarking client itself becomes a bottleneck. To remedy
this situation, use :option:`-t` option to specify the number of native
this situation, use ``-t`` option to specify the number of native
thread to use.
:option:`-t`
``-t``
The number of native threads. Default: 1
Selecting protocol for clear text
---------------------------------
By default, if \http:// URI is given, HTTP/2 protocol is used. To
change the protocol to use for clear text, use :option:`-p` option.
change the protocol to use for clear text, use ``-p`` option.
Multiple URIs
-------------
@@ -107,12 +97,3 @@ If multiple URIs are specified, they are used in round robin manner.
Please note that h2load uses scheme, host and port in the first URI
and ignores those parts in the rest of the URIs.
UNIX domain socket
------------------
To request against UNIX domain socket, use :option:`--base-uri`, and
specify ``unix:`` followed by the path to UNIX domain socket. For
example, if UNIX domain socket is ``/tmp/nghttpx.sock``, use
``--base-uri=unix:/tmp/nghttpx.sock``. h2load uses scheme, host and
port in the first URI in command-line or input file.

View File

@@ -8,8 +8,7 @@ nghttp2 - HTTP/2 C Library
This is an implementation of Hypertext Transfer Protocol version 2.
The project is hosted at `github.com/nghttp2/nghttp2
<https://github.com/nghttp2/nghttp2>`_.
The project is hosted at `github.com/tatsuhiro-t/nghttp2 <https://github.com/tatsuhiro-t/nghttp2>`_.
Contents:
@@ -37,18 +36,17 @@ Contents:
asio_http2_server.h
asio_http2_client.h
asio_http2.h
Source <https://github.com/nghttp2/nghttp2>
Issues <https://github.com/nghttp2/nghttp2/issues>
Source <https://github.com/tatsuhiro-t/nghttp2>
Issues <https://github.com/tatsuhiro-t/nghttp2/issues>
nghttp2.org <https://nghttp2.org/>
Released Versions
=================
https://github.com/nghttp2/nghttp2/releases
https://github.com/tatsuhiro-t/nghttp2/releases
Resources
---------
* HTTP/2 https://tools.ietf.org/html/rfc7540
* HPACK https://tools.ietf.org/html/rfc7541
* HTTP Alternative Services https://tools.ietf.org/html/rfc7838

View File

@@ -1,101 +1,79 @@
.. program:: nghttpx
nghttpx - HTTP/2 proxy - HOW-TO
===============================
:doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and
other protocols (e.g., HTTP/1, SPDY). It operates in several modes
and each mode may require additional programs to work with. This
article describes each operation mode and explains the intended
use-cases. It also covers some useful options later.
nghttpx is a proxy translating protocols between HTTP/2 and other
protocols (e.g., HTTP/1, SPDY). It operates in several modes and each
mode may require additional programs to work with. This article
describes each operation mode and explains the intended use-cases. It
also covers some useful options later.
Default mode
------------
If nghttpx is invoked without :option:`--http2-proxy`, it operates in
default mode. In this mode, it works as reverse proxy (gateway) for
both HTTP/2 and HTTP/1 clients to backend servers. This is also known
as "HTTP/2 router". If nghttpx is linked with spdylay library and
frontend connection is SSL/TLS, the frontend also supports SPDY
protocol.
If nghttpx is invoked without any ``-s``, ``-p`` and ``--client``, it
operates in default mode. In this mode, nghttpx frontend listens for
HTTP/2 requests and translates them to HTTP/1 requests. Thus it works
as reverse proxy (gateway) for HTTP/2 clients to HTTP/1 web server.
This is also known as "HTTP/2 router". HTTP/1 requests are also
supported in frontend as a fallback. If nghttpx is linked with
spdylay library and frontend connection is SSL/TLS, the frontend also
supports SPDY protocol.
By default, frontend connection is encrypted using SSL/TLS. So
server's private key and certificate must be supplied to the command
line (or through configuration file). In this case, the frontend
protocol selection will be done via ALPN or NPN.
By default, this mode's frontend connection is encrypted using
SSL/TLS. So server's private key and certificate must be supplied to
the command line (or through configuration file). In this case, the
frontend protocol selection will be done via ALPN or NPN.
To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option. In this case, SPDY protocol is not
available even if spdylay library is liked to nghttpx. HTTP/2 and
HTTP/1 are available on the frontend, and an HTTP/1 connection can be
upgraded to HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by
sending HTTP/2 connection preface is also supported.
With ``--frontend-no-tls`` option, user can turn off SSL/TLS in
frontend connection. In this case, SPDY protocol is not available
even if spdylay library is liked to nghttpx. HTTP/2 and HTTP/1 are
available on the frontend and a HTTP/1 connection can be upgraded to
HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by sending
HTTP/2 connection preface is also supported.
nghttpx can listen on multiple frontend addresses. This is achieved
by using multiple :option:`--frontend` options. For each frontend
address, TLS can be enabled or disabled.
By default, backend HTTP/1 connections are not encrypted. To enable
TLS on HTTP/1 backend connections, use ``--backend-http1-tls`` option.
This applies to all mode whose backend connections are HTTP/1.
By default, backend connections are not encrypted. To enable TLS
encryption on backend connections, use ``tls`` keyword in
:option:`--backend` option. Using patterns and ``proto`` keyword in
:option:`--backend` option, backend application protocol can be
specified per host/request path pattern. It means that you can use
both HTTP/2 and HTTP/1 in backend connections at the same time. Note
that default backend protocol is HTTP/1.1. To use HTTP/2 in backend,
you have to specify ``h2`` in ``proto`` keyword in :option:`--backend`
explicitly.
The backend is supposed to be Web server. For example, to make
The backend is supposed to be HTTP/1 Web server. For example, to make
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
backend Web server is configured to listen to HTTP request at port
8080 in the same host, run nghttpx command-line like this:
.. code-block:: text
backend HTTP/1 web server is configured to listen to HTTP/1 request at
port 8080 in the same host, run nghttpx command-line like this::
$ 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
example, you can send GET request to the server using nghttp:
.. code-block:: text
example, you can send GET request to the server using nghttp::
$ nghttp -nv https://localhost:8443/
HTTP/2 proxy mode
-----------------
If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
protocols in frontend and backend connections are the same in `default
mode`_. The difference is that this mode acts like forward proxy and
assumes the backend is HTTP proxy server (e.g., Squid, Apache Traffic
Server). HTTP/1 request must include absolute URI in request line.
If nghttpx is invoked with ``-s`` option, it operates in HTTP/2 proxy
mode. The supported protocols in frontend and backend connections are
the same in `default mode`_. The difference is that this mode acts
like forward proxy and assumes the backend is HTTP/1 proxy server
(e.g., squid, traffic server). So HTTP/1 request must include
absolute URI in request line.
By default, frontend connection is encrypted. So this mode is also
called secure proxy. If nghttpx is linked with spdylay, it supports
SPDY protocols and it works as so called SPDY proxy.
To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option.
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
connection, so the connection gets insecure.
The backend must be HTTP proxy server. nghttpx supports multiple
backend server addresses. It translates incoming requests to HTTP
The backend must be HTTP/1 proxy server. nghttpx supports multiple
backend server addresses. It translates incoming requests to HTTP/1
request to backend server. The backend server performs real proxy
work for each request, for example, dispatching requests to the origin
server and caching contents.
The backend connection is not encrypted by default. To enable
encryption, use ``tls`` keyword in :option:`--backend` option. The
default backend protocol is HTTP/1.1. To use HTTP/2 in backend
connection, use :option:`--backend` option, and specify ``h2`` in
``proto`` keyword explicitly.
For example, to make nghttpx listen to encrypted HTTP/2 requests at
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
like this:
.. code-block:: text
port 8443, and a backend HTTP/1 proxy server is configured to listen
to HTTP/1 request at port 8080 in the same host, run nghttpx
command-line like this::
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
@@ -118,78 +96,152 @@ Chromium require valid certificate for secure proxy.
For Firefox, open Preference window and select Advanced then click
Network tab. Clicking Connection Settings button will show the
dialog. Select "Automatic proxy configuration URL" and enter the path
to proxy.pac file, something like this:
.. code-block:: text
to proxy.pac file, something like this::
file:///path/to/proxy.pac
For Chromium, use following command-line:
.. code-block:: text
For Chromium, use following command-line::
$ 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
requires to be configured as forward proxy. Here is the minimum
configuration items to edit:
.. code-block:: text
configuration items to edit::
CONFIG proxy.config.reverse_proxy.enabled INT 0
CONFIG proxy.config.url_remap.remap_required INT 0
Consult Traffic server `documentation
<http://trafficserver.readthedocs.org/en/latest/admin-guide/configuration/transparent-forward-proxying.en.html>`_
<https://docs.trafficserver.apache.org/en/latest/admin/forward-proxy.en.html>`_
to know how to configure traffic server as forward proxy and its
security implications.
ALPN support
------------
Client mode
-----------
ALPN support requires OpenSSL >= 1.0.2.
If nghttpx is invoked with ``--client`` option, it operates in client
mode. In this mode, nghttpx listens for plain, unencrypted HTTP/2 and
HTTP/1 requests and translates them to encrypted HTTP/2 requests to
the backend. User cannot enable SSL/TLS in frontend connection.
Disable frontend SSL/TLS
------------------------
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
Upgrade. To disable SSL/TLS in backend connection, use
``--backend-no-tls`` option.
The frontend connections are encrypted with SSL/TLS by default. To
turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend`
option. If this option is used, the private key and certificate are
not required to run nghttpx.
By default, the number of backend HTTP/2 connections per worker
(thread) is determined by number of ``-b`` option. To adjust this
value, use ``--backend-http2-connections-per-worker`` option.
Enable backend SSL/TLS
----------------------
The backend server is supporsed to be a HTTP/2 web server (e.g.,
nghttpd). The one use-case of this mode is utilize existing HTTP/1
clients to test HTTP/2 deployment. Suppose that HTTP/2 web server
listens to port 80 without encryption. Then run nghttpx as client
mode to access to that web server::
The backend connections are not encrypted by default. To enable
SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option.
$ nghttpx --client -f127.0.0.1,8080 -b127.0.0.1,80 --backend-no-tls
Enable SSL/TLS on memcached connection
--------------------------------------
.. note::
By default, memcached connection is not encrypted. To enable
encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
:option:`--tls-session-cache-memcached` for TLS session cache.
You may need ``-k`` option if HTTP/2 server enables SSL/TLS and
its certificate is self-signed. But please note that it is
insecure.
Specifying additional server certificates
-----------------------------------------
Then you can use curl to access HTTP/2 server via nghttpx::
nghttpx accepts additional server private key and certificate pairs
using :option:`--subcert` option. It can be used multiple times.
$ curl http://localhost:8080/
Client proxy mode
-----------------
If nghttpx is invoked with ``-p`` option, it operates in client proxy
mode. This mode behaves like `client mode`_, but it works like
forward proxy. So HTTP/1 request must include absolute URI in request
line.
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
Upgrade. To disable SSL/TLS in backend connection, use
``--backend-no-tls`` option.
By default, the number of backend HTTP/2 connections per worker
(thread) is determined by number of ``-b`` option. To adjust this
value, use ``--backend-http2-connections-per-worker`` option.
The backend server must be a HTTP/2 proxy. You can use nghttpx in
`HTTP/2 proxy mode`_ as backend server. The one use-case of this mode
is utilize existing HTTP/1 clients to test HTTP/2 connections between
2 proxies. The another use-case is use this mode to aggregate local
HTTP/1 connections to one HTTP/2 backend encrypted connection. This
makes HTTP/1 clients which does not support secure proxy can use
secure HTTP/2 proxy via nghttpx client mode.
Suppose that HTTP/2 proxy listens to port 8443, just like we saw in
`HTTP/2 proxy mode`_. To run nghttpx in client proxy mode to access
that server, invoke nghttpx like this::
$ nghttpx -p -f127.0.0.1,8080 -b127.0.0.1,8443
.. note::
You may need ``-k`` option if HTTP/2 server's certificate is
self-signed. But please note that it is insecure.
Then you can use curl to issue HTTP request via HTTP/2 proxy::
$ curl --http-proxy=http://localhost:8080 http://www.google.com/
You can configure web browser to use localhost:8080 as forward
proxy.
HTTP/2 bridge mode
------------------
If nghttpx is invoked with ``--http2-bridge`` option, it operates in
HTTP/2 bridge mode. The supported protocols in frontend connections
are the same in `default mode`_. The protocol in backend is HTTP/2
only.
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
connection, so the connection gets insecure. To disable SSL/TLS in
backend connection, use ``--backend-no-tls`` option.
By default, the number of backend HTTP/2 connections per worker
(thread) is determined by number of ``-b`` option. To adjust this
value, use ``--backend-http2-connections-per-worker`` option.
The backend server is supporsed to be a HTTP/2 web server or HTTP/2
proxy. If backend server is HTTP/2 proxy, use
``--no-location-rewrite`` and ``--no-host-rewrite`` options to disable
rewriting location, host and :authority header field.
The use-case of this mode is aggregate the incoming connections to one
HTTP/2 connection. One backend HTTP/2 connection is created per
worker (thread).
Disable SSL/TLS
---------------
In `default mode`_, `HTTP/2 proxy mode`_ and `HTTP/2 bridge mode`_,
frontend connections are encrypted with SSL/TLS by default. To turn
off SSL/TLS, use ``--frontend-no-tls`` option. If this option is
used, the private key and certificate are not required to run nghttpx.
In `client mode`_, `client proxy mode`_ and `HTTP/2 bridge mode`_,
backend connections are encrypted with SSL/TLS by default. To turn
off SSL/TLS, use ``--backend-no-tls`` option.
Specifying additional CA certificate
------------------------------------
By default, nghttpx tries to read CA certificate from system. But
depending on the system you use, this may fail or is not supported.
To specify CA certificate manually, use :option:`--cacert` option.
The specified file must be PEM format and can contain multiple
To specify CA certificate manually, use ``--cacert`` option. The
specified file must be PEM format and can contain multiple
certificates.
By default, nghttpx validates server's certificate. If you want to
turn off this validation, knowing this is really insecure and what you
are doing, you can use :option:`--insecure` option to disable
certificate validation.
are doing, you can use ``-k`` option to disable certificate
validation.
Read/write rate limit
---------------------
@@ -198,9 +250,9 @@ nghttpx supports transfer rate limiting on frontend connections. You
can do rate limit per frontend connection for reading and writing
individually.
To perform rate limit for reading, use :option:`--read-rate` and
:option:`--read-burst` options. For writing, use
:option:`--write-rate` and :option:`--write-burst`.
To perform rate limit for reading, use ``--read-rate`` and
``--read-burst`` options. For writing, use ``--write-rate`` and
``--write-burst``.
Please note that rate limit is performed on top of TCP and nothing to
do with HTTP/2 flow control.
@@ -211,17 +263,17 @@ Rewriting location header field
nghttpx automatically rewrites location response header field if the
following all conditions satisfy:
* In the default mode (:option:`--http2-proxy` is not used)
* :option:`--no-location-rewrite` is not used
* URI in location header field is an absolute URI
* URI in location header field is not absolute URI or is not https URI.
* URI in location header field includes non empty host component.
* 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
frontend, and authority is replaced with which appears in
``:authority``, or ``host`` request header field. ``:authority``
header field has precedence over ``host``.
When rewrite happens, URI scheme and port are replaced with the ones
used in frontend, and host is replaced with which appears in
:authority or host request header field. :authority header field has
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
------------
@@ -236,191 +288,20 @@ all existing frontend connections are done, the current process will
exit. At this point, only new nghttpx process exists and serves
incoming requests.
If you want to just reload configuration file without executing new
binary, send SIGHUP to nghttpx master process.
Re-opening log files
--------------------
When rotating log files, it is desirable to re-open log files after
log rotation daemon renamed existing log files. To tell nghttpx to
re-open log files, send USR1 signal to nghttpx process. It will
re-open files specified by :option:`--accesslog-file` and
:option:`--errorlog-file` options.
Multiple frontend addresses
---------------------------
nghttpx can listen on multiple frontend addresses. To specify them,
just use :option:`--frontend` (or its shorthand :option:`-f`) option
repeatedly. TLS can be enabled or disabled per frontend address
basis. For example, to listen on port 443 with TLS enabled, and on
port 80 without TLS:
.. code-block:: text
frontend=*,443
frontend=*,80;no-tls
re-open files specified by ``--accesslog-file`` and
``--errorlog-file`` options.
Multiple backend addresses
--------------------------
nghttpx supports multiple backend addresses. To specify them, just
use :option:`--backend` (or its shorthand :option:`-b`) option
repeatedly. For example, to use ``192.168.0.10:8080`` and
``192.168.0.11:8080``, use command-line like this:
``-b192.168.0.10,8080 -b192.168.0.11,8080``. In configuration file,
this looks like:
.. code-block:: text
backend=192.168.0.10,8080
backend=192.168.0.11,8008
nghttpx can route request to different backend according to request
host and path. For example, to route request destined to host
``doc.example.com`` to backend server ``docserv:3000``, you can write
like so:
.. code-block:: text
backend=docserv,3000;doc.example.com/
When you write this option in command-line, you should enclose
argument with single or double quotes, since the character ``;`` has a
special meaning in shell.
To route, request to request path whose prefix is ``/foo`` to backend
server ``[::1]:8080``, you can write like so:
.. code-block:: text
backend=::1,8080;/foo
Of course, you can specify both host and request path at the same
time:
.. code-block:: text
backend=192.168.0.10,8080;example.com/foo
We can use ``*`` in the left most position of host to achieve wildcard
suffix match. If ``*`` is the left most character, then the remaining
string should match the request host suffix. ``*`` must match at
least one character. For example, ``*.example.com`` matches
``www.example.com`` and ``dev.example.com``, and does not match
``example.com`` and ``nghttp2.org``. The exact match (without ``*``)
always takes precedence over wildcard match.
One important thing you have to remember is that we have to specify
default routing pattern for so called "catch all" pattern. To write
"catch all" pattern, just specify backend server address, without
pattern.
Usually, host is the value of ``Host`` header field. In HTTP/2, the
value of ``:authority`` pseudo header field is used.
When you write multiple backend addresses sharing the same routing
pattern, they are used as load balancing. For example, to use 2
servers ``serv1:3000`` and ``serv2:3000`` for request host
``example.com`` and path ``/myservice``, you can write like so:
.. code-block:: text
backend=serv1,3000;example.com/myservice
backend=serv2,3000;example.com/myservice
You can also specify backend application protocol in
:option:`--backend` option using ``proto`` keyword after pattern.
Utilizing this allows ngttpx to route certain request to HTTP/2, other
requests to HTTP/1. For example, to route requests to ``/ws/`` in
backend HTTP/1.1 connection, and use backend HTTP/2 for other
requests, do this:
.. code-block:: text
backend=serv1,3000;/;proto=h2
backend=serv1,3000;/ws/;proto=http/1.1
The default backend protocol is HTTP/1.1.
TLS can be enabled per pattern basis:
.. code-block:: text
backend=serv1,8443;/;proto=h2;tls
backend=serv2,8080;/ws/;proto=http/1.1
In the above case, connection to serv1 will be encrypted by TLS. On
the other hand, connection to serv2 will not be encrypted by TLS.
Dynamic hostname lookup
-----------------------
By default, nghttpx performs backend hostname lookup at start up, or
configuration reload, and keeps using them in its entire session. To
make nghttpx perform hostname lookup dynamically, use ``dns``
parameter in :option:`--backend` option, like so:
.. code-block:: text
backend=foo.example.com;;dns
nghttpx will cache resolved addresses for certain period of time. To
change this cache period, use :option:`--dns-cache-timeout`.
Migration from nghttpx v1.8.0 or earlier
----------------------------------------
As of nghttpx 1.9.0, ``--frontend-no-tls`` and ``--backend-no-tls``
have been removed.
To disable encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` potion:
.. code-block:: text
frontend=*,3000;no-tls
The TLS encryption is now disabled on backend connection in all modes
by default. To enable encryption on backend connection, use ``tls``
keyword in :option:`--backend` option:
.. code-block:: text
backend=127.0.0.1,8080;tls
As of nghttpx 1.9.0, ``--http2-bridge``, ``--client`` and
``--client-proxy`` options have been removed. These functionality can
be used using combinations of options.
Use following option instead of ``--http2-bridge``:
.. code-block:: text
backend=<ADDR>,<PORT>;;proto=h2;tls
Use following options instead of ``--client``:
.. code-block:: text
frontend=<ADDR>,<PORT>;no-tls
backend=<ADDR>,<PORT>;;proto=h2;tls
Use following options instead of ``--client-proxy``:
.. code-block:: text
http2-proxy=yes
frontend=<ADDR>,<PORT>;no-tls
backend=<ADDR>,<PORT>;;proto=h2;tls
We also removed ``--backend-http2-connections-per-worker`` option. It
was present because previously the number of backend h2 connection was
statically configured, and defaulted to 1. Now the number of backend
h2 connection is increased on demand. We know the maximum number of
concurrent streams per connection. When we push as many request as
the maximum concurrency to the one connection, we create another new
connection so that we can distribute load and avoid delay the request
processing. This is done automatically without any configuration.
use ``-b`` option repeatedly. For example, to use backend1:8080 and
backend2:8080, use command-line like this: ``-bbackend1,8080
-bbackend2,8080``. For HTTP/2 backend, see also
``--backend-http2-connections-per-worker`` option.

View File

@@ -13,7 +13,7 @@ The extension module is called ``nghttp2``.
determined by configure script. If the detected Python version is not
what you expect, specify a path to Python executable in ``PYTHON``
variable as an argument to configure script (e.g., ``./configure
PYTHON=/usr/bin/python3.5``).
PYTHON=/usr/bin/python3.4``).
HPACK API
---------
@@ -136,15 +136,13 @@ HTTP/2 servers
.. note::
We use :py:mod:`asyncio` for HTTP/2 server classes, and ALPN.
Therefore, Python 3.5 or later is required to use these objects.
To explicitly configure nghttp2 build to use Python 3.5, specify
the ``PYTHON`` variable to the path to Python 3.5 executable when
invoking configure script like this:
We use :py:mod:`asyncio` for HTTP/2 server classes. Therefore,
Python 3.4 or later is required to use these objects. To
explicitly configure nghttp2 build to use Python 3.4, specify the
``PYTHON`` variable to the path to Python 3.4 executable when
invoking configure script like this::
.. code-block:: text
$ ./configure PYTHON=/usr/bin/python3.5
$ ./configure PYTHON=/usr/bin/python3.4
.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)

View File

@@ -7,9 +7,7 @@ the end of this page. It also resides in the examples directory in
the archive or repository.
This simple client takes a single HTTPS URI and retrieves the resource
at the URI. The synopsis is:
.. code-block:: text
at the URI. The synopsis is::
$ libevent-client HTTPS_URI
@@ -33,17 +31,6 @@ protocol the library supports::
return SSL_TLSEXT_ERR_OK;
}
If you are following TLS related RFC, you know that NPN is not the
standardized way to negotiate HTTP/2. NPN itself is not event
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
ALPN support depending on OpenSSL version. OpenSSL's ALPN
implementation does not require callback function like the above. But
we have to instruct OpenSSL SSL_CTX to use ALPN, which we'll talk
about soon.
The callback is added to the SSL_CTX object using
``SSL_CTX_set_next_proto_select_cb()``::
@@ -59,18 +46,9 @@ The callback is added to the SSL_CTX object using
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
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:
We define and use a ``http2_session_data`` structure to store data
@@ -146,27 +124,7 @@ underlying network socket::
if (events & BEV_EVENT_CONNECTED) {
int fd = bufferevent_getfd(bev);
int val = 1;
const unsigned char *alpn = NULL;
unsigned int alpnlen = 0;
SSL *ssl;
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));
initialize_nghttp2_session(session_data);
send_client_connection_header(session_data);
@@ -186,9 +144,6 @@ underlying network socket::
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``
events, we just simply tear down the connection.

View File

@@ -78,16 +78,15 @@ header data. To initialize the object, use
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
To inflate header data, use `nghttp2_hd_inflate_hd()`::
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen,
int in_final);
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
uint8_t *in, size_t inlen, int in_final);
`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a
single header field at a time. Multiple calls are normally required to
read a full stream of bytes and output all of the header fields.
`nghttp2_hd_inflate_hd()` reads a stream of bytes and outputs a single
header field at a time. Multiple calls are normally required to read a
full stream of bytes and output all of the header fields.
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
@@ -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
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`_.
Finally, to delete a :type:`nghttp2_hd_inflater` object, use

View File

@@ -10,9 +10,7 @@ archive or repository.
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
certificate file. The synopsis is:
.. code-block:: text
certificate file. The synopsis is::
$ 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
application protocol name in the wire format of NPN in a statically
allocated buffer. This is safe because we only create one ``SSL_CTX``
object in the program's entire lifetime.
If you are following TLS related RFC, you know that NPN is not the
standardized way to negotiate HTTP/2. NPN itself is not even
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
ALPN support depending on OpenSSL version. In ALPN, client sends the
list of supported application protocols, and server selects one of
them. We provide the callback for it::
object in the program's entire lifetime::
static unsigned char next_proto_list[256];
static size_t next_proto_list_len;
@@ -49,22 +37,6 @@ them. We provide the callback for it::
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) {
SSL_CTX *ssl_ctx;
EC_KEY *ecdh;
@@ -79,11 +51,6 @@ them. We provide the callback for it::
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
@@ -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
``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
application:
@@ -205,31 +167,11 @@ underlying network socket::
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
http2_session_data *session_data = (http2_session_data *)ptr;
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);
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);
if (send_server_connection_header(session_data) != 0 ||
session_send(session_data) != 0) {
if (send_server_connection_header(session_data) != 0) {
delete_http2_session_data(session_data);
return;
}
@@ -246,9 +188,6 @@ underlying network socket::
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
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
The ``delete_http2_session_data()`` function destroys the

View File

@@ -1,49 +0,0 @@
if(ENABLE_EXAMPLES)
file(GLOB c_sources *.c)
set_source_files_properties(${c_sources} PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}")
file(GLOB cxx_sources *.cc)
set_source_files_properties(${cxx_sources} PROPERTIES
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/lib/includes
${CMAKE_BINARY_DIR}/lib/includes
${CMAKE_SOURCE_DIR}/src/includes
${CMAKE_SOURCE_DIR}/third-party
${LIBEVENT_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
)
link_libraries(
nghttp2
${LIBEVENT_OPENSSL_LIBRARIES}
${OPENSSL_LIBRARIES}
${APP_LIBRARIES}
)
add_executable(client client.c $<TARGET_OBJECTS:http-parser>)
add_executable(libevent-client libevent-client.c $<TARGET_OBJECTS:http-parser>)
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:http-parser>)
add_executable(deflate deflate.c $<TARGET_OBJECTS:http-parser>)
if(ENABLE_ASIO_LIB)
foreach(name asio-sv asio-sv2 asio-cl asio-cl2)
add_executable(${name} ${name}.cc $<TARGET_OBJECTS:http-parser>)
target_include_directories(${name} PRIVATE
${OPENSSL_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
target_link_libraries(${name}
nghttp2
nghttp2_asio
${JEMALLOC_LIBRARIES}
${OPENSSL_LIBRARIES}
${Boost_LIBRARIES}
${APP_LIBRARIES}
)
endforeach()
endif()
endif()

View File

@@ -21,8 +21,6 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTRA_DIST = CMakeLists.txt
if ENABLE_EXAMPLES
AM_CFLAGS = $(WARNCFLAGS)
@@ -51,6 +49,14 @@ libevent_server_SOURCES = libevent-server.c
deflate_SOURCES = deflate.c
if ENABLE_TINY_NGHTTPD
noinst_PROGRAMS += tiny-nghttpd
tiny_nghttpd_SOURCES = tiny-nghttpd.c
endif # ENABLE_TINY_NGHTTPD
if ENABLE_ASIO_LIB
noinst_PROGRAMS += asio-sv asio-sv2 asio-cl asio-cl2

View File

@@ -66,13 +66,13 @@ enum { IO_NONE, WANT_READ, WANT_WRITE };
#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 \
}
#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 \
}
@@ -219,9 +219,9 @@ static int on_frame_send_callback(nghttp2_session *session,
const nghttp2_nv *nva = frame->headers.nva;
printf("[INFO] C ----------------------------> S (HEADERS)\n");
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(": ");
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
printf("\n");
}
}
@@ -249,9 +249,9 @@ static int on_frame_recv_callback(nghttp2_session *session,
if (req) {
printf("[INFO] C <---------------------------- S (HEADERS)\n");
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(": ");
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
printf("\n");
}
}
@@ -289,6 +289,8 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
return 0;
}
#define MAX_OUTLEN 4096
/*
* The implementation of nghttp2_on_data_chunk_recv_callback type. We
* use this function to print the received response body.
@@ -457,12 +459,11 @@ static void ctl_poll(struct pollfd *pollfd, struct Connection *connection) {
static void submit_request(struct Connection *connection, struct Request *req) {
int32_t stream_id;
/* Make sure that the last item is NULL */
const nghttp2_nv nva[] = {MAKE_NV(":method", "GET"),
MAKE_NV_CS(":path", req->path),
MAKE_NV(":scheme", "https"),
MAKE_NV_CS(":authority", req->hostport),
MAKE_NV("accept", "*/*"),
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
const nghttp2_nv nva[] = {
MAKE_NV(":method", "GET"), MAKE_NV_CS(":path", req->path),
MAKE_NV(":scheme", "https"), MAKE_NV_CS(":authority", req->hostport),
MAKE_NV("accept", "*/*"),
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
sizeof(nva) / sizeof(nva[0]), NULL, req);
@@ -563,11 +564,7 @@ static void fetch_uri(const struct URI *uri) {
diec("nghttp2_session_client_new", rv);
}
rv = nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
if (rv != 0) {
diec("nghttp2_submit_settings", rv);
}
nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
/* Submit the HTTP request to the outbound queue. */
submit_request(&connection, &req);
@@ -696,6 +693,9 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, 0);
#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_config(NULL);
#endif /* OPENSSL_IS_BORINGSSL */
SSL_load_error_strings();
SSL_library_init();

View File

@@ -33,7 +33,7 @@
#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 \
}
@@ -109,9 +109,9 @@ static void deflate(nghttp2_hd_deflater *deflater,
printf("Input (%zu byte(s)):\n\n", sum);
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(": ");
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
printf("\n");
}
@@ -186,9 +186,9 @@ int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
inlen -= proclen;
if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
fwrite(nv.name, 1, nv.namelen, stderr);
fwrite(nv.name, nv.namelen, 1, stderr);
fprintf(stderr, ": ");
fwrite(nv.value, 1, nv.valuelen, stderr);
fwrite(nv.value, nv.valuelen, 1, stderr);
fprintf(stderr, "\n");
}

View File

@@ -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,
const uint8_t *value, size_t valuelen) {
fwrite(name, 1, namelen, f);
fwrite(name, namelen, 1, f);
fprintf(f, ": ");
fwrite(value, 1, valuelen, f);
fwrite(value, valuelen, 1, f);
fprintf(f, "\n");
}
@@ -272,7 +272,7 @@ static int on_data_chunk_recv_callback(nghttp2_session *session _U_,
void *user_data) {
http2_session_data *session_data = (http2_session_data *)user_data;
if (session_data->stream_data->stream_id == stream_id) {
fwrite(data, 1, len, stdout);
fwrite(data, len, 1, stdout);
}
return 0;
}
@@ -322,11 +322,6 @@ static SSL_CTX *create_ssl_ctx(void) {
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
@@ -383,13 +378,13 @@ static void send_client_connection_header(http2_session_data *session_data) {
#define MAKE_NV(NAME, VALUE, VALUELEN) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
NGHTTP2_NV_FLAG_NONE \
}
#define MAKE_NV2(NAME, VALUE) \
{ \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
@@ -480,27 +475,7 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
if (events & BEV_EVENT_CONNECTED) {
int fd = bufferevent_getfd(bev);
int val = 1;
const unsigned char *alpn = NULL;
unsigned int alpnlen = 0;
SSL *ssl;
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));
initialize_nghttp2_session(session_data);
send_client_connection_header(session_data);
@@ -594,6 +569,9 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_config(NULL);
#endif /* OPENSSL_IS_BORINGSSL */
SSL_load_error_strings();
SSL_library_init();

View File

@@ -79,7 +79,7 @@
#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 \
}
@@ -116,22 +116,6 @@ static int next_proto_cb(SSL *s _U_, const unsigned char **data,
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. */
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
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;
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;
}
@@ -661,31 +640,11 @@ static void writecb(struct bufferevent *bev, void *ptr) {
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
http2_session_data *session_data = (http2_session_data *)ptr;
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);
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);
if (send_server_connection_header(session_data) != 0 ||
session_send(session_data) != 0) {
if (send_server_connection_header(session_data) != 0) {
delete_http2_session_data(session_data);
return;
}
@@ -781,6 +740,9 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_config(NULL);
#endif /* OPENSSL_IS_BORINGSSL */
SSL_load_error_strings();
SSL_library_init();

1344
examples/tiny-nghttpd.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -88,8 +88,7 @@ def build_header(headers):
c = k[-1]
if c not in ent:
ent[c] = []
if k not in ent[c]:
ent[c].append(k)
ent[c].append(k)
return res
@@ -107,7 +106,7 @@ def gen_enum():
def gen_index_header():
print '''\
static int32_t lookup_token(const uint8_t *name, size_t namelen) {
static inline int lookup_token(const uint8_t *name, size_t namelen) {
switch (namelen) {'''
b = build_header(HEADERS)
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)
for k in headers:
print '''\
if (memeq("{}", name, {})) {{
if (lstreq("{}", name, {})) {{
return {};
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
print '''\

View File

@@ -92,7 +92,6 @@ OPTIONS = [
"tls-ticket-key-cipher",
"host-rewrite",
"tls-session-cache-memcached",
"tls-session-cache-memcached-tls",
"tls-ticket-key-memcached",
"tls-ticket-key-memcached-interval",
"tls-ticket-key-memcached-max-retry",
@@ -115,44 +114,7 @@ OPTIONS = [
"max-header-fields",
"no-http2-cipher-black-list",
"backend-http1-tls",
"tls-session-cache-memcached-cert-file",
"tls-session-cache-memcached-private-key-file",
"tls-session-cache-memcached-address-family",
"tls-ticket-key-memcached-tls",
"tls-ticket-key-memcached-cert-file",
"tls-ticket-key-memcached-private-key-file",
"tls-ticket-key-memcached-address-family",
"backend-address-family",
"frontend-http2-max-concurrent-streams",
"backend-http2-max-concurrent-streams",
"backend-connections-per-frontend",
"backend-tls",
"backend-connections-per-host",
"error-page",
"no-kqueue",
"frontend-http2-settings-timeout",
"backend-http2-settings-timeout",
"api-max-request-body",
"backend-max-backoff",
"server-name",
"no-server-rewrite",
"frontend-http2-optimize-write-buffer-size",
"frontend-http2-optimize-window-size",
"frontend-http2-window-size",
"frontend-http2-connection-window-size",
"backend-http2-window-size",
"backend-http2-connection-window-size",
"frontend-http2-encoder-dynamic-table-size",
"frontend-http2-decoder-dynamic-table-size",
"backend-http2-encoder-dynamic-table-size",
"backend-http2-decoder-dynamic-table-size",
"ecdh-curves",
"tls-sct-dir",
"backend-connect-timeout",
"dns-cache-timeout",
"dns-lookup-timeout",
"dns-max-try",
"frontend-keep-alive-timeout",
"backend-tls-session-cache-per-worker"
]
LOGVARS = [
@@ -171,8 +133,6 @@ LOGVARS = [
"ssl_protocol",
"ssl_session_id",
"ssl_session_reused",
"backend_host",
"backend_port",
]
if __name__ == '__main__':

View File

@@ -160,15 +160,13 @@ DESCRIPTION
print(line.strip())
def format_text(text):
# escape *, but don't escape * if it is used as bullet list.
m = re.match(r'^\s*\*\s+', text)
if m:
text = text[:len(m.group(0))] + re.sub(r'\*', r'\*', text[len(m.group(0)):])
# escape *
if len(text) > len(arg_indent):
text = text[:len(arg_indent) + 1] + re.sub(r'\*', r'\*', text[len(arg_indent) + 1:])
else:
text = re.sub(r'\*', r'\*', text)
# markup option reference
text = re.sub(r'(^|\s)(-[a-zA-Z0-9]|--[a-zA-Z0-9-]+)',
r'\1:option:`\2`', text)
text = re.sub(r'(^|\s)(-[a-zA-Z0-9-]+)', r'\1:option:`\2`', text)
# sphinx does not like markup like ':option:`-f`='. We need
# backslash between ` and =.
text = re.sub(r'(:option:`.*?`)(\S)', r'\1\\\2', text)

View File

@@ -1,3 +1,2 @@
# generated files
config.go
setenv

View File

@@ -1,48 +0,0 @@
set(GO_FILES
nghttpx_http1_test.go
nghttpx_http2_test.go
nghttpx_spdy_test.go
server_tester.go
)
# XXX unused
set(EXTRA_DIST
${GO_FILES}
server.key
server.crt
alt-server.key
alt-server.crt
setenv
req-set-header.rb
resp-set-header.rb
req-return.rb
resp-return.rb
)
add_custom_target(itprep
COMMAND go get -d -v golang.org/x/net/http2
COMMAND go get -d -v github.com/tatsuhiro-t/go-nghttp2
COMMAND go get -d -v github.com/tatsuhiro-t/spdy
COMMAND go get -d -v golang.org/x/net/websocket
)
# 'go test' requires both config.go and the test files in the same directory.
# For out-of-tree builds, config.go is normally not placed next to the source
# files, so copy the tests to the build directory as a workaround.
set(GO_BUILD_FILES)
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
foreach(gofile IN LISTS GO_FILES)
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${gofile}")
add_custom_command(OUTPUT "${outfile}"
COMMAND ${CMAKE_COMMAND} -E copy
"${CMAKE_CURRENT_SOURCE_DIR}/${gofile}" "${outfile}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${gofile}"
)
list(APPEND GO_BUILD_FILES "${outfile}")
endforeach()
endif()
add_custom_target(it
COMMAND sh setenv go test -v
DEPENDS ${GO_BUILD_FILES}
)

View File

@@ -21,15 +21,11 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
GO_FILES = \
EXTRA_DIST = \
nghttpx_http1_test.go \
nghttpx_http2_test.go \
nghttpx_spdy_test.go \
server_tester.go
EXTRA_DIST = \
CMakeLists.txt \
$(GO_FILES) \
server_tester.go \
server.key \
server.crt \
alt-server.key \
@@ -40,12 +36,11 @@ EXTRA_DIST = \
req-return.rb \
resp-return.rb
itprep:
itprep-local:
go get -d -v golang.org/x/net/http2
go get -d -v github.com/tatsuhiro-t/go-nghttp2
go get -d -v github.com/tatsuhiro-t/spdy
go get -d -v golang.org/x/net/websocket
it:
for i in $(GO_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
it-local:
sh setenv go test -v

View File

@@ -2,5 +2,4 @@ package nghttp2
const (
buildDir = "@top_builddir@"
sourceDir = "@top_srcdir@"
)

View File

@@ -3,7 +3,6 @@ package nghttp2
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/websocket"
@@ -104,26 +103,26 @@ Content-Length: 0
}
}
// // TestH1H1ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/1 backend failed.
// func TestH1H1ConnectFailure(t *testing.T) {
// st := newServerTester(nil, t, noopHandler)
// defer st.Close()
// TestH1H1ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/1 backend failed.
func TestH1H1ConnectFailure(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
defer st.Close()
// // shutdown backend server to simulate backend connect failure
// st.ts.Close()
// shutdown backend server to simulate backend connect failure
st.ts.Close()
// res, err := st.http1(requestParam{
// name: "TestH1H1ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http1() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
res, err := st.http1(requestParam{
name: "TestH1H1ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestH1H1GracefulShutdown tests graceful shutdown.
func TestH1H1GracefulShutdown(t *testing.T) {
@@ -160,9 +159,8 @@ func TestH1H1GracefulShutdown(t *testing.T) {
}
want := io.EOF
b := make([]byte, 256)
if _, err := st.conn.Read(b); err == nil || err != want {
t.Errorf("st.conn.Read(): %v; want %v, %v", err, want)
if _, err := st.conn.Read(nil); err == nil || err != want {
t.Errorf("st.conn.Read(): %v; want %v", err, want)
}
}
@@ -533,26 +531,26 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
}
}
// // TestH1H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestH1H2ConnectFailure(t *testing.T) {
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
// defer st.Close()
// TestH1H2ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/2 backend failed.
func TestH1H2ConnectFailure(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
defer st.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
// simulate backend connect attempt failure
st.ts.Close()
// res, err := st.http1(requestParam{
// name: "TestH1H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http1() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
res, err := st.http1(requestParam{
name: "TestH1H2ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestH1H2NoHost tests that server rejects request without Host
// header field for HTTP/2 backend.
@@ -795,221 +793,3 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestH1H2TE tests that "te: trailers" header is forwarded to HTTP/2
// backend server by stripping other encodings.
func TestH1H2TE(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
if got, want := r.Header.Get("te"), "trailers"; got != want {
t.Errorf("te: %v; want %v", got, want)
}
})
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1H2TE",
header: []hpack.HeaderField{
pair("te", "foo,trailers,bar"),
},
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestH1APIBackendconfig exercise backendconfig API endpoint routine
// for successful case.
func TestH1APIBackendconfig(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1APIBackendconfig",
path: "/api/v1beta1/backendconfig",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH1APIBackendconfigQuery exercise backendconfig API endpoint
// routine with query.
func TestH1APIBackendconfigQuery(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1APIBackendconfigQuery",
path: "/api/v1beta1/backendconfig?foo=bar",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH1APIBackendconfigBadMethod exercise backendconfig API endpoint
// routine with bad method.
func TestH1APIBackendconfigBadMethod(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1APIBackendconfigBadMethod",
path: "/api/v1beta1/backendconfig",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 405; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 405; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH1APINotFound exercise backendconfig API endpoint routine when
// API endpoint is not found.
func TestH1APINotFound(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1APINotFound",
path: "/api/notfound",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 404; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH1Healthmon tests health monitor endpoint.
func TestH1Healthmon(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3011)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1Healthmon",
path: "/alpha/bravo",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}
// TestH1ResponseBeforeRequestEnd tests the situation where response
// ends before request body finishes.
func TestH1ResponseBeforeRequestEnd(t *testing.T) {
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("request should not be forwarded")
})
defer st.Close()
if _, err := io.WriteString(st.conn, fmt.Sprintf(`POST / HTTP/1.1
Host: %v
Test-Case: TestH1ResponseBeforeRequestEnd
Content-Length: 1000000
`, st.authority)); err != nil {
t.Fatalf("Error io.WriteString() = %v", err)
}
resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
if err != nil {
t.Fatalf("Error http.ReadResponse() = %v", err)
}
if got, want := resp.StatusCode, 404; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}

View File

@@ -2,7 +2,6 @@ package nghttp2
import (
"crypto/tls"
"encoding/json"
"fmt"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
@@ -569,26 +568,26 @@ func TestH2H1InvalidRequestCL(t *testing.T) {
}
}
// // TestH2H1ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/1 backend failed.
// func TestH2H1ConnectFailure(t *testing.T) {
// st := newServerTester(nil, t, noopHandler)
// defer st.Close()
// TestH2H1ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/1 backend failed.
func TestH2H1ConnectFailure(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
defer st.Close()
// // shutdown backend server to simulate backend connect failure
// st.ts.Close()
// shutdown backend server to simulate backend connect failure
st.ts.Close()
// res, err := st.http2(requestParam{
// name: "TestH2H1ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http2() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
res, err := st.http2(requestParam{
name: "TestH2H1ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestH2H1InvalidMethod tests that server rejects invalid method with
// 501.
@@ -1369,42 +1368,6 @@ func TestH2H1ProxyProtocolV1InvalidID(t *testing.T) {
}
}
// TestH2H1ExternalDNS tests that DNS resolution using external DNS
// with HTTP/1 backend works.
func TestH2H1ExternalDNS(t *testing.T) {
st := newServerTester([]string{"--external-dns"}, t, noopHandler)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1ExternalDNS",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1DNS tests that DNS resolution without external DNS with
// HTTP/1 backend works.
func TestH2H1DNS(t *testing.T) {
st := newServerTester([]string{"--dns"}, t, noopHandler)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1DNS",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H1GracefulShutdown tests graceful shutdown.
func TestH2H1GracefulShutdown(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
@@ -1523,26 +1486,26 @@ func TestH2H2InvalidResponseCL(t *testing.T) {
}
}
// // TestH2H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestH2H2ConnectFailure(t *testing.T) {
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
// defer st.Close()
// TestH2H2ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/2 backend failed.
func TestH2H2ConnectFailure(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
defer st.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
// simulate backend connect attempt failure
st.ts.Close()
// res, err := st.http2(requestParam{
// name: "TestH2H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http2() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
res, err := st.http2(requestParam{
name: "TestH2H2ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestH2H2HostRewrite tests that server rewrites host header field
func TestH2H2HostRewrite(t *testing.T) {
@@ -1880,226 +1843,3 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestH2H2ExternalDNS tests that DNS resolution using external DNS
// with HTTP/2 backend works.
func TestH2H2ExternalDNS(t *testing.T) {
st := newServerTester([]string{"--http2-bridge", "--external-dns"}, t, noopHandler)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2ExternalDNS",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2H2DNS tests that DNS resolution without external DNS with
// HTTP/2 backend works.
func TestH2H2DNS(t *testing.T) {
st := newServerTester([]string{"--http2-bridge", "--dns"}, t, noopHandler)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H2DNS",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
// TestH2APIBackendconfig exercise backendconfig API endpoint routine
// for successful case.
func TestH2APIBackendconfig(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APIBackendconfig",
path: "/api/v1beta1/backendconfig",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2APIBackendconfigQuery exercise backendconfig API endpoint
// routine with query.
func TestH2APIBackendconfigQuery(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APIBackendconfigQuery",
path: "/api/v1beta1/backendconfig?foo=bar",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2APIBackendconfigBadMethod exercise backendconfig API endpoint
// routine with bad method.
func TestH2APIBackendconfigBadMethod(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APIBackendconfigBadMethod",
path: "/api/v1beta1/backendconfig",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 405; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 405; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2APINotFound exercise backendconfig API endpoint routine when
// API endpoint is not found.
func TestH2APINotFound(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APINotFound",
path: "/api/notfound",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 404; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2Healthmon tests health monitor endpoint.
func TestH2Healthmon(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3011)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2Healthmon",
path: "/alpha/bravo",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}
// TestH2ResponseBeforeRequestEnd tests the situation where response
// ends before request body finishes.
func TestH2ResponseBeforeRequestEnd(t *testing.T) {
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("request should not be forwarded")
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2ResponseBeforeRequestEnd",
noEndStream: true,
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}

View File

@@ -1,7 +1,6 @@
package nghttp2
import (
"encoding/json"
"github.com/tatsuhiro-t/spdy"
"golang.org/x/net/http2/hpack"
"net/http"
@@ -385,26 +384,26 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
}
}
// // TestS3H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestS3H2ConnectFailure(t *testing.T) {
// st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
// defer st.Close()
// TestS3H2ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/2 backend failed.
func TestS3H2ConnectFailure(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
defer st.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
// simulate backend connect attempt failure
st.ts.Close()
// res, err := st.spdy(requestParam{
// name: "TestS3H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.spdy() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
res, err := st.spdy(requestParam{
name: "TestS3H2ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
// custom response.
@@ -475,190 +474,3 @@ func TestS3H2RespPhaseReturn(t *testing.T) {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestS3APIBackendconfig exercise backendconfig API endpoint routine
// for successful case.
func TestS3APIBackendconfig(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APIBackendconfig",
path: "/api/v1beta1/backendconfig",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3APIBackendconfigQuery exercise backendconfig API endpoint
// routine with query.
func TestS3APIBackendconfigQuery(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APIBackendconfigQuery",
path: "/api/v1beta1/backendconfig?foo=bar",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3APIBackendconfigBadMethod exercise backendconfig API endpoint
// routine with bad method.
func TestS3APIBackendconfigBadMethod(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APIBackendconfigBadMethod",
path: "/api/v1beta1/backendconfig",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 405; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 405; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3APINotFound exercise backendconfig API endpoint routine when
// API endpoint is not found.
func TestS3APINotFound(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3APINotFound",
path: "/api/notfound",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 404; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestS3Healthmon tests health monitor endpoint.
func TestS3Healthmon(t *testing.T) {
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3011;healthmon"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3011)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3Healthmon",
path: "/alpha/bravo",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}
// TestS3ResponseBeforeRequestEnd tests the situation where response
// ends before request body finishes.
func TestS3ResponseBeforeRequestEnd(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("request should not be forwarded")
})
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3ResponseBeforeRequestEnd",
noEndStream: true,
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}

View File

@@ -6,10 +6,10 @@ import (
"crypto/tls"
"errors"
"fmt"
"github.com/tatsuhiro-t/go-nghttp2"
"github.com/tatsuhiro-t/spdy"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
"github.com/tatsuhiro-t/go-nghttp2"
"github.com/tatsuhiro-t/spdy"
"golang.org/x/net/websocket"
"io"
"io/ioutil"
@@ -29,8 +29,7 @@ import (
const (
serverBin = buildDir + "/src/nghttpx"
serverPort = 3009
testDir = sourceDir + "/integration-tests"
logDir = buildDir + "/integration-tests"
testDir = buildDir + "/integration-tests"
)
func pair(name, value string) hpack.HeaderField {
@@ -66,54 +65,34 @@ type serverTester struct {
// newServerTester creates test context for plain TCP frontend
// connection.
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
}
func newServerTesterConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
return newServerTesterInternal(args, t, handler, false, port, nil)
return newServerTesterInternal(args, t, handler, false, nil)
}
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.
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
return newServerTesterInternal(args, t, handler, true, serverPort, nil)
}
func newServerTesterTLSConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
return newServerTesterInternal(args, t, handler, true, port, nil)
return newServerTesterInternal(args, t, handler, true, nil)
}
// newServerTester creates test context for TLS frontend connection
// with given clientConfig
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
// true, set up TLS frontend connection. connectPort is the server
// side port where client connection is made.
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, connectPort int, clientConfig *tls.Config) *serverTester {
// true, set up TLS frontend connection.
func newServerTesterInternal(args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
ts := httptest.NewUnstartedServer(handler)
args := []string{}
backendTLS := false
dns := false
externalDNS := false
for _, k := range src_args {
for _, k := range args {
switch k {
case "--http2-bridge":
backendTLS = true
case "--dns":
dns = true
case "--external-dns":
dns = true
externalDNS = true
default:
args = append(args, k)
}
}
if backendTLS {
@@ -122,7 +101,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
// NextProtos separately for ts.TLS. NextProtos set
// in nghttp2.ConfigureServer is effectively ignored.
ts.TLS = new(tls.Config)
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2-14")
ts.StartTLS()
args = append(args, "-k")
} else {
@@ -132,6 +111,8 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
if frontendTLS {
scheme = "https"
args = append(args, testDir+"/server.key", testDir+"/server.crt")
} else {
args = append(args, "--frontend-no-tls")
}
backendURL, err := url.Parse(ts.URL)
@@ -141,34 +122,11 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
// URL.Host looks like "127.0.0.1:8080", but we want
// "127.0.0.1,8080"
b := "-b"
if !externalDNS {
b += fmt.Sprintf("%v;", strings.Replace(backendURL.Host, ":", ",", -1))
} else {
sep := strings.LastIndex(backendURL.Host, ":")
if sep == -1 {
t.Fatalf("backendURL.Host %v does not contain separator ':'", backendURL.Host)
}
// We use awesome service xip.io.
b += fmt.Sprintf("%v.xip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
}
b := "-b" + strings.Replace(backendURL.Host, ":", ",", -1)
args = append(args, fmt.Sprintf("-f127.0.0.1,%v", serverPort), b,
"--errorlog-file="+testDir+"/log.txt", "-LINFO")
if backendTLS {
b += ";proto=h2;tls"
}
if dns {
b += ";dns"
}
noTLS := "no-tls"
if frontendTLS {
noTLS = ""
}
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)
st := &serverTester{
cmd: exec.Command(serverBin, args...),
@@ -190,8 +148,6 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
retry := 0
for {
time.Sleep(50 * time.Millisecond)
var conn net.Conn
var err error
if frontendTLS {
@@ -202,7 +158,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
tlsConfig = clientConfig
}
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)
} else {
conn, err = net.Dial("tcp", authority)
@@ -213,6 +169,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
st.Close()
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
}
time.Sleep(150 * time.Millisecond)
continue
}
if frontendTLS {
@@ -318,7 +275,6 @@ type requestParam struct {
body []byte // request body
trailer []hpack.HeaderField // trailer part
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
@@ -402,9 +358,8 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
if err != nil {
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
}
u.Path = ""
u.RawQuery = ""
reqURL = u.String() + rp.path
u.Path = rp.path
reqURL = u.String()
}
req, err := http.NewRequest(method, reqURL, body)
@@ -493,7 +448,7 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
}
var synStreamFlags spdy.ControlFlags
if len(rp.body) == 0 && !rp.noEndStream {
if len(rp.body) == 0 {
synStreamFlags = spdy.ControlFlagFin
}
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
@@ -507,13 +462,9 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
}
if len(rp.body) != 0 {
var dataFlags spdy.DataFlags
if !rp.noEndStream {
dataFlags = spdy.DataFlagFin
}
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
StreamId: id,
Flags: dataFlags,
Flags: spdy.DataFlagFin,
Data: rp.body,
}); err != nil {
return nil, err
@@ -626,7 +577,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
StreamID: id,
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0 && !rp.noEndStream,
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
EndHeaders: true,
BlockFragment: st.headerBlkBuf.Bytes(),
})
@@ -636,7 +587,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
if len(rp.body) != 0 {
// 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
}
}
@@ -783,8 +734,3 @@ func cloneHeader(h http.Header) http.Header {
}
func noopHandler(w http.ResponseWriter, r *http.Request) {}
type APIResponse struct {
Status string `json:"status,omitempty"`
Code int `json:"code,omitempty"`
}

View File

@@ -1,12 +1,6 @@
#!/bin/sh -e
libdir="@abs_top_builddir@/lib"
if [ -d "$libdir/.libs" ]; then
libdir="$libdir/.libs"
fi
export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
export CGO_LDFLAGS="-L$libdir"
export LD_LIBRARY_PATH="$libdir"
export GODEBUG=cgocheck=0
export CGO_LDFLAGS="-L@abs_top_builddir@/lib/.libs"
export LD_LIBRARY_PATH="@abs_top_builddir@/lib/.libs"
"$@"

View File

@@ -1,63 +0,0 @@
add_subdirectory(includes)
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
"${CMAKE_CURRENT_BINARY_DIR}/includes"
)
add_definitions(-DBUILDING_NGHTTP2)
set(NGHTTP2_SOURCES
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
nghttp2_frame.c
nghttp2_buf.c
nghttp2_stream.c nghttp2_outbound_item.c
nghttp2_session.c nghttp2_submit.c
nghttp2_helper.c
nghttp2_npn.c
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
nghttp2_version.c
nghttp2_priority_spec.c
nghttp2_option.c
nghttp2_callbacks.c
nghttp2_mem.c
nghttp2_http.c
nghttp2_rcbuf.c
nghttp2_debug.c
)
set(NGHTTP2_RES "")
if(WIN32)
configure_file(
version.rc.in
${CMAKE_CURRENT_BINARY_DIR}/version.rc
@ONLY)
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
endif()
# Public shared library
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
set_target_properties(nghttp2 PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden
)
if(HAVE_CUNIT)
# Static library (for unittests because of symbol visibility)
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
set_target_properties(nghttp2_static PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
ARCHIVE_OUTPUT_NAME nghttp2
)
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
endif()
install(TARGETS nghttp2
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

View File

@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = includes
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
EXTRA_DIST = Makefile.msvc
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
@@ -47,9 +47,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_option.c \
nghttp2_callbacks.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
nghttp2_debug.c
nghttp2_http.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
@@ -63,9 +61,7 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_option.h \
nghttp2_callbacks.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
nghttp2_debug.h
nghttp2_http.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \

View File

@@ -12,16 +12,16 @@
#
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
USE_CYTHON := 0
#USE_CYTHON := 1
USE_CYTHON := 1
#USE_CYTHON := 0
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -e 's/-DEV//g' -e 's/], //g')
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -r -e 's/(-DEV)?], //g')
_VERSION := $(subst ., ,$(_VERSION))
VER_MAJOR := $(word 1,$(_VERSION))
VER_MINOR := $(word 2,$(_VERSION))
VER_MICRO := $(word 3,$(_VERSION))
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO)
VERSION_NUM := (($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO))
VERSION_NUM := ($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO)
GENERATED := 'Generated by $(realpath Makefile.MSVC)'
@@ -90,8 +90,7 @@ NGHTTP2_SRC := nghttp2_pq.c \
nghttp2_option.c \
nghttp2_callbacks.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c
nghttp2_http.c
NGHTTP2_OBJ_R := $(addprefix $(OBJ_DIR)/r_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
@@ -102,7 +101,7 @@ NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
clean_nghttp2_pyd_0 clean_nghttp2_pyd_1
all: intro includes/nghttp2/nghttp2ver.h $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
all: intro $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
@echo 'Welcome to NgHTTP2 (release + debug).'
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
@@ -194,17 +193,17 @@ $(OBJ_DIR)/d_%.obj: %.c $(THIS_MAKEFILE)
@echo
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
$(RC) -D_RELEASE -Fo $@ $<
$(RC) -nologo -D_RELEASE -Fo $@ $<
@echo
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
$(RC) -D_DEBUG -Fo $@ $<
$(RC) -nologo -D_DEBUG -Fo $@ $<
@echo
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
sed < includes/nghttp2/nghttp2ver.h.in \
-e 's/@PACKAGE_VERSION@/$(VERSION)/g' \
-e 's/@PACKAGE_VERSION_NUM@/$(VERSION_NUM)/g' > $@
-e 's/@PACKAGE_VERSION_NUM@/($(VERSION_NUM))/g' > $@
touch --reference=includes/nghttp2/nghttp2ver.h.in $@

View File

@@ -1,4 +0,0 @@
install(FILES
nghttp2/nghttp2.h
"${CMAKE_CURRENT_BINARY_DIR}/nghttp2/nghttp2ver.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nghttp2")

View File

@@ -20,7 +20,4 @@
# 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.
EXTRA_DIST = CMakeLists.txt
nobase_include_HEADERS = nghttp2/nghttp2.h nghttp2/nghttp2ver.h

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,6 @@
#include <stdio.h>
#include "nghttp2_helper.h"
#include "nghttp2_debug.h"
void nghttp2_buf_init(nghttp2_buf *buf) {
buf->begin = NULL;
@@ -224,54 +223,13 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
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) {
if (bufs == NULL) {
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) {
@@ -298,6 +256,12 @@ size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
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) {
int rv;
nghttp2_buf_chain *chain;
@@ -317,8 +281,9 @@ static int bufs_alloc_chain(nghttp2_bufs *bufs) {
return rv;
}
DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
bufs->chunk_length, bufs, bufs->chunk_used);
DEBUGF(fprintf(stderr,
"new buffer %zu bytes allocated for bufs %p, used %zu\n",
bufs->chunk_length, bufs, 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;
const uint8_t *p;
if (bufs_avail(bufs) < len) {
return NGHTTP2_ERR_BUFFER_ERROR;
}
p = data;
while (len) {

View File

@@ -73,7 +73,7 @@ typedef struct {
/*
* Initializes the |buf|. No memory is allocated in this function. Use
* nghttp2_buf_reserve() to allocate memory.
* nghttp2_buf_reserve() or nghttp2_buf_reserve2() to allocate memory.
*/
void nghttp2_buf_init(nghttp2_buf *buf);
@@ -138,9 +138,7 @@ typedef struct {
nghttp2_buf_chain *cur;
/* Memory allocator */
nghttp2_mem *mem;
/* The buffer capacity of each buf. This field may be 0 if
nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
functions. */
/* The buffer capacity of each buf */
size_t chunk_length;
/* The maximum number of nghttp2_buf_chain */
size_t max_chunk;
@@ -199,13 +197,10 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
/*
* Initializes |bufs| using supplied buffer |begin| of length |len|.
* 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
* 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:
*
@@ -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,
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
* free supplied buffer provided in nghttp2_bufs_wrap_init().
@@ -336,8 +312,8 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
} while (0)
/*
* Copies all data stored in |bufs| to the contiguous buffer. This
* function allocates the contiguous memory to store all data in
* Copies all data stored in |bufs| to the contagious buffer. This
* function allocates the contagious memory to store all data in
* |bufs| and assigns it to |*out|.
*
* The contents of |bufs| is left unchanged.
@@ -405,7 +381,7 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
/*
* Returns the total buffer length of |bufs|.
* Returns the buffer length of |bufs|.
*/
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);

View File

@@ -104,24 +104,6 @@ void nghttp2_session_callbacks_set_on_header_callback(
cbs->on_header_callback = on_header_callback;
}
void nghttp2_session_callbacks_set_on_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback2 on_header_callback2) {
cbs->on_header_callback2 = on_header_callback2;
}
void nghttp2_session_callbacks_set_on_invalid_header_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback on_invalid_header_callback) {
cbs->on_invalid_header_callback = on_invalid_header_callback;
}
void nghttp2_session_callbacks_set_on_invalid_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) {
cbs->on_invalid_header_callback2 = on_invalid_header_callback2;
}
void nghttp2_session_callbacks_set_select_padding_callback(
nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback select_padding_callback) {
@@ -145,26 +127,3 @@ void nghttp2_session_callbacks_set_send_data_callback(
nghttp2_send_data_callback send_data_callback) {
cbs->send_data_callback = send_data_callback;
}
void nghttp2_session_callbacks_set_pack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_pack_extension_callback pack_extension_callback) {
cbs->pack_extension_callback = pack_extension_callback;
}
void nghttp2_session_callbacks_set_unpack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_unpack_extension_callback unpack_extension_callback) {
cbs->unpack_extension_callback = unpack_extension_callback;
}
void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) {
cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback;
}
void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
cbs->error_callback = error_callback;
}

View File

@@ -91,14 +91,6 @@ struct nghttp2_session_callbacks {
* received.
*/
nghttp2_on_header_callback on_header_callback;
nghttp2_on_header_callback2 on_header_callback2;
/**
* Callback function invoked when a invalid header name/value pair
* is received which is silently ignored if these callbacks are not
* set.
*/
nghttp2_on_invalid_header_callback on_invalid_header_callback;
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
/**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given
@@ -115,10 +107,6 @@ struct nghttp2_session_callbacks {
*/
nghttp2_on_begin_frame_callback on_begin_frame_callback;
nghttp2_send_data_callback send_data_callback;
nghttp2_pack_extension_callback pack_extension_callback;
nghttp2_unpack_extension_callback unpack_extension_callback;
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback;
};
#endif /* NGHTTP2_CALLBACKS_H */

View File

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

View File

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

View File

@@ -32,7 +32,6 @@
#include "nghttp2_helper.h"
#include "nghttp2_net.h"
#include "nghttp2_priority_spec.h"
#include "nghttp2_debug.h"
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) {
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
@@ -185,39 +184,6 @@ void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
void nghttp2_frame_data_free(nghttp2_data *frame _U_) {}
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
uint8_t flags, int32_t stream_id,
void *payload) {
nghttp2_frame_hd_init(&frame->hd, 0, type, flags, stream_id);
frame->payload = payload;
}
void nghttp2_frame_extension_free(nghttp2_extension *frame _U_) {}
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
uint8_t *origin, size_t origin_len,
uint8_t *field_value, size_t field_value_len) {
nghttp2_ext_altsvc *altsvc;
nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
altsvc = frame->payload;
altsvc->origin = origin;
altsvc->origin_len = origin_len;
altsvc->field_value = field_value;
altsvc->field_value_len = field_value_len;
}
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_ext_altsvc *altsvc;
altsvc = frame->payload;
/* We use the same buffer for altsvc->origin and
altsvc->field_value. */
nghttp2_mem_free(mem, altsvc->origin);
}
size_t nghttp2_frame_priority_len(uint8_t flags) {
if (flags & NGHTTP2_FLAG_PRIORITY) {
return NGHTTP2_PRIORITY_SPECLEN;
@@ -253,7 +219,8 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
hd = *frame_hd;
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
CONTINUATION frame is involved. Remove END_HEADERS flag from the
@@ -278,7 +245,8 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
hd.length = nghttp2_buf_len(buf);
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;
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
@@ -289,7 +257,8 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
/* Set END_HEADERS flag for last CONTINUATION */
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;
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
@@ -461,11 +430,25 @@ size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
}
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
nghttp2_settings_entry *iv,
size_t niv) {
frame->iv = iv;
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem) {
size_t payloadlen = niv * sizeof(nghttp2_settings_entry);
if (niv == 0) {
frame->iv = NULL;
} else {
frame->iv = nghttp2_mem_malloc(mem, payloadlen);
if (frame->iv == NULL) {
return NGHTTP2_ERR_NOMEM;
}
memcpy(frame->iv, iv, payloadlen);
}
frame->niv = niv;
return 0;
}
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
@@ -676,79 +659,6 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
}
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
int rv;
nghttp2_buf *buf;
nghttp2_ext_altsvc *altsvc;
altsvc = frame->payload;
buf = &bufs->head->buf;
assert(nghttp2_buf_avail(buf) >=
2 + altsvc->origin_len + altsvc->field_value_len);
buf->pos -= NGHTTP2_FRAME_HDLEN;
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
nghttp2_put_uint16be(buf->last, (uint16_t)altsvc->origin_len);
buf->last += 2;
rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
assert(rv == 0);
rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
assert(rv == 0);
return 0;
}
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
size_t origin_len, uint8_t *payload,
size_t payloadlen) {
nghttp2_ext_altsvc *altsvc;
uint8_t *p;
altsvc = frame->payload;
p = payload;
altsvc->origin = p;
p += origin_len;
altsvc->origin_len = origin_len;
altsvc->field_value = p;
altsvc->field_value_len = (size_t)(payload + payloadlen - p);
}
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem) {
uint8_t *buf;
size_t origin_len;
if (payloadlen < 2) {
return NGHTTP2_FRAME_SIZE_ERROR;
}
origin_len = nghttp2_get_uint16(payload);
buf = nghttp2_mem_malloc(mem, payloadlen - 2);
if (!buf) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_cpymem(buf, payload + 2, payloadlen - 2);
nghttp2_frame_unpack_altsvc_payload(frame, origin_len, buf, payloadlen - 2);
return 0;
}
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem) {
nghttp2_settings_entry *iv_copy;
@@ -869,9 +779,7 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
p->name = nva[i].name;
p->namelen = nva[i].namelen;
} else {
if (nva[i].namelen) {
memcpy(data, nva[i].name, nva[i].namelen);
}
memcpy(data, nva[i].name, nva[i].namelen);
p->name = data;
p->namelen = nva[i].namelen;
data[p->namelen] = '\0';
@@ -883,9 +791,7 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
p->value = nva[i].value;
p->valuelen = nva[i].valuelen;
} else {
if (nva[i].valuelen) {
memcpy(data, nva[i].value, nva[i].valuelen);
}
memcpy(data, nva[i].value, nva[i].valuelen);
p->value = data;
p->valuelen = nva[i].valuelen;
data[p->valuelen] = '\0';
@@ -932,7 +838,7 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
size_t trail_padlen;
size_t 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);
@@ -962,7 +868,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
nghttp2_buf *buf;
if (padlen == 0) {
DEBUGF("send: padlen = 0, nothing to do\n");
DEBUGF(fprintf(stderr, "send: padlen = 0, nothing to do\n"));
return 0;
}
@@ -996,7 +902,8 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
hd->length += padlen;
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;
}

View File

@@ -52,12 +52,14 @@
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
/* Number of inbound buffer */
#define NGHTTP2_FRAMEBUF_MAX_NUM 5
/* The default length of DATA frame payload. */
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
/* Maximum headers block size to send, calculated using
nghttp2_hd_deflate_bound(). This is the default value, and can be
overridden by nghttp2_option_set_max_send_header_block_size(). */
/* Maximum headers payload length, calculated in compressed form.
This applies to transmission only. */
#define NGHTTP2_MAX_HEADERSLEN 65536
/* The number of bytes for each SETTINGS entry */
@@ -70,7 +72,7 @@
#define NGHTTP2_MAX_PADLEN 256
/* Union of extension frame payload */
typedef union { nghttp2_ext_altsvc altsvc; } nghttp2_ext_frame_payload;
typedef union { int dummy; } nghttp2_ext_frame_payload;
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
@@ -213,12 +215,18 @@ void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
const uint8_t *payload);
/*
* Initializes payload of frame->settings. The |frame| takes
* ownership of |iv|.
* Makes a copy of |iv| in frame->settings.iv. The |niv| is assigned
* to frame->settings.niv.
*
* This function returns 0 if it succeeds or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
nghttp2_settings_entry *iv,
size_t niv);
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem);
/*
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
@@ -359,45 +367,6 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
const uint8_t *payload,
size_t payloadlen);
/*
* Packs ALTSVC frame |frame| in wire frame format and store it in
* |bufs|.
*
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
* before calling this function.
*
* This function always succeeds and returns 0.
*/
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
/*
* Unpacks ALTSVC wire format into |frame|. The |payload| of
* |payloadlen| bytes contains frame payload. This function assumes
* that frame->payload points to the nghttp2_ext_altsvc object.
*
* This function always succeeds and returns 0.
*/
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
size_t origin_len, uint8_t *payload,
size_t payloadlen);
/*
* Unpacks ALTSVC wire format into |frame|. This function only exists
* for unit test. After allocating buffer for fields, this function
* internally calls nghttp2_frame_unpack_altsvc_payload().
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FRAME_SIZE_ERROR
* The payload is too small.
*/
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem);
/*
* Initializes HEADERS frame |frame| with given values. |frame| takes
* ownership of |nva|, so caller must not free it. If |stream_id| is
@@ -470,31 +439,6 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
uint8_t flags, int32_t stream_id,
void *payload);
void nghttp2_frame_extension_free(nghttp2_extension *frame);
/*
* Initializes ALTSVC frame |frame| with given values. This function
* assumes that frame->payload points to nghttp2_ext_altsvc object.
* Also |origin| and |field_value| are allocated in single buffer,
* starting |origin|. On success, this function takes ownership of
* |origin|, so caller must not free it.
*/
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
uint8_t *origin, size_t origin_len,
uint8_t *field_value, size_t field_value_len);
/*
* Frees up resources under |frame|. This function does not free
* nghttp2_ext_altsvc object pointed by frame->payload. This function
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
* other fields must be allocated in the same buffer with origin.
*/
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
/*
* Returns the number of padding bytes after payload. The total
* padding length is given in the |padlen|. The returned value does

File diff suppressed because it is too large Load Diff

View File

@@ -34,7 +34,6 @@
#include "nghttp2_hd_huffman.h"
#include "nghttp2_buf.h"
#include "nghttp2_mem.h"
#include "nghttp2_rcbuf.h"
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
@@ -110,32 +109,28 @@ typedef enum {
NGHTTP2_TOKEN_CONNECTION,
NGHTTP2_TOKEN_KEEP_ALIVE,
NGHTTP2_TOKEN_PROXY_CONNECTION,
NGHTTP2_TOKEN_UPGRADE,
NGHTTP2_TOKEN_UPGRADE
} nghttp2_token;
typedef enum {
NGHTTP2_HD_FLAG_NONE = 0,
/* Indicates name was dynamically allocated and must be freed */
NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
/* Indicates value was dynamically allocated and must be freed */
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
/* Indicates that the name was gifted to the entry and no copying
necessary. */
NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 2,
/* Indicates that the value was gifted to the entry and no copying
necessary. */
NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 3
} nghttp2_hd_flags;
struct nghttp2_hd_entry;
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
typedef struct {
/* The buffer containing header field name. NULL-termination is
guaranteed. */
nghttp2_rcbuf *name;
/* The buffer containing header field value. NULL-termination is
guaranteed. */
nghttp2_rcbuf *value;
/* nghttp2_token value for name. It could be -1 if we have no token
for that header field name. */
int32_t token;
/* Bitwise OR of one or more of nghttp2_nv_flag. */
uint8_t flags;
} nghttp2_hd_nv;
struct nghttp2_hd_entry {
/* The header field name/value pair */
nghttp2_hd_nv nv;
/* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
APIs to keep backward compatibility. */
nghttp2_nv cnv;
nghttp2_nv nv;
/* The next entry which shares same bucket in hash table. */
nghttp2_hd_entry *next;
/* The sequence number. We will increment it by one whenever we
@@ -143,17 +138,14 @@ struct nghttp2_hd_entry {
uint32_t seq;
/* The hash value for header name (nv.name). */
uint32_t hash;
/* nghttp2_token value for nv.name. It could be -1 if we have no
token for that header field name. */
int token;
/* Reference count */
uint8_t ref;
uint8_t flags;
};
/* The entry used for static header table. */
typedef struct {
nghttp2_rcbuf name;
nghttp2_rcbuf value;
nghttp2_nv cnv;
int32_t token;
uint32_t hash;
} nghttp2_hd_static_entry;
typedef struct {
nghttp2_hd_entry **buffer;
size_t mask;
@@ -227,18 +219,24 @@ struct nghttp2_hd_deflater {
struct nghttp2_hd_inflater {
nghttp2_hd_context ctx;
/* header buffer */
nghttp2_bufs nvbufs;
/* Stores current state of huffman decoding */
nghttp2_hd_huff_decode_context huff_decode_ctx;
/* header buffer */
nghttp2_buf namebuf, valuebuf;
nghttp2_rcbuf *namercbuf, *valuercbuf;
/* Pointer to the name/value pair which are used in the current
header emission. */
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
/* Pointer to the nghttp2_hd_entry which is used current header
emission. This is required because in some cases the
ent_keep->ref == 0 and we have to keep track of it. */
nghttp2_hd_entry *ent_keep;
/* Pointer to the name/value pair buffer which is used in the
current header emission. */
uint8_t *nv_keep;
/* The number of bytes to read */
size_t left;
/* The index in indexed repr or indexed name */
size_t index;
/* The length of new name encoded in literal. For huffman encoded
string, this is the length after it is decoded. */
size_t newnamelen;
/* The maximum header table size the inflater supports. This is the
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
size_t settings_hd_table_bufsize_max;
@@ -258,16 +256,24 @@ struct nghttp2_hd_inflater {
};
/*
* Initializes the |ent| members. The reference counts of nv->name
* and nv->value are increased by one for each.
* Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
* set in the |flags|, the content pointed by the |name| with length
* |namelen| is copied. Likewise, if NGHTTP2_HD_FLAG_VALUE_ALLOC bit
* set in the |flags|, the content pointed by the |value| with length
* |valuelen| is copied. The |token| is enum number looked up by
* |name|. It could be -1 if we don't have that enum value.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags, uint8_t *name,
size_t namelen, uint8_t *value, size_t valuelen,
int token, nghttp2_mem *mem);
/*
* This function decreases the reference counts of nv->name and
* nv->value.
*/
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent, nghttp2_mem *mem);
/*
* Initializes |deflater| for deflating name/values pairs.
@@ -288,7 +294,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
/*
* Initializes |deflater| for deflating name/values pairs.
*
* 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
* nghttp2_hd_change_table_size().
*
@@ -299,7 +305,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
* Out of memory.
*/
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);
/*
@@ -348,14 +354,16 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
/*
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
* instead of nghttp2_nv as output parameter |nv_out|. Other than
* that return values and semantics are the same as
* nghttp2_hd_inflate_hd().
* Similar to nghttp2_hd_inflate_hd(), but this takes additional
* output parameter |token|. On successful header emission, it
* contains nghttp2_token value for nv_out->name. It could be -1 if
* we don't have enum value for the name. Other than that return
* values and semantics are the same as nghttp2_hd_inflate_hd().
*/
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen, int in_final);
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
int *token, uint8_t *in, size_t inlen,
int in_final);
/* For unittesting purpose */
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
@@ -369,10 +377,11 @@ int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
/* For unittesting purpose */
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
nghttp2_hd_entry *nghttp2_hd_table_get(nghttp2_hd_context *context,
size_t index);
/* For unittesting purpose */
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,
uint8_t *last, size_t prefix);
@@ -405,13 +414,14 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
/*
* Decodes the given data |src| with length |srclen|. The |ctx| must
* Decodes the given data |src| with length |srclen|. The |ctx| must
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
* will be written to |buf|. This function assumes that |buf| has the
* enough room to store the decoded byte string.
* will be added to |dest|. This function may expand |dest| as
* needed. The caller is responsible to release the memory of |dest|
* by calling nghttp2_bufs_free().
*
* The caller must set the |fin| to nonzero if the given input is the
* final block.
* The caller must set the |final| to nonzero if the given input is
* the final block.
*
* This function returns the number of read bytes from the |in|.
*
@@ -420,11 +430,13 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_BUFFER_ERROR
* Maximum buffer capacity size exceeded.
* NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed.
*/
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int fin);
nghttp2_bufs *bufs, const uint8_t *src,
size_t srclen, int final);
#endif /* NGHTTP2_HD_H */

View File

@@ -64,44 +64,15 @@ static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr,
code <<= 8 - (nbits & 0x7);
}
/* we lose at most 3 bytes, but it is not critical in practice */
if (*avail_ptr < (nbits + 7) / 8) {
/* slow path */
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);
rv = nghttp2_bufs_advance(bufs);
if (rv != 0) {
return rv;
}
*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 */
@@ -195,30 +166,47 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->accept = 1;
}
/* Use macro to make the code simpler..., but error case is tricky.
We spent most of the CPU in decoding, so we are doing this
thing. */
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
do { \
if ((avail)) { \
nghttp2_bufs_fast_addb((bufs), (sym)); \
--(avail); \
} else { \
rv = nghttp2_bufs_addb((bufs), (sym)); \
if (rv != 0) { \
return rv; \
} \
(avail) = nghttp2_bufs_cur_avail((bufs)); \
} \
} while (0)
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
nghttp2_bufs *bufs, const uint8_t *src,
size_t srclen, int final) {
size_t i;
int rv;
size_t avail;
avail = nghttp2_bufs_cur_avail(bufs);
/* We use the decoding algorithm described in
http://graphics.ics.uci.edu/pub/Prefix.pdf */
for (i = 0; i < srclen; ++i) {
const nghttp2_huff_decode *t;
t = &huff_decode_table[ctx->state][src[i] >> 4];
t = &huff_decode_table[ctx->state][src[i]];
if (t->flags & NGHTTP2_HUFF_FAIL) {
return NGHTTP2_ERR_HEADER_COMP;
}
if (t->flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
}
t = &huff_decode_table[t->state][src[i] & 0xf];
if (t->flags & NGHTTP2_HUFF_FAIL) {
return NGHTTP2_ERR_HEADER_COMP;
}
if (t->flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
if (t->flags & NGHTTP2_HUFF_SYM1) {
/* this is macro, and may return from this function on error */
hd_huff_decode_sym_emit(bufs, t->sym[0], avail);
if (t->flags & NGHTTP2_HUFF_SYM2) {
hd_huff_decode_sym_emit(bufs, t->sym[1], avail);
}
}
ctx->state = t->state;

View File

@@ -35,10 +35,12 @@ typedef enum {
/* FSA accepts this state as the end of huffman encoding
sequence. */
NGHTTP2_HUFF_ACCEPTED = 1,
/* This state emits symbol */
NGHTTP2_HUFF_SYM = (1 << 1),
/* This state emits 1st symbol */
NGHTTP2_HUFF_SYM1 = (1 << 1),
/* This state emits 2nd symbol */
NGHTTP2_HUFF_SYM2 = (1 << 2),
/* If state machine reaches this state, decoding fails. */
NGHTTP2_HUFF_FAIL = (1 << 2)
NGHTTP2_HUFF_FAIL = (1 << 3)
} nghttp2_huff_decode_flag;
typedef struct {
@@ -49,11 +51,15 @@ typedef struct {
uint8_t state;
/* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
uint8_t flags;
/* symbol if NGHTTP2_HUFF_SYM flag set */
uint8_t sym;
/* symbols if NGHTTP2_HUFF_SYM1 and optionally NGHTTP2_HUFF_SYM2
flag set. If NGHTTP2_HUFF_SYM1 is set, sym[0] has the 1st
symbol. Additionally, NGHTTP2_HUFF_SYM2 is set, sym[1] has the
2nd symbol. Since maximum huffman code is 5 bits, we may get at
most 2 symbols in one transition. */
uint8_t sym[2];
} nghttp2_huff_decode;
typedef nghttp2_huff_decode huff_decode_table_type[16];
typedef nghttp2_huff_decode huff_decode_table_type[256];
typedef struct {
/* Current huffman decoding state. We stripped leaf nodes, so the
@@ -72,6 +78,6 @@ typedef struct {
} nghttp2_huff_sym;
extern const nghttp2_huff_sym huff_sym_table[];
extern const nghttp2_huff_decode huff_decode_table[][16];
extern const nghttp2_huff_decode huff_decode_table[][256];
#endif /* NGHTTP2_HD_HUFFMAN_H */

File diff suppressed because it is too large Load Diff

View File

@@ -189,8 +189,8 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
account it in *delta_ptr. */
*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). */
/* recv_reduction_delta must be paied from *delta_ptr, since it
was added in window size reduction (see below). */
*delta_ptr -= recv_reduction_delta;
return 0;
@@ -213,38 +213,6 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
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,
int32_t recv_window_size) {
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
@@ -320,8 +288,6 @@ const char *nghttp2_strerror(int error_code) {
return "Stream was refused";
case NGHTTP2_ERR_INTERNAL:
return "Internal error";
case NGHTTP2_ERR_CANCEL:
return "Cancel";
case NGHTTP2_ERR_NOMEM:
return "Out of memory";
case NGHTTP2_ERR_CALLBACK_FAILURE:
@@ -338,70 +304,58 @@ const char *nghttp2_strerror(int error_code) {
/* Generated by gennmchartbl.py */
static int VALID_HD_NAME_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
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 */
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */,
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */,
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */,
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 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) {
@@ -426,70 +380,58 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) {
/* Generated by genvchartbl.py */
static int VALID_HD_VALUE_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
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 */
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 1 /* HT */,
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 1 /* " */,
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */,
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
1 /* Z */, 1 /* [ */, 1 /* \ */, 1 /* ] */, 1 /* ^ */,
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */,
1 /* } */, 1 /* ~ */, 0 /* DEL */, 1 /* 0x80 */, 1 /* 0x81 */,
1 /* 0x82 */, 1 /* 0x83 */, 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */,
1 /* 0x87 */, 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, 1 /* 0x90 */,
1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, 1 /* 0x94 */, 1 /* 0x95 */,
1 /* 0x96 */, 1 /* 0x97 */, 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */,
1 /* 0x9b */, 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, 1 /* 0xa4 */,
1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, 1 /* 0xa8 */, 1 /* 0xa9 */,
1 /* 0xaa */, 1 /* 0xab */, 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */,
1 /* 0xaf */, 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, 1 /* 0xb8 */,
1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, 1 /* 0xbc */, 1 /* 0xbd */,
1 /* 0xbe */, 1 /* 0xbf */, 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */,
1 /* 0xc3 */, 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, 1 /* 0xcc */,
1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, 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) {
@@ -503,46 +445,7 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
}
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
if (len == 0) {
return dest;
}
memcpy(dest, src, len);
return dest + len;
}
const char *nghttp2_http2_strerror(uint32_t error_code) {
switch (error_code) {
case NGHTTP2_NO_ERROR:
return "NO_ERROR";
case NGHTTP2_PROTOCOL_ERROR:
return "PROTOCOL_ERROR";
case NGHTTP2_INTERNAL_ERROR:
return "INTERNAL_ERROR";
case NGHTTP2_FLOW_CONTROL_ERROR:
return "FLOW_CONTROL_ERROR";
case NGHTTP2_SETTINGS_TIMEOUT:
return "SETTINGS_TIMEOUT";
case NGHTTP2_STREAM_CLOSED:
return "STREAM_CLOSED";
case NGHTTP2_FRAME_SIZE_ERROR:
return "FRAME_SIZE_ERROR";
case NGHTTP2_REFUSED_STREAM:
return "REFUSED_STREAM";
case NGHTTP2_CANCEL:
return "CANCEL";
case NGHTTP2_COMPRESSION_ERROR:
return "COMPRESSION_ERROR";
case NGHTTP2_CONNECT_ERROR:
return "CONNECT_ERROR";
case NGHTTP2_ENHANCE_YOUR_CALM:
return "ENHANCE_YOUR_CALM";
case NGHTTP2_INADEQUATE_SECURITY:
return "INADEQUATE_SECURITY";
case NGHTTP2_HTTP_1_1_REQUIRED:
return "HTTP_1_1_REQUIRED";
default:
return "unknown";
}
}

View File

@@ -89,22 +89,6 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
int32_t *recv_reduction_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
* be sent.

View File

@@ -82,12 +82,12 @@ static int lws(const uint8_t *s, size_t n) {
return 1;
}
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_nv *nv,
int flag) {
if (stream->http_flags & flag) {
return 0;
}
if (lws(nv->value->base, nv->value->len)) {
if (lws(nv->value, nv->valuelen)) {
return 0;
}
stream->http_flags = (uint16_t)(stream->http_flags | flag);
@@ -112,16 +112,16 @@ static int check_path(nghttp2_stream *stream) {
(stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
}
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
int trailer) {
if (nv->name->base[0] == ':') {
static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
int token, int trailer) {
if (nv->name[0] == ':') {
if (trailer ||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
switch (nv->token) {
switch (token) {
case NGHTTP2_TOKEN__AUTHORITY:
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
return NGHTTP2_ERR_HTTP_HEADER;
@@ -131,16 +131,16 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
switch (nv->value->len) {
switch (nv->valuelen) {
case 4:
if (lstreq("HEAD", nv->value->base, nv->value->len)) {
if (lstreq("HEAD", nv->value, nv->valuelen)) {
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
}
break;
case 7:
switch (nv->value->base[6]) {
switch (nv->value[6]) {
case 'T':
if (lstreq("CONNECT", nv->value->base, nv->value->len)) {
if (lstreq("CONNECT", nv->value, nv->valuelen)) {
if (stream->stream_id % 2 == 0) {
/* we won't allow CONNECT for push */
return NGHTTP2_ERR_HTTP_HEADER;
@@ -153,7 +153,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
}
break;
case 'S':
if (lstreq("OPTIONS", nv->value->base, nv->value->len)) {
if (lstreq("OPTIONS", nv->value, nv->valuelen)) {
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
}
break;
@@ -168,9 +168,9 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (nv->value->base[0] == '/') {
if (nv->value[0] == '/') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
} else if (nv->value->len == 1 && nv->value->base[0] == '*') {
} else if (nv->valuelen == 1 && nv->value[0] == '*') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
}
break;
@@ -181,8 +181,8 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) ||
(nv->value->len == 5 && memieq("https", nv->value->base, 5))) {
if ((nv->valuelen == 4 && memieq("http", nv->value, 4)) ||
(nv->valuelen == 5 && memieq("https", nv->value, 5))) {
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
}
break;
@@ -195,7 +195,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
if (stream->content_length != -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->content_length = parse_uint(nv->value->base, nv->value->len);
stream->content_length = parse_uint(nv->value, nv->valuelen);
if (stream->content_length == -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -209,70 +209,51 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
case NGHTTP2_TOKEN_UPGRADE:
return NGHTTP2_ERR_HTTP_HEADER;
case NGHTTP2_TOKEN_TE:
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
default:
if (nv->name->base[0] == ':') {
if (nv->name[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
if (nv->name->base[0] != ':') {
if (nv->name[0] != ':') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
}
return 0;
}
static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
int trailer) {
if (nv->name->base[0] == ':') {
static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
int token, int trailer) {
if (nv->name[0] == ':') {
if (trailer ||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
switch (nv->token) {
switch (token) {
case NGHTTP2_TOKEN__STATUS: {
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (nv->value->len != 3) {
if (nv->valuelen != 3) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len);
stream->status_code = (int16_t)parse_uint(nv->value, nv->valuelen);
if (stream->status_code == -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
}
case NGHTTP2_TOKEN_CONTENT_LENGTH: {
if (stream->status_code == 204) {
/* content-length header field in 204 response is prohibited by
RFC 7230. But some widely used servers send content-length:
0. Until they get fixed, we ignore it. */
if (stream->content_length != -1) {
/* Found multiple content-length field */
return NGHTTP2_ERR_HTTP_HEADER;
}
if (!lstrieq("0", nv->value->base, nv->value->len)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->content_length = 0;
return NGHTTP2_ERR_REMOVE_HTTP_HEADER;
}
if (stream->status_code / 100 == 1 ||
(stream->status_code == 200 &&
(stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT))) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (stream->content_length != -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->content_length = parse_uint(nv->value->base, nv->value->len);
stream->content_length = parse_uint(nv->value, nv->valuelen);
if (stream->content_length == -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -286,17 +267,17 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
case NGHTTP2_TOKEN_UPGRADE:
return NGHTTP2_ERR_HTTP_HEADER;
case NGHTTP2_TOKEN_TE:
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
default:
if (nv->name->base[0] == ':') {
if (nv->name[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
if (nv->name->base[0] != ':') {
if (nv->name[0] != ':') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
}
@@ -305,70 +286,58 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
/* Generated by genauthroitychartbl.py */
static char VALID_AUTHORITY_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */,
0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
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 */
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
0 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 1 /* @ */,
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 0 /* ^ */,
1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 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) {
@@ -406,7 +375,7 @@ static int check_scheme(const uint8_t *value, size_t len) {
}
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
nghttp2_frame *frame, nghttp2_hd_nv *nv,
nghttp2_frame *frame, nghttp2_nv *nv, int token,
int trailer) {
int rv;
@@ -417,14 +386,14 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
this, we may disrupt many web sites and/or libraries. So we
become conservative here, and just ignore those illegal regular
headers. */
if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) {
if (!nghttp2_check_header_name(nv->name, nv->namelen)) {
size_t i;
if (nv->name->len > 0 && nv->name->base[0] == ':') {
if (nv->namelen > 0 && nv->name[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
/* header field name must be lower-cased without exception */
for (i = 0; i < nv->name->len; ++i) {
uint8_t c = nv->name->base[i];
for (i = 0; i < nv->namelen; ++i) {
uint8_t c = nv->name[i];
if ('A' <= c && c <= 'Z') {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -436,18 +405,17 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
return NGHTTP2_ERR_IGN_HTTP_HEADER;
}
if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
nv->token == NGHTTP2_TOKEN_HOST) {
rv = check_authority(nv->value->base, nv->value->len);
} else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
rv = check_scheme(nv->value->base, nv->value->len);
if (token == NGHTTP2_TOKEN__AUTHORITY || token == NGHTTP2_TOKEN_HOST) {
rv = check_authority(nv->value, nv->valuelen);
} else if (token == NGHTTP2_TOKEN__SCHEME) {
rv = check_scheme(nv->value, nv->valuelen);
} else {
rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
rv = nghttp2_check_header_value(nv->value, nv->valuelen);
}
if (rv == 0) {
assert(nv->name->len > 0);
if (nv->name->base[0] == ':') {
assert(nv->namelen > 0);
if (nv->name[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
/* When ignoring regular headers, we set this flag so that we
@@ -458,10 +426,10 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
}
if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
return http_request_on_header(stream, nv, trailer);
return http_request_on_header(stream, nv, token, trailer);
}
return http_response_on_header(stream, nv, trailer);
return http_response_on_header(stream, nv, token, trailer);
}
int nghttp2_http_on_request_headers(nghttp2_stream *stream,

View File

@@ -36,7 +36,8 @@
/*
* This function is called when HTTP header field |nv| in |frame| is
* received for |stream|. This function will validate |nv| against
* the current state of stream.
* the current state of stream. The |token| is nghttp2_token value
* for nv->name, or -1 if we don't have enum value for the name.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -48,7 +49,7 @@
* if it was not received because of compatibility reasons.
*/
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
nghttp2_frame *frame, nghttp2_hd_nv *nv,
nghttp2_frame *frame, nghttp2_nv *nv, int token,
int trailer);
/*

View File

@@ -29,10 +29,16 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
/* 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|. */
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
@@ -46,13 +52,7 @@ typedef enum {
* Invalid HTTP header field was received but it can be treated as
* if it was not received because of compatibility reasons.
*/
NGHTTP2_ERR_IGN_HTTP_HEADER = -105,
/*
* Invalid HTTP header field was received, and it is ignored.
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
* nghttp2_on_invalid_header_callback.
*/
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
NGHTTP2_ERR_IGN_HTTP_HEADER = -105
} nghttp2_internal_error;
#endif /* NGHTTP2_INT_H */

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