mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-08 02:58:53 +08:00
Compare commits
416 Commits
v1.12.0
...
boringssl-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1beff1e10 | ||
|
|
b1b8308555 | ||
|
|
9b574a5a76 | ||
|
|
0567f1f038 | ||
|
|
4be5de1163 | ||
|
|
9db1c9467c | ||
|
|
3444b42d44 | ||
|
|
6595ae26ea | ||
|
|
41d8a3ac09 | ||
|
|
175001a8d9 | ||
|
|
7cf9e00283 | ||
|
|
8a3eb3f066 | ||
|
|
7e1a0d204b | ||
|
|
cbca2e35b5 | ||
|
|
fc9bdf024f | ||
|
|
3f97e6cd3a | ||
|
|
4fa150c494 | ||
|
|
e8b2508036 | ||
|
|
ac399e41ac | ||
|
|
95dd908834 | ||
|
|
9c7e54d9b5 | ||
|
|
3c03024881 | ||
|
|
36dfc0a56a | ||
|
|
55bf6cdb15 | ||
|
|
0abc220013 | ||
|
|
c28900990a | ||
|
|
5108193d7b | ||
|
|
79a24f5dd9 | ||
|
|
83c759572c | ||
|
|
1a07fb000b | ||
|
|
4aab15999d | ||
|
|
441982674f | ||
|
|
8256c6e070 | ||
|
|
ae87a44b94 | ||
|
|
87d1692e27 | ||
|
|
1d2f008656 | ||
|
|
b064d8a9ff | ||
|
|
528af200b6 | ||
|
|
c6827a7dac | ||
|
|
55ecb082ee | ||
|
|
5f2cf461e6 | ||
|
|
b313386988 | ||
|
|
3933280d29 | ||
|
|
2b6073900f | ||
|
|
d1ba43a69f | ||
|
|
a0779edec4 | ||
|
|
d70fefe72f | ||
|
|
b52db072f1 | ||
|
|
ab0b98db61 | ||
|
|
4245d98653 | ||
|
|
93b4866f5b | ||
|
|
25df164219 | ||
|
|
ba03c082e9 | ||
|
|
bcfa333322 | ||
|
|
c4aeadd57d | ||
|
|
e6b4454e48 | ||
|
|
3226d21609 | ||
|
|
3d20c2dce6 | ||
|
|
cd83d70e7b | ||
|
|
a0ce5ea9ab | ||
|
|
3c600c103f | ||
|
|
841ac75c3e | ||
|
|
80a96817aa | ||
|
|
ecc05e0a1a | ||
|
|
359730af54 | ||
|
|
e9cb19c80e | ||
|
|
049e064e28 | ||
|
|
0463928a1e | ||
|
|
02d34c8c4c | ||
|
|
46acf32c41 | ||
|
|
cab0a76795 | ||
|
|
0c76cebbfc | ||
|
|
5029b85b25 | ||
|
|
0b71d9b828 | ||
|
|
464d7c4ec6 | ||
|
|
ed21b631ae | ||
|
|
950e2d9954 | ||
|
|
71c054a789 | ||
|
|
d2f456e5b1 | ||
|
|
30a44b26d3 | ||
|
|
7dff758f8b | ||
|
|
bd3ececdd8 | ||
|
|
77416b0ac2 | ||
|
|
fce9efd341 | ||
|
|
928fda1d70 | ||
|
|
2d9d654507 | ||
|
|
7398e57174 | ||
|
|
503ec82f4d | ||
|
|
22bd9fb530 | ||
|
|
e007b6b031 | ||
|
|
c487cd888f | ||
|
|
fd403a85c8 | ||
|
|
a06a8c36a4 | ||
|
|
0967ee9cb9 | ||
|
|
d66d34f9b9 | ||
|
|
264a98d106 | ||
|
|
7c11d2d9bb | ||
|
|
b58d7b406f | ||
|
|
5ed9e4c83b | ||
|
|
e7da2a669e | ||
|
|
d66377d4b6 | ||
|
|
77a324fa46 | ||
|
|
38b5cad4e3 | ||
|
|
29014643a9 | ||
|
|
0872f6babe | ||
|
|
b6a9cf9ffa | ||
|
|
5645cad577 | ||
|
|
85ba33c08f | ||
|
|
ff64f64e1d | ||
|
|
bdd3425028 | ||
|
|
70e02cddd3 | ||
|
|
d1c0a17cc2 | ||
|
|
35c5cbbc21 | ||
|
|
2ff31bdd2b | ||
|
|
2fa3d34af1 | ||
|
|
fa3452ec68 | ||
|
|
7451f2f212 | ||
|
|
e9ab75a386 | ||
|
|
d83949bc88 | ||
|
|
50f42a80c9 | ||
|
|
00bd76fc3d | ||
|
|
93ea6b581e | ||
|
|
8e52a5c7f3 | ||
|
|
0aa35e574a | ||
|
|
5a81f2441f | ||
|
|
2b75aff32e | ||
|
|
f4474d57ec | ||
|
|
d0310c8aee | ||
|
|
8471c9e92e | ||
|
|
f5a4c9d971 | ||
|
|
a0dd8918eb | ||
|
|
baa9b1cac0 | ||
|
|
38443d2195 | ||
|
|
208d71561a | ||
|
|
25fbc7b435 | ||
|
|
6bd95d885d | ||
|
|
c171097dea | ||
|
|
6bcdb178a5 | ||
|
|
5e10cc4cad | ||
|
|
95e6c875f0 | ||
|
|
6eb2829ee8 | ||
|
|
6ad9ddcdea | ||
|
|
e082b7be72 | ||
|
|
da01d8dedb | ||
|
|
ca6f6511f2 | ||
|
|
ee8440408c | ||
|
|
9cd695a1db | ||
|
|
4b45906f46 | ||
|
|
d448eb54f9 | ||
|
|
65739fe754 | ||
|
|
0344c962f8 | ||
|
|
46d1e6bb55 | ||
|
|
04606b9339 | ||
|
|
7bb083e69e | ||
|
|
3a831fa95c | ||
|
|
5b9cacc2d7 | ||
|
|
10a84f3e3d | ||
|
|
c42715ed6a | ||
|
|
177d51ddab | ||
|
|
6c882e1ece | ||
|
|
f09c5c4bf9 | ||
|
|
08a9a2eca9 | ||
|
|
19f1785cde | ||
|
|
109de15c1f | ||
|
|
8b64e7b4e1 | ||
|
|
a5d66e71d0 | ||
|
|
3de2654223 | ||
|
|
d49bd50908 | ||
|
|
4130c68db1 | ||
|
|
ad3dac81a2 | ||
|
|
0cf6848646 | ||
|
|
e9d562f987 | ||
|
|
bc0f501dd3 | ||
|
|
a591001e7b | ||
|
|
eaa9229d72 | ||
|
|
1d5cde1c6b | ||
|
|
de03c41111 | ||
|
|
19340da8d4 | ||
|
|
5e99531b4d | ||
|
|
bef3d47c16 | ||
|
|
b8f7b474b4 | ||
|
|
1fb291d0e1 | ||
|
|
bc3dc6b765 | ||
|
|
ee7c36c022 | ||
|
|
857791dbb9 | ||
|
|
3c3267ea7d | ||
|
|
d654664fb2 | ||
|
|
1a37044d3c | ||
|
|
00a8c378d4 | ||
|
|
7549341081 | ||
|
|
5db8473f12 | ||
|
|
00b89f10bd | ||
|
|
281df33f40 | ||
|
|
e6ae681f07 | ||
|
|
7e681dc98f | ||
|
|
412c8f9e67 | ||
|
|
2795da840c | ||
|
|
175c7886ea | ||
|
|
4a4b2cf538 | ||
|
|
2c2188c09d | ||
|
|
1f07c24a2e | ||
|
|
e038625881 | ||
|
|
cdb1d6b462 | ||
|
|
1b4ccd0d51 | ||
|
|
8babaac8c3 | ||
|
|
d1624d6929 | ||
|
|
e4472b5aec | ||
|
|
9439ba75d3 | ||
|
|
9254c563ca | ||
|
|
35594e09df | ||
|
|
96ff3be5e6 | ||
|
|
3d5d76ba74 | ||
|
|
8c1e155f44 | ||
|
|
dba0d2791c | ||
|
|
f310e82fc8 | ||
|
|
1240e55bb6 | ||
|
|
75039c573c | ||
|
|
4b5179a544 | ||
|
|
8efccddcf4 | ||
|
|
97843e3874 | ||
|
|
5dd2704051 | ||
|
|
de7b7fd440 | ||
|
|
1037d3ad26 | ||
|
|
c4368a9416 | ||
|
|
fdc1eb526b | ||
|
|
99a91e3172 | ||
|
|
272cfa320e | ||
|
|
f5285d1f5a | ||
|
|
ede6104900 | ||
|
|
5aec60fbeb | ||
|
|
e1a865c406 | ||
|
|
5e03b6a0db | ||
|
|
b85924bf70 | ||
|
|
19707aac55 | ||
|
|
9ad873fc06 | ||
|
|
8a9810ed32 | ||
|
|
68a6d8c50b | ||
|
|
600605400c | ||
|
|
97aa4dabc8 | ||
|
|
a6f487240d | ||
|
|
da135416bb | ||
|
|
13eb881e5e | ||
|
|
82c84d163b | ||
|
|
a526183928 | ||
|
|
60222ae7c3 | ||
|
|
2052a1a4bd | ||
|
|
183be9cac9 | ||
|
|
69b53b9aaa | ||
|
|
02b9fcd332 | ||
|
|
231d739b10 | ||
|
|
e1dfff8929 | ||
|
|
db1716ae93 | ||
|
|
4cdc74c957 | ||
|
|
2c17ec3df8 | ||
|
|
e464b10fc3 | ||
|
|
03ba399176 | ||
|
|
751d66a397 | ||
|
|
3ec71bf5a2 | ||
|
|
f19b0724a3 | ||
|
|
a7e0a69f97 | ||
|
|
e532e20491 | ||
|
|
3e1cfa8e99 | ||
|
|
a100df9cae | ||
|
|
56284b1e15 | ||
|
|
f267e400fa | ||
|
|
8bac5899cc | ||
|
|
f4016644a9 | ||
|
|
d9bc6d04f7 | ||
|
|
743fc4a3c3 | ||
|
|
392256e542 | ||
|
|
905e16cb99 | ||
|
|
9d4e8eeb12 | ||
|
|
8099dd9558 | ||
|
|
a3a6b91c5f | ||
|
|
d9bb3448bf | ||
|
|
d508a0c72c | ||
|
|
bc31146c1f | ||
|
|
1ad7d5e366 | ||
|
|
456038e3de | ||
|
|
9aa26970be | ||
|
|
20c39fa843 | ||
|
|
f5a2f1da25 | ||
|
|
27b250ac8e | ||
|
|
b14375ec63 | ||
|
|
6858cda366 | ||
|
|
8a703d21ae | ||
|
|
1dabe43ff4 | ||
|
|
900aef10da | ||
|
|
ded576f423 | ||
|
|
136aae725f | ||
|
|
a60c3f8939 | ||
|
|
99dc31ff1a | ||
|
|
7673848325 | ||
|
|
0f8a5ffc23 | ||
|
|
fddb019baf | ||
|
|
72bf7d4af0 | ||
|
|
581e0938a9 | ||
|
|
1064e017c6 | ||
|
|
79b07f0ce2 | ||
|
|
cd471a989a | ||
|
|
0ea44072a3 | ||
|
|
6ba1abac6c | ||
|
|
0110d2f9f8 | ||
|
|
baa0f60dc8 | ||
|
|
69aa70086a | ||
|
|
13d3f785bd | ||
|
|
39c068974d | ||
|
|
0d4d1a63d4 | ||
|
|
833cd962a1 | ||
|
|
8103f43b65 | ||
|
|
1c8a672a8d | ||
|
|
4749e66c67 | ||
|
|
25ea41972a | ||
|
|
7d66188910 | ||
|
|
979c99eaea | ||
|
|
cf7f87c2ad | ||
|
|
bd0c1edaa6 | ||
|
|
c7ef021b4b | ||
|
|
00c80a15c0 | ||
|
|
8f47b68a95 | ||
|
|
d9139fc286 | ||
|
|
e693f75670 | ||
|
|
759f6c0b39 | ||
|
|
3e0d73c01d | ||
|
|
5cf21ec187 | ||
|
|
62e1d1c952 | ||
|
|
6ae58cc22e | ||
|
|
874ef1ac54 | ||
|
|
5f65460944 | ||
|
|
41b2745dad | ||
|
|
30f9f9ef87 | ||
|
|
4807e71b7d | ||
|
|
09c647fd1b | ||
|
|
d0fea96e69 | ||
|
|
b8883101d3 | ||
|
|
508c88f659 | ||
|
|
40d217beb1 | ||
|
|
e36caef006 | ||
|
|
9b864380a5 | ||
|
|
0e1d0400d8 | ||
|
|
afdd51ff15 | ||
|
|
488c3588d9 | ||
|
|
4f02b191d1 | ||
|
|
8acef2711b | ||
|
|
c6111b3792 | ||
|
|
c4d36aeff7 | ||
|
|
f50596e355 | ||
|
|
abf81b5bb7 | ||
|
|
8579b8a968 | ||
|
|
8df2c357d9 | ||
|
|
4c381611a1 | ||
|
|
7dfd6ab1ad | ||
|
|
0c7d48dede | ||
|
|
4639a66e53 | ||
|
|
65cc2f0515 | ||
|
|
4eb7f98449 | ||
|
|
2d8059a9a5 | ||
|
|
a3d22b6db9 | ||
|
|
3f31424ee2 | ||
|
|
e0119452a3 | ||
|
|
60cae325bc | ||
|
|
16c46114dc | ||
|
|
862175b21c | ||
|
|
e7e3d77c53 | ||
|
|
af9aeee752 | ||
|
|
ad3d43b8be | ||
|
|
210a5c4f01 | ||
|
|
d8822f2a8e | ||
|
|
b7a72b1e5a | ||
|
|
2f106dc96b | ||
|
|
f619286ca3 | ||
|
|
271f7fbbb6 | ||
|
|
318235db33 | ||
|
|
8ab079ccc2 | ||
|
|
a4d2104c3c | ||
|
|
44672e437a | ||
|
|
fb3d6f68a8 | ||
|
|
d7c9015d8b | ||
|
|
54f640f3e1 | ||
|
|
e2906025c8 | ||
|
|
9a8e9815c9 | ||
|
|
8c3e864989 | ||
|
|
22570b7260 | ||
|
|
fb49182c29 | ||
|
|
b9b648e0ed | ||
|
|
494775a25d | ||
|
|
1214f9e23b | ||
|
|
a54cda22ab | ||
|
|
f4a4abd180 | ||
|
|
c9559b5c0d | ||
|
|
af5b354685 | ||
|
|
3c1c2c4aad | ||
|
|
767ed255ca | ||
|
|
aa0023b3c1 | ||
|
|
3bdc143474 | ||
|
|
8b50cc0ece | ||
|
|
a24c94e92a | ||
|
|
a00442bee6 | ||
|
|
f857b63986 | ||
|
|
cbd72da9a1 | ||
|
|
7506a93179 | ||
|
|
53e1623ab3 | ||
|
|
0cb0bdabec | ||
|
|
ed8d5f04bb | ||
|
|
33153010c5 | ||
|
|
2c500b62fd | ||
|
|
30f26a2b9d | ||
|
|
ca39c71ac3 | ||
|
|
2bbe4422d2 | ||
|
|
5d3535126e | ||
|
|
d2addbc1ed | ||
|
|
110ca3131a | ||
|
|
fd7d3c57d7 | ||
|
|
179561e4be | ||
|
|
903e0077aa | ||
|
|
3fadad1bf3 |
@@ -1,57 +1,94 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
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
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: true
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: 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
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Cpp11BracedListStyle: true
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
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
|
||||
...
|
||||
|
||||
|
||||
11
.travis.yml
11
.travis.yml
@@ -28,6 +28,7 @@ addons:
|
||||
- libevent-dev
|
||||
- libjansson-dev
|
||||
- libjemalloc-dev
|
||||
- libc-ares-dev
|
||||
- cmake
|
||||
- cmake-data
|
||||
before_install:
|
||||
@@ -43,6 +44,7 @@ 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
|
||||
@@ -50,15 +52,14 @@ before_script:
|
||||
# Now build nghttp2
|
||||
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
|
||||
- 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"; fi
|
||||
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay" CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address; fi
|
||||
- if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DSPDYLAY_INCLUDE_DIR="$SPDYLAY_HOME/lib/includes" -DSPDYLAY_LIBRARY="$SPDYLAY_HOME/lib/.libs/libspdylay.so"; fi
|
||||
script:
|
||||
- make
|
||||
- make check
|
||||
- cd integration-tests
|
||||
- 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
|
||||
|
||||
4
AUTHORS
4
AUTHORS
@@ -32,6 +32,7 @@ Etienne Cimon
|
||||
Fabian Möller
|
||||
Fabian Wiesel
|
||||
Gabi Davar
|
||||
Google Inc.
|
||||
Jacob Champion
|
||||
Jan-E
|
||||
Janusz Dziemidowicz
|
||||
@@ -47,6 +48,7 @@ Kit Chan
|
||||
Kyle Schomp
|
||||
Lucas Pardue
|
||||
MATSUMOTO Ryosuke
|
||||
Matt Rudary
|
||||
Mike Conlen
|
||||
Mike Frysinger
|
||||
Nicholas Hurley
|
||||
@@ -71,11 +73,13 @@ Tomasz Buchert
|
||||
Vernon Tang
|
||||
Viacheslav Biriukov
|
||||
Viktor Szépe
|
||||
Wenfeng Liu
|
||||
Xiaoguang Sun
|
||||
Zhuoyun Wei
|
||||
acesso
|
||||
ayanamist
|
||||
bxshi
|
||||
dalf
|
||||
es
|
||||
fangdingjun
|
||||
kumagi
|
||||
|
||||
@@ -24,15 +24,15 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||
project(nghttp2 VERSION 1.12.0)
|
||||
project(nghttp2 VERSION 1.18.90)
|
||||
|
||||
# See versioning rule:
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
set(LT_CURRENT 22)
|
||||
set(LT_REVISION 0)
|
||||
set(LT_AGE 8)
|
||||
set(LT_CURRENT 26)
|
||||
set(LT_REVISION 3)
|
||||
set(LT_AGE 12)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
include(Version)
|
||||
|
||||
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
|
||||
@@ -59,6 +59,7 @@ 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)
|
||||
@@ -207,6 +208,14 @@ 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)
|
||||
@@ -304,7 +313,6 @@ include(CheckFunctionExists)
|
||||
check_function_exists(_Exit HAVE__EXIT)
|
||||
check_function_exists(accept4 HAVE_ACCEPT4)
|
||||
|
||||
# timerfd_create was added in linux kernel 2.6.25
|
||||
include(CheckSymbolExists)
|
||||
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
||||
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
|
||||
@@ -316,13 +324,6 @@ if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_function_exists(timerfd_create HAVE_TIMERFD_CREATE)
|
||||
# Checks for epoll availability, primarily for examples/tiny-nghttpd
|
||||
check_symbol_exists(epoll_create sys/epoll.h HAVE_EPOLL)
|
||||
if(HAVE_EPOLL AND HAVE_TIMERFD_CREATE)
|
||||
set(ENABLE_TINY_NGHTTPD 1)
|
||||
endif()
|
||||
|
||||
set(WARNCFLAGS)
|
||||
set(WARNCXXFLAGS)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
@@ -408,10 +409,10 @@ 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_BINARY_DIR}/dir" "${CMAKE_SOURCE_DIR}")
|
||||
file(RELATIVE_PATH top_builddir "${CMAKE_BINARY_DIR}/dir" "${CMAKE_BINARY_DIR}")
|
||||
set(abs_top_srcdir "${CMAKE_SOURCE_DIR}")
|
||||
set(abs_top_builddir "${CMAKE_BINARY_DIR}")
|
||||
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}")
|
||||
@@ -450,7 +451,7 @@ foreach(name
|
||||
endforeach()
|
||||
|
||||
include_directories(
|
||||
"${CMAKE_BINARY_DIR}" # for config.h
|
||||
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
||||
)
|
||||
# For use in src/CMakeLists.txt
|
||||
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
|
||||
@@ -499,6 +500,7 @@ message(STATUS "summary of build options:
|
||||
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}')
|
||||
|
||||
@@ -45,7 +45,8 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
|
||||
cmake/Version.cmake \
|
||||
cmake/FindCython.cmake \
|
||||
cmake/FindLibevent.cmake \
|
||||
cmake/FindJansson.cmake
|
||||
cmake/FindJansson.cmake \
|
||||
cmake/FindLibcares.cmake
|
||||
|
||||
.PHONY: clang-format
|
||||
|
||||
|
||||
52
README.rst
52
README.rst
@@ -58,6 +58,11 @@ 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:
|
||||
@@ -65,6 +70,7 @@ are required:
|
||||
* OpenSSL >= 1.0.1
|
||||
* libev >= 4.11
|
||||
* zlib >= 1.2.3
|
||||
* libc-ares >= 1.7.5
|
||||
|
||||
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
|
||||
LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more
|
||||
@@ -93,6 +99,11 @@ To mitigate heap fragmentation in long running server programs
|
||||
|
||||
* jemalloc
|
||||
|
||||
.. note::
|
||||
|
||||
Alpine Linux currently does not support malloc replacement
|
||||
due to musl limitations. See details in issue `#762 <https://github.com/nghttp2/nghttp2/issues/762>`_.
|
||||
|
||||
libnghttp2_asio C++ library requires the following packages:
|
||||
|
||||
* libboost-dev >= 1.54.0
|
||||
@@ -110,7 +121,7 @@ If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run
|
||||
|
||||
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 \
|
||||
libjemalloc-dev cython python3-dev python-setuptools
|
||||
libc-ares-dev 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
|
||||
@@ -144,6 +155,7 @@ used:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ git submodule update --init
|
||||
$ autoreconf -i
|
||||
$ automake
|
||||
$ autoconf
|
||||
@@ -154,8 +166,7 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
||||
|
||||
.. note::
|
||||
|
||||
To enable mruby support in nghttpx, run ``git submodule update
|
||||
--init`` before running configure script, and use ``--with-mruby``
|
||||
To enable mruby support in nghttpx, and use ``--with-mruby``
|
||||
configure option.
|
||||
|
||||
.. note::
|
||||
@@ -176,6 +187,23 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
||||
applications were not built, then using ``--enable-app`` may find
|
||||
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)
|
||||
--------------------------------------------
|
||||
|
||||
@@ -1353,7 +1381,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.4``).
|
||||
PYTHON=/usr/bin/python3.5``).
|
||||
|
||||
The following example code illustrates basic usage of the HPACK compressor
|
||||
and decompressor in Python:
|
||||
@@ -1483,6 +1511,17 @@ 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
|
||||
----------------
|
||||
|
||||
@@ -1495,3 +1534,8 @@ 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
|
||||
|
||||
@@ -39,9 +39,8 @@ PATH="$TOOLCHAIN"/bin:"$PATH"
|
||||
--without-libxml2 \
|
||||
--disable-python-bindings \
|
||||
--disable-examples \
|
||||
--enable-werror \
|
||||
CC="$TOOLCHAIN"/bin/clang \
|
||||
CXX="$TOOLCHAIN"/bin/clang++ \
|
||||
CC="$TOOLCHAIN"/bin/arm-linux-androideabi-gcc \
|
||||
CXX="$TOOLCHAIN"/bin/arm-linux-androideabi-g++ \
|
||||
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||
LDFLAGS="-fPIE -pie -L$PREFIX/lib"
|
||||
|
||||
53
appveyor.yml
Normal file
53
appveyor.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
# Notes:
|
||||
# - Minimal appveyor.yml file is an empty file. All sections are optional.
|
||||
# - Indent each level of configuration with 2 spaces. Do not use tabs!
|
||||
# - All section names are case-sensitive.
|
||||
# - Section names should be unique on each level.
|
||||
|
||||
#---------------------------------#
|
||||
# general configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# version format
|
||||
#version: 0.10.{build}
|
||||
|
||||
# branches to build
|
||||
branches:
|
||||
# blacklist
|
||||
except:
|
||||
- gh-pages
|
||||
|
||||
# Do not build on tags (GitHub only)
|
||||
skip_tags: true
|
||||
|
||||
#---------------------------------#
|
||||
# environment configuration #
|
||||
#---------------------------------#
|
||||
|
||||
os: Windows Server 2012
|
||||
|
||||
# scripts that run after cloning repository
|
||||
install:
|
||||
# install Win-Flex-Bison
|
||||
#- cmd: cinst winflexbison -y
|
||||
|
||||
#---------------------------------#
|
||||
# build configuration #
|
||||
#---------------------------------#
|
||||
|
||||
# scripts to run before build
|
||||
before_build:
|
||||
- cmd: cmake .
|
||||
|
||||
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
|
||||
# before_package:
|
||||
|
||||
# scripts to run after build
|
||||
# after_build:
|
||||
|
||||
# to run your custom scripts instead of automatic MSBuild
|
||||
build_script:
|
||||
- cmd: cmake --build .
|
||||
|
||||
# to disable automatic builds
|
||||
# build: off
|
||||
52
author.py
Executable file
52
author.py
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/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
|
||||
40
cmake/FindLibcares.cmake
Normal file
40
cmake/FindLibcares.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# - 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)
|
||||
113
configure.ac
113
configure.ac
@@ -25,7 +25,7 @@ dnl Do not change user variables!
|
||||
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([nghttp2], [1.12.0], [t-tujikawa@users.sourceforge.net])
|
||||
AC_INIT([nghttp2], [1.19.0-DEV], [t-tujikawa@users.sourceforge.net])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -44,9 +44,9 @@ 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, 22)
|
||||
AC_SUBST(LT_REVISION, 0)
|
||||
AC_SUBST(LT_AGE, 8)
|
||||
AC_SUBST(LT_CURRENT, 26)
|
||||
AC_SUBST(LT_REVISION, 3)
|
||||
AC_SUBST(LT_AGE, 12)
|
||||
|
||||
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"`
|
||||
@@ -234,6 +234,41 @@ 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()
|
||||
@@ -246,7 +281,7 @@ TESTLDADD=
|
||||
# Additional libraries required for programs under src directory.
|
||||
APPLDFLAGS=
|
||||
|
||||
case "$host" in
|
||||
case "$host_os" in
|
||||
*android*)
|
||||
android_build=yes
|
||||
# android does not need -pthread, but needs followng 3 libs for C++
|
||||
@@ -258,6 +293,12 @@ case "$host" 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])
|
||||
|
||||
@@ -329,6 +370,13 @@ 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],
|
||||
@@ -348,15 +396,12 @@ else
|
||||
fi
|
||||
|
||||
# libxml2 (for src/nghttp)
|
||||
have_libxml2=no
|
||||
if test "x${request_libxml2}" != "xno"; then
|
||||
m4_ifdef([AM_PATH_XML2],
|
||||
[AM_PATH_XML2(2.7.7, [have_libxml2=yes], [have_libxml2=no])],
|
||||
[AC_MSG_WARN([configure was created without libxml2 detection macro; libxml2 detection is disabled])])
|
||||
|
||||
if test "x${have_libxml2}" = "xyes"; then
|
||||
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
|
||||
fi
|
||||
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)
|
||||
fi
|
||||
|
||||
if test "x${request_libxml2}" = "xyes" &&
|
||||
@@ -438,13 +483,14 @@ if test "x${request_asio_lib}" = "xyes"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL
|
||||
# and libev
|
||||
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL,
|
||||
# libev, and libc-ares.
|
||||
enable_app=no
|
||||
if test "x${request_app}" != "xno" &&
|
||||
test "x${have_zlib}" = "xyes" &&
|
||||
test "x${have_openssl}" = "xyes" &&
|
||||
test "x${have_libev}" = "xyes"; then
|
||||
test "x${have_libev}" = "xyes" &&
|
||||
test "x${have_libcares}" = "xyes"; then
|
||||
enable_app=yes
|
||||
fi
|
||||
|
||||
@@ -599,6 +645,26 @@ 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.])
|
||||
@@ -660,13 +726,6 @@ 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
|
||||
|
||||
@@ -720,6 +779,7 @@ 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"])
|
||||
@@ -729,6 +789,7 @@ if test "x$werror" != "xno"; then
|
||||
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
|
||||
|
||||
@@ -825,6 +886,7 @@ AC_MSG_NOTICE([summary of build options:
|
||||
C preprocessor: ${CPP}
|
||||
CPPFLAGS: ${CPPFLAGS}
|
||||
WARNCFLAGS: ${WARNCFLAGS}
|
||||
WARNCXXFLAGS: ${WARNCXXFLAGS}
|
||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||
EXTRACFLAG: ${EXTRACFLAG}
|
||||
LIBS: ${LIBS}
|
||||
@@ -844,8 +906,9 @@ AC_MSG_NOTICE([summary of build options:
|
||||
Failmalloc: ${enable_failmalloc}
|
||||
Libs:
|
||||
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
|
||||
Libxml2: ${have_libxml2} (CFLAGS='${XML_CPPFLAGS}' LIBS='${XML_LIBS}')
|
||||
Libxml2: ${have_libxml2} (CFLAGS='${LIBXML2_CPPFLAGS}' LIBS='${LIBXML2_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}')
|
||||
|
||||
@@ -13,6 +13,7 @@ set(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
|
||||
@@ -23,6 +24,7 @@ set(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
|
||||
@@ -31,7 +33,9 @@ set(APIDOCS
|
||||
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
|
||||
@@ -54,13 +58,15 @@ set(APIDOCS
|
||||
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_extension_chunk_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
|
||||
@@ -68,6 +74,9 @@ set(APIDOCS
|
||||
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
|
||||
@@ -79,7 +88,11 @@ set(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
|
||||
@@ -88,20 +101,19 @@ set(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
|
||||
@@ -110,6 +122,7 @@ set(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
|
||||
|
||||
@@ -37,6 +37,7 @@ APIDOCS= \
|
||||
nghttp2_hd_deflate_get_num_table_entries.rst \
|
||||
nghttp2_hd_deflate_get_table_entry.rst \
|
||||
nghttp2_hd_deflate_hd.rst \
|
||||
nghttp2_hd_deflate_hd_vec.rst \
|
||||
nghttp2_hd_deflate_new.rst \
|
||||
nghttp2_hd_deflate_new2.rst \
|
||||
nghttp2_hd_inflate_change_table_size.rst \
|
||||
@@ -56,6 +57,7 @@ APIDOCS= \
|
||||
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 \
|
||||
@@ -87,6 +89,8 @@ APIDOCS= \
|
||||
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 \
|
||||
@@ -94,6 +98,9 @@ APIDOCS= \
|
||||
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 \
|
||||
@@ -105,7 +112,11 @@ 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 \
|
||||
@@ -114,15 +125,13 @@ 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 \
|
||||
@@ -137,6 +146,7 @@ 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 \
|
||||
@@ -256,7 +266,7 @@ apiref.rst: \
|
||||
$(APIDOCS): apiref.rst
|
||||
|
||||
clean-local:
|
||||
[ $(srcdir) = $(builddir) ] || for i in $(RST_FILES); do [ -e $(builddir)/$$i ] && rm $(builddir)/$$i; done
|
||||
[ $(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)/*
|
||||
|
||||
@@ -15,6 +15,7 @@ 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
|
||||
@@ -231,8 +232,8 @@ class RubyObject(ObjectDescription):
|
||||
|
||||
indextext = self.get_index_text(modname, name_cls)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
fullname, fullname))
|
||||
self.indexnode['entries'].append(
|
||||
_make_index('single', indextext, fullname, fullname))
|
||||
|
||||
def before_content(self):
|
||||
# needed for automatic qualification of members (reset in subclasses)
|
||||
@@ -415,11 +416,19 @@ class RubyModule(Directive):
|
||||
# modindex currently
|
||||
if not noindex:
|
||||
indextext = _('%s (module)') % modname
|
||||
inode = addnodes.index(entries=[('single', indextext,
|
||||
'module-' + modname, modname)])
|
||||
inode = addnodes.index(entries=[_make_index(
|
||||
'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):
|
||||
"""
|
||||
|
||||
@@ -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 --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" ) )
|
||||
COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --header-table-size --requests --base-uri --h1 --threads --npn-list --rate-period --data --version --connection-inactivity-timeout --timing-script-file --encoder-header-table-size --max-concurrent-streams --connection-active-timeout --input-file --help --window-bits --header ' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
@@ -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 --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 --encoder-header-table-size --padding --hexdump --max-concurrent-streams --continuation --connection-window-bits --peer-max-concurrent-streams --timeout --data --no-content-length --version --color --cert --upgrade --remote-name --trailer --weight --help --key --null-out --window-bits --expect-continue --stat --header ' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
@@ -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 --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 --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" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
@@ -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-request-buffer --max-request-header-fields --backend-http2-connection-window-bits --conf --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --no-server-push --stream-read-timeout --tls-ticket-key-memcached --forwarded-for --accesslog-syslog --frontend-http2-read-timeout --listener-disable-timeout --frontend-http2-connection-window-bits --ciphers --strip-incoming-x-forwarded-for --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --rlimit-nofile --tls-ticket-key-memcached-cert-file --ocsp-update-interval --forwarded-by --tls-session-cache-memcached-private-key-file --error-page --backend-write-timeout --tls-dyn-rec-warmup-threshold --tls-ticket-key-memcached-max-retry --http2-no-cookie-crumbling --worker-read-burst --dh-param-file --accesslog-format --errorlog-syslog --request-header-field-buffer --api-max-request-body --errorlog-file --frontend-http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend --insecure --backend-max-backoff --log-level --host-rewrite --tls-proto-list --tls-ticket-key-memcached-interval --frontend-http2-setting-timeout --worker-frontend-connections --syslog-facility --fastopen --no-location-rewrite --tls-session-cache-memcached --no-ocsp --backend-response-buffer --workers --add-forwarded --frontend-http2-window-bits --worker-write-rate --add-request-header --backend-http2-settings-timeout --subcert --no-kqueue --help --frontend-frame-debug --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --user --add-x-forwarded-for --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --backend-connections-per-host --backend-http2-window-bits --response-header-field-buffer --tls-ticket-key-memcached-address-family --padding --tls-session-cache-memcached-address-family --stream-write-timeout --cacert --tls-ticket-key-memcached-private-key-file --backend-address-family --version --add-response-header --backend-read-timeout --frontend --accesslog-file --http2-proxy --client-private-key-file --client-cert-file --accept-proxy-protocol --tls-dyn-rec-idle-timeout --verify-client --read-rate --backend-connections-per-frontend --strip-incoming-forwarded ' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W '--worker-read-rate --include --frontend-http2-dump-response-header --tls-ticket-key-file --verify-client-cacert --max-response-header-fields --backend-http2-window-size --frontend-keep-alive-timeout --backend-request-buffer --max-request-header-fields --fastopen --backend-connect-timeout --conf --dns-lookup-timeout --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --dns-max-try --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --client-no-http2-cipher-black-list --stream-read-timeout --client-ciphers --forwarded-for --accesslog-syslog --dns-cache-timeout --frontend-http2-read-timeout --listener-disable-timeout --ciphers --client-psk-secrets --strip-incoming-x-forwarded-for --no-server-rewrite --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --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 --psk-secrets --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 --tls-ticket-key-memcached --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" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
28
doc/h2load.1
28
doc/h2load.1
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "H2LOAD" "1" "June 26, 2016" "1.12.0" "nghttp2"
|
||||
.TH "H2LOAD" "1" "Jan 09, 2017" "1.19.0-DEV" "nghttp2"
|
||||
.SH NAME
|
||||
h2load \- HTTP/2 benchmarking tool
|
||||
.
|
||||
@@ -123,6 +123,8 @@ Add/Override a header to the requests.
|
||||
.B \-\-ciphers=<SUITE>
|
||||
Set allowed cipher list. The format of the string is
|
||||
described in OpenSSL ciphers(1).
|
||||
.sp
|
||||
Default: \fBECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256:ECDHE\-ECDSA\-AES128\-SHA:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-RSA\-AES128\-SHA:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES256\-SHA:ECDHE\-RSA\-AES256\-SHA:DHE\-RSA\-AES128\-SHA256:DHE\-RSA\-AES128\-SHA:DHE\-RSA\-AES256\-SHA256:DHE\-RSA\-AES256\-SHA:ECDHE\-ECDSA\-DES\-CBC3\-SHA:ECDHE\-RSA\-DES\-CBC3\-SHA:EDH\-RSA\-DES\-CBC3\-SHA:AES128\-GCM\-SHA256:AES256\-GCM\-SHA384:AES128\-SHA256:AES256\-SHA256:AES128\-SHA:AES256\-SHA:DES\-CBC3\-SHA:!DSS\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -151,7 +153,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 \fB\-t2\fP and \fB\-r4\fP, each thread gets 2
|
||||
example, with \fI\%\-t\fP2 and \fI\%\-r\fP4, 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,6 +244,23 @@ 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
|
||||
@@ -256,6 +275,9 @@ 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
|
||||
@@ -414,7 +436,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
|
||||
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fInghttpx(1)\fP
|
||||
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -96,6 +96,8 @@ OPTIONS
|
||||
Set allowed cipher list. The format of the string is
|
||||
described in OpenSSL ciphers(1).
|
||||
|
||||
Default: ``ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS``
|
||||
|
||||
.. option:: -p, --no-tls-proto=<PROTOID>
|
||||
|
||||
Specify ALPN identifier of the protocol to be used when
|
||||
@@ -120,7 +122,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:`-t2` and :option:`\-r4`, each thread gets 2
|
||||
example, with :option:`-t`\2 and :option:`-r`\4, 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,6 +204,21 @@ 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.
|
||||
@@ -216,6 +233,9 @@ 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
|
||||
|
||||
21
doc/nghttp.1
21
doc/nghttp.1
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTP" "1" "June 26, 2016" "1.12.0" "nghttp2"
|
||||
.TH "NGHTTP" "1" "Jan 09, 2017" "1.19.0-DEV" "nghttp2"
|
||||
.SH NAME
|
||||
nghttp \- HTTP/2 client
|
||||
.
|
||||
@@ -142,10 +142,13 @@ HTTP upgrade request is performed with OPTIONS method.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-p, \-\-weight=<WEIGHT>
|
||||
Sets priority group weight. The valid value range is
|
||||
Sets weight of given URI. This option can be used
|
||||
multiple times, and N\-th \fI\%\-p\fP option sets weight of N\-th
|
||||
URI in the command line. If the number of \fI\%\-p\fP option is
|
||||
less than the number of URI, the last \fI\%\-p\fP option value is
|
||||
repeated. If there is no \fI\%\-p\fP option, default weight, 16,
|
||||
is assumed. The valid value range is
|
||||
[1, 256], inclusive.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -167,6 +170,14 @@ 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.
|
||||
@@ -300,7 +311,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
|
||||
\fInghttpd(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
||||
\fBnghttpd(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -107,11 +107,14 @@ OPTIONS
|
||||
|
||||
.. option:: -p, --weight=<WEIGHT>
|
||||
|
||||
Sets priority group weight. The valid value range is
|
||||
Sets weight of given URI. This option can be used
|
||||
multiple times, and N-th :option:`-p` option sets weight of N-th
|
||||
URI in the command line. If the number of :option:`-p` option is
|
||||
less than the number of URI, the last :option:`-p` option value is
|
||||
repeated. If there is no :option:`-p` option, default weight, 16,
|
||||
is assumed. The valid value range is
|
||||
[1, 256], inclusive.
|
||||
|
||||
Default: ``16``
|
||||
|
||||
.. option:: -M, --peer-max-concurrent-streams=<N>
|
||||
|
||||
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||
@@ -128,6 +131,13 @@ 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.
|
||||
@@ -208,7 +218,9 @@ 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::
|
||||
tree:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
+-----+
|
||||
|id=0 |
|
||||
|
||||
@@ -12,7 +12,9 @@ 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::
|
||||
tree:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
+-----+
|
||||
|id=0 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPD" "1" "June 26, 2016" "1.12.0" "nghttp2"
|
||||
.TH "NGHTTPD" "1" "Jan 09, 2017" "1.19.0-DEV" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpd \- HTTP/2 server
|
||||
.
|
||||
@@ -99,6 +99,14 @@ 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
|
||||
@@ -209,7 +217,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
|
||||
\fInghttp(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
||||
\fBnghttp(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -70,6 +70,13 @@ 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.
|
||||
|
||||
357
doc/nghttpx.1
357
doc/nghttpx.1
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPX" "1" "June 26, 2016" "1.12.0" "nghttp2"
|
||||
.TH "NGHTTPX" "1" "Jan 09, 2017" "1.19.0-DEV" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpx \- HTTP/2 proxy
|
||||
.
|
||||
@@ -55,7 +55,7 @@ The options are categorized into several groups.
|
||||
.SS Connections
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;PARAM]...]
|
||||
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
|
||||
Set backend host and port. The multiple backend
|
||||
addresses are accepted by repeating this option. UNIX
|
||||
domain socket can be specified by prefixing path name
|
||||
@@ -120,13 +120,13 @@ together forming load balancing group.
|
||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||
The parameters are delimited by ";". The available
|
||||
parameters are: "proto=<PROTO>", "tls",
|
||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
|
||||
"affinity=<METHOD>". The parameter consists of keyword,
|
||||
and optionally followed by "=" and value. For example,
|
||||
the parameter "proto=h2" consists of the keyword "proto"
|
||||
and value "h2". The parameter "tls" consists of the
|
||||
keyword "tls" without value. Each parameter is
|
||||
described as follows.
|
||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>",
|
||||
"affinity=<METHOD>", and "dns". The parameter consists
|
||||
of keyword, and optionally followed by "=" and value.
|
||||
For example, the parameter "proto=h2" consists of the
|
||||
keyword "proto" and value "h2". The parameter "tls"
|
||||
consists of the keyword "tls" without value. Each
|
||||
parameter is described as follows.
|
||||
.sp
|
||||
The backend application protocol can be specified using
|
||||
optional "proto" parameter, and in the form of
|
||||
@@ -175,6 +175,14 @@ session affinity is desired. The session affinity may
|
||||
break if one of the backend gets unreachable, or backend
|
||||
settings are reloaded or replaced by API.
|
||||
.sp
|
||||
By default, name resolution of backend host name is done
|
||||
at start up, or reloading configuration. If "dns"
|
||||
parameter is given, name resolution takes place
|
||||
dynamically. This is useful if backend address changes
|
||||
frequently. If "dns" is given, name resolution of
|
||||
backend host name at start up, or reloading
|
||||
configuration is skipped.
|
||||
.sp
|
||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||
not contain these characters. Since ";" has special
|
||||
meaning in shell, the option value must be quoted.
|
||||
@@ -183,7 +191,7 @@ Default: \fB127.0.0.1,80\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[[;PARAM]...]
|
||||
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
|
||||
Set frontend host and port. If <HOST> is \(aq*\(aq, it
|
||||
assumes all addresses including both IPv4 and IPv6.
|
||||
UNIX domain socket can be specified by prefixing path
|
||||
@@ -210,6 +218,10 @@ specify "healthmon" parameter. This is disabled by
|
||||
default. Any requests which come through this address
|
||||
are replied with 200 HTTP status, without no body.
|
||||
.sp
|
||||
To accept PROXY protocol version 1 on frontend
|
||||
connection, specify "proxyproto" parameter. This is
|
||||
disabled by default.
|
||||
.sp
|
||||
Default: \fB*,3000\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -245,11 +257,6 @@ timeouts when connecting and making CONNECT request can
|
||||
be specified by \fI\%\-\-backend\-read\-timeout\fP and
|
||||
\fI\%\-\-backend\-write\-timeout\fP options.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-accept\-proxy\-protocol
|
||||
Accept PROXY protocol version 1 on frontend connection.
|
||||
.UNINDENT
|
||||
.SS Performance
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -426,6 +433,14 @@ Default: \fB30s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-keep\-alive\-timeout=<DURATION>
|
||||
Specify keep\-alive timeout for frontend HTTP/1
|
||||
connection.
|
||||
.sp
|
||||
Default: \fB1m\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-stream\-read\-timeout=<DURATION>
|
||||
Specify read timeout for HTTP/2 and SPDY streams. 0
|
||||
means no timeout.
|
||||
@@ -456,8 +471,17 @@ Default: \fB30s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-connect\-timeout=<DURATION>
|
||||
Specify timeout before establishing TCP connection to
|
||||
backend.
|
||||
.sp
|
||||
Default: \fB30s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-keep\-alive\-timeout=<DURATION>
|
||||
Specify keep\-alive timeout for backend connection.
|
||||
Specify keep\-alive timeout for backend HTTP/1
|
||||
connection.
|
||||
.sp
|
||||
Default: \fB2s\fP
|
||||
.UNINDENT
|
||||
@@ -504,8 +528,29 @@ Default: \fB2m\fP
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-ciphers=<SUITE>
|
||||
Set allowed cipher list. The format of the string is
|
||||
described in OpenSSL ciphers(1).
|
||||
Set allowed cipher list for frontend connection. The
|
||||
format of the string is described in OpenSSL ciphers(1).
|
||||
.sp
|
||||
Default: \fBECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256:ECDHE\-ECDSA\-AES128\-SHA:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-RSA\-AES128\-SHA:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES256\-SHA:ECDHE\-RSA\-AES256\-SHA:DHE\-RSA\-AES128\-SHA256:DHE\-RSA\-AES128\-SHA:DHE\-RSA\-AES256\-SHA256:DHE\-RSA\-AES256\-SHA:ECDHE\-ECDSA\-DES\-CBC3\-SHA:ECDHE\-RSA\-DES\-CBC3\-SHA:EDH\-RSA\-DES\-CBC3\-SHA:AES128\-GCM\-SHA256:AES256\-GCM\-SHA384:AES128\-SHA256:AES256\-SHA256:AES128\-SHA:AES256\-SHA:DES\-CBC3\-SHA:!DSS\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-client\-ciphers=<SUITE>
|
||||
Set allowed cipher list for backend connection. The
|
||||
format of the string is described in OpenSSL ciphers(1).
|
||||
.sp
|
||||
Default: \fBECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256:ECDHE\-ECDSA\-AES128\-SHA:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-RSA\-AES128\-SHA:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES256\-SHA:ECDHE\-RSA\-AES256\-SHA:DHE\-RSA\-AES128\-SHA256:DHE\-RSA\-AES128\-SHA:DHE\-RSA\-AES256\-SHA256:DHE\-RSA\-AES256\-SHA:ECDHE\-ECDSA\-DES\-CBC3\-SHA:ECDHE\-RSA\-DES\-CBC3\-SHA:EDH\-RSA\-DES\-CBC3\-SHA:AES128\-GCM\-SHA256:AES256\-GCM\-SHA384:AES128\-SHA256:AES256\-SHA256:AES128\-SHA:AES256\-SHA:DES\-CBC3\-SHA:!DSS\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-ecdh\-curves=<LIST>
|
||||
Set supported curve list for frontend connections.
|
||||
<LIST> is a colon separated list of curve NID or names
|
||||
in the preference order. The supported curves depend on
|
||||
the linked OpenSSL library. This function requires
|
||||
OpenSSL >= 1.0.2.
|
||||
.sp
|
||||
Default: \fBX25519:P\-256:P\-384:P\-521\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -531,12 +576,21 @@ password protected it\(aqll be requested interactively.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-subcert=<KEYPATH>:<CERTPATH>
|
||||
.B \-\-subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
|
||||
Specify additional certificate and private key file.
|
||||
nghttpx will choose certificates based on the hostname
|
||||
indicated by client using TLS SNI extension. This
|
||||
option can be used multiple times. To make OCSP
|
||||
stapling work, <CERTPATH> must be absolute path.
|
||||
.sp
|
||||
Additional parameter can be specified in <PARAM>. The
|
||||
available <PARAM> is "sct\-dir=<DIR>".
|
||||
.sp
|
||||
"sct\-dir=<DIR>" specifies the path to directory which
|
||||
contains *.sct files for TLS
|
||||
signed_certificate_timestamp extension (RFC 6962). This
|
||||
feature requires OpenSSL >= 1.0.2. See also
|
||||
\fI\%\-\-tls\-sct\-dir\fP option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -775,9 +829,63 @@ Default: \fB1s\fP
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-no\-http2\-cipher\-black\-list
|
||||
Allow black listed cipher suite on HTTP/2 connection.
|
||||
See \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for
|
||||
the complete HTTP/2 cipher suites black list.
|
||||
Allow black listed cipher suite on frontend HTTP/2
|
||||
connection. See
|
||||
\fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for the
|
||||
complete HTTP/2 cipher suites black list.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-client\-no\-http2\-cipher\-black\-list
|
||||
Allow black listed cipher suite on backend HTTP/2
|
||||
connection. See
|
||||
\fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for the
|
||||
complete HTTP/2 cipher suites black list.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-sct\-dir=<DIR>
|
||||
Specifies the directory where *.sct files exist. All
|
||||
*.sct files in <DIR> are read, and sent as
|
||||
extension_data of TLS signed_certificate_timestamp (RFC
|
||||
6962) to client. These *.sct files are for the
|
||||
certificate specified in positional command\-line
|
||||
argument <CERT>, or certificate option in configuration
|
||||
file. For additional certificates, use \fI\%\-\-subcert\fP
|
||||
option. This option requires OpenSSL >= 1.0.2.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-psk\-secrets=<PATH>
|
||||
Read list of PSK identity and secrets from <PATH>. This
|
||||
is used for frontend connection. The each line of input
|
||||
file is formatted as <identity>:<hex\-secret>, where
|
||||
<identity> is PSK identity, and <hex\-secret> is secret
|
||||
in hex. An empty line, and line which starts with \(aq#\(aq
|
||||
are skipped. The default enabled cipher list might not
|
||||
contain any PSK cipher suite. In that case, desired PSK
|
||||
cipher suites must be enabled using \fI\%\-\-ciphers\fP option.
|
||||
The desired PSK cipher suite may be black listed by
|
||||
HTTP/2. To use those cipher suites with HTTP/2,
|
||||
consider to use \fI\%\-\-no\-http2\-cipher\-black\-list\fP option.
|
||||
But be aware its implications.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-client\-psk\-secrets=<PATH>
|
||||
Read PSK identity and secrets from <PATH>. This is used
|
||||
for backend connection. The each line of input file is
|
||||
formatted as <identity>:<hex\-secret>, where <identity>
|
||||
is PSK identity, and <hex\-secret> is secret in hex. An
|
||||
empty line, and line which starts with \(aq#\(aq are skipped.
|
||||
The first identity and secret pair encountered is used.
|
||||
The default enabled cipher list might not contain any
|
||||
PSK cipher suite. In that case, desired PSK cipher
|
||||
suites must be enabled using \fI\%\-\-client\-ciphers\fP option.
|
||||
The desired PSK cipher suite may be black listed by
|
||||
HTTP/2. To use those cipher suites with HTTP/2,
|
||||
consider to use \fI\%\-\-client\-no\-http2\-cipher\-black\-list\fP
|
||||
option. But be aware its implications.
|
||||
.UNINDENT
|
||||
.SS HTTP/2 and SPDY
|
||||
.INDENT 0.0
|
||||
@@ -800,37 +908,36 @@ Default: \fB100\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-window\-bits=<N>
|
||||
Sets the per\-stream initial window size of HTTP/2 SPDY
|
||||
frontend connection. For HTTP/2, the size is 2**<N>\-1.
|
||||
For SPDY, the size is 2**<N>.
|
||||
.B \-\-frontend\-http2\-window\-size=<SIZE>
|
||||
Sets the per\-stream initial window size of HTTP/2 and
|
||||
SPDY frontend connection.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB65535\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-connection\-window\-bits=<N>
|
||||
.B \-\-frontend\-http2\-connection\-window\-size=<SIZE>
|
||||
Sets the per\-connection window size of HTTP/2 and SPDY
|
||||
frontend connection. For HTTP/2, the size is
|
||||
2**<N>\-1. For SPDY, the size is 2**<N>.
|
||||
frontend connection. For SPDY connection, the value
|
||||
less than 64KiB is rounded up to 64KiB.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB65535\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-window\-bits=<N>
|
||||
.B \-\-backend\-http2\-window\-size=<SIZE>
|
||||
Sets the initial window size of HTTP/2 backend
|
||||
connection to 2**<N>\-1.
|
||||
connection.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB65535\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-connection\-window\-bits=<N>
|
||||
.B \-\-backend\-http2\-connection\-window\-size=<SIZE>
|
||||
Sets the per\-connection window size of HTTP/2 backend
|
||||
connection to 2**<N>\-1.
|
||||
connection.
|
||||
.sp
|
||||
Default: \fB30\fP
|
||||
Default: \fB2147483647\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -856,6 +963,71 @@ backend session is relayed to frontend, and server push
|
||||
via Link header field is also supported. SPDY frontend
|
||||
does not support server push.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-optimize\-write\-buffer\-size
|
||||
(Experimental) Enable write buffer size optimization in
|
||||
frontend HTTP/2 TLS connection. This optimization aims
|
||||
to reduce write buffer size so that it only contains
|
||||
bytes which can send immediately. This makes server
|
||||
more responsive to prioritized HTTP/2 stream because the
|
||||
buffering of lower priority stream is reduced. This
|
||||
option is only effective on recent Linux platform.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-optimize\-window\-size
|
||||
(Experimental) Automatically tune connection level
|
||||
window size of frontend HTTP/2 TLS connection. If this
|
||||
feature is enabled, connection window size starts with
|
||||
the default window size, 65535 bytes. nghttpx
|
||||
automatically adjusts connection window size based on
|
||||
TCP receiving window size. The maximum window size is
|
||||
capped by the value specified by
|
||||
\fI\%\-\-frontend\-http2\-connection\-window\-size\fP\&. Since the
|
||||
stream is subject to stream level window size, it should
|
||||
be adjusted using \fI\%\-\-frontend\-http2\-window\-size\fP option as
|
||||
well. This option is only effective on recent Linux
|
||||
platform.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the frontend HTTP/2 connection. The decoder (client)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which client specified.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the frontend HTTP/2 connection.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the backend HTTP/2 connection. The decoder (backend)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which backend specified.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the backend HTTP/2 connection.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.SS Mode
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -938,6 +1110,12 @@ $ssl_session_id: session ID for SSL/TLS connection.
|
||||
.IP \(bu 2
|
||||
$ssl_session_reused: "r" if SSL/TLS session was
|
||||
reused. Otherwise, "."
|
||||
.IP \(bu 2
|
||||
$backend_host: backend host used to fulfill the
|
||||
request. "\-" if backend host is not available.
|
||||
.IP \(bu 2
|
||||
$backend_port: backend port used to fulfill the
|
||||
request. "\-" if backend host is not available.
|
||||
.UNINDENT
|
||||
.sp
|
||||
The variable can be enclosed by "{" and "}" for
|
||||
@@ -1123,6 +1301,20 @@ originally generates HTTP error status code <CODE>.
|
||||
HTTP status code. If error status code comes from
|
||||
backend server, the custom error pages are not used.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-server\-name=<NAME>
|
||||
Change server response header field value to <NAME>.
|
||||
.sp
|
||||
Default: \fBnghttpx nghttp2/1.19.0\-DEV\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-no\-server\-rewrite
|
||||
Don\(aqt rewrite server header field in default mode. When
|
||||
\fI\%\-\-http2\-proxy\fP is used, these headers will not be altered
|
||||
regardless of this option.
|
||||
.UNINDENT
|
||||
.SS API
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1131,6 +1323,33 @@ Set the maximum size of request body for API request.
|
||||
.sp
|
||||
Default: \fB16K\fP
|
||||
.UNINDENT
|
||||
.SS DNS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-dns\-cache\-timeout=<DURATION>
|
||||
Set duration that cached DNS results remain valid. Note
|
||||
that nghttpx caches the unsuccessful results as well.
|
||||
.sp
|
||||
Default: \fB10s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-dns\-lookup\-timeout=<DURATION>
|
||||
Set timeout that DNS server is given to respond to the
|
||||
initial DNS query. For the 2nd and later queries,
|
||||
server is given time based on this timeout, and it is
|
||||
scaled linearly.
|
||||
.sp
|
||||
Default: \fB5s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-dns\-max\-try=<N>
|
||||
Set the number of DNS query before nghttpx gives up name
|
||||
lookup.
|
||||
.sp
|
||||
Default: \fB2\fP
|
||||
.UNINDENT
|
||||
.SS Debug
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1269,6 +1488,35 @@ positional arguments in command\-line, use \fBprivate\-key\-file\fP and
|
||||
.sp
|
||||
\fI\%\-\-conf\fP option cannot be used in the configuration file and
|
||||
will be ignored if specified.
|
||||
.TP
|
||||
.B Error log
|
||||
Error log is written to stderr by default. It can be configured
|
||||
using \fI\%\-\-errorlog\-file\fP\&. The format of log message is as
|
||||
follows:
|
||||
.sp
|
||||
<datetime> <master\-pid> <current\-pid> <thread\-id> <level> (<filename>:<line>) <msg>
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B <datetime>
|
||||
It is a conbination of date and time when the log is written. It
|
||||
is in ISO 8601 format.
|
||||
.TP
|
||||
.B <master\-pid>
|
||||
It is a master process ID.
|
||||
.TP
|
||||
.B <current\-pid>
|
||||
It is a process ID which writes this log.
|
||||
.TP
|
||||
.B <thread\-id>
|
||||
It is a thread ID which writes this log. It would be unique
|
||||
within <current\-pid>.
|
||||
.TP
|
||||
.B <filename> and <line>
|
||||
They are source file name, and line number which produce this log.
|
||||
.TP
|
||||
.B <msg>
|
||||
It is a log message body.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH SIGNALS
|
||||
.INDENT 0.0
|
||||
@@ -1278,6 +1526,9 @@ Shutdown gracefully. First accept pending connections and stop
|
||||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
.TP
|
||||
.B SIGHUP
|
||||
Reload configuration file given in \fI\%\-\-conf\fP\&.
|
||||
.TP
|
||||
.B SIGUSR1
|
||||
Reopen log files.
|
||||
.TP
|
||||
@@ -1285,7 +1536,11 @@ Reopen log files.
|
||||
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.
|
||||
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.
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
@@ -1434,6 +1689,19 @@ If \fI\%\-\-tls\-ticket\-key\-file\fP is given, encryption key is read
|
||||
from the given file. In this case, nghttpx does not rotate key
|
||||
automatically. To rotate key, one has to restart nghttpx (see
|
||||
SIGNALS).
|
||||
.SH CERTIFICATE TRANSPARENCY
|
||||
.sp
|
||||
nghttpx supports TLS \fBsigned_certificate_timestamp\fP extension (\fI\%RFC
|
||||
6962\fP). The relevant options
|
||||
are \fI\%\-\-tls\-sct\-dir\fP and \fBsct\-dir\fP parameter in
|
||||
\fI\%\-\-subcert\fP\&. They takes a directory, and nghttpx reads all
|
||||
files whose extension is \fB\&.sct\fP under the directory. The \fB*.sct\fP
|
||||
files are encoded as \fBSignedCertificateTimestamp\fP struct described
|
||||
in \fI\%section 3.2 of RFC 69662\fP\&. This format is
|
||||
the same one used by \fI\%nginx\-ct\fP and \fI\%mod_ssl_ct\fP\&.
|
||||
\fI\%ct\-submit\fP can be
|
||||
used to submit certificates to log servers, and obtain the
|
||||
\fBSignedCertificateTimestamp\fP struct which can be used with nghttpx.
|
||||
.SH MRUBY SCRIPTING
|
||||
.sp
|
||||
\fBWARNING:\fP
|
||||
@@ -1525,6 +1793,11 @@ connection from client.
|
||||
.B attribute [R] tls_used
|
||||
Return true if TLS is used on the connection.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B attribute [R] tls_sni
|
||||
Return the TLS SNI value which client sent in this connection.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1787,12 +2060,12 @@ connections or requests. It also avoids any process creation as is
|
||||
the case with hot swapping with signals.
|
||||
.sp
|
||||
The one limitation is that only numeric IP address is allowd in
|
||||
\fI\%backend\fP in request body while non numeric
|
||||
hostname is allowed in command\-line or configuration file is read
|
||||
using \fI\%\-\-conf\fP\&.
|
||||
\fI\%backend\fP in request body unless "dns" parameter
|
||||
is used while non numeric hostname is allowed in command\-line or
|
||||
configuration file is read using \fI\%\-\-conf\fP\&.
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fIh2load(1)\fP
|
||||
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBh2load(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -37,7 +37,7 @@ The options are categorized into several groups.
|
||||
Connections
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;PARAM]...]
|
||||
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
|
||||
|
||||
|
||||
Set backend host and port. The multiple backend
|
||||
@@ -70,7 +70,7 @@ Connections
|
||||
|
||||
Host can include "\*" in the left most position to
|
||||
indicate wildcard match (only suffix match is done).
|
||||
The "*" must match at least one character. For example,
|
||||
The "\*" must match at least one character. For example,
|
||||
host pattern "\*.nghttp2.org" matches against
|
||||
"www.nghttp2.org" and "git.ngttp2.org", but does not
|
||||
match against "nghttp2.org". The exact hosts match
|
||||
@@ -104,13 +104,13 @@ Connections
|
||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||
The parameters are delimited by ";". The available
|
||||
parameters are: "proto=<PROTO>", "tls",
|
||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
|
||||
"affinity=<METHOD>". The parameter consists of keyword,
|
||||
and optionally followed by "=" and value. For example,
|
||||
the parameter "proto=h2" consists of the keyword "proto"
|
||||
and value "h2". The parameter "tls" consists of the
|
||||
keyword "tls" without value. Each parameter is
|
||||
described as follows.
|
||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>",
|
||||
"affinity=<METHOD>", and "dns". The parameter consists
|
||||
of keyword, and optionally followed by "=" and value.
|
||||
For example, the parameter "proto=h2" consists of the
|
||||
keyword "proto" and value "h2". The parameter "tls"
|
||||
consists of the keyword "tls" without value. Each
|
||||
parameter is described as follows.
|
||||
|
||||
The backend application protocol can be specified using
|
||||
optional "proto" parameter, and in the form of
|
||||
@@ -159,6 +159,14 @@ Connections
|
||||
break if one of the backend gets unreachable, or backend
|
||||
settings are reloaded or replaced by API.
|
||||
|
||||
By default, name resolution of backend host name is done
|
||||
at start up, or reloading configuration. If "dns"
|
||||
parameter is given, name resolution takes place
|
||||
dynamically. This is useful if backend address changes
|
||||
frequently. If "dns" is given, name resolution of
|
||||
backend host name at start up, or reloading
|
||||
configuration is skipped.
|
||||
|
||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||
not contain these characters. Since ";" has special
|
||||
meaning in shell, the option value must be quoted.
|
||||
@@ -166,7 +174,7 @@ Connections
|
||||
|
||||
Default: ``127.0.0.1,80``
|
||||
|
||||
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[[;PARAM]...]
|
||||
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
|
||||
|
||||
Set frontend host and port. If <HOST> is '\*', it
|
||||
assumes all addresses including both IPv4 and IPv6.
|
||||
@@ -194,6 +202,10 @@ Connections
|
||||
default. Any requests which come through this address
|
||||
are replied with 200 HTTP status, without no body.
|
||||
|
||||
To accept PROXY protocol version 1 on frontend
|
||||
connection, specify "proxyproto" parameter. This is
|
||||
disabled by default.
|
||||
|
||||
|
||||
Default: ``*,3000``
|
||||
|
||||
@@ -227,10 +239,6 @@ Connections
|
||||
be specified by :option:`--backend-read-timeout` and
|
||||
:option:`--backend-write-timeout` options.
|
||||
|
||||
.. option:: --accept-proxy-protocol
|
||||
|
||||
Accept PROXY protocol version 1 on frontend connection.
|
||||
|
||||
|
||||
Performance
|
||||
~~~~~~~~~~~
|
||||
@@ -391,6 +399,13 @@ Timeout
|
||||
|
||||
Default: ``30s``
|
||||
|
||||
.. option:: --frontend-keep-alive-timeout=<DURATION>
|
||||
|
||||
Specify keep-alive timeout for frontend HTTP/1
|
||||
connection.
|
||||
|
||||
Default: ``1m``
|
||||
|
||||
.. option:: --stream-read-timeout=<DURATION>
|
||||
|
||||
Specify read timeout for HTTP/2 and SPDY streams. 0
|
||||
@@ -417,9 +432,17 @@ Timeout
|
||||
|
||||
Default: ``30s``
|
||||
|
||||
.. option:: --backend-connect-timeout=<DURATION>
|
||||
|
||||
Specify timeout before establishing TCP connection to
|
||||
backend.
|
||||
|
||||
Default: ``30s``
|
||||
|
||||
.. option:: --backend-keep-alive-timeout=<DURATION>
|
||||
|
||||
Specify keep-alive timeout for backend connection.
|
||||
Specify keep-alive timeout for backend HTTP/1
|
||||
connection.
|
||||
|
||||
Default: ``2s``
|
||||
|
||||
@@ -464,8 +487,27 @@ SSL/TLS
|
||||
|
||||
.. option:: --ciphers=<SUITE>
|
||||
|
||||
Set allowed cipher list. The format of the string is
|
||||
described in OpenSSL ciphers(1).
|
||||
Set allowed cipher list for frontend connection. The
|
||||
format of the string is described in OpenSSL ciphers(1).
|
||||
|
||||
Default: ``ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS``
|
||||
|
||||
.. option:: --client-ciphers=<SUITE>
|
||||
|
||||
Set allowed cipher list for backend connection. The
|
||||
format of the string is described in OpenSSL ciphers(1).
|
||||
|
||||
Default: ``ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS``
|
||||
|
||||
.. option:: --ecdh-curves=<LIST>
|
||||
|
||||
Set supported curve list for frontend connections.
|
||||
<LIST> is a colon separated list of curve NID or names
|
||||
in the preference order. The supported curves depend on
|
||||
the linked OpenSSL library. This function requires
|
||||
OpenSSL >= 1.0.2.
|
||||
|
||||
Default: ``X25519:P-256:P-384:P-521``
|
||||
|
||||
.. option:: -k, --insecure
|
||||
|
||||
@@ -486,7 +528,7 @@ SSL/TLS
|
||||
private key. If none is given and the private key is
|
||||
password protected it'll be requested interactively.
|
||||
|
||||
.. option:: --subcert=<KEYPATH>:<CERTPATH>
|
||||
.. option:: --subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
|
||||
|
||||
Specify additional certificate and private key file.
|
||||
nghttpx will choose certificates based on the hostname
|
||||
@@ -494,6 +536,15 @@ SSL/TLS
|
||||
option can be used multiple times. To make OCSP
|
||||
stapling work, <CERTPATH> must be absolute path.
|
||||
|
||||
Additional parameter can be specified in <PARAM>. The
|
||||
available <PARAM> is "sct-dir=<DIR>".
|
||||
|
||||
"sct-dir=<DIR>" specifies the path to directory which
|
||||
contains \*.sct files for TLS
|
||||
signed_certificate_timestamp extension (RFC 6962). This
|
||||
feature requires OpenSSL >= 1.0.2. See also
|
||||
:option:`--tls-sct-dir` option.
|
||||
|
||||
.. option:: --dh-param-file=<PATH>
|
||||
|
||||
Path to file that contains DH parameters in PEM format.
|
||||
@@ -705,9 +756,59 @@ SSL/TLS
|
||||
|
||||
.. option:: --no-http2-cipher-black-list
|
||||
|
||||
Allow black listed cipher suite on HTTP/2 connection.
|
||||
See https://tools.ietf.org/html/rfc7540#appendix-A for
|
||||
the complete HTTP/2 cipher suites black list.
|
||||
Allow black listed cipher suite on frontend HTTP/2
|
||||
connection. See
|
||||
https://tools.ietf.org/html/rfc7540#appendix-A for the
|
||||
complete HTTP/2 cipher suites black list.
|
||||
|
||||
.. option:: --client-no-http2-cipher-black-list
|
||||
|
||||
Allow black listed cipher suite on backend HTTP/2
|
||||
connection. See
|
||||
https://tools.ietf.org/html/rfc7540#appendix-A for the
|
||||
complete HTTP/2 cipher suites black list.
|
||||
|
||||
.. option:: --tls-sct-dir=<DIR>
|
||||
|
||||
Specifies the directory where \*.sct files exist. All
|
||||
\*.sct files in <DIR> are read, and sent as
|
||||
extension_data of TLS signed_certificate_timestamp (RFC
|
||||
6962) to client. These \*.sct files are for the
|
||||
certificate specified in positional command-line
|
||||
argument <CERT>, or certificate option in configuration
|
||||
file. For additional certificates, use :option:`--subcert`
|
||||
option. This option requires OpenSSL >= 1.0.2.
|
||||
|
||||
.. option:: --psk-secrets=<PATH>
|
||||
|
||||
Read list of PSK identity and secrets from <PATH>. This
|
||||
is used for frontend connection. The each line of input
|
||||
file is formatted as <identity>:<hex-secret>, where
|
||||
<identity> is PSK identity, and <hex-secret> is secret
|
||||
in hex. An empty line, and line which starts with '#'
|
||||
are skipped. The default enabled cipher list might not
|
||||
contain any PSK cipher suite. In that case, desired PSK
|
||||
cipher suites must be enabled using :option:`--ciphers` option.
|
||||
The desired PSK cipher suite may be black listed by
|
||||
HTTP/2. To use those cipher suites with HTTP/2,
|
||||
consider to use :option:`--no-http2-cipher-black-list` option.
|
||||
But be aware its implications.
|
||||
|
||||
.. option:: --client-psk-secrets=<PATH>
|
||||
|
||||
Read PSK identity and secrets from <PATH>. This is used
|
||||
for backend connection. The each line of input file is
|
||||
formatted as <identity>:<hex-secret>, where <identity>
|
||||
is PSK identity, and <hex-secret> is secret in hex. An
|
||||
empty line, and line which starts with '#' are skipped.
|
||||
The first identity and secret pair encountered is used.
|
||||
The default enabled cipher list might not contain any
|
||||
PSK cipher suite. In that case, desired PSK cipher
|
||||
suites must be enabled using :option:`--client-ciphers` option.
|
||||
The desired PSK cipher suite may be black listed by
|
||||
HTTP/2. To use those cipher suites with HTTP/2,
|
||||
consider to use :option:`--client-no-http2-cipher-black-list`
|
||||
option. But be aware its implications.
|
||||
|
||||
|
||||
HTTP/2 and SPDY
|
||||
@@ -729,35 +830,34 @@ HTTP/2 and SPDY
|
||||
|
||||
Default: ``100``
|
||||
|
||||
.. option:: --frontend-http2-window-bits=<N>
|
||||
.. option:: --frontend-http2-window-size=<SIZE>
|
||||
|
||||
Sets the per-stream initial window size of HTTP/2 SPDY
|
||||
frontend connection. For HTTP/2, the size is 2\*\*<N>-1.
|
||||
For SPDY, the size is 2\*\*<N>.
|
||||
Sets the per-stream initial window size of HTTP/2 and
|
||||
SPDY frontend connection.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``65535``
|
||||
|
||||
.. option:: --frontend-http2-connection-window-bits=<N>
|
||||
.. option:: --frontend-http2-connection-window-size=<SIZE>
|
||||
|
||||
Sets the per-connection window size of HTTP/2 and SPDY
|
||||
frontend connection. For HTTP/2, the size is
|
||||
2**<N>-1. For SPDY, the size is 2\*\*<N>.
|
||||
frontend connection. For SPDY connection, the value
|
||||
less than 64KiB is rounded up to 64KiB.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``65535``
|
||||
|
||||
.. option:: --backend-http2-window-bits=<N>
|
||||
.. option:: --backend-http2-window-size=<SIZE>
|
||||
|
||||
Sets the initial window size of HTTP/2 backend
|
||||
connection to 2\*\*<N>-1.
|
||||
connection.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``65535``
|
||||
|
||||
.. option:: --backend-http2-connection-window-bits=<N>
|
||||
.. option:: --backend-http2-connection-window-size=<SIZE>
|
||||
|
||||
Sets the per-connection window size of HTTP/2 backend
|
||||
connection to 2\*\*<N>-1.
|
||||
connection.
|
||||
|
||||
Default: ``30``
|
||||
Default: ``2147483647``
|
||||
|
||||
.. option:: --http2-no-cookie-crumbling
|
||||
|
||||
@@ -780,6 +880,65 @@ HTTP/2 and SPDY
|
||||
via Link header field is also supported. SPDY frontend
|
||||
does not support server push.
|
||||
|
||||
.. option:: --frontend-http2-optimize-write-buffer-size
|
||||
|
||||
(Experimental) Enable write buffer size optimization in
|
||||
frontend HTTP/2 TLS connection. This optimization aims
|
||||
to reduce write buffer size so that it only contains
|
||||
bytes which can send immediately. This makes server
|
||||
more responsive to prioritized HTTP/2 stream because the
|
||||
buffering of lower priority stream is reduced. This
|
||||
option is only effective on recent Linux platform.
|
||||
|
||||
.. option:: --frontend-http2-optimize-window-size
|
||||
|
||||
(Experimental) Automatically tune connection level
|
||||
window size of frontend HTTP/2 TLS connection. If this
|
||||
feature is enabled, connection window size starts with
|
||||
the default window size, 65535 bytes. nghttpx
|
||||
automatically adjusts connection window size based on
|
||||
TCP receiving window size. The maximum window size is
|
||||
capped by the value specified by
|
||||
:option:`--frontend-http2-connection-window-size`\. Since the
|
||||
stream is subject to stream level window size, it should
|
||||
be adjusted using :option:`--frontend-http2-window-size` option as
|
||||
well. This option is only effective on recent Linux
|
||||
platform.
|
||||
|
||||
.. option:: --frontend-http2-encoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the frontend HTTP/2 connection. The decoder (client)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which client specified.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --frontend-http2-decoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the frontend HTTP/2 connection.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --backend-http2-encoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the backend HTTP/2 connection. The decoder (backend)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which backend specified.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --backend-http2-decoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the backend HTTP/2 connection.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
|
||||
Mode
|
||||
~~~~
|
||||
@@ -847,6 +1006,10 @@ Logging
|
||||
* $ssl_session_id: session ID for SSL/TLS connection.
|
||||
* $ssl_session_reused: "r" if SSL/TLS session was
|
||||
reused. Otherwise, "."
|
||||
* $backend_host: backend host used to fulfill the
|
||||
request. "-" if backend host is not available.
|
||||
* $backend_port: backend port used to fulfill the
|
||||
request. "-" if backend host is not available.
|
||||
|
||||
The variable can be enclosed by "{" and "}" for
|
||||
disambiguation (e.g., ${remote_addr}).
|
||||
@@ -1011,10 +1174,22 @@ HTTP
|
||||
Set file path to custom error page served when nghttpx
|
||||
originally generates HTTP error status code <CODE>.
|
||||
<CODE> must be greater than or equal to 400, and at most
|
||||
599. If "*" is used instead of <CODE>, it matches all
|
||||
599. If "\*" is used instead of <CODE>, it matches all
|
||||
HTTP status code. If error status code comes from
|
||||
backend server, the custom error pages are not used.
|
||||
|
||||
.. option:: --server-name=<NAME>
|
||||
|
||||
Change server response header field value to <NAME>.
|
||||
|
||||
Default: ``nghttpx nghttp2/1.19.0-DEV``
|
||||
|
||||
.. option:: --no-server-rewrite
|
||||
|
||||
Don't rewrite server header field in default mode. When
|
||||
:option:`--http2-proxy` is used, these headers will not be altered
|
||||
regardless of this option.
|
||||
|
||||
|
||||
API
|
||||
~~~
|
||||
@@ -1026,6 +1201,33 @@ API
|
||||
Default: ``16K``
|
||||
|
||||
|
||||
DNS
|
||||
~~~
|
||||
|
||||
.. option:: --dns-cache-timeout=<DURATION>
|
||||
|
||||
Set duration that cached DNS results remain valid. Note
|
||||
that nghttpx caches the unsuccessful results as well.
|
||||
|
||||
Default: ``10s``
|
||||
|
||||
.. option:: --dns-lookup-timeout=<DURATION>
|
||||
|
||||
Set timeout that DNS server is given to respond to the
|
||||
initial DNS query. For the 2nd and later queries,
|
||||
server is given time based on this timeout, and it is
|
||||
scaled linearly.
|
||||
|
||||
Default: ``5s``
|
||||
|
||||
.. option:: --dns-max-try=<N>
|
||||
|
||||
Set the number of DNS query before nghttpx gives up name
|
||||
lookup.
|
||||
|
||||
Default: ``2``
|
||||
|
||||
|
||||
Debug
|
||||
~~~~~
|
||||
|
||||
@@ -1155,6 +1357,33 @@ 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
|
||||
-------
|
||||
|
||||
@@ -1163,6 +1392,9 @@ SIGQUIT
|
||||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
|
||||
SIGHUP
|
||||
Reload configuration file given in :option:`--conf`.
|
||||
|
||||
SIGUSR1
|
||||
Reopen log files.
|
||||
|
||||
@@ -1170,7 +1402,11 @@ 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.
|
||||
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.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -1199,7 +1435,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:: http
|
||||
.. code-block:: text
|
||||
|
||||
Link: </fonts/font.woff>; rel=preload
|
||||
Link: </css/theme.css>; rel=preload
|
||||
@@ -1316,6 +1552,24 @@ 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
|
||||
---------------
|
||||
|
||||
@@ -1398,6 +1652,10 @@ respectively.
|
||||
|
||||
Return true if TLS is used on the connection.
|
||||
|
||||
.. rb:attr_reader:: tls_sni
|
||||
|
||||
Return the TLS SNI value which client sent in this connection.
|
||||
|
||||
.. rb:class:: Request
|
||||
|
||||
Object to represent request from client. The modification to
|
||||
@@ -1628,9 +1886,9 @@ connections or requests. It also avoids any process creation as is
|
||||
the case with hot swapping with signals.
|
||||
|
||||
The one limitation is that only numeric IP address is allowd in
|
||||
:option:`backend <--backend>` in request body while non numeric
|
||||
hostname is allowed in command-line or configuration file is read
|
||||
using :option:`--conf`.
|
||||
: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
|
||||
--------
|
||||
|
||||
@@ -41,6 +41,33 @@ 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
|
||||
-------
|
||||
|
||||
@@ -49,6 +76,9 @@ SIGQUIT
|
||||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
|
||||
SIGHUP
|
||||
Reload configuration file given in :option:`--conf`.
|
||||
|
||||
SIGUSR1
|
||||
Reopen log files.
|
||||
|
||||
@@ -56,7 +86,11 @@ 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.
|
||||
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.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -85,7 +119,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:: http
|
||||
.. code-block:: text
|
||||
|
||||
Link: </fonts/font.woff>; rel=preload
|
||||
Link: </css/theme.css>; rel=preload
|
||||
@@ -202,6 +236,24 @@ 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
|
||||
---------------
|
||||
|
||||
@@ -284,6 +336,10 @@ respectively.
|
||||
|
||||
Return true if TLS is used on the connection.
|
||||
|
||||
.. rb:attr_reader:: tls_sni
|
||||
|
||||
Return the TLS SNI value which client sent in this connection.
|
||||
|
||||
.. rb:class:: Request
|
||||
|
||||
Object to represent request from client. The modification to
|
||||
@@ -514,9 +570,9 @@ connections or requests. It also avoids any process creation as is
|
||||
the case with hot swapping with signals.
|
||||
|
||||
The one limitation is that only numeric IP address is allowd in
|
||||
:option:`backend <--backend>` in request body while non numeric
|
||||
hostname is allowed in command-line or configuration file is read
|
||||
using :option:`--conf`.
|
||||
: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
|
||||
--------
|
||||
|
||||
@@ -36,7 +36,7 @@ functions, and it also interacts with it via many API function calls.
|
||||
An application can create as many :type:`nghttp2_session` object as it
|
||||
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 applicatons use is single thread per
|
||||
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
|
||||
@@ -173,10 +173,64 @@ 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
|
||||
-----------------------------------------------------
|
||||
|
||||
|
||||
@@ -17,24 +17,22 @@ 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:
|
||||
|
||||
$ build/tools/make-standalone-toolchain.sh \
|
||||
--install-dir=$ANDROID_HOME/toolchain \
|
||||
--toolchain=arm-linux-androideabi-4.9 \
|
||||
--llvm-version=3.5 \
|
||||
--platform=android-16
|
||||
.. code-block:: text
|
||||
|
||||
The additional flag ``--system=linux-x86_64`` may be required if you
|
||||
are using x86_64 system.
|
||||
$ build/tools/make_standalone_toolchain.py \
|
||||
--arch arm --api 16 --stl gnustl
|
||||
--install-dir $ANDROID_HOME/toolchain
|
||||
|
||||
The platform level is not important here because we don't use Android
|
||||
specific C/C++ API.
|
||||
The API level (``--api``) is not important here because we don't use
|
||||
Android specific C/C++ API.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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
|
||||
@@ -45,7 +43,9 @@ 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``::
|
||||
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
|
||||
|
||||
@@ -97,6 +97,26 @@ 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
|
||||
@@ -133,24 +153,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.
|
||||
|
||||
@@ -159,6 +179,8 @@ 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::
|
||||
using the following command:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ arm-linux-androideabi-strip src/nghttpx
|
||||
|
||||
@@ -27,7 +27,7 @@ We use clang-format to format source code consistently. The
|
||||
clang-format configuration file .clang-format is located at the root
|
||||
directory. Since clang-format produces slightly different results
|
||||
between versions, we currently use clang-format which comes with
|
||||
clang-3.6.
|
||||
clang-3.9.
|
||||
|
||||
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.6 in debian), either add it to PATH variable or
|
||||
clang-format-diff-3.9 in debian), either add it to PATH variable or
|
||||
add git option ``clangformatdiff.binary`` to point to the script.
|
||||
|
||||
For emacs users, integrating clang-format to emacs is very easy.
|
||||
|
||||
@@ -48,12 +48,16 @@ explicitly.
|
||||
The backend is supposed to be Web server. For example, to make
|
||||
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
|
||||
backend Web server is configured to listen to HTTP request at port
|
||||
8080 in the same host, run nghttpx command-line like this::
|
||||
8080 in the same host, run nghttpx command-line like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||
|
||||
Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
|
||||
example, you can send GET request to the server using nghttp::
|
||||
example, you can send GET request to the server using nghttp:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttp -nv https://localhost:8443/
|
||||
|
||||
@@ -89,7 +93,9 @@ connection, use :option:`--backend` option, and specify ``h2`` in
|
||||
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::
|
||||
like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||
|
||||
@@ -118,13 +124,17 @@ to proxy.pac file, something like this:
|
||||
|
||||
file:///path/to/proxy.pac
|
||||
|
||||
For Chromium, use following command-line::
|
||||
For Chromium, use following command-line:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||
|
||||
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::
|
||||
configuration items to edit:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
CONFIG proxy.config.reverse_proxy.enabled INT 0
|
||||
CONFIG proxy.config.url_remap.remap_required INT 0
|
||||
@@ -134,6 +144,11 @@ Consult Traffic server `documentation
|
||||
to know how to configure traffic server as forward proxy and its
|
||||
security implications.
|
||||
|
||||
ALPN support
|
||||
------------
|
||||
|
||||
ALPN support requires OpenSSL >= 1.0.2.
|
||||
|
||||
Disable frontend SSL/TLS
|
||||
------------------------
|
||||
|
||||
@@ -152,9 +167,9 @@ Enable SSL/TLS on memcached connection
|
||||
--------------------------------------
|
||||
|
||||
By default, memcached connection is not encrypted. To enable
|
||||
encryption, use :option:`--tls-ticket-key-memcached-tls` for TLS
|
||||
ticket key, and use :option:`--tls-session-cache-memcached-tls` for
|
||||
TLS session cache.
|
||||
encryption, use ``tls`` keyword in
|
||||
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
|
||||
:option:`--tls-session-cache-memcached` for TLS session cache.
|
||||
|
||||
Specifying additional server certificates
|
||||
-----------------------------------------
|
||||
@@ -196,17 +211,17 @@ Rewriting location header field
|
||||
nghttpx automatically rewrites location response header field if the
|
||||
following all conditions satisfy:
|
||||
|
||||
* URI in location header field is not absolute URI or is not https URI.
|
||||
* 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 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 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.
|
||||
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``.
|
||||
|
||||
Hot swapping
|
||||
------------
|
||||
@@ -221,6 +236,9 @@ 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
|
||||
--------------------
|
||||
|
||||
@@ -325,10 +343,9 @@ requests, do this:
|
||||
backend=serv1,3000;/;proto=h2
|
||||
backend=serv1,3000;/ws/;proto=http/1.1
|
||||
|
||||
Note that the backends share the same pattern must have the same
|
||||
backend protocol. The default backend protocol is HTTP/1.1.
|
||||
The default backend protocol is HTTP/1.1.
|
||||
|
||||
TLS can be enabed per pattern basis:
|
||||
TLS can be enabled per pattern basis:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
@@ -338,6 +355,96 @@ TLS can be enabed per pattern basis:
|
||||
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`.
|
||||
|
||||
Enable PROXY protocol
|
||||
---------------------
|
||||
|
||||
PROXY protocol can be enabled per frontend. In order to enable PROXY
|
||||
protocol, use ``proxyproto`` parameter in :option:`--frontend` option,
|
||||
like so:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
frontend=*,443;proxyproto
|
||||
|
||||
PSK cipher suites
|
||||
-----------------
|
||||
|
||||
nghttpx supports pre-shared key (PSK) cipher suites for both frontend
|
||||
and backend TLS connections. For frontend connection, use
|
||||
:option:`--psk-secrets` option to specify a file which contains PSK
|
||||
identity and secrets. The format of the file is
|
||||
``<identity>:<hex-secret>``, where ``<identity>`` is PSK identity, and
|
||||
``<hex-secret>`` is PSK secret in hex, like so:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
client1:9567800e065e078085c241d54a01c6c3f24b3bab71a606600f4c6ad2c134f3b9
|
||||
client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99
|
||||
|
||||
nghttpx server accepts any of the identity and secret pairs in the
|
||||
file. The default cipher suite list does not contain PSK cipher
|
||||
suites. In order to use PSK, PSK cipher suite must be enabled by
|
||||
using :option:`--ciphers` option. The desired PSK cipher suite may be
|
||||
listed in `HTTP/2 cipher black list
|
||||
<https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use
|
||||
such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
|
||||
using :option:`--no-http2-cipher-black-list` option. But you should
|
||||
understand its implications.
|
||||
|
||||
At the time of writing, even if only PSK cipher suites are specified
|
||||
in :option:`--ciphers` option, certificate and private key are still
|
||||
required.
|
||||
|
||||
For backend connection, use :option:`--client-psk-secrets` option to
|
||||
specify a file which contains single PSK identity and secret. The
|
||||
format is the same as the file used by :option:`--psk-secrets`
|
||||
described above, but only first identity and secret pair is solely
|
||||
used, like so:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99
|
||||
|
||||
The default cipher suite list does not contain PSK cipher suites. In
|
||||
order to use PSK, PSK cipher suite must be enabled by using
|
||||
:option:`--client-ciphers` option. The desired PSK cipher suite may
|
||||
be listed in `HTTP/2 cipher black list
|
||||
<https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use
|
||||
such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
|
||||
using :option:`--client-no-http2-cipher-black-list` option. But you
|
||||
should understand its implications.
|
||||
|
||||
Migration from nghttpx v1.18.x or earlier
|
||||
-----------------------------------------
|
||||
|
||||
As of nghttpx v1.19.0, :option:`--ciphers` option only changes cipher
|
||||
list for frontend TLS connection. In order to change cipher list for
|
||||
backend connection, use :option:`--client-ciphers` option.
|
||||
|
||||
Similarly, :option:`--no-http2-cipher-black-list` option only disables
|
||||
HTTP/2 cipher black list for frontend connection. In order to disable
|
||||
HTTP/2 cipher black list for backend connection, use
|
||||
:option:`--client-no-http2-cipher-black-list` option.
|
||||
|
||||
``--accept-proxy-protocol`` option was deprecated. Instead, use
|
||||
``proxyproto`` parameter in :option:`--frontend` option to enable
|
||||
PROXY protocol support per frontend.
|
||||
|
||||
Migration from nghttpx v1.8.0 or earlier
|
||||
----------------------------------------
|
||||
|
||||
|
||||
@@ -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.4``).
|
||||
PYTHON=/usr/bin/python3.5``).
|
||||
|
||||
HPACK API
|
||||
---------
|
||||
@@ -136,13 +136,15 @@ HTTP/2 servers
|
||||
|
||||
.. note::
|
||||
|
||||
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::
|
||||
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:
|
||||
|
||||
$ ./configure PYTHON=/usr/bin/python3.4
|
||||
.. code-block:: text
|
||||
|
||||
$ ./configure PYTHON=/usr/bin/python3.5
|
||||
|
||||
.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ 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::
|
||||
at the URI. The synopsis is:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ libevent-client HTTPS_URI
|
||||
|
||||
|
||||
@@ -78,15 +78,16 @@ 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_hd()`::
|
||||
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
|
||||
|
||||
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);
|
||||
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_nv *nv_out, int *inflate_flags,
|
||||
const uint8_t *in, size_t inlen,
|
||||
int in_final);
|
||||
|
||||
`nghttp2_hd_inflate_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.
|
||||
`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.
|
||||
|
||||
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
|
||||
@@ -118,11 +119,7 @@ If *in_final* is zero and the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag is
|
||||
not set, it indicates that all given data was processed. The caller
|
||||
is required to pass additional data.
|
||||
|
||||
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
|
||||
Example usage of `nghttp2_hd_inflate_hd2()` is shown in the
|
||||
`inflate_header_block()` function in `deflate.c`_.
|
||||
|
||||
Finally, to delete a :type:`nghttp2_hd_inflater` object, use
|
||||
|
||||
@@ -10,7 +10,9 @@ 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::
|
||||
certificate file. The synopsis is:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ libevent-server PORT /path/to/server.key /path/to/server.crt
|
||||
|
||||
|
||||
@@ -29,10 +29,6 @@ if(ENABLE_EXAMPLES)
|
||||
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:http-parser>)
|
||||
add_executable(deflate deflate.c $<TARGET_OBJECTS:http-parser>)
|
||||
|
||||
if(ENABLE_TINY_NGHTTPD)
|
||||
add_executable(tiny-nghttpd tiny-nghttpd.c $<TARGET_OBJECTS:http-parser>)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ASIO_LIB)
|
||||
foreach(name asio-sv asio-sv2 asio-cl asio-cl2)
|
||||
add_executable(${name} ${name}.cc $<TARGET_OBJECTS:http-parser>)
|
||||
|
||||
@@ -51,14 +51,6 @@ 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
|
||||
|
||||
@@ -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 \
|
||||
}
|
||||
|
||||
@@ -457,11 +457,12 @@ 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);
|
||||
@@ -695,9 +696,6 @@ 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();
|
||||
|
||||
|
||||
@@ -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 \
|
||||
}
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
|
||||
int rv;
|
||||
|
||||
if (session_data->stream_data->stream_id == stream_id) {
|
||||
fprintf(stderr, "Stream %d closed with error_code=%d\n", stream_id,
|
||||
fprintf(stderr, "Stream %d closed with error_code=%u\n", stream_id,
|
||||
error_code);
|
||||
rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR);
|
||||
if (rv != 0) {
|
||||
@@ -383,13 +383,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 \
|
||||
}
|
||||
|
||||
@@ -594,9 +594,6 @@ 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();
|
||||
|
||||
|
||||
@@ -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 \
|
||||
}
|
||||
|
||||
@@ -781,9 +781,6 @@ 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();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,8 @@ def build_header(headers):
|
||||
c = k[-1]
|
||||
if c not in ent:
|
||||
ent[c] = []
|
||||
ent[c].append(k)
|
||||
if k not in ent[c]:
|
||||
ent[c].append(k)
|
||||
|
||||
return res
|
||||
|
||||
@@ -106,7 +107,7 @@ def gen_enum():
|
||||
|
||||
def gen_index_header():
|
||||
print '''\
|
||||
static inline int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
||||
static int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
||||
switch (namelen) {'''
|
||||
b = build_header(HEADERS)
|
||||
for size in sorted(b.keys()):
|
||||
@@ -121,7 +122,7 @@ static inline int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
||||
case '{}':'''.format(c)
|
||||
for k in headers:
|
||||
print '''\
|
||||
if (lstreq("{}", name, {})) {{
|
||||
if (memeq("{}", name, {})) {{
|
||||
return {};
|
||||
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
|
||||
print '''\
|
||||
|
||||
@@ -134,6 +134,29 @@ OPTIONS = [
|
||||
"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",
|
||||
"psk-secrets",
|
||||
"client-psk-secrets",
|
||||
"client-no-http2-cipher-black-list",
|
||||
"client-ciphers",
|
||||
]
|
||||
|
||||
LOGVARS = [
|
||||
@@ -152,6 +175,8 @@ LOGVARS = [
|
||||
"ssl_protocol",
|
||||
"ssl_session_id",
|
||||
"ssl_session_reused",
|
||||
"backend_host",
|
||||
"backend_port",
|
||||
]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
10
help2rst.py
10
help2rst.py
@@ -160,13 +160,15 @@ DESCRIPTION
|
||||
print(line.strip())
|
||||
|
||||
def format_text(text):
|
||||
# escape *
|
||||
if len(text) > len(arg_indent):
|
||||
text = text[:len(arg_indent) + 1] + re.sub(r'\*', r'\*', text[len(arg_indent) + 1:])
|
||||
# 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)):])
|
||||
else:
|
||||
text = re.sub(r'\*', r'\*', text)
|
||||
# markup option reference
|
||||
text = re.sub(r'(^|\s)(-[a-zA-Z0-9-]+)', r'\1:option:`\2`', text)
|
||||
text = re.sub(r'(^|\s)(-[a-zA-Z0-9]|--[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)
|
||||
|
||||
@@ -160,8 +160,9 @@ func TestH1H1GracefulShutdown(t *testing.T) {
|
||||
}
|
||||
|
||||
want := io.EOF
|
||||
if _, err := st.conn.Read(nil); err == nil || err != want {
|
||||
t.Errorf("st.conn.Read(): %v; want %v", err, want)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -795,6 +796,30 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
@@ -1369,6 +1369,42 @@ 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)
|
||||
@@ -1845,6 +1881,42 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
@@ -101,10 +101,20 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||
args := []string{}
|
||||
|
||||
backendTLS := false
|
||||
dns := false
|
||||
externalDNS := false
|
||||
acceptProxyProtocol := false
|
||||
for _, k := range src_args {
|
||||
switch k {
|
||||
case "--http2-bridge":
|
||||
backendTLS = true
|
||||
case "--dns":
|
||||
dns = true
|
||||
case "--external-dns":
|
||||
dns = true
|
||||
externalDNS = true
|
||||
case "--accept-proxy-protocol":
|
||||
acceptProxyProtocol = true
|
||||
default:
|
||||
args = append(args, k)
|
||||
}
|
||||
@@ -117,7 +127,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
|
||||
ts.TLS = new(tls.Config)
|
||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
|
||||
ts.StartTLS()
|
||||
args = append(args, "-k", "--backend-tls")
|
||||
args = append(args, "-k")
|
||||
} else {
|
||||
ts.Start()
|
||||
}
|
||||
@@ -134,17 +144,36 @@ 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" + strings.Replace(backendURL.Host, ":", ",", -1)
|
||||
if backendTLS {
|
||||
b += ";;proto=h2;tls"
|
||||
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:])
|
||||
}
|
||||
|
||||
noTLS := "no-tls"
|
||||
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,
|
||||
var proxyProto string
|
||||
if acceptProxyProtocol {
|
||||
proxyProto = ";proxyproto"
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v%v%v", serverPort, noTLS, proxyProto), b,
|
||||
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
||||
|
||||
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
|
||||
|
||||
@@ -23,10 +23,22 @@ set(NGHTTP2_SOURCES
|
||||
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})
|
||||
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
|
||||
set_target_properties(nghttp2 PROPERTIES
|
||||
COMPILE_FLAGS "${WARNCFLAGS}"
|
||||
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
SUBDIRS = includes
|
||||
|
||||
EXTRA_DIST = Makefile.msvc CMakeLists.txt
|
||||
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
|
||||
|
||||
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
||||
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
||||
@@ -48,7 +48,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
||||
nghttp2_callbacks.c \
|
||||
nghttp2_mem.c \
|
||||
nghttp2_http.c \
|
||||
nghttp2_rcbuf.c
|
||||
nghttp2_rcbuf.c \
|
||||
nghttp2_debug.c
|
||||
|
||||
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||
nghttp2_frame.h \
|
||||
@@ -63,7 +64,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||
nghttp2_callbacks.h \
|
||||
nghttp2_mem.h \
|
||||
nghttp2_http.h \
|
||||
nghttp2_rcbuf.h
|
||||
nghttp2_rcbuf.h \
|
||||
nghttp2_debug.h
|
||||
|
||||
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
||||
libnghttp2_la_LDFLAGS = -no-undefined \
|
||||
|
||||
@@ -45,6 +45,7 @@ extern "C" {
|
||||
#include <inttypes.h>
|
||||
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <nghttp2/nghttp2ver.h>
|
||||
|
||||
@@ -668,6 +669,10 @@ typedef enum {
|
||||
/**
|
||||
* @macro
|
||||
*
|
||||
* .. warning::
|
||||
*
|
||||
* Deprecated. The initial max concurrent streams is 0xffffffffu.
|
||||
*
|
||||
* Default maximum number of incoming concurrent streams. Use
|
||||
* `nghttp2_submit_settings()` with
|
||||
* :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
|
||||
@@ -856,8 +861,13 @@ typedef enum {
|
||||
* achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
|
||||
* any data in this invocation. The library removes DATA frame from
|
||||
* the outgoing queue temporarily. To move back deferred DATA frame
|
||||
* to outgoing queue, call `nghttp2_session_resume_data()`. In case
|
||||
* of error, there are 2 choices. Returning
|
||||
* to outgoing queue, call `nghttp2_session_resume_data()`.
|
||||
*
|
||||
* If the application just wants to return from
|
||||
* `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
|
||||
* sending anything, return :enum:`NGHTTP2_ERR_PAUSE`.
|
||||
*
|
||||
* In case of error, there are 2 choices. Returning
|
||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
|
||||
* by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. If a
|
||||
* different error code is desirable, use
|
||||
@@ -1454,9 +1464,19 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
|
||||
* `nghttp2_session_server_new()`.
|
||||
*
|
||||
* The implementation of this function must return 0 if it succeeds.
|
||||
* If nonzero is returned, it is treated as fatal error and
|
||||
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
|
||||
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
|
||||
* It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the
|
||||
* transmission of the given frame.
|
||||
*
|
||||
* If there is a fatal error while executing this callback, the
|
||||
* implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
|
||||
* which makes `nghttp2_session_send()` and
|
||||
* `nghttp2_session_mem_send()` functions immediately return
|
||||
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
|
||||
*
|
||||
* If the other value is returned, it is treated as if
|
||||
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. But the
|
||||
* implementation should not rely on this since the library may define
|
||||
* new return value to extend its capability.
|
||||
*
|
||||
* To set this callback to :type:`nghttp2_session_callbacks`, use
|
||||
* `nghttp2_session_callbacks_set_before_frame_send_callback()`.
|
||||
@@ -1707,6 +1727,69 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
|
||||
nghttp2_rcbuf *value, uint8_t flags,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* Callback function invoked when a invalid header name/value pair is
|
||||
* received for the |frame|.
|
||||
*
|
||||
* The parameter and behaviour are similar to
|
||||
* :type:`nghttp2_on_header_callback`. The difference is that this
|
||||
* callback is only invoked when a invalid header name/value pair is
|
||||
* received which is silently ignored if this callback is not set.
|
||||
* Only invalid regular header field are passed to this callback. In
|
||||
* other words, invalid pseudo header field is not passed to this
|
||||
* callback. Also header fields which includes upper cased latter are
|
||||
* also treated as error without passing them to this callback.
|
||||
*
|
||||
* This callback is only considered if HTTP messaging validation is
|
||||
* turned on (which is on by default, see
|
||||
* `nghttp2_option_set_no_http_messaging()`).
|
||||
*
|
||||
* With this callback, application inspects the incoming invalid
|
||||
* field, and it also can reset stream from this callback by returning
|
||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
|
||||
* error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
|
||||
* code, call `nghttp2_submit_rst_stream()` with the error code of
|
||||
* choice in addition to returning
|
||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
|
||||
*/
|
||||
typedef int (*nghttp2_on_invalid_header_callback)(
|
||||
nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name,
|
||||
size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* Callback function invoked when a invalid header name/value pair is
|
||||
* received for the |frame|.
|
||||
*
|
||||
* The parameter and behaviour are similar to
|
||||
* :type:`nghttp2_on_header_callback2`. The difference is that this
|
||||
* callback is only invoked when a invalid header name/value pair is
|
||||
* received which is silently ignored if this callback is not set.
|
||||
* Only invalid regular header field are passed to this callback. In
|
||||
* other words, invalid pseudo header field is not passed to this
|
||||
* callback. Also header fields which includes upper cased latter are
|
||||
* also treated as error without passing them to this callback.
|
||||
*
|
||||
* This callback is only considered if HTTP messaging validation is
|
||||
* turned on (which is on by default, see
|
||||
* `nghttp2_option_set_no_http_messaging()`).
|
||||
*
|
||||
* With this callback, application inspects the incoming invalid
|
||||
* field, and it also can reset stream from this callback by returning
|
||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
|
||||
* error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
|
||||
* code, call `nghttp2_submit_rst_stream()` with the error code of
|
||||
* choice in addition to returning
|
||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
|
||||
*/
|
||||
typedef int (*nghttp2_on_invalid_header_callback2)(
|
||||
nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
|
||||
nghttp2_rcbuf *value, uint8_t flags, void *user_data);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
@@ -2065,6 +2148,29 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_on_header_callback2 on_header_callback2);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Sets callback function invoked when a invalid header name/value
|
||||
* pair is received. If both
|
||||
* `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
|
||||
* `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
|
||||
* used to set callbacks, the latter takes the precedence.
|
||||
*/
|
||||
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_on_invalid_header_callback on_invalid_header_callback);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Sets callback function invoked when a invalid header name/value
|
||||
* pair is received.
|
||||
*/
|
||||
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
@@ -2427,6 +2533,19 @@ NGHTTP2_EXTERN void
|
||||
nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
|
||||
size_t val);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* This option sets the maximum dynamic table size for deflating
|
||||
* header fields. The default value is 4KiB. In HTTP/2, receiver of
|
||||
* deflated header block can specify maximum dynamic table size. The
|
||||
* actual maximum size is the minimum of the size receiver specified
|
||||
* and this option value.
|
||||
*/
|
||||
NGHTTP2_EXTERN void
|
||||
nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
|
||||
size_t val);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
@@ -2619,14 +2738,20 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
|
||||
*
|
||||
* 6. :type:`nghttp2_before_frame_send_callback` is invoked.
|
||||
*
|
||||
* 7. :type:`nghttp2_send_callback` is invoked one or more times to
|
||||
* 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from
|
||||
* :type:`nghttp2_before_frame_send_callback`, the current frame
|
||||
* transmission is canceled, and
|
||||
* :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort
|
||||
* the following steps.
|
||||
*
|
||||
* 8. :type:`nghttp2_send_callback` is invoked one or more times to
|
||||
* send the frame.
|
||||
*
|
||||
* 8. :type:`nghttp2_on_frame_send_callback` is invoked.
|
||||
* 9. :type:`nghttp2_on_frame_send_callback` is invoked.
|
||||
*
|
||||
* 9. If the transmission of the frame triggers closure of the stream,
|
||||
* the stream is closed and
|
||||
* :type:`nghttp2_on_stream_close_callback` is invoked.
|
||||
* 10. If the transmission of the frame triggers closure of the
|
||||
* stream, the stream is closed and
|
||||
* :type:`nghttp2_on_stream_close_callback` is invoked.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -2677,8 +2802,8 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
|
||||
* buffer up small chunks of data as necessary to avoid this
|
||||
* situation.
|
||||
*/
|
||||
NGHTTP2_EXTERN ssize_t
|
||||
nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr);
|
||||
NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
|
||||
const uint8_t **data_ptr);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2718,12 +2843,13 @@ nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr);
|
||||
* taken. If the frame is either HEADERS or PUSH_PROMISE,
|
||||
* :type:`nghttp2_on_begin_headers_callback` is invoked. Then
|
||||
* :type:`nghttp2_on_header_callback` is invoked for each header
|
||||
* name/value pair. After all name/value pairs are emitted
|
||||
* successfully, :type:`nghttp2_on_frame_recv_callback` is
|
||||
* invoked. For other frames,
|
||||
* :type:`nghttp2_on_frame_recv_callback` is invoked. If the
|
||||
* reception of the frame triggers the closure of the stream,
|
||||
* :type:`nghttp2_on_stream_close_callback` is invoked.
|
||||
* name/value pair. For invalid header field,
|
||||
* :type:`nghttp2_on_invalid_header_callback` is called. After
|
||||
* all name/value pairs are emitted successfully,
|
||||
* :type:`nghttp2_on_frame_recv_callback` is invoked. For other
|
||||
* frames, :type:`nghttp2_on_frame_recv_callback` is invoked.
|
||||
* If the reception of the frame triggers the closure of the
|
||||
* stream, :type:`nghttp2_on_stream_close_callback` is invoked.
|
||||
*
|
||||
* 3. If the received frame is unpacked but is interpreted as
|
||||
* invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is
|
||||
@@ -2892,9 +3018,8 @@ nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
|
||||
*
|
||||
* This function returns -1 if it fails.
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length(
|
||||
nghttp2_session *session, int32_t stream_id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2904,11 +3029,32 @@ nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session,
|
||||
* `nghttp2_submit_window_update()`. This function takes into account
|
||||
* that and returns effective window size.
|
||||
*
|
||||
* This function does not take into account the amount of received
|
||||
* data from the remote endpoint. Use
|
||||
* `nghttp2_session_get_stream_local_window_size()` to know the amount
|
||||
* of data the remote endpoint can send without receiving stream level
|
||||
* WINDOW_UPDATE frame. Note that each stream is still subject to the
|
||||
* connection level flow control.
|
||||
*
|
||||
* This function returns -1 if it fails.
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_session_get_stream_effective_local_window_size(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size(
|
||||
nghttp2_session *session, int32_t stream_id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Returns the amount of flow-controlled payload (e.g., DATA) that the
|
||||
* remote endpoint can send without receiving stream level
|
||||
* WINDOW_UPDATE frame. It is also subject to the connection level
|
||||
* flow control. So the actual amount of data to send is
|
||||
* min(`nghttp2_session_get_stream_local_window_size()`,
|
||||
* `nghttp2_session_get_local_window_size()`).
|
||||
*
|
||||
* This function returns -1 if it fails.
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size(
|
||||
nghttp2_session *session, int32_t stream_id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2935,11 +3081,32 @@ nghttp2_session_get_effective_recv_data_length(nghttp2_session *session);
|
||||
* `nghttp2_submit_window_update()`. This function takes into account
|
||||
* that and returns effective window size.
|
||||
*
|
||||
* This function does not take into account the amount of received
|
||||
* data from the remote endpoint. Use
|
||||
* `nghttp2_session_get_local_window_size()` to know the amount of
|
||||
* data the remote endpoint can send without receiving
|
||||
* connection-level WINDOW_UPDATE frame. Note that each stream is
|
||||
* still subject to the stream level flow control.
|
||||
*
|
||||
* This function returns -1 if it fails.
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Returns the amount of flow-controlled payload (e.g., DATA) that the
|
||||
* remote endpoint can send without receiving connection level
|
||||
* WINDOW_UPDATE frame. Note that each stream is still subject to the
|
||||
* stream level flow control (see
|
||||
* `nghttp2_session_get_stream_local_window_size()`).
|
||||
*
|
||||
* This function returns -1 if it fails.
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_session_get_local_window_size(nghttp2_session *session);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
@@ -2954,9 +3121,8 @@ nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
|
||||
*
|
||||
* This function returns -1 if it fails.
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_session_get_stream_remote_window_size(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size(
|
||||
nghttp2_session *session, int32_t stream_id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -2988,6 +3154,24 @@ NGHTTP2_EXTERN int
|
||||
nghttp2_session_get_stream_remote_close(nghttp2_session *session,
|
||||
int32_t stream_id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Returns the current dynamic table size of HPACK inflater, including
|
||||
* the overhead 32 bytes per entry described in RFC 7541.
|
||||
*/
|
||||
NGHTTP2_EXTERN size_t
|
||||
nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Returns the current dynamic table size of HPACK deflater including
|
||||
* the overhead 32 bytes per entry described in RFC 7541.
|
||||
*/
|
||||
NGHTTP2_EXTERN size_t
|
||||
nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
@@ -3091,9 +3275,18 @@ NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session);
|
||||
* The |id| must be one of values defined in
|
||||
* :enum:`nghttp2_settings_id`.
|
||||
*/
|
||||
NGHTTP2_EXTERN uint32_t
|
||||
nghttp2_session_get_remote_settings(nghttp2_session *session,
|
||||
nghttp2_settings_id id);
|
||||
NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings(
|
||||
nghttp2_session *session, nghttp2_settings_id id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Returns the value of SETTINGS |id| of local endpoint acknowledged
|
||||
* by the remote endpoint. The |id| must be one of the values defined
|
||||
* in :enum:`nghttp2_settings_id`.
|
||||
*/
|
||||
NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
|
||||
nghttp2_session *session, nghttp2_settings_id id);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -3388,9 +3581,8 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
|
||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||
* The provided |buflen| size is too small to hold the output.
|
||||
*/
|
||||
NGHTTP2_EXTERN ssize_t
|
||||
nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
|
||||
const nghttp2_settings_entry *iv, size_t niv);
|
||||
NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
|
||||
uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -3515,12 +3707,10 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
|
||||
* frame.
|
||||
*
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_submit_request(nghttp2_session *session,
|
||||
const nghttp2_priority_spec *pri_spec,
|
||||
const nghttp2_nv *nva, size_t nvlen,
|
||||
const nghttp2_data_provider *data_prd,
|
||||
void *stream_user_data);
|
||||
NGHTTP2_EXTERN int32_t nghttp2_submit_request(
|
||||
nghttp2_session *session, const nghttp2_priority_spec *pri_spec,
|
||||
const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd,
|
||||
void *stream_user_data);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -3598,8 +3788,8 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
|
||||
*
|
||||
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
|
||||
* |nvlen| elements. The application is responsible not to include
|
||||
* required pseudo-header fields (header field whose name starts with
|
||||
* ":") in |nva|.
|
||||
* pseudo-header fields (header field whose name starts with ":") in
|
||||
* |nva|.
|
||||
*
|
||||
* This function creates copies of all name/value pairs in |nva|. It
|
||||
* also lower-cases all names in |nva|. The order of elements in
|
||||
@@ -3614,20 +3804,20 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
|
||||
* :type:`nghttp2_on_frame_not_send_callback` is called.
|
||||
*
|
||||
* For server, trailer fields must follow response HEADERS or response
|
||||
* DATA with END_STREAM flag set. The library does not enforce this
|
||||
* requirement, and applications should do this for themselves. If
|
||||
* `nghttp2_submit_trailer()` is called before any response HEADERS
|
||||
* DATA without END_STREAM flat set. The library does not enforce
|
||||
* this requirement, and applications should do this for themselves.
|
||||
* If `nghttp2_submit_trailer()` is called before any response HEADERS
|
||||
* submission (usually by `nghttp2_submit_response()`), the content of
|
||||
* |nva| will be sent as response headers, which will result in error.
|
||||
*
|
||||
* This function has the same effect with `nghttp2_submit_headers()`,
|
||||
* with flags = :enum:`NGHTTP2_FLAG_END_HEADERS` and both pri_spec and
|
||||
* with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
|
||||
* stream_user_data to NULL.
|
||||
*
|
||||
* To submit trailer fields after `nghttp2_submit_response()` is
|
||||
* called, the application has to specify
|
||||
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`. In
|
||||
* side :type:`nghttp2_data_source_read_callback`, when setting
|
||||
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
|
||||
* Inside of :type:`nghttp2_data_source_read_callback`, when setting
|
||||
* :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
|
||||
* :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`. After that, the
|
||||
* application can send trailer fields using
|
||||
@@ -3735,11 +3925,10 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
|
||||
* frame.
|
||||
*
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
|
||||
int32_t stream_id, const nghttp2_priority_spec *pri_spec,
|
||||
const nghttp2_nv *nva, size_t nvlen,
|
||||
void *stream_user_data);
|
||||
NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
|
||||
nghttp2_session *session, uint8_t flags, int32_t stream_id,
|
||||
const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen,
|
||||
void *stream_user_data);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -3947,10 +4136,9 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
|
||||
* is called for this frame.
|
||||
*
|
||||
*/
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
|
||||
int32_t stream_id, const nghttp2_nv *nva,
|
||||
size_t nvlen, void *promised_stream_user_data);
|
||||
NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
|
||||
nghttp2_session *session, uint8_t flags, int32_t stream_id,
|
||||
const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -4086,7 +4274,7 @@ nghttp2_session_check_server_session(nghttp2_session *session);
|
||||
* that value as window_size_increment is queued. If the
|
||||
* |window_size_increment| is larger than the received bytes from the
|
||||
* remote endpoint, the local window size is increased by that
|
||||
* difference. If the sole intention is to increase the local window
|
||||
* difference. If the sole purpose is to increase the local window
|
||||
* size, consider to use `nghttp2_session_set_local_window_size()`.
|
||||
*
|
||||
* If the |window_size_increment| is negative, the local window size
|
||||
@@ -4095,8 +4283,8 @@ nghttp2_session_check_server_session(nghttp2_session *session);
|
||||
* (`nghttp2_option_set_no_auto_window_update()`), and the library
|
||||
* decided that the WINDOW_UPDATE should be submitted, then
|
||||
* WINDOW_UPDATE is queued with the current received bytes count. If
|
||||
* the sole intention is to decrease the local window size, consider
|
||||
* to use `nghttp2_session_set_local_window_size()`.
|
||||
* the sole purpose is to decrease the local window size, consider to
|
||||
* use `nghttp2_session_set_local_window_size()`.
|
||||
*
|
||||
* If the |window_size_increment| is 0, the function does nothing and
|
||||
* returns 0.
|
||||
@@ -4398,7 +4586,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
||||
*
|
||||
* Initializes |*deflater_ptr| for deflating name/values pairs.
|
||||
*
|
||||
* The |deflate_hd_table_bufsize_max| is the upper bound of header
|
||||
* The |max_deflate_dynamic_table_size| is the upper bound of header
|
||||
* table size the deflater will use.
|
||||
*
|
||||
* If this function fails, |*deflater_ptr| is left untouched.
|
||||
@@ -4409,8 +4597,9 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
|
||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
*/
|
||||
NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||
size_t deflate_hd_table_bufsize_max);
|
||||
NGHTTP2_EXTERN int
|
||||
nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||
size_t max_deflate_dynamic_table_size);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -4427,9 +4616,10 @@ NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
|
||||
* The library code does not refer to |mem| pointer after this
|
||||
* function returns, so the application can safely free it.
|
||||
*/
|
||||
NGHTTP2_EXTERN int nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
|
||||
size_t deflate_hd_table_bufsize_max,
|
||||
nghttp2_mem *mem);
|
||||
NGHTTP2_EXTERN int
|
||||
nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
|
||||
size_t max_deflate_dynamic_table_size,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -4442,18 +4632,18 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
||||
* @function
|
||||
*
|
||||
* Changes header table size of the |deflater| to
|
||||
* |settings_hd_table_bufsize_max| bytes. This may trigger eviction
|
||||
* |settings_max_dynamic_table_size| bytes. This may trigger eviction
|
||||
* in the dynamic table.
|
||||
*
|
||||
* The |settings_hd_table_bufsize_max| should be the value received in
|
||||
* SETTINGS_HEADER_TABLE_SIZE.
|
||||
* The |settings_max_dynamic_table_size| should be the value received
|
||||
* in SETTINGS_HEADER_TABLE_SIZE.
|
||||
*
|
||||
* The deflater never uses more memory than
|
||||
* ``deflate_hd_table_bufsize_max`` bytes specified in
|
||||
* ``max_deflate_dynamic_table_size`` bytes specified in
|
||||
* `nghttp2_hd_deflate_new()`. Therefore, if
|
||||
* |settings_hd_table_bufsize_max| > ``deflate_hd_table_bufsize_max``,
|
||||
* resulting maximum table size becomes
|
||||
* ``deflate_hd_table_bufsize_max``.
|
||||
* |settings_max_dynamic_table_size| >
|
||||
* ``max_deflate_dynamic_table_size``, resulting maximum table size
|
||||
* becomes ``max_deflate_dynamic_table_size``.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -4463,7 +4653,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
|
||||
*/
|
||||
NGHTTP2_EXTERN int
|
||||
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||
size_t settings_hd_table_bufsize_max);
|
||||
size_t settings_max_dynamic_table_size);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -4492,9 +4682,43 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
|
||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||
* The provided |buflen| size is too small to hold the output.
|
||||
*/
|
||||
NGHTTP2_EXTERN ssize_t
|
||||
nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
|
||||
size_t buflen, const nghttp2_nv *nva, size_t nvlen);
|
||||
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
|
||||
uint8_t *buf, size_t buflen,
|
||||
const nghttp2_nv *nva,
|
||||
size_t nvlen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||
* the |veclen| size of buf vector |vec|. The each size of buffer
|
||||
* must be set in len field of :type:`nghttp2_vec`. If and only if
|
||||
* one chunk is filled up completely, next chunk will be used. If
|
||||
* |vec| is not large enough to store the deflated header block, this
|
||||
* function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
|
||||
* should use `nghttp2_hd_deflate_bound()` to know the upper bound of
|
||||
* buffer size required to deflate given header name/value pairs.
|
||||
*
|
||||
* Once this function fails, subsequent call of this function always
|
||||
* returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
|
||||
*
|
||||
* After this function returns, it is safe to delete the |nva|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
* :enum:`NGHTTP2_ERR_HEADER_COMP`
|
||||
* Deflation process has failed.
|
||||
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
|
||||
* The provided |buflen| size is too small to hold the output.
|
||||
*/
|
||||
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
|
||||
const nghttp2_vec *vec,
|
||||
size_t veclen,
|
||||
const nghttp2_nv *nva,
|
||||
size_t nvlen);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -4603,8 +4827,8 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
|
||||
* Changes header table size in the |inflater|. This may trigger
|
||||
* eviction in the dynamic table.
|
||||
*
|
||||
* The |settings_hd_table_bufsize_max| should be the value transmitted
|
||||
* in SETTINGS_HEADER_TABLE_SIZE.
|
||||
* The |settings_max_dynamic_table_size| should be the value
|
||||
* transmitted in SETTINGS_HEADER_TABLE_SIZE.
|
||||
*
|
||||
* This function must not be called while header block is being
|
||||
* inflated. In other words, this function must be called after
|
||||
@@ -4625,7 +4849,7 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
|
||||
*/
|
||||
NGHTTP2_EXTERN int
|
||||
nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
|
||||
size_t settings_hd_table_bufsize_max);
|
||||
size_t settings_max_dynamic_table_size);
|
||||
|
||||
/**
|
||||
* @enum
|
||||
@@ -4748,10 +4972,14 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||
*
|
||||
* The application should call this function repeatedly until the
|
||||
* ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
|
||||
* return value is non-negative. This means the all input values are
|
||||
* processed successfully. Then the application must call
|
||||
* `nghttp2_hd_inflate_end_headers()` to prepare for the next header
|
||||
* block input.
|
||||
* return value is non-negative. If that happens, all given input
|
||||
* data (|inlen| bytes) are processed successfully. Then the
|
||||
* application must call `nghttp2_hd_inflate_end_headers()` to prepare
|
||||
* for the next header block input.
|
||||
*
|
||||
* In other words, if |in_final| is nonzero, and this function returns
|
||||
* |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is
|
||||
* set in |*inflate_flags|.
|
||||
*
|
||||
* The caller can feed complete compressed header block. It also can
|
||||
* feed it in several chunks. The caller must set |in_final| to
|
||||
@@ -4810,10 +5038,11 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||
* }
|
||||
*
|
||||
*/
|
||||
NGHTTP2_EXTERN ssize_t
|
||||
nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out,
|
||||
int *inflate_flags, const uint8_t *in, size_t inlen,
|
||||
int in_final);
|
||||
NGHTTP2_EXTERN 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);
|
||||
|
||||
/**
|
||||
* @function
|
||||
@@ -5003,6 +5232,42 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
|
||||
NGHTTP2_EXTERN int32_t
|
||||
nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
|
||||
|
||||
/**
|
||||
* @functypedef
|
||||
*
|
||||
* Callback function invoked when the library outputs debug logging.
|
||||
* The function is called with arguments suitable for ``vfprintf(3)``
|
||||
*
|
||||
* The debug output is only enabled if the library is built with
|
||||
* ``DEBUGBUILD`` macro defined.
|
||||
*/
|
||||
typedef void (*nghttp2_debug_vprintf_callback)(const char *format,
|
||||
va_list args);
|
||||
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
* Sets a debug output callback called by the library when built with
|
||||
* ``DEBUGBUILD`` macro defined. If this option is not used, debug
|
||||
* log is written into standard error output.
|
||||
*
|
||||
* For builds without ``DEBUGBUILD`` macro defined, this function is
|
||||
* noop.
|
||||
*
|
||||
* Note that building with ``DEBUGBUILD`` may cause significant
|
||||
* performance penalty to libnghttp2 because of extra processing. It
|
||||
* should be used for debugging purpose only.
|
||||
*
|
||||
* .. Warning::
|
||||
*
|
||||
* Building with ``DEBUGBUILD`` may cause significant performance
|
||||
* penalty to libnghttp2 because of extra processing. It should be
|
||||
* used for debugging purpose only. We write this two times because
|
||||
* this is important.
|
||||
*/
|
||||
NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback(
|
||||
nghttp2_debug_vprintf_callback debug_vprintf_callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nghttp2_helper.h"
|
||||
#include "nghttp2_debug.h"
|
||||
|
||||
void nghttp2_buf_init(nghttp2_buf *buf) {
|
||||
buf->begin = NULL;
|
||||
@@ -223,13 +224,54 @@ 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;
|
||||
}
|
||||
|
||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||
bufs->head = NULL;
|
||||
if (bufs->head) {
|
||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
||||
@@ -256,12 +298,6 @@ 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;
|
||||
@@ -281,9 +317,8 @@ static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
DEBUGF(fprintf(stderr,
|
||||
"new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
||||
bufs->chunk_length, bufs, bufs->chunk_used));
|
||||
DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
||||
bufs->chunk_length, bufs, bufs->chunk_used);
|
||||
|
||||
++bufs->chunk_used;
|
||||
|
||||
@@ -301,10 +336,6 @@ 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) {
|
||||
|
||||
@@ -138,7 +138,9 @@ typedef struct {
|
||||
nghttp2_buf_chain *cur;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* The buffer capacity of each buf */
|
||||
/* The buffer capacity of each buf. This field may be 0 if
|
||||
nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
|
||||
functions. */
|
||||
size_t chunk_length;
|
||||
/* The maximum number of nghttp2_buf_chain */
|
||||
size_t max_chunk;
|
||||
@@ -197,10 +199,13 @@ 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 allocate extra chunk buffer is allocated. In other
|
||||
* is fixed and no 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:
|
||||
*
|
||||
@@ -210,6 +215,25 @@ 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().
|
||||
@@ -381,7 +405,7 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
||||
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
||||
|
||||
/*
|
||||
* Returns the buffer length of |bufs|.
|
||||
* Returns the total buffer length of |bufs|.
|
||||
*/
|
||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||
|
||||
|
||||
@@ -110,6 +110,18 @@ void nghttp2_session_callbacks_set_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) {
|
||||
|
||||
@@ -92,6 +92,13 @@ struct nghttp2_session_callbacks {
|
||||
*/
|
||||
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
|
||||
|
||||
58
lib/nghttp2_debug.c
Normal file
58
lib/nghttp2_debug.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 */
|
||||
43
lib/nghttp2_debug.h
Normal file
43
lib/nghttp2_debug.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_DEBUG_H
|
||||
#define NGHTTP2_DEBUG_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
|
||||
void nghttp2_debug_vprintf(const char *format, ...);
|
||||
#else
|
||||
#define DEBUGF(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* NGHTTP2_DEBUG_H */
|
||||
@@ -32,6 +32,7 @@
|
||||
#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));
|
||||
@@ -252,8 +253,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
||||
hd = *frame_hd;
|
||||
hd.length = nghttp2_buf_len(buf);
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n",
|
||||
hd.length));
|
||||
DEBUGF("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,8 +278,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
||||
|
||||
hd.length = nghttp2_buf_len(buf);
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: int CONTINUATION, payloadlen=%zu\n",
|
||||
hd.length));
|
||||
DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length);
|
||||
|
||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||
@@ -290,8 +289,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
||||
/* Set END_HEADERS flag for last CONTINUATION */
|
||||
hd.flags = NGHTTP2_FLAG_END_HEADERS;
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: last CONTINUATION, payloadlen=%zu\n",
|
||||
hd.length));
|
||||
DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length);
|
||||
|
||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||
@@ -871,7 +869,9 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
||||
p->name = nva[i].name;
|
||||
p->namelen = nva[i].namelen;
|
||||
} else {
|
||||
memcpy(data, nva[i].name, nva[i].namelen);
|
||||
if (nva[i].namelen) {
|
||||
memcpy(data, nva[i].name, nva[i].namelen);
|
||||
}
|
||||
p->name = data;
|
||||
p->namelen = nva[i].namelen;
|
||||
data[p->namelen] = '\0';
|
||||
@@ -883,7 +883,9 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
||||
p->value = nva[i].value;
|
||||
p->valuelen = nva[i].valuelen;
|
||||
} else {
|
||||
memcpy(data, nva[i].value, nva[i].valuelen);
|
||||
if (nva[i].valuelen) {
|
||||
memcpy(data, nva[i].value, nva[i].valuelen);
|
||||
}
|
||||
p->value = data;
|
||||
p->valuelen = nva[i].valuelen;
|
||||
data[p->valuelen] = '\0';
|
||||
@@ -930,7 +932,7 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
|
||||
size_t trail_padlen;
|
||||
size_t newlen;
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: padlen=%zu, shift left 1 bytes\n", padlen));
|
||||
DEBUGF("send: padlen=%zu, shift left 1 bytes\n", padlen);
|
||||
|
||||
memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
|
||||
|
||||
@@ -960,7 +962,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||
nghttp2_buf *buf;
|
||||
|
||||
if (padlen == 0) {
|
||||
DEBUGF(fprintf(stderr, "send: padlen = 0, nothing to do\n"));
|
||||
DEBUGF("send: padlen = 0, nothing to do\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -994,8 +996,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||
hd->length += padlen;
|
||||
hd->flags |= NGHTTP2_FLAG_PADDED;
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: final payloadlen=%zu, padlen=%zu\n", hd->length,
|
||||
padlen));
|
||||
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
447
lib/nghttp2_hd.c
447
lib/nghttp2_hd.c
File diff suppressed because it is too large
Load Diff
@@ -288,7 +288,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
*
|
||||
* The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
|
||||
* The encoder only uses up to |max_deflate_dynamic_table_size| bytes
|
||||
* for header table even if the larger value is specified later in
|
||||
* nghttp2_hd_change_table_size().
|
||||
*
|
||||
@@ -299,7 +299,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 deflate_hd_table_bufsize_max,
|
||||
size_t max_deflate_dynamic_table_size,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
@@ -372,7 +372,7 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
||||
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
||||
|
||||
/* For unittesting purpose */
|
||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
|
||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
|
||||
uint32_t initial, size_t shift, uint8_t *in,
|
||||
uint8_t *last, size_t prefix);
|
||||
|
||||
@@ -410,8 +410,8 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
||||
* will be written to |buf|. This function assumes that |buf| has the
|
||||
* enough room to store the decoded byte string.
|
||||
*
|
||||
* The caller must set the |final| to nonzero if the given input is
|
||||
* the final block.
|
||||
* The caller must set the |fin| to nonzero if the given input is the
|
||||
* final block.
|
||||
*
|
||||
* This function returns the number of read bytes from the |in|.
|
||||
*
|
||||
@@ -425,6 +425,6 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
||||
*/
|
||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
nghttp2_buf *buf, const uint8_t *src,
|
||||
size_t srclen, int final);
|
||||
size_t srclen, int fin);
|
||||
|
||||
#endif /* NGHTTP2_HD_H */
|
||||
|
||||
@@ -64,15 +64,44 @@ 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) {
|
||||
rv = nghttp2_bufs_advance(bufs);
|
||||
/* 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);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
||||
/* we assume that we at least 3 buffer space available */
|
||||
assert(*avail_ptr >= 3);
|
||||
return (ssize_t)(8 - nbits);
|
||||
}
|
||||
|
||||
/* fast path, since most code is less than 8 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -189,8 +189,8 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
||||
account it in *delta_ptr. */
|
||||
*recv_window_size_ptr = recv_reduction_delta;
|
||||
}
|
||||
/* recv_reduction_delta must be paied from *delta_ptr, since it
|
||||
was added in window size reduction (see below). */
|
||||
/* 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;
|
||||
@@ -238,7 +238,7 @@ int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||
|
||||
*recv_window_size_ptr += recv_reduction_delta;
|
||||
|
||||
/* recv_reduction_delta must be paied from *delta_ptr, since it was
|
||||
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
||||
added in window size reduction (see below). */
|
||||
*delta_ptr -= recv_reduction_delta;
|
||||
|
||||
@@ -338,58 +338,70 @@ 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) {
|
||||
@@ -414,58 +426,70 @@ 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) {
|
||||
@@ -479,6 +503,10 @@ 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;
|
||||
|
||||
@@ -250,6 +250,25 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
||||
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;
|
||||
}
|
||||
@@ -286,58 +305,70 @@ 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) {
|
||||
|
||||
@@ -29,15 +29,9 @@
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* Macros, types and constants for internal use */
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(x) x
|
||||
#else
|
||||
#define DEBUGF(x) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
/* Macros, types and constants for internal use */
|
||||
|
||||
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
||||
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
||||
@@ -52,7 +46,13 @@ 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
|
||||
NGHTTP2_ERR_IGN_HTTP_HEADER = -105,
|
||||
/*
|
||||
* Invalid HTTP header field was received, and it is ignored.
|
||||
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
|
||||
* nghttp2_on_invalid_header_callback.
|
||||
*/
|
||||
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
|
||||
} nghttp2_internal_error;
|
||||
|
||||
#endif /* NGHTTP2_INT_H */
|
||||
|
||||
@@ -30,7 +30,7 @@ static int select_next_protocol(unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen,
|
||||
const char *key, unsigned int keylen) {
|
||||
unsigned int i;
|
||||
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in [i] + 1)) {
|
||||
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) {
|
||||
if (memcmp(&in[i], key, keylen) == 0) {
|
||||
*out = (unsigned char *)&in[i + 1];
|
||||
*outlen = in[i];
|
||||
|
||||
@@ -101,3 +101,9 @@ void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
|
||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH;
|
||||
option->max_send_header_block_length = val;
|
||||
}
|
||||
|
||||
void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
|
||||
size_t val) {
|
||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE;
|
||||
option->max_deflate_dynamic_table_size = val;
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef enum {
|
||||
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
|
||||
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
|
||||
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
|
||||
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
|
||||
} nghttp2_option_flag;
|
||||
|
||||
/**
|
||||
@@ -74,6 +75,10 @@ struct nghttp2_option {
|
||||
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
||||
*/
|
||||
size_t max_send_header_block_length;
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
|
||||
*/
|
||||
size_t max_deflate_dynamic_table_size;
|
||||
/**
|
||||
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
||||
* are specified.
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "nghttp2_mem.h"
|
||||
#include "nghttp2_helper.h"
|
||||
|
||||
int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size,
|
||||
nghttp2_mem *mem) {
|
||||
@@ -58,10 +59,8 @@ int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
|
||||
return rv;
|
||||
}
|
||||
|
||||
memcpy((*rcbuf_ptr)->base, src, srclen);
|
||||
|
||||
(*rcbuf_ptr)->len = srclen;
|
||||
(*rcbuf_ptr)->base[srclen] = '\0';
|
||||
*nghttp2_cpymem((*rcbuf_ptr)->base, src, srclen) = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -97,6 +97,9 @@ typedef struct {
|
||||
these frames in this number, it is considered suspicious. */
|
||||
#define NGHTTP2_MAX_OBQ_FLOOD_ITEM 10000
|
||||
|
||||
/* The default value of maximum number of concurrent streams. */
|
||||
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
|
||||
|
||||
/* Internal state when receiving incoming frame */
|
||||
typedef enum {
|
||||
/* Receiving frame header */
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "nghttp2_session.h"
|
||||
#include "nghttp2_helper.h"
|
||||
#include "nghttp2_debug.h"
|
||||
|
||||
/* Maximum distance between any two stream's cycle in the same
|
||||
prirority queue. Imagine stream A's cycle is A, and stream B's
|
||||
@@ -152,11 +153,11 @@ static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
|
||||
stream_next_cycle(stream, dep_stream->descendant_last_cycle);
|
||||
stream->seq = dep_stream->descendant_next_seq++;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d obq push cycle=%d\n",
|
||||
stream->stream_id, stream->cycle));
|
||||
DEBUGF("stream: stream=%d obq push cycle=%d\n", stream->stream_id,
|
||||
stream->cycle);
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: push stream %d to stream %d\n",
|
||||
stream->stream_id, dep_stream->stream_id));
|
||||
DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
|
||||
dep_stream->stream_id);
|
||||
|
||||
rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
||||
if (rv != 0) {
|
||||
@@ -183,8 +184,8 @@ static void stream_obq_remove(nghttp2_stream *stream) {
|
||||
}
|
||||
|
||||
for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
|
||||
DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d\n",
|
||||
stream->stream_id, dep_stream->stream_id));
|
||||
DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
|
||||
dep_stream->stream_id);
|
||||
|
||||
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
|
||||
|
||||
@@ -214,8 +215,8 @@ static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src,
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d (move)\n",
|
||||
stream->stream_id, src->stream_id));
|
||||
DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
|
||||
src->stream_id);
|
||||
|
||||
nghttp2_pq_remove(&src->obq, &stream->pq_entry);
|
||||
stream->queued = 0;
|
||||
@@ -238,8 +239,8 @@ void nghttp2_stream_reschedule(nghttp2_stream *stream) {
|
||||
|
||||
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
|
||||
stream->stream_id, stream->cycle));
|
||||
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id,
|
||||
stream->cycle);
|
||||
|
||||
dep_stream->last_writelen = stream->last_writelen;
|
||||
}
|
||||
@@ -298,8 +299,8 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
|
||||
|
||||
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
|
||||
stream->stream_id, stream->cycle));
|
||||
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id,
|
||||
stream->cycle);
|
||||
}
|
||||
|
||||
static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
|
||||
@@ -481,8 +482,7 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
|
||||
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
|
||||
assert(stream->item == NULL);
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d attach item=%p\n",
|
||||
stream->stream_id, item));
|
||||
DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
|
||||
|
||||
stream->item = item;
|
||||
|
||||
@@ -500,8 +500,7 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
|
||||
}
|
||||
|
||||
int nghttp2_stream_detach_item(nghttp2_stream *stream) {
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d detach item=%p\n",
|
||||
stream->stream_id, stream->item));
|
||||
DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item);
|
||||
|
||||
stream->item = NULL;
|
||||
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
|
||||
@@ -512,8 +511,8 @@ int nghttp2_stream_detach_item(nghttp2_stream *stream) {
|
||||
int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
|
||||
assert(stream->item);
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d defer item=%p cause=%02x\n",
|
||||
stream->stream_id, stream->item, flags));
|
||||
DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id,
|
||||
stream->item, flags);
|
||||
|
||||
stream->flags |= flags;
|
||||
|
||||
@@ -523,8 +522,8 @@ int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
|
||||
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
|
||||
assert(stream->item);
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: stream=%d resume item=%p flags=%02x\n",
|
||||
stream->stream_id, stream->item, flags));
|
||||
DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
|
||||
stream->item, flags);
|
||||
|
||||
stream->flags = (uint8_t)(stream->flags & ~flags);
|
||||
|
||||
@@ -593,9 +592,8 @@ int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *si;
|
||||
int rv;
|
||||
|
||||
DEBUGF(fprintf(stderr,
|
||||
"stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n",
|
||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||
DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
|
||||
dep_stream->stream_id, stream, stream->stream_id);
|
||||
|
||||
stream->sum_dep_weight = dep_stream->sum_dep_weight;
|
||||
dep_stream->sum_dep_weight = stream->weight;
|
||||
@@ -740,8 +738,8 @@ static void unlink_dep(nghttp2_stream *stream) {
|
||||
|
||||
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *stream) {
|
||||
DEBUGF(fprintf(stderr, "stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n",
|
||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||
DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
|
||||
dep_stream->stream_id, stream, stream->stream_id);
|
||||
|
||||
dep_stream->sum_dep_weight += stream->weight;
|
||||
|
||||
@@ -759,8 +757,7 @@ int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
|
||||
int32_t sum_dep_weight_delta;
|
||||
int rv;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: dep_remove stream(%p)=%d\n", stream,
|
||||
stream->stream_id));
|
||||
DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
|
||||
|
||||
/* Distribute weight of |stream| to direct descendants */
|
||||
sum_dep_weight_delta = -stream->weight;
|
||||
@@ -813,9 +810,8 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *si;
|
||||
int rv;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: dep_insert_subtree dep_stream(%p)=%d "
|
||||
"stream(%p)=%d\n",
|
||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||
DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
|
||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
|
||||
|
||||
stream->sum_dep_weight += dep_stream->sum_dep_weight;
|
||||
dep_stream->sum_dep_weight = stream->weight;
|
||||
@@ -862,9 +858,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
||||
nghttp2_stream *stream) {
|
||||
int rv;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: dep_add_subtree dep_stream(%p)=%d "
|
||||
"stream(%p)=%d\n",
|
||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
|
||||
DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
|
||||
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
|
||||
|
||||
dep_stream->sum_dep_weight += stream->weight;
|
||||
|
||||
@@ -889,8 +884,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
|
||||
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
|
||||
nghttp2_stream *next, *dep_prev;
|
||||
|
||||
DEBUGF(fprintf(stderr, "stream: dep_remove_subtree stream(%p)=%d\n", stream,
|
||||
stream->stream_id));
|
||||
DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
|
||||
stream->stream_id);
|
||||
|
||||
assert(stream->dep_prev);
|
||||
|
||||
|
||||
@@ -365,7 +365,7 @@ int32_t nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags _U_,
|
||||
return promised_stream_id;
|
||||
}
|
||||
|
||||
int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||
int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags _U_,
|
||||
int32_t stream_id,
|
||||
int32_t window_size_increment) {
|
||||
int rv;
|
||||
@@ -373,7 +373,6 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||
if (window_size_increment == 0) {
|
||||
return 0;
|
||||
}
|
||||
flags = 0;
|
||||
if (stream_id == 0) {
|
||||
rv = nghttp2_adjust_local_window_size(
|
||||
&session->local_window_size, &session->recv_window_size,
|
||||
@@ -404,14 +403,14 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||
nghttp2_max(0, stream->consumed_size - window_size_increment);
|
||||
}
|
||||
|
||||
return nghttp2_session_add_window_update(session, flags, stream_id,
|
||||
return nghttp2_session_add_window_update(session, 0, stream_id,
|
||||
window_size_increment);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nghttp2_session_set_local_window_size(nghttp2_session *session,
|
||||
uint8_t flags, int32_t stream_id,
|
||||
uint8_t flags _U_, int32_t stream_id,
|
||||
int32_t window_size) {
|
||||
int32_t window_size_increment;
|
||||
nghttp2_stream *stream;
|
||||
@@ -421,8 +420,6 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session,
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (stream_id == 0) {
|
||||
window_size_increment = window_size - session->local_window_size;
|
||||
|
||||
@@ -472,7 +469,7 @@ int nghttp2_session_set_local_window_size(nghttp2_session *session,
|
||||
}
|
||||
|
||||
if (window_size_increment > 0) {
|
||||
return nghttp2_session_add_window_update(session, flags, stream_id,
|
||||
return nghttp2_session_add_window_update(session, 0, stream_id,
|
||||
window_size_increment);
|
||||
}
|
||||
|
||||
|
||||
40
lib/version.rc.in
Normal file
40
lib/version.rc.in
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <winver.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
|
||||
FILEVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, 0
|
||||
PRODUCTVERSION @PROJECT_VERSION_MAJOR@, @PROJECT_VERSION_MINOR@, @PROJECT_VERSION_PATCH@, 0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
#ifdef _DEBUG
|
||||
#define VER_STR "@PROJECT_VERSION@.0 (MSVC debug)"
|
||||
#define DBG "d"
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
#define VER_STR "@PROJECT_VERSION@.0 (MSVC release)"
|
||||
#define DBG ""
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "https://nghttp2.org/"
|
||||
VALUE "FileDescription", "nghttp2; HTTP/2 C library"
|
||||
VALUE "FileVersion", VER_STR
|
||||
VALUE "InternalName", "nghttp2" DBG
|
||||
VALUE "LegalCopyright", "The MIT License"
|
||||
VALUE "LegalTrademarks", ""
|
||||
VALUE "OriginalFilename", "nghttp2" DBG ".dll"
|
||||
VALUE "ProductName", "NGHTTP2."
|
||||
VALUE "ProductVersion", VER_STR
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
@@ -1,104 +0,0 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_have_epoll.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_HAVE_EPOLL([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
# AX_HAVE_EPOLL_PWAIT([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro determines whether the system supports the epoll I/O event
|
||||
# interface. A neat usage example would be:
|
||||
#
|
||||
# AX_HAVE_EPOLL(
|
||||
# [AX_CONFIG_FEATURE_ENABLE(epoll)],
|
||||
# [AX_CONFIG_FEATURE_DISABLE(epoll)])
|
||||
# AX_CONFIG_FEATURE(
|
||||
# [epoll], [This platform supports epoll(7)],
|
||||
# [HAVE_EPOLL], [This platform supports epoll(7).])
|
||||
#
|
||||
# The epoll interface was added to the Linux kernel in version 2.5.45, and
|
||||
# the macro verifies that a kernel newer than this is installed. This
|
||||
# check is somewhat unreliable if <linux/version.h> doesn't match the
|
||||
# running kernel, but it is necessary regardless, because glibc comes with
|
||||
# stubs for the epoll_create(), epoll_wait(), etc. that allow programs to
|
||||
# compile and link even if the kernel is too old; the problem would then
|
||||
# be detected only at runtime.
|
||||
#
|
||||
# Linux kernel version 2.6.19 adds the epoll_pwait() call in addition to
|
||||
# epoll_wait(). The availability of that function can be tested with the
|
||||
# second macro. Generally speaking, it is safe to assume that
|
||||
# AX_HAVE_EPOLL would succeed if AX_HAVE_EPOLL_PWAIT has, but not the
|
||||
# other way round.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Peter Simons <simons@cryp.to>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 10
|
||||
|
||||
AC_DEFUN([AX_HAVE_EPOLL], [dnl
|
||||
ax_have_epoll_cppflags="${CPPFLAGS}"
|
||||
AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"])
|
||||
AC_MSG_CHECKING([for Linux epoll(7) interface])
|
||||
AC_CACHE_VAL([ax_cv_have_epoll], [dnl
|
||||
AC_LINK_IFELSE([dnl
|
||||
AC_LANG_PROGRAM([dnl
|
||||
#include <sys/epoll.h>
|
||||
#ifdef HAVE_LINUX_VERSION_H
|
||||
# include <linux/version.h>
|
||||
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
|
||||
# error linux kernel version is too old to have epoll
|
||||
# endif
|
||||
#endif
|
||||
], [dnl
|
||||
int fd, rc;
|
||||
struct epoll_event ev;
|
||||
fd = epoll_create(128);
|
||||
rc = epoll_wait(fd, &ev, 1, 0);])],
|
||||
[ax_cv_have_epoll=yes],
|
||||
[ax_cv_have_epoll=no])])
|
||||
CPPFLAGS="${ax_have_epoll_cppflags}"
|
||||
AS_IF([test "${ax_cv_have_epoll}" = "yes"],
|
||||
[AC_MSG_RESULT([yes])
|
||||
$1],[AC_MSG_RESULT([no])
|
||||
$2])
|
||||
])dnl
|
||||
|
||||
AC_DEFUN([AX_HAVE_EPOLL_PWAIT], [dnl
|
||||
ax_have_epoll_cppflags="${CPPFLAGS}"
|
||||
AC_CHECK_HEADER([linux/version.h],
|
||||
[CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"])
|
||||
AC_MSG_CHECKING([for Linux epoll(7) interface with signals extension])
|
||||
AC_CACHE_VAL([ax_cv_have_epoll_pwait], [dnl
|
||||
AC_LINK_IFELSE([dnl
|
||||
AC_LANG_PROGRAM([dnl
|
||||
#ifdef HAVE_LINUX_VERSION_H
|
||||
# include <linux/version.h>
|
||||
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||
# error linux kernel version is too old to have epoll_pwait
|
||||
# endif
|
||||
#endif
|
||||
#include <sys/epoll.h>
|
||||
#include <signal.h>
|
||||
], [dnl
|
||||
int fd, rc;
|
||||
struct epoll_event ev;
|
||||
fd = epoll_create(128);
|
||||
rc = epoll_wait(fd, &ev, 1, 0);
|
||||
rc = epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0));])],
|
||||
[ax_cv_have_epoll_pwait=yes],
|
||||
[ax_cv_have_epoll_pwait=no])])
|
||||
CPPFLAGS="${ax_have_epoll_cppflags}"
|
||||
AS_IF([test "${ax_cv_have_epoll_pwait}" = "yes"],
|
||||
[AC_MSG_RESULT([yes])
|
||||
$1],[AC_MSG_RESULT([no])
|
||||
$2])
|
||||
])dnl
|
||||
@@ -12,7 +12,7 @@ if [ -z "$CLANGFORMATDIFF" ]; then
|
||||
CLANGFORMATDIFF=clang-format-diff.py
|
||||
fi
|
||||
|
||||
errors=`git diff-index --cached --diff-filter=ACMR -p HEAD -- | $CLANGFORMATDIFF -p1`
|
||||
errors=`git diff-index --cached --diff-filter=ACMR -p HEAD lib src examples tests | $CLANGFORMATDIFF -p1`
|
||||
|
||||
if [ -n "$errors" ]; then
|
||||
echo "$errors"
|
||||
|
||||
@@ -260,6 +260,7 @@ try:
|
||||
import email.utils
|
||||
import datetime
|
||||
import time
|
||||
import ssl as tls
|
||||
from urllib.parse import urlparse
|
||||
except ImportError:
|
||||
asyncio = None
|
||||
@@ -294,6 +295,25 @@ def wrap_body(body):
|
||||
# string and flag.
|
||||
return body
|
||||
|
||||
def negotiated_protocol(ssl_obj):
|
||||
protocol = ssl_obj.selected_alpn_protocol()
|
||||
if protocol:
|
||||
logging.info('alpn, protocol:%s', protocol)
|
||||
return protocol
|
||||
|
||||
protocol = ssl_obj.selected_npn_protocol()
|
||||
if protocol:
|
||||
logging.info('npn, protocol:%s', protocol)
|
||||
return protocol
|
||||
|
||||
return None
|
||||
|
||||
def set_application_protocol(ssl_ctx):
|
||||
app_protos = [cnghttp2.NGHTTP2_PROTO_VERSION_ID.decode('utf-8')]
|
||||
ssl_ctx.set_npn_protocols(app_protos)
|
||||
if tls.HAS_ALPN:
|
||||
ssl_ctx.set_alpn_protocols(app_protos)
|
||||
|
||||
cdef _get_stream_user_data(cnghttp2.nghttp2_session *session,
|
||||
int32_t stream_id):
|
||||
cdef void *stream_user_data
|
||||
@@ -902,6 +922,8 @@ cdef class _HTTP2SessionCore(_HTTP2SessionCoreBase):
|
||||
return promised_handler
|
||||
|
||||
def connection_lost(self):
|
||||
self._stop_settings_timer()
|
||||
|
||||
for handler in self.handlers:
|
||||
handler.on_close(cnghttp2.NGHTTP2_INTERNAL_ERROR)
|
||||
self.handlers = set()
|
||||
@@ -1284,8 +1306,8 @@ if asyncio:
|
||||
logging.info('failed to set tcp-nodelay: %s', str(e))
|
||||
ssl_ctx = self.transport.get_extra_info('sslcontext')
|
||||
if ssl_ctx:
|
||||
protocol = sock.selected_npn_protocol()
|
||||
logging.info('npn, protocol:%s', protocol)
|
||||
ssl_obj = self.transport.get_extra_info('ssl_object')
|
||||
protocol = negotiated_protocol(ssl_obj)
|
||||
if protocol is None or protocol.encode('utf-8') != \
|
||||
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
||||
self.transport.abort()
|
||||
@@ -1346,8 +1368,7 @@ if asyncio:
|
||||
self.loop = asyncio.get_event_loop()
|
||||
|
||||
if ssl:
|
||||
ssl.set_npn_protocols([cnghttp2.NGHTTP2_PROTO_VERSION_ID\
|
||||
.decode('utf-8')])
|
||||
set_application_protocol(ssl)
|
||||
|
||||
coro = self.loop.create_server(session_factory,
|
||||
host=address[0], port=address[1],
|
||||
@@ -1516,8 +1537,8 @@ if asyncio:
|
||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
|
||||
ssl_ctx = self.transport.get_extra_info('sslcontext')
|
||||
if ssl_ctx:
|
||||
protocol = sock.selected_npn_protocol()
|
||||
logging.info('npn, protocol:%s', protocol)
|
||||
ssl_obj = self.transport.get_extra_info('ssl_object')
|
||||
protocol = negotiated_protocol(ssl_obj)
|
||||
if protocol is None or protocol.encode('utf-8') != \
|
||||
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
|
||||
self.transport.abort()
|
||||
@@ -1594,8 +1615,7 @@ if asyncio:
|
||||
return self.session
|
||||
|
||||
if ssl:
|
||||
ssl.set_npn_protocols([cnghttp2.NGHTTP2_PROTO_VERSION_ID\
|
||||
.decode('utf-8')])
|
||||
set_application_protocol(ssl)
|
||||
|
||||
self.loop = loop
|
||||
if not self.loop:
|
||||
|
||||
@@ -146,7 +146,7 @@ def send_and_receive_ocsp(respder_fn, cmd, cert_fn, issuer_fn, ocsp_uri,
|
||||
'-noverify', '-respout', respder_fn
|
||||
]
|
||||
ver = openssl_version.lower()
|
||||
if ver.startswith('openssl 1.') or ver.startswith('libressl '):
|
||||
if ver.startswith('openssl 1.0.') or ver.startswith('libressl '):
|
||||
args.extend(['-header', 'Host', ocsp_host])
|
||||
resp = run_openssl(args, allow_tempfail=True)
|
||||
return resp.decode('utf-8')
|
||||
|
||||
@@ -19,6 +19,7 @@ include_directories(
|
||||
${LIBXML2_INCLUDE_DIRS}
|
||||
${LIBEV_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
${LIBCARES_INCLUDE_DIRS}
|
||||
${JANSSON_INCLUDE_DIRS}
|
||||
${ZLIB_INCLUDE_DIRS}
|
||||
)
|
||||
@@ -31,6 +32,7 @@ link_libraries(
|
||||
${LIBXML2_LIBRARIES}
|
||||
${LIBEV_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${LIBCARES_LIBRARIES}
|
||||
${JANSSON_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
${APP_LIBRARIES}
|
||||
@@ -111,6 +113,11 @@ if(ENABLE_APP)
|
||||
shrpx_router.cc
|
||||
shrpx_api_downstream_connection.cc
|
||||
shrpx_health_monitor_downstream_connection.cc
|
||||
shrpx_exec.cc
|
||||
shrpx_dns_resolver.cc
|
||||
shrpx_dual_dns_resolver.cc
|
||||
shrpx_dns_tracker.cc
|
||||
xsi_strerror.c
|
||||
)
|
||||
if(HAVE_SPDYLAY)
|
||||
list(APPEND NGHTTPX_SRCS
|
||||
|
||||
@@ -96,6 +96,7 @@ Config::Config()
|
||||
num_worker(1),
|
||||
max_concurrent_streams(100),
|
||||
header_table_size(-1),
|
||||
encoder_header_table_size(-1),
|
||||
window_bits(-1),
|
||||
connection_window_bits(-1),
|
||||
port(0),
|
||||
@@ -231,6 +232,7 @@ public:
|
||||
config_(config),
|
||||
ssl_ctx_(ssl_ctx),
|
||||
callbacks_(nullptr),
|
||||
option_(nullptr),
|
||||
next_session_id_(1),
|
||||
tstamp_cached_(ev_now(loop)),
|
||||
cached_date_(util::http_date(tstamp_cached_)) {
|
||||
@@ -238,6 +240,13 @@ public:
|
||||
|
||||
fill_callback(callbacks_, config_);
|
||||
|
||||
nghttp2_option_new(&option_);
|
||||
|
||||
if (config_->encoder_header_table_size != -1) {
|
||||
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||
option_, config_->encoder_header_table_size);
|
||||
}
|
||||
|
||||
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
||||
release_fd_timer_.data = this;
|
||||
}
|
||||
@@ -246,6 +255,7 @@ public:
|
||||
for (auto handler : handlers_) {
|
||||
delete handler;
|
||||
}
|
||||
nghttp2_option_del(option_);
|
||||
nghttp2_session_callbacks_del(callbacks_);
|
||||
}
|
||||
void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
|
||||
@@ -283,6 +293,7 @@ public:
|
||||
return session_id;
|
||||
}
|
||||
const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
|
||||
const nghttp2_option *get_option() const { return option_; }
|
||||
void accept_connection(int fd) {
|
||||
util::make_socket_nodelay(fd);
|
||||
SSL *ssl = nullptr;
|
||||
@@ -408,6 +419,7 @@ private:
|
||||
const Config *config_;
|
||||
SSL_CTX *ssl_ctx_;
|
||||
nghttp2_session_callbacks *callbacks_;
|
||||
nghttp2_option *option_;
|
||||
ev_timer release_fd_timer_;
|
||||
int64_t next_session_id_;
|
||||
ev_tstamp tstamp_cached_;
|
||||
@@ -545,7 +557,7 @@ Http2Handler::~Http2Handler() {
|
||||
on_session_closed(this, session_id_);
|
||||
nghttp2_session_del(session_);
|
||||
if (ssl_) {
|
||||
SSL_set_shutdown(ssl_, SSL_RECEIVED_SHUTDOWN);
|
||||
SSL_set_shutdown(ssl_, SSL_get_shutdown(ssl_) | SSL_RECEIVED_SHUTDOWN);
|
||||
ERR_clear_error();
|
||||
SSL_shutdown(ssl_);
|
||||
}
|
||||
@@ -825,7 +837,8 @@ int Http2Handler::on_write() { return write_(*this); }
|
||||
int Http2Handler::connection_made() {
|
||||
int r;
|
||||
|
||||
r = nghttp2_session_server_new(&session_, sessions_->get_callbacks(), this);
|
||||
r = nghttp2_session_server_new2(&session_, sessions_->get_callbacks(), this,
|
||||
sessions_->get_option());
|
||||
|
||||
if (r != 0) {
|
||||
return r;
|
||||
@@ -1908,13 +1921,18 @@ namespace {
|
||||
FileEntry make_status_body(int status, uint16_t port) {
|
||||
BlockAllocator balloc(1024, 1024);
|
||||
|
||||
auto status_string = http2::get_status_string(balloc, status);
|
||||
auto status_string = http2::stringify_status(balloc, status);
|
||||
auto reason_pharase = http2::get_reason_phrase(status);
|
||||
|
||||
std::string body;
|
||||
body = "<html><head><title>";
|
||||
body += status_string;
|
||||
body += ' ';
|
||||
body += reason_pharase;
|
||||
body += "</title></head><body><h1>";
|
||||
body += status_string;
|
||||
body += ' ';
|
||||
body += reason_pharase;
|
||||
body += "</h1><hr><address>";
|
||||
body += NGHTTPD_SERVER;
|
||||
body += " at port ";
|
||||
@@ -2069,7 +2087,7 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
||||
std::cout << "[ALPN] client offers:" << std::endl;
|
||||
}
|
||||
if (config->verbose) {
|
||||
for (unsigned int i = 0; i < inlen; i += in [i] + 1) {
|
||||
for (unsigned int i = 0; i < inlen; i += in[i] + 1) {
|
||||
std::cout << " * ";
|
||||
std::cout.write(reinterpret_cast<const char *>(&in[i + 1]), in[i]);
|
||||
std::cout << std::endl;
|
||||
@@ -2103,6 +2121,7 @@ int HttpServer::run() {
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts);
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
SSL_CTX_set_max_version(ssl_ctx, TLS1_3_VERSION);
|
||||
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, ssl::DEFAULT_CIPHER_LIST) == 0) {
|
||||
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
|
||||
|
||||
@@ -69,6 +69,7 @@ struct Config {
|
||||
size_t num_worker;
|
||||
size_t max_concurrent_streams;
|
||||
ssize_t header_table_size;
|
||||
ssize_t encoder_header_table_size;
|
||||
int window_bits;
|
||||
int connection_window_bits;
|
||||
uint16_t port;
|
||||
|
||||
@@ -41,9 +41,10 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/includes \
|
||||
-I$(top_srcdir)/third-party \
|
||||
@LIBSPDYLAY_CFLAGS@ \
|
||||
@XML_CPPFLAGS@ \
|
||||
@LIBXML2_CFLAGS@ \
|
||||
@LIBEV_CFLAGS@ \
|
||||
@OPENSSL_CFLAGS@ \
|
||||
@LIBCARES_CFLAGS@ \
|
||||
@JANSSON_CFLAGS@ \
|
||||
@ZLIB_CFLAGS@ \
|
||||
@DEFS@
|
||||
@@ -52,9 +53,10 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
|
||||
$(top_builddir)/third-party/libhttp-parser.la \
|
||||
@JEMALLOC_LIBS@ \
|
||||
@LIBSPDYLAY_LIBS@ \
|
||||
@XML_LIBS@ \
|
||||
@LIBXML2_LIBS@ \
|
||||
@LIBEV_LIBS@ \
|
||||
@OPENSSL_LIBS@ \
|
||||
@LIBCARES_LIBS@ \
|
||||
@JANSSON_LIBS@ \
|
||||
@ZLIB_LIBS@ \
|
||||
@APPLDFLAGS@
|
||||
@@ -138,7 +140,12 @@ NGHTTPX_SRCS = \
|
||||
shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
|
||||
shrpx_health_monitor_downstream_connection.cc \
|
||||
shrpx_health_monitor_downstream_connection.h \
|
||||
buffer.h memchunk.h template.h allocator.h
|
||||
shrpx_exec.cc shrpx_exec.h \
|
||||
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
||||
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
||||
shrpx_dns_tracker.cc shrpx_dns_tracker.h \
|
||||
buffer.h memchunk.h template.h allocator.h \
|
||||
xsi_strerror.c xsi_strerror.h
|
||||
|
||||
if HAVE_SPDYLAY
|
||||
NGHTTPX_SRCS += shrpx_spdy_upstream.cc shrpx_spdy_upstream.h
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "template.h"
|
||||
|
||||
namespace nghttp2 {
|
||||
@@ -45,14 +47,18 @@ struct MemBlock {
|
||||
|
||||
// BlockAllocator allocates memory block with given size at once, and
|
||||
// cuts the region from it when allocation is requested. If the
|
||||
// requested size is larger than given threshold, it will be allocated
|
||||
// in a distinct buffer on demand.
|
||||
// requested size is larger than given threshold (plus small internal
|
||||
// overhead), it will be allocated in a distinct buffer on demand.
|
||||
// The |isolation_threshold| must be less than or equal to
|
||||
// |block_size|.
|
||||
struct BlockAllocator {
|
||||
BlockAllocator(size_t block_size, size_t isolation_threshold)
|
||||
: retain(nullptr),
|
||||
head(nullptr),
|
||||
block_size(block_size),
|
||||
isolation_threshold(std::min(block_size, isolation_threshold)) {}
|
||||
isolation_threshold(std::min(block_size, isolation_threshold)) {
|
||||
assert(isolation_threshold <= block_size);
|
||||
}
|
||||
|
||||
~BlockAllocator() { reset(); }
|
||||
|
||||
@@ -105,20 +111,60 @@ struct BlockAllocator {
|
||||
}
|
||||
|
||||
void *alloc(size_t size) {
|
||||
if (size >= isolation_threshold) {
|
||||
auto mb = alloc_mem_block(size);
|
||||
if (size + sizeof(size_t) >= isolation_threshold) {
|
||||
auto len = std::max(static_cast<size_t>(16), size);
|
||||
// We will store the allocated size in size_t field.
|
||||
auto mb = alloc_mem_block(len + sizeof(size_t));
|
||||
auto sp = reinterpret_cast<size_t *>(mb->begin);
|
||||
*sp = len;
|
||||
mb->last = mb->end;
|
||||
return mb->begin;
|
||||
return mb->begin + sizeof(size_t);
|
||||
}
|
||||
|
||||
if (!head || head->end - head->last < static_cast<ssize_t>(size)) {
|
||||
if (!head ||
|
||||
head->end - head->last < static_cast<ssize_t>(size + sizeof(size_t))) {
|
||||
head = alloc_mem_block(block_size);
|
||||
}
|
||||
|
||||
auto res = head->last;
|
||||
// We will store the allocated size in size_t field.
|
||||
auto res = head->last + sizeof(size_t);
|
||||
auto sp = reinterpret_cast<size_t *>(head->last);
|
||||
*sp = size;
|
||||
|
||||
head->last = reinterpret_cast<uint8_t *>(
|
||||
(reinterpret_cast<intptr_t>(head->last + size) + 0xf) & ~0xf);
|
||||
(reinterpret_cast<intptr_t>(res + size) + 0xf) & ~0xf);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Returns allocated size for memory pointed by |ptr|. We assume
|
||||
// that |ptr| was returned from alloc() or realloc().
|
||||
size_t get_alloc_length(void *ptr) {
|
||||
return *reinterpret_cast<size_t *>(static_cast<uint8_t *>(ptr) -
|
||||
sizeof(size_t));
|
||||
}
|
||||
|
||||
// Allocates memory of at least |size| bytes. If |ptr| is nullptr,
|
||||
// this is equivalent to alloc(size). If |ptr| is not nullptr,
|
||||
// obtain the allocated size for |ptr|, assuming that |ptr| was
|
||||
// returned from alloc() or realloc(). If the allocated size is
|
||||
// greater than or equal to size, |ptr| is returned. Otherwise,
|
||||
// allocates at least |size| bytes of memory, and the original
|
||||
// content pointed by |ptr| is copied to the newly allocated memory.
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
if (!ptr) {
|
||||
return alloc(size);
|
||||
}
|
||||
auto alloclen = get_alloc_length(ptr);
|
||||
auto p = reinterpret_cast<uint8_t *>(ptr);
|
||||
if (size <= alloclen) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
auto nalloclen = std::max(size + 1, alloclen * 2);
|
||||
|
||||
auto res = alloc(nalloclen);
|
||||
std::copy_n(p, alloclen, static_cast<uint8_t *>(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -186,6 +232,30 @@ StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) {
|
||||
return StringRef{dst, len};
|
||||
}
|
||||
|
||||
// Returns the string which is the concatenation of |value| and |args|
|
||||
// in the given order. The resulting string will be NULL-terminated.
|
||||
// This function assumes that the pointer value value.c_str() was
|
||||
// obtained from alloc.alloc() or alloc.realloc(), and attempts to use
|
||||
// unused memory region by using alloc.realloc(). If value is empty,
|
||||
// then just call concat_string_ref().
|
||||
template <typename BlockAllocator, typename... Args>
|
||||
StringRef realloc_concat_string_ref(BlockAllocator &alloc,
|
||||
const StringRef &value, Args &&... args) {
|
||||
if (value.empty()) {
|
||||
return concat_string_ref(alloc, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
auto len =
|
||||
value.size() + concat_string_ref_count(0, std::forward<Args>(args)...);
|
||||
auto dst = static_cast<uint8_t *>(
|
||||
alloc.realloc(const_cast<uint8_t *>(value.byte()), len + 1));
|
||||
auto p = dst + value.size();
|
||||
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
|
||||
*p = '\0';
|
||||
|
||||
return StringRef{dst, len};
|
||||
}
|
||||
|
||||
struct ByteRef {
|
||||
// The pointer to the beginning of the buffer.
|
||||
uint8_t *base;
|
||||
|
||||
@@ -334,7 +334,8 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
|
||||
frame->goaway.error_code,
|
||||
static_cast<unsigned int>(frame->goaway.opaque_data_len),
|
||||
util::ascii_dump(frame->goaway.opaque_data,
|
||||
frame->goaway.opaque_data_len).c_str());
|
||||
frame->goaway.opaque_data_len)
|
||||
.c_str());
|
||||
break;
|
||||
case NGHTTP2_WINDOW_UPDATE:
|
||||
print_frame_attr_indent();
|
||||
|
||||
@@ -503,7 +503,7 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
||||
}
|
||||
|
||||
auto nva = std::vector<nghttp2_nv>();
|
||||
nva.reserve(3 + h.size());
|
||||
nva.reserve(4 + h.size());
|
||||
nva.push_back(http2::make_nv_ls(":method", method));
|
||||
nva.push_back(http2::make_nv_ls(":scheme", uref.scheme));
|
||||
nva.push_back(http2::make_nv_ls(":path", path));
|
||||
@@ -521,13 +521,13 @@ const request *session_impl::submit(boost::system::error_code &ec,
|
||||
if (cb) {
|
||||
strm->request().impl().on_read(std::move(cb));
|
||||
prd.source.ptr = strm.get();
|
||||
prd.read_callback =
|
||||
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
|
||||
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
|
||||
void *user_data) -> ssize_t {
|
||||
auto strm = static_cast<stream *>(source->ptr);
|
||||
return strm->request().impl().call_on_read(buf, length, data_flags);
|
||||
};
|
||||
prd.read_callback = [](nghttp2_session *session, int32_t stream_id,
|
||||
uint8_t *buf, size_t length, uint32_t *data_flags,
|
||||
nghttp2_data_source *source,
|
||||
void *user_data) -> ssize_t {
|
||||
auto strm = static_cast<stream *>(source->ptr);
|
||||
return strm->request().impl().call_on_read(buf, length, data_flags);
|
||||
};
|
||||
prdptr = &prd;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,10 +74,12 @@ public:
|
||||
|
||||
virtual void start_connect(tcp::resolver::iterator endpoint_it) = 0;
|
||||
virtual tcp::socket &socket() = 0;
|
||||
virtual void read_socket(std::function<
|
||||
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
|
||||
virtual void write_socket(std::function<
|
||||
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
|
||||
virtual void read_socket(
|
||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
||||
h) = 0;
|
||||
virtual void write_socket(
|
||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
||||
h) = 0;
|
||||
virtual void shutdown_socket() = 0;
|
||||
|
||||
void shutdown();
|
||||
|
||||
@@ -44,10 +44,12 @@ public:
|
||||
|
||||
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
||||
virtual tcp::socket &socket();
|
||||
virtual void read_socket(std::function<
|
||||
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||
virtual void write_socket(std::function<
|
||||
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||
virtual void read_socket(
|
||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
||||
h);
|
||||
virtual void write_socket(
|
||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
||||
h);
|
||||
virtual void shutdown_socket();
|
||||
|
||||
private:
|
||||
|
||||
@@ -47,10 +47,12 @@ public:
|
||||
|
||||
virtual void start_connect(tcp::resolver::iterator endpoint_it);
|
||||
virtual tcp::socket &socket();
|
||||
virtual void read_socket(std::function<
|
||||
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||
virtual void write_socket(std::function<
|
||||
void(const boost::system::error_code &ec, std::size_t n)> h);
|
||||
virtual void read_socket(
|
||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
||||
h);
|
||||
virtual void write_socket(
|
||||
std::function<void(const boost::system::error_code &ec, std::size_t n)>
|
||||
h);
|
||||
virtual void shutdown_socket();
|
||||
|
||||
private:
|
||||
|
||||
@@ -113,22 +113,22 @@ generator_cb file_generator(const std::string &path) {
|
||||
generator_cb file_generator_from_fd(int fd) {
|
||||
auto d = defer_shared(close, fd);
|
||||
|
||||
return [fd, d](uint8_t *buf, size_t len, uint32_t *data_flags)
|
||||
-> generator_cb::result_type {
|
||||
ssize_t n;
|
||||
while ((n = read(fd, buf, len)) == -1 && errno == EINTR)
|
||||
;
|
||||
return [fd, d](uint8_t *buf, size_t len,
|
||||
uint32_t *data_flags) -> generator_cb::result_type {
|
||||
ssize_t n;
|
||||
while ((n = read(fd, buf, len)) == -1 && errno == EINTR)
|
||||
;
|
||||
|
||||
if (n == -1) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
if (n == -1) {
|
||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
|
||||
}
|
||||
if (n == 0) {
|
||||
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
|
||||
}
|
||||
|
||||
return n;
|
||||
};
|
||||
return n;
|
||||
};
|
||||
}
|
||||
|
||||
bool check_path(const std::string &path) { return util::check_path(path); }
|
||||
|
||||
@@ -58,7 +58,7 @@ void io_service_pool::run(bool asynchronous) {
|
||||
// Create a pool of threads to run all of the io_services.
|
||||
for (std::size_t i = 0; i < io_services_.size(); ++i) {
|
||||
futures_.push_back(std::async(std::launch::async,
|
||||
(size_t (boost::asio::io_service::*)(void)) &
|
||||
(size_t(boost::asio::io_service::*)(void)) &
|
||||
boost::asio::io_service::run,
|
||||
io_services_[i]));
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ void server::start_accept(boost::asio::ssl::context &tls_context,
|
||||
|
||||
acceptor.async_accept(
|
||||
new_connection->socket().lowest_layer(),
|
||||
[this, &tls_context, &acceptor, &mux, new_connection](
|
||||
const boost::system::error_code &e) {
|
||||
[this, &tls_context, &acceptor, &mux,
|
||||
new_connection](const boost::system::error_code &e) {
|
||||
if (!e) {
|
||||
new_connection->socket().lowest_layer().set_option(
|
||||
tcp::no_delay(true));
|
||||
|
||||
@@ -245,10 +245,19 @@ http2_handler::http2_handler(boost::asio::io_service &io_service,
|
||||
buf_(nullptr),
|
||||
buflen_(0),
|
||||
inside_callback_(false),
|
||||
write_signaled_(false),
|
||||
tstamp_cached_(time(nullptr)),
|
||||
formatted_date_(util::http_date(tstamp_cached_)) {}
|
||||
|
||||
http2_handler::~http2_handler() { nghttp2_session_del(session_); }
|
||||
http2_handler::~http2_handler() {
|
||||
for (auto &p : streams_) {
|
||||
auto &strm = p.second;
|
||||
strm->response().impl().call_on_close(NGHTTP2_INTERNAL_ERROR);
|
||||
close_stream(strm->get_stream_id());
|
||||
}
|
||||
|
||||
nghttp2_session_del(session_);
|
||||
}
|
||||
|
||||
const std::string &http2_handler::http_date() {
|
||||
auto t = time(nullptr);
|
||||
@@ -345,13 +354,13 @@ int http2_handler::start_response(stream &strm) {
|
||||
auto &req = strm.request().impl();
|
||||
if (::nghttp2::http2::expect_response_body(req.method(), res.status_code())) {
|
||||
prd.source.ptr = &strm;
|
||||
prd.read_callback =
|
||||
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
|
||||
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
|
||||
void *user_data) -> ssize_t {
|
||||
auto &strm = *static_cast<stream *>(source->ptr);
|
||||
return strm.response().impl().call_read(buf, length, data_flags);
|
||||
};
|
||||
prd.read_callback = [](nghttp2_session *session, int32_t stream_id,
|
||||
uint8_t *buf, size_t length, uint32_t *data_flags,
|
||||
nghttp2_data_source *source,
|
||||
void *user_data) -> ssize_t {
|
||||
auto &strm = *static_cast<stream *>(source->ptr);
|
||||
return strm.response().impl().call_read(buf, length, data_flags);
|
||||
};
|
||||
prd_ptr = &prd;
|
||||
}
|
||||
rv = nghttp2_submit_response(session_, strm.get_stream_id(), nva.data(),
|
||||
@@ -403,12 +412,17 @@ void http2_handler::stream_error(int32_t stream_id, uint32_t error_code) {
|
||||
}
|
||||
|
||||
void http2_handler::signal_write() {
|
||||
if (!inside_callback_) {
|
||||
initiate_write();
|
||||
if (!inside_callback_ && !write_signaled_) {
|
||||
write_signaled_ = true;
|
||||
auto self = shared_from_this();
|
||||
io_service_.post([self]() { self->initiate_write(); });
|
||||
}
|
||||
}
|
||||
|
||||
void http2_handler::initiate_write() { writefun_(); }
|
||||
void http2_handler::initiate_write() {
|
||||
write_signaled_ = false;
|
||||
writefun_();
|
||||
}
|
||||
|
||||
void http2_handler::resume(stream &strm) {
|
||||
nghttp2_session_resume_data(session_, strm.get_stream_id());
|
||||
|
||||
@@ -160,6 +160,9 @@ private:
|
||||
const uint8_t *buf_;
|
||||
std::size_t buflen_;
|
||||
bool inside_callback_;
|
||||
// true if we have pending on_write call. This avoids repeated call
|
||||
// of io_service::post.
|
||||
bool write_signaled_;
|
||||
time_t tstamp_cached_;
|
||||
std::string formatted_date_;
|
||||
};
|
||||
|
||||
@@ -36,11 +36,16 @@ std::string create_html(int status_code) {
|
||||
BlockAllocator balloc(1024, 1024);
|
||||
std::string res;
|
||||
res.reserve(512);
|
||||
auto status = ::nghttp2::http2::get_status_string(balloc, status_code);
|
||||
auto status_string = ::nghttp2::http2::stringify_status(balloc, status_code);
|
||||
auto reason_phrase = ::nghttp2::http2::get_reason_phrase(status_code);
|
||||
res += R"(<!DOCTYPE html><html lang="en"><title>)";
|
||||
res += status;
|
||||
res += status_string;
|
||||
res += ' ';
|
||||
res += reason_phrase;
|
||||
res += "</title><body><h1>";
|
||||
res += status;
|
||||
res += status_string;
|
||||
res += ' ';
|
||||
res += reason_phrase;
|
||||
res += "</h1></body></html>";
|
||||
return res;
|
||||
}
|
||||
|
||||
56
src/base64.h
56
src/base64.h
@@ -29,6 +29,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "template.h"
|
||||
#include "allocator.h"
|
||||
|
||||
namespace nghttp2 {
|
||||
|
||||
namespace base64 {
|
||||
@@ -87,7 +90,8 @@ InputIt next_decode_input(InputIt first, InputIt last, const int *tbl) {
|
||||
return first;
|
||||
}
|
||||
|
||||
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
||||
template <typename InputIt, typename OutputIt>
|
||||
OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
||||
static constexpr int INDEX_TABLE[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
@@ -104,37 +108,29 @@ template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1};
|
||||
auto len = last - first;
|
||||
if (len % 4 != 0) {
|
||||
return "";
|
||||
}
|
||||
std::string res;
|
||||
res.resize(len / 4 * 3);
|
||||
|
||||
auto p = std::begin(res);
|
||||
assert(std::distance(first, last) % 4 == 0);
|
||||
auto p = d_first;
|
||||
for (; first != last;) {
|
||||
uint32_t n = 0;
|
||||
for (int i = 1; i <= 4; ++i, ++first) {
|
||||
auto idx = INDEX_TABLE[static_cast<size_t>(*first)];
|
||||
if (idx == -1) {
|
||||
if (i <= 2) {
|
||||
return "";
|
||||
return d_first;
|
||||
}
|
||||
if (i == 3) {
|
||||
if (*first == '=' && *(first + 1) == '=' && first + 2 == last) {
|
||||
*p++ = n >> 16;
|
||||
res.resize(p - std::begin(res));
|
||||
return res;
|
||||
return p;
|
||||
}
|
||||
return "";
|
||||
return d_first;
|
||||
}
|
||||
if (*first == '=' && first + 1 == last) {
|
||||
*p++ = n >> 16;
|
||||
*p++ = n >> 8 & 0xffu;
|
||||
res.resize(p - std::begin(res));
|
||||
return res;
|
||||
return p;
|
||||
}
|
||||
return "";
|
||||
return d_first;
|
||||
}
|
||||
|
||||
n += idx << (24 - i * 6);
|
||||
@@ -145,9 +141,37 @@ template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
||||
*p++ = n & 0xffu;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
||||
auto len = std::distance(first, last);
|
||||
if (len % 4 != 0) {
|
||||
return "";
|
||||
}
|
||||
std::string res;
|
||||
res.resize(len / 4 * 3);
|
||||
|
||||
res.erase(decode(first, last, std::begin(res)), std::end(res));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template <typename InputIt>
|
||||
StringRef decode(BlockAllocator &balloc, InputIt first, InputIt last) {
|
||||
auto len = std::distance(first, last);
|
||||
if (len % 4 != 0) {
|
||||
return StringRef::from_lit("");
|
||||
}
|
||||
auto iov = make_byte_ref(balloc, len / 4 * 3 + 1);
|
||||
auto p = iov.base;
|
||||
|
||||
p = decode(first, last, p);
|
||||
*p = '\0';
|
||||
|
||||
return StringRef{iov.base, p};
|
||||
}
|
||||
|
||||
} // namespace base64
|
||||
|
||||
} // namespace nghttp2
|
||||
|
||||
@@ -59,31 +59,40 @@ void test_base64_encode(void) {
|
||||
}
|
||||
|
||||
void test_base64_decode(void) {
|
||||
BlockAllocator balloc(4096, 4096);
|
||||
{
|
||||
std::string in = "/w==";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("\xff" == out);
|
||||
CU_ASSERT("\xff" == base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
std::string in = "//4=";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("\xff\xfe" == out);
|
||||
CU_ASSERT("\xff\xfe" ==
|
||||
base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
std::string in = "//79";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("\xff\xfe\xfd" == out);
|
||||
CU_ASSERT("\xff\xfe\xfd" ==
|
||||
base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
std::string in = "//79/A==";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("\xff\xfe\xfd\xfc" == out);
|
||||
CU_ASSERT("\xff\xfe\xfd\xfc" ==
|
||||
base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
// we check the number of valid input must be multiples of 4
|
||||
std::string in = "//79=";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("" == out);
|
||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
// ending invalid character at the boundary of multiples of 4 is
|
||||
@@ -91,18 +100,21 @@ void test_base64_decode(void) {
|
||||
std::string in = "bmdodHRw\n";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("" == out);
|
||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
// after seeing '=', subsequent input must be also '='.
|
||||
std::string in = "//79/A=A";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("" == out);
|
||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
{
|
||||
// additional '=' at the end is bad
|
||||
std::string in = "//79/A======";
|
||||
auto out = base64::decode(std::begin(in), std::end(in));
|
||||
CU_ASSERT("" == out);
|
||||
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,9 @@ static int deflate_hd_json(json_t *obj, nghttp2_hd_deflater *deflater,
|
||||
static nghttp2_hd_deflater *init_deflater() {
|
||||
nghttp2_hd_deflater *deflater;
|
||||
nghttp2_hd_deflate_new(&deflater, config.deflate_table_size);
|
||||
nghttp2_hd_deflate_change_table_size(deflater, config.table_size);
|
||||
if (config.table_size != NGHTTP2_DEFAULT_HEADER_TABLE_SIZE) {
|
||||
nghttp2_hd_deflate_change_table_size(deflater, config.table_size);
|
||||
}
|
||||
return deflater;
|
||||
}
|
||||
|
||||
@@ -367,10 +369,11 @@ OPTIONS:
|
||||
buffer.
|
||||
Default: 4096
|
||||
-d, --dump-header-table
|
||||
Output dynamic header table.)" << std::endl;
|
||||
Output dynamic header table.)"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
static struct option long_options[] = {
|
||||
constexpr static struct option long_options[] = {
|
||||
{"http1text", no_argument, nullptr, 't'},
|
||||
{"table-size", required_argument, nullptr, 's'},
|
||||
{"deflate-table-size", required_argument, nullptr, 'S'},
|
||||
|
||||
169
src/h2load.cc
169
src/h2load.cc
@@ -79,7 +79,8 @@ bool recorded(const std::chrono::steady_clock::time_point &t) {
|
||||
} // namespace
|
||||
|
||||
Config::Config()
|
||||
: data_length(-1),
|
||||
: ciphers(ssl::DEFAULT_CIPHER_LIST),
|
||||
data_length(-1),
|
||||
addrs(nullptr),
|
||||
nreqs(1),
|
||||
nclients(1),
|
||||
@@ -92,6 +93,8 @@ Config::Config()
|
||||
conn_active_timeout(0.),
|
||||
conn_inactivity_timeout(0.),
|
||||
no_tls_proto(PROTO_HTTP2),
|
||||
header_table_size(4_k),
|
||||
encoder_header_table_size(4_k),
|
||||
data_fd(-1),
|
||||
port(0),
|
||||
default_port(0),
|
||||
@@ -507,7 +510,7 @@ void Client::disconnect() {
|
||||
ev_io_stop(worker->loop, &wev);
|
||||
ev_io_stop(worker->loop, &rev);
|
||||
if (ssl) {
|
||||
SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN);
|
||||
SSL_set_shutdown(ssl, SSL_get_shutdown(ssl) | SSL_RECEIVED_SHUTDOWN);
|
||||
ERR_clear_error();
|
||||
|
||||
if (SSL_shutdown(ssl) != 1) {
|
||||
@@ -593,7 +596,8 @@ void print_server_tmp_key(SSL *ssl) {
|
||||
|
||||
std::cout << "Server Temp Key: ";
|
||||
|
||||
switch (EVP_PKEY_id(key)) {
|
||||
auto pkey_id = EVP_PKEY_id(key);
|
||||
switch (pkey_id) {
|
||||
case EVP_PKEY_RSA:
|
||||
std::cout << "RSA " << EVP_PKEY_bits(key) << " bits" << std::endl;
|
||||
break;
|
||||
@@ -613,6 +617,10 @@ void print_server_tmp_key(SSL *ssl) {
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
std::cout << OBJ_nid2sn(pkey_id) << " " << EVP_PKEY_bits(key) << " bits"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
}
|
||||
@@ -1337,7 +1345,8 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
||||
}
|
||||
request_times.push_back(
|
||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
req_stat.stream_close_time - req_stat.request_time).count());
|
||||
req_stat.stream_close_time - req_stat.request_time)
|
||||
.count());
|
||||
}
|
||||
|
||||
const auto &stat = w->stats;
|
||||
@@ -1346,7 +1355,8 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
||||
if (recorded(cstat.client_start_time) &&
|
||||
recorded(cstat.client_end_time)) {
|
||||
auto t = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
cstat.client_end_time - cstat.client_start_time).count();
|
||||
cstat.client_end_time - cstat.client_start_time)
|
||||
.count();
|
||||
if (t > 1e-9) {
|
||||
rps_values.push_back(cstat.req_success / t);
|
||||
}
|
||||
@@ -1360,7 +1370,8 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
||||
|
||||
connect_times.push_back(
|
||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
cstat.connect_time - cstat.connect_start_time).count());
|
||||
cstat.connect_time - cstat.connect_start_time)
|
||||
.count());
|
||||
|
||||
if (!recorded(cstat.ttfb)) {
|
||||
continue;
|
||||
@@ -1368,7 +1379,8 @@ process_time_stats(const std::vector<std::unique_ptr<Worker>> &workers) {
|
||||
|
||||
ttfb_times.push_back(
|
||||
std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
cstat.ttfb - cstat.connect_start_time).count());
|
||||
cstat.ttfb - cstat.connect_start_time)
|
||||
.count());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1585,6 +1597,27 @@ std::unique_ptr<Worker> create_worker(uint32_t id, SSL_CTX *ssl_ctx,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
int parse_header_table_size(uint32_t &dst, const char *opt,
|
||||
const char *optarg) {
|
||||
auto n = util::parse_uint_with_unit(optarg);
|
||||
if (n == -1) {
|
||||
std::cerr << "--" << opt << ": Bad option value: " << optarg << std::endl;
|
||||
return -1;
|
||||
}
|
||||
if (n > std::numeric_limits<uint32_t>::max()) {
|
||||
std::cerr << "--" << opt
|
||||
<< ": Value too large. It should be less than or equal to "
|
||||
<< std::numeric_limits<uint32_t>::max() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dst = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
void print_version(std::ostream &out) {
|
||||
out << "h2load nghttp2/" NGHTTP2_VERSION << std::endl;
|
||||
@@ -1594,7 +1627,8 @@ void print_version(std::ostream &out) {
|
||||
namespace {
|
||||
void print_usage(std::ostream &out) {
|
||||
out << R"(Usage: h2load [OPTIONS]... [URI]...
|
||||
benchmarking tool for HTTP/2 and SPDY server)" << std::endl;
|
||||
benchmarking tool for HTTP/2 and SPDY server)"
|
||||
<< std::endl;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -1626,14 +1660,17 @@ Options:
|
||||
with --timing-script-file option, this option specifies
|
||||
the number of requests each client performs rather than
|
||||
the number of requests across all clients.
|
||||
Default: )" << config.nreqs << R"(
|
||||
Default: )"
|
||||
<< config.nreqs << R"(
|
||||
-c, --clients=<N>
|
||||
Number of concurrent clients. With -r option, this
|
||||
specifies the maximum number of connections to be made.
|
||||
Default: )" << config.nclients << R"(
|
||||
Default: )"
|
||||
<< config.nclients << R"(
|
||||
-t, --threads=<N>
|
||||
Number of native threads.
|
||||
Default: )" << config.nthreads << R"(
|
||||
Default: )"
|
||||
<< config.nthreads << R"(
|
||||
-i, --input-file=<PATH>
|
||||
Path of a file with multiple URIs are separated by EOLs.
|
||||
This option will disable URIs getting from command-line.
|
||||
@@ -1652,18 +1689,22 @@ Options:
|
||||
-w, --window-bits=<N>
|
||||
Sets the stream level initial window size to (2**<N>)-1.
|
||||
For SPDY, 2**<N> is used instead.
|
||||
Default: )" << config.window_bits << R"(
|
||||
Default: )"
|
||||
<< config.window_bits << R"(
|
||||
-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,
|
||||
this option is ignored. Otherwise 2**<N> is used for
|
||||
SPDY.
|
||||
Default: )" << config.connection_window_bits << R"(
|
||||
Default: )"
|
||||
<< config.connection_window_bits << R"(
|
||||
-H, --header=<HEADER>
|
||||
Add/Override a header to the requests.
|
||||
--ciphers=<SUITE>
|
||||
Set allowed cipher list. The format of the string is
|
||||
described in OpenSSL ciphers(1).
|
||||
Default: )"
|
||||
<< config.ciphers << R"(
|
||||
-p, --no-tls-proto=<PROTOID>
|
||||
Specify ALPN identifier of the protocol to be used when
|
||||
accessing http URI without SSL/TLS.)";
|
||||
@@ -1676,8 +1717,10 @@ Options:
|
||||
Available protocols: )";
|
||||
#endif // !HAVE_SPDYLAY
|
||||
out << NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"( and
|
||||
)" << NGHTTP2_H1_1 << R"(
|
||||
Default: )" << NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"(
|
||||
)"
|
||||
<< NGHTTP2_H1_1 << R"(
|
||||
Default: )"
|
||||
<< NGHTTP2_CLEARTEXT_PROTO_VERSION_ID << R"(
|
||||
-d, --data=<PATH>
|
||||
Post FILE to server. The request method is changed to
|
||||
POST. For http/1.1 connection, if -d is used, the
|
||||
@@ -1751,10 +1794,22 @@ Options:
|
||||
NPN. The parameter must be delimited by a single comma
|
||||
only and any white spaces are treated as a part of
|
||||
protocol string.
|
||||
Default: )" << DEFAULT_NPN_LIST << R"(
|
||||
Default: )"
|
||||
<< DEFAULT_NPN_LIST << R"(
|
||||
--h1 Short hand for --npn-list=http/1.1
|
||||
--no-tls-proto=http/1.1, which effectively force
|
||||
http/1.1 for both http and https URI.
|
||||
--header-table-size=<SIZE>
|
||||
Specify decoder header table size.
|
||||
Default: )"
|
||||
<< util::utos_unit(config.header_table_size) << R"(
|
||||
--encoder-header-table-size=<SIZE>
|
||||
Specify encoder header table size. The decoder (server)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which server specified.
|
||||
Default: )"
|
||||
<< util::utos_unit(config.encoder_header_table_size) << R"(
|
||||
-v, --verbose
|
||||
Output debug information.
|
||||
--version Display version information and exit.
|
||||
@@ -1762,10 +1817,14 @@ 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
|
||||
is omitted, a second is used as unit.)" << std::endl;
|
||||
is omitted, a second is used as unit.)"
|
||||
<< std::endl;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -1780,7 +1839,7 @@ int main(int argc, char **argv) {
|
||||
bool nreqs_set_manually = false;
|
||||
while (1) {
|
||||
static int flag = 0;
|
||||
static option long_options[] = {
|
||||
constexpr static option long_options[] = {
|
||||
{"requests", required_argument, nullptr, 'n'},
|
||||
{"clients", required_argument, nullptr, 'c'},
|
||||
{"data", required_argument, nullptr, 'd'},
|
||||
@@ -1803,6 +1862,8 @@ int main(int argc, char **argv) {
|
||||
{"npn-list", required_argument, &flag, 4},
|
||||
{"rate-period", required_argument, &flag, 5},
|
||||
{"h1", no_argument, &flag, 6},
|
||||
{"header-table-size", required_argument, &flag, 7},
|
||||
{"encoder-header-table-size", required_argument, &flag, 8},
|
||||
{nullptr, 0, nullptr, 0}};
|
||||
int option_index = 0;
|
||||
auto c = getopt_long(argc, argv, "hvW:c:d:m:n:p:t:w:H:i:r:T:N:B:",
|
||||
@@ -2003,6 +2064,20 @@ int main(int argc, char **argv) {
|
||||
util::parse_config_str_list(StringRef::from_lit("http/1.1"));
|
||||
config.no_tls_proto = Config::PROTO_HTTP1_1;
|
||||
break;
|
||||
case 7:
|
||||
// --header-table-size
|
||||
if (parse_header_table_size(config.header_table_size,
|
||||
"header-table-size", optarg) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
// --encoder-header-table-size
|
||||
if (parse_header_table_size(config.encoder_header_table_size,
|
||||
"encoder-header-table-size", optarg) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -2070,7 +2145,8 @@ int main(int argc, char **argv) {
|
||||
if (config.nreqs > uris.size()) {
|
||||
std::cerr << "-n: the number of requests must be less than or equal "
|
||||
"to the number of timing script entries. Setting number "
|
||||
"of requests to " << uris.size() << std::endl;
|
||||
"of requests to "
|
||||
<< uris.size() << std::endl;
|
||||
|
||||
config.nreqs = uris.size();
|
||||
}
|
||||
@@ -2120,7 +2196,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (config.nclients < config.nthreads) {
|
||||
std::cerr << "-c, -t: the number of clients must be greater than or equal "
|
||||
"to the number of threads." << std::endl;
|
||||
"to the number of threads."
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -2133,7 +2210,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (config.rate > config.nclients) {
|
||||
std::cerr << "-r, -c: the connection rate must be smaller than or equal "
|
||||
"to the number of clients." << std::endl;
|
||||
"to the number of clients."
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -2170,16 +2248,10 @@ int main(int argc, char **argv) {
|
||||
SSL_CTX_set_options(ssl_ctx, ssl_opts);
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
|
||||
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
|
||||
SSL_CTX_set_max_version(ssl_ctx, TLS1_3_VERSION);
|
||||
|
||||
const char *ciphers;
|
||||
if (config.ciphers.empty()) {
|
||||
ciphers = ssl::DEFAULT_CIPHER_LIST;
|
||||
} else {
|
||||
ciphers = config.ciphers.c_str();
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, ciphers) == 0) {
|
||||
std::cerr << "SSL_CTX_set_cipher_list with " << ciphers
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, config.ciphers.c_str()) == 0) {
|
||||
std::cerr << "SSL_CTX_set_cipher_list with " << config.ciphers
|
||||
<< " failed: " << ERR_error_string(ERR_get_error(), nullptr)
|
||||
<< std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -2480,26 +2552,29 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
std::cout << std::fixed << std::setprecision(2) << R"(
|
||||
finished in )" << util::format_duration(duration) << ", " << rps << " req/s, "
|
||||
finished in )"
|
||||
<< util::format_duration(duration) << ", " << rps << " req/s, "
|
||||
<< util::utos_funit(bps) << R"(B/s
|
||||
requests: )" << stats.req_todo << " total, " << stats.req_started
|
||||
<< " started, " << stats.req_done << " done, "
|
||||
<< stats.req_status_success << " succeeded, " << stats.req_failed
|
||||
<< " failed, " << stats.req_error << " errored, "
|
||||
<< stats.req_timedout << R"( timeout
|
||||
status codes: )" << stats.status[2] << " 2xx, " << stats.status[3] << " 3xx, "
|
||||
requests: )" << stats.req_todo
|
||||
<< " total, " << stats.req_started << " started, " << stats.req_done
|
||||
<< " done, " << stats.req_status_success << " succeeded, "
|
||||
<< stats.req_failed << " failed, " << stats.req_error
|
||||
<< " errored, " << stats.req_timedout << R"( timeout
|
||||
status codes: )"
|
||||
<< stats.status[2] << " 2xx, " << stats.status[3] << " 3xx, "
|
||||
<< stats.status[4] << " 4xx, " << stats.status[5] << R"( 5xx
|
||||
traffic: )" << util::utos_funit(stats.bytes_total) << "B (" << stats.bytes_total
|
||||
<< ") total, " << util::utos_funit(stats.bytes_head) << "B ("
|
||||
<< stats.bytes_head << ") headers (space savings "
|
||||
<< header_space_savings * 100 << "%), "
|
||||
<< util::utos_funit(stats.bytes_body) << "B (" << stats.bytes_body
|
||||
<< R"() data
|
||||
traffic: )" << util::utos_funit(stats.bytes_total)
|
||||
<< "B (" << stats.bytes_total << ") total, "
|
||||
<< util::utos_funit(stats.bytes_head) << "B (" << stats.bytes_head
|
||||
<< ") headers (space savings " << header_space_savings * 100
|
||||
<< "%), " << util::utos_funit(stats.bytes_body) << "B ("
|
||||
<< stats.bytes_body << R"() data
|
||||
min max mean sd +/- sd
|
||||
time for request: )" << std::setw(10) << util::format_duration(ts.request.min)
|
||||
<< " " << std::setw(10) << util::format_duration(ts.request.max)
|
||||
<< " " << std::setw(10) << util::format_duration(ts.request.mean)
|
||||
<< " " << std::setw(10) << util::format_duration(ts.request.sd)
|
||||
time for request: )"
|
||||
<< std::setw(10) << util::format_duration(ts.request.min) << " "
|
||||
<< std::setw(10) << util::format_duration(ts.request.max) << " "
|
||||
<< std::setw(10) << util::format_duration(ts.request.mean) << " "
|
||||
<< std::setw(10) << util::format_duration(ts.request.sd)
|
||||
<< std::setw(9) << util::dtos(ts.request.within_sd) << "%"
|
||||
<< "\ntime for connect: " << std::setw(10)
|
||||
<< util::format_duration(ts.connect.min) << " " << std::setw(10)
|
||||
|
||||
@@ -96,6 +96,8 @@ struct Config {
|
||||
PROTO_SPDY3_1,
|
||||
PROTO_HTTP1_1
|
||||
} no_tls_proto;
|
||||
uint32_t header_table_size;
|
||||
uint32_t encoder_header_table_size;
|
||||
// file descriptor for upload data
|
||||
int data_fd;
|
||||
uint16_t port;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user