mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-09 19:48:53 +08:00
Compare commits
516 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0880de4668 | ||
|
|
e4454672f0 | ||
|
|
e15a5517c7 | ||
|
|
9b0044d051 | ||
|
|
e9e5e15bbf | ||
|
|
2c7ef6442d | ||
|
|
d3ecf78031 | ||
|
|
d01db47215 | ||
|
|
8a760d0726 | ||
|
|
73bfe4bf21 | ||
|
|
6e5e9bceca | ||
|
|
0476f0efbc | ||
|
|
ca23a490c3 | ||
|
|
ee2a4b625b | ||
|
|
cec4bf08a2 | ||
|
|
ebf4b7eaee | ||
|
|
0bf5b764fa | ||
|
|
081eb29e9f | ||
|
|
ca81d89fe1 | ||
|
|
450ed6afce | ||
|
|
e72f4af5de | ||
|
|
3fa6a6349c | ||
|
|
6c0fd9400d | ||
|
|
de81da7621 | ||
|
|
8593b1f46c | ||
|
|
0e9d325dee | ||
|
|
534b74b725 | ||
|
|
090c7fe26c | ||
|
|
527cdebfee | ||
|
|
a2667a6692 | ||
|
|
aedc348754 | ||
|
|
19fbcf5238 | ||
|
|
6fe99003df | ||
|
|
0139746d53 | ||
|
|
8dd0c86bde | ||
|
|
5d4df477e8 | ||
|
|
2b355a338c | ||
|
|
cfeec12a52 | ||
|
|
26e2d53536 | ||
|
|
d921c54209 | ||
|
|
8f729331c1 | ||
|
|
a25dd12811 | ||
|
|
2f1565b0e2 | ||
|
|
389ae66d12 | ||
|
|
a60e00c628 | ||
|
|
53ce088694 | ||
|
|
e802ccc02a | ||
|
|
17428a5d09 | ||
|
|
83683742f1 | ||
|
|
fa585e9182 | ||
|
|
7434a37016 | ||
|
|
a2c47748f0 | ||
|
|
1784c1c0d1 | ||
|
|
59a9534a2d | ||
|
|
7fcbcd786e | ||
|
|
4e0738d24a | ||
|
|
1e0413f4a6 | ||
|
|
06e7219d10 | ||
|
|
c06c069126 | ||
|
|
d8ed2559f6 | ||
|
|
d829be3517 | ||
|
|
6aa9f6c72e | ||
|
|
4181fffc02 | ||
|
|
8f8eef40e8 | ||
|
|
3a95bf47f3 | ||
|
|
c218d441ea | ||
|
|
1952b166e9 | ||
|
|
bcfb5d8305 | ||
|
|
37fb82621c | ||
|
|
00bd05edcc | ||
|
|
45c67616b9 | ||
|
|
d94ce2a557 | ||
|
|
8a5c731533 | ||
|
|
6dfb3bdb8f | ||
|
|
43649c8004 | ||
|
|
b35fa94ba5 | ||
|
|
ee6565feb7 | ||
|
|
7caa11f09e | ||
|
|
cb73b18a53 | ||
|
|
4da70b34d1 | ||
|
|
cd868f00b9 | ||
|
|
9fc31cfd16 | ||
|
|
e9f04ae0ad | ||
|
|
5e75f0ac81 | ||
|
|
8c3f077c5e | ||
|
|
9cbe936a25 | ||
|
|
b815972b03 | ||
|
|
59b6d0d1d9 | ||
|
|
028eeeefeb | ||
|
|
1feb3679fe | ||
|
|
b00d8da2e2 | ||
|
|
9df3962d08 | ||
|
|
304bfcbb70 | ||
|
|
280845e52e | ||
|
|
bdc5d5a6d1 | ||
|
|
c9ff3599de | ||
|
|
15912bf810 | ||
|
|
9e65104b00 | ||
|
|
80ecefebb5 | ||
|
|
43b4369fba | ||
|
|
89b30903cc | ||
|
|
4904c736e1 | ||
|
|
3b45a19423 | ||
|
|
fbf4a7b750 | ||
|
|
2a190bf5ee | ||
|
|
877a78186c | ||
|
|
3d363ae478 | ||
|
|
73141a7698 | ||
|
|
eacf3484ca | ||
|
|
45ac57609b | ||
|
|
3190d030f7 | ||
|
|
6979a07da6 | ||
|
|
768e383662 | ||
|
|
6fd2f9e027 | ||
|
|
54359802fa | ||
|
|
bc57689f17 | ||
|
|
3ae75e840e | ||
|
|
7f79fbfa3e | ||
|
|
4c10abe99e | ||
|
|
2fed8b4945 | ||
|
|
f266ee500d | ||
|
|
708912fe20 | ||
|
|
f90a801609 | ||
|
|
107b7814fa | ||
|
|
bd70a1546c | ||
|
|
6e660ddc4b | ||
|
|
ea28e672ae | ||
|
|
fe8685e37f | ||
|
|
62c12b673b | ||
|
|
9ba0b7fde0 | ||
|
|
f9f5db5b6a | ||
|
|
7ef3a91d9b | ||
|
|
e435050378 | ||
|
|
8f5b450237 | ||
|
|
5f5fdc780f | ||
|
|
fd48570e7f | ||
|
|
daa4260f61 | ||
|
|
451853f39b | ||
|
|
dfab53ef65 | ||
|
|
5d4d517535 | ||
|
|
c36b8ee88a | ||
|
|
2e84de0be9 | ||
|
|
e18beaa3bd | ||
|
|
4890cb0fb8 | ||
|
|
06fb688be2 | ||
|
|
56d5406bce | ||
|
|
0196b2cc03 | ||
|
|
de7da99453 | ||
|
|
40124de400 | ||
|
|
6d7f80ed7f | ||
|
|
7bf98f2729 | ||
|
|
e434b74e50 | ||
|
|
7784fa979d | ||
|
|
8391ae7a57 | ||
|
|
d63d2568b7 | ||
|
|
d8d94e7a69 | ||
|
|
ef3b25e152 | ||
|
|
52ae8b7d9f | ||
|
|
d204cd0880 | ||
|
|
32a5793b02 | ||
|
|
b81979f35b | ||
|
|
808271a5a9 | ||
|
|
4bfd528d44 | ||
|
|
2fefe482bf | ||
|
|
1c2ba03f94 | ||
|
|
5edfa62c7b | ||
|
|
efad89d9d2 | ||
|
|
a8dfe825d0 | ||
|
|
a9b0230e57 | ||
|
|
01b16f64f4 | ||
|
|
b41ca012b4 | ||
|
|
d2b58bd0cd | ||
|
|
fc43fc1805 | ||
|
|
1616d9ef05 | ||
|
|
05b29df6eb | ||
|
|
9f0c59d6dd | ||
|
|
af02195b60 | ||
|
|
0f46173c2d | ||
|
|
ac22e0efe3 | ||
|
|
031ae82552 | ||
|
|
6b3e58127d | ||
|
|
5e576bda7d | ||
|
|
6039258f01 | ||
|
|
121e401166 | ||
|
|
67ab8145c7 | ||
|
|
68b663eaba | ||
|
|
c9f3166c4d | ||
|
|
eafb876a5b | ||
|
|
c8790efadf | ||
|
|
fbcf341878 | ||
|
|
1adb1d9bb7 | ||
|
|
c9bf55f125 | ||
|
|
2b07607cac | ||
|
|
556fa9f781 | ||
|
|
827da803f6 | ||
|
|
b1496253d0 | ||
|
|
811608bef8 | ||
|
|
db304adf70 | ||
|
|
ef94a3be9a | ||
|
|
2f283177f7 | ||
|
|
b13eb2c13f | ||
|
|
9707f9bfbe | ||
|
|
53785c2434 | ||
|
|
4f450d0f5a | ||
|
|
86a36fec8a | ||
|
|
5ccd54734a | ||
|
|
ecf42e76a8 | ||
|
|
c72e5f116d | ||
|
|
d79fd53b67 | ||
|
|
0bfdc8682d | ||
|
|
af5f768a52 | ||
|
|
9a51528aab | ||
|
|
e403873ac8 | ||
|
|
e004f75e77 | ||
|
|
55e02bdb70 | ||
|
|
d28170aaeb | ||
|
|
d2e9479da4 | ||
|
|
e0c815249d | ||
|
|
f5053fb2ad | ||
|
|
53ca70ae70 | ||
|
|
eea717d21b | ||
|
|
2e86b1bd77 | ||
|
|
8b638f219c | ||
|
|
91340d59bb | ||
|
|
3eafe7e630 | ||
|
|
923014d163 | ||
|
|
4fe2aab723 | ||
|
|
65c9142cd1 | ||
|
|
d159ff9baa | ||
|
|
4ef64cab52 | ||
|
|
a7ae4f80ab | ||
|
|
075788af7c | ||
|
|
24d4afb967 | ||
|
|
a4d961eb17 | ||
|
|
1d8abe7d1c | ||
|
|
6ad6c61af2 | ||
|
|
1440e88347 | ||
|
|
4e34e45be6 | ||
|
|
3ebd7f9966 | ||
|
|
ef7b349928 | ||
|
|
abdd0ea313 | ||
|
|
7eb7740e01 | ||
|
|
bbc091d762 | ||
|
|
4fa4e5fdad | ||
|
|
06b758de98 | ||
|
|
c98c67ae73 | ||
|
|
32e26bcf68 | ||
|
|
b420749135 | ||
|
|
47e886b5a0 | ||
|
|
cf5b34a12e | ||
|
|
91328046dd | ||
|
|
d34515372a | ||
|
|
2a79151248 | ||
|
|
b07227a169 | ||
|
|
1213986096 | ||
|
|
fe0f31a85c | ||
|
|
550000f160 | ||
|
|
36a9d3620e | ||
|
|
e6463c00f7 | ||
|
|
c827d07c10 | ||
|
|
f8e31cf478 | ||
|
|
963cbb4cce | ||
|
|
a1e557a725 | ||
|
|
a6c036e719 | ||
|
|
80627afe00 | ||
|
|
052a3fafa9 | ||
|
|
5535d099f6 | ||
|
|
23e555662e | ||
|
|
bbe10abe2e | ||
|
|
a86e70d278 | ||
|
|
ba484c41a9 | ||
|
|
413674f3ab | ||
|
|
e907529aaf | ||
|
|
05f517b118 | ||
|
|
d99de27967 | ||
|
|
ceeb73fbfb | ||
|
|
f336a3dfde | ||
|
|
196e533430 | ||
|
|
eefe3759f1 | ||
|
|
fd18019e84 | ||
|
|
8dfd1c3f95 | ||
|
|
d448ee9fa5 | ||
|
|
0f6f47ebc9 | ||
|
|
03c416a2ca | ||
|
|
2ac38479f5 | ||
|
|
a4e447bd84 | ||
|
|
bf292cc752 | ||
|
|
3ed14f2b38 | ||
|
|
c3574b711d | ||
|
|
8d9c80a285 | ||
|
|
34b18758cb | ||
|
|
89fb8dd503 | ||
|
|
7634e06611 | ||
|
|
9278383c1a | ||
|
|
86ba78b461 | ||
|
|
82320337ea | ||
|
|
3b7cabf15a | ||
|
|
63aa83ac42 | ||
|
|
9a09d9602b | ||
|
|
9ac5a1a773 | ||
|
|
1814fc1f2f | ||
|
|
23f2cb85fe | ||
|
|
1c07b88b2a | ||
|
|
44484e2ed5 | ||
|
|
78f542d59e | ||
|
|
99f658d600 | ||
|
|
aa2955c8fb | ||
|
|
d995c75173 | ||
|
|
bb7a0c78ce | ||
|
|
4993297326 | ||
|
|
e0089070f5 | ||
|
|
c3c418ce7a | ||
|
|
2643afa593 | ||
|
|
1a118fc0b2 | ||
|
|
1af84eca7b | ||
|
|
e3fbf4b0f1 | ||
|
|
ac080aeabb | ||
|
|
f59f7b6ded | ||
|
|
d73b5d42e9 | ||
|
|
8b0c12219a | ||
|
|
f0fce329b3 | ||
|
|
c39db11532 | ||
|
|
be06de738c | ||
|
|
3b82d4848a | ||
|
|
5504920feb | ||
|
|
faa3831d05 | ||
|
|
75d836c21e | ||
|
|
0b730de705 | ||
|
|
4f2b72dbeb | ||
|
|
5faf84cf2f | ||
|
|
784c1dbe36 | ||
|
|
74c6a20d96 | ||
|
|
901d8d777c | ||
|
|
880fa82e65 | ||
|
|
855e65b9c8 | ||
|
|
a2f37abdbe | ||
|
|
e9b9de1006 | ||
|
|
ab32a1bb40 | ||
|
|
e81aeb6fe4 | ||
|
|
a404ba5c12 | ||
|
|
7d15a7aa6b | ||
|
|
d41fd15d23 | ||
|
|
c1f08ca2f6 | ||
|
|
aeb5185a44 | ||
|
|
88171ab2bf | ||
|
|
02d1de1d9d | ||
|
|
339bc419bf | ||
|
|
81e817f695 | ||
|
|
6659de1cfd | ||
|
|
9e11a12c72 | ||
|
|
a1e9e5f640 | ||
|
|
2f02abfe7a | ||
|
|
3bca3282f1 | ||
|
|
646615022d | ||
|
|
dd293082fc | ||
|
|
9e235fe957 | ||
|
|
2b47d4b525 | ||
|
|
fa5ac09ade | ||
|
|
a993d99977 | ||
|
|
d400319bcc | ||
|
|
10d00c8a53 | ||
|
|
b559f69199 | ||
|
|
4513bfc3fc | ||
|
|
5e373a3514 | ||
|
|
0df91a4b0c | ||
|
|
c362f9d36c | ||
|
|
9b568cf542 | ||
|
|
6be52029db | ||
|
|
fef9e8fb20 | ||
|
|
09bb8350e8 | ||
|
|
10ebb3825a | ||
|
|
8bdf022465 | ||
|
|
14f1169a5a | ||
|
|
93dd369b0e | ||
|
|
bb3c2a3664 | ||
|
|
11903f36a9 | ||
|
|
afedd3aa06 | ||
|
|
242c0c3988 | ||
|
|
ed3b31fa4c | ||
|
|
b7be212c30 | ||
|
|
ac92a4daae | ||
|
|
ed1c6ed344 | ||
|
|
f804e92785 | ||
|
|
9275353a47 | ||
|
|
d1bc03bd57 | ||
|
|
853b9ccd3c | ||
|
|
dd02d164ba | ||
|
|
c36d0cb807 | ||
|
|
68ed952004 | ||
|
|
f7f8592d6d | ||
|
|
500eb25302 | ||
|
|
d074d20ad4 | ||
|
|
66e5d45994 | ||
|
|
e68fa65166 | ||
|
|
d5b11e6f94 | ||
|
|
51909d8bf8 | ||
|
|
299b6a4e31 | ||
|
|
a7407b28ce | ||
|
|
4397a37b31 | ||
|
|
996b02c2fe | ||
|
|
f27d667cec | ||
|
|
50c2a0fc99 | ||
|
|
9a7dad6a50 | ||
|
|
12e6caadce | ||
|
|
3cdfcd3819 | ||
|
|
87396313d6 | ||
|
|
48ee27dcd0 | ||
|
|
cb94c00a36 | ||
|
|
fa00277afe | ||
|
|
bf5565ea2c | ||
|
|
da6f0dd646 | ||
|
|
71dd4399fc | ||
|
|
08c0dad06f | ||
|
|
be9066bd7a | ||
|
|
13aa7e5e78 | ||
|
|
0dbcb08e64 | ||
|
|
a158d1dbb4 | ||
|
|
5742430337 | ||
|
|
75453db4ce | ||
|
|
458613c923 | ||
|
|
f29a47d577 | ||
|
|
4b6e156ddf | ||
|
|
5e26011caf | ||
|
|
4cd3369ed1 | ||
|
|
90b2fbea66 | ||
|
|
5b725c8a83 | ||
|
|
83e079322e | ||
|
|
cc0207c967 | ||
|
|
1f84d34371 | ||
|
|
f1808e1a0f | ||
|
|
07cc22bffa | ||
|
|
db0a936158 | ||
|
|
e1c1168db3 | ||
|
|
f5606f9855 | ||
|
|
d014becee2 | ||
|
|
b27c5481ef | ||
|
|
fe6288421f | ||
|
|
6e60f76825 | ||
|
|
5784ff5b46 | ||
|
|
d75fddda00 | ||
|
|
c17cf5f1f5 | ||
|
|
2fb05c54ad | ||
|
|
9555260a65 | ||
|
|
4ce6c8e1dc | ||
|
|
6677faed55 | ||
|
|
8a8838de29 | ||
|
|
fa453878c4 | ||
|
|
93072a2828 | ||
|
|
f52d191a69 | ||
|
|
84f36115e5 | ||
|
|
8dd0637645 | ||
|
|
4d6bca22cc | ||
|
|
7bb4146e58 | ||
|
|
ed5f3df612 | ||
|
|
f402668a4e | ||
|
|
f723380e32 | ||
|
|
1db823f451 | ||
|
|
fcd710e31d | ||
|
|
6922b336b0 | ||
|
|
6edf4343b2 | ||
|
|
81864f3c7f | ||
|
|
2a0c0a2598 | ||
|
|
3db4000c80 | ||
|
|
c7b33ceea9 | ||
|
|
e47a2cc34a | ||
|
|
aa77184ed5 | ||
|
|
58ff9e5188 | ||
|
|
a0bf1d13bb | ||
|
|
c47ab92f69 | ||
|
|
ad4b9529dc | ||
|
|
b5819be055 | ||
|
|
21dfefa0c3 | ||
|
|
4c013d1087 | ||
|
|
825b296d12 | ||
|
|
514b7743d6 | ||
|
|
5265110509 | ||
|
|
aa96bfcb27 | ||
|
|
c7f062aeca | ||
|
|
32eeffcd11 | ||
|
|
67a93b53a3 | ||
|
|
941024f193 | ||
|
|
127adf6acf | ||
|
|
ff3655c7cd | ||
|
|
b58c6402f9 | ||
|
|
0af7b9bb84 | ||
|
|
188cd1ef6b | ||
|
|
aa82e0132a | ||
|
|
dbd027c796 | ||
|
|
999baf9090 | ||
|
|
ce5b1e9235 | ||
|
|
ac29d9da5f | ||
|
|
44495acf4f | ||
|
|
29263b1b41 | ||
|
|
3d2e252e2c | ||
|
|
e1337244d3 | ||
|
|
885ea764a0 | ||
|
|
58a38d00e4 | ||
|
|
24a1554e3a | ||
|
|
d167c34753 | ||
|
|
4fd86afb89 | ||
|
|
a2aa9d1fc7 | ||
|
|
283cbc4df5 | ||
|
|
18d98dd215 | ||
|
|
3dee622df6 | ||
|
|
6b81eeb106 | ||
|
|
594bc072ae | ||
|
|
077259c08c | ||
|
|
168f210f34 | ||
|
|
a86dbfd723 | ||
|
|
daef61594c | ||
|
|
de7b174cec | ||
|
|
d6af4a90d5 | ||
|
|
ea6079c2ab | ||
|
|
3fbebd97cd | ||
|
|
b3f18d73f5 | ||
|
|
cfbe1ff69c |
@@ -35,7 +35,29 @@ AlignConsecutiveShortCaseStatements:
|
|||||||
Enabled: false
|
Enabled: false
|
||||||
AcrossEmptyLines: false
|
AcrossEmptyLines: false
|
||||||
AcrossComments: false
|
AcrossComments: false
|
||||||
|
AlignCaseArrows: false
|
||||||
AlignCaseColons: false
|
AlignCaseColons: false
|
||||||
|
AlignConsecutiveTableGenBreakingDAGArgColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveTableGenCondOperatorColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveTableGenDefinitionColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
AlignEscapedNewlines: Right
|
AlignEscapedNewlines: Right
|
||||||
AlignOperands: Align
|
AlignOperands: Align
|
||||||
AlignTrailingComments:
|
AlignTrailingComments:
|
||||||
@@ -45,6 +67,7 @@ AllowAllArgumentsOnNextLine: true
|
|||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowBreakBeforeNoexceptSpecifier: Never
|
AllowBreakBeforeNoexceptSpecifier: Never
|
||||||
AllowShortBlocksOnASingleLine: Never
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseExpressionOnASingleLine: true
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortCompoundRequirementOnASingleLine: true
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
AllowShortEnumsOnASingleLine: true
|
AllowShortEnumsOnASingleLine: true
|
||||||
@@ -53,9 +76,7 @@ AllowShortIfStatementsOnASingleLine: Never
|
|||||||
AllowShortLambdasOnASingleLine: All
|
AllowShortLambdasOnASingleLine: All
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
AlwaysBreakTemplateDeclarations: MultiLine
|
|
||||||
AttributeMacros:
|
AttributeMacros:
|
||||||
- __capability
|
- __capability
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
@@ -83,6 +104,7 @@ BraceWrapping:
|
|||||||
BreakAdjacentStringLiterals: true
|
BreakAdjacentStringLiterals: true
|
||||||
BreakAfterAttributes: Leave
|
BreakAfterAttributes: Leave
|
||||||
BreakAfterJavaFieldAnnotations: false
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakAfterReturnType: None
|
||||||
BreakArrays: true
|
BreakArrays: true
|
||||||
BreakBeforeBinaryOperators: None
|
BreakBeforeBinaryOperators: None
|
||||||
BreakBeforeConceptDeclarations: Always
|
BreakBeforeConceptDeclarations: Always
|
||||||
@@ -90,8 +112,10 @@ BreakBeforeBraces: Attach
|
|||||||
BreakBeforeInlineASMColon: OnlyMultiline
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
BreakBeforeTernaryOperators: true
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializers: BeforeColon
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakFunctionDefinitionParameters: false
|
||||||
BreakInheritanceList: BeforeColon
|
BreakInheritanceList: BeforeColon
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
|
BreakTemplateDeclarations: MultiLine
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
CompactNamespaces: false
|
CompactNamespaces: false
|
||||||
@@ -147,12 +171,15 @@ IntegerLiteralSeparator:
|
|||||||
HexMinDigits: 0
|
HexMinDigits: 0
|
||||||
JavaScriptQuotes: Leave
|
JavaScriptQuotes: Leave
|
||||||
JavaScriptWrapImports: true
|
JavaScriptWrapImports: true
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
KeepEmptyLines:
|
||||||
KeepEmptyLinesAtEOF: false
|
AtEndOfFile: false
|
||||||
|
AtStartOfBlock: false
|
||||||
|
AtStartOfFile: true
|
||||||
LambdaBodyIndentation: Signature
|
LambdaBodyIndentation: Signature
|
||||||
LineEnding: DeriveLF
|
LineEnding: DeriveLF
|
||||||
MacroBlockBegin: ''
|
MacroBlockBegin: ''
|
||||||
MacroBlockEnd: ''
|
MacroBlockEnd: ''
|
||||||
|
MainIncludeChar: Quote
|
||||||
MaxEmptyLinesToKeep: 1
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
ObjCBinPackProtocolList: Auto
|
ObjCBinPackProtocolList: Auto
|
||||||
@@ -221,6 +248,7 @@ SpacesInLineCommentPrefix:
|
|||||||
Maximum: -1
|
Maximum: -1
|
||||||
SpacesInParens: Never
|
SpacesInParens: Never
|
||||||
SpacesInParensOptions:
|
SpacesInParensOptions:
|
||||||
|
ExceptDoubleParentheses: false
|
||||||
InCStyleCasts: false
|
InCStyleCasts: false
|
||||||
InConditionalStatements: false
|
InConditionalStatements: false
|
||||||
InEmptyParentheses: false
|
InEmptyParentheses: false
|
||||||
@@ -235,6 +263,7 @@ StatementMacros:
|
|||||||
- munit_void_test_decl
|
- munit_void_test_decl
|
||||||
- nghttp2_max_def
|
- nghttp2_max_def
|
||||||
- nghttp2_min_def
|
- nghttp2_min_def
|
||||||
|
TableGenBreakInsideDAGArg: DontBreak
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
VerilogBreakBetweenInstancePorts: true
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
|||||||
24
.github/workflows/android.yml
vendored
Normal file
24
.github/workflows/android.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: android
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- Dockerfile.android
|
||||||
|
- .github/workflows/android.yml
|
||||||
|
branches:
|
||||||
|
- '**'
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
- name: Build
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
file: Dockerfile.android
|
||||||
95
.github/workflows/build.yml
vendored
95
.github/workflows/build.yml
vendored
@@ -5,26 +5,26 @@ on: [push, pull_request]
|
|||||||
permissions: read-all
|
permissions: read-all
|
||||||
|
|
||||||
env:
|
env:
|
||||||
LIBBPF_VERSION: v1.5.0
|
LIBBPF_VERSION: v1.6.2
|
||||||
OPENSSL1_VERSION: 1_1_1w+quic
|
OPENSSL1_VERSION: 1_1_1w+quic
|
||||||
OPENSSL3_VERSION: 3.1.7+quic
|
OPENSSL3_VERSION: 3.6.0
|
||||||
BORINGSSL_VERSION: 294ab9730c570213b496cfc2fc14b3c0bfcd4bcc
|
BORINGSSL_VERSION: db1a8456167249f95b854a1cd24c6b553d0f1567
|
||||||
AWSLC_VERSION: v1.46.1
|
AWSLC_VERSION: v1.62.0
|
||||||
NGHTTP3_VERSION: v1.8.0
|
NGHTTP3_VERSION: v1.12.0
|
||||||
NGTCP2_VERSION: v1.11.0
|
NGTCP2_VERSION: v1.17.0
|
||||||
WOLFSSL_VERSION: v5.7.6-stable
|
WOLFSSL_VERSION: v5.8.2-stable
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-cache:
|
build-cache:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-24.04, macos-13, macos-14]
|
os: [ubuntu-24.04, macos-14, macos-15]
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Restore libbpf cache
|
- name: Restore libbpf cache
|
||||||
id: cache-libbpf
|
id: cache-libbpf
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -49,8 +49,8 @@ jobs:
|
|||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
boringssl/build/crypto/libcrypto.a
|
boringssl/build/libcrypto.a
|
||||||
boringssl/build/ssl/libssl.a
|
boringssl/build/libssl.a
|
||||||
boringssl/include
|
boringssl/include
|
||||||
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
|
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
|
||||||
- name: Restore aws-lc cache
|
- name: Restore aws-lc cache
|
||||||
@@ -133,12 +133,12 @@ jobs:
|
|||||||
./config --prefix=$PWD/build
|
./config --prefix=$PWD/build
|
||||||
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
||||||
make install_sw
|
make install_sw
|
||||||
- name: Build quictls/openssl v3.x
|
- name: Build openssl/openssl v3.x
|
||||||
if: steps.cache-openssl3.outputs.cache-hit != 'true'
|
if: steps.cache-openssl3.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
git clone --recursive --shallow-submodules --depth 1 -b openssl-${{ env.OPENSSL3_VERSION }} https://github.com/quictls/openssl openssl3
|
git clone --recursive --shallow-submodules --depth 1 -b openssl-${{ env.OPENSSL3_VERSION }} https://github.com/openssl/openssl openssl3
|
||||||
cd openssl3
|
cd openssl3
|
||||||
./config enable-ktls --prefix=$PWD/build --libdir=$PWD/build/lib
|
./config enable-ktls --prefix=$PWD/build
|
||||||
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
||||||
make install_sw
|
make install_sw
|
||||||
- name: Build BoringSSL
|
- name: Build BoringSSL
|
||||||
@@ -190,7 +190,7 @@ jobs:
|
|||||||
./configure --prefix=$PWD/build --enable-lib-only \
|
./configure --prefix=$PWD/build --enable-lib-only \
|
||||||
PKG_CONFIG_PATH="../openssl1/build/lib/pkgconfig:../wolfssl/build/lib/pkgconfig" \
|
PKG_CONFIG_PATH="../openssl1/build/lib/pkgconfig:../wolfssl/build/lib/pkgconfig" \
|
||||||
BORINGSSL_CFLAGS="-I$PWD/../boringssl/include/" \
|
BORINGSSL_CFLAGS="-I$PWD/../boringssl/include/" \
|
||||||
BORINGSSL_LIBS="-L$PWD/../boringssl/build/ssl -lssl -L$PWD/../boringssl/build/crypto -lcrypto" \
|
BORINGSSL_LIBS="-L$PWD/../boringssl/build -lssl -lcrypto" \
|
||||||
--disable-dependency-tracking \
|
--disable-dependency-tracking \
|
||||||
--with-boringssl \
|
--with-boringssl \
|
||||||
--with-wolfssl
|
--with-wolfssl
|
||||||
@@ -203,7 +203,7 @@ jobs:
|
|||||||
cd ngtcp2-openssl3
|
cd ngtcp2-openssl3
|
||||||
autoreconf -i
|
autoreconf -i
|
||||||
./configure --prefix=$PWD/build --enable-lib-only \
|
./configure --prefix=$PWD/build --enable-lib-only \
|
||||||
PKG_CONFIG_PATH="../openssl3/build/lib/pkgconfig" \
|
PKG_CONFIG_PATH="../openssl3/build/lib64/pkgconfig:../openssl3/build/lib/pkgconfig" \
|
||||||
BORINGSSL_CFLAGS="-I$PWD/../aws-lc/include/" \
|
BORINGSSL_CFLAGS="-I$PWD/../aws-lc/include/" \
|
||||||
BORINGSSL_LIBS="-L$PWD/../aws-lc/build/ssl -lssl -L$PWD/../aws-lc/build/crypto -lcrypto" \
|
BORINGSSL_LIBS="-L$PWD/../aws-lc/build/ssl -lssl -L$PWD/../aws-lc/build/crypto -lcrypto" \
|
||||||
--disable-dependency-tracking \
|
--disable-dependency-tracking \
|
||||||
@@ -217,40 +217,36 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-24.04, macos-13, macos-14]
|
os: [ubuntu-24.04, macos-14, macos-15]
|
||||||
compiler: [gcc, clang]
|
compiler: [gcc, clang]
|
||||||
buildtool: [autotools, cmake]
|
buildtool: [autotools, cmake]
|
||||||
http3: [http3, no-http3]
|
http3: [http3, no-http3]
|
||||||
openssl: [openssl1, openssl3, boringssl, awslc, wolfssl]
|
openssl: [openssl1, openssl3, boringssl, awslc, wolfssl]
|
||||||
exclude:
|
exclude:
|
||||||
- os: macos-13
|
|
||||||
openssl: openssl3
|
|
||||||
- os: macos-14
|
|
||||||
openssl: openssl3
|
|
||||||
- http3: no-http3
|
- http3: no-http3
|
||||||
openssl: openssl3
|
openssl: openssl3
|
||||||
- os: macos-13
|
|
||||||
compiler: gcc
|
|
||||||
- os: macos-14
|
- os: macos-14
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
- # disable macos cmake because of include path issue
|
- os: macos-15
|
||||||
os: macos-13
|
compiler: gcc
|
||||||
buildtool: cmake
|
|
||||||
- # disable macos cmake because of include path issue
|
- # disable macos cmake because of include path issue
|
||||||
os: macos-14
|
os: macos-14
|
||||||
buildtool: cmake
|
buildtool: cmake
|
||||||
- os: macos-13
|
- # disable macos cmake because of include path issue
|
||||||
openssl: boringssl
|
os: macos-15
|
||||||
|
buildtool: cmake
|
||||||
- os: macos-14
|
- os: macos-14
|
||||||
openssl: boringssl
|
openssl: boringssl
|
||||||
|
- os: macos-15
|
||||||
|
openssl: boringssl
|
||||||
- openssl: boringssl
|
- openssl: boringssl
|
||||||
buildtool: cmake
|
buildtool: cmake
|
||||||
- openssl: boringssl
|
- openssl: boringssl
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
- os: macos-13
|
|
||||||
openssl: awslc
|
|
||||||
- os: macos-14
|
- os: macos-14
|
||||||
openssl: awslc
|
openssl: awslc
|
||||||
|
- os: macos-15
|
||||||
|
openssl: awslc
|
||||||
- openssl: awslc
|
- openssl: awslc
|
||||||
buildtool: cmake
|
buildtool: cmake
|
||||||
- openssl: awslc
|
- openssl: awslc
|
||||||
@@ -266,7 +262,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Linux setup
|
- name: Linux setup
|
||||||
@@ -275,7 +271,7 @@ jobs:
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install \
|
sudo apt-get install \
|
||||||
g++-14 \
|
g++-14 \
|
||||||
clang-18 \
|
clang-19 \
|
||||||
autoconf \
|
autoconf \
|
||||||
automake \
|
automake \
|
||||||
autotools-dev \
|
autotools-dev \
|
||||||
@@ -314,8 +310,8 @@ jobs:
|
|||||||
- name: Setup clang (Linux)
|
- name: Setup clang (Linux)
|
||||||
if: runner.os == 'Linux' && matrix.compiler == 'clang'
|
if: runner.os == 'Linux' && matrix.compiler == 'clang'
|
||||||
run: |
|
run: |
|
||||||
echo 'CC=clang-18' >> $GITHUB_ENV
|
echo 'CC=clang-19' >> $GITHUB_ENV
|
||||||
echo 'CXX=clang++-18' >> $GITHUB_ENV
|
echo 'CXX=clang++-19' >> $GITHUB_ENV
|
||||||
- name: Setup clang (MacOS)
|
- name: Setup clang (MacOS)
|
||||||
if: runner.os == 'macOS' && matrix.compiler == 'clang'
|
if: runner.os == 'macOS' && matrix.compiler == 'clang'
|
||||||
run: |
|
run: |
|
||||||
@@ -351,7 +347,7 @@ jobs:
|
|||||||
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
|
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
|
||||||
echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
|
echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
|
||||||
- name: Setup libev variables
|
- name: Setup libev variables
|
||||||
if: matrix.os == 'macos-14'
|
if: runner.os == 'macOS'
|
||||||
run: |
|
run: |
|
||||||
LIBEV_CFLAGS="-I/opt/homebrew/Cellar/libev/4.33/include"
|
LIBEV_CFLAGS="-I/opt/homebrew/Cellar/libev/4.33/include"
|
||||||
LIBEV_LIBS="-L/opt/homebrew/Cellar/libev/4.33/lib -lev"
|
LIBEV_LIBS="-L/opt/homebrew/Cellar/libev/4.33/lib -lev"
|
||||||
@@ -365,7 +361,7 @@ jobs:
|
|||||||
path: openssl1/build
|
path: openssl1/build
|
||||||
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL1_VERSION }}
|
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL1_VERSION }}
|
||||||
fail-on-cache-miss: true
|
fail-on-cache-miss: true
|
||||||
- name: Restore quictls/openssl v3.x cache
|
- name: Restore openssl/openssl v3.x cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
if: matrix.openssl == 'openssl3'
|
if: matrix.openssl == 'openssl3'
|
||||||
with:
|
with:
|
||||||
@@ -377,8 +373,8 @@ jobs:
|
|||||||
if: matrix.openssl == 'boringssl'
|
if: matrix.openssl == 'boringssl'
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
boringssl/build/crypto/libcrypto.a
|
boringssl/build/libcrypto.a
|
||||||
boringssl/build/ssl/libssl.a
|
boringssl/build/libssl.a
|
||||||
boringssl/include
|
boringssl/include
|
||||||
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
|
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
|
||||||
fail-on-cache-miss: true
|
fail-on-cache-miss: true
|
||||||
@@ -398,7 +394,7 @@ jobs:
|
|||||||
cd boringssl
|
cd boringssl
|
||||||
|
|
||||||
OPENSSL_CFLAGS="-I$PWD/include/"
|
OPENSSL_CFLAGS="-I$PWD/include/"
|
||||||
OPENSSL_LIBS="-L$PWD/build/ssl -lssl -L$PWD/build/crypto -lcrypto -pthread"
|
OPENSSL_LIBS="-L$PWD/build -lssl -lcrypto -pthread"
|
||||||
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --without-neverbleed --without-jemalloc --disable-examples"
|
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --without-neverbleed --without-jemalloc --disable-examples"
|
||||||
|
|
||||||
echo 'OPENSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
|
echo 'OPENSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
|
||||||
@@ -459,16 +455,16 @@ jobs:
|
|||||||
- name: Setup extra environment variables
|
- name: Setup extra environment variables
|
||||||
if: matrix.http3 == 'no-http3'
|
if: matrix.http3 == 'no-http3'
|
||||||
run: |
|
run: |
|
||||||
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PKG_CONFIG_PATH"
|
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib64/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib"
|
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib64 -Wl,-rpath,$PWD/openssl3/build/lib"
|
||||||
|
|
||||||
echo 'PKG_CONFIG_PATH='"$PKG_CONFIG_PATH" >> $GITHUB_ENV
|
echo 'PKG_CONFIG_PATH='"$PKG_CONFIG_PATH" >> $GITHUB_ENV
|
||||||
echo 'LDFLAGS='"$LDFLAGS" >> $GITHUB_ENV
|
echo 'LDFLAGS='"$LDFLAGS" >> $GITHUB_ENV
|
||||||
- name: Setup extra environment variables for HTTP/3
|
- name: Setup extra environment variables for HTTP/3
|
||||||
if: matrix.http3 == 'http3'
|
if: matrix.http3 == 'http3'
|
||||||
run: |
|
run: |
|
||||||
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2-openssl1/build/lib/pkgconfig:$PWD/ngtcp2-openssl3/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
|
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib64/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2-openssl1/build/lib/pkgconfig:$PWD/ngtcp2-openssl3/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
|
||||||
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
|
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib64 -Wl,-rpath,$PWD/openssl3/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
|
||||||
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --enable-http3"
|
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --enable-http3"
|
||||||
EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DENABLE_HTTP3=1"
|
EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DENABLE_HTTP3=1"
|
||||||
|
|
||||||
@@ -528,15 +524,16 @@ jobs:
|
|||||||
cd $NGHTTP2_BUILD_DIR
|
cd $NGHTTP2_BUILD_DIR
|
||||||
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
|
||||||
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
|
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v6
|
||||||
if: matrix.buildtool != 'distcheck'
|
if: matrix.buildtool != 'distcheck'
|
||||||
with:
|
with:
|
||||||
go-version: "1.22"
|
go-version: "1.24"
|
||||||
- name: Integration test
|
- name: Integration test
|
||||||
# Integration tests for nghttpx; autotools erases build
|
# Integration tests for nghttpx; autotools erases build
|
||||||
# artifacts.
|
# artifacts.
|
||||||
if: matrix.buildtool != 'distcheck'
|
if: matrix.buildtool != 'distcheck'
|
||||||
run: |
|
run: |
|
||||||
|
sudo sh -c 'echo "127.0.0.1 127.0.0.1.nip.io" >> /etc/hosts'
|
||||||
cd $NGHTTP2_BUILD_DIR/integration-tests
|
cd $NGHTTP2_BUILD_DIR/integration-tests
|
||||||
make it
|
make it
|
||||||
|
|
||||||
@@ -552,7 +549,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Prepare for i386
|
- name: Prepare for i386
|
||||||
@@ -600,7 +597,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- uses: microsoft/setup-msbuild@v2
|
- uses: microsoft/setup-msbuild@v2
|
||||||
@@ -625,7 +622,7 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
@@ -642,7 +639,7 @@ jobs:
|
|||||||
GPG_KEY: ${{ secrets.GPG_KEY }}
|
GPG_KEY: ${{ secrets.GPG_KEY }}
|
||||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||||
- name: Make release
|
- name: Make release
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v8
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
|||||||
2
.github/workflows/docker.yaml
vendored
2
.github/workflows/docker.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
2
.github/workflows/fuzz.yml
vendored
2
.github/workflows/fuzz.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
fuzz-seconds: 600
|
fuzz-seconds: 600
|
||||||
dry-run: false
|
dry-run: false
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v5
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|||||||
2
.github/workflows/stale.yaml
vendored
2
.github/workflows/stale.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9
|
- uses: actions/stale@v10
|
||||||
with:
|
with:
|
||||||
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||||
days-before-stale: 30
|
days-before-stale: 30
|
||||||
|
|||||||
7
AUTHORS
7
AUTHORS
@@ -80,6 +80,7 @@ Jonas Kvinge
|
|||||||
Josh Braegger
|
Josh Braegger
|
||||||
José F. Calcerrada
|
José F. Calcerrada
|
||||||
Kamil Dudka
|
Kamil Dudka
|
||||||
|
Karthik Dasari
|
||||||
Kazuho Oku
|
Kazuho Oku
|
||||||
Kenny (kang-yen) Peng
|
Kenny (kang-yen) Peng
|
||||||
Kenny Peng
|
Kenny Peng
|
||||||
@@ -89,6 +90,7 @@ LazyHamster
|
|||||||
Leo Neat
|
Leo Neat
|
||||||
Lorenz Nickel
|
Lorenz Nickel
|
||||||
Lucas Pardue
|
Lucas Pardue
|
||||||
|
Lukas Märdian
|
||||||
MATSUMOTO Ryosuke
|
MATSUMOTO Ryosuke
|
||||||
Marc Bachmann
|
Marc Bachmann
|
||||||
Marcelo Trylesinski
|
Marcelo Trylesinski
|
||||||
@@ -104,6 +106,7 @@ Nora Shoemaker
|
|||||||
Paweł Wegner
|
Paweł Wegner
|
||||||
Pedro Santos
|
Pedro Santos
|
||||||
Peeyush Aggarwal
|
Peeyush Aggarwal
|
||||||
|
Peng-Yu Chen
|
||||||
Peter Wu
|
Peter Wu
|
||||||
Piotr Sikora
|
Piotr Sikora
|
||||||
PufferOverflow
|
PufferOverflow
|
||||||
@@ -119,6 +122,7 @@ Ryan Carsten Schmidt
|
|||||||
Ryo Ota
|
Ryo Ota
|
||||||
Scott Mitchell
|
Scott Mitchell
|
||||||
Sebastiaan Deckers
|
Sebastiaan Deckers
|
||||||
|
Sergei Trofimovich
|
||||||
Sergey Fedorov
|
Sergey Fedorov
|
||||||
Shelley Vohr
|
Shelley Vohr
|
||||||
Simon Frankenberger
|
Simon Frankenberger
|
||||||
@@ -146,15 +150,18 @@ Ville Vesilehto
|
|||||||
Wenfeng Liu
|
Wenfeng Liu
|
||||||
William A Rowe Jr
|
William A Rowe Jr
|
||||||
Xiaoguang Sun
|
Xiaoguang Sun
|
||||||
|
Zachary Turner
|
||||||
Zhuoyun Wei
|
Zhuoyun Wei
|
||||||
acesso
|
acesso
|
||||||
ayanamist
|
ayanamist
|
||||||
|
bmarques1995
|
||||||
bxshi
|
bxshi
|
||||||
clemahieu
|
clemahieu
|
||||||
dalf
|
dalf
|
||||||
dawg
|
dawg
|
||||||
es
|
es
|
||||||
fangdingjun
|
fangdingjun
|
||||||
|
feicong
|
||||||
hrxi
|
hrxi
|
||||||
jwchoi
|
jwchoi
|
||||||
kumagi
|
kumagi
|
||||||
|
|||||||
@@ -24,13 +24,13 @@
|
|||||||
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
cmake_minimum_required(VERSION 3.14)
|
||||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||||
project(nghttp2 VERSION 1.65.0 LANGUAGES C)
|
project(nghttp2 VERSION 1.68.90 LANGUAGES C)
|
||||||
|
|
||||||
# See versioning rule:
|
# See versioning rule:
|
||||||
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
set(LT_CURRENT 42)
|
set(LT_CURRENT 43)
|
||||||
set(LT_REVISION 4)
|
set(LT_REVISION 2)
|
||||||
set(LT_AGE 28)
|
set(LT_AGE 29)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
include(Version)
|
include(Version)
|
||||||
@@ -71,20 +71,8 @@ if(WITH_WOLFSSL)
|
|||||||
else()
|
else()
|
||||||
find_package(OpenSSL 1.1.1)
|
find_package(OpenSSL 1.1.1)
|
||||||
endif()
|
endif()
|
||||||
find_package(Libngtcp2 1.0.0)
|
find_package(Libngtcp2 1.15.0)
|
||||||
if(OPENSSL_FOUND)
|
find_package(Libnghttp3 1.11.0)
|
||||||
find_package(Libngtcp2_crypto_quictls 1.0.0)
|
|
||||||
if(LIBNGTCP2_CRYPTO_QUICTLS_FOUND)
|
|
||||||
set(HAVE_LIBNGTCP2_CRYPTO_QUICTLS 1)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(WOLFSSL_FOUND)
|
|
||||||
find_package(Libngtcp2_crypto_wolfssl 1.0.0)
|
|
||||||
if(LIBNGTCP2_CRYPTO_WOLFSSL_FOUND)
|
|
||||||
set(HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
find_package(Libnghttp3 1.1.0)
|
|
||||||
if(WITH_LIBBPF)
|
if(WITH_LIBBPF)
|
||||||
find_package(Libbpf 0.7.0)
|
find_package(Libbpf 0.7.0)
|
||||||
if(NOT LIBBPF_FOUND)
|
if(NOT LIBBPF_FOUND)
|
||||||
@@ -155,10 +143,10 @@ if(NOT ENABLE_LIB_ONLY)
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <future>
|
#include <future>
|
||||||
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
|
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
|
||||||
# Check that std::map::emplace is available for g++-4.7.
|
# Check that std::chrono::time_zone is available.
|
||||||
check_cxx_source_compiles("
|
check_cxx_source_compiles("
|
||||||
#include <map>
|
#include <chrono>
|
||||||
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
|
int main() { auto tz = std::chrono::current_zone(); (void)tz; }" HAVE_STD_CHRONO_TIME_ZONE)
|
||||||
cmake_pop_check_state()
|
cmake_pop_check_state()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -196,10 +184,14 @@ if(NOT ENABLE_LIB_ONLY AND OPENSSL_FOUND)
|
|||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}" "ws2_32" "bcrypt")
|
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}" "ws2_32" "bcrypt")
|
||||||
endif()
|
endif()
|
||||||
|
check_symbol_exists("LIBRESSL_VERSION_NUMBER" "openssl/opensslv.h" LIBRESSL_FOUND)
|
||||||
if(ENABLE_HTTP3)
|
if(ENABLE_HTTP3)
|
||||||
check_symbol_exists(SSL_provide_quic_data "openssl/ssl.h" HAVE_SSL_PROVIDE_QUIC_DATA)
|
check_symbol_exists(SSL_provide_quic_data "openssl/ssl.h" HAVE_SSL_PROVIDE_QUIC_DATA)
|
||||||
if(NOT HAVE_SSL_PROVIDE_QUIC_DATA)
|
if(NOT HAVE_SSL_PROVIDE_QUIC_DATA)
|
||||||
message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} does not have SSL_provide_quic_data. HTTP/3 support cannot be enabled")
|
check_symbol_exists(SSL_set_quic_tls_cbs "openssl/ssl.h" HAVE_SSL_SET_QUIC_TLS_CBS)
|
||||||
|
if(NOT HAVE_SSL_SET_QUIC_TLS_CBS)
|
||||||
|
message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} has neither SSL_provide_quic_data nor SSL_set_quic_tls_cbs. HTTP/3 support cannot be enabled")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
cmake_pop_check_state()
|
cmake_pop_check_state()
|
||||||
@@ -279,12 +271,41 @@ if(ENABLE_APP AND NOT (ZLIB_FOUND AND (OPENSSL_FOUND OR WOLFSSL_FOUND) AND LIBEV
|
|||||||
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
|
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# HTTP/3 requires libngtcp2 + (quictls/openssl +
|
if(ENABLE_HTTP3)
|
||||||
# libngtcp2_crypto_quictls or wolfSSL + libngtcp2_crypto_wolfssl) and
|
if(HAVE_SSL_PROVIDE_QUIC_DATA AND NOT LIBRESSL_FOUND)
|
||||||
# libnghttp3.
|
find_package(Libngtcp2_crypto_quictls 1.15.0)
|
||||||
|
if(LIBNGTCP2_CRYPTO_QUICTLS_FOUND)
|
||||||
|
set(HAVE_LIBNGTCP2_CRYPTO_QUICTLS 1)
|
||||||
|
endif()
|
||||||
|
elseif(HAVE_SSL_PROVIDE_QUIC_DATA AND LIBRESSL_FOUND)
|
||||||
|
find_package(Libngtcp2_crypto_libressl 1.15.0)
|
||||||
|
if(LIBNGTCP2_CRYPTO_LIBRESSL_FOUND)
|
||||||
|
set(HAVE_LIBNGTCP2_CRYPTO_LIBRESSL 1)
|
||||||
|
endif()
|
||||||
|
elseif(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA)
|
||||||
|
find_package(Libngtcp2_crypto_wolfssl 1.15.0)
|
||||||
|
if(LIBNGTCP2_CRYPTO_WOLFSSL_FOUND)
|
||||||
|
set(HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1)
|
||||||
|
endif()
|
||||||
|
elseif(HAVE_SSL_SET_QUIC_TLS_CBS)
|
||||||
|
find_package(Libngtcp2_crypto_ossl 1.15.0)
|
||||||
|
if(LIBNGTCP2_CRYPTO_OSSL_FOUND)
|
||||||
|
set(HAVE_LIBNGTCP2_CRYPTO_OSSL 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# HTTP/3 requires libngtcp2 + nghttp3 + one of:
|
||||||
|
#
|
||||||
|
# - quictls/openssl + libngtcp2_crypto_quictls
|
||||||
|
# - libressl + libngtcp2_crypto_libressl
|
||||||
|
# - wolfSSL + libngtcp2_crypto_wolfssl
|
||||||
|
# - openssl/openssl + libngtcp2_crypto_ossl
|
||||||
if(ENABLE_HTTP3 AND NOT (LIBNGTCP2_FOUND AND LIBNGHTTP3_FOUND AND
|
if(ENABLE_HTTP3 AND NOT (LIBNGTCP2_FOUND AND LIBNGHTTP3_FOUND AND
|
||||||
((HAVE_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_QUICTLS_FOUND) OR
|
((HAVE_SSL_PROVIDE_QUIC_DATA AND NOT LIBRESSL_FOUND AND LIBNGTCP2_CRYPTO_QUICTLS_FOUND) OR
|
||||||
(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_WOLFSSL_FOUND))))
|
(HAVE_SSL_PROVIDE_QUIC_DATA AND LIBRESSL_FOUND AND LIBNGTCP2_CRYPTO_LIBRESSL_FOUND) OR
|
||||||
|
(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_WOLFSSL_FOUND) OR
|
||||||
|
(HAVE_SSL_SET_QUIC_TLS_CBS AND LIBNGTCP2_CRYPTO_OSSL_FOUND))))
|
||||||
message(FATAL_ERROR "HTTP/3 was requested (ENABLE_HTTP3=1) but dependencies are not met.")
|
message(FATAL_ERROR "HTTP/3 was requested (ENABLE_HTTP3=1) but dependencies are not met.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -361,7 +382,7 @@ check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
|||||||
check_function_exists(mkostemp HAVE_MKOSTEMP)
|
check_function_exists(mkostemp HAVE_MKOSTEMP)
|
||||||
check_function_exists(pipe2 HAVE_PIPE2)
|
check_function_exists(pipe2 HAVE_PIPE2)
|
||||||
|
|
||||||
check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64)
|
check_symbol_exists(GetTickCount64 "windows.h;sysinfoapi.h" HAVE_GETTICKCOUNT64)
|
||||||
|
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
||||||
@@ -478,7 +499,6 @@ if(ENABLE_DOC)
|
|||||||
add_subdirectory(doc)
|
add_subdirectory(doc)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(contrib)
|
add_subdirectory(contrib)
|
||||||
add_subdirectory(script)
|
|
||||||
add_subdirectory(bpf)
|
add_subdirectory(bpf)
|
||||||
|
|
||||||
|
|
||||||
@@ -512,6 +532,7 @@ message(STATUS "summary of build options:
|
|||||||
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
|
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
|
||||||
Libngtcp2: ${HAVE_LIBNGTCP2} (LIBS='${LIBNGTCP2_LIBRARIES}')
|
Libngtcp2: ${HAVE_LIBNGTCP2} (LIBS='${LIBNGTCP2_LIBRARIES}')
|
||||||
Libngtcp2_crypto_quictls: ${HAVE_LIBNGTCP2_CRYPTO_QUICTLS} (LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}')
|
Libngtcp2_crypto_quictls: ${HAVE_LIBNGTCP2_CRYPTO_QUICTLS} (LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}')
|
||||||
|
Libngtcp2_crypto_libressl: ${HAVE_LIBNGTCP2_CRYPTO_LIBRESSL} (LIBS='${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES}')
|
||||||
Libngtcp2_crypto_wolfssl: ${HAVE_LIBNGTCP2_CRYPTO_WOLFSSL} (LIBS='${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}')
|
Libngtcp2_crypto_wolfssl: ${HAVE_LIBNGTCP2_CRYPTO_WOLFSSL} (LIBS='${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}')
|
||||||
Libnghttp3: ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}')
|
Libnghttp3: ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}')
|
||||||
Libbpf: ${HAVE_LIBBPF} (LIBS='${LIBBPF_LIBRARIES}')
|
Libbpf: ${HAVE_LIBBPF} (LIBS='${LIBBPF_LIBRARIES}')
|
||||||
|
|||||||
@@ -12,21 +12,21 @@
|
|||||||
|
|
||||||
|
|
||||||
# Only use standalone-toolchain for reduce size
|
# Only use standalone-toolchain for reduce size
|
||||||
FROM ubuntu:22.04
|
FROM ubuntu:24.04
|
||||||
MAINTAINER Tatsuhiro Tsujikawa
|
LABEL org.opencontainers.image.authors="Tatsuhiro Tsujikawa"
|
||||||
|
|
||||||
ENV NDK_VERSION r26d
|
ARG NDK_VERSION=r27c
|
||||||
ENV NDK /root/android-ndk-$NDK_VERSION
|
ARG NDK=/root/android-ndk-$NDK_VERSION
|
||||||
ENV TOOLCHAIN $NDK/toolchains/llvm/prebuilt/linux-x86_64
|
ARG TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
|
||||||
ENV TARGET aarch64-linux-android
|
ARG TARGET=aarch64-linux-android
|
||||||
ENV API 33
|
ARG API=33
|
||||||
ENV AR $TOOLCHAIN/bin/llvm-ar
|
ARG AR=$TOOLCHAIN/bin/llvm-ar
|
||||||
ENV CC $TOOLCHAIN/bin/$TARGET$API-clang
|
ARG CC=$TOOLCHAIN/bin/$TARGET$API-clang
|
||||||
ENV CXX $TOOLCHAIN/bin/$TARGET$API-clang++
|
ARG CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
|
||||||
ENV LD $TOOLCHAIN/bin/ld
|
ARG LD=$TOOLCHAIN/bin/ld
|
||||||
ENV RANDLIB $TOOLCHAIN/bin/llvm-ranlib
|
ARG RANDLIB=$TOOLCHAIN/bin/llvm-ranlib
|
||||||
ENV STRIP $TOOLCHAIN/bin/llvm-strip
|
ARG STRIP=$TOOLCHAIN/bin/llvm-strip
|
||||||
ENV PREFIX /root/usr/local
|
ARG PREFIX=/root/usr/local
|
||||||
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
@@ -42,11 +42,11 @@ RUN curl -L -O https://dl.google.com/android/repository/android-ndk-$NDK_VERSION
|
|||||||
rm android-ndk-$NDK_VERSION-linux.zip
|
rm android-ndk-$NDK_VERSION-linux.zip
|
||||||
|
|
||||||
# Setup version of libraries
|
# Setup version of libraries
|
||||||
ENV OPENSSL_VERSION 1.1.1w
|
ARG OPENSSL_VERSION=1.1.1w
|
||||||
ENV LIBEV_VERSION 4.33
|
ARG LIBEV_VERSION=4.33
|
||||||
ENV ZLIB_VERSION 1.3.1
|
ARG ZLIB_VERSION=1.3.1
|
||||||
ENV CARES_VERSION 1.18.1
|
ARG CARES_VERSION=1.18.1
|
||||||
ENV NGHTTP2_VERSION master
|
ARG NGHTTP2_VERSION=master
|
||||||
|
|
||||||
WORKDIR /root/build
|
WORKDIR /root/build
|
||||||
RUN curl -L -O https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz && \
|
RUN curl -L -O https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz && \
|
||||||
@@ -105,7 +105,7 @@ RUN ./configure \
|
|||||||
make install
|
make install
|
||||||
|
|
||||||
WORKDIR /root/build
|
WORKDIR /root/build
|
||||||
RUN git clone https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
|
RUN git clone --recursive --shallow-submodules https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
|
||||||
WORKDIR /root/build/nghttp2
|
WORKDIR /root/build/nghttp2
|
||||||
RUN autoreconf -i && \
|
RUN autoreconf -i && \
|
||||||
./configure \
|
./configure \
|
||||||
@@ -119,6 +119,6 @@ RUN autoreconf -i && \
|
|||||||
--disable-threads \
|
--disable-threads \
|
||||||
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
||||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||||
LDFLAGS="-fPIE -pie -L$PREFIX/lib" && \
|
LDFLAGS="-static-libstdc++ -static-libgcc -fPIE -pie -L$PREFIX/lib" && \
|
||||||
make && \
|
make && \
|
||||||
$STRIP src/nghttpx src/nghttpd src/nghttp
|
$STRIP src/nghttpx src/nghttpd src/nghttp
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
SUBDIRS = lib third-party src bpf examples tests integration-tests \
|
SUBDIRS = lib tests third-party src bpf examples integration-tests \
|
||||||
doc contrib script
|
doc contrib
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-env \
|
|||||||
cmake/FindLibbrotlienc.cmake \
|
cmake/FindLibbrotlienc.cmake \
|
||||||
cmake/FindLibbrotlidec.cmake \
|
cmake/FindLibbrotlidec.cmake \
|
||||||
cmake/FindLibngtcp2_crypto_wolfssl.cmake \
|
cmake/FindLibngtcp2_crypto_wolfssl.cmake \
|
||||||
|
cmake/FindLibngtcp2_crypto_ossl.cmake \
|
||||||
cmake/FindWolfSSL.cmake \
|
cmake/FindWolfSSL.cmake \
|
||||||
cmake/PickyWarningsC.cmake \
|
cmake/PickyWarningsC.cmake \
|
||||||
cmake/PickyWarningsCXX.cmake
|
cmake/PickyWarningsCXX.cmake
|
||||||
|
|||||||
33
README.rst
33
README.rst
@@ -31,9 +31,8 @@ implementation.
|
|||||||
|
|
||||||
* https://nghttp2.org/ (TLS + ALPN and HTTP/3)
|
* https://nghttp2.org/ (TLS + ALPN and HTTP/3)
|
||||||
|
|
||||||
This endpoint supports ``h2``, ``h2-16``, ``h2-14``, and
|
This endpoint supports ``h2`` and ``http/1.1`` via ALPN and requires
|
||||||
``http/1.1`` via ALPN and requires TLSv1.2 for HTTP/2
|
TLSv1.2 for HTTP/2 connection.
|
||||||
connection.
|
|
||||||
|
|
||||||
It also supports HTTP/3.
|
It also supports HTTP/3.
|
||||||
|
|
||||||
@@ -123,13 +122,13 @@ exploited. The neverbleed is disabled by default. To enable it, use
|
|||||||
To enable the experimental HTTP/3 support for h2load and nghttpx, the
|
To enable the experimental HTTP/3 support for h2load and nghttpx, the
|
||||||
following libraries are required:
|
following libraries are required:
|
||||||
|
|
||||||
* `OpenSSL with QUIC support
|
* `quictls
|
||||||
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1w+quic>`_; or
|
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1w+quic>`_; or
|
||||||
wolfSSL; or LibreSSL (does not support 0RTT); or aws-lc; or
|
wolfSSL; or LibreSSL (does not support 0RTT); or aws-lc; or
|
||||||
`BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
|
`BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
|
||||||
294ab9730c570213b496cfc2fc14b3c0bfcd4bcc)
|
db1a8456167249f95b854a1cd24c6b553d0f1567); or OpenSSL >= 3.5.0
|
||||||
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ >= 1.4.0
|
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ >= 1.16.0
|
||||||
* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ >= 1.1.0
|
* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ >= 1.12.0
|
||||||
|
|
||||||
Use ``--enable-http3`` configure option to enable HTTP/3 feature for
|
Use ``--enable-http3`` configure option to enable HTTP/3 feature for
|
||||||
h2load and nghttpx.
|
h2load and nghttpx.
|
||||||
@@ -151,7 +150,7 @@ executable.
|
|||||||
Compiling libnghttp2 C source code requires a C99 compiler. gcc 4.8
|
Compiling libnghttp2 C source code requires a C99 compiler. gcc 4.8
|
||||||
is known to be adequate. In order to compile the C++ source code,
|
is known to be adequate. In order to compile the C++ source code,
|
||||||
C++20 compliant compiler is required. At least g++ >= 12 and
|
C++20 compliant compiler is required. At least g++ >= 12 and
|
||||||
clang++ >= 15 are known to work.
|
clang++ >= 18 are known to work.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
@@ -341,7 +340,7 @@ Build aws-lc:
|
|||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
$ git clone --depth 1 -b v1.46.1 https://github.com/aws/aws-lc
|
$ git clone --depth 1 -b v1.62.0 https://github.com/aws/aws-lc
|
||||||
$ cd aws-lc
|
$ cd aws-lc
|
||||||
$ cmake -B build -DDISABLE_GO=ON --install-prefix=$PWD/opt
|
$ cmake -B build -DDISABLE_GO=ON --install-prefix=$PWD/opt
|
||||||
$ make -j$(nproc) -C build
|
$ make -j$(nproc) -C build
|
||||||
@@ -352,7 +351,7 @@ Build nghttp3:
|
|||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
$ git clone --depth 1 -b v1.8.0 https://github.com/ngtcp2/nghttp3
|
$ git clone --depth 1 -b v1.12.0 https://github.com/ngtcp2/nghttp3
|
||||||
$ cd nghttp3
|
$ cd nghttp3
|
||||||
$ git submodule update --init --depth 1
|
$ git submodule update --init --depth 1
|
||||||
$ autoreconf -i
|
$ autoreconf -i
|
||||||
@@ -365,7 +364,7 @@ Build ngtcp2:
|
|||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
$ git clone --depth 1 -b v1.11.0 https://github.com/ngtcp2/ngtcp2
|
$ git clone --depth 1 -b v1.17.0 https://github.com/ngtcp2/ngtcp2
|
||||||
$ cd ngtcp2
|
$ cd ngtcp2
|
||||||
$ git submodule update --init --depth 1
|
$ git submodule update --init --depth 1
|
||||||
$ autoreconf -i
|
$ autoreconf -i
|
||||||
@@ -381,7 +380,7 @@ from source:
|
|||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
$ git clone --depth 1 -b v1.5.0 https://github.com/libbpf/libbpf
|
$ git clone --depth 1 -b v1.6.2 https://github.com/libbpf/libbpf
|
||||||
$ cd libbpf
|
$ cd libbpf
|
||||||
$ PREFIX=$PWD/build make -C src install
|
$ PREFIX=$PWD/build make -C src install
|
||||||
$ cd ..
|
$ cd ..
|
||||||
@@ -395,7 +394,7 @@ Build nghttp2:
|
|||||||
$ git submodule update --init
|
$ git submodule update --init
|
||||||
$ autoreconf -i
|
$ autoreconf -i
|
||||||
$ ./configure --with-mruby --enable-http3 --with-libbpf \
|
$ ./configure --with-mruby --enable-http3 --with-libbpf \
|
||||||
CC=clang-15 CXX=clang++-15 \
|
CC=clang-19 CXX=clang++-19 \
|
||||||
PKG_CONFIG_PATH="$PWD/../aws-lc/opt/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/../libbpf/build/lib64/pkgconfig" \
|
PKG_CONFIG_PATH="$PWD/../aws-lc/opt/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/../libbpf/build/lib64/pkgconfig" \
|
||||||
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../aws-lc/opt/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
|
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../aws-lc/opt/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
|
||||||
$ make -j$(nproc)
|
$ make -j$(nproc)
|
||||||
@@ -847,10 +846,10 @@ to know how to migrate from earlier releases.
|
|||||||
|
|
||||||
``nghttpx`` implements `important performance-oriented features
|
``nghttpx`` implements `important performance-oriented features
|
||||||
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
|
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
|
||||||
session IDs, session tickets (with automatic key rotation), OCSP
|
session IDs, session tickets (with automatic key rotation), dynamic
|
||||||
stapling, dynamic record sizing, ALPN, forward secrecy and HTTP/2.
|
record sizing, ALPN, forward secrecy and HTTP/2. ``nghttpx`` also
|
||||||
``nghttpx`` also offers the functionality to share session cache and
|
offers the functionality to share ticket keys among multiple
|
||||||
ticket keys among multiple ``nghttpx`` instances via memcached.
|
``nghttpx`` instances via memcached.
|
||||||
|
|
||||||
``nghttpx`` has 2 operation modes:
|
``nghttpx`` has 2 operation modes:
|
||||||
|
|
||||||
|
|||||||
43
cmake/FindLibngtcp2_crypto_libressl.cmake
Normal file
43
cmake/FindLibngtcp2_crypto_libressl.cmake
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# - Try to find libngtcp2_crypto_libressl
|
||||||
|
# Once done this will define
|
||||||
|
# LIBNGTCP2_CRYPTO_LIBRESSL_FOUND - System has libngtcp2_crypto_libressl
|
||||||
|
# LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS - The libngtcp2_crypto_libressl include directories
|
||||||
|
# LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_libressl
|
||||||
|
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_LIBRESSL QUIET libngtcp2_crypto_libressl)
|
||||||
|
|
||||||
|
find_path(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
|
||||||
|
NAMES ngtcp2/ngtcp2_crypto_quictls.h
|
||||||
|
HINTS ${PC_LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
find_library(LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY
|
||||||
|
NAMES ngtcp2_crypto_libressl
|
||||||
|
HINTS ${PC_LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR)
|
||||||
|
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
|
||||||
|
file(STRINGS "${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR}/ngtcp2/version.h"
|
||||||
|
LIBNGTCP2_CRYPTO_LIBRESSL_VERSION REGEX "${_version_regex}")
|
||||||
|
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||||
|
LIBNGTCP2_CRYPTO_LIBRESSL_VERSION "${LIBNGTCP2_CRYPTO_LIBRESSL_VERSION}")
|
||||||
|
unset(_version_regex)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set
|
||||||
|
# LIBNGTCP2_CRYPTO_LIBRESSL_FOUND to TRUE if all listed variables are
|
||||||
|
# TRUE and the requested version matches.
|
||||||
|
find_package_handle_standard_args(Libngtcp2_crypto_libressl REQUIRED_VARS
|
||||||
|
LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY
|
||||||
|
LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
|
||||||
|
VERSION_VAR LIBNGTCP2_CRYPTO_LIBRESSL_VERSION)
|
||||||
|
|
||||||
|
if(LIBNGTCP2_CRYPTO_LIBRESSL_FOUND)
|
||||||
|
set(LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES ${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY})
|
||||||
|
set(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
|
||||||
|
LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY)
|
||||||
43
cmake/FindLibngtcp2_crypto_ossl.cmake
Normal file
43
cmake/FindLibngtcp2_crypto_ossl.cmake
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# - Try to find libngtcp2_crypto_ossl
|
||||||
|
# Once done this will define
|
||||||
|
# LIBNGTCP2_CRYPTO_OSSL_FOUND - System has libngtcp2_crypto_ossl
|
||||||
|
# LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS - The libngtcp2_crypto_ossl include directories
|
||||||
|
# LIBNGTCP2_CRYPTO_OSSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_ossl
|
||||||
|
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_OSSL QUIET libngtcp2_crypto_ossl)
|
||||||
|
|
||||||
|
find_path(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
|
||||||
|
NAMES ngtcp2/ngtcp2_crypto_ossl.h
|
||||||
|
HINTS ${PC_LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
find_library(LIBNGTCP2_CRYPTO_OSSL_LIBRARY
|
||||||
|
NAMES ngtcp2_crypto_ossl
|
||||||
|
HINTS ${PC_LIBNGTCP2_CRYPTO_OSSL_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR)
|
||||||
|
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
|
||||||
|
file(STRINGS "${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR}/ngtcp2/version.h"
|
||||||
|
LIBNGTCP2_CRYPTO_OSSL_VERSION REGEX "${_version_regex}")
|
||||||
|
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||||
|
LIBNGTCP2_CRYPTO_OSSL_VERSION "${LIBNGTCP2_CRYPTO_OSSL_VERSION}")
|
||||||
|
unset(_version_regex)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set
|
||||||
|
# LIBNGTCP2_CRYPTO_OSSL_FOUND to TRUE if all listed variables are
|
||||||
|
# TRUE and the requested version matches.
|
||||||
|
find_package_handle_standard_args(Libngtcp2_crypto_ossl REQUIRED_VARS
|
||||||
|
LIBNGTCP2_CRYPTO_OSSL_LIBRARY
|
||||||
|
LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
|
||||||
|
VERSION_VAR LIBNGTCP2_CRYPTO_OSSL_VERSION)
|
||||||
|
|
||||||
|
if(LIBNGTCP2_CRYPTO_OSSL_FOUND)
|
||||||
|
set(LIBNGTCP2_CRYPTO_OSSL_LIBRARIES ${LIBNGTCP2_CRYPTO_OSSL_LIBRARY})
|
||||||
|
set(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
|
||||||
|
LIBNGTCP2_CRYPTO_OSSL_LIBRARY)
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
/* Define to `int' if <sys/types.h> does not define. */
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
#cmakedefine ssize_t @ssize_t@
|
#cmakedefine ssize_t @ssize_t@
|
||||||
|
|
||||||
/* Define to 1 if you have the `std::map::emplace`. */
|
/* Define to 1 if you have the `std::chrono::time_zone`. */
|
||||||
#cmakedefine HAVE_STD_MAP_EMPLACE 1
|
#cmakedefine HAVE_STD_CHRONO_TIME_ZONE 1
|
||||||
|
|
||||||
/* Define to 1 if you have `libjansson` library. */
|
/* Define to 1 if you have `libjansson` library. */
|
||||||
#cmakedefine HAVE_JANSSON 1
|
#cmakedefine HAVE_JANSSON 1
|
||||||
@@ -100,6 +100,9 @@
|
|||||||
/* Define to 1 if you have `libngtcp2_crypto_quictls` library. */
|
/* Define to 1 if you have `libngtcp2_crypto_quictls` library. */
|
||||||
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_QUICTLS
|
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_QUICTLS
|
||||||
|
|
||||||
|
/* Define to 1 if you have `libngtcp2_crypto_libressl` library. */
|
||||||
|
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_LIBRESSL
|
||||||
|
|
||||||
/* Define to 1 if you have `libngtcp2_crypto_wolfssl` library. */
|
/* Define to 1 if you have `libngtcp2_crypto_wolfssl` library. */
|
||||||
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1
|
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1
|
||||||
|
|
||||||
|
|||||||
124
configure.ac
124
configure.ac
@@ -25,7 +25,7 @@ dnl Do not change user variables!
|
|||||||
dnl https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
dnl https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||||
|
|
||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
AC_INIT([nghttp2], [1.65.0], [t-tujikawa@users.sourceforge.net])
|
AC_INIT([nghttp2], [1.69.0-DEV], [t-tujikawa@users.sourceforge.net])
|
||||||
AC_CONFIG_AUX_DIR([.])
|
AC_CONFIG_AUX_DIR([.])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
@@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
|||||||
|
|
||||||
dnl See versioning rule:
|
dnl See versioning rule:
|
||||||
dnl https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
dnl https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
AC_SUBST(LT_CURRENT, 42)
|
AC_SUBST(LT_CURRENT, 43)
|
||||||
AC_SUBST(LT_REVISION, 4)
|
AC_SUBST(LT_REVISION, 2)
|
||||||
AC_SUBST(LT_AGE, 28)
|
AC_SUBST(LT_AGE, 29)
|
||||||
|
|
||||||
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
||||||
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
||||||
@@ -272,22 +272,6 @@ std::vector<std::future<int>> v;
|
|||||||
[have_std_future=no
|
[have_std_future=no
|
||||||
AC_MSG_RESULT([no])])
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
# Check that std::map::emplace is available for g++-4.7.
|
|
||||||
AC_MSG_CHECKING([whether std::map::emplace is available])
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
|
||||||
[[
|
|
||||||
#include <map>
|
|
||||||
]],
|
|
||||||
[[
|
|
||||||
std::map<int, int>().emplace(1, 2);
|
|
||||||
]])],
|
|
||||||
[AC_DEFINE([HAVE_STD_MAP_EMPLACE], [1],
|
|
||||||
[Define to 1 if you have the `std::map::emplace`.])
|
|
||||||
have_std_map_emplace=yes
|
|
||||||
AC_MSG_RESULT([yes])],
|
|
||||||
[have_std_map_emplace=no
|
|
||||||
AC_MSG_RESULT([no])])
|
|
||||||
|
|
||||||
# Check that std::atomic<std::shared_ptr<T>> is supported.
|
# Check that std::atomic<std::shared_ptr<T>> is supported.
|
||||||
AC_MSG_CHECKING([whether std::atomic<std::shared_ptr<T>> is supported])
|
AC_MSG_CHECKING([whether std::atomic<std::shared_ptr<T>> is supported])
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||||
@@ -307,19 +291,21 @@ a.store(p);
|
|||||||
[have_atomic_std_shared_ptr=no
|
[have_atomic_std_shared_ptr=no
|
||||||
AC_MSG_RESULT([no])])
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
# Check that thread_local storage specifier is available
|
# Check that std::chrono::time_zone is available.
|
||||||
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
|
AC_MSG_CHECKING([whether std::chrono::time_zone is available])
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||||
,
|
|
||||||
[[
|
[[
|
||||||
thread_local int a = 0;
|
#include <chrono>
|
||||||
(void)a;
|
]],
|
||||||
|
[[
|
||||||
|
auto tz = std::chrono::current_zone();
|
||||||
|
(void)tz;
|
||||||
]])],
|
]])],
|
||||||
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
|
[AC_DEFINE([HAVE_STD_CHRONO_TIME_ZONE], [1],
|
||||||
[Define to 1 if you have thread_local storage specifier.])
|
[Define to 1 if you have the `std::chrono::time_zone`.])
|
||||||
have_thread_local=yes
|
have_std_chrono_time_zone=yes
|
||||||
AC_MSG_RESULT([yes])],
|
AC_MSG_RESULT([yes])],
|
||||||
[have_Thread_local=no
|
[have_std_chrono_time_zone=no
|
||||||
AC_MSG_RESULT([no])])
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
CXXFLAGS=$save_CXXFLAGS
|
CXXFLAGS=$save_CXXFLAGS
|
||||||
@@ -450,6 +436,22 @@ if test "x${request_openssl}" != "xno" &&
|
|||||||
[AC_MSG_RESULT([yes]); have_ssl_provide_quic_data=yes],
|
[AC_MSG_RESULT([yes]); have_ssl_provide_quic_data=yes],
|
||||||
[AC_MSG_RESULT([no]); have_ssl_provide_quic_data=no])
|
[AC_MSG_RESULT([no]); have_ssl_provide_quic_data=no])
|
||||||
|
|
||||||
|
# Check whether this is libressl or not
|
||||||
|
AC_CHECK_DECLS([LIBRESSL_VERSION_NUMBER],
|
||||||
|
[have_libressl=yes], [have_libressl=no],
|
||||||
|
[[
|
||||||
|
#include <openssl/opensslv.h>
|
||||||
|
]])
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for SSL_set_quic_tls_cbs])
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
]], [[
|
||||||
|
SSL_set_quic_tls_cbs(NULL, NULL, NULL);
|
||||||
|
]])],
|
||||||
|
[AC_MSG_RESULT([yes]); have_ossl_quic=yes],
|
||||||
|
[AC_MSG_RESULT([no]); have_ossl_quic=no])
|
||||||
|
|
||||||
# boringssl has SSL_set_quic_early_data_context.
|
# boringssl has SSL_set_quic_early_data_context.
|
||||||
AC_MSG_CHECKING([for SSL_set_quic_early_data_context])
|
AC_MSG_CHECKING([for SSL_set_quic_early_data_context])
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||||
@@ -530,7 +532,7 @@ fi
|
|||||||
# ngtcp2 (for src)
|
# ngtcp2 (for src)
|
||||||
have_libngtcp2=no
|
have_libngtcp2=no
|
||||||
if test "x${request_libngtcp2}" != "xno"; then
|
if test "x${request_libngtcp2}" != "xno"; then
|
||||||
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 1.4.0], [have_libngtcp2=yes],
|
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 1.16.0], [have_libngtcp2=yes],
|
||||||
[have_libngtcp2=no])
|
[have_libngtcp2=no])
|
||||||
if test "x${have_libngtcp2}" = "xno"; then
|
if test "x${have_libngtcp2}" = "xno"; then
|
||||||
AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
|
AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
|
||||||
@@ -547,7 +549,7 @@ have_libngtcp2_crypto_wolfssl=no
|
|||||||
if test "x${have_wolfssl_quic}" = "xyes" &&
|
if test "x${have_wolfssl_quic}" = "xyes" &&
|
||||||
test "x${request_libngtcp2}" != "xno"; then
|
test "x${request_libngtcp2}" != "xno"; then
|
||||||
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_WOLFSSL],
|
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_WOLFSSL],
|
||||||
[libngtcp2_crypto_wolfssl >= 1.0.0],
|
[libngtcp2_crypto_wolfssl >= 1.16.0],
|
||||||
[have_libngtcp2_crypto_wolfssl=yes],
|
[have_libngtcp2_crypto_wolfssl=yes],
|
||||||
[have_libngtcp2_crypto_wolfssl=no])
|
[have_libngtcp2_crypto_wolfssl=no])
|
||||||
if test "x${have_libngtcp2_crypto_wolfssl}" = "xno"; then
|
if test "x${have_libngtcp2_crypto_wolfssl}" = "xno"; then
|
||||||
@@ -567,10 +569,11 @@ fi
|
|||||||
# ngtcp2_crypto_quictls (for src)
|
# ngtcp2_crypto_quictls (for src)
|
||||||
have_libngtcp2_crypto_quictls=no
|
have_libngtcp2_crypto_quictls=no
|
||||||
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
||||||
|
test "x${have_libressl}" != "xyes" &&
|
||||||
test "x${have_boringssl_quic}" != "xyes" &&
|
test "x${have_boringssl_quic}" != "xyes" &&
|
||||||
test "x${request_libngtcp2}" != "xno"; then
|
test "x${request_libngtcp2}" != "xno"; then
|
||||||
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_QUICTLS],
|
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_QUICTLS],
|
||||||
[libngtcp2_crypto_quictls >= 1.0.0],
|
[libngtcp2_crypto_quictls >= 1.16.0],
|
||||||
[have_libngtcp2_crypto_quictls=yes],
|
[have_libngtcp2_crypto_quictls=yes],
|
||||||
[have_libngtcp2_crypto_quictls=no])
|
[have_libngtcp2_crypto_quictls=no])
|
||||||
if test "x${have_libngtcp2_crypto_quictls}" = "xno"; then
|
if test "x${have_libngtcp2_crypto_quictls}" = "xno"; then
|
||||||
@@ -582,12 +585,37 @@ if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
||||||
|
test "x${have_libressl}" != "xyes" &&
|
||||||
test "x${have_boringssl_quic}" != "xyes" &&
|
test "x${have_boringssl_quic}" != "xyes" &&
|
||||||
test "x${request_libngtcp2}" = "xyes" &&
|
test "x${request_libngtcp2}" = "xyes" &&
|
||||||
test "x${have_libngtcp2_crypto_quictls}" != "xyes"; then
|
test "x${have_libngtcp2_crypto_quictls}" != "xyes"; then
|
||||||
AC_MSG_ERROR([libngtcp2_crypto_quictls was requested (--with-libngtcp2) but not found])
|
AC_MSG_ERROR([libngtcp2_crypto_quictls was requested (--with-libngtcp2) but not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ngtcp2_crypto_libressl (for src)
|
||||||
|
have_libngtcp2_crypto_libressl=no
|
||||||
|
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
||||||
|
test "x${have_libressl}" = "xyes" &&
|
||||||
|
test "x${request_libngtcp2}" != "xno"; then
|
||||||
|
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_LIBRESSL],
|
||||||
|
[libngtcp2_crypto_libressl >= 1.16.0],
|
||||||
|
[have_libngtcp2_crypto_libressl=yes],
|
||||||
|
[have_libngtcp2_crypto_libressl=no])
|
||||||
|
if test "x${have_libngtcp2_crypto_libressl}" = "xno"; then
|
||||||
|
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_LIBRESSL_PKG_ERRORS)
|
||||||
|
else
|
||||||
|
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_LIBRESSL], [1],
|
||||||
|
[Define to 1 if you have `libngtcp2_crypto_libressl` library.])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
|
||||||
|
test "x${have_libressl}" = "xyes" &&
|
||||||
|
test "x${request_libngtcp2}" = "xyes" &&
|
||||||
|
test "x${have_libngtcp2_crypto_libressl}" != "xyes"; then
|
||||||
|
AC_MSG_ERROR([libngtcp2_crypto_libressl was requested (--with-libngtcp2) but not found])
|
||||||
|
fi
|
||||||
|
|
||||||
# ngtcp2_crypto_boringssl (for src)
|
# ngtcp2_crypto_boringssl (for src)
|
||||||
have_libngtcp2_crypto_boringssl=no
|
have_libngtcp2_crypto_boringssl=no
|
||||||
if test "x${have_boringssl_quic}" = "xyes" &&
|
if test "x${have_boringssl_quic}" = "xyes" &&
|
||||||
@@ -610,10 +638,32 @@ if test "x${have_boringssl_quic}" = "xyes" &&
|
|||||||
AC_MSG_ERROR([libngtcp2_crypto_boringssl was requested (--with-libngtcp2) but not found])
|
AC_MSG_ERROR([libngtcp2_crypto_boringssl was requested (--with-libngtcp2) but not found])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ngtcp2_crypto_ossl (for src)
|
||||||
|
have_libngtcp2_crypto_ossl=no
|
||||||
|
if test "x${have_ossl_quic}" = "xyes" &&
|
||||||
|
test "x${request_libngtcp2}" != "xno"; then
|
||||||
|
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OSSL],
|
||||||
|
[libngtcp2_crypto_ossl >= 1.16.0],
|
||||||
|
[have_libngtcp2_crypto_ossl=yes],
|
||||||
|
[have_libngtcp2_crypto_ossl=no])
|
||||||
|
if test "x${have_libngtcp2_crypto_ossl}" = "xno"; then
|
||||||
|
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OSSL_PKG_ERRORS)
|
||||||
|
else
|
||||||
|
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_OSSL], [1],
|
||||||
|
[Define to 1 if you have `libngtcp2_crypto_ossl` library.])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x${have_ossl_quic}" = "xyes" &&
|
||||||
|
test "x${request_libngtcp2}" = "xyes" &&
|
||||||
|
test "x${have_libngtcp2_crypto_ossl}" != "xyes"; then
|
||||||
|
AC_MSG_ERROR([libngtcp2_crypto_ossl was requested (--with-libngtcp2) but not found])
|
||||||
|
fi
|
||||||
|
|
||||||
# nghttp3 (for src)
|
# nghttp3 (for src)
|
||||||
have_libnghttp3=no
|
have_libnghttp3=no
|
||||||
if test "x${request_libnghttp3}" != "xno"; then
|
if test "x${request_libnghttp3}" != "xno"; then
|
||||||
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 1.1.0], [have_libnghttp3=yes],
|
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 1.12.0], [have_libnghttp3=yes],
|
||||||
[have_libnghttp3=no])
|
[have_libnghttp3=no])
|
||||||
if test "x${have_libnghttp3}" = "xno"; then
|
if test "x${have_libnghttp3}" = "xno"; then
|
||||||
AC_MSG_NOTICE($LIBNGHTTP3_PKG_ERRORS)
|
AC_MSG_NOTICE($LIBNGHTTP3_PKG_ERRORS)
|
||||||
@@ -842,7 +892,9 @@ if test "x${request_http3}" != "xno" &&
|
|||||||
test "x${have_libngtcp2}" = "xyes" &&
|
test "x${have_libngtcp2}" = "xyes" &&
|
||||||
(test "x${have_libngtcp2_crypto_wolfssl}" = "xyes" ||
|
(test "x${have_libngtcp2_crypto_wolfssl}" = "xyes" ||
|
||||||
test "x${have_libngtcp2_crypto_quictls}" = "xyes" ||
|
test "x${have_libngtcp2_crypto_quictls}" = "xyes" ||
|
||||||
test "x${have_libngtcp2_crypto_boringssl}" = "xyes") &&
|
test "x${have_libngtcp2_crypto_libressl}" = "xyes" ||
|
||||||
|
test "x${have_libngtcp2_crypto_boringssl}" = "xyes" ||
|
||||||
|
test "x${have_libngtcp2_crypto_ossl}" = "xyes") &&
|
||||||
test "x${have_libnghttp3}" = "xyes"; then
|
test "x${have_libnghttp3}" = "xyes"; then
|
||||||
enable_http3=yes
|
enable_http3=yes
|
||||||
AC_DEFINE([ENABLE_HTTP3], [1], [Define to 1 if HTTP/3 is enabled.])
|
AC_DEFINE([ENABLE_HTTP3], [1], [Define to 1 if HTTP/3 is enabled.])
|
||||||
@@ -1135,6 +1187,7 @@ if test "x$werror" != "xno"; then
|
|||||||
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
|
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
|
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wextra-semi], [CXXFLAGS="$CXXFLAGS -Wextra-semi"])
|
AX_CHECK_COMPILE_FLAG([-Wextra-semi], [CXXFLAGS="$CXXFLAGS -Wextra-semi"])
|
||||||
|
AX_CHECK_COMPILE_FLAG([-Wconversion], [CXXFLAGS="$CXXFLAGS -Wconversion"])
|
||||||
# Disable noexcept-type warning of g++-7. This is not harmful as
|
# Disable noexcept-type warning of g++-7. This is not harmful as
|
||||||
# long as all source files are compiled with the same compiler.
|
# long as all source files are compiled with the same compiler.
|
||||||
AX_CHECK_COMPILE_FLAG([-Wno-noexcept-type], [CXXFLAGS="$CXXFLAGS -Wno-noexcept-type"])
|
AX_CHECK_COMPILE_FLAG([-Wno-noexcept-type], [CXXFLAGS="$CXXFLAGS -Wno-noexcept-type"])
|
||||||
@@ -1206,7 +1259,6 @@ AC_CONFIG_FILES([
|
|||||||
doc/nghttp2ver.h.rst
|
doc/nghttp2ver.h.rst
|
||||||
doc/contribute.rst
|
doc/contribute.rst
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
script/Makefile
|
|
||||||
])
|
])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
@@ -1255,7 +1307,9 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
Libc-ares: ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
|
Libc-ares: ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
|
||||||
libngtcp2: ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
|
libngtcp2: ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
|
||||||
libngtcp2_crypto_quictls: ${have_libngtcp2_crypto_quictls} (CFLAGS='${LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBS}')
|
libngtcp2_crypto_quictls: ${have_libngtcp2_crypto_quictls} (CFLAGS='${LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBS}')
|
||||||
|
libngtcp2_crypto_libressl: ${have_libngtcp2_crypto_libressl} (CFLAGS='${LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_LIBRESSL_LIBS}')
|
||||||
libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
|
libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
|
||||||
|
libngtcp2_crypto_ossl: ${have_libngtcp2_crypto_ossl} (CFLAGS='${LIBNGTCP2_CRYPTO_OSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OSSL_LIBS}')
|
||||||
libnghttp3: ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
|
libnghttp3: ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
|
||||||
libbpf: ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
|
libbpf: ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
|
||||||
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
|
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ APIDOCS= \
|
|||||||
nghttp2_option_set_max_outbound_ack.rst \
|
nghttp2_option_set_max_outbound_ack.rst \
|
||||||
nghttp2_option_set_max_settings.rst \
|
nghttp2_option_set_max_settings.rst \
|
||||||
nghttp2_option_set_stream_reset_rate_limit.rst \
|
nghttp2_option_set_stream_reset_rate_limit.rst \
|
||||||
|
nghttp2_option_set_glitch_rate_limit.rst \
|
||||||
nghttp2_pack_settings_payload.rst \
|
nghttp2_pack_settings_payload.rst \
|
||||||
nghttp2_pack_settings_payload2.rst \
|
nghttp2_pack_settings_payload2.rst \
|
||||||
nghttp2_priority_spec_check_default.rst \
|
nghttp2_priority_spec_check_default.rst \
|
||||||
@@ -114,6 +115,7 @@ APIDOCS= \
|
|||||||
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
||||||
nghttp2_session_callbacks_set_pack_extension_callback.rst \
|
nghttp2_session_callbacks_set_pack_extension_callback.rst \
|
||||||
nghttp2_session_callbacks_set_pack_extension_callback2.rst \
|
nghttp2_session_callbacks_set_pack_extension_callback2.rst \
|
||||||
|
nghttp2_session_callbacks_set_rand_callback.rst \
|
||||||
nghttp2_session_callbacks_set_recv_callback.rst \
|
nghttp2_session_callbacks_set_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_recv_callback2.rst \
|
nghttp2_session_callbacks_set_recv_callback2.rst \
|
||||||
nghttp2_session_callbacks_set_select_padding_callback.rst \
|
nghttp2_session_callbacks_set_select_padding_callback.rst \
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ The example follows::
|
|||||||
|
|
||||||
``@struct`` is used to refer to the struct. Currently, only struct
|
``@struct`` is used to refer to the struct. Currently, only struct
|
||||||
typedefs are supported. The comment block is used for the document for
|
typedefs are supported. The comment block is used for the document for
|
||||||
the struct type itself.To document each member, put comment block
|
the struct type itself. To document each member, put comment block
|
||||||
starting with the line ``/**`` and ending with the ``*/`` just before
|
starting with the line ``/**`` and ending with the ``*/`` just before
|
||||||
the member. When the line starts with ``}`` is encountered, the
|
the member. When the line starts with ``}`` is encountered, the
|
||||||
``mkapiref.py`` extracts strings next to ``}`` as the name of struct.
|
``mkapiref.py`` extracts strings next to ``}`` as the name of struct.
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
sphinxcontrib
|
|
||||||
~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This package is a namespace package that contains all extensions
|
|
||||||
distributed in the ``sphinx-contrib`` distribution.
|
|
||||||
|
|
||||||
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
|
|
||||||
:license: BSD, see LICENSE for details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__import__('pkg_resources').declare_namespace(__name__)
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ _nghttpd()
|
|||||||
_get_comp_words_by_ref cur prev
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --ktls --version --help ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --groups --ktls --version --help ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ _nghttpx()
|
|||||||
_get_comp_words_by_ref cur prev
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-idle-timeout --frontend-http3-idle-timeout --frontend-write-timeout --frontend-keep-alive-timeout --frontend-header-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --ecdh-curves --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --alpn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --fetch-ocsp-response-file --ocsp-update-interval --ocsp-startup --no-verify-ocsp --no-ocsp --tls-session-cache-memcached --tls-session-cache-memcached-address-family --tls-session-cache-memcached-cert-file --tls-session-cache-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --tls-ktls --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-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 --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --require-http-scheme --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-idle-timeout --frontend-http3-idle-timeout --frontend-write-timeout --frontend-keep-alive-timeout --frontend-header-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --groups --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --alpn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --tls-ktls --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-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 --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --require-http-scheme --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
12
doc/h2load.1
12
doc/h2load.1
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "H2LOAD" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
|
.TH "H2LOAD" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
h2load \- HTTP/2 benchmarking tool
|
h2load \- HTTP/2 benchmarking tool
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -109,9 +109,9 @@ Default: \fB16K\fP
|
|||||||
.TP
|
.TP
|
||||||
.B \-w, \-\-window\-bits=<N>
|
.B \-w, \-\-window\-bits=<N>
|
||||||
Sets the stream level initial window size to (2**<N>)\-1.
|
Sets the stream level initial window size to (2**<N>)\-1.
|
||||||
For QUIC, <N> is capped to 26 (roughly 64MiB).
|
For QUIC, <N> is capped to 26 (roughly 64MiB). It
|
||||||
.sp
|
defaults to 24 (16MiB) for QUIC, and 30 for other
|
||||||
Default: \fB30\fP
|
protocols.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -262,7 +262,7 @@ protocol comes first. The parameter must be delimited
|
|||||||
by a single comma only and any white spaces are treated
|
by a single comma only and any white spaces are treated
|
||||||
as a part of protocol string.
|
as a part of protocol string.
|
||||||
.sp
|
.sp
|
||||||
Default: \fBh2,h2\-16,h2\-14,http/1.1\fP
|
Default: \fBh2,http/1.1\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -388,7 +388,7 @@ The number of requests completed.
|
|||||||
.TP
|
.TP
|
||||||
.B succeeded
|
.B succeeded
|
||||||
The number of requests completed successfully. Only HTTP status
|
The number of requests completed successfully. Only HTTP status
|
||||||
code 2xx or3xx are considered as success.
|
code 2xx or 3xx are considered as success.
|
||||||
.TP
|
.TP
|
||||||
.B failed
|
.B failed
|
||||||
The number of requests failed, including HTTP level failures
|
The number of requests failed, including HTTP level failures
|
||||||
|
|||||||
@@ -83,9 +83,9 @@ OPTIONS
|
|||||||
.. option:: -w, --window-bits=<N>
|
.. option:: -w, --window-bits=<N>
|
||||||
|
|
||||||
Sets the stream level initial window size to (2\*\*<N>)-1.
|
Sets the stream level initial window size to (2\*\*<N>)-1.
|
||||||
For QUIC, <N> is capped to 26 (roughly 64MiB).
|
For QUIC, <N> is capped to 26 (roughly 64MiB). It
|
||||||
|
defaults to 24 (16MiB) for QUIC, and 30 for other
|
||||||
Default: ``30``
|
protocols.
|
||||||
|
|
||||||
.. option:: -W, --connection-window-bits=<N>
|
.. option:: -W, --connection-window-bits=<N>
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ OPTIONS
|
|||||||
by a single comma only and any white spaces are treated
|
by a single comma only and any white spaces are treated
|
||||||
as a part of protocol string.
|
as a part of protocol string.
|
||||||
|
|
||||||
Default: ``h2,h2-16,h2-14,http/1.1``
|
Default: ``h2,http/1.1``
|
||||||
|
|
||||||
.. option:: --h1
|
.. option:: --h1
|
||||||
|
|
||||||
@@ -331,7 +331,7 @@ requests
|
|||||||
The number of requests completed.
|
The number of requests completed.
|
||||||
succeeded
|
succeeded
|
||||||
The number of requests completed successfully. Only HTTP status
|
The number of requests completed successfully. Only HTTP status
|
||||||
code 2xx or3xx are considered as success.
|
code 2xx or 3xx are considered as success.
|
||||||
failed
|
failed
|
||||||
The number of requests failed, including HTTP level failures
|
The number of requests failed, including HTTP level failures
|
||||||
(non-successful HTTP status code).
|
(non-successful HTTP status code).
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ requests
|
|||||||
The number of requests completed.
|
The number of requests completed.
|
||||||
succeeded
|
succeeded
|
||||||
The number of requests completed successfully. Only HTTP status
|
The number of requests completed successfully. Only HTTP status
|
||||||
code 2xx or3xx are considered as success.
|
code 2xx or 3xx are considered as success.
|
||||||
failed
|
failed
|
||||||
The number of requests failed, including HTTP level failures
|
The number of requests failed, including HTTP level failures
|
||||||
(non-successful HTTP status code).
|
(non-successful HTTP status code).
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "NGHTTP" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
|
.TH "NGHTTP" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttp \- HTTP/2 client
|
nghttp \- HTTP/2 client
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -243,11 +243,6 @@ Enable ktls.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-no\-rfc7540\-pri
|
|
||||||
Disable RFC7540 priorities.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-version
|
.B \-\-version
|
||||||
Display version information and exit.
|
Display version information and exit.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "NGHTTPD" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
|
.TH "NGHTTPD" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttpd \- HTTP/2 server
|
nghttpd \- HTTP/2 server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -204,6 +204,13 @@ Don\(aqt send content\-length header field.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-groups=<GROUPS>
|
||||||
|
Specify the supported groups.
|
||||||
|
.sp
|
||||||
|
Default: \fBX25519:P\-256:P\-384:P\-521\fP
|
||||||
|
.UNINDENT
|
||||||
|
.INDENT 0.0
|
||||||
|
.TP
|
||||||
.B \-\-ktls
|
.B \-\-ktls
|
||||||
Enable ktls.
|
Enable ktls.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
|
|||||||
@@ -159,6 +159,12 @@ OPTIONS
|
|||||||
|
|
||||||
Don't send content-length header field.
|
Don't send content-length header field.
|
||||||
|
|
||||||
|
.. option:: --groups=<GROUPS>
|
||||||
|
|
||||||
|
Specify the supported groups.
|
||||||
|
|
||||||
|
Default: ``X25519:P-256:P-384:P-521``
|
||||||
|
|
||||||
.. option:: --ktls
|
.. option:: --ktls
|
||||||
|
|
||||||
Enable ktls.
|
Enable ktls.
|
||||||
|
|||||||
170
doc/nghttpx.1
170
doc/nghttpx.1
@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
|||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "NGHTTPX" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
|
.TH "NGHTTPX" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttpx \- HTTP/2 proxy
|
nghttpx \- HTTP/2 proxy
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -46,8 +46,7 @@ Set path to server\(aqs private key. Required unless
|
|||||||
.TP
|
.TP
|
||||||
.B <CERT>
|
.B <CERT>
|
||||||
Set path to server\(aqs certificate. Required unless
|
Set path to server\(aqs certificate. Required unless
|
||||||
\(dqno\-tls\(dq parameter is used in \fI\%\-\-frontend\fP option. To
|
\(dqno\-tls\(dq parameter is used in \fI\%\-\-frontend\fP option.
|
||||||
make OCSP stapling work, this must be an absolute path.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.sp
|
.sp
|
||||||
@@ -688,8 +687,8 @@ Default: \fB2m\fP
|
|||||||
.B \-\-ciphers=<SUITE>
|
.B \-\-ciphers=<SUITE>
|
||||||
Set allowed cipher list for frontend connection. The
|
Set allowed cipher list for frontend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.2 or earlier.
|
This option sets cipher suites for TLSv1.2. Use
|
||||||
Use \fI\%\-\-tls13\-ciphers\fP for TLSv1.3.
|
\fI\%\-\-tls13\-ciphers\fP for TLSv1.3.
|
||||||
.sp
|
.sp
|
||||||
Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384\fP
|
Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -699,7 +698,7 @@ Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:EC
|
|||||||
Set allowed cipher list for frontend connection. The
|
Set allowed cipher list for frontend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.3. Use
|
This option sets cipher suites for TLSv1.3. Use
|
||||||
\fI\%\-\-ciphers\fP for TLSv1.2 or earlier.
|
\fI\%\-\-ciphers\fP for TLSv1.2.
|
||||||
.sp
|
.sp
|
||||||
Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\fP
|
Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -708,8 +707,8 @@ Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_
|
|||||||
.B \-\-client\-ciphers=<SUITE>
|
.B \-\-client\-ciphers=<SUITE>
|
||||||
Set allowed cipher list for backend connection. The
|
Set allowed cipher list for backend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.2 or earlier.
|
This option sets cipher suites for TLSv1.2. Use
|
||||||
Use \fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.3.
|
\fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.3.
|
||||||
.sp
|
.sp
|
||||||
Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384\fP
|
Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -719,15 +718,15 @@ Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:EC
|
|||||||
Set allowed cipher list for backend connection. The
|
Set allowed cipher list for backend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.3. Use
|
This option sets cipher suites for TLSv1.3. Use
|
||||||
\fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.2 or earlier.
|
\fI\%\-\-client\-ciphers\fP for TLSv1.2.
|
||||||
.sp
|
.sp
|
||||||
Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\fP
|
Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-ecdh\-curves=<LIST>
|
.B \-\-groups=<LIST>
|
||||||
Set supported curve list for frontend connections.
|
Set the supported group list for frontend connections.
|
||||||
<LIST> is a colon separated list of curve NID or names
|
<LIST> is a colon separated list of group NID or names
|
||||||
in the preference order. The supported curves depend on
|
in the preference order. The supported curves depend on
|
||||||
the linked OpenSSL library. This function requires
|
the linked OpenSSL library. This function requires
|
||||||
OpenSSL >= 1.0.2.
|
OpenSSL >= 1.0.2.
|
||||||
@@ -745,12 +744,10 @@ enabled for backend connections.
|
|||||||
.B \-\-cacert=<PATH>
|
.B \-\-cacert=<PATH>
|
||||||
Set path to trusted CA certificate file. It is used in
|
Set path to trusted CA certificate file. It is used in
|
||||||
backend TLS connections to verify peer\(aqs certificate.
|
backend TLS connections to verify peer\(aqs certificate.
|
||||||
It is also used to verify OCSP response from the script
|
The file must be in PEM format. It can contain multiple
|
||||||
set by \fI\%\-\-fetch\-ocsp\-response\-file\fP\&. The file must be in
|
certificates. If the linked OpenSSL is configured to
|
||||||
PEM format. It can contain multiple certificates. If
|
load system wide certificates, they are loaded at
|
||||||
the linked OpenSSL is configured to load system wide
|
startup regardless of this option.
|
||||||
certificates, they are loaded at startup regardless of
|
|
||||||
this option.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -765,13 +762,12 @@ password protected it\(aqll be requested interactively.
|
|||||||
Specify additional certificate and private key file.
|
Specify additional certificate and private key file.
|
||||||
nghttpx will choose certificates based on the hostname
|
nghttpx will choose certificates based on the hostname
|
||||||
indicated by client using TLS SNI extension. If nghttpx
|
indicated by client using TLS SNI extension. If nghttpx
|
||||||
is built with OpenSSL >= 1.0.2, the shared elliptic
|
is built with OpenSSL >= 1.0.2, the signature algorithms
|
||||||
curves (e.g., P\-256) between client and server are also
|
(e.g., ECDSA+SHA256) presented by client are also taken
|
||||||
taken into consideration. This allows nghttpx to send
|
into consideration. This allows nghttpx to send ML\-DSA
|
||||||
ECDSA certificate to modern clients, while sending RSA
|
or ECDSA certificate to modern clients, while sending
|
||||||
based certificate to older clients. This option can be
|
RSA based certificate to older clients. This option can
|
||||||
used multiple times. To make OCSP stapling work,
|
be used multiple times.
|
||||||
<CERTPATH> must be absolute path.
|
|
||||||
.sp
|
.sp
|
||||||
Additional parameter can be specified in <PARAM>. The
|
Additional parameter can be specified in <PARAM>. The
|
||||||
available <PARAM> is \(dqsct\-dir=<DIR>\(dq.
|
available <PARAM> is \(dqsct\-dir=<DIR>\(dq.
|
||||||
@@ -798,7 +794,7 @@ protocol comes first. The parameter must be delimited
|
|||||||
by a single comma only and any white spaces are treated
|
by a single comma only and any white spaces are treated
|
||||||
as a part of protocol string.
|
as a part of protocol string.
|
||||||
.sp
|
.sp
|
||||||
Default: \fBh2,h2\-16,h2\-14,http/1.1\fP
|
Default: \fBh2,http/1.1\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -840,12 +836,8 @@ done in case\-insensitive manner. The versions between
|
|||||||
\fI\%\-\-tls\-min\-proto\-version\fP and \fI\%\-\-tls\-max\-proto\-version\fP are
|
\fI\%\-\-tls\-min\-proto\-version\fP and \fI\%\-\-tls\-max\-proto\-version\fP are
|
||||||
enabled. If the protocol list advertised by client does
|
enabled. If the protocol list advertised by client does
|
||||||
not overlap this range, you will receive the error
|
not overlap this range, you will receive the error
|
||||||
message \(dqunknown protocol\(dq. If a protocol version lower
|
message \(dqunknown protocol\(dq. The available versions are:
|
||||||
than TLSv1.2 is specified, make sure that the compatible
|
TLSv1.3 and TLSv1.2
|
||||||
ciphers are included in \fI\%\-\-ciphers\fP option. The default
|
|
||||||
cipher list only includes ciphers compatible with
|
|
||||||
TLSv1.2 or above. The available versions are:
|
|
||||||
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
|
|
||||||
.sp
|
.sp
|
||||||
Default: \fBTLSv1.2\fP
|
Default: \fBTLSv1.2\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -858,7 +850,7 @@ done in case\-insensitive manner. The versions between
|
|||||||
enabled. If the protocol list advertised by client does
|
enabled. If the protocol list advertised by client does
|
||||||
not overlap this range, you will receive the error
|
not overlap this range, you will receive the error
|
||||||
message \(dqunknown protocol\(dq. The available versions are:
|
message \(dqunknown protocol\(dq. The available versions are:
|
||||||
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
|
TLSv1.3 and TLSv1.2
|
||||||
.sp
|
.sp
|
||||||
Default: \fBTLSv1.3\fP
|
Default: \fBTLSv1.3\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -962,72 +954,6 @@ get TLS ticket keys.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-fetch\-ocsp\-response\-file=<PATH>
|
|
||||||
Path to fetch\-ocsp\-response script file. It should be
|
|
||||||
absolute path.
|
|
||||||
.sp
|
|
||||||
Default: \fB/usr/local/share/nghttp2/fetch\-ocsp\-response\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-ocsp\-update\-interval=<DURATION>
|
|
||||||
Set interval to update OCSP response cache.
|
|
||||||
.sp
|
|
||||||
Default: \fB4h\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-ocsp\-startup
|
|
||||||
Start accepting connections after initial attempts to
|
|
||||||
get OCSP responses finish. It does not matter some of
|
|
||||||
the attempts fail. This feature is useful if OCSP
|
|
||||||
responses must be available before accepting
|
|
||||||
connections.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-no\-verify\-ocsp
|
|
||||||
nghttpx does not verify OCSP response.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-no\-ocsp
|
|
||||||
Disable OCSP stapling.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-tls\-session\-cache\-memcached=<HOST>,<PORT>[;tls]
|
|
||||||
Specify address of memcached server to store session
|
|
||||||
cache. This enables shared session cache between
|
|
||||||
multiple nghttpx instances. Optionally, memcached
|
|
||||||
connection can be encrypted with TLS by specifying \(dqtls\(dq
|
|
||||||
parameter.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-tls\-session\-cache\-memcached\-address\-family=(auto|IPv4|IPv6)
|
|
||||||
Specify address family of memcached connections to store
|
|
||||||
session cache. If \(dqauto\(dq is given, both IPv4 and IPv6
|
|
||||||
are considered. If \(dqIPv4\(dq is given, only IPv4 address
|
|
||||||
is considered. If \(dqIPv6\(dq is given, only IPv6 address is
|
|
||||||
considered.
|
|
||||||
.sp
|
|
||||||
Default: \fBauto\fP
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-tls\-session\-cache\-memcached\-cert\-file=<PATH>
|
|
||||||
Path to client certificate for memcached connections to
|
|
||||||
store session cache.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-tls\-session\-cache\-memcached\-private\-key\-file=<PATH>
|
|
||||||
Path to client private key for memcached connections to
|
|
||||||
store session cache.
|
|
||||||
.UNINDENT
|
|
||||||
.INDENT 0.0
|
|
||||||
.TP
|
|
||||||
.B \-\-tls\-dyn\-rec\-warmup\-threshold=<SIZE>
|
.B \-\-tls\-dyn\-rec\-warmup\-threshold=<SIZE>
|
||||||
Specify the threshold size for TLS dynamic record size
|
Specify the threshold size for TLS dynamic record size
|
||||||
behaviour. During a TLS session, after the threshold
|
behaviour. During a TLS session, after the threshold
|
||||||
@@ -1135,8 +1061,7 @@ Default: \fB16K\fP
|
|||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-\-tls\-ktls
|
.B \-\-tls\-ktls
|
||||||
Enable ktls. For server, ktls is enable if
|
Enable ktls.
|
||||||
\fI\%\-\-tls\-session\-cache\-memcached\fP is not configured.
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.SS HTTP/2
|
.SS HTTP/2
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
@@ -1675,7 +1600,7 @@ initial DNS query. For the 2nd and later queries,
|
|||||||
server is given time based on this timeout, and it is
|
server is given time based on this timeout, and it is
|
||||||
scaled linearly.
|
scaled linearly.
|
||||||
.sp
|
.sp
|
||||||
Default: \fB5s\fP
|
Default: \fB250ms\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -1683,7 +1608,7 @@ Default: \fB5s\fP
|
|||||||
Set the number of DNS query before nghttpx gives up name
|
Set the number of DNS query before nghttpx gives up name
|
||||||
lookup.
|
lookup.
|
||||||
.sp
|
.sp
|
||||||
Default: \fB2\fP
|
Default: \fB3\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -2154,35 +2079,6 @@ specified socket already exists in the file system, nghttpx first
|
|||||||
deletes it. However, if SIGUSR2 is used to execute new binary and
|
deletes it. However, if SIGUSR2 is used to execute new binary and
|
||||||
both old and new configurations use same filename, new binary does not
|
both old and new configurations use same filename, new binary does not
|
||||||
delete the socket and continues to use it.
|
delete the socket and continues to use it.
|
||||||
.SH OCSP STAPLING
|
|
||||||
.sp
|
|
||||||
OCSP query is done using external Python script
|
|
||||||
\fBfetch\-ocsp\-response\fP, which has been originally developed in Perl
|
|
||||||
as part of h2o project (\X'tty: link https://github.com/h2o/h2o'\fI\%https://github.com/h2o/h2o\fP\X'tty: link'), and was
|
|
||||||
translated into Python.
|
|
||||||
.sp
|
|
||||||
The script file is usually installed under
|
|
||||||
\fB$(prefix)/share/nghttp2/\fP directory. The actual path to script can
|
|
||||||
be customized using \fI\%\-\-fetch\-ocsp\-response\-file\fP option.
|
|
||||||
.sp
|
|
||||||
If OCSP query is failed, previous OCSP response, if any, is continued
|
|
||||||
to be used.
|
|
||||||
.sp
|
|
||||||
\fI\%\-\-fetch\-ocsp\-response\-file\fP option provides wide range of
|
|
||||||
possibility to manage OCSP response. It can take an arbitrary script
|
|
||||||
or executable. The requirement is that it supports the command\-line
|
|
||||||
interface of \fBfetch\-ocsp\-response\fP script, and it must return a
|
|
||||||
valid DER encoded OCSP response on success. It must return exit code
|
|
||||||
0 on success, and 75 for temporary error, and the other error code for
|
|
||||||
generic failure. For large cluster of servers, it is not efficient
|
|
||||||
for each server to perform OCSP query using \fBfetch\-ocsp\-response\fP\&.
|
|
||||||
Instead, you can retrieve OCSP response in some way, and store it in a
|
|
||||||
disk or a shared database. Then specify a program in
|
|
||||||
\fI\%\-\-fetch\-ocsp\-response\-file\fP to fetch it from those stores.
|
|
||||||
This could provide a way to share the OCSP response between fleet of
|
|
||||||
servers, and also any OCSP query strategy can be applied which may be
|
|
||||||
beyond the ability of nghttpx itself or \fBfetch\-ocsp\-response\fP
|
|
||||||
script.
|
|
||||||
.SH TLS SESSION RESUMPTION
|
.SH TLS SESSION RESUMPTION
|
||||||
.sp
|
.sp
|
||||||
nghttpx supports TLS session resumption through both session ID and
|
nghttpx supports TLS session resumption through both session ID and
|
||||||
@@ -2190,16 +2086,6 @@ session ticket.
|
|||||||
.SS SESSION ID RESUMPTION
|
.SS SESSION ID RESUMPTION
|
||||||
.sp
|
.sp
|
||||||
By default, session ID is shared by all worker threads.
|
By default, session ID is shared by all worker threads.
|
||||||
.sp
|
|
||||||
If \fI\%\-\-tls\-session\-cache\-memcached\fP is given, nghttpx will
|
|
||||||
insert serialized session data to memcached with
|
|
||||||
\fBnghttpx:tls\-session\-cache:\fP + lowercase hex string of session ID
|
|
||||||
as a memcached entry key, with expiry time 12 hours. Session timeout
|
|
||||||
is set to 12 hours.
|
|
||||||
.sp
|
|
||||||
By default, connections to memcached server are not encrypted. To
|
|
||||||
enable encryption, use \fBtls\fP keyword in
|
|
||||||
\fI\%\-\-tls\-session\-cache\-memcached\fP option.
|
|
||||||
.SS TLS SESSION TICKET RESUMPTION
|
.SS TLS SESSION TICKET RESUMPTION
|
||||||
.sp
|
.sp
|
||||||
By default, session ticket is shared by all worker threads. The
|
By default, session ticket is shared by all worker threads. The
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ A reverse proxy for HTTP/3, HTTP/2, and HTTP/1.
|
|||||||
.. describe:: <CERT>
|
.. describe:: <CERT>
|
||||||
|
|
||||||
Set path to server's certificate. Required unless
|
Set path to server's certificate. Required unless
|
||||||
"no-tls" parameter is used in :option:`--frontend` option. To
|
"no-tls" parameter is used in :option:`--frontend` option.
|
||||||
make OCSP stapling work, this must be an absolute path.
|
|
||||||
|
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
@@ -644,8 +643,8 @@ SSL/TLS
|
|||||||
|
|
||||||
Set allowed cipher list for frontend connection. The
|
Set allowed cipher list for frontend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.2 or earlier.
|
This option sets cipher suites for TLSv1.2. Use
|
||||||
Use :option:`--tls13-ciphers` for TLSv1.3.
|
:option:`--tls13-ciphers` for TLSv1.3.
|
||||||
|
|
||||||
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
|
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
|
||||||
|
|
||||||
@@ -654,7 +653,7 @@ SSL/TLS
|
|||||||
Set allowed cipher list for frontend connection. The
|
Set allowed cipher list for frontend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.3. Use
|
This option sets cipher suites for TLSv1.3. Use
|
||||||
:option:`--ciphers` for TLSv1.2 or earlier.
|
:option:`--ciphers` for TLSv1.2.
|
||||||
|
|
||||||
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
|
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
|
||||||
|
|
||||||
@@ -662,8 +661,8 @@ SSL/TLS
|
|||||||
|
|
||||||
Set allowed cipher list for backend connection. The
|
Set allowed cipher list for backend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.2 or earlier.
|
This option sets cipher suites for TLSv1.2. Use
|
||||||
Use :option:`--tls13-client-ciphers` for TLSv1.3.
|
:option:`--tls13-client-ciphers` for TLSv1.3.
|
||||||
|
|
||||||
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
|
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
|
||||||
|
|
||||||
@@ -672,14 +671,14 @@ SSL/TLS
|
|||||||
Set allowed cipher list for backend connection. The
|
Set allowed cipher list for backend connection. The
|
||||||
format of the string is described in OpenSSL ciphers(1).
|
format of the string is described in OpenSSL ciphers(1).
|
||||||
This option sets cipher suites for TLSv1.3. Use
|
This option sets cipher suites for TLSv1.3. Use
|
||||||
:option:`--tls13-client-ciphers` for TLSv1.2 or earlier.
|
:option:`--client-ciphers` for TLSv1.2.
|
||||||
|
|
||||||
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
|
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
|
||||||
|
|
||||||
.. option:: --ecdh-curves=<LIST>
|
.. option:: --groups=<LIST>
|
||||||
|
|
||||||
Set supported curve list for frontend connections.
|
Set the supported group list for frontend connections.
|
||||||
<LIST> is a colon separated list of curve NID or names
|
<LIST> is a colon separated list of group NID or names
|
||||||
in the preference order. The supported curves depend on
|
in the preference order. The supported curves depend on
|
||||||
the linked OpenSSL library. This function requires
|
the linked OpenSSL library. This function requires
|
||||||
OpenSSL >= 1.0.2.
|
OpenSSL >= 1.0.2.
|
||||||
@@ -695,12 +694,10 @@ SSL/TLS
|
|||||||
|
|
||||||
Set path to trusted CA certificate file. It is used in
|
Set path to trusted CA certificate file. It is used in
|
||||||
backend TLS connections to verify peer's certificate.
|
backend TLS connections to verify peer's certificate.
|
||||||
It is also used to verify OCSP response from the script
|
The file must be in PEM format. It can contain multiple
|
||||||
set by :option:`--fetch-ocsp-response-file`\. The file must be in
|
certificates. If the linked OpenSSL is configured to
|
||||||
PEM format. It can contain multiple certificates. If
|
load system wide certificates, they are loaded at
|
||||||
the linked OpenSSL is configured to load system wide
|
startup regardless of this option.
|
||||||
certificates, they are loaded at startup regardless of
|
|
||||||
this option.
|
|
||||||
|
|
||||||
.. option:: --private-key-passwd-file=<PATH>
|
.. option:: --private-key-passwd-file=<PATH>
|
||||||
|
|
||||||
@@ -713,13 +710,12 @@ SSL/TLS
|
|||||||
Specify additional certificate and private key file.
|
Specify additional certificate and private key file.
|
||||||
nghttpx will choose certificates based on the hostname
|
nghttpx will choose certificates based on the hostname
|
||||||
indicated by client using TLS SNI extension. If nghttpx
|
indicated by client using TLS SNI extension. If nghttpx
|
||||||
is built with OpenSSL >= 1.0.2, the shared elliptic
|
is built with OpenSSL >= 1.0.2, the signature algorithms
|
||||||
curves (e.g., P-256) between client and server are also
|
(e.g., ECDSA+SHA256) presented by client are also taken
|
||||||
taken into consideration. This allows nghttpx to send
|
into consideration. This allows nghttpx to send ML-DSA
|
||||||
ECDSA certificate to modern clients, while sending RSA
|
or ECDSA certificate to modern clients, while sending
|
||||||
based certificate to older clients. This option can be
|
RSA based certificate to older clients. This option can
|
||||||
used multiple times. To make OCSP stapling work,
|
be used multiple times.
|
||||||
<CERTPATH> must be absolute path.
|
|
||||||
|
|
||||||
Additional parameter can be specified in <PARAM>. The
|
Additional parameter can be specified in <PARAM>. The
|
||||||
available <PARAM> is "sct-dir=<DIR>".
|
available <PARAM> is "sct-dir=<DIR>".
|
||||||
@@ -744,7 +740,7 @@ SSL/TLS
|
|||||||
by a single comma only and any white spaces are treated
|
by a single comma only and any white spaces are treated
|
||||||
as a part of protocol string.
|
as a part of protocol string.
|
||||||
|
|
||||||
Default: ``h2,h2-16,h2-14,http/1.1``
|
Default: ``h2,http/1.1``
|
||||||
|
|
||||||
.. option:: --verify-client
|
.. option:: --verify-client
|
||||||
|
|
||||||
@@ -780,12 +776,8 @@ SSL/TLS
|
|||||||
:option:`--tls-min-proto-version` and :option:`\--tls-max-proto-version` are
|
:option:`--tls-min-proto-version` and :option:`\--tls-max-proto-version` are
|
||||||
enabled. If the protocol list advertised by client does
|
enabled. If the protocol list advertised by client does
|
||||||
not overlap this range, you will receive the error
|
not overlap this range, you will receive the error
|
||||||
message "unknown protocol". If a protocol version lower
|
message "unknown protocol". The available versions are:
|
||||||
than TLSv1.2 is specified, make sure that the compatible
|
TLSv1.3 and TLSv1.2
|
||||||
ciphers are included in :option:`--ciphers` option. The default
|
|
||||||
cipher list only includes ciphers compatible with
|
|
||||||
TLSv1.2 or above. The available versions are:
|
|
||||||
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
|
|
||||||
|
|
||||||
Default: ``TLSv1.2``
|
Default: ``TLSv1.2``
|
||||||
|
|
||||||
@@ -797,7 +789,7 @@ SSL/TLS
|
|||||||
enabled. If the protocol list advertised by client does
|
enabled. If the protocol list advertised by client does
|
||||||
not overlap this range, you will receive the error
|
not overlap this range, you will receive the error
|
||||||
message "unknown protocol". The available versions are:
|
message "unknown protocol". The available versions are:
|
||||||
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
|
TLSv1.3 and TLSv1.2
|
||||||
|
|
||||||
Default: ``TLSv1.3``
|
Default: ``TLSv1.3``
|
||||||
|
|
||||||
@@ -890,63 +882,6 @@ SSL/TLS
|
|||||||
Path to client private key for memcached connections to
|
Path to client private key for memcached connections to
|
||||||
get TLS ticket keys.
|
get TLS ticket keys.
|
||||||
|
|
||||||
.. option:: --fetch-ocsp-response-file=<PATH>
|
|
||||||
|
|
||||||
Path to fetch-ocsp-response script file. It should be
|
|
||||||
absolute path.
|
|
||||||
|
|
||||||
Default: ``/usr/local/share/nghttp2/fetch-ocsp-response``
|
|
||||||
|
|
||||||
.. option:: --ocsp-update-interval=<DURATION>
|
|
||||||
|
|
||||||
Set interval to update OCSP response cache.
|
|
||||||
|
|
||||||
Default: ``4h``
|
|
||||||
|
|
||||||
.. option:: --ocsp-startup
|
|
||||||
|
|
||||||
Start accepting connections after initial attempts to
|
|
||||||
get OCSP responses finish. It does not matter some of
|
|
||||||
the attempts fail. This feature is useful if OCSP
|
|
||||||
responses must be available before accepting
|
|
||||||
connections.
|
|
||||||
|
|
||||||
.. option:: --no-verify-ocsp
|
|
||||||
|
|
||||||
nghttpx does not verify OCSP response.
|
|
||||||
|
|
||||||
.. option:: --no-ocsp
|
|
||||||
|
|
||||||
Disable OCSP stapling.
|
|
||||||
|
|
||||||
.. option:: --tls-session-cache-memcached=<HOST>,<PORT>[;tls]
|
|
||||||
|
|
||||||
Specify address of memcached server to store session
|
|
||||||
cache. This enables shared session cache between
|
|
||||||
multiple nghttpx instances. Optionally, memcached
|
|
||||||
connection can be encrypted with TLS by specifying "tls"
|
|
||||||
parameter.
|
|
||||||
|
|
||||||
.. option:: --tls-session-cache-memcached-address-family=(auto|IPv4|IPv6)
|
|
||||||
|
|
||||||
Specify address family of memcached connections to store
|
|
||||||
session cache. If "auto" is given, both IPv4 and IPv6
|
|
||||||
are considered. If "IPv4" is given, only IPv4 address
|
|
||||||
is considered. If "IPv6" is given, only IPv6 address is
|
|
||||||
considered.
|
|
||||||
|
|
||||||
Default: ``auto``
|
|
||||||
|
|
||||||
.. option:: --tls-session-cache-memcached-cert-file=<PATH>
|
|
||||||
|
|
||||||
Path to client certificate for memcached connections to
|
|
||||||
store session cache.
|
|
||||||
|
|
||||||
.. option:: --tls-session-cache-memcached-private-key-file=<PATH>
|
|
||||||
|
|
||||||
Path to client private key for memcached connections to
|
|
||||||
store session cache.
|
|
||||||
|
|
||||||
.. option:: --tls-dyn-rec-warmup-threshold=<SIZE>
|
.. option:: --tls-dyn-rec-warmup-threshold=<SIZE>
|
||||||
|
|
||||||
Specify the threshold size for TLS dynamic record size
|
Specify the threshold size for TLS dynamic record size
|
||||||
@@ -1046,8 +981,7 @@ SSL/TLS
|
|||||||
|
|
||||||
.. option:: --tls-ktls
|
.. option:: --tls-ktls
|
||||||
|
|
||||||
Enable ktls. For server, ktls is enable if
|
Enable ktls.
|
||||||
:option:`--tls-session-cache-memcached` is not configured.
|
|
||||||
|
|
||||||
|
|
||||||
HTTP/2
|
HTTP/2
|
||||||
@@ -1524,14 +1458,14 @@ DNS
|
|||||||
server is given time based on this timeout, and it is
|
server is given time based on this timeout, and it is
|
||||||
scaled linearly.
|
scaled linearly.
|
||||||
|
|
||||||
Default: ``5s``
|
Default: ``250ms``
|
||||||
|
|
||||||
.. option:: --dns-max-try=<N>
|
.. option:: --dns-max-try=<N>
|
||||||
|
|
||||||
Set the number of DNS query before nghttpx gives up name
|
Set the number of DNS query before nghttpx gives up name
|
||||||
lookup.
|
lookup.
|
||||||
|
|
||||||
Default: ``2``
|
Default: ``3``
|
||||||
|
|
||||||
.. option:: --frontend-max-requests=<N>
|
.. option:: --frontend-max-requests=<N>
|
||||||
|
|
||||||
@@ -1971,37 +1905,6 @@ deletes it. However, if SIGUSR2 is used to execute new binary and
|
|||||||
both old and new configurations use same filename, new binary does not
|
both old and new configurations use same filename, new binary does not
|
||||||
delete the socket and continues to use it.
|
delete the socket and continues to use it.
|
||||||
|
|
||||||
OCSP STAPLING
|
|
||||||
-------------
|
|
||||||
|
|
||||||
OCSP query is done using external Python script
|
|
||||||
``fetch-ocsp-response``, which has been originally developed in Perl
|
|
||||||
as part of h2o project (https://github.com/h2o/h2o), and was
|
|
||||||
translated into Python.
|
|
||||||
|
|
||||||
The script file is usually installed under
|
|
||||||
``$(prefix)/share/nghttp2/`` directory. The actual path to script can
|
|
||||||
be customized using :option:`--fetch-ocsp-response-file` option.
|
|
||||||
|
|
||||||
If OCSP query is failed, previous OCSP response, if any, is continued
|
|
||||||
to be used.
|
|
||||||
|
|
||||||
:option:`--fetch-ocsp-response-file` option provides wide range of
|
|
||||||
possibility to manage OCSP response. It can take an arbitrary script
|
|
||||||
or executable. The requirement is that it supports the command-line
|
|
||||||
interface of ``fetch-ocsp-response`` script, and it must return a
|
|
||||||
valid DER encoded OCSP response on success. It must return exit code
|
|
||||||
0 on success, and 75 for temporary error, and the other error code for
|
|
||||||
generic failure. For large cluster of servers, it is not efficient
|
|
||||||
for each server to perform OCSP query using ``fetch-ocsp-response``.
|
|
||||||
Instead, you can retrieve OCSP response in some way, and store it in a
|
|
||||||
disk or a shared database. Then specify a program in
|
|
||||||
:option:`--fetch-ocsp-response-file` to fetch it from those stores.
|
|
||||||
This could provide a way to share the OCSP response between fleet of
|
|
||||||
servers, and also any OCSP query strategy can be applied which may be
|
|
||||||
beyond the ability of nghttpx itself or ``fetch-ocsp-response``
|
|
||||||
script.
|
|
||||||
|
|
||||||
TLS SESSION RESUMPTION
|
TLS SESSION RESUMPTION
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
@@ -2013,16 +1916,6 @@ SESSION ID RESUMPTION
|
|||||||
|
|
||||||
By default, session ID is shared by all worker threads.
|
By default, session ID is shared by all worker threads.
|
||||||
|
|
||||||
If :option:`--tls-session-cache-memcached` is given, nghttpx will
|
|
||||||
insert serialized session data to memcached with
|
|
||||||
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID
|
|
||||||
as a memcached entry key, with expiry time 12 hours. Session timeout
|
|
||||||
is set to 12 hours.
|
|
||||||
|
|
||||||
By default, connections to memcached server are not encrypted. To
|
|
||||||
enable encryption, use ``tls`` keyword in
|
|
||||||
:option:`--tls-session-cache-memcached` option.
|
|
||||||
|
|
||||||
TLS SESSION TICKET RESUMPTION
|
TLS SESSION TICKET RESUMPTION
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -156,37 +156,6 @@ deletes it. However, if SIGUSR2 is used to execute new binary and
|
|||||||
both old and new configurations use same filename, new binary does not
|
both old and new configurations use same filename, new binary does not
|
||||||
delete the socket and continues to use it.
|
delete the socket and continues to use it.
|
||||||
|
|
||||||
OCSP STAPLING
|
|
||||||
-------------
|
|
||||||
|
|
||||||
OCSP query is done using external Python script
|
|
||||||
``fetch-ocsp-response``, which has been originally developed in Perl
|
|
||||||
as part of h2o project (https://github.com/h2o/h2o), and was
|
|
||||||
translated into Python.
|
|
||||||
|
|
||||||
The script file is usually installed under
|
|
||||||
``$(prefix)/share/nghttp2/`` directory. The actual path to script can
|
|
||||||
be customized using :option:`--fetch-ocsp-response-file` option.
|
|
||||||
|
|
||||||
If OCSP query is failed, previous OCSP response, if any, is continued
|
|
||||||
to be used.
|
|
||||||
|
|
||||||
:option:`--fetch-ocsp-response-file` option provides wide range of
|
|
||||||
possibility to manage OCSP response. It can take an arbitrary script
|
|
||||||
or executable. The requirement is that it supports the command-line
|
|
||||||
interface of ``fetch-ocsp-response`` script, and it must return a
|
|
||||||
valid DER encoded OCSP response on success. It must return exit code
|
|
||||||
0 on success, and 75 for temporary error, and the other error code for
|
|
||||||
generic failure. For large cluster of servers, it is not efficient
|
|
||||||
for each server to perform OCSP query using ``fetch-ocsp-response``.
|
|
||||||
Instead, you can retrieve OCSP response in some way, and store it in a
|
|
||||||
disk or a shared database. Then specify a program in
|
|
||||||
:option:`--fetch-ocsp-response-file` to fetch it from those stores.
|
|
||||||
This could provide a way to share the OCSP response between fleet of
|
|
||||||
servers, and also any OCSP query strategy can be applied which may be
|
|
||||||
beyond the ability of nghttpx itself or ``fetch-ocsp-response``
|
|
||||||
script.
|
|
||||||
|
|
||||||
TLS SESSION RESUMPTION
|
TLS SESSION RESUMPTION
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
@@ -198,16 +167,6 @@ SESSION ID RESUMPTION
|
|||||||
|
|
||||||
By default, session ID is shared by all worker threads.
|
By default, session ID is shared by all worker threads.
|
||||||
|
|
||||||
If :option:`--tls-session-cache-memcached` is given, nghttpx will
|
|
||||||
insert serialized session data to memcached with
|
|
||||||
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID
|
|
||||||
as a memcached entry key, with expiry time 12 hours. Session timeout
|
|
||||||
is set to 12 hours.
|
|
||||||
|
|
||||||
By default, connections to memcached server are not encrypted. To
|
|
||||||
enable encryption, use ``tls`` keyword in
|
|
||||||
:option:`--tls-session-cache-memcached` option.
|
|
||||||
|
|
||||||
TLS SESSION TICKET RESUMPTION
|
TLS SESSION TICKET RESUMPTION
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ Coding style
|
|||||||
We use clang-format to format source code consistently. The
|
We use clang-format to format source code consistently. The
|
||||||
clang-format configuration file .clang-format is located at the root
|
clang-format configuration file .clang-format is located at the root
|
||||||
directory. Since clang-format produces slightly different results
|
directory. Since clang-format produces slightly different results
|
||||||
between versions, we currently use clang-format-18.
|
between versions, we currently use clang-format-19.
|
||||||
|
|
||||||
To detect any violation to the coding style, we recommend to setup git
|
To detect any violation to the coding style, we recommend to setup git
|
||||||
pre-commit hook to check coding style of the changes you introduced.
|
pre-commit hook to check coding style of the changes you introduced.
|
||||||
|
|||||||
@@ -167,8 +167,7 @@ Enable SSL/TLS on memcached connection
|
|||||||
|
|
||||||
By default, memcached connection is not encrypted. To enable
|
By default, memcached connection is not encrypted. To enable
|
||||||
encryption, use ``tls`` keyword in
|
encryption, use ``tls`` keyword in
|
||||||
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
|
:option:`--tls-ticket-key-memcached`.
|
||||||
:option:`--tls-session-cache-memcached` for TLS session cache.
|
|
||||||
|
|
||||||
Specifying additional server certificates
|
Specifying additional server certificates
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|||||||
@@ -4,33 +4,36 @@ ARG NGHTTP2_BRANCH=master
|
|||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
git clang make binutils autoconf automake autotools-dev libtool \
|
git clang-19 make binutils autoconf automake autotools-dev libtool \
|
||||||
pkg-config cmake cmake-data \
|
pkg-config cmake cmake-data \
|
||||||
zlib1g-dev libev-dev libjemalloc-dev ruby-dev libc-ares-dev bison \
|
zlib1g-dev libev-dev libjemalloc-dev ruby-dev libc-ares-dev bison \
|
||||||
libelf-dev libbrotli-dev
|
libelf-dev libbrotli-dev
|
||||||
|
|
||||||
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.46.1 https://github.com/aws/aws-lc && \
|
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.62.0 https://github.com/aws/aws-lc && \
|
||||||
cd aws-lc && \
|
cd aws-lc && \
|
||||||
|
export CC=clang-19 CXX=clang++-19 && \
|
||||||
cmake -B build -DDISABLE_GO=ON && \
|
cmake -B build -DDISABLE_GO=ON && \
|
||||||
make -j$(nproc) -C build && \
|
make -j$(nproc) -C build && \
|
||||||
cmake --install build && \
|
cmake --install build && \
|
||||||
cd .. && \
|
cd .. && \
|
||||||
rm -rf aws-lc
|
rm -rf aws-lc
|
||||||
|
|
||||||
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.8.0 https://github.com/ngtcp2/nghttp3 && \
|
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.12.0 https://github.com/ngtcp2/nghttp3 && \
|
||||||
cd nghttp3 && \
|
cd nghttp3 && \
|
||||||
autoreconf -i && \
|
autoreconf -i && \
|
||||||
./configure --disable-dependency-tracking --enable-lib-only && \
|
./configure --disable-dependency-tracking --enable-lib-only \
|
||||||
|
CC=clang-19 CXX=clang++-19 && \
|
||||||
make -j$(nproc) && \
|
make -j$(nproc) && \
|
||||||
make install-strip && \
|
make install-strip && \
|
||||||
cd .. && \
|
cd .. && \
|
||||||
rm -rf nghttp3
|
rm -rf nghttp3
|
||||||
|
|
||||||
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.11.0 https://github.com/ngtcp2/ngtcp2 && \
|
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.17.0 https://github.com/ngtcp2/ngtcp2 && \
|
||||||
cd ngtcp2 && \
|
cd ngtcp2 && \
|
||||||
autoreconf -i && \
|
autoreconf -i && \
|
||||||
./configure --disable-dependency-tracking --enable-lib-only \
|
./configure --disable-dependency-tracking --enable-lib-only \
|
||||||
--with-boringssl \
|
--with-boringssl \
|
||||||
|
CC=clang-19 CXX=clang++-19 \
|
||||||
LIBTOOL_LDFLAGS="-static-libtool-libs" \
|
LIBTOOL_LDFLAGS="-static-libtool-libs" \
|
||||||
BORINGSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
|
BORINGSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
|
||||||
PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig" && \
|
PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig" && \
|
||||||
@@ -39,9 +42,9 @@ RUN git clone --recursive --shallow-submodules --depth 1 -b v1.11.0 https://gith
|
|||||||
cd .. && \
|
cd .. && \
|
||||||
rm -rf ngtcp2
|
rm -rf ngtcp2
|
||||||
|
|
||||||
RUN git clone --depth 1 -b v1.5.0 https://github.com/libbpf/libbpf && \
|
RUN git clone --depth 1 -b v1.6.2 https://github.com/libbpf/libbpf && \
|
||||||
cd libbpf && \
|
cd libbpf && \
|
||||||
PREFIX=/usr/local make -C src install && \
|
CC=clang-19 PREFIX=/usr/local make -C src install && \
|
||||||
cd .. && \
|
cd .. && \
|
||||||
rm -rf libbpf
|
rm -rf libbpf
|
||||||
|
|
||||||
@@ -53,7 +56,7 @@ RUN git clone --recursive --shallow-submodules --depth 1 -b $NGHTTP2_BRANCH http
|
|||||||
--with-mruby \
|
--with-mruby \
|
||||||
--enable-http3 --with-libbpf \
|
--enable-http3 --with-libbpf \
|
||||||
--with-libbrotlienc --with-libbrotlidec \
|
--with-libbrotlienc --with-libbrotlidec \
|
||||||
CC=clang CXX=clang++ \
|
CC=clang-19 CXX=clang++-19 \
|
||||||
LIBTOOL_LDFLAGS="-static-libtool-libs" \
|
LIBTOOL_LDFLAGS="-static-libtool-libs" \
|
||||||
OPENSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
|
OPENSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
|
||||||
LIBEV_LIBS="-l:libev.a" \
|
LIBEV_LIBS="-l:libev.a" \
|
||||||
@@ -71,9 +74,6 @@ RUN git clone --recursive --shallow-submodules --depth 1 -b $NGHTTP2_BRANCH http
|
|||||||
|
|
||||||
FROM gcr.io/distroless/base-nossl-debian12
|
FROM gcr.io/distroless/base-nossl-debian12
|
||||||
|
|
||||||
COPY --from=build --link \
|
|
||||||
/usr/local/share/nghttp2/ \
|
|
||||||
/usr/local/share/nghttp2/
|
|
||||||
COPY --from=build --link \
|
COPY --from=build --link \
|
||||||
/usr/local/bin/h2load \
|
/usr/local/bin/h2load \
|
||||||
/usr/local/bin/nghttpx \
|
/usr/local/bin/nghttpx \
|
||||||
|
|||||||
@@ -28,26 +28,26 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* HAVE_UNISTD_H */
|
#endif /* defined(HAVE_UNISTD_H) */
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
#endif /* HAVE_FCNTL_H */
|
#endif /* defined(HAVE_FCNTL_H) */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif /* HAVE_SYS_SOCKET_H */
|
#endif /* defined(HAVE_SYS_SOCKET_H) */
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
#endif /* HAVE_NETDB_H */
|
#endif /* defined(HAVE_NETDB_H) */
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif /* HAVE_NETINET_IN_H */
|
#endif /* defined(HAVE_NETINET_IN_H) */
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* !HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -31,26 +31,26 @@
|
|||||||
}
|
}
|
||||||
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
|
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
|
||||||
char *strndup(const char *s, size_t size);
|
char *strndup(const char *s, size_t size);
|
||||||
#endif
|
#endif /* defined(__sgi) */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* HAVE_UNISTD_H */
|
#endif /* defined(HAVE_UNISTD_H) */
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif /* HAVE_SYS_SOCKET_H */
|
#endif /* defined(HAVE_SYS_SOCKET_H) */
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif /* HAVE_NETINET_IN_H */
|
#endif /* defined(HAVE_NETINET_IN_H) */
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#ifndef __sgi
|
#ifndef __sgi
|
||||||
# include <err.h>
|
# include <err.h>
|
||||||
#endif
|
#endif /* !defined(__sgi) */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|||||||
@@ -30,35 +30,35 @@
|
|||||||
}
|
}
|
||||||
# define warn(format, args...) warnx(format ": %s", ##args, strerror(errno))
|
# define warn(format, args...) warnx(format ": %s", ##args, strerror(errno))
|
||||||
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
|
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
|
||||||
#endif
|
#endif /* defined(__sgi) */
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif /* HAVE_SYS_SOCKET_H */
|
#endif /* defined(HAVE_SYS_SOCKET_H) */
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
#endif /* HAVE_NETDB_H */
|
#endif /* defined(HAVE_NETDB_H) */
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif /* HAVE_UNISTD_H */
|
#endif /* defined(HAVE_UNISTD_H) */
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
#endif /* HAVE_FCNTL_H */
|
#endif /* defined(HAVE_FCNTL_H) */
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif /* HAVE_NETINET_IN_H */
|
#endif /* defined(HAVE_NETINET_IN_H) */
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#ifndef __sgi
|
#ifndef __sgi
|
||||||
# include <err.h>
|
# include <err.h>
|
||||||
#endif
|
#endif /* !defined(__sgi) */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
@@ -136,11 +136,11 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
|||||||
SSL_OP_NO_COMPRESSION |
|
SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
|
if (SSL_CTX_set1_groups_list(ssl_ctx, "P-256") != 1) {
|
||||||
errx(1, "SSL_CTX_set1_curves_list failed: %s",
|
errx(1, "SSL_CTX_set1_groups_list failed: %s",
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
}
|
}
|
||||||
#else /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
|
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||||
{
|
{
|
||||||
EC_KEY *ecdh;
|
EC_KEY *ecdh;
|
||||||
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
|
||||||
@@ -151,7 +151,7 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
|||||||
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
|
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
|
||||||
EC_KEY_free(ecdh);
|
EC_KEY_free(ecdh);
|
||||||
}
|
}
|
||||||
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
|
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||||
|
|
||||||
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
|
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
|
||||||
errx(1, "Could not read private key file %s", key_file);
|
errx(1, "Could not read private key file %s", key_file);
|
||||||
@@ -727,7 +727,7 @@ static void start_listen(struct event_base *evbase, const char *service,
|
|||||||
hints.ai_flags = AI_PASSIVE;
|
hints.ai_flags = AI_PASSIVE;
|
||||||
#ifdef AI_ADDRCONFIG
|
#ifdef AI_ADDRCONFIG
|
||||||
hints.ai_flags |= AI_ADDRCONFIG;
|
hints.ai_flags |= AI_ADDRCONFIG;
|
||||||
#endif /* AI_ADDRCONFIG */
|
#endif /* defined(AI_ADDRCONFIG) */
|
||||||
|
|
||||||
rv = getaddrinfo(NULL, service, &hints, &res);
|
rv = getaddrinfo(NULL, service, &hints, &res);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ OPTIONS = [
|
|||||||
"frontend-header-timeout",
|
"frontend-header-timeout",
|
||||||
"frontend-http2-idle-timeout",
|
"frontend-http2-idle-timeout",
|
||||||
"frontend-http3-idle-timeout",
|
"frontend-http3-idle-timeout",
|
||||||
|
"groups",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ enum {''')
|
|||||||
|
|
||||||
def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
|
def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
|
||||||
print('''\
|
print('''\
|
||||||
{} lookup_token(const StringRef &name) {{
|
{} lookup_token(const std::string_view &name) {{
|
||||||
switch (name.size()) {{'''.format(return_type))
|
switch (name.size()) {{'''.format(return_type))
|
||||||
b = build_header(tokens)
|
b = build_header(tokens)
|
||||||
for size in sorted(b.keys()):
|
for size in sorted(b.keys()):
|
||||||
@@ -50,7 +50,7 @@ def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
|
|||||||
case '{}':'''.format(c))
|
case '{}':'''.format(c))
|
||||||
for k in headers:
|
for k in headers:
|
||||||
print('''\
|
print('''\
|
||||||
if ({}("{}"_sr, name, {})) {{
|
if ({}("{}"sv, name.substr(0, {}))) {{
|
||||||
return {};
|
return {};
|
||||||
}}'''.format(comp_fun, k[:-1], size - 1, to_enum_hd(k, prefix)))
|
}}'''.format(comp_fun, k[:-1], size - 1, to_enum_hd(k, prefix)))
|
||||||
print('''\
|
print('''\
|
||||||
|
|||||||
23
go.mod
23
go.mod
@@ -1,25 +1,20 @@
|
|||||||
module github.com/nghttp2/nghttp2
|
module github.com/nghttp2/nghttp2
|
||||||
|
|
||||||
go 1.22.0
|
go 1.24.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
|
||||||
github.com/quic-go/quic-go v0.49.0
|
github.com/quic-go/quic-go v0.55.0
|
||||||
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8
|
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8
|
||||||
golang.org/x/net v0.35.0
|
golang.org/x/net v0.46.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
|
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
|
|
||||||
github.com/quic-go/qpack v0.5.1 // indirect
|
github.com/quic-go/qpack v0.5.1 // indirect
|
||||||
go.uber.org/mock v0.5.0 // indirect
|
golang.org/x/crypto v0.43.0 // indirect
|
||||||
golang.org/x/crypto v0.33.0 // indirect
|
golang.org/x/mod v0.28.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
golang.org/x/sync v0.17.0 // indirect
|
||||||
golang.org/x/mod v0.18.0 // indirect
|
golang.org/x/sys v0.37.0 // indirect
|
||||||
golang.org/x/sync v0.11.0 // indirect
|
golang.org/x/text v0.30.0 // indirect
|
||||||
golang.org/x/sys v0.30.0 // indirect
|
golang.org/x/tools v0.37.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
|
||||||
golang.org/x/tools v0.22.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
64
go.sum
64
go.sum
@@ -1,62 +1,34 @@
|
|||||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
|
||||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
|
|
||||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
|
|
||||||
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
|
|
||||||
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
|
|
||||||
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||||
github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=
|
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
|
||||||
github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
|
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8 h1:zKJxuRe+a0O34V81GAZWOrotuU6mveT30QLjJ7OPMMg=
|
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8 h1:zKJxuRe+a0O34V81GAZWOrotuU6mveT30QLjJ7OPMMg=
|
||||||
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8/go.mod h1:gTqc3Q4boc+cKRlSFywTYdX9t6VGRcsThlNIWwaL3Dc=
|
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8/go.mod h1:gTqc3Q4boc+cKRlSFywTYdX9t6VGRcsThlNIWwaL3Dc=
|
||||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
|
||||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
|
||||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
|
||||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
|
||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
|
||||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
|
||||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
|
||||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
|
||||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
|
||||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|||||||
@@ -882,12 +882,39 @@ func TestH1H1CONNECTMethodFailure(t *testing.T) {
|
|||||||
if _, err := io.ReadAll(resp.Body); err != nil {
|
if _, err := io.ReadAll(resp.Body); err != nil {
|
||||||
t.Fatalf("Error io.ReadAll() = %v", err)
|
t.Fatalf("Error io.ReadAll() = %v", err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := io.WriteString(st.conn, "CONNECT 127.0.0.1:443 HTTP/1.1\r\nTest-Case: TestH1H1CONNECTMethodFailure\r\nHost: 127.0.0.1:443\r\nrequired-header: foo\r\n\r\n"); err != nil {
|
// TestH1H1CONNECTMethod tests that CONNECT request succeeds.
|
||||||
|
func TestH1H1CONNECTMethod(t *testing.T) {
|
||||||
|
opts := options{
|
||||||
|
handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
hj, ok := w.(http.Hijacker)
|
||||||
|
if !ok {
|
||||||
|
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, bufrw, err := hj.Hijack()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := bufrw.WriteString("HTTP/1.1 200\r\n\r\n"); err != nil {
|
||||||
|
t.Fatalf("Error bufrw.WriteString() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bufrw.Flush()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
st := newServerTester(t, opts)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
if _, err := io.WriteString(st.conn, "CONNECT 127.0.0.1:443 HTTP/1.1\r\nTest-Case: TestH1H1CONNECTMethod\r\nHost: 127.0.0.1:443\r\n\r\n"); err != nil {
|
||||||
t.Fatalf("Error io.WriteString() = %v", err)
|
t.Fatalf("Error io.WriteString() = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err = http.ReadResponse(bufio.NewReader(st.conn), nil)
|
resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error http.ReadResponse() = %v", err)
|
t.Fatalf("Error http.ReadResponse() = %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1334,7 +1334,6 @@ func TestH2H1Upgrade(t *testing.T) {
|
|||||||
pair("HTTP2-Settings", "AAMAAABkAAQAAP__"),
|
pair("HTTP2-Settings", "AAMAAABkAAQAAP__"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error st.http1() = %v", err)
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ func newServerTester(t *testing.T, opts options) *serverTester {
|
|||||||
b := "-b"
|
b := "-b"
|
||||||
|
|
||||||
if !externalDNS {
|
if !externalDNS {
|
||||||
b += fmt.Sprintf("%v;", strings.Replace(backendURL.Host, ":", ",", -1))
|
b += fmt.Sprintf("%v;", strings.ReplaceAll(backendURL.Host, ":", ","))
|
||||||
} else {
|
} else {
|
||||||
sep := strings.LastIndex(backendURL.Host, ":")
|
sep := strings.LastIndex(backendURL.Host, ":")
|
||||||
if sep == -1 {
|
if sep == -1 {
|
||||||
@@ -170,6 +170,8 @@ func newServerTester(t *testing.T, opts options) *serverTester {
|
|||||||
|
|
||||||
// We use awesome service nip.io.
|
// We use awesome service nip.io.
|
||||||
b += fmt.Sprintf("%v.nip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
|
b += fmt.Sprintf("%v.nip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
|
||||||
|
// Make external DNS tests less flaky.
|
||||||
|
args = append(args, "--backend-address-family=IPv4")
|
||||||
}
|
}
|
||||||
|
|
||||||
if backendTLS {
|
if backendTLS {
|
||||||
@@ -206,7 +208,19 @@ func newServerTester(t *testing.T, opts options) *serverTester {
|
|||||||
if opts.quic {
|
if opts.quic {
|
||||||
args = append(args,
|
args = append(args,
|
||||||
fmt.Sprintf("-f127.0.0.1,%v;quic", serverPort),
|
fmt.Sprintf("-f127.0.0.1,%v;quic", serverPort),
|
||||||
"--no-quic-bpf")
|
"--no-quic-bpf",
|
||||||
|
// quic-go client just closes connection after
|
||||||
|
// receiving the first GOAWAY without any
|
||||||
|
// indication like sending CONNECTION_CLOSE if
|
||||||
|
// there is no active stream. If that
|
||||||
|
// happens, server keeps resending 2nd GOAWAY
|
||||||
|
// until idle timeout passes. If that happens
|
||||||
|
// during Close(), the process will be killed
|
||||||
|
// because the default idle timeout is longer
|
||||||
|
// than the close timeout. Shorten the idle
|
||||||
|
// timeout to prevent it from happening.
|
||||||
|
"--frontend-quic-idle-timeout=5",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
authority := fmt.Sprintf("127.0.0.1:%v", opts.connectPort)
|
authority := fmt.Sprintf("127.0.0.1:%v", opts.connectPort)
|
||||||
@@ -309,14 +323,14 @@ func (st *serverTester) Close() {
|
|||||||
close(done)
|
close(done)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := st.cmd.Process.Signal(syscall.SIGQUIT); err != nil {
|
if err := st.cmd.Process.Signal(syscall.SIGQUIT); err != nil && !errors.Is(err, os.ErrProcessDone) {
|
||||||
st.t.Errorf("Error st.cmd.Process.Signal() = %v", err)
|
st.t.Errorf("Error st.cmd.Process.Signal() = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
case <-time.After(10 * time.Second):
|
case <-time.After(10 * time.Second):
|
||||||
if err := st.cmd.Process.Kill(); err != nil {
|
if err := st.cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) {
|
||||||
st.t.Errorf("Error st.cmd.Process.Kill() = %v", err)
|
st.t.Errorf("Error st.cmd.Process.Kill() = %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,7 +645,7 @@ loop:
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sr, ok := streams[f.FrameHeader.StreamID]
|
sr, ok := streams[f.StreamID]
|
||||||
if !ok {
|
if !ok {
|
||||||
st.header = make(http.Header)
|
st.header = make(http.Header)
|
||||||
break
|
break
|
||||||
@@ -643,7 +657,7 @@ loop:
|
|||||||
|
|
||||||
status, err = strconv.Atoi(sr.header.Get(":status"))
|
status, err = strconv.Atoi(sr.header.Get(":status"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, fmt.Errorf("Error parsing status code: %w", err)
|
return res, fmt.Errorf("could not parse :status: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sr.status = status
|
sr.status = status
|
||||||
@@ -664,7 +678,7 @@ loop:
|
|||||||
|
|
||||||
streams[sr.streamID] = sr
|
streams[sr.streamID] = sr
|
||||||
case *http2.DataFrame:
|
case *http2.DataFrame:
|
||||||
sr, ok := streams[f.FrameHeader.StreamID]
|
sr, ok := streams[f.StreamID]
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -675,7 +689,7 @@ loop:
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
case *http2.RSTStreamFrame:
|
case *http2.RSTStreamFrame:
|
||||||
sr, ok := streams[f.FrameHeader.StreamID]
|
sr, ok := streams[f.StreamID]
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (st *serverTester) http3(rp requestParam) (*serverResponse, error) {
|
func (st *serverTester) http3(rp requestParam) (*serverResponse, error) {
|
||||||
rt := &http3.RoundTripper{
|
rt := &http3.Transport{
|
||||||
TLSClientConfig: &tls.Config{
|
TLSClientConfig: &tls.Config{
|
||||||
InsecureSkipVerify: true,
|
InsecureSkipVerify: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -47,7 +47,29 @@ if(WIN32)
|
|||||||
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(EXPORT_SET "${PROJECT_NAME}-targets")
|
set(NGHTTP2_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
|
||||||
|
set(NGHTTP2_VERSION_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
|
||||||
|
set(NGHTTP2_PROJECT_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
|
||||||
|
set(NGHTTP2_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
|
||||||
|
set(NGHTTP2_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
|
||||||
|
set(NGHTTP2_NAMESPACE "${PROJECT_NAME}::")
|
||||||
|
set(NGHTTP2_VERSION ${PROJECT_VERSION})
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
write_basic_package_version_file(
|
||||||
|
"${NGHTTP2_VERSION_CONFIG}" VERSION ${NGHTTP2_VERSION} COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in" "${NGHTTP2_PROJECT_CONFIG}" @ONLY)
|
||||||
|
|
||||||
|
# Install cmake config files
|
||||||
|
install(
|
||||||
|
FILES "${NGHTTP2_PROJECT_CONFIG}" "${NGHTTP2_VERSION_CONFIG}"
|
||||||
|
DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT "${NGHTTP2_TARGETS_EXPORT_NAME}"
|
||||||
|
NAMESPACE "${NGHTTP2_NAMESPACE}"
|
||||||
|
DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
|
||||||
|
|
||||||
# Public shared library
|
# Public shared library
|
||||||
if(BUILD_SHARED_LIBS)
|
if(BUILD_SHARED_LIBS)
|
||||||
@@ -65,7 +87,11 @@ if(BUILD_SHARED_LIBS)
|
|||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS ${SHARED_LIB} EXPORT ${EXPORT_SET})
|
install(TARGETS ${SHARED_LIB}
|
||||||
|
EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
|
||||||
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||||
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||||
list(APPEND nghttp2_exports ${SHARED_LIB})
|
list(APPEND nghttp2_exports ${SHARED_LIB})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -87,7 +113,9 @@ if(BUILD_STATIC_LIBS)
|
|||||||
|
|
||||||
target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB")
|
target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB")
|
||||||
|
|
||||||
install(TARGETS ${STATIC_LIB} EXPORT ${EXPORT_SET})
|
install(TARGETS ${STATIC_LIB}
|
||||||
|
EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
|
||||||
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
list(APPEND nghttp2_exports ${STATIC_LIB})
|
list(APPEND nghttp2_exports ${STATIC_LIB})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -97,11 +125,7 @@ else()
|
|||||||
set(LIB_SELECTED ${STATIC_LIB})
|
set(LIB_SELECTED ${STATIC_LIB})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(${PROJECT_NAME}::nghttp2 ALIAS ${LIB_SELECTED})
|
add_library(nghttp2 ALIAS ${LIB_SELECTED})
|
||||||
|
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
|
||||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
|
|
||||||
install(EXPORT ${EXPORT_SET}
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
|
|
||||||
NAMESPACE ${PROJECT_NAME}::)
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
SUBDIRS = includes
|
SUBDIRS = includes
|
||||||
|
|
||||||
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
|
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in
|
||||||
|
|
||||||
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
||||||
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
||||||
|
|||||||
3
lib/config.cmake.in
Normal file
3
lib/config.cmake.in
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
include(CMakeFindDependencyMacro)
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/@NGHTTP2_TARGETS_EXPORT_NAME@.cmake")
|
||||||
@@ -2039,18 +2039,19 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
|
|||||||
/**
|
/**
|
||||||
* @functypedef
|
* @functypedef
|
||||||
*
|
*
|
||||||
* Callback function invoked when a invalid header name/value pair is
|
* Callback function invoked when an invalid header name/value pair is
|
||||||
* received for the |frame|.
|
* received for the |frame|.
|
||||||
*
|
*
|
||||||
* The parameter and behaviour are similar to
|
* The parameter and behaviour are similar to
|
||||||
* :type:`nghttp2_on_header_callback`. The difference is that this
|
* :type:`nghttp2_on_header_callback`. The difference is that this
|
||||||
* callback is only invoked when a invalid header name/value pair is
|
* callback is only invoked when an invalid header name/value pair is
|
||||||
* received which is treated as stream error if this callback is not
|
* received which is treated as stream error if this callback returns
|
||||||
* set. Only invalid regular header field are passed to this
|
* :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and
|
||||||
* callback. In other words, invalid pseudo header field is not
|
* :type:`nghttp2_on_invalid_header_callback2` is not set. Only
|
||||||
* passed to this callback. Also header fields which includes upper
|
* invalid regular header field are passed to this callback. In other
|
||||||
* cased latter are also treated as error without passing them to this
|
* words, invalid pseudo header field is not passed to this callback.
|
||||||
* 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
|
* This callback is only considered if HTTP messaging validation is
|
||||||
* turned on (which is on by default, see
|
* turned on (which is on by default, see
|
||||||
@@ -2076,17 +2077,18 @@ typedef int (*nghttp2_on_invalid_header_callback)(
|
|||||||
/**
|
/**
|
||||||
* @functypedef
|
* @functypedef
|
||||||
*
|
*
|
||||||
* Callback function invoked when a invalid header name/value pair is
|
* Callback function invoked when an invalid header name/value pair is
|
||||||
* received for the |frame|.
|
* received for the |frame|.
|
||||||
*
|
*
|
||||||
* The parameter and behaviour are similar to
|
* The parameter and behaviour are similar to
|
||||||
* :type:`nghttp2_on_header_callback2`. The difference is that this
|
* :type:`nghttp2_on_header_callback2`. The difference is that this
|
||||||
* callback is only invoked when a invalid header name/value pair is
|
* callback is only invoked when an invalid header name/value pair is
|
||||||
* received which is silently ignored if this callback is not set.
|
* received which is silently ignored if neither this callback nor
|
||||||
* Only invalid regular header field are passed to this callback. In
|
* :type:`nghttp2_on_invalid_header_callback` is set. Only invalid
|
||||||
* other words, invalid pseudo header field is not passed to this
|
* regular header field are passed to this callback. In other words,
|
||||||
* callback. Also header fields which includes upper cased latter are
|
* invalid pseudo header field is not passed to this callback. Also
|
||||||
* also treated as error without passing them to this callback.
|
* 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
|
* This callback is only considered if HTTP messaging validation is
|
||||||
* turned on (which is on by default, see
|
* turned on (which is on by default, see
|
||||||
@@ -2445,6 +2447,15 @@ typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
|
|||||||
int lib_error_code, const char *msg,
|
int lib_error_code, const char *msg,
|
||||||
size_t len, void *user_data);
|
size_t len, void *user_data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @functypedef
|
||||||
|
*
|
||||||
|
* Callback function invoked when unpredictable data of |destlen|
|
||||||
|
* bytes are needed. The implementation must write unpredictable data
|
||||||
|
* of |destlen| bytes into the buffer pointed by |dest|.
|
||||||
|
*/
|
||||||
|
typedef void (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen);
|
||||||
|
|
||||||
struct nghttp2_session_callbacks;
|
struct nghttp2_session_callbacks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2649,7 +2660,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
|
|||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
* Sets callback function invoked when a invalid header name/value
|
* Sets callback function invoked when an invalid header name/value
|
||||||
* pair is received. If both
|
* pair is received. If both
|
||||||
* `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
|
* `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
|
||||||
* `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
|
* `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
|
||||||
@@ -2662,7 +2673,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
|
|||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
* Sets callback function invoked when a invalid header name/value
|
* Sets callback function invoked when an invalid header name/value
|
||||||
* pair is received.
|
* pair is received.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
||||||
@@ -2833,6 +2844,18 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
|
|||||||
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
|
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
|
||||||
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
|
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* Sets callback function invoked when unpredictable data is needed.
|
||||||
|
* Although this callback is optional due to the backward
|
||||||
|
* compatibility, it is recommended to specify it to harden the
|
||||||
|
* runtime behavior against suspicious activities of a remote
|
||||||
|
* endpoint.
|
||||||
|
*/
|
||||||
|
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback(
|
||||||
|
nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @functypedef
|
* @functypedef
|
||||||
*
|
*
|
||||||
@@ -3218,6 +3241,23 @@ nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
|
|||||||
NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
|
NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
|
||||||
size_t val);
|
size_t val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* This function sets the rate limit for the "glitches", the
|
||||||
|
* suspicious activities from a remote endpoint. It is a token-bucket
|
||||||
|
* based rate limiter. |burst| specifies the number of tokens that is
|
||||||
|
* initially available. The maximum number of tokens is capped to
|
||||||
|
* this value. |rate| specifies the number of tokens that are
|
||||||
|
* regenerated per second. When a suspicious activity is detected,
|
||||||
|
* some amount of tokens are consumed. If there is no token
|
||||||
|
* available, GOAWAY is sent to tear down the connection. |burst| and
|
||||||
|
* |rate| default to 1000 and 33 respectively.
|
||||||
|
*/
|
||||||
|
NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
|
||||||
|
uint64_t burst,
|
||||||
|
uint64_t rate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -27,8 +27,8 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#endif /* NGHTTP2_ALPN_H */
|
#endif /* !defined(NGHTTP2_ALPN_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -409,4 +409,4 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
|||||||
*/
|
*/
|
||||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||||
|
|
||||||
#endif /* NGHTTP2_BUF_H */
|
#endif /* !defined(NGHTTP2_BUF_H) */
|
||||||
|
|||||||
@@ -201,3 +201,8 @@ void nghttp2_session_callbacks_set_error_callback2(
|
|||||||
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
|
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
|
||||||
cbs->error_callback2 = error_callback2;
|
cbs->error_callback2 = error_callback2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nghttp2_session_callbacks_set_rand_callback(
|
||||||
|
nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) {
|
||||||
|
cbs->rand_callback = rand_callback;
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -151,6 +151,7 @@ struct nghttp2_session_callbacks {
|
|||||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
||||||
nghttp2_error_callback error_callback;
|
nghttp2_error_callback error_callback;
|
||||||
nghttp2_error_callback2 error_callback2;
|
nghttp2_error_callback2 error_callback2;
|
||||||
|
nghttp2_rand_callback rand_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NGHTTP2_CALLBACKS_H */
|
#endif /* !defined(NGHTTP2_CALLBACKS_H) */
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ void nghttp2_set_debug_vprintf_callback(
|
|||||||
static_debug_vprintf_callback = debug_vprintf_callback;
|
static_debug_vprintf_callback = debug_vprintf_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !DEBUGBUILD */
|
#else /* !defined(DEBUGBUILD) */
|
||||||
|
|
||||||
void nghttp2_set_debug_vprintf_callback(
|
void nghttp2_set_debug_vprintf_callback(
|
||||||
nghttp2_debug_vprintf_callback debug_vprintf_callback) {
|
nghttp2_debug_vprintf_callback debug_vprintf_callback) {
|
||||||
(void)debug_vprintf_callback;
|
(void)debug_vprintf_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !DEBUGBUILD */
|
#endif /* !defined(DEBUGBUILD) */
|
||||||
|
|||||||
@@ -27,17 +27,17 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#ifdef DEBUGBUILD
|
#ifdef DEBUGBUILD
|
||||||
# define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
|
# define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
|
||||||
void nghttp2_debug_vprintf(const char *format, ...);
|
void nghttp2_debug_vprintf(const char *format, ...);
|
||||||
#else
|
#else /* !defined(DEBUGBUILD) */
|
||||||
# define DEBUGF(...) \
|
# define DEBUGF(...) \
|
||||||
do { \
|
do { \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif /* !defined(DEBUGBUILD) */
|
||||||
|
|
||||||
#endif /* NGHTTP2_DEBUG_H */
|
#endif /* !defined(NGHTTP2_DEBUG_H) */
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -62,4 +62,4 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri);
|
|||||||
*/
|
*/
|
||||||
#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0)
|
#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0)
|
||||||
|
|
||||||
#endif /* NGHTTP2_EXTPRI_H */
|
#endif /* !defined(NGHTTP2_EXTPRI_H) */
|
||||||
|
|||||||
@@ -27,17 +27,14 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#include "nghttp2_hd.h"
|
#include "nghttp2_hd.h"
|
||||||
#include "nghttp2_buf.h"
|
#include "nghttp2_buf.h"
|
||||||
|
|
||||||
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
|
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
|
||||||
#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
|
|
||||||
#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
|
|
||||||
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
|
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
|
||||||
#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
|
|
||||||
|
|
||||||
/* The number of bytes of frame header. */
|
/* The number of bytes of frame header. */
|
||||||
#define NGHTTP2_FRAME_HDLEN 9
|
#define NGHTTP2_FRAME_HDLEN 9
|
||||||
@@ -634,4 +631,4 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
|
|||||||
void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||||
size_t padlen, int framehd_only);
|
size_t padlen, int framehd_only);
|
||||||
|
|
||||||
#endif /* NGHTTP2_FRAME_H */
|
#endif /* !defined(NGHTTP2_FRAME_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -439,4 +439,4 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
|||||||
*/
|
*/
|
||||||
int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
|
int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_H */
|
#endif /* !defined(NGHTTP2_HD_H) */
|
||||||
|
|||||||
@@ -104,15 +104,15 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
|
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
|
||||||
ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
|
ctx->fstate = 0;
|
||||||
|
ctx->flags = NGHTTP2_HUFF_ACCEPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||||
nghttp2_buf *buf, const uint8_t *src,
|
nghttp2_buf *buf, const uint8_t *src,
|
||||||
size_t srclen, int final) {
|
size_t srclen, int final) {
|
||||||
const uint8_t *end = src + srclen;
|
const uint8_t *end = src + srclen;
|
||||||
nghttp2_huff_decode node = {ctx->fstate, 0};
|
nghttp2_huff_decode t = {ctx->fstate, ctx->flags, 0};
|
||||||
const nghttp2_huff_decode *t = &node;
|
|
||||||
uint8_t c;
|
uint8_t c;
|
||||||
|
|
||||||
/* We use the decoding algorithm described in
|
/* We use the decoding algorithm described in
|
||||||
@@ -121,20 +121,21 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
|||||||
- https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
|
- https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
|
||||||
for (; src != end;) {
|
for (; src != end;) {
|
||||||
c = *src++;
|
c = *src++;
|
||||||
t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
|
t = huff_decode_table[t.fstate][c >> 4];
|
||||||
if (t->fstate & NGHTTP2_HUFF_SYM) {
|
if (t.flags & NGHTTP2_HUFF_SYM) {
|
||||||
*buf->last++ = t->sym;
|
*buf->last++ = t.sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf];
|
t = huff_decode_table[t.fstate][c & 0xf];
|
||||||
if (t->fstate & NGHTTP2_HUFF_SYM) {
|
if (t.flags & NGHTTP2_HUFF_SYM) {
|
||||||
*buf->last++ = t->sym;
|
*buf->last++ = t.sym;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->fstate = t->fstate;
|
ctx->fstate = t.fstate;
|
||||||
|
ctx->flags = t.flags;
|
||||||
|
|
||||||
if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) {
|
if (final && !(ctx->flags & NGHTTP2_HUFF_ACCEPTED)) {
|
||||||
return NGHTTP2_ERR_HEADER_COMP;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,16 +27,16 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* FSA accepts this state as the end of huffman encoding
|
/* FSA accepts this state as the end of huffman encoding
|
||||||
sequence. */
|
sequence. */
|
||||||
NGHTTP2_HUFF_ACCEPTED = 1 << 14,
|
NGHTTP2_HUFF_ACCEPTED = 1,
|
||||||
/* This state emits symbol */
|
/* This state emits symbol */
|
||||||
NGHTTP2_HUFF_SYM = 1 << 15,
|
NGHTTP2_HUFF_SYM = 1 << 1,
|
||||||
} nghttp2_huff_decode_flag;
|
} nghttp2_huff_decode_flag;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -48,6 +48,7 @@ typedef struct {
|
|||||||
a special node and it is a terminal state that means decoding
|
a special node and it is a terminal state that means decoding
|
||||||
failed. */
|
failed. */
|
||||||
uint16_t fstate;
|
uint16_t fstate;
|
||||||
|
uint8_t flags;
|
||||||
/* symbol if NGHTTP2_HUFF_SYM flag set */
|
/* symbol if NGHTTP2_HUFF_SYM flag set */
|
||||||
uint8_t sym;
|
uint8_t sym;
|
||||||
} nghttp2_huff_decode;
|
} nghttp2_huff_decode;
|
||||||
@@ -57,6 +58,7 @@ typedef nghttp2_huff_decode huff_decode_table_type[16];
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* fstate is the current huffman decoding state. */
|
/* fstate is the current huffman decoding state. */
|
||||||
uint16_t fstate;
|
uint16_t fstate;
|
||||||
|
uint8_t flags;
|
||||||
} nghttp2_hd_huff_decode_context;
|
} nghttp2_hd_huff_decode_context;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -69,4 +71,4 @@ typedef struct {
|
|||||||
extern const nghttp2_huff_sym huff_sym_table[];
|
extern const nghttp2_huff_sym huff_sym_table[];
|
||||||
extern const nghttp2_huff_decode huff_decode_table[][16];
|
extern const nghttp2_huff_decode huff_decode_table[][16];
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_HUFFMAN_H */
|
#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -142,4 +142,4 @@ int nghttp2_should_send_window_update(int32_t local_window_size,
|
|||||||
*/
|
*/
|
||||||
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
|
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HELPER_H */
|
#endif /* !defined(NGHTTP2_HELPER_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#include "nghttp2_session.h"
|
#include "nghttp2_session.h"
|
||||||
@@ -97,4 +97,4 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream,
|
|||||||
int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
|
int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
|
||||||
size_t valuelen);
|
size_t valuelen);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HTTP_H */
|
#endif /* !defined(NGHTTP2_HTTP_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -39,7 +39,6 @@ typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
|||||||
/* Internal error code. They must be in the range [-499, -100],
|
/* Internal error code. They must be in the range [-499, -100],
|
||||||
inclusive. */
|
inclusive. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
|
|
||||||
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
|
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
|
||||||
NGHTTP2_ERR_IGN_PAYLOAD = -104,
|
NGHTTP2_ERR_IGN_PAYLOAD = -104,
|
||||||
/*
|
/*
|
||||||
@@ -52,7 +51,11 @@ typedef enum {
|
|||||||
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
|
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
|
||||||
* nghttp2_on_invalid_header_callback.
|
* nghttp2_on_invalid_header_callback.
|
||||||
*/
|
*/
|
||||||
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
|
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106,
|
||||||
|
/*
|
||||||
|
* Cancel pushed stream.
|
||||||
|
*/
|
||||||
|
NGHTTP2_ERR_PUSH_CANCEL = -107,
|
||||||
} nghttp2_internal_error;
|
} nghttp2_internal_error;
|
||||||
|
|
||||||
#endif /* NGHTTP2_INT_H */
|
#endif /* !defined(NGHTTP2_INT_H) */
|
||||||
|
|||||||
@@ -31,13 +31,13 @@
|
|||||||
|
|
||||||
#include "nghttp2_helper.h"
|
#include "nghttp2_helper.h"
|
||||||
|
|
||||||
#define NGHTTP2_INITIAL_TABLE_LENBITS 4
|
#define NGHTTP2_INITIAL_HASHBITS 4
|
||||||
|
|
||||||
void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
|
void nghttp2_map_init(nghttp2_map *map, uint64_t seed, nghttp2_mem *mem) {
|
||||||
map->mem = mem;
|
*map = (nghttp2_map){
|
||||||
map->hashbits = 0;
|
.mem = mem,
|
||||||
map->table = NULL;
|
.seed = seed,
|
||||||
map->size = 0;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_map_free(nghttp2_map *map) {
|
void nghttp2_map_free(nghttp2_map *map) {
|
||||||
@@ -45,30 +45,27 @@ void nghttp2_map_free(nghttp2_map *map) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_mem_free(map->mem, map->table);
|
nghttp2_mem_free(map->mem, map->keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
|
int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
|
||||||
void *ptr) {
|
void *ptr) {
|
||||||
int rv;
|
int rv;
|
||||||
size_t i;
|
size_t i;
|
||||||
nghttp2_map_bucket *bkt;
|
|
||||||
size_t tablelen;
|
size_t tablelen;
|
||||||
|
|
||||||
if (map->size == 0) {
|
if (map->size == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tablelen = 1u << map->hashbits;
|
tablelen = (size_t)1 << map->hashbits;
|
||||||
|
|
||||||
for (i = 0; i < tablelen; ++i) {
|
for (i = 0; i < tablelen; ++i) {
|
||||||
bkt = &map->table[i];
|
if (map->psl[i] == 0) {
|
||||||
|
|
||||||
if (bkt->data == NULL) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = func(bkt->data, ptr);
|
rv = func(map->data[i], ptr);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -77,164 +74,230 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t hash(nghttp2_map_key_type key, size_t bits) {
|
/* Hasher from
|
||||||
return (size_t)(((uint32_t)key * 2654435769u) >> (32 - bits));
|
https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
|
||||||
}
|
to maximize the output's sensitivity to all input bits. */
|
||||||
|
#define NGHTTP2_MAP_HASHER 0xf1357aea2e62a9c5ull
|
||||||
|
/* 64-bit Fibonacci hashing constant, Golden Ratio constant, to get
|
||||||
|
the high bits with the good distribution. */
|
||||||
|
#define NGHTTP2_MAP_FIBO 0x9e3779b97f4a7c15ull
|
||||||
|
|
||||||
static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) {
|
static size_t map_index(const nghttp2_map *map, nghttp2_map_key_type key32) {
|
||||||
nghttp2_map_bucket c = *a;
|
uint64_t key = (uint64_t)key32;
|
||||||
|
|
||||||
*a = *b;
|
key += map->seed;
|
||||||
*b = c;
|
key *= NGHTTP2_MAP_HASHER;
|
||||||
|
return (size_t)((key * NGHTTP2_MAP_FIBO) >> (64 - map->hashbits));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
void nghttp2_map_print_distance(const nghttp2_map *map) {
|
void nghttp2_map_print_distance(const nghttp2_map *map) {
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t idx;
|
size_t idx;
|
||||||
nghttp2_map_bucket *bkt;
|
|
||||||
size_t tablelen;
|
size_t tablelen;
|
||||||
|
|
||||||
if (map->size == 0) {
|
if (map->size == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tablelen = 1u << map->hashbits;
|
tablelen = (size_t)1 << map->hashbits;
|
||||||
|
|
||||||
for (i = 0; i < tablelen; ++i) {
|
for (i = 0; i < tablelen; ++i) {
|
||||||
bkt = &map->table[i];
|
if (map->psl[i] == 0) {
|
||||||
|
|
||||||
if (bkt->data == NULL) {
|
|
||||||
fprintf(stderr, "@%zu <EMPTY>\n", i);
|
fprintf(stderr, "@%zu <EMPTY>\n", i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = hash(bkt->key, map->hashbits);
|
idx = map_index(map, map->keys[i]);
|
||||||
fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i,
|
fprintf(stderr, "@%zu key=%d base=%zu distance=%u\n", i, map->keys[i], idx,
|
||||||
hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl);
|
map->psl[i] - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !WIN32 */
|
#endif /* !defined(WIN32) */
|
||||||
|
|
||||||
static int insert(nghttp2_map_bucket *table, size_t hashbits,
|
static void map_set_entry(nghttp2_map *map, size_t idx,
|
||||||
nghttp2_map_key_type key, void *data) {
|
nghttp2_map_key_type key, void *data, size_t psl) {
|
||||||
size_t idx = hash(key, hashbits);
|
map->keys[idx] = key;
|
||||||
nghttp2_map_bucket b = {0, key, data}, *bkt;
|
map->data[idx] = data;
|
||||||
size_t mask = (1u << hashbits) - 1;
|
map->psl[idx] = (uint8_t)psl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NGHTTP2_SWAP(TYPE, A, B) \
|
||||||
|
do { \
|
||||||
|
TYPE t = (TYPE) * (A); \
|
||||||
|
\
|
||||||
|
*(A) = *(B); \
|
||||||
|
*(B) = t; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* map_insert inserts |key| and |data| to |map|, and returns the index
|
||||||
|
* where the pair is stored if it succeeds. Otherwise, it returns one
|
||||||
|
* of the following negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||||
|
* The another data associated to |key| is already present.
|
||||||
|
*/
|
||||||
|
static nghttp2_ssize map_insert(nghttp2_map *map, nghttp2_map_key_type key,
|
||||||
|
void *data) {
|
||||||
|
size_t idx = map_index(map, key);
|
||||||
|
size_t mask = ((size_t)1 << map->hashbits) - 1;
|
||||||
|
size_t psl = 1;
|
||||||
|
size_t kpsl;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bkt = &table[idx];
|
kpsl = map->psl[idx];
|
||||||
|
|
||||||
if (bkt->data == NULL) {
|
if (kpsl == 0) {
|
||||||
*bkt = b;
|
map_set_entry(map, idx, key, data, psl);
|
||||||
return 0;
|
++map->size;
|
||||||
|
|
||||||
|
return (nghttp2_ssize)idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b.psl > bkt->psl) {
|
if (psl > kpsl) {
|
||||||
map_bucket_swap(bkt, &b);
|
NGHTTP2_SWAP(nghttp2_map_key_type, &key, &map->keys[idx]);
|
||||||
} else if (bkt->key == key) {
|
NGHTTP2_SWAP(void *, &data, &map->data[idx]);
|
||||||
/* TODO This check is just a waste after first swap or if this
|
NGHTTP2_SWAP(uint8_t, &psl, &map->psl[idx]);
|
||||||
function is called from map_resize. That said, there is no
|
} else if (map->keys[idx] == key) {
|
||||||
difference with or without this conditional in performance
|
/* This check ensures that no duplicate keys are inserted. But
|
||||||
wise. */
|
it is just a waste after first swap or if this function is
|
||||||
|
called from map_resize. That said, there is no difference
|
||||||
|
with or without this conditional in performance wise. */
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
++b.psl;
|
++psl;
|
||||||
idx = (idx + 1) & mask;
|
idx = (idx + 1) & mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NGHTTP2_MAP_MAX_HASHBITS is the maximum number of bits used for
|
||||||
|
hash table. The theoretical limit of the maximum number of keys
|
||||||
|
that can be stored is 1 << NGHTTP2_MAP_MAX_HASHBITS. */
|
||||||
|
#define NGHTTP2_MAP_MAX_HASHBITS (sizeof(size_t) * 8 - 1)
|
||||||
|
|
||||||
static int map_resize(nghttp2_map *map, size_t new_hashbits) {
|
static int map_resize(nghttp2_map *map, size_t new_hashbits) {
|
||||||
size_t i;
|
size_t i;
|
||||||
nghttp2_map_bucket *new_table;
|
|
||||||
nghttp2_map_bucket *bkt;
|
|
||||||
size_t tablelen;
|
size_t tablelen;
|
||||||
int rv;
|
nghttp2_ssize idx;
|
||||||
(void)rv;
|
nghttp2_map new_map = {
|
||||||
|
.mem = map->mem,
|
||||||
|
.seed = map->seed,
|
||||||
|
.hashbits = new_hashbits,
|
||||||
|
};
|
||||||
|
void *buf;
|
||||||
|
(void)idx;
|
||||||
|
|
||||||
new_table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
|
if (new_hashbits > NGHTTP2_MAP_MAX_HASHBITS) {
|
||||||
sizeof(nghttp2_map_bucket));
|
|
||||||
if (new_table == NULL) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tablelen = (size_t)1 << new_hashbits;
|
||||||
|
|
||||||
|
buf = nghttp2_mem_calloc(map->mem, tablelen,
|
||||||
|
sizeof(nghttp2_map_key_type) + sizeof(void *) +
|
||||||
|
sizeof(uint8_t));
|
||||||
|
if (buf == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_map.keys = buf;
|
||||||
|
new_map.data =
|
||||||
|
(void *)((uint8_t *)new_map.keys + tablelen * sizeof(nghttp2_map_key_type));
|
||||||
|
new_map.psl = (uint8_t *)new_map.data + tablelen * sizeof(void *);
|
||||||
|
|
||||||
if (map->size) {
|
if (map->size) {
|
||||||
tablelen = 1u << map->hashbits;
|
tablelen = (size_t)1 << map->hashbits;
|
||||||
|
|
||||||
for (i = 0; i < tablelen; ++i) {
|
for (i = 0; i < tablelen; ++i) {
|
||||||
bkt = &map->table[i];
|
if (map->psl[i] == 0) {
|
||||||
if (bkt->data == NULL) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = insert(new_table, new_hashbits, bkt->key, bkt->data);
|
idx = map_insert(&new_map, map->keys[i], map->data[i]);
|
||||||
|
|
||||||
assert(0 == rv);
|
/* map_insert must not fail because all keys are unique during
|
||||||
|
resize. */
|
||||||
|
assert(idx >= 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_mem_free(map->mem, map->table);
|
nghttp2_mem_free(map->mem, map->keys);
|
||||||
|
map->keys = new_map.keys;
|
||||||
|
map->data = new_map.data;
|
||||||
|
map->psl = new_map.psl;
|
||||||
map->hashbits = new_hashbits;
|
map->hashbits = new_hashbits;
|
||||||
map->table = new_table;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NGHTTP2_MAX_PSL_RESIZE_THRESH is the maximum psl threshold. If
|
||||||
|
reached, resize the table. */
|
||||||
|
#define NGHTTP2_MAX_PSL_RESIZE_THRESH 128
|
||||||
|
|
||||||
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
|
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
|
||||||
int rv;
|
int rv;
|
||||||
|
size_t tablelen;
|
||||||
|
nghttp2_ssize idx;
|
||||||
|
|
||||||
assert(data);
|
assert(data);
|
||||||
|
|
||||||
/* Load factor is 0.75 */
|
/* tablelen is incorrect if map->hashbits == 0 which leads to
|
||||||
/* Under the very initial condition, that is map->size == 0 and
|
tablelen = 1, but it is only used to check the load factor, and
|
||||||
map->hashbits == 0, 4 > 3 still holds nicely. */
|
it works in this special case. */
|
||||||
if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) {
|
tablelen = (size_t)1 << map->hashbits;
|
||||||
if (map->hashbits) {
|
|
||||||
rv = map_resize(map, map->hashbits + 1);
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rv = map_resize(map, NGHTTP2_INITIAL_TABLE_LENBITS);
|
|
||||||
if (rv != 0) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = insert(map->table, map->hashbits, key, data);
|
/* Load factor is 7 / 8. Because tablelen is power of 2, (tablelen
|
||||||
|
- (tablelen >> 3)) computes tablelen * 7 / 8. */
|
||||||
|
if (map->size + 1 >= (tablelen - (tablelen >> 3))) {
|
||||||
|
rv = map_resize(map, map->hashbits ? map->hashbits + 1
|
||||||
|
: NGHTTP2_INITIAL_HASHBITS);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
++map->size;
|
idx = map_insert(map, key, data);
|
||||||
|
if (idx < 0) {
|
||||||
|
return (int)idx;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = map_insert(map, key, data);
|
||||||
|
if (idx < 0) {
|
||||||
|
return (int)idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resize if psl reaches really large value which is almost
|
||||||
|
improbable, but just in case. */
|
||||||
|
if (map->psl[idx] - 1 < NGHTTP2_MAX_PSL_RESIZE_THRESH) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return map_resize(map, map->hashbits + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
|
void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
|
||||||
size_t idx;
|
size_t idx;
|
||||||
nghttp2_map_bucket *bkt;
|
size_t psl = 1;
|
||||||
size_t psl = 0;
|
|
||||||
size_t mask;
|
size_t mask;
|
||||||
|
|
||||||
if (map->size == 0) {
|
if (map->size == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = hash(key, map->hashbits);
|
idx = map_index(map, key);
|
||||||
mask = (1u << map->hashbits) - 1;
|
mask = ((size_t)1 << map->hashbits) - 1;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bkt = &map->table[idx];
|
if (psl > map->psl[idx]) {
|
||||||
|
|
||||||
if (bkt->data == NULL || psl > bkt->psl) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bkt->key == key) {
|
if (map->keys[idx] == key) {
|
||||||
return bkt->data;
|
return map->data[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
++psl;
|
++psl;
|
||||||
@@ -244,38 +307,36 @@ void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
|
|||||||
|
|
||||||
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
|
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
|
||||||
size_t idx;
|
size_t idx;
|
||||||
nghttp2_map_bucket *b, *bkt;
|
size_t dest;
|
||||||
size_t psl = 0;
|
size_t psl = 1, kpsl;
|
||||||
size_t mask;
|
size_t mask;
|
||||||
|
|
||||||
if (map->size == 0) {
|
if (map->size == 0) {
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = hash(key, map->hashbits);
|
idx = map_index(map, key);
|
||||||
mask = (1u << map->hashbits) - 1;
|
mask = ((size_t)1 << map->hashbits) - 1;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bkt = &map->table[idx];
|
if (psl > map->psl[idx]) {
|
||||||
|
|
||||||
if (bkt->data == NULL || psl > bkt->psl) {
|
|
||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bkt->key == key) {
|
if (map->keys[idx] == key) {
|
||||||
b = bkt;
|
dest = idx;
|
||||||
idx = (idx + 1) & mask;
|
idx = (idx + 1) & mask;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bkt = &map->table[idx];
|
kpsl = map->psl[idx];
|
||||||
if (bkt->data == NULL || bkt->psl == 0) {
|
if (kpsl <= 1) {
|
||||||
b->data = NULL;
|
map->psl[dest] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
--bkt->psl;
|
map_set_entry(map, dest, map->keys[idx], map->data[idx], kpsl - 1);
|
||||||
*b = *bkt;
|
|
||||||
b = bkt;
|
dest = idx;
|
||||||
|
|
||||||
idx = (idx + 1) & mask;
|
idx = (idx + 1) & mask;
|
||||||
}
|
}
|
||||||
@@ -295,7 +356,7 @@ void nghttp2_map_clear(nghttp2_map *map) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits));
|
memset(map->psl, 0, sizeof(*map->psl) * ((size_t)1 << map->hashbits));
|
||||||
map->size = 0;
|
map->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -38,15 +38,15 @@
|
|||||||
|
|
||||||
typedef int32_t nghttp2_map_key_type;
|
typedef int32_t nghttp2_map_key_type;
|
||||||
|
|
||||||
typedef struct nghttp2_map_bucket {
|
|
||||||
uint32_t psl;
|
|
||||||
nghttp2_map_key_type key;
|
|
||||||
void *data;
|
|
||||||
} nghttp2_map_bucket;
|
|
||||||
|
|
||||||
typedef struct nghttp2_map {
|
typedef struct nghttp2_map {
|
||||||
nghttp2_map_bucket *table;
|
nghttp2_map_key_type *keys;
|
||||||
|
void **data;
|
||||||
|
/* psl is the Probe Sequence Length. 0 has special meaning that the
|
||||||
|
element is not stored at i-th position if psl[i] == 0. Because
|
||||||
|
of this, the actual psl value is psl[i] - 1 if psl[i] > 0. */
|
||||||
|
uint8_t *psl;
|
||||||
nghttp2_mem *mem;
|
nghttp2_mem *mem;
|
||||||
|
uint64_t seed;
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t hashbits;
|
size_t hashbits;
|
||||||
} nghttp2_map;
|
} nghttp2_map;
|
||||||
@@ -54,7 +54,7 @@ typedef struct nghttp2_map {
|
|||||||
/*
|
/*
|
||||||
* nghttp2_map_init initializes the map |map|.
|
* nghttp2_map_init initializes the map |map|.
|
||||||
*/
|
*/
|
||||||
void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
|
void nghttp2_map_init(nghttp2_map *map, uint64_t seed, nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nghttp2_map_free deallocates any resources allocated for |map|.
|
* nghttp2_map_free deallocates any resources allocated for |map|.
|
||||||
@@ -123,6 +123,6 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
|
|||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
void nghttp2_map_print_distance(const nghttp2_map *map);
|
void nghttp2_map_print_distance(const nghttp2_map *map);
|
||||||
#endif /* !WIN32 */
|
#endif /* !defined(WIN32) */
|
||||||
|
|
||||||
#endif /* NGHTTP2_MAP_H */
|
#endif /* !defined(NGHTTP2_MAP_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -42,4 +42,4 @@ void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
|
|||||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
||||||
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
||||||
|
|
||||||
#endif /* NGHTTP2_MEM_H */
|
#endif /* !defined(NGHTTP2_MEM_H) */
|
||||||
|
|||||||
@@ -27,28 +27,28 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#ifdef HAVE_ARPA_INET_H
|
#ifdef HAVE_ARPA_INET_H
|
||||||
# include <arpa/inet.h>
|
# include <arpa/inet.h>
|
||||||
#endif /* HAVE_ARPA_INET_H */
|
#endif /* defined(HAVE_ARPA_INET_H) */
|
||||||
|
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif /* HAVE_NETINET_IN_H */
|
#endif /* defined(HAVE_NETINET_IN_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
#if defined(WIN32)
|
#ifdef WIN32
|
||||||
/* Windows requires ws2_32 library for ntonl family functions. We
|
/* Windows requires ws2_32 library for ntonl family functions. We
|
||||||
define inline functions for those function so that we don't have
|
define inline functions for those function so that we don't have
|
||||||
dependency on that lib. */
|
dependency on that lib. */
|
||||||
|
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
# define STIN static __inline
|
# define STIN static __inline
|
||||||
# else
|
# else /* !defined(_MSC_VER) */
|
||||||
# define STIN static inline
|
# define STIN static inline
|
||||||
# endif
|
# endif /* !defined(_MSC_VER) */
|
||||||
|
|
||||||
STIN uint32_t htonl(uint32_t hostlong) {
|
STIN uint32_t htonl(uint32_t hostlong) {
|
||||||
uint32_t res;
|
uint32_t res;
|
||||||
@@ -86,6 +86,6 @@ STIN uint16_t ntohs(uint16_t netshort) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WIN32 */
|
#endif /* defined(WIN32) */
|
||||||
|
|
||||||
#endif /* NGHTTP2_NET_H */
|
#endif /* !defined(NGHTTP2_NET_H) */
|
||||||
|
|||||||
@@ -155,3 +155,10 @@ void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) {
|
|||||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
|
option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
|
||||||
option->max_continuations = val;
|
option->max_continuations = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
|
||||||
|
uint64_t burst, uint64_t rate) {
|
||||||
|
option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT;
|
||||||
|
option->glitch_burst = burst;
|
||||||
|
option->glitch_rate = rate;
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -72,6 +72,7 @@ typedef enum {
|
|||||||
NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
|
NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
|
||||||
NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
|
NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
|
||||||
NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
|
NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
|
||||||
|
NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17,
|
||||||
} nghttp2_option_flag;
|
} nghttp2_option_flag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +84,11 @@ struct nghttp2_option {
|
|||||||
*/
|
*/
|
||||||
uint64_t stream_reset_burst;
|
uint64_t stream_reset_burst;
|
||||||
uint64_t stream_reset_rate;
|
uint64_t stream_reset_rate;
|
||||||
|
/**
|
||||||
|
* NGHTTP2_OPT_GLITCH_RATE_LIMIT
|
||||||
|
*/
|
||||||
|
uint64_t glitch_burst;
|
||||||
|
uint64_t glitch_rate;
|
||||||
/**
|
/**
|
||||||
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
||||||
*/
|
*/
|
||||||
@@ -154,4 +160,4 @@ struct nghttp2_option {
|
|||||||
uint8_t user_recv_ext_types[32];
|
uint8_t user_recv_ext_types[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NGHTTP2_OPTION_H */
|
#endif /* !defined(NGHTTP2_OPTION_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#include "nghttp2_frame.h"
|
#include "nghttp2_frame.h"
|
||||||
@@ -186,4 +186,4 @@ void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q);
|
|||||||
/* Returns the size of the queue */
|
/* Returns the size of the queue */
|
||||||
#define nghttp2_outbound_queue_size(Q) ((Q)->n)
|
#define nghttp2_outbound_queue_size(Q) ((Q)->n)
|
||||||
|
|
||||||
#endif /* NGHTTP2_OUTBOUND_ITEM_H */
|
#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#include "nghttp2_int.h"
|
#include "nghttp2_int.h"
|
||||||
@@ -121,4 +121,4 @@ int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
|
|||||||
*/
|
*/
|
||||||
void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
|
void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
|
||||||
|
|
||||||
#endif /* NGHTTP2_PQ_H */
|
#endif /* !defined(NGHTTP2_PQ_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -39,4 +39,4 @@
|
|||||||
*/
|
*/
|
||||||
void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
|
void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
|
||||||
|
|
||||||
#endif /* NGHTTP2_PRIORITY_SPEC_H */
|
#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -48,4 +48,4 @@ void *nghttp2_queue_front(nghttp2_queue *queue);
|
|||||||
void *nghttp2_queue_back(nghttp2_queue *queue);
|
void *nghttp2_queue_back(nghttp2_queue *queue);
|
||||||
int nghttp2_queue_empty(nghttp2_queue *queue);
|
int nghttp2_queue_empty(nghttp2_queue *queue);
|
||||||
|
|
||||||
#endif /* NGHTTP2_QUEUE_H */
|
#endif /* !defined(NGHTTP2_QUEUE_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -54,4 +54,4 @@ void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
|
|||||||
succeeds, or -1. */
|
succeeds, or -1. */
|
||||||
int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
|
int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
|
||||||
|
|
||||||
#endif /* NGHTTP2_RATELIM_H */
|
#endif /* !defined(NGHTTP2_RATELIM_H) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -77,4 +77,4 @@ int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
|
|||||||
*/
|
*/
|
||||||
void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
|
void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
|
||||||
|
|
||||||
#endif /* NGHTTP2_RCBUF_H */
|
#endif /* !defined(NGHTTP2_RCBUF_H) */
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
#include "nghttp2_debug.h"
|
#include "nghttp2_debug.h"
|
||||||
#include "nghttp2_submit.h"
|
#include "nghttp2_submit.h"
|
||||||
|
|
||||||
nghttp2_stream root;
|
nghttp2_stream nghttp2_stream_root;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if the number of outgoing opened streams is larger
|
* Returns non-zero if the number of outgoing opened streams is larger
|
||||||
@@ -438,6 +438,7 @@ static int session_new(nghttp2_session **session_ptr,
|
|||||||
size_t max_deflate_dynamic_table_size =
|
size_t max_deflate_dynamic_table_size =
|
||||||
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
|
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
uint64_t map_seed;
|
||||||
|
|
||||||
if (mem == NULL) {
|
if (mem == NULL) {
|
||||||
mem = nghttp2_mem_default();
|
mem = nghttp2_mem_default();
|
||||||
@@ -474,6 +475,10 @@ static int session_new(nghttp2_session **session_ptr,
|
|||||||
NGHTTP2_DEFAULT_STREAM_RESET_BURST,
|
NGHTTP2_DEFAULT_STREAM_RESET_BURST,
|
||||||
NGHTTP2_DEFAULT_STREAM_RESET_RATE);
|
NGHTTP2_DEFAULT_STREAM_RESET_RATE);
|
||||||
|
|
||||||
|
nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
|
||||||
|
NGHTTP2_DEFAULT_GLITCH_BURST,
|
||||||
|
NGHTTP2_DEFAULT_GLITCH_RATE);
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
(*session_ptr)->server = 1;
|
(*session_ptr)->server = 1;
|
||||||
}
|
}
|
||||||
@@ -566,6 +571,11 @@ static int session_new(nghttp2_session **session_ptr,
|
|||||||
if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
|
if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
|
||||||
(*session_ptr)->max_continuations = option->max_continuations;
|
(*session_ptr)->max_continuations = option->max_continuations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) {
|
||||||
|
nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
|
||||||
|
option->glitch_burst, option->glitch_rate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
|
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
|
||||||
@@ -594,7 +604,13 @@ static int session_new(nghttp2_session **session_ptr,
|
|||||||
goto fail_aob_framebuf;
|
goto fail_aob_framebuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_map_init(&(*session_ptr)->streams, mem);
|
if (callbacks->rand_callback) {
|
||||||
|
callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed));
|
||||||
|
} else {
|
||||||
|
map_seed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem);
|
||||||
|
|
||||||
active_outbound_item_reset(&(*session_ptr)->aob, mem);
|
active_outbound_item_reset(&(*session_ptr)->aob, mem);
|
||||||
|
|
||||||
@@ -1092,6 +1108,15 @@ int nghttp2_session_add_item(nghttp2_session *session,
|
|||||||
|
|
||||||
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
|
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
|
||||||
uint32_t error_code) {
|
uint32_t error_code) {
|
||||||
|
return nghttp2_session_add_rst_stream_continue(
|
||||||
|
session, stream_id, error_code,
|
||||||
|
/* continue_without_stream = */ 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
|
||||||
|
int32_t stream_id,
|
||||||
|
uint32_t error_code,
|
||||||
|
int continue_without_stream) {
|
||||||
int rv;
|
int rv;
|
||||||
nghttp2_outbound_item *item;
|
nghttp2_outbound_item *item;
|
||||||
nghttp2_frame *frame;
|
nghttp2_frame *frame;
|
||||||
@@ -1148,6 +1173,12 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To keep the old behaviour, do not fail if stream was not
|
||||||
|
found. */
|
||||||
|
if (!continue_without_stream && !stream) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
|
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
return NGHTTP2_ERR_NOMEM;
|
return NGHTTP2_ERR_NOMEM;
|
||||||
@@ -3241,7 +3272,9 @@ static int session_call_on_invalid_header(nghttp2_session *session,
|
|||||||
session, frame, nv->name->base, nv->name->len, nv->value->base,
|
session, frame, nv->name->base, nv->name->len, nv->value->base,
|
||||||
nv->value->len, nv->flags, session->user_data);
|
nv->value->len, nv->flags, session->user_data);
|
||||||
} else {
|
} else {
|
||||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
/* If both callbacks are not set, the invalid field nv is
|
||||||
|
ignored. */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||||
@@ -3326,6 +3359,10 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) {
|
|||||||
case NGHTTP2_ERR_HTTP_HEADER:
|
case NGHTTP2_ERR_HTTP_HEADER:
|
||||||
case NGHTTP2_ERR_HTTP_MESSAGING:
|
case NGHTTP2_ERR_HTTP_MESSAGING:
|
||||||
return NGHTTP2_PROTOCOL_ERROR;
|
return NGHTTP2_PROTOCOL_ERROR;
|
||||||
|
case NGHTTP2_ERR_INTERNAL:
|
||||||
|
return NGHTTP2_INTERNAL_ERROR;
|
||||||
|
case NGHTTP2_ERR_PUSH_CANCEL:
|
||||||
|
return NGHTTP2_CANCEL;
|
||||||
default:
|
default:
|
||||||
return NGHTTP2_INTERNAL_ERROR;
|
return NGHTTP2_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
@@ -3352,17 +3389,32 @@ static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int session_update_glitch_ratelim(nghttp2_session *session) {
|
||||||
|
if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec());
|
||||||
|
|
||||||
|
if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM);
|
||||||
|
}
|
||||||
|
|
||||||
static int session_handle_invalid_stream2(nghttp2_session *session,
|
static int session_handle_invalid_stream2(nghttp2_session *session,
|
||||||
int32_t stream_id,
|
int32_t stream_id,
|
||||||
nghttp2_frame *frame,
|
nghttp2_frame *frame,
|
||||||
int lib_error_code) {
|
int lib_error_code) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
rv = nghttp2_session_add_rst_stream(
|
rv = nghttp2_session_add_rst_stream(
|
||||||
session, stream_id, get_error_code_from_lib_error_code(lib_error_code));
|
session, stream_id, get_error_code_from_lib_error_code(lib_error_code));
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
if (session->callbacks.on_invalid_frame_recv_callback) {
|
if (frame && session->callbacks.on_invalid_frame_recv_callback) {
|
||||||
if (session->callbacks.on_invalid_frame_recv_callback(
|
if (session->callbacks.on_invalid_frame_recv_callback(
|
||||||
session, frame, lib_error_code, session->user_data) != 0) {
|
session, frame, lib_error_code, session->user_data) != 0) {
|
||||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||||
@@ -3517,7 +3569,29 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
|
|||||||
|
|
||||||
rv2 = session_call_on_invalid_header(session, frame, &nv);
|
rv2 = session_call_on_invalid_header(session, frame, &nv);
|
||||||
if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||||
rv = NGHTTP2_ERR_HTTP_HEADER;
|
DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n",
|
||||||
|
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
|
||||||
|
nv.name->base, (int)nv.value->len, nv.value->base);
|
||||||
|
|
||||||
|
rv = session_call_error_callback(
|
||||||
|
session, NGHTTP2_ERR_HTTP_HEADER,
|
||||||
|
"Invalid HTTP header field was received: frame type: "
|
||||||
|
"%u, stream: %d, name: [%.*s], value: [%.*s]",
|
||||||
|
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
|
||||||
|
nv.name->base, (int)nv.value->len, nv.value->base);
|
||||||
|
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = session_handle_invalid_stream2(
|
||||||
|
session, subject_stream->stream_id, frame,
|
||||||
|
NGHTTP2_ERR_HTTP_HEADER);
|
||||||
|
if (nghttp2_is_fatal(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
if (rv2 != 0) {
|
if (rv2 != 0) {
|
||||||
return rv2;
|
return rv2;
|
||||||
@@ -3557,13 +3631,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv =
|
return nghttp2_session_terminate_session(session,
|
||||||
session_handle_invalid_stream2(session, subject_stream->stream_id,
|
NGHTTP2_PROTOCOL_ERROR);
|
||||||
frame, NGHTTP2_ERR_HTTP_HEADER);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
@@ -3676,27 +3745,7 @@ static int session_after_header_block_received(nghttp2_session *session) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
int32_t stream_id;
|
return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
|
||||||
|
|
||||||
if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
|
||||||
stream_id = frame->push_promise.promised_stream_id;
|
|
||||||
} else {
|
|
||||||
stream_id = frame->hd.stream_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = session_handle_invalid_stream2(session, stream_id, frame,
|
|
||||||
NGHTTP2_ERR_HTTP_MESSAGING);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (frame->hd.type == NGHTTP2_HEADERS &&
|
|
||||||
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
|
|
||||||
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
|
|
||||||
/* Don't call nghttp2_session_close_stream_if_shut_rdwr
|
|
||||||
because RST_STREAM has been submitted. */
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4032,8 +4081,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
|
|||||||
rv = nghttp2_stream_update_remote_initial_window_size(
|
rv = nghttp2_stream_update_remote_initial_window_size(
|
||||||
stream, arg->new_window_size, arg->old_window_size);
|
stream, arg->new_window_size, arg->old_window_size);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
|
return NGHTTP2_ERR_FLOW_CONTROL;
|
||||||
NGHTTP2_FLOW_CONTROL_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If window size gets positive, push deferred DATA frame to
|
/* If window size gets positive, push deferred DATA frame to
|
||||||
@@ -4059,6 +4107,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
|
|||||||
*
|
*
|
||||||
* NGHTTP2_ERR_NOMEM
|
* NGHTTP2_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
|
* NGHTTP2_ERR_FLOW_CONTROL
|
||||||
|
* Window size gets out of range.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
session_update_remote_initial_window_size(nghttp2_session *session,
|
session_update_remote_initial_window_size(nghttp2_session *session,
|
||||||
@@ -4082,8 +4132,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
|
|||||||
rv = nghttp2_stream_update_local_initial_window_size(
|
rv = nghttp2_stream_update_local_initial_window_size(
|
||||||
stream, arg->new_window_size, arg->old_window_size);
|
stream, arg->new_window_size, arg->old_window_size);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
|
return NGHTTP2_ERR_FLOW_CONTROL;
|
||||||
NGHTTP2_FLOW_CONTROL_ERROR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->window_update_queued) {
|
if (stream->window_update_queued) {
|
||||||
@@ -4117,6 +4166,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
|
|||||||
*
|
*
|
||||||
* NGHTTP2_ERR_NOMEM
|
* NGHTTP2_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
|
* NGHTTP2_ERR_FLOW_CONTROL
|
||||||
|
* Window size gets out of range.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
session_update_local_initial_window_size(nghttp2_session *session,
|
session_update_local_initial_window_size(nghttp2_session *session,
|
||||||
@@ -4503,9 +4554,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
|
|||||||
session->max_incoming_reserved_streams) {
|
session->max_incoming_reserved_streams) {
|
||||||
/* Currently, client does not retain closed stream, so we don't
|
/* Currently, client does not retain closed stream, so we don't
|
||||||
check NGHTTP2_SHUT_RD condition here. */
|
check NGHTTP2_SHUT_RD condition here. */
|
||||||
|
rv = session_handle_invalid_stream2(session,
|
||||||
rv = nghttp2_session_add_rst_stream(
|
frame->push_promise.promised_stream_id,
|
||||||
session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL);
|
NULL, NGHTTP2_ERR_PUSH_CANCEL);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -4662,8 +4713,9 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
|
|||||||
}
|
}
|
||||||
if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
|
if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
|
||||||
stream->remote_window_size) {
|
stream->remote_window_size) {
|
||||||
return session_handle_invalid_stream(session, frame,
|
return session_handle_invalid_connection(
|
||||||
NGHTTP2_ERR_FLOW_CONTROL);
|
session, frame, NGHTTP2_ERR_FLOW_CONTROL,
|
||||||
|
"WINDOW_UPDATE: window size overflow");
|
||||||
}
|
}
|
||||||
stream->remote_window_size += frame->window_update.window_size_increment;
|
stream->remote_window_size += frame->window_update.window_size_increment;
|
||||||
|
|
||||||
@@ -4893,16 +4945,7 @@ int nghttp2_session_on_data_received(nghttp2_session *session,
|
|||||||
if (session_enforce_http_messaging(session) &&
|
if (session_enforce_http_messaging(session) &&
|
||||||
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
|
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
|
||||||
if (nghttp2_http_on_remote_end_stream(stream) != 0) {
|
if (nghttp2_http_on_remote_end_stream(stream) != 0) {
|
||||||
rv = nghttp2_session_add_rst_stream(session, stream->stream_id,
|
return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
|
||||||
NGHTTP2_PROTOCOL_ERROR);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
|
|
||||||
/* Don't call nghttp2_session_close_stream_if_shut_rdwr because
|
|
||||||
RST_STREAM has been submitted. */
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4960,7 +5003,7 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
|
|||||||
rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
|
rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
|
||||||
stream->local_window_size);
|
stream->local_window_size);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return nghttp2_session_add_rst_stream(session, stream->stream_id,
|
return nghttp2_session_terminate_session(session,
|
||||||
NGHTTP2_FLOW_CONTROL_ERROR);
|
NGHTTP2_FLOW_CONTROL_ERROR);
|
||||||
}
|
}
|
||||||
/* We don't have to send WINDOW_UPDATE if the data received is the
|
/* We don't have to send WINDOW_UPDATE if the data received is the
|
||||||
@@ -5429,6 +5472,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
|
if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
|
||||||
DEBUGF("recv: DATA not allowed stream_id=%d\n",
|
DEBUGF("recv: DATA not allowed stream_id=%d\n",
|
||||||
iframe->frame.hd.stream_id);
|
iframe->frame.hd.stream_id);
|
||||||
|
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
iframe->state = NGHTTP2_IB_IGN_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5454,6 +5507,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Empty DATA frame without END_STREAM flag set is
|
||||||
|
suspicious. */
|
||||||
|
if (iframe->payloadleft == 0 &&
|
||||||
|
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_READ_DATA;
|
iframe->state = NGHTTP2_IB_READ_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5520,8 +5587,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||||
rv = nghttp2_session_add_rst_stream(
|
rv = session_handle_invalid_stream2(
|
||||||
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
|
session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -5530,6 +5597,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
|
if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
|
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5550,6 +5626,18 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is deprecated RFC 7540 priorities mechanism which is
|
||||||
|
very unpopular. We do not expect it is received so
|
||||||
|
frequently. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_READ_NBYTE;
|
iframe->state = NGHTTP2_IB_READ_NBYTE;
|
||||||
|
|
||||||
inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN);
|
inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN);
|
||||||
@@ -5566,7 +5654,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
DEBUGF("recv: WINDOW_UPDATE\n");
|
DEBUGF("recv: WINDOW_UPDATE\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* DEBUGBUILD */
|
#endif /* defined(DEBUGBUILD) */
|
||||||
|
|
||||||
iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
|
iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
|
||||||
|
|
||||||
@@ -5722,8 +5810,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
if (check_ext_type_set(session->user_recv_ext_types,
|
if (check_ext_type_set(session->user_recv_ext_types,
|
||||||
iframe->frame.hd.type)) {
|
iframe->frame.hd.type)) {
|
||||||
if (!session->callbacks.unpack_extension_callback) {
|
if (!session->callbacks.unpack_extension_callback) {
|
||||||
/* Silently ignore unknown frame type. */
|
/* Receiving too frequent unknown frames is suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Silently ignore unknown frame type. */
|
||||||
busy = 1;
|
busy = 1;
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
@@ -5741,6 +5838,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
case NGHTTP2_ALTSVC:
|
case NGHTTP2_ALTSVC:
|
||||||
if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
|
if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
|
||||||
0) {
|
0) {
|
||||||
|
/* Receiving too frequent unknown frames is suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
break;
|
break;
|
||||||
@@ -5752,6 +5859,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
|
iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
|
||||||
|
|
||||||
if (session->server) {
|
if (session->server) {
|
||||||
|
/* Receiving too frequent ALTSVC from client is
|
||||||
|
suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
break;
|
break;
|
||||||
@@ -5771,6 +5889,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
break;
|
break;
|
||||||
case NGHTTP2_ORIGIN:
|
case NGHTTP2_ORIGIN:
|
||||||
if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) {
|
if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) {
|
||||||
|
/* Receiving too frequent unknown frames is suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
break;
|
break;
|
||||||
@@ -5782,6 +5910,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
|
|
||||||
if (session->server || iframe->frame.hd.stream_id ||
|
if (session->server || iframe->frame.hd.stream_id ||
|
||||||
(iframe->frame.hd.flags & 0xf0)) {
|
(iframe->frame.hd.flags & 0xf0)) {
|
||||||
|
/* Receiving too frequent invalid frames is
|
||||||
|
suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
break;
|
break;
|
||||||
@@ -5808,6 +5947,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
case NGHTTP2_PRIORITY_UPDATE:
|
case NGHTTP2_PRIORITY_UPDATE:
|
||||||
if ((session->builtin_recv_ext_types &
|
if ((session->builtin_recv_ext_types &
|
||||||
NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
|
NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
|
||||||
|
/* Receiving too frequent unknown frames is suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
break;
|
break;
|
||||||
@@ -5835,6 +5984,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Receiving too frequent PRIORITY_UPDATE is
|
||||||
|
suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
|
if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
|
||||||
busy = 1;
|
busy = 1;
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
@@ -5848,6 +6008,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
/* Receiving too frequent unknown frames is suspicious. */
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
|
||||||
@@ -5934,8 +6104,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||||
rv = nghttp2_session_add_rst_stream(
|
rv = session_handle_invalid_stream2(
|
||||||
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
|
session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -5944,6 +6114,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
|
if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
|
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -6009,9 +6188,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
||||||
rv = nghttp2_session_add_rst_stream(
|
rv = session_handle_invalid_stream2(
|
||||||
session, iframe->frame.push_promise.promised_stream_id,
|
session, iframe->frame.push_promise.promised_stream_id, NULL,
|
||||||
NGHTTP2_INTERNAL_ERROR);
|
NGHTTP2_ERR_INTERNAL);
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -6136,7 +6315,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
} else {
|
} else {
|
||||||
DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n");
|
DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n");
|
||||||
}
|
}
|
||||||
#endif /* DEBUGBUILD */
|
#endif /* defined(DEBUGBUILD) */
|
||||||
|
|
||||||
readlen = inbound_frame_payload_readlen(iframe, in, last);
|
readlen = inbound_frame_payload_readlen(iframe, in, last);
|
||||||
|
|
||||||
@@ -6189,12 +6368,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
iframe->payloadleft -= hd_proclen;
|
iframe->payloadleft -= hd_proclen;
|
||||||
|
|
||||||
/* Use promised stream ID for PUSH_PROMISE */
|
/* Use promised stream ID for PUSH_PROMISE */
|
||||||
rv = nghttp2_session_add_rst_stream(
|
rv = session_handle_invalid_stream2(
|
||||||
session,
|
session,
|
||||||
iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
|
iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
|
||||||
? iframe->frame.push_promise.promised_stream_id
|
? iframe->frame.push_promise.promised_stream_id
|
||||||
: iframe->frame.hd.stream_id,
|
: iframe->frame.hd.stream_id,
|
||||||
NGHTTP2_INTERNAL_ERROR);
|
NULL, NGHTTP2_ERR_INTERNAL);
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -6241,6 +6420,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
session_inbound_frame_reset(session);
|
session_inbound_frame_reset(session);
|
||||||
|
|
||||||
@@ -6364,7 +6547,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
|
fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
|
||||||
}
|
}
|
||||||
#endif /* DEBUGBUILD */
|
#endif /* defined(DEBUGBUILD) */
|
||||||
|
|
||||||
if (++session->num_continuations > session->max_continuations) {
|
if (++session->num_continuations > session->max_continuations) {
|
||||||
return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
|
return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
|
||||||
@@ -6466,6 +6649,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
busy = 1;
|
busy = 1;
|
||||||
@@ -6482,6 +6669,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
|
|
||||||
iframe->frame.data.padlen = (size_t)padlen;
|
iframe->frame.data.padlen = (size_t)padlen;
|
||||||
|
|
||||||
|
/* Empty DATA frame without END_STREAM flag set is
|
||||||
|
suspicious. */
|
||||||
|
if (iframe->payloadleft == 0 &&
|
||||||
|
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
|
||||||
|
rv = session_update_glitch_ratelim(session);
|
||||||
|
if (rv != 0) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iframe->state = NGHTTP2_IB_READ_DATA;
|
iframe->state = NGHTTP2_IB_READ_DATA;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -6524,6 +6725,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
data_readlen =
|
data_readlen =
|
||||||
inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen);
|
inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen);
|
||||||
|
|
||||||
@@ -6553,30 +6758,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
if (data_readlen > 0) {
|
if (data_readlen > 0) {
|
||||||
if (session_enforce_http_messaging(session)) {
|
if (session_enforce_http_messaging(session)) {
|
||||||
if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) {
|
if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) {
|
||||||
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
|
rv = nghttp2_session_terminate_session(session,
|
||||||
/* Consume all data for connection immediately here */
|
NGHTTP2_PROTOCOL_ERROR);
|
||||||
rv = session_update_connection_consumed_size(
|
|
||||||
session, (size_t)data_readlen);
|
|
||||||
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
if (nghttp2_is_fatal(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iframe->state == NGHTTP2_IB_IGN_DATA) {
|
|
||||||
return (nghttp2_ssize)inlen;
|
return (nghttp2_ssize)inlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_session_add_rst_stream(
|
|
||||||
session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR);
|
|
||||||
if (nghttp2_is_fatal(rv)) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
busy = 1;
|
|
||||||
iframe->state = NGHTTP2_IB_IGN_DATA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (session->callbacks.on_data_chunk_recv_callback) {
|
if (session->callbacks.on_data_chunk_recv_callback) {
|
||||||
rv = session->callbacks.on_data_chunk_recv_callback(
|
rv = session->callbacks.on_data_chunk_recv_callback(
|
||||||
session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
|
session, iframe->frame.hd.flags, iframe->frame.hd.stream_id,
|
||||||
@@ -6601,6 +6791,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
|
||||||
|
return (nghttp2_ssize)inlen;
|
||||||
|
}
|
||||||
|
|
||||||
session_inbound_frame_reset(session);
|
session_inbound_frame_reset(session);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -7715,7 +7909,7 @@ int32_t nghttp2_session_get_last_proc_stream_id(nghttp2_session *session) {
|
|||||||
nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
|
nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
|
||||||
int32_t stream_id) {
|
int32_t stream_id) {
|
||||||
if (stream_id == 0) {
|
if (stream_id == 0) {
|
||||||
return &root;
|
return &nghttp2_stream_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nghttp2_session_get_stream_raw(session, stream_id);
|
return nghttp2_session_get_stream_raw(session, stream_id);
|
||||||
@@ -7724,7 +7918,7 @@ nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
|
|||||||
nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
|
nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
|
||||||
(void)session;
|
(void)session;
|
||||||
|
|
||||||
return &root;
|
return &nghttp2_stream_root;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_session_check_server_session(nghttp2_session *session) {
|
int nghttp2_session_check_server_session(nghttp2_session *session) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#include "nghttp2_map.h"
|
#include "nghttp2_map.h"
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
preface handling. */
|
preface handling. */
|
||||||
extern int nghttp2_enable_strict_preface;
|
extern int nghttp2_enable_strict_preface;
|
||||||
|
|
||||||
extern nghttp2_stream root;
|
extern nghttp2_stream nghttp2_stream_root;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Option flags.
|
* Option flags.
|
||||||
@@ -106,6 +106,10 @@ typedef struct {
|
|||||||
#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
|
#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
|
||||||
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
|
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
|
||||||
|
|
||||||
|
/* The default values for glitch rate limiter. */
|
||||||
|
#define NGHTTP2_DEFAULT_GLITCH_BURST 1000
|
||||||
|
#define NGHTTP2_DEFAULT_GLITCH_RATE 33
|
||||||
|
|
||||||
/* The default max number of CONTINUATION frames following an incoming
|
/* The default max number of CONTINUATION frames following an incoming
|
||||||
HEADER frame. */
|
HEADER frame. */
|
||||||
#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
|
#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
|
||||||
@@ -229,6 +233,8 @@ struct nghttp2_session {
|
|||||||
/* Stream reset rate limiter. If receiving excessive amount of
|
/* Stream reset rate limiter. If receiving excessive amount of
|
||||||
stream resets, GOAWAY will be sent. */
|
stream resets, GOAWAY will be sent. */
|
||||||
nghttp2_ratelim stream_reset_ratelim;
|
nghttp2_ratelim stream_reset_ratelim;
|
||||||
|
/* Rate limiter for all kinds of glitches. */
|
||||||
|
nghttp2_ratelim glitch_ratelim;
|
||||||
/* Sequential number across all streams to process streams in
|
/* Sequential number across all streams to process streams in
|
||||||
FIFO. */
|
FIFO. */
|
||||||
uint64_t stream_seq;
|
uint64_t stream_seq;
|
||||||
@@ -402,6 +408,13 @@ int nghttp2_session_is_my_stream_id(nghttp2_session *session,
|
|||||||
int nghttp2_session_add_item(nghttp2_session *session,
|
int nghttp2_session_add_item(nghttp2_session *session,
|
||||||
nghttp2_outbound_item *item);
|
nghttp2_outbound_item *item);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function wraps around nghttp2_session_add_rst_stream_continue
|
||||||
|
* with continue_without_stream = 1.
|
||||||
|
*/
|
||||||
|
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
|
||||||
|
uint32_t error_code);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds RST_STREAM frame for the stream |stream_id| with the error
|
* Adds RST_STREAM frame for the stream |stream_id| with the error
|
||||||
* code |error_code|. This is a convenient function built on top of
|
* code |error_code|. This is a convenient function built on top of
|
||||||
@@ -409,7 +422,9 @@ int nghttp2_session_add_item(nghttp2_session *session,
|
|||||||
*
|
*
|
||||||
* This function simply returns 0 without adding RST_STREAM frame if
|
* This function simply returns 0 without adding RST_STREAM frame if
|
||||||
* given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
|
* given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
|
||||||
* RST_STREAM for a stream is redundant.
|
* RST_STREAM for a stream is redundant. It also returns 0 without
|
||||||
|
* adding the frame if |continue_without_stream| is nonzero, and
|
||||||
|
* stream was already gone.
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
@@ -417,8 +432,10 @@ int nghttp2_session_add_item(nghttp2_session *session,
|
|||||||
* NGHTTP2_ERR_NOMEM
|
* NGHTTP2_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
|
int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
|
||||||
uint32_t error_code);
|
int32_t stream_id,
|
||||||
|
uint32_t error_code,
|
||||||
|
int continue_without_stream);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds PING frame. This is a convenient function built on top of
|
* Adds PING frame. This is a convenient function built on top of
|
||||||
@@ -875,4 +892,4 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
|
|||||||
size_t delta_size,
|
size_t delta_size,
|
||||||
int send_window_update);
|
int send_window_update);
|
||||||
|
|
||||||
#endif /* NGHTTP2_SESSION_H */
|
#endif /* !defined(NGHTTP2_SESSION_H) */
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
|
nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
|
||||||
if (stream == &root) {
|
if (stream == &nghttp2_stream_root) {
|
||||||
return NGHTTP2_STREAM_STATE_IDLE;
|
return NGHTTP2_STREAM_STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#include "nghttp2_outbound_item.h"
|
#include "nghttp2_outbound_item.h"
|
||||||
@@ -294,4 +294,4 @@ void nghttp2_stream_attach_item(nghttp2_stream *stream,
|
|||||||
*/
|
*/
|
||||||
void nghttp2_stream_detach_item(nghttp2_stream *stream);
|
void nghttp2_stream_detach_item(nghttp2_stream *stream);
|
||||||
|
|
||||||
#endif /* NGHTTP2_STREAM */
|
#endif /* !defined(NGHTTP2_STREAM_H) */
|
||||||
|
|||||||
@@ -185,7 +185,8 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
|
|||||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nghttp2_session_add_rst_stream(session, stream_id, error_code);
|
return nghttp2_session_add_rst_stream_continue(
|
||||||
|
session, stream_id, error_code, /* continue_without_stream = */ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
|
int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
|
||||||
@@ -486,7 +487,7 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_item_malloc:
|
fail_item_malloc:
|
||||||
free(buf);
|
nghttp2_mem_free(mem, buf);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -569,7 +570,7 @@ int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_item_malloc:
|
fail_item_malloc:
|
||||||
free(ov_copy);
|
nghttp2_mem_free(mem, ov_copy);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -641,7 +642,7 @@ int nghttp2_submit_priority_update(nghttp2_session *session, uint8_t flags,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail_item_malloc:
|
fail_item_malloc:
|
||||||
free(buf);
|
nghttp2_mem_free(mem, buf);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -37,4 +37,4 @@ int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
|
|||||||
int32_t stream_id,
|
int32_t stream_id,
|
||||||
const nghttp2_data_provider_wrap *dpw);
|
const nghttp2_data_provider_wrap *dpw);
|
||||||
|
|
||||||
#endif /* NGHTTP2_SUBMIT_H */
|
#endif /* !defined(NGHTTP2_SUBMIT_H) */
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_WINDOWS_H
|
#ifdef HAVE_WINDOWS_H
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif /* HAVE_WINDOWS_H */
|
#endif /* defined(HAVE_WINDOWS_H) */
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
@@ -40,12 +40,11 @@ static uint64_t time_now_sec(void) {
|
|||||||
|
|
||||||
return (uint64_t)t;
|
return (uint64_t)t;
|
||||||
}
|
}
|
||||||
#endif /* !HAVE_GETTICKCOUNT64 || __CYGWIN__ */
|
#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */
|
||||||
|
|
||||||
#if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__)
|
#if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__)
|
||||||
uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
|
uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
|
||||||
#elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \
|
#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
|
||||||
HAVE_DECL_CLOCK_MONOTONIC
|
|
||||||
uint64_t nghttp2_time_now_sec(void) {
|
uint64_t nghttp2_time_now_sec(void) {
|
||||||
struct timespec tp;
|
struct timespec tp;
|
||||||
int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
|
int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||||
@@ -56,8 +55,8 @@ uint64_t nghttp2_time_now_sec(void) {
|
|||||||
|
|
||||||
return (uint64_t)tp.tv_sec;
|
return (uint64_t)tp.tv_sec;
|
||||||
}
|
}
|
||||||
#else /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \
|
#else /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \
|
||||||
(!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */
|
(!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
|
||||||
uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
|
uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
|
||||||
#endif /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \
|
#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \
|
||||||
(!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */
|
(!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
@@ -35,4 +35,4 @@
|
|||||||
timepoint. If it is unable to get seconds, it returns 0. */
|
timepoint. If it is unable to get seconds, it returns 0. */
|
||||||
uint64_t nghttp2_time_now_sec(void);
|
uint64_t nghttp2_time_now_sec(void);
|
||||||
|
|
||||||
#endif /* NGHTTP2_TIME_H */
|
#endif /* !defined(NGHTTP2_TIME_H) */
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif /* HAVE_CONFIG_H */
|
#endif /* defined(HAVE_CONFIG_H) */
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
|
|
||||||
|
|||||||
27
mkhufftbl.py
27
mkhufftbl.py
@@ -356,8 +356,8 @@ def _build_transition_table(ctx, node):
|
|||||||
def huffman_tree_build_transition_table(ctx):
|
def huffman_tree_build_transition_table(ctx):
|
||||||
_build_transition_table(ctx, ctx.root)
|
_build_transition_table(ctx, ctx.root)
|
||||||
|
|
||||||
NGHTTP2_HUFF_ACCEPTED = 1 << 14
|
NGHTTP2_HUFF_ACCEPTED = 1
|
||||||
NGHTTP2_HUFF_SYM = 1 << 15
|
NGHTTP2_HUFF_SYM = 1 << 1
|
||||||
|
|
||||||
def _print_transition_table(node):
|
def _print_transition_table(node):
|
||||||
if node.term is not None:
|
if node.term is not None:
|
||||||
@@ -381,7 +381,7 @@ def _print_transition_table(node):
|
|||||||
flags |= NGHTTP2_HUFF_ACCEPTED
|
flags |= NGHTTP2_HUFF_ACCEPTED
|
||||||
elif nd.accept:
|
elif nd.accept:
|
||||||
flags |= NGHTTP2_HUFF_ACCEPTED
|
flags |= NGHTTP2_HUFF_ACCEPTED
|
||||||
print(' {{0x{:02x}, {}}},'.format(id | flags, out))
|
print(' {{0x{:02x}, {}, {}}},'.format(id, flags, out))
|
||||||
print('},')
|
print('},')
|
||||||
_print_transition_table(node.left)
|
_print_transition_table(node.left)
|
||||||
_print_transition_table(node.right)
|
_print_transition_table(node.right)
|
||||||
@@ -390,22 +390,10 @@ def huffman_tree_print_transition_table(ctx):
|
|||||||
_print_transition_table(ctx.root)
|
_print_transition_table(ctx.root)
|
||||||
print('/* 256 */')
|
print('/* 256 */')
|
||||||
print('{')
|
print('{')
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
for _ in range(16):
|
||||||
print(' {0x100, 0},')
|
print(' {0x100, 0, 0},')
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print(' {0x100, 0},')
|
|
||||||
print('},')
|
print('},')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@@ -458,6 +446,7 @@ enum {{
|
|||||||
print('''\
|
print('''\
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t fstate;
|
uint16_t fstate;
|
||||||
|
uint8_t flags;
|
||||||
uint8_t sym;
|
uint8_t sym;
|
||||||
} nghttp2_huff_decode;
|
} nghttp2_huff_decode;
|
||||||
''')
|
''')
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
# EXTRA_DIST = README.rst
|
|
||||||
install(
|
|
||||||
PROGRAMS fetch-ocsp-response
|
|
||||||
DESTINATION "${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}"
|
|
||||||
)
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# nghttp2 - HTTP/2 C Library
|
|
||||||
|
|
||||||
# Copyright (c) 2015 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.
|
|
||||||
|
|
||||||
EXTRA_DIST = README.rst CMakeLists.txt
|
|
||||||
dist_pkgdata_SCRIPTS = fetch-ocsp-response
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
fetch-ocsp-response is a Python script which performs OCSP query and
|
|
||||||
get response. It uses openssl command under the hood. nghttpx uses
|
|
||||||
it to enable OCSP stapling feature.
|
|
||||||
|
|
||||||
fetch-ocsp-response is a translation from original fetch-ocsp-response
|
|
||||||
written in Perl and which has been developed as part of h2o project
|
|
||||||
(https://github.com/h2o/h2o).
|
|
||||||
|
|
||||||
fetch-ocsp-response is usually installed under $(pkgdatadir), which is
|
|
||||||
$(prefix)/share/nghttp2.
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# nghttp2 - HTTP/2 C Library
|
|
||||||
|
|
||||||
# Copyright (c) 2015 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.
|
|
||||||
|
|
||||||
# This program was translated from the program originally developed by
|
|
||||||
# h2o project (https://github.com/h2o/h2o), written in Perl. It had
|
|
||||||
# the following copyright notice:
|
|
||||||
|
|
||||||
# Copyright (c) 2015 DeNA Co., Ltd.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
import argparse
|
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
import re
|
|
||||||
import shutil
|
|
||||||
import subprocess
|
|
||||||
import sys
|
|
||||||
import tempfile
|
|
||||||
|
|
||||||
# make this program work for both Python 3 and Python 2.
|
|
||||||
try:
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
stdout_bwrite = sys.stdout.buffer.write
|
|
||||||
except ImportError:
|
|
||||||
from urlparse import urlparse
|
|
||||||
stdout_bwrite = sys.stdout.write
|
|
||||||
|
|
||||||
|
|
||||||
def die(msg):
|
|
||||||
sys.stderr.write(msg)
|
|
||||||
sys.stderr.write('\n')
|
|
||||||
sys.exit(255)
|
|
||||||
|
|
||||||
|
|
||||||
def tempfail(msg):
|
|
||||||
sys.stderr.write(msg)
|
|
||||||
sys.stderr.write('\n')
|
|
||||||
sys.exit(os.EX_TEMPFAIL)
|
|
||||||
|
|
||||||
|
|
||||||
def run_openssl(args, allow_tempfail=False):
|
|
||||||
buf = io.BytesIO()
|
|
||||||
try:
|
|
||||||
p = subprocess.Popen(args, stdout=subprocess.PIPE)
|
|
||||||
except Exception as e:
|
|
||||||
die('failed to invoke {}:{}'.format(args, e))
|
|
||||||
try:
|
|
||||||
while True:
|
|
||||||
data = p.stdout.read()
|
|
||||||
if len(data) == 0:
|
|
||||||
break
|
|
||||||
buf.write(data)
|
|
||||||
if p.wait() != 0:
|
|
||||||
raise Exception('nonzero return code {}'.format(p.returncode))
|
|
||||||
return buf.getvalue()
|
|
||||||
except Exception as e:
|
|
||||||
msg = 'OpenSSL exited abnormally: {}:{}'.format(args, e)
|
|
||||||
tempfail(msg) if allow_tempfail else die(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def read_file(path):
|
|
||||||
with open(path, 'rb') as f:
|
|
||||||
return f.read()
|
|
||||||
|
|
||||||
|
|
||||||
def write_file(path, data):
|
|
||||||
with open(path, 'wb') as f:
|
|
||||||
f.write(data)
|
|
||||||
|
|
||||||
|
|
||||||
def detect_openssl_version(cmd):
|
|
||||||
return run_openssl([cmd, 'version']).decode('utf-8').strip()
|
|
||||||
|
|
||||||
|
|
||||||
def extract_ocsp_uri(cmd, cert_fn):
|
|
||||||
# obtain ocsp uri
|
|
||||||
ocsp_uri = run_openssl(
|
|
||||||
[cmd, 'x509', '-in', cert_fn, '-noout',
|
|
||||||
'-ocsp_uri']).decode('utf-8').strip()
|
|
||||||
|
|
||||||
if not re.match(r'^https?://', ocsp_uri):
|
|
||||||
die('failed to extract ocsp URI from {}'.format(cert_fn))
|
|
||||||
|
|
||||||
return ocsp_uri
|
|
||||||
|
|
||||||
|
|
||||||
def save_issuer_certificate(issuer_fn, cert_fn):
|
|
||||||
# save issuer certificate
|
|
||||||
chain = read_file(cert_fn).decode('utf-8')
|
|
||||||
m = re.match(
|
|
||||||
r'.*?-----END CERTIFICATE-----.*?(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)',
|
|
||||||
chain, re.DOTALL)
|
|
||||||
if not m:
|
|
||||||
die('--issuer option was not used, and failed to extract issuer certificate from the certificate')
|
|
||||||
write_file(issuer_fn, (m.group(1) + '\n').encode('utf-8'))
|
|
||||||
|
|
||||||
|
|
||||||
def send_and_receive_ocsp(respder_fn, cmd, cert_fn, issuer_fn, ocsp_uri,
|
|
||||||
ocsp_host, openssl_version):
|
|
||||||
# obtain response (without verification)
|
|
||||||
sys.stderr.write('sending OCSP request to {}\n'.format(ocsp_uri))
|
|
||||||
args = [
|
|
||||||
cmd, 'ocsp', '-issuer', issuer_fn, '-cert', cert_fn, '-url', ocsp_uri,
|
|
||||||
'-noverify', '-respout', respder_fn
|
|
||||||
]
|
|
||||||
ver = openssl_version.lower()
|
|
||||||
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')
|
|
||||||
|
|
||||||
|
|
||||||
def verify_response(cmd, tempdir, issuer_fn, respder_fn):
|
|
||||||
# verify the response
|
|
||||||
sys.stderr.write('verifying the response signature\n')
|
|
||||||
|
|
||||||
verify_fn = os.path.join(tempdir, 'verify.out')
|
|
||||||
|
|
||||||
# try from exotic options
|
|
||||||
allextra = [
|
|
||||||
# for comodo
|
|
||||||
['-VAfile', issuer_fn],
|
|
||||||
# these options are only available in OpenSSL >= 1.0.2
|
|
||||||
['-partial_chain', '-trusted_first', '-CAfile', issuer_fn],
|
|
||||||
# for OpenSSL <= 1.0.1
|
|
||||||
['-CAfile', issuer_fn],
|
|
||||||
]
|
|
||||||
|
|
||||||
for extra in allextra:
|
|
||||||
with open(verify_fn, 'w+b') as f:
|
|
||||||
args = [cmd, 'ocsp', '-respin', respder_fn]
|
|
||||||
args.extend(extra)
|
|
||||||
p = subprocess.Popen(args, stdout=f, stderr=f)
|
|
||||||
if p.wait() == 0:
|
|
||||||
# OpenSSL <= 1.0.1, openssl ocsp still returns exit
|
|
||||||
# code 0 even if verification was failed. So check
|
|
||||||
# the error message in stderr output.
|
|
||||||
f.seek(0)
|
|
||||||
if f.read().decode('utf-8').find(
|
|
||||||
'Response Verify Failure') != -1:
|
|
||||||
continue
|
|
||||||
sys.stderr.write('verify OK (used: {})\n'.format(extra))
|
|
||||||
return True
|
|
||||||
|
|
||||||
sys.stderr.write(read_file(verify_fn).decode('utf-8'))
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_ocsp_response(cmd, cert_fn, tempdir, issuer_fn=None):
|
|
||||||
openssl_version = detect_openssl_version(cmd)
|
|
||||||
|
|
||||||
sys.stderr.write(
|
|
||||||
'fetch-ocsp-response (using {})\n'.format(openssl_version))
|
|
||||||
|
|
||||||
ocsp_uri = extract_ocsp_uri(cmd, cert_fn)
|
|
||||||
ocsp_host = urlparse(ocsp_uri).netloc
|
|
||||||
|
|
||||||
if not issuer_fn:
|
|
||||||
issuer_fn = os.path.join(tempdir, 'issuer.crt')
|
|
||||||
save_issuer_certificate(issuer_fn, cert_fn)
|
|
||||||
|
|
||||||
respder_fn = os.path.join(tempdir, 'resp.der')
|
|
||||||
resp = send_and_receive_ocsp(
|
|
||||||
respder_fn, cmd, cert_fn, issuer_fn, ocsp_uri, ocsp_host,
|
|
||||||
openssl_version)
|
|
||||||
|
|
||||||
sys.stderr.write('{}\n'.format(resp))
|
|
||||||
|
|
||||||
# OpenSSL 1.0.2 still returns exit code 0 even if ocsp responder
|
|
||||||
# returned error status (e.g., trylater(3))
|
|
||||||
if resp.find('Responder Error:') != -1:
|
|
||||||
raise Exception('responder returned error')
|
|
||||||
|
|
||||||
if not verify_response(cmd, tempdir, issuer_fn, respder_fn):
|
|
||||||
tempfail('failed to verify the response')
|
|
||||||
|
|
||||||
# success
|
|
||||||
res = read_file(respder_fn)
|
|
||||||
stdout_bwrite(res)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description=
|
|
||||||
'''The command issues an OCSP request for given server certificate, verifies the response and prints the resulting DER.''',
|
|
||||||
epilog=
|
|
||||||
'''The command exits 0 if successful, or 75 (EX_TEMPFAIL) on temporary error. Other exit codes may be returned in case of hard errors.''')
|
|
||||||
parser.add_argument(
|
|
||||||
'--issuer',
|
|
||||||
metavar='FILE',
|
|
||||||
help=
|
|
||||||
'issuer certificate (if omitted, is extracted from the certificate chain)')
|
|
||||||
parser.add_argument('--openssl',
|
|
||||||
metavar='CMD',
|
|
||||||
help='openssl command to use (default: "openssl")',
|
|
||||||
default='openssl')
|
|
||||||
parser.add_argument('certificate',
|
|
||||||
help='path to certificate file to validate')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
tempdir = None
|
|
||||||
try:
|
|
||||||
# Python3.2 has tempfile.TemporaryDirectory, which has nice
|
|
||||||
# feature to delete its tree by cleanup() function. We have
|
|
||||||
# to support Python2.7, so we have to do this manually.
|
|
||||||
tempdir = tempfile.mkdtemp()
|
|
||||||
fetch_ocsp_response(args.openssl, args.certificate, tempdir,
|
|
||||||
args.issuer)
|
|
||||||
finally:
|
|
||||||
if tempdir:
|
|
||||||
shutil.rmtree(tempdir)
|
|
||||||
@@ -16,7 +16,9 @@ include_directories(
|
|||||||
${LIBNGHTTP3_INCLUDE_DIRS}
|
${LIBNGHTTP3_INCLUDE_DIRS}
|
||||||
${LIBNGTCP2_INCLUDE_DIRS}
|
${LIBNGTCP2_INCLUDE_DIRS}
|
||||||
${LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIRS}
|
${LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIRS}
|
||||||
|
${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS}
|
||||||
${LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIRS}
|
${LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIRS}
|
||||||
|
${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS}
|
||||||
${OPENSSL_INCLUDE_DIRS}
|
${OPENSSL_INCLUDE_DIRS}
|
||||||
${WOLFSSL_INCLUDE_DIRS}
|
${WOLFSSL_INCLUDE_DIRS}
|
||||||
${LIBCARES_INCLUDE_DIRS}
|
${LIBCARES_INCLUDE_DIRS}
|
||||||
@@ -36,7 +38,9 @@ link_libraries(
|
|||||||
${LIBNGHTTP3_LIBRARIES}
|
${LIBNGHTTP3_LIBRARIES}
|
||||||
${LIBNGTCP2_LIBRARIES}
|
${LIBNGTCP2_LIBRARIES}
|
||||||
${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}
|
${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}
|
||||||
|
${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES}
|
||||||
${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}
|
${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}
|
||||||
|
${LIBNGTCP2_CRYPTO_OSSL_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
${WOLFSSL_LIBRARIES}
|
${WOLFSSL_LIBRARIES}
|
||||||
${LIBCARES_LIBRARIES}
|
${LIBCARES_LIBRARIES}
|
||||||
@@ -85,7 +89,6 @@ if(ENABLE_APP)
|
|||||||
list(APPEND H2LOAD_SOURCES
|
list(APPEND H2LOAD_SOURCES
|
||||||
h2load_http3_session.cc
|
h2load_http3_session.cc
|
||||||
h2load_quic.cc
|
h2load_quic.cc
|
||||||
quic.cc
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -125,7 +128,6 @@ if(ENABLE_APP)
|
|||||||
shrpx_api_downstream_connection.cc
|
shrpx_api_downstream_connection.cc
|
||||||
shrpx_health_monitor_downstream_connection.cc
|
shrpx_health_monitor_downstream_connection.cc
|
||||||
shrpx_null_downstream_connection.cc
|
shrpx_null_downstream_connection.cc
|
||||||
shrpx_exec.cc
|
|
||||||
shrpx_dns_resolver.cc
|
shrpx_dns_resolver.cc
|
||||||
shrpx_dual_dns_resolver.cc
|
shrpx_dual_dns_resolver.cc
|
||||||
shrpx_dns_tracker.cc
|
shrpx_dns_tracker.cc
|
||||||
@@ -147,7 +149,6 @@ if(ENABLE_APP)
|
|||||||
shrpx_quic_connection_handler.cc
|
shrpx_quic_connection_handler.cc
|
||||||
shrpx_http3_upstream.cc
|
shrpx_http3_upstream.cc
|
||||||
http3.cc
|
http3.cc
|
||||||
quic.cc
|
|
||||||
siphash.cc
|
siphash.cc
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
@@ -248,6 +249,7 @@ if(ENABLE_HPACK_TOOLS)
|
|||||||
comp_helper.c
|
comp_helper.c
|
||||||
util.cc
|
util.cc
|
||||||
timegm.c
|
timegm.c
|
||||||
|
tls.cc
|
||||||
)
|
)
|
||||||
add_executable(inflatehd ${inflatehd_SOURCES})
|
add_executable(inflatehd ${inflatehd_SOURCES})
|
||||||
add_executable(deflatehd ${deflatehd_SOURCES})
|
add_executable(deflatehd ${deflatehd_SOURCES})
|
||||||
|
|||||||
@@ -39,30 +39,28 @@ HtmlParser::HtmlParser(const std::string &base_uri)
|
|||||||
HtmlParser::~HtmlParser() { htmlFreeParserCtxt(parser_ctx_); }
|
HtmlParser::~HtmlParser() { htmlFreeParserCtxt(parser_ctx_); }
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
StringRef get_attr(const xmlChar **attrs, const StringRef &name) {
|
std::string_view get_attr(const xmlChar **attrs, const std::string_view &name) {
|
||||||
if (attrs == nullptr) {
|
if (attrs == nullptr) {
|
||||||
return StringRef{};
|
return ""sv;
|
||||||
}
|
}
|
||||||
for (; *attrs; attrs += 2) {
|
for (; *attrs; attrs += 2) {
|
||||||
if (util::strieq(
|
if (util::strieq(std::string_view{reinterpret_cast<const char *>(attrs[0])},
|
||||||
StringRef{attrs[0], strlen(reinterpret_cast<const char *>(attrs[0]))},
|
|
||||||
name)) {
|
name)) {
|
||||||
return StringRef{attrs[1],
|
return std::string_view{reinterpret_cast<const char *>(attrs[1])};
|
||||||
strlen(reinterpret_cast<const char *>(attrs[1]))};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return StringRef{};
|
return ""sv;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
ResourceType
|
ResourceType
|
||||||
get_resource_type_for_preload_as(const StringRef &attribute_value) {
|
get_resource_type_for_preload_as(const std::string_view &attribute_value) {
|
||||||
if (util::strieq("image"_sr, attribute_value)) {
|
if (util::strieq("image"sv, attribute_value)) {
|
||||||
return REQ_IMG;
|
return REQ_IMG;
|
||||||
} else if (util::strieq("style"_sr, attribute_value)) {
|
} else if (util::strieq("style"sv, attribute_value)) {
|
||||||
return REQ_CSS;
|
return REQ_CSS;
|
||||||
} else if (util::strieq("script"_sr, attribute_value)) {
|
} else if (util::strieq("script"sv, attribute_value)) {
|
||||||
return REQ_UNBLOCK_JS;
|
return REQ_UNBLOCK_JS;
|
||||||
} else {
|
} else {
|
||||||
return REQ_OTHERS;
|
return REQ_OTHERS;
|
||||||
@@ -71,7 +69,7 @@ get_resource_type_for_preload_as(const StringRef &attribute_value) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void add_link(ParserData *parser_data, const StringRef &uri,
|
void add_link(ParserData *parser_data, const std::string_view &uri,
|
||||||
ResourceType res_type) {
|
ResourceType res_type) {
|
||||||
auto u = xmlBuildURI(
|
auto u = xmlBuildURI(
|
||||||
reinterpret_cast<const xmlChar *>(uri.data()),
|
reinterpret_cast<const xmlChar *>(uri.data()),
|
||||||
@@ -88,37 +86,36 @@ namespace {
|
|||||||
void start_element_func(void *user_data, const xmlChar *src_name,
|
void start_element_func(void *user_data, const xmlChar *src_name,
|
||||||
const xmlChar **attrs) {
|
const xmlChar **attrs) {
|
||||||
auto parser_data = static_cast<ParserData *>(user_data);
|
auto parser_data = static_cast<ParserData *>(user_data);
|
||||||
auto name =
|
auto name = std::string_view{reinterpret_cast<const char *>(src_name)};
|
||||||
StringRef{src_name, strlen(reinterpret_cast<const char *>(src_name))};
|
if (util::strieq("head"sv, name)) {
|
||||||
if (util::strieq("head"_sr, name)) {
|
|
||||||
++parser_data->inside_head;
|
++parser_data->inside_head;
|
||||||
}
|
}
|
||||||
if (util::strieq("link"_sr, name)) {
|
if (util::strieq("link"sv, name)) {
|
||||||
auto rel_attr = get_attr(attrs, "rel"_sr);
|
auto rel_attr = get_attr(attrs, "rel"sv);
|
||||||
auto href_attr = get_attr(attrs, "href"_sr);
|
auto href_attr = get_attr(attrs, "href"sv);
|
||||||
if (rel_attr.empty() || href_attr.empty()) {
|
if (rel_attr.empty() || href_attr.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (util::strieq("shortcut icon"_sr, rel_attr)) {
|
if (util::strieq("shortcut icon"sv, rel_attr)) {
|
||||||
add_link(parser_data, href_attr, REQ_OTHERS);
|
add_link(parser_data, href_attr, REQ_OTHERS);
|
||||||
} else if (util::strieq("stylesheet"_sr, rel_attr)) {
|
} else if (util::strieq("stylesheet"sv, rel_attr)) {
|
||||||
add_link(parser_data, href_attr, REQ_CSS);
|
add_link(parser_data, href_attr, REQ_CSS);
|
||||||
} else if (util::strieq("preload"_sr, rel_attr)) {
|
} else if (util::strieq("preload"sv, rel_attr)) {
|
||||||
auto as_attr = get_attr(attrs, "as"_sr);
|
auto as_attr = get_attr(attrs, "as"sv);
|
||||||
if (as_attr.empty()) {
|
if (as_attr.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
add_link(parser_data, href_attr,
|
add_link(parser_data, href_attr,
|
||||||
get_resource_type_for_preload_as(as_attr));
|
get_resource_type_for_preload_as(as_attr));
|
||||||
}
|
}
|
||||||
} else if (util::strieq("img"_sr, name)) {
|
} else if (util::strieq("img"sv, name)) {
|
||||||
auto src_attr = get_attr(attrs, "src"_sr);
|
auto src_attr = get_attr(attrs, "src"sv);
|
||||||
if (src_attr.empty()) {
|
if (src_attr.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
add_link(parser_data, src_attr, REQ_IMG);
|
add_link(parser_data, src_attr, REQ_IMG);
|
||||||
} else if (util::strieq("script"_sr, name)) {
|
} else if (util::strieq("script"sv, name)) {
|
||||||
auto src_attr = get_attr(attrs, "src"_sr);
|
auto src_attr = get_attr(attrs, "src"sv);
|
||||||
if (src_attr.empty()) {
|
if (src_attr.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -134,9 +131,8 @@ void start_element_func(void *user_data, const xmlChar *src_name,
|
|||||||
namespace {
|
namespace {
|
||||||
void end_element_func(void *user_data, const xmlChar *name) {
|
void end_element_func(void *user_data, const xmlChar *name) {
|
||||||
auto parser_data = static_cast<ParserData *>(user_data);
|
auto parser_data = static_cast<ParserData *>(user_data);
|
||||||
if (util::strieq(
|
if (util::strieq("head"sv,
|
||||||
"head"_sr,
|
std::string_view{reinterpret_cast<const char *>(name)})) {
|
||||||
StringRef{name, strlen(reinterpret_cast<const char *>(name))})) {
|
|
||||||
--parser_data->inside_head;
|
--parser_data->inside_head;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,8 +177,8 @@ xmlSAXHandler saxHandler = {
|
|||||||
|
|
||||||
int HtmlParser::parse_chunk(const char *chunk, size_t size, int fin) {
|
int HtmlParser::parse_chunk(const char *chunk, size_t size, int fin) {
|
||||||
if (!parser_ctx_) {
|
if (!parser_ctx_) {
|
||||||
parser_ctx_ =
|
parser_ctx_ = htmlCreatePushParserCtxt(
|
||||||
htmlCreatePushParserCtxt(&saxHandler, &parser_data_, chunk, size,
|
&saxHandler, &parser_data_, chunk, static_cast<int>(size),
|
||||||
base_uri_.c_str(), XML_CHAR_ENCODING_NONE);
|
base_uri_.c_str(), XML_CHAR_ENCODING_NONE);
|
||||||
if (!parser_ctx_) {
|
if (!parser_ctx_) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -199,7 +195,7 @@ int HtmlParser::parse_chunk(const char *chunk, size_t size, int fin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int HtmlParser::parse_chunk_internal(const char *chunk, size_t size, int fin) {
|
int HtmlParser::parse_chunk_internal(const char *chunk, size_t size, int fin) {
|
||||||
int rv = htmlParseChunk(parser_ctx_, chunk, size, fin);
|
int rv = htmlParseChunk(parser_ctx_, chunk, static_cast<int>(size), fin);
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -31,10 +31,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifdef HAVE_LIBXML2
|
#ifdef HAVE_LIBXML2
|
||||||
|
|
||||||
# include <libxml/HTMLparser.h>
|
# include <libxml/HTMLparser.h>
|
||||||
|
#endif // defined(HAVE_LIBXML2)
|
||||||
#endif // HAVE_LIBXML2
|
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
@@ -72,7 +70,7 @@ private:
|
|||||||
ParserData parser_data_;
|
ParserData parser_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // !HAVE_LIBXML2
|
#else // !defined(HAVE_LIBXML2)
|
||||||
|
|
||||||
class HtmlParser {
|
class HtmlParser {
|
||||||
public:
|
public:
|
||||||
@@ -87,8 +85,8 @@ private:
|
|||||||
std::vector<std::pair<std::string, ResourceType>> links_;
|
std::vector<std::pair<std::string, ResourceType>> links_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !HAVE_LIBXML2
|
#endif // !defined(HAVE_LIBXML2)
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
||||||
#endif // HTML_PARSER_H
|
#endif // !defined(HTML_PARSER_H)
|
||||||
|
|||||||
@@ -27,26 +27,26 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif // HAVE_SYS_SOCKET_H
|
#endif // defined(HAVE_SYS_SOCKET_H)
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
#endif // HAVE_NETDB_H
|
#endif // defined(HAVE_NETDB_H)
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif // HAVE_UNISTD_H
|
#endif // defined(HAVE_UNISTD_H)
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
#endif // HAVE_FCNTL_H
|
#endif // defined(HAVE_FCNTL_H)
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif // HAVE_NETINET_IN_H
|
#endif // defined(HAVE_NETINET_IN_H)
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#ifdef HAVE_ARPA_INET_H
|
#ifdef HAVE_ARPA_INET_H
|
||||||
# include <arpa/inet.h>
|
# include <arpa/inet.h>
|
||||||
#endif // HAVE_ARPA_INET_H
|
#endif // defined(HAVE_ARPA_INET_H)
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <set>
|
#include <unordered_set>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@@ -58,13 +58,13 @@
|
|||||||
# include <wolfssl/options.h>
|
# include <wolfssl/options.h>
|
||||||
# include <wolfssl/openssl/err.h>
|
# include <wolfssl/openssl/err.h>
|
||||||
# include <wolfssl/openssl/dh.h>
|
# include <wolfssl/openssl/dh.h>
|
||||||
#else // !NGHTTP2_OPENSSL_IS_WOLFSSL
|
#else // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
|
||||||
# include <openssl/err.h>
|
# include <openssl/err.h>
|
||||||
# include <openssl/dh.h>
|
# include <openssl/dh.h>
|
||||||
# if OPENSSL_3_0_0_API
|
# if OPENSSL_3_0_0_API
|
||||||
# include <openssl/decoder.h>
|
# include <openssl/decoder.h>
|
||||||
# endif // OPENSSL_3_0_0_API
|
# endif // OPENSSL_3_0_0_API
|
||||||
#endif // !NGHTTP2_OPENSSL_IS_WOLFSSL
|
#endif // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
@@ -76,16 +76,17 @@
|
|||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
# define O_BINARY (0)
|
# define O_BINARY (0)
|
||||||
#endif // O_BINARY
|
#endif // !defined(O_BINARY)
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// TODO could be constexpr
|
// TODO could be constexpr
|
||||||
constexpr auto DEFAULT_HTML = "index.html"_sr;
|
constexpr auto DEFAULT_HTML = "index.html"sv;
|
||||||
constexpr auto NGHTTPD_SERVER = "nghttpd nghttp2/" NGHTTP2_VERSION ""_sr;
|
constexpr auto NGHTTPD_SERVER = "nghttpd nghttp2/" NGHTTP2_VERSION ""sv;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -101,6 +102,7 @@ void print_session_id(int64_t id) { std::cout << "[id=" << id << "] "; }
|
|||||||
|
|
||||||
Config::Config()
|
Config::Config()
|
||||||
: mime_types_file("/etc/mime.types"),
|
: mime_types_file("/etc/mime.types"),
|
||||||
|
groups("X25519:P-256:P-384:P-521"sv),
|
||||||
stream_read_timeout(1_min),
|
stream_read_timeout(1_min),
|
||||||
stream_write_timeout(1_min),
|
stream_write_timeout(1_min),
|
||||||
data_ptr(nullptr),
|
data_ptr(nullptr),
|
||||||
@@ -250,7 +252,9 @@ public:
|
|||||||
option_(nullptr),
|
option_(nullptr),
|
||||||
next_session_id_(1),
|
next_session_id_(1),
|
||||||
tstamp_cached_(ev_now(loop)),
|
tstamp_cached_(ev_now(loop)),
|
||||||
cached_date_(util::http_date(tstamp_cached_)) {
|
cached_date_(
|
||||||
|
util::format_http_date(std::chrono::system_clock::from_time_t(
|
||||||
|
static_cast<time_t>(tstamp_cached_)))) {
|
||||||
nghttp2_session_callbacks_new(&callbacks_);
|
nghttp2_session_callbacks_new(&callbacks_);
|
||||||
|
|
||||||
fill_callback(callbacks_, config_);
|
fill_callback(callbacks_, config_);
|
||||||
@@ -259,7 +263,7 @@ public:
|
|||||||
|
|
||||||
if (config_->encoder_header_table_size != -1) {
|
if (config_->encoder_header_table_size != -1) {
|
||||||
nghttp2_option_set_max_deflate_dynamic_table_size(
|
nghttp2_option_set_max_deflate_dynamic_table_size(
|
||||||
option_, config_->encoder_header_table_size);
|
option_, as_unsigned(config_->encoder_header_table_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
|
||||||
@@ -326,7 +330,11 @@ public:
|
|||||||
}
|
}
|
||||||
add_handler(handler.release());
|
add_handler(handler.release());
|
||||||
}
|
}
|
||||||
void update_cached_date() { cached_date_ = util::http_date(tstamp_cached_); }
|
void update_cached_date() {
|
||||||
|
cached_date_ =
|
||||||
|
util::format_http_date(std::chrono::system_clock::from_time_t(
|
||||||
|
static_cast<time_t>(tstamp_cached_)));
|
||||||
|
}
|
||||||
const std::string &get_cached_date() {
|
const std::string &get_cached_date() {
|
||||||
auto t = ev_now(loop_);
|
auto t = ev_now(loop_);
|
||||||
if (t != tstamp_cached_) {
|
if (t != tstamp_cached_) {
|
||||||
@@ -370,19 +378,13 @@ public:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
FileEntry *cache_fd(const std::string &path, const FileEntry &ent) {
|
FileEntry *cache_fd(const std::string &path, const FileEntry &ent) {
|
||||||
#ifdef HAVE_STD_MAP_EMPLACE
|
|
||||||
auto rv = fd_cache_.emplace(path, std::make_unique<FileEntry>(ent));
|
auto rv = fd_cache_.emplace(path, std::make_unique<FileEntry>(ent));
|
||||||
#else // !HAVE_STD_MAP_EMPLACE
|
|
||||||
// for gcc-4.7
|
|
||||||
auto rv =
|
|
||||||
fd_cache_.insert(std::make_pair(path, std::make_unique<FileEntry>(ent)));
|
|
||||||
#endif // !HAVE_STD_MAP_EMPLACE
|
|
||||||
auto &res = (*rv).second;
|
auto &res = (*rv).second;
|
||||||
res->it = rv;
|
res->it = rv;
|
||||||
fd_cache_lru_.append(res.get());
|
fd_cache_lru_.append(res.get());
|
||||||
|
|
||||||
while (fd_cache_.size() > FILE_ENTRY_EVICT_THRES) {
|
while (fd_cache_.size() > FILE_ENTRY_EVICT_THRES) {
|
||||||
auto ent = fd_cache_lru_.head;
|
auto ent = fd_cache_lru_.front();
|
||||||
if (ent->usecount) {
|
if (ent->usecount) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -407,7 +409,8 @@ public:
|
|||||||
// cache. The timer will be started when there is no handler.
|
// cache. The timer will be started when there is no handler.
|
||||||
}
|
}
|
||||||
void release_unused_fd() {
|
void release_unused_fd() {
|
||||||
for (auto i = std::begin(fd_cache_); i != std::end(fd_cache_);) {
|
for (auto i = std::ranges::begin(fd_cache_);
|
||||||
|
i != std::ranges::end(fd_cache_);) {
|
||||||
auto &ent = (*i).second;
|
auto &ent = (*i).second;
|
||||||
if (ent->usecount != 0) {
|
if (ent->usecount != 0) {
|
||||||
++i;
|
++i;
|
||||||
@@ -423,10 +426,10 @@ public:
|
|||||||
bool handlers_empty() const { return handlers_.empty(); }
|
bool handlers_empty() const { return handlers_.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<Http2Handler *> handlers_;
|
std::unordered_set<Http2Handler *> handlers_;
|
||||||
// cache for file descriptors to read file.
|
// cache for file descriptors to read file.
|
||||||
std::multimap<std::string, std::unique_ptr<FileEntry>> fd_cache_;
|
std::unordered_multimap<std::string, std::unique_ptr<FileEntry>> fd_cache_;
|
||||||
DList<FileEntry> fd_cache_lru_;
|
SList<FileEntry, &FileEntry::slent> fd_cache_lru_;
|
||||||
HttpServer *sv_;
|
HttpServer *sv_;
|
||||||
struct ev_loop *loop_;
|
struct ev_loop *loop_;
|
||||||
const Config *config_;
|
const Config *config_;
|
||||||
@@ -615,16 +618,16 @@ int Http2Handler::fill_wb() {
|
|||||||
|
|
||||||
if (datalen < 0) {
|
if (datalen < 0) {
|
||||||
std::cerr << "nghttp2_session_mem_send2() returned error: "
|
std::cerr << "nghttp2_session_mem_send2() returned error: "
|
||||||
<< nghttp2_strerror(datalen) << std::endl;
|
<< nghttp2_strerror(static_cast<int>(datalen)) << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (datalen == 0) {
|
if (datalen == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto n = wb_.write(data, datalen);
|
auto n = wb_.write(data, as_unsigned(datalen));
|
||||||
if (n < static_cast<decltype(n)>(datalen)) {
|
if (n < static_cast<decltype(n)>(datalen)) {
|
||||||
data_pending_ = data + n;
|
data_pending_ = data + n;
|
||||||
data_pendinglen_ = datalen - n;
|
data_pendinglen_ = as_unsigned(datalen) - n;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,7 +635,6 @@ int Http2Handler::fill_wb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Http2Handler::read_clear() {
|
int Http2Handler::read_clear() {
|
||||||
int rv;
|
|
||||||
std::array<uint8_t, 8_k> buf;
|
std::array<uint8_t, 8_k> buf;
|
||||||
|
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
@@ -649,14 +651,15 @@ int Http2Handler::read_clear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (get_config()->hexdump) {
|
if (get_config()->hexdump) {
|
||||||
util::hexdump(stdout, buf.data(), nread);
|
util::hexdump(stdout, buf.data(), as_unsigned(nread));
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
|
auto nrecv =
|
||||||
if (rv < 0) {
|
nghttp2_session_mem_recv2(session_, buf.data(), as_unsigned(nread));
|
||||||
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
if (nrecv < 0) {
|
||||||
|
if (nrecv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||||
std::cerr << "nghttp2_session_mem_recv2() returned error: "
|
std::cerr << "nghttp2_session_mem_recv2() returned error: "
|
||||||
<< nghttp2_strerror(rv) << std::endl;
|
<< nghttp2_strerror(static_cast<int>(nrecv)) << std::endl;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -679,7 +682,7 @@ int Http2Handler::write_clear() {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wb_.drain(nwrite);
|
wb_.drain(as_unsigned(nwrite));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
wb_.reset();
|
wb_.reset();
|
||||||
@@ -770,17 +773,17 @@ int Http2Handler::read_tls() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nread = rv;
|
auto nread = static_cast<size_t>(rv);
|
||||||
|
|
||||||
if (get_config()->hexdump) {
|
if (get_config()->hexdump) {
|
||||||
util::hexdump(stdout, buf.data(), nread);
|
util::hexdump(stdout, buf.data(), nread);
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
|
auto nrecv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
|
||||||
if (rv < 0) {
|
if (nrecv < 0) {
|
||||||
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
if (nrecv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
|
||||||
std::cerr << "nghttp2_session_mem_recv2() returned error: "
|
std::cerr << "nghttp2_session_mem_recv2() returned error: "
|
||||||
<< nghttp2_strerror(rv) << std::endl;
|
<< nghttp2_strerror(static_cast<int>(nrecv)) << std::endl;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -800,7 +803,7 @@ int Http2Handler::write_tls() {
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (wb_.rleft() > 0) {
|
if (wb_.rleft() > 0) {
|
||||||
auto rv = SSL_write(ssl_, wb_.pos, wb_.rleft());
|
auto rv = SSL_write(ssl_, wb_.pos, static_cast<int>(wb_.rleft()));
|
||||||
|
|
||||||
if (rv <= 0) {
|
if (rv <= 0) {
|
||||||
auto err = SSL_get_error(ssl_, rv);
|
auto err = SSL_get_error(ssl_, rv);
|
||||||
@@ -816,7 +819,7 @@ int Http2Handler::write_tls() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wb_.drain(rv);
|
wb_.drain(static_cast<size_t>(rv));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
wb_.reset();
|
wb_.reset();
|
||||||
@@ -861,14 +864,14 @@ int Http2Handler::connection_made() {
|
|||||||
size_t niv = 2;
|
size_t niv = 2;
|
||||||
|
|
||||||
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
|
||||||
entry[0].value = config->max_concurrent_streams;
|
entry[0].value = static_cast<uint32_t>(config->max_concurrent_streams);
|
||||||
|
|
||||||
entry[1].settings_id = NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES;
|
entry[1].settings_id = NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES;
|
||||||
entry[1].value = 1;
|
entry[1].value = 1;
|
||||||
|
|
||||||
if (config->header_table_size >= 0) {
|
if (config->header_table_size >= 0) {
|
||||||
entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
|
entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
|
||||||
entry[niv].value = config->header_table_size;
|
entry[niv].value = static_cast<uint32_t>(config->header_table_size);
|
||||||
++niv;
|
++niv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,7 +908,7 @@ int Http2Handler::verify_alpn_result() {
|
|||||||
// Check the negotiated protocol in ALPN
|
// Check the negotiated protocol in ALPN
|
||||||
SSL_get0_alpn_selected(ssl_, &next_proto, &next_proto_len);
|
SSL_get0_alpn_selected(ssl_, &next_proto, &next_proto_len);
|
||||||
if (next_proto) {
|
if (next_proto) {
|
||||||
auto proto = StringRef{next_proto, next_proto_len};
|
auto proto = as_string_view(next_proto, next_proto_len);
|
||||||
if (sessions_->get_config()->verbose) {
|
if (sessions_->get_config()->verbose) {
|
||||||
std::cout << "The negotiated protocol: " << proto << std::endl;
|
std::cout << "The negotiated protocol: " << proto << std::endl;
|
||||||
}
|
}
|
||||||
@@ -921,16 +924,17 @@ int Http2Handler::verify_alpn_result() {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
|
int Http2Handler::submit_file_response(const std::string_view &status,
|
||||||
time_t last_modified, off_t file_length,
|
Stream *stream, time_t last_modified,
|
||||||
|
off_t file_length,
|
||||||
const std::string *content_type,
|
const std::string *content_type,
|
||||||
nghttp2_data_provider2 *data_prd) {
|
nghttp2_data_provider2 *data_prd) {
|
||||||
std::string last_modified_str;
|
std::string last_modified_str;
|
||||||
auto nva = std::to_array({
|
auto nva = std::to_array({
|
||||||
http2::make_field(":status"_sr, status),
|
http2::make_field(":status"sv, status),
|
||||||
http2::make_field("server"_sr, NGHTTPD_SERVER),
|
http2::make_field("server"sv, NGHTTPD_SERVER),
|
||||||
http2::make_field("cache-control"_sr, "max-age=3600"_sr),
|
http2::make_field("cache-control"sv, "max-age=3600"sv),
|
||||||
http2::make_field_v("date"_sr, sessions_->get_cached_date()),
|
http2::make_field_v("date"sv, sessions_->get_cached_date()),
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
{},
|
{},
|
||||||
@@ -939,37 +943,38 @@ int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
|
|||||||
size_t nvlen = 4;
|
size_t nvlen = 4;
|
||||||
if (!get_config()->no_content_length) {
|
if (!get_config()->no_content_length) {
|
||||||
nva[nvlen++] = http2::make_field(
|
nva[nvlen++] = http2::make_field(
|
||||||
"content-length"_sr,
|
"content-length"sv,
|
||||||
util::make_string_ref_uint(stream->balloc, file_length));
|
util::make_string_ref_uint(stream->balloc, as_unsigned(file_length)));
|
||||||
}
|
}
|
||||||
if (last_modified != 0) {
|
if (last_modified != 0) {
|
||||||
last_modified_str = util::http_date(last_modified);
|
last_modified_str = util::format_http_date(
|
||||||
nva[nvlen++] = http2::make_field_v("last-modified"_sr, last_modified_str);
|
std::chrono::system_clock::from_time_t(last_modified));
|
||||||
|
nva[nvlen++] = http2::make_field_v("last-modified"sv, last_modified_str);
|
||||||
}
|
}
|
||||||
if (content_type) {
|
if (content_type) {
|
||||||
nva[nvlen++] = http2::make_field_v("content-type"_sr, *content_type);
|
nva[nvlen++] = http2::make_field_v("content-type"sv, *content_type);
|
||||||
}
|
}
|
||||||
auto &trailer_names = get_config()->trailer_names;
|
auto &trailer_names = get_config()->trailer_names;
|
||||||
if (!trailer_names.empty()) {
|
if (!trailer_names.empty()) {
|
||||||
nva[nvlen++] = http2::make_field("trailer"_sr, trailer_names);
|
nva[nvlen++] = http2::make_field("trailer"sv, trailer_names);
|
||||||
}
|
}
|
||||||
return nghttp2_submit_response2(session_, stream->stream_id, nva.data(),
|
return nghttp2_submit_response2(session_, stream->stream_id, nva.data(),
|
||||||
nvlen, data_prd);
|
nvlen, data_prd);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
|
int Http2Handler::submit_response(const std::string_view &status,
|
||||||
const HeaderRefs &headers,
|
int32_t stream_id, const HeaderRefs &headers,
|
||||||
nghttp2_data_provider2 *data_prd) {
|
nghttp2_data_provider2 *data_prd) {
|
||||||
auto nva = std::vector<nghttp2_nv>();
|
auto nva = std::vector<nghttp2_nv>();
|
||||||
nva.reserve(4 + headers.size());
|
nva.reserve(4 + headers.size());
|
||||||
nva.push_back(http2::make_field(":status"_sr, status));
|
nva.push_back(http2::make_field(":status"sv, status));
|
||||||
nva.push_back(http2::make_field("server"_sr, NGHTTPD_SERVER));
|
nva.push_back(http2::make_field("server"sv, NGHTTPD_SERVER));
|
||||||
nva.push_back(http2::make_field_v("date"_sr, sessions_->get_cached_date()));
|
nva.push_back(http2::make_field_v("date"sv, sessions_->get_cached_date()));
|
||||||
|
|
||||||
if (data_prd) {
|
if (data_prd) {
|
||||||
auto &trailer_names = get_config()->trailer_names;
|
auto &trailer_names = get_config()->trailer_names;
|
||||||
if (!trailer_names.empty()) {
|
if (!trailer_names.empty()) {
|
||||||
nva.push_back(http2::make_field("trailer"_sr, trailer_names));
|
nva.push_back(http2::make_field("trailer"sv, trailer_names));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,12 +987,13 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
|
int Http2Handler::submit_response(const std::string_view &status,
|
||||||
|
int32_t stream_id,
|
||||||
nghttp2_data_provider2 *data_prd) {
|
nghttp2_data_provider2 *data_prd) {
|
||||||
auto nva = std::to_array({
|
auto nva = std::to_array({
|
||||||
http2::make_field(":status"_sr, status),
|
http2::make_field(":status"sv, status),
|
||||||
http2::make_field("server"_sr, NGHTTPD_SERVER),
|
http2::make_field("server"sv, NGHTTPD_SERVER),
|
||||||
http2::make_field_v("date"_sr, sessions_->get_cached_date()),
|
http2::make_field_v("date"sv, sessions_->get_cached_date()),
|
||||||
{},
|
{},
|
||||||
});
|
});
|
||||||
size_t nvlen = 3;
|
size_t nvlen = 3;
|
||||||
@@ -995,7 +1001,7 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
|
|||||||
if (data_prd) {
|
if (data_prd) {
|
||||||
auto &trailer_names = get_config()->trailer_names;
|
auto &trailer_names = get_config()->trailer_names;
|
||||||
if (!trailer_names.empty()) {
|
if (!trailer_names.empty()) {
|
||||||
nva[nvlen++] = http2::make_field("trailer"_sr, trailer_names);
|
nva[nvlen++] = http2::make_field("trailer"sv, trailer_names);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,25 +1011,25 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
|
|||||||
|
|
||||||
int Http2Handler::submit_non_final_response(const std::string &status,
|
int Http2Handler::submit_non_final_response(const std::string &status,
|
||||||
int32_t stream_id) {
|
int32_t stream_id) {
|
||||||
auto nva = std::to_array({http2::make_field_v(":status"_sr, status)});
|
auto nva = std::to_array({http2::make_field_v(":status"sv, status)});
|
||||||
return nghttp2_submit_headers(session_, NGHTTP2_FLAG_NONE, stream_id, nullptr,
|
return nghttp2_submit_headers(session_, NGHTTP2_FLAG_NONE, stream_id, nullptr,
|
||||||
nva.data(), nva.size(), nullptr);
|
nva.data(), nva.size(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Http2Handler::submit_push_promise(Stream *stream,
|
int Http2Handler::submit_push_promise(Stream *stream,
|
||||||
const StringRef &push_path) {
|
const std::string_view &push_path) {
|
||||||
auto authority = stream->header.authority;
|
auto authority = stream->header.authority;
|
||||||
|
|
||||||
if (authority.empty()) {
|
if (authority.empty()) {
|
||||||
authority = stream->header.host;
|
authority = stream->header.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto scheme = get_config()->no_tls ? "http"_sr : "https"_sr;
|
auto scheme = get_config()->no_tls ? "http"sv : "https"sv;
|
||||||
|
|
||||||
auto nva = std::to_array({http2::make_field(":method"_sr, "GET"_sr),
|
auto nva = std::to_array({http2::make_field(":method"sv, "GET"sv),
|
||||||
http2::make_field(":path"_sr, push_path),
|
http2::make_field(":path"sv, push_path),
|
||||||
http2::make_field(":scheme"_sr, scheme),
|
http2::make_field(":scheme"sv, scheme),
|
||||||
http2::make_field(":authority"_sr, authority)});
|
http2::make_field(":authority"sv, authority)});
|
||||||
|
|
||||||
auto promised_stream_id = nghttp2_submit_push_promise(
|
auto promised_stream_id = nghttp2_submit_push_promise(
|
||||||
session_, NGHTTP2_FLAG_END_HEADERS, stream->stream_id, nva.data(),
|
session_, NGHTTP2_FLAG_END_HEADERS, stream->stream_id, nva.data(),
|
||||||
@@ -1036,7 +1042,7 @@ int Http2Handler::submit_push_promise(Stream *stream,
|
|||||||
auto promised_stream = std::make_unique<Stream>(this, promised_stream_id);
|
auto promised_stream = std::make_unique<Stream>(this, promised_stream_id);
|
||||||
|
|
||||||
auto &promised_header = promised_stream->header;
|
auto &promised_header = promised_stream->header;
|
||||||
promised_header.method = "GET"_sr;
|
promised_header.method = "GET"sv;
|
||||||
promised_header.path = push_path;
|
promised_header.path = push_path;
|
||||||
promised_header.scheme = scheme;
|
promised_header.scheme = scheme;
|
||||||
promised_header.authority =
|
promised_header.authority =
|
||||||
@@ -1066,7 +1072,7 @@ void Http2Handler::remove_stream(int32_t stream_id) {
|
|||||||
|
|
||||||
Stream *Http2Handler::get_stream(int32_t stream_id) {
|
Stream *Http2Handler::get_stream(int32_t stream_id) {
|
||||||
auto itr = id2stream_.find(stream_id);
|
auto itr = id2stream_.find(stream_id);
|
||||||
if (itr == std::end(id2stream_)) {
|
if (itr == std::ranges::end(id2stream_)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
} else {
|
||||||
return (*itr).second.get();
|
return (*itr).second.get();
|
||||||
@@ -1148,12 +1154,12 @@ void prepare_status_response(Stream *stream, Http2Handler *hd, int status) {
|
|||||||
|
|
||||||
HeaderRefs headers;
|
HeaderRefs headers;
|
||||||
headers.reserve(2);
|
headers.reserve(2);
|
||||||
headers.emplace_back("content-type"_sr, "text/html; charset=UTF-8"_sr);
|
headers.emplace_back("content-type"sv, "text/html; charset=UTF-8"sv);
|
||||||
headers.emplace_back(
|
headers.emplace_back(
|
||||||
"content-length"_sr,
|
"content-length"sv,
|
||||||
util::make_string_ref_uint(stream->balloc, file_ent->length));
|
util::make_string_ref_uint(stream->balloc, as_unsigned(file_ent->length)));
|
||||||
hd->submit_response(StringRef{status_page->status}, stream->stream_id,
|
hd->submit_response(status_page->status, stream->stream_id, headers,
|
||||||
headers, &data_prd);
|
&data_prd);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1174,13 +1180,14 @@ void prepare_echo_response(Stream *stream, Http2Handler *hd) {
|
|||||||
data_prd.read_callback = file_read_callback;
|
data_prd.read_callback = file_read_callback;
|
||||||
|
|
||||||
HeaderRefs headers;
|
HeaderRefs headers;
|
||||||
headers.emplace_back("nghttpd-response"_sr, "echo"_sr);
|
headers.emplace_back("nghttpd-response"sv, "echo"sv);
|
||||||
if (!hd->get_config()->no_content_length) {
|
if (!hd->get_config()->no_content_length) {
|
||||||
headers.emplace_back("content-length"_sr,
|
headers.emplace_back(
|
||||||
util::make_string_ref_uint(stream->balloc, length));
|
"content-length"sv,
|
||||||
|
util::make_string_ref_uint(stream->balloc, as_unsigned(length)));
|
||||||
}
|
}
|
||||||
|
|
||||||
hd->submit_response("200"_sr, stream->stream_id, headers, &data_prd);
|
hd->submit_response("200"sv, stream->stream_id, headers, &data_prd);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1206,7 +1213,7 @@ bool prepare_upload_temp_store(Stream *stream, Http2Handler *hd) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void prepare_redirect_response(Stream *stream, Http2Handler *hd,
|
void prepare_redirect_response(Stream *stream, Http2Handler *hd,
|
||||||
const StringRef &path, int status) {
|
const std::string_view &path, int status) {
|
||||||
auto scheme = stream->header.scheme;
|
auto scheme = stream->header.scheme;
|
||||||
|
|
||||||
auto authority = stream->header.authority;
|
auto authority = stream->header.authority;
|
||||||
@@ -1215,15 +1222,14 @@ void prepare_redirect_response(Stream *stream, Http2Handler *hd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto location =
|
auto location =
|
||||||
concat_string_ref(stream->balloc, scheme, "://"_sr, authority, path);
|
concat_string_ref(stream->balloc, scheme, "://"sv, authority, path);
|
||||||
|
|
||||||
auto headers = HeaderRefs{{"location"_sr, location}};
|
auto headers = HeaderRefs{{"location"sv, location}};
|
||||||
|
|
||||||
auto sessions = hd->get_sessions();
|
auto sessions = hd->get_sessions();
|
||||||
auto status_page = sessions->get_server()->get_status_page(status);
|
auto status_page = sessions->get_server()->get_status_page(status);
|
||||||
|
|
||||||
hd->submit_response(StringRef{status_page->status}, stream->stream_id,
|
hd->submit_response(status_page->status, stream->stream_id, headers, nullptr);
|
||||||
headers, nullptr);
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1246,34 +1252,32 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
last_mod = util::parse_http_date(ims);
|
last_mod = util::parse_http_date(ims);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef raw_path, raw_query;
|
std::string_view raw_path, raw_query;
|
||||||
auto query_pos = std::find(std::begin(reqpath), std::end(reqpath), '?');
|
auto query_pos = std::ranges::find(reqpath, '?');
|
||||||
if (query_pos != std::end(reqpath)) {
|
if (query_pos != std::ranges::end(reqpath)) {
|
||||||
// Do not response to this request to allow clients to test timeouts.
|
// Do not response to this request to allow clients to test timeouts.
|
||||||
if ("nghttpd_do_not_respond_to_req=yes"_sr ==
|
if ("nghttpd_do_not_respond_to_req=yes"sv ==
|
||||||
StringRef{query_pos, std::end(reqpath)}) {
|
std::string_view{query_pos, std::ranges::end(reqpath)}) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
raw_path = StringRef{std::begin(reqpath), query_pos};
|
raw_path = std::string_view{std::ranges::begin(reqpath), query_pos};
|
||||||
raw_query = StringRef{query_pos, std::end(reqpath)};
|
raw_query = std::string_view{query_pos, std::ranges::end(reqpath)};
|
||||||
} else {
|
} else {
|
||||||
raw_path = reqpath;
|
raw_path = reqpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sessions = hd->get_sessions();
|
auto sessions = hd->get_sessions();
|
||||||
|
|
||||||
StringRef path;
|
std::string_view path;
|
||||||
if (std::find(std::begin(raw_path), std::end(raw_path), '%') ==
|
if (util::contains(raw_path, '%')) {
|
||||||
std::end(raw_path)) {
|
|
||||||
path = raw_path;
|
|
||||||
} else {
|
|
||||||
path = util::percent_decode(stream->balloc, raw_path);
|
path = util::percent_decode(stream->balloc, raw_path);
|
||||||
|
} else {
|
||||||
|
path = raw_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
path = http2::path_join(stream->balloc, StringRef{}, StringRef{}, path,
|
path = http2::path_join(stream->balloc, ""sv, ""sv, path, ""sv);
|
||||||
StringRef{});
|
|
||||||
|
|
||||||
if (std::find(std::begin(path), std::end(path), '\\') != std::end(path)) {
|
if (util::contains(path, '\\')) {
|
||||||
if (stream->file_ent) {
|
if (stream->file_ent) {
|
||||||
sessions->release_fd(stream->file_ent);
|
sessions->release_fd(stream->file_ent);
|
||||||
stream->file_ent = nullptr;
|
stream->file_ent = nullptr;
|
||||||
@@ -1284,9 +1288,9 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
|
|
||||||
if (!hd->get_config()->push.empty()) {
|
if (!hd->get_config()->push.empty()) {
|
||||||
auto push_itr = hd->get_config()->push.find(std::string{path});
|
auto push_itr = hd->get_config()->push.find(std::string{path});
|
||||||
if (allow_push && push_itr != std::end(hd->get_config()->push)) {
|
if (allow_push && push_itr != std::ranges::end(hd->get_config()->push)) {
|
||||||
for (auto &push_path : (*push_itr).second) {
|
for (auto &push_path : (*push_itr).second) {
|
||||||
rv = hd->submit_push_promise(stream, StringRef{push_path});
|
rv = hd->submit_push_promise(stream, push_path);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
std::cerr << "nghttp2_submit_push_promise() returned error: "
|
std::cerr << "nghttp2_submit_push_promise() returned error: "
|
||||||
<< nghttp2_strerror(rv) << std::endl;
|
<< nghttp2_strerror(rv) << std::endl;
|
||||||
@@ -1309,10 +1313,10 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
auto p = &file_path[0];
|
auto p = &file_path[0];
|
||||||
|
|
||||||
auto &htdocs = hd->get_config()->htdocs;
|
auto &htdocs = hd->get_config()->htdocs;
|
||||||
p = std::copy(std::begin(htdocs), std::end(htdocs), p);
|
p = std::ranges::copy(htdocs, p).out;
|
||||||
p = std::copy(std::begin(path), std::end(path), p);
|
p = std::ranges::copy(path, p).out;
|
||||||
if (trailing_slash) {
|
if (trailing_slash) {
|
||||||
std::copy(std::begin(DEFAULT_HTML), std::end(DEFAULT_HTML), p);
|
std::ranges::copy(DEFAULT_HTML, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1345,7 +1349,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
close(file);
|
close(file);
|
||||||
|
|
||||||
auto reqpath =
|
auto reqpath =
|
||||||
concat_string_ref(stream->balloc, raw_path, "/"_sr, raw_query);
|
concat_string_ref(stream->balloc, raw_path, "/"sv, raw_query);
|
||||||
|
|
||||||
prepare_redirect_response(stream, hd, reqpath, 301);
|
prepare_redirect_response(stream, hd, reqpath, 301);
|
||||||
|
|
||||||
@@ -1362,7 +1366,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
|
|
||||||
const auto &mime_types = hd->get_config()->mime_types;
|
const auto &mime_types = hd->get_config()->mime_types;
|
||||||
auto content_type_itr = mime_types.find(ext);
|
auto content_type_itr = mime_types.find(ext);
|
||||||
if (content_type_itr != std::end(mime_types)) {
|
if (content_type_itr != std::ranges::end(mime_types)) {
|
||||||
content_type = &(*content_type_itr).second;
|
content_type = &(*content_type_itr).second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1375,15 +1379,15 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
stream->file_ent = file_ent;
|
stream->file_ent = file_ent;
|
||||||
|
|
||||||
if (last_mod_found && file_ent->mtime <= last_mod) {
|
if (last_mod_found && file_ent->mtime <= last_mod) {
|
||||||
hd->submit_response("304"_sr, stream->stream_id, nullptr);
|
hd->submit_response("304"sv, stream->stream_id, nullptr);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto method = stream->header.method;
|
auto method = stream->header.method;
|
||||||
if (method == "HEAD"_sr) {
|
if (method == "HEAD"sv) {
|
||||||
hd->submit_file_response("200"_sr, stream, file_ent->mtime,
|
hd->submit_file_response("200"sv, stream, file_ent->mtime, file_ent->length,
|
||||||
file_ent->length, file_ent->content_type, nullptr);
|
file_ent->content_type, nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1394,7 +1398,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
|
|||||||
data_prd.source.fd = file_ent->fd;
|
data_prd.source.fd = file_ent->fd;
|
||||||
data_prd.read_callback = file_read_callback;
|
data_prd.read_callback = file_read_callback;
|
||||||
|
|
||||||
hd->submit_file_response("200"_sr, stream, file_ent->mtime, file_ent->length,
|
hd->submit_file_response("200"sv, stream, file_ent->mtime, file_ent->length,
|
||||||
file_ent->content_type, &data_prd);
|
file_ent->content_type, &data_prd);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -1429,43 +1433,43 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
|
|
||||||
stream->header_buffer_size += namebuf.len + valuebuf.len;
|
stream->header_buffer_size += namebuf.len + valuebuf.len;
|
||||||
|
|
||||||
auto token = http2::lookup_token(StringRef{namebuf.base, namebuf.len});
|
auto token = http2::lookup_token(as_string_view(namebuf.base, namebuf.len));
|
||||||
|
|
||||||
auto &header = stream->header;
|
auto &header = stream->header;
|
||||||
|
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case http2::HD__METHOD:
|
case http2::HD__METHOD:
|
||||||
header.method = StringRef{valuebuf.base, valuebuf.len};
|
header.method = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.method = value;
|
header.rcbuf.method = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
case http2::HD__SCHEME:
|
case http2::HD__SCHEME:
|
||||||
header.scheme = StringRef{valuebuf.base, valuebuf.len};
|
header.scheme = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.scheme = value;
|
header.rcbuf.scheme = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
case http2::HD__AUTHORITY:
|
case http2::HD__AUTHORITY:
|
||||||
header.authority = StringRef{valuebuf.base, valuebuf.len};
|
header.authority = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.authority = value;
|
header.rcbuf.authority = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
case http2::HD_HOST:
|
case http2::HD_HOST:
|
||||||
header.host = StringRef{valuebuf.base, valuebuf.len};
|
header.host = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.host = value;
|
header.rcbuf.host = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
case http2::HD__PATH:
|
case http2::HD__PATH:
|
||||||
header.path = StringRef{valuebuf.base, valuebuf.len};
|
header.path = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.path = value;
|
header.rcbuf.path = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
case http2::HD_IF_MODIFIED_SINCE:
|
case http2::HD_IF_MODIFIED_SINCE:
|
||||||
header.ims = StringRef{valuebuf.base, valuebuf.len};
|
header.ims = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.ims = value;
|
header.rcbuf.ims = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
case http2::HD_EXPECT:
|
case http2::HD_EXPECT:
|
||||||
header.expect = StringRef{valuebuf.base, valuebuf.len};
|
header.expect = as_string_view(valuebuf.base, valuebuf.len);
|
||||||
header.rcbuf.expect = value;
|
header.rcbuf.expect = value;
|
||||||
nghttp2_rcbuf_incref(value);
|
nghttp2_rcbuf_incref(value);
|
||||||
break;
|
break;
|
||||||
@@ -1531,13 +1535,13 @@ int hd_on_frame_recv_callback(nghttp2_session *session,
|
|||||||
if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
|
if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
|
||||||
auto expect100 = stream->header.expect;
|
auto expect100 = stream->header.expect;
|
||||||
|
|
||||||
if (util::strieq("100-continue"_sr, expect100)) {
|
if (util::strieq("100-continue"sv, expect100)) {
|
||||||
hd->submit_non_final_response("100", frame->hd.stream_id);
|
hd->submit_non_final_response("100", frame->hd.stream_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto method = stream->header.method;
|
auto method = stream->header.method;
|
||||||
if (hd->get_config()->echo_upload &&
|
if (hd->get_config()->echo_upload &&
|
||||||
(method == "POST"_sr || method == "PUT"_sr)) {
|
(method == "POST"sv || method == "PUT"sv)) {
|
||||||
if (!prepare_upload_temp_store(stream, hd)) {
|
if (!prepare_upload_temp_store(stream, hd)) {
|
||||||
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
|
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1649,10 +1653,10 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
|
|||||||
|
|
||||||
auto p = wb->last;
|
auto p = wb->last;
|
||||||
|
|
||||||
p = std::copy_n(framehd, 9, p);
|
p = std::ranges::copy_n(framehd, 9, p).out;
|
||||||
|
|
||||||
if (padlen) {
|
if (padlen) {
|
||||||
*p++ = padlen - 1;
|
*p++ = static_cast<uint8_t>(padlen - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (length) {
|
while (length) {
|
||||||
@@ -1669,12 +1673,12 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
stream->body_offset += nread;
|
stream->body_offset += nread;
|
||||||
length -= nread;
|
length -= as_unsigned(nread);
|
||||||
p += nread;
|
p += nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (padlen) {
|
if (padlen) {
|
||||||
std::fill(p, p + padlen - 1, 0);
|
std::ranges::fill(p, p + padlen - 1, 0);
|
||||||
p += padlen - 1;
|
p += padlen - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1689,7 +1693,8 @@ nghttp2_ssize select_padding_callback(nghttp2_session *session,
|
|||||||
const nghttp2_frame *frame,
|
const nghttp2_frame *frame,
|
||||||
size_t max_payload, void *user_data) {
|
size_t max_payload, void *user_data) {
|
||||||
auto hd = static_cast<Http2Handler *>(user_data);
|
auto hd = static_cast<Http2Handler *>(user_data);
|
||||||
return std::min(max_payload, frame->hd.length + hd->get_config()->padding);
|
return as_signed(
|
||||||
|
std::min(max_payload, frame->hd.length + hd->get_config()->padding));
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1715,7 +1720,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
|
|||||||
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
|
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
len -= n;
|
len -= as_unsigned(n);
|
||||||
data += n;
|
data += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1777,6 +1782,8 @@ void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
|
|||||||
nghttp2_session_callbacks_set_select_padding_callback2(
|
nghttp2_session_callbacks_set_select_padding_callback2(
|
||||||
callbacks, select_padding_callback);
|
callbacks, select_padding_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nghttp2_session_callbacks_set_rand_callback(callbacks, util::secure_random);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -1817,12 +1824,12 @@ void run_worker(Worker *worker) {
|
|||||||
|
|
||||||
#ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
|
#ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
|
||||||
wc_ecc_fp_free();
|
wc_ecc_fp_free();
|
||||||
#endif // NGHTTP2_OPENSSL_IS_WOLFSSL
|
#endif // defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int get_ev_loop_flags() {
|
unsigned int get_ev_loop_flags() {
|
||||||
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
|
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
|
||||||
return ev_recommended_backends() | EVBACKEND_KQUEUE;
|
return ev_recommended_backends() | EVBACKEND_KQUEUE;
|
||||||
}
|
}
|
||||||
@@ -1902,15 +1909,15 @@ public:
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
#ifdef HAVE_ACCEPT4
|
#ifdef HAVE_ACCEPT4
|
||||||
auto fd = accept4(fd_, nullptr, nullptr, SOCK_NONBLOCK);
|
auto fd = accept4(fd_, nullptr, nullptr, SOCK_NONBLOCK);
|
||||||
#else // !HAVE_ACCEPT4
|
#else // !defined(HAVE_ACCEPT4)
|
||||||
auto fd = accept(fd_, nullptr, nullptr);
|
auto fd = accept(fd_, nullptr, nullptr);
|
||||||
#endif // !HAVE_ACCEPT4
|
#endif // !defined(HAVE_ACCEPT4)
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef HAVE_ACCEPT4
|
#ifndef HAVE_ACCEPT4
|
||||||
util::make_socket_nonblocking(fd);
|
util::make_socket_nonblocking(fd);
|
||||||
#endif // !HAVE_ACCEPT4
|
#endif // !defined(HAVE_ACCEPT4)
|
||||||
acceptor_->accept_connection(fd);
|
acceptor_->accept_connection(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1930,7 +1937,7 @@ void acceptcb(struct ev_loop *loop, ev_io *w, int revents) {
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
FileEntry make_status_body(int status, uint16_t port) {
|
FileEntry make_status_body(uint32_t status, uint16_t port) {
|
||||||
BlockAllocator balloc(1024, 1024);
|
BlockAllocator balloc(1024, 1024);
|
||||||
|
|
||||||
auto status_string = http2::stringify_status(balloc, status);
|
auto status_string = http2::stringify_status(balloc, status);
|
||||||
@@ -2012,13 +2019,15 @@ int start_listen(HttpServer *sv, struct ev_loop *loop, Sessions *sessions,
|
|||||||
std::shared_ptr<AcceptHandler> acceptor;
|
std::shared_ptr<AcceptHandler> acceptor;
|
||||||
auto service = util::utos(config->port);
|
auto service = util::utos(config->port);
|
||||||
|
|
||||||
addrinfo hints{};
|
addrinfo hints{
|
||||||
hints.ai_family = AF_UNSPEC;
|
.ai_flags = AI_PASSIVE
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
hints.ai_flags = AI_PASSIVE;
|
|
||||||
#ifdef AI_ADDRCONFIG
|
#ifdef AI_ADDRCONFIG
|
||||||
hints.ai_flags |= AI_ADDRCONFIG;
|
| AI_ADDRCONFIG
|
||||||
#endif // AI_ADDRCONFIG
|
#endif // defined(AI_ADDRCONFIG)
|
||||||
|
,
|
||||||
|
.ai_family = AF_UNSPEC,
|
||||||
|
.ai_socktype = SOCK_STREAM,
|
||||||
|
};
|
||||||
|
|
||||||
if (!config->address.empty()) {
|
if (!config->address.empty()) {
|
||||||
addr = config->address.c_str();
|
addr = config->address.c_str();
|
||||||
@@ -2051,7 +2060,7 @@ int start_listen(HttpServer *sv, struct ev_loop *loop, Sessions *sessions,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // IPV6_V6ONLY
|
#endif // defined(IPV6_V6ONLY)
|
||||||
if (bind(fd, rp->ai_addr, rp->ai_addrlen) == 0 && listen(fd, 1000) == 0) {
|
if (bind(fd, rp->ai_addr, rp->ai_addrlen) == 0 && listen(fd, 1000) == 0) {
|
||||||
if (!acceptor) {
|
if (!acceptor) {
|
||||||
acceptor = std::make_shared<AcceptHandler>(sv, sessions, config);
|
acceptor = std::make_shared<AcceptHandler>(sv, sessions, config);
|
||||||
@@ -2103,7 +2112,6 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
|
|||||||
|
|
||||||
int HttpServer::run() {
|
int HttpServer::run() {
|
||||||
SSL_CTX *ssl_ctx = nullptr;
|
SSL_CTX *ssl_ctx = nullptr;
|
||||||
std::vector<unsigned char> next_proto;
|
|
||||||
|
|
||||||
if (!config_->no_tls) {
|
if (!config_->no_tls) {
|
||||||
ssl_ctx = SSL_CTX_new(TLS_server_method());
|
ssl_ctx = SSL_CTX_new(TLS_server_method());
|
||||||
@@ -2112,17 +2120,17 @@ int HttpServer::run() {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ssl_opts = (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) |
|
auto ssl_opts = static_cast<nghttp2_ssl_op_type>(
|
||||||
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION |
|
(SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) | SSL_OP_NO_SSLv2 |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
|
SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_TICKET |
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
|
||||||
SSL_OP_CIPHER_SERVER_PREFERENCE;
|
SSL_OP_NO_TICKET | SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||||
|
|
||||||
#ifdef SSL_OP_ENABLE_KTLS
|
#ifdef SSL_OP_ENABLE_KTLS
|
||||||
if (config_->ktls) {
|
if (config_->ktls) {
|
||||||
ssl_opts |= SSL_OP_ENABLE_KTLS;
|
ssl_opts |= SSL_OP_ENABLE_KTLS;
|
||||||
}
|
}
|
||||||
#endif // SSL_OP_ENABLE_KTLS
|
#endif // defined(SSL_OP_ENABLE_KTLS)
|
||||||
|
|
||||||
SSL_CTX_set_options(ssl_ctx, ssl_opts);
|
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_AUTO_RETRY);
|
||||||
@@ -2147,19 +2155,17 @@ int HttpServer::run() {
|
|||||||
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
|
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif // NGHTTP2_OPENSSL_IS_WOLFSSL
|
#endif // defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
|
||||||
|
|
||||||
const unsigned char sid_ctx[] = "nghttpd";
|
const unsigned char sid_ctx[] = "nghttpd";
|
||||||
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx) - 1);
|
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx) - 1);
|
||||||
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
|
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_EC
|
if (SSL_CTX_set1_groups_list(ssl_ctx, config_->groups.data()) != 1) {
|
||||||
if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
|
std::cerr << "SSL_CTX_set1_groups_list failed: "
|
||||||
std::cerr << "SSL_CTX_set1_curves_list failed: "
|
|
||||||
<< ERR_error_string(ERR_get_error(), nullptr);
|
<< ERR_error_string(ERR_get_error(), nullptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif // OPENSSL_NO_EC
|
|
||||||
|
|
||||||
if (!config_->dh_param_file.empty()) {
|
if (!config_->dh_param_file.empty()) {
|
||||||
// Read DH parameters from file
|
// Read DH parameters from file
|
||||||
@@ -2223,8 +2229,6 @@ int HttpServer::run() {
|
|||||||
verify_callback);
|
verify_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
next_proto = util::get_default_alpn();
|
|
||||||
|
|
||||||
// ALPN selection callback
|
// ALPN selection callback
|
||||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);
|
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);
|
||||||
|
|
||||||
@@ -2235,7 +2239,13 @@ int HttpServer::run() {
|
|||||||
std::cerr << "SSL_CTX_add_cert_compression_alg failed." << std::endl;
|
std::cerr << "SSL_CTX_add_cert_compression_alg failed." << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
|
#endif // defined(NGHTTP2_OPENSSL_IS_BORINGSSL) &&
|
||||||
|
// defined(HAVE_LIBBROTLI)
|
||||||
|
|
||||||
|
if (tls::setup_keylog_callback(ssl_ctx) != 0) {
|
||||||
|
std::cerr << "Failed to setup keylog" << std::endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto loop = EV_DEFAULT;
|
auto loop = EV_DEFAULT;
|
||||||
|
|||||||
@@ -34,17 +34,18 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <unordered_map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "ssl_compat.h"
|
#include "ssl_compat.h"
|
||||||
|
|
||||||
#ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
|
#ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
|
||||||
# include <wolfssl/options.h>
|
# include <wolfssl/options.h>
|
||||||
# include <wolfssl/openssl/ssl.h>
|
# include <wolfssl/openssl/ssl.h>
|
||||||
#else // !NGHTTP2_OPENSSL_IS_WOLFSSL
|
#else // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
|
||||||
# include <openssl/ssl.h>
|
# include <openssl/ssl.h>
|
||||||
#endif // !NGHTTP2_OPENSSL_IS_WOLFSSL
|
#endif // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
|
||||||
|
|
||||||
#include <ev.h>
|
#include <ev.h>
|
||||||
|
|
||||||
@@ -59,8 +60,8 @@
|
|||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
std::map<std::string, std::vector<std::string>> push;
|
std::unordered_map<std::string, std::vector<std::string>> push;
|
||||||
std::map<std::string, std::string> mime_types;
|
std::unordered_map<std::string, std::string> mime_types;
|
||||||
Headers trailer;
|
Headers trailer;
|
||||||
std::string trailer_names;
|
std::string trailer_names;
|
||||||
std::string htdocs;
|
std::string htdocs;
|
||||||
@@ -70,6 +71,7 @@ struct Config {
|
|||||||
std::string dh_param_file;
|
std::string dh_param_file;
|
||||||
std::string address;
|
std::string address;
|
||||||
std::string mime_types_file;
|
std::string mime_types_file;
|
||||||
|
std::string_view groups;
|
||||||
ev_tstamp stream_read_timeout;
|
ev_tstamp stream_read_timeout;
|
||||||
ev_tstamp stream_write_timeout;
|
ev_tstamp stream_write_timeout;
|
||||||
void *data_ptr;
|
void *data_ptr;
|
||||||
@@ -107,31 +109,29 @@ struct FileEntry {
|
|||||||
mtime(mtime),
|
mtime(mtime),
|
||||||
last_valid(last_valid),
|
last_valid(last_valid),
|
||||||
content_type(content_type),
|
content_type(content_type),
|
||||||
dlnext(nullptr),
|
|
||||||
dlprev(nullptr),
|
|
||||||
fd(fd),
|
fd(fd),
|
||||||
usecount(1),
|
usecount(1),
|
||||||
stale(stale) {}
|
stale(stale) {}
|
||||||
std::string path;
|
std::string path;
|
||||||
std::multimap<std::string, std::unique_ptr<FileEntry>>::iterator it;
|
std::unordered_multimap<std::string, std::unique_ptr<FileEntry>>::iterator it;
|
||||||
int64_t length;
|
int64_t length;
|
||||||
int64_t mtime;
|
int64_t mtime;
|
||||||
std::chrono::steady_clock::time_point last_valid;
|
std::chrono::steady_clock::time_point last_valid;
|
||||||
const std::string *content_type;
|
const std::string *content_type;
|
||||||
FileEntry *dlnext, *dlprev;
|
SListEntry<FileEntry> slent;
|
||||||
int fd;
|
int fd;
|
||||||
int usecount;
|
int usecount;
|
||||||
bool stale;
|
bool stale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RequestHeader {
|
struct RequestHeader {
|
||||||
StringRef method;
|
std::string_view method;
|
||||||
StringRef scheme;
|
std::string_view scheme;
|
||||||
StringRef authority;
|
std::string_view authority;
|
||||||
StringRef host;
|
std::string_view host;
|
||||||
StringRef path;
|
std::string_view path;
|
||||||
StringRef ims;
|
std::string_view ims;
|
||||||
StringRef expect;
|
std::string_view expect;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
nghttp2_rcbuf *method;
|
nghttp2_rcbuf *method;
|
||||||
@@ -176,21 +176,21 @@ public:
|
|||||||
int connection_made();
|
int connection_made();
|
||||||
int verify_alpn_result();
|
int verify_alpn_result();
|
||||||
|
|
||||||
int submit_file_response(const StringRef &status, Stream *stream,
|
int submit_file_response(const std::string_view &status, Stream *stream,
|
||||||
time_t last_modified, off_t file_length,
|
time_t last_modified, off_t file_length,
|
||||||
const std::string *content_type,
|
const std::string *content_type,
|
||||||
nghttp2_data_provider2 *data_prd);
|
nghttp2_data_provider2 *data_prd);
|
||||||
|
|
||||||
int submit_response(const StringRef &status, int32_t stream_id,
|
int submit_response(const std::string_view &status, int32_t stream_id,
|
||||||
nghttp2_data_provider2 *data_prd);
|
nghttp2_data_provider2 *data_prd);
|
||||||
|
|
||||||
int submit_response(const StringRef &status, int32_t stream_id,
|
int submit_response(const std::string_view &status, int32_t stream_id,
|
||||||
const HeaderRefs &headers,
|
const HeaderRefs &headers,
|
||||||
nghttp2_data_provider2 *data_prd);
|
nghttp2_data_provider2 *data_prd);
|
||||||
|
|
||||||
int submit_non_final_response(const std::string &status, int32_t stream_id);
|
int submit_non_final_response(const std::string &status, int32_t stream_id);
|
||||||
|
|
||||||
int submit_push_promise(Stream *stream, const StringRef &push_path);
|
int submit_push_promise(Stream *stream, const std::string_view &push_path);
|
||||||
|
|
||||||
int submit_rst_stream(Stream *stream, uint32_t error_code);
|
int submit_rst_stream(Stream *stream, uint32_t error_code);
|
||||||
|
|
||||||
@@ -221,7 +221,7 @@ private:
|
|||||||
ev_io wev_;
|
ev_io wev_;
|
||||||
ev_io rev_;
|
ev_io rev_;
|
||||||
ev_timer settings_timerev_;
|
ev_timer settings_timerev_;
|
||||||
std::map<int32_t, std::unique_ptr<Stream>> id2stream_;
|
std::unordered_map<int32_t, std::unique_ptr<Stream>> id2stream_;
|
||||||
WriteBuf wb_;
|
WriteBuf wb_;
|
||||||
std::function<int(Http2Handler &)> read_, write_;
|
std::function<int(Http2Handler &)> read_, write_;
|
||||||
int64_t session_id_;
|
int64_t session_id_;
|
||||||
@@ -258,4 +258,4 @@ nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
|
|||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
||||||
#endif // HTTP_SERVER_H
|
#endif // !defined(HTTP_SERVER_H)
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ AM_CPPFLAGS = \
|
|||||||
@LIBNGHTTP3_CFLAGS@ \
|
@LIBNGHTTP3_CFLAGS@ \
|
||||||
@LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@ \
|
@LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@ \
|
||||||
@LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@ \
|
@LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@ \
|
||||||
|
@LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS@ \
|
||||||
@LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ \
|
@LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ \
|
||||||
|
@LIBNGTCP2_CRYPTO_OSSL_CFLAGS@ \
|
||||||
@LIBNGTCP2_CFLAGS@ \
|
@LIBNGTCP2_CFLAGS@ \
|
||||||
@WOLFSSL_CFLAGS@ \
|
@WOLFSSL_CFLAGS@ \
|
||||||
@OPENSSL_CFLAGS@ \
|
@OPENSSL_CFLAGS@ \
|
||||||
@@ -70,7 +72,9 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
|
|||||||
@LIBNGHTTP3_LIBS@ \
|
@LIBNGHTTP3_LIBS@ \
|
||||||
@LIBNGTCP2_CRYPTO_WOLFSSL_LIBS@ \
|
@LIBNGTCP2_CRYPTO_WOLFSSL_LIBS@ \
|
||||||
@LIBNGTCP2_CRYPTO_QUICTLS_LIBS@ \
|
@LIBNGTCP2_CRYPTO_QUICTLS_LIBS@ \
|
||||||
|
@LIBNGTCP2_CRYPTO_LIBRESSL_LIBS@ \
|
||||||
@LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ \
|
@LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ \
|
||||||
|
@LIBNGTCP2_CRYPTO_OSSL_LIBS@ \
|
||||||
@LIBNGTCP2_LIBS@ \
|
@LIBNGTCP2_LIBS@ \
|
||||||
@WOLFSSL_LIBS@ \
|
@WOLFSSL_LIBS@ \
|
||||||
@OPENSSL_LIBS@ \
|
@OPENSSL_LIBS@ \
|
||||||
@@ -121,8 +125,7 @@ h2load_SOURCES = util.cc util.h \
|
|||||||
if ENABLE_HTTP3
|
if ENABLE_HTTP3
|
||||||
h2load_SOURCES += \
|
h2load_SOURCES += \
|
||||||
h2load_http3_session.cc h2load_http3_session.h \
|
h2load_http3_session.cc h2load_http3_session.h \
|
||||||
h2load_quic.cc h2load_quic.h \
|
h2load_quic.cc h2load_quic.h
|
||||||
quic.cc quic.h
|
|
||||||
endif # ENABLE_HTTP3
|
endif # ENABLE_HTTP3
|
||||||
|
|
||||||
NGHTTPX_SRCS = \
|
NGHTTPX_SRCS = \
|
||||||
@@ -166,7 +169,6 @@ NGHTTPX_SRCS = \
|
|||||||
shrpx_health_monitor_downstream_connection.cc \
|
shrpx_health_monitor_downstream_connection.cc \
|
||||||
shrpx_health_monitor_downstream_connection.h \
|
shrpx_health_monitor_downstream_connection.h \
|
||||||
shrpx_null_downstream_connection.cc shrpx_null_downstream_connection.h \
|
shrpx_null_downstream_connection.cc shrpx_null_downstream_connection.h \
|
||||||
shrpx_exec.cc shrpx_exec.h \
|
|
||||||
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
|
||||||
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
|
||||||
shrpx_dns_tracker.cc shrpx_dns_tracker.h \
|
shrpx_dns_tracker.cc shrpx_dns_tracker.h \
|
||||||
@@ -189,7 +191,6 @@ NGHTTPX_SRCS += \
|
|||||||
shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
|
shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
|
||||||
shrpx_http3_upstream.cc shrpx_http3_upstream.h \
|
shrpx_http3_upstream.cc shrpx_http3_upstream.h \
|
||||||
http3.cc http3.h \
|
http3.cc http3.h \
|
||||||
quic.cc quic.h \
|
|
||||||
siphash.cc siphash.h
|
siphash.cc siphash.h
|
||||||
endif # ENABLE_HTTP3
|
endif # ENABLE_HTTP3
|
||||||
|
|
||||||
@@ -261,7 +262,8 @@ bin_PROGRAMS += inflatehd deflatehd
|
|||||||
HPACK_TOOLS_COMMON_SRCS = \
|
HPACK_TOOLS_COMMON_SRCS = \
|
||||||
comp_helper.c comp_helper.h \
|
comp_helper.c comp_helper.h \
|
||||||
util.cc util.h \
|
util.cc util.h \
|
||||||
timegm.c timegm.h
|
timegm.c timegm.h \
|
||||||
|
tls.cc tls.h
|
||||||
|
|
||||||
inflatehd_SOURCES = inflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)
|
inflatehd_SOURCES = inflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,12 @@
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
# include <sys/uio.h>
|
# include <sys/uio.h>
|
||||||
#endif // !_WIN32
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
|
||||||
@@ -179,7 +180,7 @@ struct BlockAllocator {
|
|||||||
auto nalloclen = std::max(size + 1, alloclen * 2);
|
auto nalloclen = std::max(size + 1, alloclen * 2);
|
||||||
|
|
||||||
auto res = alloc(nalloclen);
|
auto res = alloc(nalloclen);
|
||||||
std::copy_n(p, alloclen, static_cast<uint8_t *>(res));
|
std::ranges::copy_n(p, as_signed(alloclen), static_cast<uint8_t *>(res));
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -195,29 +196,37 @@ struct BlockAllocator {
|
|||||||
size_t isolation_threshold;
|
size_t isolation_threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Makes a copy of |src|. The resulting string will be
|
// Makes a copy of a range [|first|, |last|). The resulting string
|
||||||
// NULL-terminated.
|
// will be NULL-terminated.
|
||||||
template <typename BlockAllocator>
|
template <std::input_iterator I>
|
||||||
StringRef make_string_ref(BlockAllocator &alloc, const StringRef &src) {
|
std::string_view make_string_ref(BlockAllocator &alloc, I first, I last) {
|
||||||
auto dst = static_cast<uint8_t *>(alloc.alloc(src.size() + 1));
|
auto dst = static_cast<char *>(
|
||||||
auto p = dst;
|
alloc.alloc(static_cast<size_t>(std::ranges::distance(first, last) + 1)));
|
||||||
p = std::copy(std::begin(src), std::end(src), p);
|
auto p = std::ranges::copy(first, last, dst).out;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return StringRef{dst, src.size()};
|
|
||||||
|
return std::string_view{dst, p};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Makes a copy of |r| as std::string_view. The resulting string will be
|
||||||
|
// NULL-terminated.
|
||||||
|
template <std::ranges::input_range R>
|
||||||
|
requires(!std::is_array_v<std::remove_cvref_t<R>>)
|
||||||
|
std::string_view make_string_ref(BlockAllocator &alloc, R &&r) {
|
||||||
|
return make_string_ref(alloc, std::ranges::begin(r), std::ranges::end(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
// private function used in concat_string_ref. this is the base
|
// private function used in concat_string_ref. this is the base
|
||||||
// function of concat_string_ref_count().
|
// function of concat_string_ref_count().
|
||||||
inline constexpr size_t concat_string_ref_count(size_t acc) { return acc; }
|
constexpr size_t concat_string_ref_count(size_t acc) { return acc; }
|
||||||
|
|
||||||
// private function used in concat_string_ref. This function counts
|
// private function used in concat_string_ref. This function counts
|
||||||
// the sum of length of given arguments. The calculated length is
|
// the sum of length of given arguments. The calculated length is
|
||||||
// accumulated, and passed to the next function.
|
// accumulated, and passed to the next function.
|
||||||
template <typename... Args>
|
template <std::ranges::input_range R, std::ranges::input_range... Args>
|
||||||
constexpr size_t concat_string_ref_count(size_t acc, const StringRef &value,
|
requires(!std::is_array_v<std::remove_cvref_t<R>>)
|
||||||
Args &&...args) {
|
constexpr size_t concat_string_ref_count(size_t acc, R &&r, Args &&...args) {
|
||||||
return concat_string_ref_count(acc + value.size(),
|
return concat_string_ref_count(acc + std::ranges::size(r), args...);
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// private function used in concat_string_ref. this is the base
|
// private function used in concat_string_ref. this is the base
|
||||||
@@ -228,23 +237,23 @@ inline uint8_t *concat_string_ref_copy(uint8_t *p) { return p; }
|
|||||||
// given strings into |p|. |p| is incremented by the copied length,
|
// given strings into |p|. |p| is incremented by the copied length,
|
||||||
// and returned. In the end, return value points to the location one
|
// and returned. In the end, return value points to the location one
|
||||||
// beyond the last byte written.
|
// beyond the last byte written.
|
||||||
template <typename... Args>
|
template <std::ranges::input_range R, std::ranges::input_range... Args>
|
||||||
uint8_t *concat_string_ref_copy(uint8_t *p, const StringRef &value,
|
requires(!std::is_array_v<std::remove_cvref_t<R>>)
|
||||||
Args &&...args) {
|
uint8_t *concat_string_ref_copy(uint8_t *p, R &&r, Args &&...args) {
|
||||||
p = std::copy(std::begin(value), std::end(value), p);
|
return concat_string_ref_copy(std::ranges::copy(std::forward<R>(r), p).out,
|
||||||
return concat_string_ref_copy(p, std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the string which is the concatenation of |args| in the
|
// Returns the string which is the concatenation of |args| in the
|
||||||
// given order. The resulting string will be NULL-terminated.
|
// given order. The resulting string will be NULL-terminated.
|
||||||
template <typename BlockAllocator, typename... Args>
|
template <std::ranges::input_range... Args>
|
||||||
StringRef concat_string_ref(BlockAllocator &alloc, Args &&...args) {
|
std::string_view concat_string_ref(BlockAllocator &alloc, Args &&...args) {
|
||||||
size_t len = concat_string_ref_count(0, std::forward<Args>(args)...);
|
auto len = concat_string_ref_count(0, args...);
|
||||||
auto dst = static_cast<uint8_t *>(alloc.alloc(len + 1));
|
auto dst = static_cast<uint8_t *>(alloc.alloc(len + 1));
|
||||||
auto p = dst;
|
auto p = dst;
|
||||||
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
|
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return StringRef{dst, len};
|
return as_string_view(dst, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the string which is the concatenation of |value| and |args|
|
// Returns the string which is the concatenation of |value| and |args|
|
||||||
@@ -253,30 +262,30 @@ StringRef concat_string_ref(BlockAllocator &alloc, Args &&...args) {
|
|||||||
// obtained from alloc.alloc() or alloc.realloc(), and attempts to use
|
// obtained from alloc.alloc() or alloc.realloc(), and attempts to use
|
||||||
// unused memory region by using alloc.realloc(). If value is empty,
|
// unused memory region by using alloc.realloc(). If value is empty,
|
||||||
// then just call concat_string_ref().
|
// then just call concat_string_ref().
|
||||||
template <typename BlockAllocator, typename... Args>
|
template <std::ranges::input_range... Args>
|
||||||
StringRef realloc_concat_string_ref(BlockAllocator &alloc,
|
std::string_view realloc_concat_string_ref(BlockAllocator &alloc,
|
||||||
const StringRef &value, Args &&...args) {
|
const std::string_view &value,
|
||||||
|
Args &&...args) {
|
||||||
if (value.empty()) {
|
if (value.empty()) {
|
||||||
return concat_string_ref(alloc, std::forward<Args>(args)...);
|
return concat_string_ref(alloc, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto len =
|
auto len = value.size() + concat_string_ref_count(0, args...);
|
||||||
value.size() + concat_string_ref_count(0, std::forward<Args>(args)...);
|
auto dst = static_cast<uint8_t *>(alloc.realloc(
|
||||||
auto dst = static_cast<uint8_t *>(
|
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data())),
|
||||||
alloc.realloc(const_cast<uint8_t *>(value.byte()), len + 1));
|
len + 1));
|
||||||
auto p = dst + value.size();
|
auto p = dst + value.size();
|
||||||
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
|
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
return StringRef{dst, len};
|
return as_string_view(dst, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makes an uninitialized buffer with given size.
|
// Makes an uninitialized buffer with given size.
|
||||||
template <typename BlockAllocator>
|
inline std::span<uint8_t> make_byte_ref(BlockAllocator &alloc, size_t size) {
|
||||||
std::span<uint8_t> make_byte_ref(BlockAllocator &alloc, size_t size) {
|
|
||||||
return {static_cast<uint8_t *>(alloc.alloc(size)), size};
|
return {static_cast<uint8_t *>(alloc.alloc(size)), size};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
||||||
#endif // ALLOCATOR_H
|
#endif // !defined(ALLOCATOR_H)
|
||||||
|
|||||||
@@ -25,19 +25,19 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
#endif // HAVE_SYS_SOCKET_H
|
#endif // defined(HAVE_SYS_SOCKET_H)
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
#endif // HAVE_NETDB_H
|
#endif // defined(HAVE_NETDB_H)
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif // HAVE_UNISTD_H
|
#endif // defined(HAVE_UNISTD_H)
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
#endif // HAVE_FCNTL_H
|
#endif // defined(HAVE_FCNTL_H)
|
||||||
#ifdef HAVE_NETINET_IN_H
|
#ifdef HAVE_NETINET_IN_H
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
#endif // HAVE_NETINET_IN_H
|
#endif // defined(HAVE_NETINET_IN_H)
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
@@ -49,7 +49,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
@@ -329,7 +328,7 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
|
|||||||
case NGHTTP2_PING:
|
case NGHTTP2_PING:
|
||||||
print_frame_attr_indent();
|
print_frame_attr_indent();
|
||||||
fprintf(outfile, "(opaque_data=%s)\n",
|
fprintf(outfile, "(opaque_data=%s)\n",
|
||||||
util::format_hex(frame->ping.opaque_data).c_str());
|
util::format_hex(std::span{frame->ping.opaque_data}).c_str());
|
||||||
break;
|
break;
|
||||||
case NGHTTP2_GOAWAY:
|
case NGHTTP2_GOAWAY:
|
||||||
print_frame_attr_indent();
|
print_frame_attr_indent();
|
||||||
|
|||||||
@@ -31,10 +31,9 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
#endif // HAVE_SYS_TIME_H
|
#endif // defined(HAVE_SYS_TIME_H)
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
@@ -92,4 +91,4 @@ void set_output(FILE *file);
|
|||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
||||||
#endif // APP_HELPER_H
|
#endif // !defined(APP_HELPER_H)
|
||||||
|
|||||||
193
src/base64.h
193
src/base64.h
@@ -36,109 +36,90 @@ namespace nghttp2 {
|
|||||||
|
|
||||||
namespace base64 {
|
namespace base64 {
|
||||||
|
|
||||||
namespace {
|
inline constexpr char B64_CHARS[] = {
|
||||||
constexpr char B64_CHARS[] = {
|
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
|
||||||
};
|
};
|
||||||
} // namespace
|
|
||||||
|
|
||||||
template <typename InputIt> std::string encode(InputIt first, InputIt last) {
|
|
||||||
std::string res;
|
|
||||||
size_t len = last - first;
|
|
||||||
if (len == 0) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
size_t r = len % 3;
|
|
||||||
res.resize((len + 2) / 3 * 4);
|
|
||||||
auto j = last - r;
|
|
||||||
auto p = std::begin(res);
|
|
||||||
while (first != j) {
|
|
||||||
uint32_t n = static_cast<uint8_t>(*first++) << 16;
|
|
||||||
n += static_cast<uint8_t>(*first++) << 8;
|
|
||||||
n += static_cast<uint8_t>(*first++);
|
|
||||||
*p++ = B64_CHARS[n >> 18];
|
|
||||||
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
|
|
||||||
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
|
|
||||||
*p++ = B64_CHARS[n & 0x3fu];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r == 2) {
|
|
||||||
uint32_t n = static_cast<uint8_t>(*first++) << 16;
|
|
||||||
n += static_cast<uint8_t>(*first++) << 8;
|
|
||||||
*p++ = B64_CHARS[n >> 18];
|
|
||||||
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
|
|
||||||
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
|
|
||||||
*p++ = '=';
|
|
||||||
} else if (r == 1) {
|
|
||||||
uint32_t n = static_cast<uint8_t>(*first++) << 16;
|
|
||||||
*p++ = B64_CHARS[n >> 18];
|
|
||||||
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
|
|
||||||
*p++ = '=';
|
|
||||||
*p++ = '=';
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr size_t encode_length(size_t n) { return (n + 2) / 3 * 4; }
|
constexpr size_t encode_length(size_t n) { return (n + 2) / 3 * 4; }
|
||||||
|
|
||||||
template <typename InputIt, typename OutputIt>
|
template <std::input_iterator I, std::weakly_incrementable O>
|
||||||
OutputIt encode(InputIt first, InputIt last, OutputIt d_first) {
|
requires(std::indirectly_writable<O, char>)
|
||||||
size_t len = last - first;
|
constexpr O encode(I first, I last, O result) {
|
||||||
|
using result_type = std::iter_value_t<O>;
|
||||||
|
|
||||||
|
auto len = std::ranges::distance(first, last);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return d_first;
|
return result;
|
||||||
}
|
|
||||||
auto r = len % 3;
|
|
||||||
auto j = last - r;
|
|
||||||
auto p = d_first;
|
|
||||||
while (first != j) {
|
|
||||||
uint32_t n = static_cast<uint8_t>(*first++) << 16;
|
|
||||||
n += static_cast<uint8_t>(*first++) << 8;
|
|
||||||
n += static_cast<uint8_t>(*first++);
|
|
||||||
*p++ = B64_CHARS[n >> 18];
|
|
||||||
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
|
|
||||||
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
|
|
||||||
*p++ = B64_CHARS[n & 0x3fu];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (r) {
|
auto p = result;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
len = std::ranges::distance(first, last);
|
||||||
|
if (len < 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto n = static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 16);
|
||||||
|
n += static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 8);
|
||||||
|
n += static_cast<uint8_t>(*first++);
|
||||||
|
*p++ = static_cast<result_type>(B64_CHARS[n >> 18]);
|
||||||
|
*p++ = static_cast<result_type>(B64_CHARS[(n >> 12) & 0x3fu]);
|
||||||
|
*p++ = static_cast<result_type>(B64_CHARS[(n >> 6) & 0x3fu]);
|
||||||
|
*p++ = static_cast<result_type>(B64_CHARS[n & 0x3fu]);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (len) {
|
||||||
case 2: {
|
case 2: {
|
||||||
uint32_t n = static_cast<uint8_t>(*first++) << 16;
|
auto n = static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 16);
|
||||||
n += static_cast<uint8_t>(*first++) << 8;
|
n += static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 8);
|
||||||
*p++ = B64_CHARS[n >> 18];
|
*p++ = static_cast<result_type>(B64_CHARS[n >> 18]);
|
||||||
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
|
*p++ = static_cast<result_type>(B64_CHARS[(n >> 12) & 0x3fu]);
|
||||||
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
|
*p++ = static_cast<result_type>(B64_CHARS[(n >> 6) & 0x3fu]);
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: {
|
case 1: {
|
||||||
uint32_t n = static_cast<uint8_t>(*first++) << 16;
|
auto n = static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 16);
|
||||||
*p++ = B64_CHARS[n >> 18];
|
*p++ = static_cast<result_type>(B64_CHARS[n >> 18]);
|
||||||
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
|
*p++ = static_cast<result_type>(B64_CHARS[(n >> 12) & 0x3fu]);
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
*p++ = '=';
|
*p++ = '=';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIt>
|
template <std::ranges::input_range R, std::weakly_incrementable O>
|
||||||
InputIt next_decode_input(InputIt first, InputIt last, const int *tbl) {
|
requires(std::indirectly_writable<O, char> &&
|
||||||
for (; first != last; ++first) {
|
!std::is_array_v<std::remove_cvref_t<R>>)
|
||||||
if (tbl[static_cast<size_t>(*first)] != -1 || *first == '=') {
|
constexpr O encode(R &&r, O result) {
|
||||||
break;
|
return encode(std::ranges::begin(r), std::ranges::end(r), std::move(result));
|
||||||
}
|
|
||||||
}
|
|
||||||
return first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIt, typename OutputIt>
|
template <std::ranges::input_range R>
|
||||||
OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
requires(!std::is_array_v<std::remove_cvref_t<R>>)
|
||||||
static constexpr int INDEX_TABLE[] = {
|
constexpr std::string encode(R &&r) {
|
||||||
|
std::string res;
|
||||||
|
auto len = std::ranges::size(r);
|
||||||
|
if (len == 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.resize((len + 2) / 3 * 4);
|
||||||
|
|
||||||
|
encode(std::forward<R>(r), std::ranges::begin(res));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr int B64_INDEX_TABLE[] = {
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
|
-1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
|
||||||
@@ -153,35 +134,42 @@ OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
|||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1};
|
-1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||||
assert(std::distance(first, last) % 4 == 0);
|
|
||||||
auto p = d_first;
|
template <std::input_iterator I, std::weakly_incrementable O>
|
||||||
|
requires(std::indirectly_writable<O, uint8_t>)
|
||||||
|
constexpr O decode(I first, I last, O result) {
|
||||||
|
using result_type = std::iter_value_t<O>;
|
||||||
|
|
||||||
|
assert(std::ranges::distance(first, last) % 4 == 0);
|
||||||
|
auto p = result;
|
||||||
for (; first != last;) {
|
for (; first != last;) {
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
for (int i = 1; i <= 4; ++i, ++first) {
|
for (int i = 1; i <= 4; ++i, ++first) {
|
||||||
auto idx = INDEX_TABLE[static_cast<size_t>(*first)];
|
auto idx = B64_INDEX_TABLE[static_cast<size_t>(*first)];
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
if (i <= 2) {
|
if (i <= 2) {
|
||||||
return d_first;
|
return result;
|
||||||
}
|
}
|
||||||
if (i == 3) {
|
if (i == 3) {
|
||||||
if (*first == '=' && *(first + 1) == '=' && first + 2 == last) {
|
if (*first == '=' && *std::ranges::next(first, 1) == '=' &&
|
||||||
*p++ = n >> 16;
|
std::ranges::next(first, 2) == last) {
|
||||||
|
*p++ = static_cast<result_type>(n >> 16);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
return d_first;
|
return result;
|
||||||
}
|
}
|
||||||
if (*first == '=' && first + 1 == last) {
|
if (*first == '=' && std::ranges::next(first, 1) == last) {
|
||||||
*p++ = n >> 16;
|
*p++ = static_cast<result_type>(n >> 16);
|
||||||
*p++ = n >> 8 & 0xffu;
|
*p++ = n >> 8 & 0xffu;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
return d_first;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
n += idx << (24 - i * 6);
|
n += static_cast<uint32_t>(idx) << (24 - i * 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
*p++ = n >> 16;
|
*p++ = static_cast<result_type>(n >> 16);
|
||||||
*p++ = n >> 8 & 0xffu;
|
*p++ = n >> 8 & 0xffu;
|
||||||
*p++ = n & 0xffu;
|
*p++ = n & 0xffu;
|
||||||
}
|
}
|
||||||
@@ -189,37 +177,24 @@ OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
|
template <std::ranges::input_range R>
|
||||||
auto len = std::distance(first, last);
|
requires(!std::is_array_v<std::remove_cvref_t<R>>)
|
||||||
if (len % 4 != 0) {
|
std::span<const uint8_t> decode(BlockAllocator &balloc, R &&r) {
|
||||||
return "";
|
auto len = std::ranges::size(r);
|
||||||
}
|
|
||||||
std::string res;
|
|
||||||
res.resize(len / 4 * 3);
|
|
||||||
|
|
||||||
res.erase(decode(first, last, std::begin(res)), std::end(res));
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename InputIt>
|
|
||||||
std::span<const uint8_t> decode(BlockAllocator &balloc, InputIt first,
|
|
||||||
InputIt last) {
|
|
||||||
auto len = std::distance(first, last);
|
|
||||||
if (len % 4 != 0) {
|
if (len % 4 != 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto iov = make_byte_ref(balloc, len / 4 * 3 + 1);
|
auto iov = make_byte_ref(balloc, len / 4 * 3 + 1);
|
||||||
auto p = std::begin(iov);
|
auto p = std::ranges::begin(iov);
|
||||||
|
|
||||||
p = decode(first, last, p);
|
p = decode(std::ranges::begin(r), std::ranges::end(r), p);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
return {std::begin(iov), p};
|
return {std::ranges::begin(iov), p};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace base64
|
} // namespace base64
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
||||||
#endif // BASE64_H
|
#endif // !defined(BASE64_H)
|
||||||
|
|||||||
@@ -52,22 +52,22 @@ const MunitSuite base64_suite{
|
|||||||
void test_base64_encode(void) {
|
void test_base64_encode(void) {
|
||||||
{
|
{
|
||||||
std::string in = "\xff";
|
std::string in = "\xff";
|
||||||
auto out = base64::encode(std::begin(in), std::end(in));
|
auto out = base64::encode(in);
|
||||||
assert_stdstring_equal("/w==", out);
|
assert_stdstring_equal("/w==", out);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string in = "\xff\xfe";
|
std::string in = "\xff\xfe";
|
||||||
auto out = base64::encode(std::begin(in), std::end(in));
|
auto out = base64::encode(in);
|
||||||
assert_stdstring_equal("//4=", out);
|
assert_stdstring_equal("//4=", out);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string in = "\xff\xfe\xfd";
|
std::string in = "\xff\xfe\xfd";
|
||||||
auto out = base64::encode(std::begin(in), std::end(in));
|
auto out = base64::encode(in);
|
||||||
assert_stdstring_equal("//79", out);
|
assert_stdstring_equal("//79", out);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string in = "\xff\xfe\xfd\xfc";
|
std::string in = "\xff\xfe\xfd\xfc";
|
||||||
auto out = base64::encode(std::begin(in), std::end(in));
|
auto out = base64::encode(in);
|
||||||
assert_stdstring_equal("//79/A==", out);
|
assert_stdstring_equal("//79/A==", out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,66 +76,43 @@ void test_base64_decode(void) {
|
|||||||
BlockAllocator balloc(4096, 4096);
|
BlockAllocator balloc(4096, 4096);
|
||||||
{
|
{
|
||||||
auto in = "/w=="sv;
|
auto in = "/w=="sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal("\xff"sv, as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal("\xff"sv, out);
|
|
||||||
assert_stdsv_equal("\xff"sv, StringRef{base64::decode(
|
|
||||||
balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto in = "//4="sv;
|
auto in = "//4="sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal("\xff\xfe"sv,
|
||||||
assert_stdsv_equal("\xff\xfe"sv, out);
|
as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal("\xff\xfe"sv, StringRef{base64::decode(
|
|
||||||
balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto in = "//79"sv;
|
auto in = "//79"sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal("\xff\xfe\xfd"sv,
|
||||||
assert_stdsv_equal("\xff\xfe\xfd"sv, out);
|
as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal(
|
|
||||||
"\xff\xfe\xfd"sv,
|
|
||||||
StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto in = "//79/A=="sv;
|
auto in = "//79/A=="sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal("\xff\xfe\xfd\xfc"sv,
|
||||||
assert_stdsv_equal("\xff\xfe\xfd\xfc"sv, out);
|
as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal(
|
|
||||||
"\xff\xfe\xfd\xfc"sv,
|
|
||||||
StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// we check the number of valid input must be multiples of 4
|
// we check the number of valid input must be multiples of 4
|
||||||
auto in = "//79="sv;
|
auto in = "//79="sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal(""sv, out);
|
|
||||||
assert_stdsv_equal(
|
|
||||||
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// ending invalid character at the boundary of multiples of 4 is
|
// ending invalid character at the boundary of multiples of 4 is
|
||||||
// bad
|
// bad
|
||||||
auto in = "bmdodHRw\n"sv;
|
auto in = "bmdodHRw\n"sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal("", out);
|
|
||||||
assert_stdsv_equal(
|
|
||||||
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// after seeing '=', subsequent input must be also '='.
|
// after seeing '=', subsequent input must be also '='.
|
||||||
auto in = "//79/A=A"sv;
|
auto in = "//79/A=A"sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal(""sv, out);
|
|
||||||
assert_stdsv_equal(
|
|
||||||
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// additional '=' at the end is bad
|
// additional '=' at the end is bad
|
||||||
auto in = "//79/A======"sv;
|
auto in = "//79/A======"sv;
|
||||||
auto out = base64::decode(std::begin(in), std::end(in));
|
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
|
||||||
assert_stdsv_equal(""sv, out);
|
|
||||||
assert_stdsv_equal(
|
|
||||||
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user