mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-07 02:28:53 +08:00
Compare commits
750 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0344c962f8 | ||
|
|
46d1e6bb55 | ||
|
|
04606b9339 | ||
|
|
7bb083e69e | ||
|
|
3a831fa95c | ||
|
|
5b9cacc2d7 | ||
|
|
10a84f3e3d | ||
|
|
c42715ed6a | ||
|
|
177d51ddab | ||
|
|
6c882e1ece | ||
|
|
f09c5c4bf9 | ||
|
|
08a9a2eca9 | ||
|
|
19f1785cde | ||
|
|
109de15c1f | ||
|
|
8b64e7b4e1 | ||
|
|
a5d66e71d0 | ||
|
|
3de2654223 | ||
|
|
d49bd50908 | ||
|
|
4130c68db1 | ||
|
|
ad3dac81a2 | ||
|
|
0cf6848646 | ||
|
|
e9d562f987 | ||
|
|
bc0f501dd3 | ||
|
|
a591001e7b | ||
|
|
eaa9229d72 | ||
|
|
1d5cde1c6b | ||
|
|
de03c41111 | ||
|
|
19340da8d4 | ||
|
|
5e99531b4d | ||
|
|
bef3d47c16 | ||
|
|
b8f7b474b4 | ||
|
|
1fb291d0e1 | ||
|
|
bc3dc6b765 | ||
|
|
ee7c36c022 | ||
|
|
857791dbb9 | ||
|
|
3c3267ea7d | ||
|
|
d654664fb2 | ||
|
|
1a37044d3c | ||
|
|
00a8c378d4 | ||
|
|
7549341081 | ||
|
|
5db8473f12 | ||
|
|
00b89f10bd | ||
|
|
281df33f40 | ||
|
|
e6ae681f07 | ||
|
|
7e681dc98f | ||
|
|
412c8f9e67 | ||
|
|
2795da840c | ||
|
|
175c7886ea | ||
|
|
4a4b2cf538 | ||
|
|
2c2188c09d | ||
|
|
1f07c24a2e | ||
|
|
e038625881 | ||
|
|
cdb1d6b462 | ||
|
|
1b4ccd0d51 | ||
|
|
8babaac8c3 | ||
|
|
d1624d6929 | ||
|
|
e4472b5aec | ||
|
|
9439ba75d3 | ||
|
|
9254c563ca | ||
|
|
35594e09df | ||
|
|
96ff3be5e6 | ||
|
|
3d5d76ba74 | ||
|
|
8c1e155f44 | ||
|
|
dba0d2791c | ||
|
|
f310e82fc8 | ||
|
|
1240e55bb6 | ||
|
|
75039c573c | ||
|
|
4b5179a544 | ||
|
|
8efccddcf4 | ||
|
|
97843e3874 | ||
|
|
5dd2704051 | ||
|
|
de7b7fd440 | ||
|
|
1037d3ad26 | ||
|
|
c4368a9416 | ||
|
|
fdc1eb526b | ||
|
|
99a91e3172 | ||
|
|
272cfa320e | ||
|
|
f5285d1f5a | ||
|
|
ede6104900 | ||
|
|
5aec60fbeb | ||
|
|
e1a865c406 | ||
|
|
5e03b6a0db | ||
|
|
b85924bf70 | ||
|
|
19707aac55 | ||
|
|
9ad873fc06 | ||
|
|
8a9810ed32 | ||
|
|
68a6d8c50b | ||
|
|
600605400c | ||
|
|
97aa4dabc8 | ||
|
|
a6f487240d | ||
|
|
da135416bb | ||
|
|
13eb881e5e | ||
|
|
82c84d163b | ||
|
|
a526183928 | ||
|
|
60222ae7c3 | ||
|
|
2052a1a4bd | ||
|
|
183be9cac9 | ||
|
|
69b53b9aaa | ||
|
|
02b9fcd332 | ||
|
|
231d739b10 | ||
|
|
e1dfff8929 | ||
|
|
db1716ae93 | ||
|
|
4cdc74c957 | ||
|
|
2c17ec3df8 | ||
|
|
e464b10fc3 | ||
|
|
03ba399176 | ||
|
|
751d66a397 | ||
|
|
3ec71bf5a2 | ||
|
|
f19b0724a3 | ||
|
|
a7e0a69f97 | ||
|
|
e532e20491 | ||
|
|
3e1cfa8e99 | ||
|
|
a100df9cae | ||
|
|
56284b1e15 | ||
|
|
f267e400fa | ||
|
|
8bac5899cc | ||
|
|
f4016644a9 | ||
|
|
d9bc6d04f7 | ||
|
|
743fc4a3c3 | ||
|
|
392256e542 | ||
|
|
905e16cb99 | ||
|
|
9d4e8eeb12 | ||
|
|
8099dd9558 | ||
|
|
a3a6b91c5f | ||
|
|
d9bb3448bf | ||
|
|
d508a0c72c | ||
|
|
bc31146c1f | ||
|
|
1ad7d5e366 | ||
|
|
456038e3de | ||
|
|
9aa26970be | ||
|
|
20c39fa843 | ||
|
|
f5a2f1da25 | ||
|
|
27b250ac8e | ||
|
|
b14375ec63 | ||
|
|
6858cda366 | ||
|
|
8a703d21ae | ||
|
|
1dabe43ff4 | ||
|
|
900aef10da | ||
|
|
ded576f423 | ||
|
|
136aae725f | ||
|
|
a60c3f8939 | ||
|
|
99dc31ff1a | ||
|
|
7673848325 | ||
|
|
0f8a5ffc23 | ||
|
|
fddb019baf | ||
|
|
72bf7d4af0 | ||
|
|
581e0938a9 | ||
|
|
1064e017c6 | ||
|
|
79b07f0ce2 | ||
|
|
cd471a989a | ||
|
|
0ea44072a3 | ||
|
|
6ba1abac6c | ||
|
|
0110d2f9f8 | ||
|
|
baa0f60dc8 | ||
|
|
69aa70086a | ||
|
|
13d3f785bd | ||
|
|
39c068974d | ||
|
|
0d4d1a63d4 | ||
|
|
833cd962a1 | ||
|
|
8103f43b65 | ||
|
|
1c8a672a8d | ||
|
|
4749e66c67 | ||
|
|
25ea41972a | ||
|
|
7d66188910 | ||
|
|
979c99eaea | ||
|
|
cf7f87c2ad | ||
|
|
bd0c1edaa6 | ||
|
|
c7ef021b4b | ||
|
|
00c80a15c0 | ||
|
|
8f47b68a95 | ||
|
|
d9139fc286 | ||
|
|
e693f75670 | ||
|
|
759f6c0b39 | ||
|
|
3e0d73c01d | ||
|
|
5cf21ec187 | ||
|
|
62e1d1c952 | ||
|
|
6ae58cc22e | ||
|
|
874ef1ac54 | ||
|
|
5f65460944 | ||
|
|
41b2745dad | ||
|
|
30f9f9ef87 | ||
|
|
4807e71b7d | ||
|
|
09c647fd1b | ||
|
|
d0fea96e69 | ||
|
|
b8883101d3 | ||
|
|
508c88f659 | ||
|
|
40d217beb1 | ||
|
|
e36caef006 | ||
|
|
9b864380a5 | ||
|
|
0e1d0400d8 | ||
|
|
afdd51ff15 | ||
|
|
488c3588d9 | ||
|
|
4f02b191d1 | ||
|
|
8acef2711b | ||
|
|
c6111b3792 | ||
|
|
c4d36aeff7 | ||
|
|
f50596e355 | ||
|
|
abf81b5bb7 | ||
|
|
8579b8a968 | ||
|
|
8df2c357d9 | ||
|
|
4c381611a1 | ||
|
|
7dfd6ab1ad | ||
|
|
0c7d48dede | ||
|
|
4639a66e53 | ||
|
|
65cc2f0515 | ||
|
|
4eb7f98449 | ||
|
|
2d8059a9a5 | ||
|
|
a3d22b6db9 | ||
|
|
3f31424ee2 | ||
|
|
e0119452a3 | ||
|
|
60cae325bc | ||
|
|
16c46114dc | ||
|
|
862175b21c | ||
|
|
e7e3d77c53 | ||
|
|
af9aeee752 | ||
|
|
ad3d43b8be | ||
|
|
210a5c4f01 | ||
|
|
d8822f2a8e | ||
|
|
b7a72b1e5a | ||
|
|
2f106dc96b | ||
|
|
f619286ca3 | ||
|
|
271f7fbbb6 | ||
|
|
318235db33 | ||
|
|
8ab079ccc2 | ||
|
|
a4d2104c3c | ||
|
|
44672e437a | ||
|
|
fb3d6f68a8 | ||
|
|
d7c9015d8b | ||
|
|
54f640f3e1 | ||
|
|
e2906025c8 | ||
|
|
9a8e9815c9 | ||
|
|
8c3e864989 | ||
|
|
22570b7260 | ||
|
|
fb49182c29 | ||
|
|
b9b648e0ed | ||
|
|
494775a25d | ||
|
|
1214f9e23b | ||
|
|
a54cda22ab | ||
|
|
f4a4abd180 | ||
|
|
c9559b5c0d | ||
|
|
af5b354685 | ||
|
|
3c1c2c4aad | ||
|
|
767ed255ca | ||
|
|
aa0023b3c1 | ||
|
|
3bdc143474 | ||
|
|
8b50cc0ece | ||
|
|
a24c94e92a | ||
|
|
a00442bee6 | ||
|
|
f857b63986 | ||
|
|
cbd72da9a1 | ||
|
|
7506a93179 | ||
|
|
53e1623ab3 | ||
|
|
0cb0bdabec | ||
|
|
ed8d5f04bb | ||
|
|
33153010c5 | ||
|
|
2c500b62fd | ||
|
|
30f26a2b9d | ||
|
|
ca39c71ac3 | ||
|
|
2bbe4422d2 | ||
|
|
5d3535126e | ||
|
|
d2addbc1ed | ||
|
|
110ca3131a | ||
|
|
fd7d3c57d7 | ||
|
|
179561e4be | ||
|
|
903e0077aa | ||
|
|
3fadad1bf3 | ||
|
|
acb5d45a88 | ||
|
|
6fd4dd99da | ||
|
|
1bcf13b28b | ||
|
|
c7210908df | ||
|
|
ad7cded2f4 | ||
|
|
7d847d8796 | ||
|
|
ab9cc37ca0 | ||
|
|
65095c448d | ||
|
|
76e188e368 | ||
|
|
0613a16c11 | ||
|
|
aced5b3b6c | ||
|
|
97d8bb16e6 | ||
|
|
3e14f0d8a5 | ||
|
|
f7c0d48152 | ||
|
|
2a4733857f | ||
|
|
3c1efeff55 | ||
|
|
532f801fbd | ||
|
|
cbced219ec | ||
|
|
66ca8272ca | ||
|
|
f945653ba9 | ||
|
|
fdc27c9f0e | ||
|
|
3aa0ebbbd6 | ||
|
|
aa16412850 | ||
|
|
e2bdf1d734 | ||
|
|
4aa79763be | ||
|
|
057db65657 | ||
|
|
c42296acf1 | ||
|
|
d6def22ad5 | ||
|
|
cdd72bad77 | ||
|
|
123752a032 | ||
|
|
ec5e438a7c | ||
|
|
c0b6b9a282 | ||
|
|
1fb3d71f77 | ||
|
|
43d595b7f3 | ||
|
|
fa8bccbae2 | ||
|
|
56e7cd4be2 | ||
|
|
af9662f971 | ||
|
|
af4e262d47 | ||
|
|
96218a1078 | ||
|
|
50c9c3358a | ||
|
|
6f025619de | ||
|
|
7e31340045 | ||
|
|
cddb411495 | ||
|
|
92572203e7 | ||
|
|
57259481c8 | ||
|
|
c7b0e04498 | ||
|
|
47fa56fd0a | ||
|
|
fd09d8b861 | ||
|
|
d48d399fb3 | ||
|
|
34468eccc4 | ||
|
|
81bfb84b32 | ||
|
|
11bca9a98a | ||
|
|
2868370f9e | ||
|
|
9f6c947a87 | ||
|
|
1a2dc1e822 | ||
|
|
9bdf214f48 | ||
|
|
7469139dda | ||
|
|
51c7a13cee | ||
|
|
c06e8c89ff | ||
|
|
a809da68a3 | ||
|
|
084206bace | ||
|
|
288449b9bc | ||
|
|
11e66510e4 | ||
|
|
38f4f50e93 | ||
|
|
d36afb7cdb | ||
|
|
f9897f8ccd | ||
|
|
143d0b69b7 | ||
|
|
ac97c122d4 | ||
|
|
7751f4fb3b | ||
|
|
3cd0b87685 | ||
|
|
2867f03861 | ||
|
|
8248598601 | ||
|
|
4ef3f9d11c | ||
|
|
c3817913ee | ||
|
|
6214c1b4b6 | ||
|
|
2499b36801 | ||
|
|
d196639aed | ||
|
|
2c33da36cc | ||
|
|
708c99c052 | ||
|
|
fbdfecc143 | ||
|
|
d3495405d9 | ||
|
|
aad2a24a22 | ||
|
|
27fa9c3c12 | ||
|
|
92db6820d8 | ||
|
|
851cbd49f4 | ||
|
|
8288f5713b | ||
|
|
951ef0c6d5 | ||
|
|
9653ae98a6 | ||
|
|
d837887af6 | ||
|
|
2a504224de | ||
|
|
d0bf247419 | ||
|
|
9237d30e34 | ||
|
|
ef3fa23b2e | ||
|
|
cb7269f334 | ||
|
|
0ca7c4cb38 | ||
|
|
43913838b4 | ||
|
|
845aa7a710 | ||
|
|
fe58614b23 | ||
|
|
2fd095d036 | ||
|
|
09150a7927 | ||
|
|
667c8b0e27 | ||
|
|
2a0d0e798b | ||
|
|
8b6947eda5 | ||
|
|
88e635e0b9 | ||
|
|
3753b47475 | ||
|
|
be06f1d428 | ||
|
|
e4dc6cf432 | ||
|
|
204f9a3ec7 | ||
|
|
f68dc02d6b | ||
|
|
2ca3bf7a7e | ||
|
|
43b045e84c | ||
|
|
852a320586 | ||
|
|
631f977236 | ||
|
|
046ec307c3 | ||
|
|
50083f0d22 | ||
|
|
c4fba5139c | ||
|
|
81b3e3811b | ||
|
|
26eb983cf0 | ||
|
|
e0491c2ee8 | ||
|
|
fce7908fe6 | ||
|
|
2a4bf9f615 | ||
|
|
45f7c17932 | ||
|
|
f2a1fadda9 | ||
|
|
98396f00ff | ||
|
|
e7d5cfff30 | ||
|
|
c308be39de | ||
|
|
65135bc319 | ||
|
|
944297df28 | ||
|
|
f725e419e8 | ||
|
|
0fca352114 | ||
|
|
9a3461e2b6 | ||
|
|
0b9ee38db6 | ||
|
|
a224aba577 | ||
|
|
9f770fec36 | ||
|
|
c39a669671 | ||
|
|
e6dfd4ff27 | ||
|
|
e99f3c58f7 | ||
|
|
2a3b6c11eb | ||
|
|
e26d6a2b27 | ||
|
|
dce7288658 | ||
|
|
d1968c4465 | ||
|
|
863fbffda4 | ||
|
|
629f1e6f0f | ||
|
|
7a3c656adf | ||
|
|
2a96d433ec | ||
|
|
796160cb77 | ||
|
|
5c82a36072 | ||
|
|
b011012d8f | ||
|
|
8026bdd45a | ||
|
|
5ff6da11b1 | ||
|
|
de3f2951b3 | ||
|
|
d00788ceeb | ||
|
|
e0df95a1d8 | ||
|
|
6d22898936 | ||
|
|
15a9dfbaea | ||
|
|
c6facaf662 | ||
|
|
60e443b90b | ||
|
|
d39335829d | ||
|
|
5d4f3f36e3 | ||
|
|
752b5b3d44 | ||
|
|
70e8dc3761 | ||
|
|
0ee80be995 | ||
|
|
3712c89a66 | ||
|
|
8e33f0a535 | ||
|
|
fd801864e3 | ||
|
|
99f7e7e2a5 | ||
|
|
6c999e6fb5 | ||
|
|
4aa4fe56e1 | ||
|
|
09b97a3313 | ||
|
|
d2f4e4e325 | ||
|
|
dba0f35ee1 | ||
|
|
2d2b72d4eb | ||
|
|
b39ad3135d | ||
|
|
13f97ccf45 | ||
|
|
43bbcd35aa | ||
|
|
220f49b157 | ||
|
|
918ca4ca7c | ||
|
|
7d7dc830ef | ||
|
|
f939000ad9 | ||
|
|
4b34bc583d | ||
|
|
91fce2f0e6 | ||
|
|
5487b64fa6 | ||
|
|
b27107385e | ||
|
|
3d00dd6537 | ||
|
|
e85bc70bef | ||
|
|
b0e98718f5 | ||
|
|
3d4a4cb617 | ||
|
|
86777defa8 | ||
|
|
52b455cfeb | ||
|
|
add182b495 | ||
|
|
3d948fd3d7 | ||
|
|
e04e24c1c2 | ||
|
|
68059ccda9 | ||
|
|
bc2b941866 | ||
|
|
9b81eec944 | ||
|
|
00bf701600 | ||
|
|
5339c1774c | ||
|
|
e41d8c2f62 | ||
|
|
73740477fb | ||
|
|
f86a9d654d | ||
|
|
6f52da834b | ||
|
|
4041d1eb26 | ||
|
|
81f81e6b70 | ||
|
|
a16daf109b | ||
|
|
b6708a4b87 | ||
|
|
bda352bf73 | ||
|
|
ca261a7971 | ||
|
|
0819716332 | ||
|
|
a14cea6363 | ||
|
|
2cac7bb838 | ||
|
|
65378f80ea | ||
|
|
40f3779eb1 | ||
|
|
d88f962565 | ||
|
|
9c0bd8c60a | ||
|
|
9e64d10223 | ||
|
|
94c8a8fbde | ||
|
|
16647622f5 | ||
|
|
9028512a5f | ||
|
|
3086d65657 | ||
|
|
d4144a7475 | ||
|
|
6638ca9333 | ||
|
|
b924ef5fff | ||
|
|
df56f55f84 | ||
|
|
31595c2416 | ||
|
|
795ee8c20f | ||
|
|
efbd48b122 | ||
|
|
9b4089c244 | ||
|
|
8b5a85ae1d | ||
|
|
ecabef2dc7 | ||
|
|
4a6fc6cede | ||
|
|
287d4e35f3 | ||
|
|
a803be9171 | ||
|
|
ece3654139 | ||
|
|
bf5392dafe | ||
|
|
7bc35044c7 | ||
|
|
f9b872ab78 | ||
|
|
ffddefc177 | ||
|
|
2a59c832c1 | ||
|
|
ea5f424dec | ||
|
|
46514074a4 | ||
|
|
1816af4fb2 | ||
|
|
b1662a31f4 | ||
|
|
5974abad75 | ||
|
|
344541dd89 | ||
|
|
c17b3b8517 | ||
|
|
b26503f51c | ||
|
|
2b22ec42c7 | ||
|
|
dfdeeb3815 | ||
|
|
4bed7854b5 | ||
|
|
aa64e7ad3c | ||
|
|
8667bbb823 | ||
|
|
1fef49aaa4 | ||
|
|
e30edb096a | ||
|
|
cdb466956d | ||
|
|
199600af73 | ||
|
|
edb874e659 | ||
|
|
fe0843be88 | ||
|
|
ff07018720 | ||
|
|
402eccf06d | ||
|
|
0641d314a6 | ||
|
|
2928afa51f | ||
|
|
757bcf1310 | ||
|
|
c9aba4ea0c | ||
|
|
2cee80acf0 | ||
|
|
d9a2ff278c | ||
|
|
8a539420c2 | ||
|
|
371497968b | ||
|
|
388d7a944a | ||
|
|
afe724ecda | ||
|
|
0d636893f1 | ||
|
|
4ac9417d8d | ||
|
|
75110320ab | ||
|
|
8691ec4899 | ||
|
|
b6e2214903 | ||
|
|
7ec50e55c9 | ||
|
|
ad8be7d474 | ||
|
|
07926cffca | ||
|
|
00b2d7d513 | ||
|
|
f74d7ea119 | ||
|
|
2bca6360b6 | ||
|
|
841b3c87db | ||
|
|
2ab79f4938 | ||
|
|
2182a85875 | ||
|
|
72d8d78d36 | ||
|
|
dad61d032e | ||
|
|
1bbb241baa | ||
|
|
3e6c38e3be | ||
|
|
9272e80fa6 | ||
|
|
333dd73a18 | ||
|
|
8e84bbd781 | ||
|
|
44af3dab50 | ||
|
|
22128767e6 | ||
|
|
f6b78a027c | ||
|
|
a46c815e4e | ||
|
|
186d440168 | ||
|
|
a9e365ad7d | ||
|
|
a104d8a80b | ||
|
|
a5029d1eed | ||
|
|
848e45e333 | ||
|
|
7972593586 | ||
|
|
79968c6374 | ||
|
|
1699aef609 | ||
|
|
2d2d6c3cc0 | ||
|
|
bfccab9b9f | ||
|
|
17ccbae084 | ||
|
|
0875e66aab | ||
|
|
4dfae3484f | ||
|
|
372123c178 | ||
|
|
13596bde90 | ||
|
|
3b7b6a660e | ||
|
|
daa1ae3a45 | ||
|
|
44ee67ff71 | ||
|
|
144ae3af9d | ||
|
|
eec0b04a33 | ||
|
|
58b06f32a2 | ||
|
|
5b58db39ff | ||
|
|
1bc5cf5ee4 | ||
|
|
f4c7ebcbca | ||
|
|
feb3d1b478 | ||
|
|
7c954c1ea7 | ||
|
|
e9f4d0eec2 | ||
|
|
4f9c78799c | ||
|
|
0f9ed40bd9 | ||
|
|
4bb88b35ec | ||
|
|
04145e22a2 | ||
|
|
cca7e398fd | ||
|
|
3d04fe2a87 | ||
|
|
c459034ae9 | ||
|
|
442bd47535 | ||
|
|
5cea3e227c | ||
|
|
db0a22e991 | ||
|
|
dc3119303a | ||
|
|
d2b55ad1a2 | ||
|
|
d7051f5207 | ||
|
|
db1ee3aa88 | ||
|
|
a1e0bd134e | ||
|
|
7a1e0eb618 | ||
|
|
65b59bd78a | ||
|
|
dcae6efaa2 | ||
|
|
71cc7a96c2 | ||
|
|
8da0d649e4 | ||
|
|
08c7656e47 | ||
|
|
bd253e1bdd | ||
|
|
d10f149161 | ||
|
|
3a2a943fe9 | ||
|
|
f34971774b | ||
|
|
f8a9a21428 | ||
|
|
0c49e5d56e | ||
|
|
e84755eb35 | ||
|
|
b348a02b85 | ||
|
|
439636c579 | ||
|
|
162b1c5e03 | ||
|
|
dc56b951df | ||
|
|
4d801cd696 | ||
|
|
7c55c335cc | ||
|
|
2ddb83206b | ||
|
|
ab734f09b6 | ||
|
|
dd2bdf3e31 | ||
|
|
a909bb3eca | ||
|
|
aaebeceded | ||
|
|
3de435d7b8 | ||
|
|
01408209d8 | ||
|
|
e8b62c620d | ||
|
|
2eb7137e04 | ||
|
|
caa12ec587 | ||
|
|
0f71fbce8d | ||
|
|
4e2972a5dc | ||
|
|
78e5417ff2 | ||
|
|
77852cf572 | ||
|
|
fa36537f82 | ||
|
|
4cde76c9c3 | ||
|
|
e02512032b | ||
|
|
b092166bc6 | ||
|
|
e58db4f8b0 | ||
|
|
dad222b8f4 | ||
|
|
e80977c812 | ||
|
|
2b3bc710fc | ||
|
|
a45540fd79 | ||
|
|
7f8110601e | ||
|
|
37b09f6785 | ||
|
|
2a606bae4c | ||
|
|
3b2811bfc4 | ||
|
|
27275a02ac | ||
|
|
34d209b30b | ||
|
|
94f52d49dc | ||
|
|
0720671e0a | ||
|
|
0ee09320e0 | ||
|
|
78fcb2143f | ||
|
|
755b14de5d | ||
|
|
3455cb35e4 | ||
|
|
c1571a3209 | ||
|
|
67569486d1 | ||
|
|
d64051fedc | ||
|
|
c897d5b294 | ||
|
|
863a944179 | ||
|
|
3db9c2c796 | ||
|
|
12dad32890 | ||
|
|
689d2a1afb | ||
|
|
ff0d137fb3 | ||
|
|
8da20975f9 | ||
|
|
eb393985b7 | ||
|
|
7a412df9a5 | ||
|
|
b1b57cc740 | ||
|
|
bdb6581990 | ||
|
|
618073e2b4 | ||
|
|
fa601e5ba3 | ||
|
|
bae37e3e4a | ||
|
|
907eeeda8a | ||
|
|
fe6ccd16da | ||
|
|
10ec00126c | ||
|
|
2d6211c455 | ||
|
|
e302cc9c16 | ||
|
|
3f2b54cfc4 | ||
|
|
acbf38fd3c | ||
|
|
1e8bea15e5 | ||
|
|
aaf0177318 | ||
|
|
9afc017532 | ||
|
|
5da38b22c0 | ||
|
|
ce61f62644 | ||
|
|
2c525f2471 | ||
|
|
5bbcb7148c | ||
|
|
8bca2d1048 | ||
|
|
d6c3b6e84c | ||
|
|
e453759637 | ||
|
|
a21c87d11c | ||
|
|
478fde5fef | ||
|
|
bffc0ec87a | ||
|
|
1b9b03b68f | ||
|
|
a59445ccff | ||
|
|
c2ec73302d | ||
|
|
284691253f | ||
|
|
124d4c9fad | ||
|
|
5fbe4cc225 | ||
|
|
df6466cfbd | ||
|
|
2326337d32 | ||
|
|
06921f35f3 | ||
|
|
44d3801760 | ||
|
|
1832f78684 | ||
|
|
e7601cde8a | ||
|
|
36f6a009b8 | ||
|
|
1e1752266f | ||
|
|
aafcc55006 | ||
|
|
c731d1fea5 | ||
|
|
aa892e4d37 | ||
|
|
8ca3e5f6ba | ||
|
|
21007da392 | ||
|
|
9eeac27966 | ||
|
|
e6ff7e1e4a | ||
|
|
9c874bf9b5 | ||
|
|
9ab5ef3b5b | ||
|
|
4814d14db5 | ||
|
|
77e8190b6c | ||
|
|
f4b2a4ab00 | ||
|
|
a909eb6b23 | ||
|
|
3dd57e1f59 | ||
|
|
1b67b2d33e | ||
|
|
9bc6dc7113 | ||
|
|
f407f7f406 | ||
|
|
474ecc4b47 | ||
|
|
0afc21c9d8 | ||
|
|
8c46d9181f | ||
|
|
cc92ebf471 | ||
|
|
c96cf1b303 | ||
|
|
503f0a29a7 | ||
|
|
ee285fa5da | ||
|
|
8c562bd38d | ||
|
|
15adc23277 | ||
|
|
a2ec695ec9 | ||
|
|
55b270587b | ||
|
|
5297136bc0 | ||
|
|
61bb6428fd | ||
|
|
ccd2d34160 | ||
|
|
ea6eed10c7 | ||
|
|
7a86758edb | ||
|
|
90d66ea4a9 | ||
|
|
5b21c39bb2 | ||
|
|
744e80d579 | ||
|
|
3842fe175c | ||
|
|
900667a998 | ||
|
|
147e098827 | ||
|
|
5819d03c68 | ||
|
|
90f5bf796d | ||
|
|
2b63980758 | ||
|
|
65d33c553c |
@@ -1,57 +1,94 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: false
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
BreakBeforeBinaryOperators: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BinPackParameters: true
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '$'
|
||||
IndentCaseLabels: false
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
Cpp11BracedListStyle: true
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
IndentWidth: 2
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
BreakBeforeBraces: Attach
|
||||
SpacesInParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 4
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
SpaceBeforeParens: ControlStatements
|
||||
DisableFormat: false
|
||||
...
|
||||
|
||||
|
||||
16
.gitignore
vendored
16
.gitignore
vendored
@@ -29,6 +29,22 @@ missing
|
||||
stamp-h1
|
||||
test-driver
|
||||
|
||||
# cmake
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
CTestTestfile.cmake
|
||||
build.ninja
|
||||
rules.ninja
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
lib*.so
|
||||
lib*.so.*
|
||||
lib*.a
|
||||
# generated by "make test" with cmake
|
||||
Testing/
|
||||
|
||||
# test logs generated by `make check`
|
||||
*.log
|
||||
*.trs
|
||||
|
||||
25
.travis.yml
25
.travis.yml
@@ -1,3 +1,7 @@
|
||||
env:
|
||||
matrix:
|
||||
- CI_BUILD=cmake
|
||||
- CI_BUILD=autotools
|
||||
language: cpp
|
||||
compiler:
|
||||
- clang
|
||||
@@ -7,6 +11,7 @@ addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- george-edison55-precise-backports
|
||||
packages:
|
||||
- g++-4.9
|
||||
- libstdc++-4.9-dev
|
||||
@@ -23,11 +28,14 @@ addons:
|
||||
- libevent-dev
|
||||
- libjansson-dev
|
||||
- libjemalloc-dev
|
||||
- cmake
|
||||
- cmake-data
|
||||
before_install:
|
||||
- $CC --version
|
||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
|
||||
- $CC --version
|
||||
- go version
|
||||
- cmake --version
|
||||
before_script:
|
||||
# First build spdylay, since integration tests require it.
|
||||
# spdylay is going to be built under third-party/spdylay
|
||||
@@ -35,18 +43,21 @@ before_script:
|
||||
- git clone https://github.com/tatsuhiro-t/spdylay.git
|
||||
- cd spdylay
|
||||
- autoreconf -i
|
||||
# Don't use ASAN for spdylay since failmalloc does not work with it.
|
||||
- ./configure --disable-src --disable-examples
|
||||
- make check
|
||||
- export SPDYLAY_HOME=$PWD
|
||||
- cd ../..
|
||||
# Now build nghttp2
|
||||
- autoreconf -i
|
||||
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
|
||||
- git submodule update --init
|
||||
- ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"
|
||||
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay" CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address; fi
|
||||
- if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DSPDYLAY_INCLUDE_DIR="$SPDYLAY_HOME/lib/includes" -DSPDYLAY_LIBRARY="$SPDYLAY_HOME/lib/.libs/libspdylay.so"; fi
|
||||
script:
|
||||
- make
|
||||
- make check
|
||||
- cd integration-tests
|
||||
- export GOPATH="$PWD/integration-tests/golang"
|
||||
- make itprep-local
|
||||
- make it-local
|
||||
# As of April, 23, 2016, golang http2 build fails, probably because
|
||||
# the default go version is too old.
|
||||
# - cd integration-tests
|
||||
# - export GOPATH="$PWD/integration-tests/golang"
|
||||
# - make itprep
|
||||
# - make it
|
||||
|
||||
8
AUTHORS
8
AUTHORS
@@ -9,7 +9,7 @@ contribution, but you are missing in the list, please let us know via
|
||||
github issues [2].
|
||||
|
||||
[1] https://github.com/tatsuhiro-t/spdylay
|
||||
[2] https://github.com/tatsuhiro-t/nghttp2/issues
|
||||
[2] https://github.com/nghttp2/nghttp2/issues
|
||||
|
||||
--------
|
||||
|
||||
@@ -23,6 +23,7 @@ Andy Davies
|
||||
Ant Bryan
|
||||
Bernard Spil
|
||||
Brian Card
|
||||
Brian Suh
|
||||
Daniel Stenberg
|
||||
Dave Reisner
|
||||
David Beitey
|
||||
@@ -31,8 +32,11 @@ Etienne Cimon
|
||||
Fabian Möller
|
||||
Fabian Wiesel
|
||||
Gabi Davar
|
||||
Jacob Champion
|
||||
Jan-E
|
||||
Janusz Dziemidowicz
|
||||
Jay Satiro
|
||||
Jianqing Wang
|
||||
Jim Morrison
|
||||
José F. Calcerrada
|
||||
Kamil Dudka
|
||||
@@ -43,6 +47,7 @@ Kit Chan
|
||||
Kyle Schomp
|
||||
Lucas Pardue
|
||||
MATSUMOTO Ryosuke
|
||||
Mike Conlen
|
||||
Mike Frysinger
|
||||
Nicholas Hurley
|
||||
Nora Shoemaker
|
||||
@@ -66,6 +71,7 @@ Tomasz Buchert
|
||||
Vernon Tang
|
||||
Viacheslav Biriukov
|
||||
Viktor Szépe
|
||||
Wenfeng Liu
|
||||
Xiaoguang Sun
|
||||
Zhuoyun Wei
|
||||
acesso
|
||||
|
||||
524
CMakeLists.txt
Normal file
524
CMakeLists.txt
Normal file
@@ -0,0 +1,524 @@
|
||||
# nghttp2 - HTTP/2 C Library
|
||||
#
|
||||
# Copyright (c) 2012, 2013, 2014, 2015 Tatsuhiro Tsujikawa
|
||||
# Copyright (c) 2016 Peter Wu <peter@lekensteyn.nl>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
# XXX using 1.8.90 instead of 1.9.0-DEV
|
||||
project(nghttp2 VERSION 1.16.0)
|
||||
|
||||
# See versioning rule:
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
set(LT_CURRENT 26)
|
||||
set(LT_REVISION 0)
|
||||
set(LT_AGE 12)
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
include(Version)
|
||||
|
||||
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
|
||||
set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}")
|
||||
set(PACKAGE_VERSION "${PROJECT_VERSION}")
|
||||
HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH})
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE)
|
||||
|
||||
# Include "None" as option to disable any additional (optimization) flags,
|
||||
# relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by
|
||||
# default). These strings are presented in cmake-gui.
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
"None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# For Python bindings and documentation
|
||||
# (Must be called before PythonLibs for matching versions.)
|
||||
find_package(PythonInterp)
|
||||
|
||||
# Auto-detection of features that can be toggled
|
||||
find_package(OpenSSL 1.0.1)
|
||||
find_package(Libev 4.11)
|
||||
find_package(ZLIB 1.2.3)
|
||||
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
|
||||
set(ENABLE_APP_DEFAULT ON)
|
||||
else()
|
||||
set(ENABLE_APP_DEFAULT OFF)
|
||||
endif()
|
||||
find_package(Jansson 2.5)
|
||||
set(ENABLE_HPACK_TOOLS_DEFAULT ${JANSSON_FOUND})
|
||||
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
||||
find_package(Libevent 2.0.8 COMPONENTS libevent openssl)
|
||||
set(ENABLE_EXAMPLES_DEFAULT ${LIBEVENT_OPENSSL_FOUND})
|
||||
find_package(Cython)
|
||||
find_package(PythonLibs)
|
||||
if(CYTHON_FOUND AND PYTHONLIBS_FOUND)
|
||||
set(ENABLE_PYTHON_BINDINGS_DEFAULT ON)
|
||||
else()
|
||||
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
find_package(LibXml2 2.7.7)
|
||||
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
|
||||
find_package(Jemalloc)
|
||||
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
|
||||
find_package(Spdylay 1.3.2)
|
||||
set(WITH_SPDYLAY_DEFAULT ${SPDYLAY_FOUND})
|
||||
|
||||
include(CMakeOptions.txt)
|
||||
|
||||
if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_EXAMPLES OR
|
||||
ENABLE_PYTHON_BINDINGS))
|
||||
# Remember when disabled options are disabled for later diagnostics.
|
||||
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1)
|
||||
else()
|
||||
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0)
|
||||
endif()
|
||||
if(ENABLE_LIB_ONLY)
|
||||
set(ENABLE_APP OFF)
|
||||
set(ENABLE_HPACK_TOOLS OFF)
|
||||
set(ENABLE_EXAMPLES OFF)
|
||||
set(ENABLE_PYTHON_BINDINGS OFF)
|
||||
endif()
|
||||
|
||||
# Do not disable assertions based on CMAKE_BUILD_TYPE.
|
||||
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
|
||||
foreach(_lang C CXX)
|
||||
string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
|
||||
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" "" ${_var} "${${_var}}")
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# If we're running GCC or clang define _U_ to be "__attribute__((unused))"
|
||||
# so we can use _U_ to flag unused function parameters and not get warnings
|
||||
# about them. Otherwise, define _U_ to be an empty string so that _U_ used
|
||||
# to flag an unused function parameters will compile with other compilers.
|
||||
#
|
||||
# XXX - similar hints for other compilers?
|
||||
#
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(HINT_UNUSED_PARAM "__attribute__((unused))")
|
||||
set(HINT_NORETURN "__attribute__((noreturn))")
|
||||
else()
|
||||
set(HINT_UNUSED_PARAM)
|
||||
set(HINT_NORETURN)
|
||||
endif()
|
||||
|
||||
include(ExtractValidFlags)
|
||||
foreach(_cxx1x_flag -std=c++11 -std=c++0x)
|
||||
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
|
||||
if(_cxx1x_flag_supported)
|
||||
set(CXX1XCXXFLAGS ${_cxx1x_flag})
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
include(CMakePushCheckState)
|
||||
include(CheckCXXSourceCompiles)
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
|
||||
# Check that std::future is available.
|
||||
check_cxx_source_compiles("
|
||||
#include <vector>
|
||||
#include <future>
|
||||
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
|
||||
# Check that std::map::emplace is available for g++-4.7.
|
||||
check_cxx_source_compiles("
|
||||
#include <map>
|
||||
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
|
||||
cmake_pop_check_state()
|
||||
|
||||
|
||||
# Checks for libraries.
|
||||
# Additional libraries required for programs under src directory.
|
||||
set(APP_LIBRARIES)
|
||||
|
||||
if(ENABLE_PYTHON_BINDINGS)
|
||||
if(NOT (CYTHON_FOUND AND PYTHONLIBS_FOUND))
|
||||
message(FATAL_ERROR "python bindings were requested "
|
||||
"(ENABLE_PYTHON_BINDINGS=1) but dependencies are not met.")
|
||||
endif()
|
||||
if(NOT PYTHON_VERSION_STRING STREQUAL PYTHONLIBS_VERSION_STRING)
|
||||
message(FATAL_ERROR
|
||||
"Python executable and library must have the same version!"
|
||||
" Found Python ${PYTHON_VERSION_STRING} and"
|
||||
" PythonLibs ${PYTHONLIBS_VERSION_STRING}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD 1)
|
||||
find_package(Threads)
|
||||
if(CMAKE_USE_PTHREADS_INIT)
|
||||
list(APPEND APP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
# XXX android and C++, is this still needed in cmake?
|
||||
# case "$host" in
|
||||
# *android*)
|
||||
# android_build=yes
|
||||
# # android does not need -pthread, but needs followng 3 libs for C++
|
||||
# APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
|
||||
|
||||
# dl: openssl requires libdl when it is statically linked.
|
||||
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
|
||||
# APP_LIBRARIES if it is really specific to OpenSSL?
|
||||
|
||||
find_package(CUnit 2.1)
|
||||
enable_testing()
|
||||
set(HAVE_CUNIT ${CUNIT_FOUND})
|
||||
if(HAVE_CUNIT)
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
|
||||
endif()
|
||||
|
||||
# openssl (for src)
|
||||
set(HAVE_OPENSSL ${OPENSSL_FOUND})
|
||||
if(OPENSSL_FOUND)
|
||||
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
||||
else()
|
||||
set(OPENSSL_INCLUDE_DIRS "")
|
||||
set(OPENSSL_LIBRARIES "")
|
||||
endif()
|
||||
# libev (for src)
|
||||
set(HAVE_LIBEV ${LIBEV_FOUND})
|
||||
set(HAVE_ZLIB ${ZLIB_FOUND})
|
||||
set(HAVE_LIBEVENT_OPENSSL ${LIBEVENT_FOUND})
|
||||
if(LIBEVENT_FOUND)
|
||||
# Must both link the core and openssl libraries.
|
||||
set(LIBEVENT_OPENSSL_LIBRARIES ${LIBEVENT_LIBRARIES})
|
||||
endif()
|
||||
# jansson (for src/nghttp, src/deflatehd and src/inflatehd)
|
||||
set(HAVE_JANSSON ${JANSSON_FOUND})
|
||||
# libxml2 (for src/nghttp)
|
||||
set(HAVE_LIBXML2 ${LIBXML2_FOUND})
|
||||
if(LIBXML2_FOUND)
|
||||
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
|
||||
else()
|
||||
set(LIBXML2_INCLUDE_DIRS "")
|
||||
set(LIBXML2_LIBRARIES "")
|
||||
endif()
|
||||
# jemalloc
|
||||
set(HAVE_JEMALLOC ${JEMALLOC_FOUND})
|
||||
# spdylay (for src/nghttpx and src/h2load)
|
||||
set(HAVE_SPDYLAY ${SPDYLAY_FOUND})
|
||||
|
||||
if(ENABLE_ASIO_LIB)
|
||||
find_package(Boost 1.54.0 REQUIRED system thread)
|
||||
endif()
|
||||
|
||||
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
|
||||
if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
|
||||
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
|
||||
endif()
|
||||
|
||||
# HPACK tools requires jansson
|
||||
if(ENABLE_HPACK_TOOLS AND NOT HAVE_JANSSON)
|
||||
message(FATAL_ERROR "HPACK tools were requested (ENABLE_HPACK_TOOLS=1) but dependencies are not met.")
|
||||
endif()
|
||||
|
||||
# C++ library libnghttp2_asio
|
||||
if(ENABLE_EXAMPLES AND NOT (OPENSSL_FOUND AND LIBEVENT_OPENSSL_FOUND))
|
||||
message(FATAL_ERROR "examples were requested (ENABLE_EXAMPLES=1) but dependencies are not met.")
|
||||
endif()
|
||||
|
||||
# third-party http-parser only be built when needed
|
||||
if(ENABLE_EXAMPLES OR ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_ASIO_LIB)
|
||||
set(ENABLE_THIRD_PARTY 1)
|
||||
# mruby (for src/nghttpx)
|
||||
set(HAVE_MRUBY ${WITH_MRUBY})
|
||||
set(HAVE_NEVERBLEED ${WITH_NEVERBLEED})
|
||||
else()
|
||||
set(HAVE_MRUBY 0)
|
||||
set(HAVE_NEVERBLEED 0)
|
||||
endif()
|
||||
|
||||
# Checks for header files.
|
||||
include(CheckIncludeFile)
|
||||
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||
check_include_file("fcntl.h" HAVE_FCNTL_H)
|
||||
check_include_file("inttypes.h" HAVE_INTTYPES_H)
|
||||
check_include_file("limits.h" HAVE_LIMITS_H)
|
||||
check_include_file("netdb.h" HAVE_NETDB_H)
|
||||
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
|
||||
check_include_file("pwd.h" HAVE_PWD_H)
|
||||
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
|
||||
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
|
||||
check_include_file("syslog.h" HAVE_SYSLOG_H)
|
||||
check_include_file("time.h" HAVE_TIME_H)
|
||||
check_include_file("unistd.h" HAVE_UNISTD_H)
|
||||
|
||||
include(CheckTypeSize)
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
# AC_TYPE_SIZE_T
|
||||
check_type_size("ssize_t" SIZEOF_SSIZE_T)
|
||||
if(SIZEOF_SSIZE_T STREQUAL "")
|
||||
# ssize_t is a signed type in POSIX storing at least -1.
|
||||
# Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools).
|
||||
set(ssize_t int)
|
||||
endif()
|
||||
# AC_TYPE_UINT8_T
|
||||
# AC_TYPE_UINT16_T
|
||||
# AC_TYPE_UINT32_T
|
||||
# AC_TYPE_UINT64_T
|
||||
# AC_TYPE_INT8_T
|
||||
# AC_TYPE_INT16_T
|
||||
# AC_TYPE_INT32_T
|
||||
# AC_TYPE_INT64_T
|
||||
# AC_TYPE_OFF_T
|
||||
# AC_TYPE_PID_T
|
||||
# AC_TYPE_UID_T
|
||||
# XXX To support inline for crappy compilers, see https://cmake.org/Wiki/CMakeTestInline
|
||||
# AC_C_INLINE
|
||||
# XXX is AC_SYS_LARGEFILE still needed for modern systems?
|
||||
# add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
include(CheckStructHasMember)
|
||||
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
|
||||
|
||||
# Check size of pointer to decide we need 8 bytes alignment adjustment.
|
||||
check_type_size("int *" SIZEOF_INT_P)
|
||||
check_type_size("time_t" SIZEOF_TIME_T)
|
||||
|
||||
# Checks for library functions.
|
||||
include(CheckFunctionExists)
|
||||
check_function_exists(_Exit HAVE__EXIT)
|
||||
check_function_exists(accept4 HAVE_ACCEPT4)
|
||||
|
||||
# timerfd_create was added in linux kernel 2.6.25
|
||||
include(CheckSymbolExists)
|
||||
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
||||
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
|
||||
if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
|
||||
# FreeBSD declares initgroups() in unistd.h
|
||||
check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2)
|
||||
if(HAVE_DECL_INITGROUPS2)
|
||||
set(HAVE_DECL_INITGROUPS 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_function_exists(timerfd_create HAVE_TIMERFD_CREATE)
|
||||
# Checks for epoll availability, primarily for examples/tiny-nghttpd
|
||||
check_symbol_exists(epoll_create sys/epoll.h HAVE_EPOLL)
|
||||
if(HAVE_EPOLL AND HAVE_TIMERFD_CREATE)
|
||||
set(ENABLE_TINY_NGHTTPD 1)
|
||||
endif()
|
||||
|
||||
set(WARNCFLAGS)
|
||||
set(WARNCXXFLAGS)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
if(ENABLE_WERROR)
|
||||
set(WARNCFLAGS /WX)
|
||||
set(WARNCXXFLAGS /WX)
|
||||
endif()
|
||||
else()
|
||||
if(ENABLE_WERROR)
|
||||
extract_valid_c_flags(WARNCFLAGS -Werror)
|
||||
extract_valid_c_flags(WARNCXXFLAGS -Werror)
|
||||
endif()
|
||||
|
||||
# For C compiler
|
||||
extract_valid_c_flags(WARNCFLAGS
|
||||
-Wall
|
||||
-Wextra
|
||||
-Wmissing-prototypes
|
||||
-Wstrict-prototypes
|
||||
-Wmissing-declarations
|
||||
-Wpointer-arith
|
||||
-Wdeclaration-after-statement
|
||||
-Wformat-security
|
||||
-Wwrite-strings
|
||||
-Wshadow
|
||||
-Winline
|
||||
-Wnested-externs
|
||||
-Wfloat-equal
|
||||
-Wundef
|
||||
-Wendif-labels
|
||||
-Wempty-body
|
||||
-Wcast-align
|
||||
-Wclobbered
|
||||
-Wvla
|
||||
-Wpragmas
|
||||
-Wunreachable-code
|
||||
-Waddress
|
||||
-Wattributes
|
||||
-Wdiv-by-zero
|
||||
-Wshorten-64-to-32
|
||||
|
||||
-Wconversion
|
||||
-Wextended-offsetof
|
||||
-Wformat-nonliteral
|
||||
-Wlanguage-extension-token
|
||||
-Wmissing-field-initializers
|
||||
-Wmissing-noreturn
|
||||
-Wmissing-variable-declarations
|
||||
# Not used because we cannot change public structs
|
||||
# -Wpadded
|
||||
-Wsign-conversion
|
||||
# Not used because this basically disallows default case
|
||||
# -Wswitch-enum
|
||||
-Wunreachable-code-break
|
||||
-Wunused-macros
|
||||
-Wunused-parameter
|
||||
-Wredundant-decls
|
||||
# Only work with Clang for the moment
|
||||
-Wheader-guard
|
||||
# This is required because we pass format string as "const char*.
|
||||
-Wno-format-nonliteral
|
||||
)
|
||||
|
||||
extract_valid_cxx_flags(WARNCXXFLAGS
|
||||
# For C++ compiler
|
||||
-Wall
|
||||
-Wformat-security
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DEBUG)
|
||||
set(DEBUGBUILD 1)
|
||||
endif()
|
||||
|
||||
# Some platform does not have working std::future. We disable
|
||||
# threading for those platforms.
|
||||
if(NOT ENABLE_THREADS OR NOT HAVE_STD_FUTURE)
|
||||
set(NOTHREADS 1)
|
||||
endif()
|
||||
|
||||
add_definitions(-DHAVE_CONFIG_H)
|
||||
configure_file(cmakeconfig.h.in config.h)
|
||||
# autotools-compatible names
|
||||
# Sphinx expects relative paths in the .rst files. Use the fact that the files
|
||||
# below are all one directory level deep.
|
||||
file(RELATIVE_PATH top_srcdir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
# libnghttp2.pc (pkg-config file)
|
||||
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
||||
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
|
||||
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
|
||||
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
||||
set(VERSION "${PACKAGE_VERSION}")
|
||||
# For init scripts and systemd service file (in contrib/)
|
||||
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||
set(sbindir "${CMAKE_INSTALL_FULL_SBINDIR}")
|
||||
foreach(name
|
||||
lib/libnghttp2.pc
|
||||
lib/includes/nghttp2/nghttp2ver.h
|
||||
src/libnghttp2_asio.pc
|
||||
python/setup.py
|
||||
integration-tests/config.go
|
||||
integration-tests/setenv
|
||||
doc/conf.py
|
||||
doc/index.rst
|
||||
doc/package_README.rst
|
||||
doc/tutorial-client.rst
|
||||
doc/tutorial-server.rst
|
||||
doc/tutorial-hpack.rst
|
||||
doc/nghttpx-howto.rst
|
||||
doc/h2load-howto.rst
|
||||
doc/libnghttp2_asio.rst
|
||||
doc/python-apiref.rst
|
||||
doc/building-android-binary.rst
|
||||
doc/nghttp2.h.rst
|
||||
doc/nghttp2ver.h.rst
|
||||
doc/asio_http2.h.rst
|
||||
doc/asio_http2_server.h.rst
|
||||
doc/asio_http2_client.h.rst
|
||||
doc/contribute.rst
|
||||
)
|
||||
configure_file("${name}.in" "${name}" @ONLY)
|
||||
endforeach()
|
||||
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
||||
)
|
||||
# For use in src/CMakeLists.txt
|
||||
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
|
||||
|
||||
install(FILES README.rst DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||
|
||||
add_subdirectory(lib)
|
||||
#add_subdirectory(lib/includes)
|
||||
add_subdirectory(third-party)
|
||||
add_subdirectory(src)
|
||||
#add_subdirectory(src/includes)
|
||||
add_subdirectory(examples)
|
||||
add_subdirectory(python)
|
||||
add_subdirectory(tests)
|
||||
#add_subdirectory(tests/testdata)
|
||||
add_subdirectory(integration-tests)
|
||||
add_subdirectory(doc)
|
||||
add_subdirectory(contrib)
|
||||
add_subdirectory(script)
|
||||
|
||||
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
|
||||
message(STATUS "summary of build options:
|
||||
|
||||
Package version: ${VERSION}
|
||||
Library version: ${LT_CURRENT}:${LT_REVISION}:${LT_AGE}
|
||||
Install prefix: ${CMAKE_INSTALL_PREFIX}
|
||||
Target system: ${CMAKE_SYSTEM_NAME}
|
||||
Compiler:
|
||||
Build type: ${CMAKE_BUILD_TYPE}
|
||||
C compiler: ${CMAKE_C_COMPILER}
|
||||
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
|
||||
C++ compiler: ${CMAKE_CXX_COMPILER}
|
||||
CXXFLAGS: ${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
|
||||
WARNCFLAGS: ${WARNCFLAGS}
|
||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||
Python:
|
||||
Python: ${PYTHON_EXECUTABLE}
|
||||
PYTHON_VERSION: ${PYTHON_VERSION_STRING}
|
||||
Library version:${PYTHONLIBS_VERSION_STRING}
|
||||
Cython: ${CYTHON_EXECUTABLE}
|
||||
Test:
|
||||
CUnit: ${HAVE_CUNIT} (LIBS='${CUNIT_LIBRARIES}')
|
||||
Failmalloc: ${ENABLE_FAILMALLOC}
|
||||
Libs:
|
||||
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
|
||||
Libxml2: ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
|
||||
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
|
||||
Libevent(SSL): ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
|
||||
Spdylay: ${HAVE_SPDYLAY} (LIBS='${SPDYLAY_LIBRARIES}')
|
||||
Jansson: ${HAVE_JANSSON} (LIBS='${JANSSON_LIBRARIES}')
|
||||
Jemalloc: ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
|
||||
Zlib: ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
|
||||
Boost::System: ${Boost_SYSTEM_LIBRARY}
|
||||
Boost::Thread: ${Boost_THREAD_LIBRARY}
|
||||
Third-party:
|
||||
http-parser: ${ENABLE_THIRD_PARTY}
|
||||
MRuby: ${HAVE_MRUBY}
|
||||
Neverbleed: ${HAVE_NEVERBLEED}
|
||||
Features:
|
||||
Applications: ${ENABLE_APP}
|
||||
HPACK tools: ${ENABLE_HPACK_TOOLS}
|
||||
Libnghttp2_asio:${ENABLE_ASIO_LIB}
|
||||
Examples: ${ENABLE_EXAMPLES}
|
||||
Python bindings:${ENABLE_PYTHON_BINDINGS}
|
||||
Threading: ${ENABLE_THREADS}
|
||||
")
|
||||
if(ENABLE_LIB_ONLY_DISABLED_OTHERS)
|
||||
message("Only the library will be built. To build other components "
|
||||
"(such as applications and examples), set ENABLE_LIB_ONLY=OFF.")
|
||||
endif()
|
||||
27
CMakeOptions.txt
Normal file
27
CMakeOptions.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
# Features that can be enabled for cmake (see CMakeLists.txt)
|
||||
|
||||
option(ENABLE_WERROR "Turn on compile time warnings")
|
||||
option(ENABLE_DEBUG "Turn on debug output")
|
||||
option(ENABLE_THREADS "Turn on threading in apps" ON)
|
||||
option(ENABLE_APP "Build applications (nghttp, nghttpd, nghttpx and h2load)"
|
||||
${ENABLE_APP_DEFAULT})
|
||||
option(ENABLE_HPACK_TOOLS "Build HPACK tools"
|
||||
${ENABLE_HPACK_TOOLS_DEFAULT})
|
||||
option(ENABLE_ASIO_LIB "Build C++ libnghttp2_asio library")
|
||||
option(ENABLE_EXAMPLES "Build examples"
|
||||
${ENABLE_EXAMPLES_DEFAULT})
|
||||
option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
|
||||
${ENABLE_PYTHON_BINDINGS_DEFAULT})
|
||||
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
|
||||
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
|
||||
|
||||
option(WITH_LIBXML2 "Use libxml2"
|
||||
${WITH_LIBXML2_DEFAULT})
|
||||
option(WITH_JEMALLOC "Use jemalloc"
|
||||
${WITH_JEMALLOC_DEFAULT})
|
||||
option(WITH_SPDYLAY "Use spdylay"
|
||||
${WITH_SPDYLAY_DEFAULT})
|
||||
option(WITH_MRUBY "Use mruby")
|
||||
option(WITH_NEVERBLEED "Use neverbleed")
|
||||
|
||||
# vim: ft=cmake:
|
||||
@@ -106,7 +106,7 @@ RUN HOST=arm-linux-androideabi \
|
||||
make install
|
||||
|
||||
WORKDIR /root/build
|
||||
RUN git clone https://github.com/tatsuhiro-t/nghttp2
|
||||
RUN git clone https://github.com/nghttp2/nghttp2
|
||||
WORKDIR /root/build/nghttp2
|
||||
RUN autoreconf -i && \
|
||||
./configure \
|
||||
|
||||
14
Makefile.am
14
Makefile.am
@@ -33,7 +33,19 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
dist_doc_DATA = README.rst
|
||||
|
||||
EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
|
||||
Dockerfile.android
|
||||
Dockerfile.android \
|
||||
cmakeconfig.h.in \
|
||||
CMakeLists.txt \
|
||||
CMakeOptions.txt \
|
||||
cmake/FindSpdylay.cmake \
|
||||
cmake/ExtractValidFlags.cmake \
|
||||
cmake/FindJemalloc.cmake \
|
||||
cmake/FindLibev.cmake \
|
||||
cmake/FindCUnit.cmake \
|
||||
cmake/Version.cmake \
|
||||
cmake/FindCython.cmake \
|
||||
cmake/FindLibevent.cmake \
|
||||
cmake/FindJansson.cmake
|
||||
|
||||
.PHONY: clang-format
|
||||
|
||||
|
||||
194
README.rst
194
README.rst
@@ -58,12 +58,17 @@ To build the documentation, you need to install:
|
||||
|
||||
* sphinx (http://sphinx-doc.org/)
|
||||
|
||||
If you need libnghttp2 (C library) only, then the above packages are
|
||||
all you need. Use ``--enable-lib-only`` to ensure that only
|
||||
libnghttp2 is built. This avoids potential build error related to
|
||||
building bundled applications.
|
||||
|
||||
To build and run the application programs (``nghttp``, ``nghttpd``,
|
||||
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
|
||||
are required:
|
||||
|
||||
* OpenSSL >= 1.0.1
|
||||
* libev >= 4.15
|
||||
* libev >= 4.11
|
||||
* zlib >= 1.2.3
|
||||
|
||||
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
|
||||
@@ -104,7 +109,9 @@ The Python bindings require the following packages:
|
||||
* python >= 2.7
|
||||
* python-setuptools
|
||||
|
||||
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages::
|
||||
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \
|
||||
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
|
||||
@@ -138,7 +145,9 @@ Building from git
|
||||
-----------------
|
||||
|
||||
Building from git is easy, but please be sure that at least autoconf 2.68 is
|
||||
used::
|
||||
used:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ autoreconf -i
|
||||
$ automake
|
||||
@@ -172,6 +181,23 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
||||
applications were not built, then using ``--enable-app`` may find
|
||||
that cause, such as the missing dependency.
|
||||
|
||||
Notes for building on Windows (MSVC)
|
||||
------------------------------------
|
||||
|
||||
The easiest way to build native Windows nghttp2 dll is use `cmake
|
||||
<https://cmake.org/>`_. The free version of `Visual C++ Build Tools
|
||||
<http://landinghub.visualstudio.com/visual-cpp-build-tools>`_ works
|
||||
fine.
|
||||
|
||||
1. Install cmake for windows
|
||||
2. Open "Visual C++ ... Native Build Tool Command Prompt", and inside
|
||||
nghttp2 directly, run ``cmake``.
|
||||
3. Then run ``cmake --build`` to build library.
|
||||
4. nghttp2.dll, nghttp2.lib, nghttp2.exp are placed under lib directory.
|
||||
|
||||
Note that the above steps most likely produce nghttp2 library only.
|
||||
No bundled applications are compiled.
|
||||
|
||||
Notes for building on Windows (Mingw/Cygwin)
|
||||
--------------------------------------------
|
||||
|
||||
@@ -188,7 +214,9 @@ Secondly, you need to undefine the macro ``__STRICT_ANSI__``, if you
|
||||
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
|
||||
available.
|
||||
|
||||
the sample command like this::
|
||||
the sample command like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ export CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
|
||||
$ export CXXFLAGS=$CFLAGS
|
||||
@@ -206,7 +234,9 @@ Building the documentation
|
||||
|
||||
Documentation is still incomplete.
|
||||
|
||||
To build the documentation, run::
|
||||
To build the documentation, run:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ make html
|
||||
|
||||
@@ -235,12 +265,16 @@ its testing framework. We depend on the following libraries:
|
||||
* https://github.com/tatsuhiro-t/spdy
|
||||
|
||||
To download the above packages, after settings ``GOPATH``, run the
|
||||
following command under ``integration-tests`` directory::
|
||||
following command under ``integration-tests`` directory:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ make itprep
|
||||
|
||||
To run the tests, run the following command under
|
||||
``integration-tests`` directory::
|
||||
``integration-tests`` directory:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ make it
|
||||
|
||||
@@ -361,7 +395,9 @@ nghttp - client
|
||||
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
|
||||
|
||||
It has verbose output mode for framing information. Here is sample
|
||||
output from ``nghttp`` client::
|
||||
output from ``nghttp`` client:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttp -nv https://nghttp2.org
|
||||
[ 0.190] Connected
|
||||
@@ -444,7 +480,9 @@ output from ``nghttp`` client::
|
||||
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
|
||||
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
||||
|
||||
The HTTP Upgrade is performed like so::
|
||||
The HTTP Upgrade is performed like so:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttp -nvu http://nghttp2.org
|
||||
[ 0.011] Connected
|
||||
@@ -540,7 +578,9 @@ The HTTP Upgrade is performed like so::
|
||||
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
||||
|
||||
Using the ``-s`` option, ``nghttp`` prints out some timing information for
|
||||
requests, sorted by completion time::
|
||||
requests, sorted by completion time:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttp -nas https://nghttp2.org/
|
||||
***** Statistics *****
|
||||
@@ -584,7 +624,9 @@ HTTP/2 connections. No HTTP Upgrade is supported.
|
||||
The ``-p`` option allows users to configure server push.
|
||||
|
||||
Just like ``nghttp``, it has a verbose output mode for framing
|
||||
information. Here is sample output from ``nghttpd``::
|
||||
information. Here is sample output from ``nghttpd``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttpd --no-tls -v 8080
|
||||
IPv4: listen 0.0.0.0:8080
|
||||
@@ -647,6 +689,14 @@ nghttpx - proxy
|
||||
HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
|
||||
push.
|
||||
|
||||
We reworked ``nghttpx`` command-line interface, and as a result, there
|
||||
are several incompatibles from 1.8.0 or earlier. This is necessary to
|
||||
extend its capability, and secure the further feature enhancements in
|
||||
the future release. Please read `Migration from nghttpx v1.8.0 or
|
||||
earlier
|
||||
<https://nghttp2.org/documentation/nghttpx-howto.html#migration-from-nghttpx-v1-8-0-or-earlier>`_
|
||||
to know how to migrate from earlier releases.
|
||||
|
||||
``nghttpx`` implements `important performance-oriented features
|
||||
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
|
||||
session IDs, session tickets (with automatic key rotation), OCSP
|
||||
@@ -655,46 +705,42 @@ HTTP/2. ``nghttpx`` also offers the functionality to share session
|
||||
cache and ticket keys among multiple ``nghttpx`` instances via
|
||||
memcached.
|
||||
|
||||
``nghttpx`` has several operational modes:
|
||||
``nghttpx`` has 2 operation modes:
|
||||
|
||||
================== ============================ ============== =============
|
||||
Mode option Frontend Backend Note
|
||||
================== ============================ ============== =============
|
||||
default mode HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 Reverse proxy
|
||||
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 SPDY proxy
|
||||
``--http2-bridge`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/2 (TLS)
|
||||
``--client`` HTTP/2, HTTP/1.1 HTTP/2 (TLS)
|
||||
``--client-proxy`` HTTP/2, HTTP/1.1 HTTP/2 (TLS) Forward proxy
|
||||
================== ============================ ============== =============
|
||||
================== ====================== ================ =============
|
||||
Mode option Frontend Backend Note
|
||||
================== ====================== ================ =============
|
||||
default mode HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
|
||||
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
|
||||
================== ====================== ================ =============
|
||||
|
||||
The interesting mode at the moment is the default mode. It works like
|
||||
a reverse proxy and listens for HTTP/2, SPDY and HTTP/1.1 and can be
|
||||
deployed as a SSL/TLS terminator for existing web server.
|
||||
|
||||
The default mode, ``--http2-proxy`` and ``--http2-bridge`` modes use
|
||||
SSL/TLS in the frontend connection by default. To disable SSL/TLS,
|
||||
use the ``--frontend-no-tls`` option. If that option is used, SPDY is
|
||||
disabled in the frontend and incoming HTTP/1.1 connections can be
|
||||
upgraded to HTTP/2 through HTTP Upgrade. In these modes, HTTP/1
|
||||
backend connections are cleartext by default. To enable TLS, use
|
||||
``--backend-http1-tls`` opiton.
|
||||
|
||||
The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use
|
||||
SSL/TLS in the backend connection by default. To disable SSL/TLS, use
|
||||
the ``--backend-no-tls`` option.
|
||||
In all modes, the frontend connections are encrypted by SSL/TLS by
|
||||
default. To disable encryption, use the ``no-tls`` keyword in
|
||||
``--frontend`` option. If encryption is disabled, SPDY is disabled in
|
||||
the frontend and incoming HTTP/1.1 connections can be upgraded to
|
||||
HTTP/2 through HTTP Upgrade. On the other hard, backend connections
|
||||
are not encrypted by default. To encrypt backend connections, use
|
||||
``tls`` keyword in ``--backend`` option.
|
||||
|
||||
``nghttpx`` supports a configuration file. See the ``--conf`` option and
|
||||
sample configuration file ``nghttpx.conf.sample``.
|
||||
|
||||
In the default mode, (without any of ``--http2-proxy``,
|
||||
``--http2-bridge``, ``--client-proxy`` and ``--client`` options),
|
||||
``nghttpx`` works as reverse proxy to the backend server::
|
||||
In the default mode, ``nghttpx`` works as reverse proxy to the backend
|
||||
server:
|
||||
|
||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Web Server
|
||||
.. code-block:: text
|
||||
|
||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
|
||||
[reverse proxy]
|
||||
|
||||
With the ``--http2-proxy`` option, it works as a so called secure proxy (aka
|
||||
SPDY proxy)::
|
||||
With the ``--http2-proxy`` option, it works as forward proxy, and it
|
||||
is so called secure HTTP/2 proxy (aka SPDY proxy):
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
|
||||
[secure proxy] (e.g., Squid, ATS)
|
||||
@@ -702,9 +748,9 @@ SPDY proxy)::
|
||||
The ``Client`` in the above example needs to be configured to use
|
||||
``nghttpx`` as secure proxy.
|
||||
|
||||
At the time of this writing, Chrome is the only browser which supports
|
||||
secure proxy. One way to configure Chrome to use a secure proxy is
|
||||
to create a proxy.pac script like this:
|
||||
At the time of this writing, both Chrome and Firefox support secure
|
||||
HTTP/2 proxy. One way to configure Chrome to use a secure proxy is to
|
||||
create a proxy.pac script like this:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
@@ -716,42 +762,18 @@ to create a proxy.pac script like this:
|
||||
machine nghttpx is running on. Please note that Chrome requires a valid
|
||||
certificate for secure proxy.
|
||||
|
||||
Then run Chrome with the following arguments::
|
||||
Then run Chrome with the following arguments:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||
|
||||
With ``--http2-bridge``, it accepts HTTP/2, SPDY and HTTP/1.1
|
||||
connections and communicates with the backend in HTTP/2::
|
||||
|
||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web or HTTP/2 Proxy etc
|
||||
(e.g., nghttpx -s)
|
||||
|
||||
With ``--client-proxy``, it works as a forward proxy and expects
|
||||
that the backend is an HTTP/2 proxy::
|
||||
|
||||
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> HTTP/2 Proxy
|
||||
[forward proxy] (e.g., nghttpx -s)
|
||||
|
||||
The ``Client`` needs to be configured to use nghttpx as a forward
|
||||
proxy. The frontend HTTP/1.1 connection can be upgraded to HTTP/2
|
||||
through HTTP Upgrade. With the above configuration, one can use
|
||||
HTTP/1.1 client to access and test their HTTP/2 servers.
|
||||
|
||||
With ``--client``, it works as a reverse proxy and expects that
|
||||
the backend is an HTTP/2 Web server::
|
||||
|
||||
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web Server
|
||||
[reverse proxy]
|
||||
|
||||
The frontend HTTP/1.1 connection can be upgraded to HTTP/2
|
||||
through HTTP Upgrade.
|
||||
|
||||
For the operation modes which talk to the backend in HTTP/2 over
|
||||
SSL/TLS, the backend connections can be tunneled through an HTTP proxy.
|
||||
The backend HTTP/2 connections can be tunneled through an HTTP proxy.
|
||||
The proxy is specified using ``--backend-http-proxy-uri``. The
|
||||
following figure illustrates the example of the ``--http2-bridge`` and
|
||||
``--backend-http-proxy-uri`` options to talk to the outside HTTP/2
|
||||
proxy through an HTTP proxy::
|
||||
following figure illustrates how nghttpx talks to the outside HTTP/2
|
||||
proxy through an HTTP proxy:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
|
||||
|
||||
@@ -765,7 +787,9 @@ The ``h2load`` program is a benchmarking tool for HTTP/2 and SPDY.
|
||||
The SPDY support is enabled if the program was built with the spdylay
|
||||
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
|
||||
(https://github.com/lighttpd/weighttp). The typical usage is as
|
||||
follows::
|
||||
follows:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ h2load -n100000 -c100 -m100 https://localhost:8443/
|
||||
starting benchmark...
|
||||
@@ -853,7 +877,9 @@ Example:
|
||||
With the ``-t`` option, the program can accept more familiar HTTP/1 style
|
||||
header field blocks. Each header set is delimited by an empty line:
|
||||
|
||||
Example::
|
||||
Example:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
:method: GET
|
||||
:scheme: https
|
||||
@@ -1349,7 +1375,7 @@ The extension module is called ``nghttp2``.
|
||||
determined by the ``configure`` script. If the detected Python version is not
|
||||
what you expect, specify a path to Python executable in a ``PYTHON``
|
||||
variable as an argument to configure script (e.g., ``./configure
|
||||
PYTHON=/usr/bin/python3.4``).
|
||||
PYTHON=/usr/bin/python3.5``).
|
||||
|
||||
The following example code illustrates basic usage of the HPACK compressor
|
||||
and decompressor in Python:
|
||||
@@ -1479,6 +1505,17 @@ See `Contribution Guidelines
|
||||
<https://nghttp2.org/documentation/contribute.html>`_ for more
|
||||
details.
|
||||
|
||||
Reporting vulnerability
|
||||
-----------------------
|
||||
|
||||
If you find a vulnerability in our software, please send the email to
|
||||
"tatsuhiro.t at gmail dot com" about its details instead of submitting
|
||||
issues on github issue page. It is a standard practice not to
|
||||
disclose vulnerability information publicly until a fixed version is
|
||||
released, or mitigation is worked out.
|
||||
|
||||
In the future, we may setup a dedicated mail address for this purpose.
|
||||
|
||||
Release schedule
|
||||
----------------
|
||||
|
||||
@@ -1491,3 +1528,8 @@ severe security bug fixes.
|
||||
|
||||
We have no plan to break API compatibility changes involving soname
|
||||
bump, so MAJOR version will stay 1 for the foreseeable future.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
The MIT License
|
||||
|
||||
@@ -39,9 +39,8 @@ PATH="$TOOLCHAIN"/bin:"$PATH"
|
||||
--without-libxml2 \
|
||||
--disable-python-bindings \
|
||||
--disable-examples \
|
||||
--enable-werror \
|
||||
CC="$TOOLCHAIN"/bin/clang \
|
||||
CXX="$TOOLCHAIN"/bin/clang++ \
|
||||
CC="$TOOLCHAIN"/bin/arm-linux-androideabi-gcc \
|
||||
CXX="$TOOLCHAIN"/bin/arm-linux-androideabi-g++ \
|
||||
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||
LDFLAGS="-fPIE -pie -L$PREFIX/lib"
|
||||
|
||||
52
author.py
Executable file
52
author.py
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# script to extract commit author's name from standard input. The
|
||||
# input should be <AUTHOR>:<EMAIL>, one per line.
|
||||
# This script expects the input is created by git-log command:
|
||||
#
|
||||
# git log --format=%aN:%aE
|
||||
#
|
||||
# This script removes duplicates based on email address, breaking a
|
||||
# tie with longer author name. Among the all author names extract the
|
||||
# previous step, we remove duplicate by case-insensitive match.
|
||||
#
|
||||
# So we can do this in one line:
|
||||
#
|
||||
# git log --format=%aN:%aE | sort | uniq | ./author.py > authors
|
||||
|
||||
import sys
|
||||
|
||||
edict = {}
|
||||
|
||||
for line in sys.stdin:
|
||||
author, email = line.strip().split(':', 1)
|
||||
if email in edict:
|
||||
an = edict[email]
|
||||
if len(an) < len(author) or an > author:
|
||||
sys.stderr.write(
|
||||
'eliminated {} in favor of {}\n'.format(an, author))
|
||||
edict[email] = author
|
||||
else:
|
||||
sys.stderr.write(
|
||||
'eliminated {} in favor of {}\n'.format(author, an))
|
||||
else:
|
||||
edict[email] = author
|
||||
|
||||
names = list(sorted(edict.values()))
|
||||
|
||||
ndict = {}
|
||||
|
||||
for name in names:
|
||||
lowname = name.lower()
|
||||
if lowname in ndict:
|
||||
an = ndict[lowname]
|
||||
if an > name:
|
||||
sys.stderr.write('eliminated {} in favor of {}\n'.format(an, name))
|
||||
ndict[lowname] = name
|
||||
else:
|
||||
sys.stderr.write('eliminated {} in favor of {}\n'.format(name, an))
|
||||
else:
|
||||
ndict[lowname] = name
|
||||
|
||||
for name in sorted(ndict.values()):
|
||||
print name
|
||||
31
cmake/ExtractValidFlags.cmake
Normal file
31
cmake/ExtractValidFlags.cmake
Normal file
@@ -0,0 +1,31 @@
|
||||
# Convenience function that checks the availability of certain
|
||||
# C or C++ compiler flags and returns valid ones as a string.
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
function(extract_valid_c_flags varname)
|
||||
set(valid_flags)
|
||||
foreach(flag IN LISTS ARGN)
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
|
||||
set(flag_var "C_FLAG_${flag_var}")
|
||||
check_c_compiler_flag("${flag}" "${flag_var}")
|
||||
if(${flag_var})
|
||||
set(valid_flags "${valid_flags} ${flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${varname} "${valid_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(extract_valid_cxx_flags varname)
|
||||
set(valid_flags)
|
||||
foreach(flag IN LISTS ARGN)
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
|
||||
set(flag_var "CXX_FLAG_${flag_var}")
|
||||
check_cxx_compiler_flag("${flag}" "${flag_var}")
|
||||
if(${flag_var})
|
||||
set(valid_flags "${valid_flags} ${flag}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${varname} "${valid_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
40
cmake/FindCUnit.cmake
Normal file
40
cmake/FindCUnit.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# - Try to find cunit
|
||||
# Once done this will define
|
||||
# CUNIT_FOUND - System has cunit
|
||||
# CUNIT_INCLUDE_DIRS - The cunit include directories
|
||||
# CUNIT_LIBRARIES - The libraries needed to use cunit
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_CUNIT QUIET cunit)
|
||||
|
||||
find_path(CUNIT_INCLUDE_DIR
|
||||
NAMES CUnit/CUnit.h
|
||||
HINTS ${PC_CUNIT_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(CUNIT_LIBRARY
|
||||
NAMES cunit
|
||||
HINTS ${PC_CUNIT_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(CUNIT_INCLUDE_DIR)
|
||||
set(_version_regex "^#define[ \t]+CU_VERSION[ \t]+\"([^\"]+)\".*")
|
||||
file(STRINGS "${CUNIT_INCLUDE_DIR}/CUnit/CUnit.h"
|
||||
CUNIT_VERSION REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||
CUNIT_VERSION "${CUNIT_VERSION}")
|
||||
unset(_version_regex)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set CUNIT_FOUND to TRUE
|
||||
# if all listed variables are TRUE and the requested version matches.
|
||||
find_package_handle_standard_args(CUnit REQUIRED_VARS
|
||||
CUNIT_LIBRARY CUNIT_INCLUDE_DIR
|
||||
VERSION_VAR CUNIT_VERSION)
|
||||
|
||||
if(CUNIT_FOUND)
|
||||
set(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
|
||||
set(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)
|
||||
44
cmake/FindCython.cmake
Normal file
44
cmake/FindCython.cmake
Normal file
@@ -0,0 +1,44 @@
|
||||
# Find the Cython compiler.
|
||||
#
|
||||
# This code sets the following variables:
|
||||
#
|
||||
# CYTHON_EXECUTABLE
|
||||
#
|
||||
# See also UseCython.cmake
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2011 Kitware, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#=============================================================================
|
||||
|
||||
# Use the Cython executable that lives next to the Python executable
|
||||
# if it is a local installation.
|
||||
find_package( PythonInterp )
|
||||
if( PYTHONINTERP_FOUND )
|
||||
get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
|
||||
find_program( CYTHON_EXECUTABLE
|
||||
NAMES cython cython.bat cython3
|
||||
HINTS ${_python_path}
|
||||
)
|
||||
else()
|
||||
find_program( CYTHON_EXECUTABLE
|
||||
NAMES cython cython.bat cython3
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
include( FindPackageHandleStandardArgs )
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE )
|
||||
|
||||
mark_as_advanced( CYTHON_EXECUTABLE )
|
||||
40
cmake/FindJansson.cmake
Normal file
40
cmake/FindJansson.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# - Try to find jansson
|
||||
# Once done this will define
|
||||
# JANSSON_FOUND - System has jansson
|
||||
# JANSSON_INCLUDE_DIRS - The jansson include directories
|
||||
# JANSSON_LIBRARIES - The libraries needed to use jansson
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_JANSSON QUIET jansson)
|
||||
|
||||
find_path(JANSSON_INCLUDE_DIR
|
||||
NAMES jansson.h
|
||||
HINTS ${PC_JANSSON_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(JANSSON_LIBRARY
|
||||
NAMES jansson
|
||||
HINTS ${PC_JANSSON_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(JANSSON_INCLUDE_DIR)
|
||||
set(_version_regex "^#define[ \t]+JANSSON_VERSION[ \t]+\"([^\"]+)\".*")
|
||||
file(STRINGS "${JANSSON_INCLUDE_DIR}/jansson.h"
|
||||
JANSSON_VERSION REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||
JANSSON_VERSION "${JANSSON_VERSION}")
|
||||
unset(_version_regex)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set JANSSON_FOUND to TRUE
|
||||
# if all listed variables are TRUE and the requested version matches.
|
||||
find_package_handle_standard_args(Jansson REQUIRED_VARS
|
||||
JANSSON_LIBRARY JANSSON_INCLUDE_DIR
|
||||
VERSION_VAR JANSSON_VERSION)
|
||||
|
||||
if(JANSSON_FOUND)
|
||||
set(JANSSON_LIBRARIES ${JANSSON_LIBRARY})
|
||||
set(JANSSON_INCLUDE_DIRS ${JANSSON_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(JANSSON_INCLUDE_DIR JANSSON_LIBRARY)
|
||||
40
cmake/FindJemalloc.cmake
Normal file
40
cmake/FindJemalloc.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# - Try to find jemalloc
|
||||
# Once done this will define
|
||||
# JEMALLOC_FOUND - System has jemalloc
|
||||
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
|
||||
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
|
||||
|
||||
find_path(JEMALLOC_INCLUDE_DIR
|
||||
NAMES jemalloc/jemalloc.h
|
||||
HINTS ${PC_JEMALLOC_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(JEMALLOC_LIBRARY
|
||||
NAMES jemalloc
|
||||
HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(JEMALLOC_INCLUDE_DIR)
|
||||
set(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
|
||||
file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc/jemalloc.h"
|
||||
JEMALLOC_VERSION REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||
JEMALLOC_VERSION "${JEMALLOC_VERSION}")
|
||||
unset(_version_regex)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
|
||||
# if all listed variables are TRUE and the requested version matches.
|
||||
find_package_handle_standard_args(Jemalloc REQUIRED_VARS
|
||||
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR
|
||||
VERSION_VAR JEMALLOC_VERSION)
|
||||
|
||||
if(JEMALLOC_FOUND)
|
||||
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
|
||||
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)
|
||||
38
cmake/FindLibev.cmake
Normal file
38
cmake/FindLibev.cmake
Normal file
@@ -0,0 +1,38 @@
|
||||
# - Try to find libev
|
||||
# Once done this will define
|
||||
# LIBEV_FOUND - System has libev
|
||||
# LIBEV_INCLUDE_DIRS - The libev include directories
|
||||
# LIBEV_LIBRARIES - The libraries needed to use libev
|
||||
|
||||
find_path(LIBEV_INCLUDE_DIR
|
||||
NAMES ev.h
|
||||
)
|
||||
find_library(LIBEV_LIBRARY
|
||||
NAMES ev
|
||||
)
|
||||
|
||||
if(LIBEV_INCLUDE_DIR)
|
||||
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
|
||||
LIBEV_VERSION_MAJOR REGEX "^#define[ \t]+EV_VERSION_MAJOR[ \t]+[0-9]+")
|
||||
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
|
||||
LIBEV_VERSION_MINOR REGEX "^#define[ \t]+EV_VERSION_MINOR[ \t]+[0-9]+")
|
||||
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MAJOR "${LIBEV_VERSION_MAJOR}")
|
||||
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MINOR "${LIBEV_VERSION_MINOR}")
|
||||
set(LIBEV_VERSION "${LIBEV_VERSION_MAJOR}.${LIBEV_VERSION_MINOR}")
|
||||
unset(LIBEV_VERSION_MINOR)
|
||||
unset(LIBEV_VERSION_MAJOR)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBEV_FOUND to TRUE
|
||||
# if all listed variables are TRUE and the requested version matches.
|
||||
find_package_handle_standard_args(Libev REQUIRED_VARS
|
||||
LIBEV_LIBRARY LIBEV_INCLUDE_DIR
|
||||
VERSION_VAR LIBEV_VERSION)
|
||||
|
||||
if(LIBEV_FOUND)
|
||||
set(LIBEV_LIBRARIES ${LIBEV_LIBRARY})
|
||||
set(LIBEV_INCLUDE_DIRS ${LIBEV_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBEV_INCLUDE_DIR LIBEV_LIBRARY)
|
||||
94
cmake/FindLibevent.cmake
Normal file
94
cmake/FindLibevent.cmake
Normal file
@@ -0,0 +1,94 @@
|
||||
# - Try to find libevent
|
||||
#.rst
|
||||
# FindLibevent
|
||||
# ------------
|
||||
#
|
||||
# Find Libevent include directories and libraries. Invoke as::
|
||||
#
|
||||
# find_package(Libevent
|
||||
# [version] [EXACT] # Minimum or exact version
|
||||
# [REQUIRED] # Fail if Libevent is not found
|
||||
# [COMPONENT <C>...]) # Libraries to look for
|
||||
#
|
||||
# Valid components are one or more of:: libevent core extra pthreads openssl.
|
||||
# Note that 'libevent' contains both core and extra. You must specify one of
|
||||
# them for the other components.
|
||||
#
|
||||
# This module will define the following variables::
|
||||
#
|
||||
# LIBEVENT_FOUND - True if headers and requested libraries were found
|
||||
# LIBEVENT_INCLUDE_DIRS - Libevent include directories
|
||||
# LIBEVENT_LIBRARIES - Libevent libraries to be linked
|
||||
# LIBEVENT_<C>_FOUND - Component <C> was found (<C> is uppercase)
|
||||
# LIBEVENT_<C>_LIBRARY - Library to be linked for Libevent component <C>.
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_LIBEVENT QUIET libevent)
|
||||
|
||||
# Look for the Libevent 2.0 or 1.4 headers
|
||||
find_path(LIBEVENT_INCLUDE_DIR
|
||||
NAMES
|
||||
event2/event-config.h
|
||||
event-config.h
|
||||
HINTS
|
||||
${PC_LIBEVENT_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if(LIBEVENT_INCLUDE_DIR)
|
||||
set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
|
||||
if(EXISTS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h")
|
||||
# Libevent 2.0
|
||||
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h"
|
||||
LIBEVENT_VERSION REGEX "${_version_regex}")
|
||||
else()
|
||||
# Libevent 1.4
|
||||
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h"
|
||||
LIBEVENT_VERSION REGEX "${_version_regex}")
|
||||
endif()
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||
LIBEVENT_VERSION "${LIBEVENT_VERSION}")
|
||||
unset(_version_regex)
|
||||
endif()
|
||||
|
||||
set(_LIBEVENT_REQUIRED_VARS)
|
||||
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
|
||||
set(_LIBEVENT_LIBNAME libevent)
|
||||
# Note: compare two variables to avoid a CMP0054 policy warning
|
||||
if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
|
||||
set(_LIBEVENT_LIBNAME event)
|
||||
else()
|
||||
set(_LIBEVENT_LIBNAME "event_${COMPONENT}")
|
||||
endif()
|
||||
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
|
||||
find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
|
||||
NAMES ${_LIBEVENT_LIBNAME}
|
||||
HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
|
||||
)
|
||||
if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
|
||||
set(Libevent_${COMPONENT}_FOUND 1)
|
||||
endif()
|
||||
list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
|
||||
endforeach()
|
||||
unset(_LIBEVENT_LIBNAME)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
|
||||
# if all listed variables are TRUE and the requested version matches.
|
||||
find_package_handle_standard_args(Libevent REQUIRED_VARS
|
||||
${_LIBEVENT_REQUIRED_VARS}
|
||||
LIBEVENT_INCLUDE_DIR
|
||||
VERSION_VAR LIBEVENT_VERSION
|
||||
HANDLE_COMPONENTS)
|
||||
|
||||
if(LIBEVENT_FOUND)
|
||||
set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
|
||||
set(LIBEVENT_LIBRARIES)
|
||||
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
|
||||
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
|
||||
list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
|
||||
set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS})
|
||||
unset(_LIBEVENT_REQUIRED_VARS)
|
||||
40
cmake/FindSpdylay.cmake
Normal file
40
cmake/FindSpdylay.cmake
Normal file
@@ -0,0 +1,40 @@
|
||||
# - Try to find spdylay
|
||||
# Once done this will define
|
||||
# SPDYLAY_FOUND - System has spdylay
|
||||
# SPDYLAY_INCLUDE_DIRS - The spdylay include directories
|
||||
# SPDYLAY_LIBRARIES - The libraries needed to use spdylay
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_SPDYLAY QUIET libspdylay)
|
||||
|
||||
find_path(SPDYLAY_INCLUDE_DIR
|
||||
NAMES spdylay/spdylay.h
|
||||
HINTS ${PC_SPDYLAY_INCLUDE_DIRS}
|
||||
)
|
||||
find_library(SPDYLAY_LIBRARY
|
||||
NAMES spdylay
|
||||
HINTS ${PC_SPDYLAY_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
if(SPDYLAY_INCLUDE_DIR)
|
||||
set(_version_regex "^#define[ \t]+SPDYLAY_VERSION[ \t]+\"([^\"]+)\".*")
|
||||
file(STRINGS "${SPDYLAY_INCLUDE_DIR}/spdylay/spdylayver.h"
|
||||
SPDYLAY_VERSION REGEX "${_version_regex}")
|
||||
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||
SPDYLAY_VERSION "${SPDYLAY_VERSION}")
|
||||
unset(_version_regex)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
# handle the QUIETLY and REQUIRED arguments and set SPDYLAY_FOUND to TRUE
|
||||
# if all listed variables are TRUE and the requested version matches.
|
||||
find_package_handle_standard_args(Spdylay REQUIRED_VARS
|
||||
SPDYLAY_LIBRARY SPDYLAY_INCLUDE_DIR
|
||||
VERSION_VAR SPDYLAY_VERSION)
|
||||
|
||||
if(SPDYLAY_FOUND)
|
||||
set(SPDYLAY_LIBRARIES ${SPDYLAY_LIBRARY})
|
||||
set(SPDYLAY_INCLUDE_DIRS ${SPDYLAY_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(SPDYLAY_INCLUDE_DIR SPDYLAY_LIBRARY)
|
||||
11
cmake/Version.cmake
Normal file
11
cmake/Version.cmake
Normal file
@@ -0,0 +1,11 @@
|
||||
# Converts a version such as 1.2.255 to 0x0102ff
|
||||
function(HexVersion version_hex_var major minor patch)
|
||||
math(EXPR version_dec "${major} * 256 * 256 + ${minor} * 256 + ${patch}")
|
||||
set(version_hex "0x")
|
||||
foreach(i RANGE 5 0 -1)
|
||||
math(EXPR num "(${version_dec} >> (4 * ${i})) & 15")
|
||||
string(SUBSTRING "0123456789abcdef" ${num} 1 num_hex)
|
||||
set(version_hex "${version_hex}${num_hex}")
|
||||
endforeach()
|
||||
set(${version_hex_var} "${version_hex}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
84
cmakeconfig.h.in
Normal file
84
cmakeconfig.h.in
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
/* Hint to the compiler that a function parameter is not used */
|
||||
#define _U_ @HINT_UNUSED_PARAM@
|
||||
|
||||
/* Hint to the compiler that a function never returns */
|
||||
#define NGHTTP2_NORETURN @HINT_NORETURN@
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#cmakedefine ssize_t @ssize_t@
|
||||
|
||||
/* Define to 1 if you have the `std::map::emplace`. */
|
||||
#cmakedefine HAVE_STD_MAP_EMPLACE 1
|
||||
|
||||
/* Define to 1 if you have `libjansson` library. */
|
||||
#cmakedefine HAVE_JANSSON 1
|
||||
|
||||
/* Define to 1 if you have `libxml2` library. */
|
||||
#cmakedefine HAVE_LIBXML2 1
|
||||
|
||||
/* Define to 1 if you have `spdylay` library. */
|
||||
#cmakedefine HAVE_SPDYLAY 1
|
||||
|
||||
/* Define to 1 if you have `mruby` library. */
|
||||
#cmakedefine HAVE_MRUBY 1
|
||||
|
||||
/* Define to 1 if you have `neverbleed` library. */
|
||||
#cmakedefine HAVE_NEVERBLEED 1
|
||||
|
||||
/* sizeof(int *) */
|
||||
#cmakedefine SIZEOF_INT_P @SIZEOF_INT_P@
|
||||
|
||||
/* sizeof(time_t) */
|
||||
#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
|
||||
|
||||
/* Define to 1 if you have the `_Exit` function. */
|
||||
#cmakedefine HAVE__EXIT 1
|
||||
|
||||
/* Define to 1 if you have the `accept4` function. */
|
||||
#cmakedefine HAVE_ACCEPT4 1
|
||||
|
||||
/* Define to 1 if you have the `initgroups` function. */
|
||||
#cmakedefine01 HAVE_DECL_INITGROUPS
|
||||
|
||||
/* Define to 1 to enable debug output. */
|
||||
#cmakedefine DEBUGBUILD 1
|
||||
|
||||
/* Define to 1 if you want to disable threads. */
|
||||
#cmakedefine NOTHREADS 1
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#cmakedefine HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#cmakedefine HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#cmakedefine HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#cmakedefine HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#cmakedefine HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#cmakedefine HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#cmakedefine HAVE_PWD_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#cmakedefine HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#cmakedefine HAVE_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H 1
|
||||
57
configure.ac
57
configure.ac
@@ -25,7 +25,7 @@ dnl Do not change user variables!
|
||||
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([nghttp2], [1.8.0], [t-tujikawa@users.sourceforge.net])
|
||||
AC_INIT([nghttp2], [1.16.0], [t-tujikawa@users.sourceforge.net])
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
@@ -40,15 +40,13 @@ AC_CANONICAL_TARGET
|
||||
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
|
||||
# AM_EXTRA_RECURSIVE_TARGETS requires automake 1.13 or higher
|
||||
m4_ifdef([AM_EXTRA_RECURSIVE_TARGETS], [AM_EXTRA_RECURSIVE_TARGETS([it itprep])])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl See versioning rule:
|
||||
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
AC_SUBST(LT_CURRENT, 19)
|
||||
AC_SUBST(LT_CURRENT, 26)
|
||||
AC_SUBST(LT_REVISION, 0)
|
||||
AC_SUBST(LT_AGE, 5)
|
||||
AC_SUBST(LT_AGE, 12)
|
||||
|
||||
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
||||
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
||||
@@ -236,6 +234,41 @@ std::map<int, int>().emplace(1, 2);
|
||||
[have_std_map_emplace=no
|
||||
AC_MSG_RESULT([no])])
|
||||
|
||||
# Check that std::atomic_* overloads for std::shared_ptr are
|
||||
# available.
|
||||
AC_MSG_CHECKING([whether std::atomic_* overloads for std::shared_ptr are available])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <memory>
|
||||
]],
|
||||
[[
|
||||
auto a = std::make_shared<int>(1000000007);
|
||||
auto p = std::atomic_load(&a);
|
||||
++*p;
|
||||
std::atomic_store(&a, p);
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_ATOMIC_STD_SHARED_PTR], [1],
|
||||
[Define to 1 if you have the std::atomic_* overloads for std::shared_ptr.])
|
||||
have_atomic_std_shared_ptr=yes
|
||||
AC_MSG_RESULT([yes])],
|
||||
[have_atomic_std_shared_ptr=no
|
||||
AC_MSG_RESULT([no])])
|
||||
|
||||
# Check that thread_local storage specifier is available
|
||||
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||
,
|
||||
[[
|
||||
thread_local int a = 0;
|
||||
(void)a;
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
|
||||
[Define to 1 if you have thread_local storage specifier.])
|
||||
have_thread_local=yes
|
||||
AC_MSG_RESULT([yes])],
|
||||
[have_Thread_local=no
|
||||
AC_MSG_RESULT([no])])
|
||||
|
||||
CXXFLAGS=$save_CXXFLAGS
|
||||
|
||||
AC_LANG_POP()
|
||||
@@ -248,7 +281,7 @@ TESTLDADD=
|
||||
# Additional libraries required for programs under src directory.
|
||||
APPLDFLAGS=
|
||||
|
||||
case "$host" in
|
||||
case "$host_os" in
|
||||
*android*)
|
||||
android_build=yes
|
||||
# android does not need -pthread, but needs followng 3 libs for C++
|
||||
@@ -260,6 +293,12 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$host_os" in
|
||||
*solaris*)
|
||||
APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
|
||||
;;
|
||||
esac
|
||||
|
||||
# zlib
|
||||
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
|
||||
|
||||
@@ -722,12 +761,17 @@ if test "x$werror" != "xno"; then
|
||||
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
|
||||
# Only work with Clang for the moment
|
||||
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CFLAGS="$CFLAGS -Wsometimes-uninitialized"])
|
||||
|
||||
# This is required because we pass format string as "const char*.
|
||||
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
|
||||
|
||||
# For C++ compiler
|
||||
AC_LANG_PUSH(C++)
|
||||
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
|
||||
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
|
||||
AC_LANG_POP()
|
||||
fi
|
||||
|
||||
@@ -824,6 +868,7 @@ AC_MSG_NOTICE([summary of build options:
|
||||
C preprocessor: ${CPP}
|
||||
CPPFLAGS: ${CPPFLAGS}
|
||||
WARNCFLAGS: ${WARNCFLAGS}
|
||||
WARNCXXFLAGS: ${WARNCXXFLAGS}
|
||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||
EXTRACFLAG: ${EXTRACFLAG}
|
||||
LIBS: ${LIBS}
|
||||
|
||||
12
contrib/CMakeLists.txt
Normal file
12
contrib/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
set(CONFIGFILES
|
||||
nghttpx-init
|
||||
nghttpx.service
|
||||
nghttpx-upstart.conf
|
||||
)
|
||||
|
||||
# Note that the execute permissions of nghttpx-init is preserved
|
||||
foreach(name IN LISTS CONFIGFILES)
|
||||
configure_file("${name}.in" "${name}" @ONLY)
|
||||
endforeach()
|
||||
|
||||
# set(EXTRA_DIST ${CONFIGFILES} nghttpx-logrotate tlsticketupdate.go)
|
||||
@@ -23,17 +23,24 @@
|
||||
|
||||
configfiles = nghttpx-init nghttpx.service nghttpx-upstart.conf
|
||||
|
||||
EXTRA_DIST = $(configfiles:%=%.in) nghttpx-logrotate tlsticketupdate.go
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
$(configfiles:%=%.in) \
|
||||
nghttpx-logrotate \
|
||||
tlsticketupdate.go
|
||||
|
||||
edit = sed -e 's|@bindir[@]|$(bindir)|g'
|
||||
|
||||
nghttpx-init: %: $(srcdir)/%.in
|
||||
nghttpx-init: $(srcdir)/nghttpx-init.in
|
||||
rm -f $@ $@.tmp
|
||||
$(edit) $< > $@.tmp
|
||||
chmod +x $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
nghttpx.service nghttpx-upstart.conf: %: $(srcdir)/%.in
|
||||
nghttpx.service: $(srcdir)/nghttpx.service.in
|
||||
$(edit) $< > $@
|
||||
|
||||
nghttpx-upstart.conf: $(srcdir)/nghttpx-upstart.conf.in
|
||||
$(edit) $< > $@
|
||||
|
||||
$(configfiles): Makefile
|
||||
|
||||
352
doc/CMakeLists.txt
Normal file
352
doc/CMakeLists.txt
Normal file
@@ -0,0 +1,352 @@
|
||||
# Generated documents
|
||||
set(APIDOCS
|
||||
macros.rst
|
||||
enums.rst
|
||||
types.rst
|
||||
nghttp2_check_header_name.rst
|
||||
nghttp2_check_header_value.rst
|
||||
nghttp2_hd_deflate_bound.rst
|
||||
nghttp2_hd_deflate_change_table_size.rst
|
||||
nghttp2_hd_deflate_del.rst
|
||||
nghttp2_hd_deflate_get_dynamic_table_size.rst
|
||||
nghttp2_hd_deflate_get_max_dynamic_table_size.rst
|
||||
nghttp2_hd_deflate_get_num_table_entries.rst
|
||||
nghttp2_hd_deflate_get_table_entry.rst
|
||||
nghttp2_hd_deflate_hd.rst
|
||||
nghttp2_hd_deflate_hd_vec.rst
|
||||
nghttp2_hd_deflate_new.rst
|
||||
nghttp2_hd_deflate_new2.rst
|
||||
nghttp2_hd_inflate_change_table_size.rst
|
||||
nghttp2_hd_inflate_del.rst
|
||||
nghttp2_hd_inflate_end_headers.rst
|
||||
nghttp2_hd_inflate_get_dynamic_table_size.rst
|
||||
nghttp2_hd_inflate_get_max_dynamic_table_size.rst
|
||||
nghttp2_hd_inflate_get_num_table_entries.rst
|
||||
nghttp2_hd_inflate_get_table_entry.rst
|
||||
nghttp2_hd_inflate_hd.rst
|
||||
nghttp2_hd_inflate_hd2.rst
|
||||
nghttp2_hd_inflate_new.rst
|
||||
nghttp2_hd_inflate_new2.rst
|
||||
nghttp2_http2_strerror.rst
|
||||
nghttp2_is_fatal.rst
|
||||
nghttp2_nv_compare_name.rst
|
||||
nghttp2_option_del.rst
|
||||
nghttp2_option_new.rst
|
||||
nghttp2_option_set_builtin_recv_extension_type.rst
|
||||
nghttp2_option_set_max_deflate_dynamic_table_size.rst
|
||||
nghttp2_option_set_max_reserved_remote_streams.rst
|
||||
nghttp2_option_set_max_send_header_block_length.rst
|
||||
nghttp2_option_set_no_auto_ping_ack.rst
|
||||
nghttp2_option_set_no_auto_window_update.rst
|
||||
nghttp2_option_set_no_http_messaging.rst
|
||||
nghttp2_option_set_no_recv_client_magic.rst
|
||||
nghttp2_option_set_peer_max_concurrent_streams.rst
|
||||
nghttp2_option_set_user_recv_extension_type.rst
|
||||
nghttp2_pack_settings_payload.rst
|
||||
nghttp2_priority_spec_check_default.rst
|
||||
nghttp2_priority_spec_default_init.rst
|
||||
nghttp2_priority_spec_init.rst
|
||||
nghttp2_rcbuf_decref.rst
|
||||
nghttp2_rcbuf_get_buf.rst
|
||||
nghttp2_rcbuf_incref.rst
|
||||
nghttp2_select_next_protocol.rst
|
||||
nghttp2_session_callbacks_del.rst
|
||||
nghttp2_session_callbacks_new.rst
|
||||
nghttp2_session_callbacks_set_before_frame_send_callback.rst
|
||||
nghttp2_session_callbacks_set_data_source_read_length_callback.rst
|
||||
nghttp2_session_callbacks_set_error_callback.rst
|
||||
nghttp2_session_callbacks_set_on_begin_frame_callback.rst
|
||||
nghttp2_session_callbacks_set_on_begin_headers_callback.rst
|
||||
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst
|
||||
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst
|
||||
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst
|
||||
nghttp2_session_callbacks_set_on_frame_recv_callback.rst
|
||||
nghttp2_session_callbacks_set_on_frame_send_callback.rst
|
||||
nghttp2_session_callbacks_set_on_header_callback.rst
|
||||
nghttp2_session_callbacks_set_on_header_callback2.rst
|
||||
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst
|
||||
nghttp2_session_callbacks_set_on_invalid_header_callback.rst
|
||||
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst
|
||||
nghttp2_session_callbacks_set_on_stream_close_callback.rst
|
||||
nghttp2_session_callbacks_set_pack_extension_callback.rst
|
||||
nghttp2_session_callbacks_set_recv_callback.rst
|
||||
nghttp2_session_callbacks_set_select_padding_callback.rst
|
||||
nghttp2_session_callbacks_set_send_callback.rst
|
||||
nghttp2_session_callbacks_set_send_data_callback.rst
|
||||
nghttp2_session_callbacks_set_unpack_extension_callback.rst
|
||||
nghttp2_session_change_stream_priority.rst
|
||||
nghttp2_session_check_request_allowed.rst
|
||||
nghttp2_session_check_server_session.rst
|
||||
nghttp2_session_client_new.rst
|
||||
nghttp2_session_client_new2.rst
|
||||
nghttp2_session_client_new3.rst
|
||||
nghttp2_session_consume.rst
|
||||
nghttp2_session_consume_connection.rst
|
||||
nghttp2_session_consume_stream.rst
|
||||
nghttp2_session_create_idle_stream.rst
|
||||
nghttp2_session_del.rst
|
||||
nghttp2_session_find_stream.rst
|
||||
nghttp2_session_get_effective_local_window_size.rst
|
||||
nghttp2_session_get_effective_recv_data_length.rst
|
||||
nghttp2_session_get_hd_deflate_dynamic_table_size.rst
|
||||
nghttp2_session_get_hd_inflate_dynamic_table_size.rst
|
||||
nghttp2_session_get_last_proc_stream_id.rst
|
||||
nghttp2_session_get_local_settings.rst
|
||||
nghttp2_session_get_local_window_size.rst
|
||||
nghttp2_session_get_next_stream_id.rst
|
||||
nghttp2_session_get_outbound_queue_size.rst
|
||||
nghttp2_session_get_remote_settings.rst
|
||||
nghttp2_session_get_remote_window_size.rst
|
||||
nghttp2_session_get_root_stream.rst
|
||||
nghttp2_session_get_stream_effective_local_window_size.rst
|
||||
nghttp2_session_get_stream_effective_recv_data_length.rst
|
||||
nghttp2_session_get_stream_local_close.rst
|
||||
nghttp2_session_get_stream_local_window_size.rst
|
||||
nghttp2_session_get_stream_remote_close.rst
|
||||
nghttp2_session_get_stream_remote_window_size.rst
|
||||
nghttp2_session_get_stream_user_data.rst
|
||||
nghttp2_session_mem_recv.rst
|
||||
nghttp2_session_mem_send.rst
|
||||
nghttp2_session_recv.rst
|
||||
nghttp2_session_resume_data.rst
|
||||
nghttp2_session_send.rst
|
||||
nghttp2_session_server_new.rst
|
||||
nghttp2_session_server_new2.rst
|
||||
nghttp2_session_server_new3.rst
|
||||
nghttp2_session_set_local_window_size.rst
|
||||
nghttp2_session_set_next_stream_id.rst
|
||||
nghttp2_session_set_stream_user_data.rst
|
||||
nghttp2_session_terminate_session.rst
|
||||
nghttp2_session_terminate_session2.rst
|
||||
nghttp2_session_upgrade.rst
|
||||
nghttp2_session_upgrade2.rst
|
||||
nghttp2_session_want_read.rst
|
||||
nghttp2_session_want_write.rst
|
||||
nghttp2_set_debug_vprintf_callback.rst
|
||||
nghttp2_stream_get_first_child.rst
|
||||
nghttp2_stream_get_next_sibling.rst
|
||||
nghttp2_stream_get_parent.rst
|
||||
nghttp2_stream_get_previous_sibling.rst
|
||||
nghttp2_stream_get_state.rst
|
||||
nghttp2_stream_get_sum_dependency_weight.rst
|
||||
nghttp2_stream_get_weight.rst
|
||||
nghttp2_strerror.rst
|
||||
nghttp2_submit_altsvc.rst
|
||||
nghttp2_submit_data.rst
|
||||
nghttp2_submit_extension.rst
|
||||
nghttp2_submit_goaway.rst
|
||||
nghttp2_submit_headers.rst
|
||||
nghttp2_submit_ping.rst
|
||||
nghttp2_submit_priority.rst
|
||||
nghttp2_submit_push_promise.rst
|
||||
nghttp2_submit_request.rst
|
||||
nghttp2_submit_response.rst
|
||||
nghttp2_submit_rst_stream.rst
|
||||
nghttp2_submit_settings.rst
|
||||
nghttp2_submit_shutdown_notice.rst
|
||||
nghttp2_submit_trailer.rst
|
||||
nghttp2_submit_window_update.rst
|
||||
nghttp2_version.rst
|
||||
)
|
||||
|
||||
set(MAN_PAGES
|
||||
nghttp.1
|
||||
nghttpd.1
|
||||
nghttpx.1
|
||||
h2load.1
|
||||
)
|
||||
|
||||
# Other .rst files from the source tree that need to be copied
|
||||
# XXX move them to sources/ and create .in files?
|
||||
set(RST_FILES
|
||||
README.rst
|
||||
programmers-guide.rst
|
||||
nghttp.1.rst
|
||||
nghttpd.1.rst
|
||||
nghttpx.1.rst
|
||||
h2load.1.rst
|
||||
)
|
||||
|
||||
# XXX unused for now
|
||||
set(EXTRA_DIST
|
||||
mkapiref.py
|
||||
${RST_FILES}
|
||||
${APIDOCS}
|
||||
sources/index.rst
|
||||
sources/tutorial-client.rst
|
||||
sources/tutorial-server.rst
|
||||
sources/tutorial-hpack.rst
|
||||
sources/nghttpx-howto.rst
|
||||
sources/h2load-howto.rst
|
||||
sources/libnghttp2_asio.rst
|
||||
sources/python-apiref.rst
|
||||
sources/building-android-binary.rst
|
||||
sources/contribute.rst
|
||||
_exts/sphinxcontrib/LICENSE.rubydomain
|
||||
_exts/sphinxcontrib/__init__.py
|
||||
_exts/sphinxcontrib/rubydomain.py
|
||||
_themes/sphinx_rtd_theme/__init__.py
|
||||
_themes/sphinx_rtd_theme/breadcrumbs.html
|
||||
_themes/sphinx_rtd_theme/footer.html
|
||||
_themes/sphinx_rtd_theme/layout.html
|
||||
_themes/sphinx_rtd_theme/layout_old.html
|
||||
_themes/sphinx_rtd_theme/search.html
|
||||
_themes/sphinx_rtd_theme/searchbox.html
|
||||
_themes/sphinx_rtd_theme/static/css/badge_only.css
|
||||
_themes/sphinx_rtd_theme/static/css/theme.css
|
||||
_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
|
||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
|
||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
|
||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
|
||||
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
|
||||
_themes/sphinx_rtd_theme/static/js/theme.js
|
||||
_themes/sphinx_rtd_theme/theme.conf
|
||||
_themes/sphinx_rtd_theme/versions.html
|
||||
${MAN_PAGES}
|
||||
bash_completion/nghttp
|
||||
bash_completion/nghttpd
|
||||
bash_completion/nghttpx
|
||||
bash_completion/h2load
|
||||
)
|
||||
|
||||
# Based on Makefile for Sphinx documentation
|
||||
|
||||
# You can set these variables from the command line.
|
||||
set(SPHINXOPTS)
|
||||
set(SPHINXBUILD sphinx-build)
|
||||
set(PAPER)
|
||||
set(BUILDDIR manual)
|
||||
|
||||
# Internal variables.
|
||||
set(PAPEROPT_a4 -D latex_paper_size=a4)
|
||||
set(PAPEROPT_letter -D latex_paper_size=letter)
|
||||
set(ALLSPHINXOPTS -d ${BUILDDIR}/doctrees ${PAPEROPT_${PAPER}} ${SPHINXOPTS} .)
|
||||
|
||||
# "Please use `make <target>' where <target> is one of"
|
||||
# " html to make standalone HTML files"
|
||||
# " dirhtml to make HTML files named index.html in directories"
|
||||
# " singlehtml to make a single large HTML file"
|
||||
# " pickle to make pickle files"
|
||||
# " json to make JSON files"
|
||||
# " htmlhelp to make HTML files and a HTML help project"
|
||||
# " qthelp to make HTML files and a qthelp project"
|
||||
# " devhelp to make HTML files and a Devhelp project"
|
||||
# " epub to make an epub"
|
||||
# " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
# " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
# " text to make text files"
|
||||
# " man to make manual pages"
|
||||
# " changes to make an overview of all changed/added/deprecated items"
|
||||
# " linkcheck to check all external links for integrity"
|
||||
# " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
|
||||
# Copy files for out-of-tree builds
|
||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
set(RST_BUILD_FILES)
|
||||
foreach(rstfile IN LISTS RST_FILES)
|
||||
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${rstfile}")
|
||||
add_custom_command(OUTPUT "${outfile}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}" "${outfile}"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}"
|
||||
)
|
||||
list(APPEND RST_BUILD_FILES "${outfile}")
|
||||
endforeach()
|
||||
else()
|
||||
set(RST_BUILD_FILES "${RST_FILES}")
|
||||
endif()
|
||||
|
||||
set(apiref_SOURCES
|
||||
${CMAKE_BINARY_DIR}/lib/includes/nghttp2/nghttp2ver.h
|
||||
${CMAKE_SOURCE_DIR}/lib/includes/nghttp2/nghttp2.h
|
||||
)
|
||||
# Generates apiref.rst and other files
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
apiref.rst
|
||||
${APIDOCS}
|
||||
COMMAND
|
||||
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkapiref.py"
|
||||
apiref.rst macros.rst enums.rst types.rst .
|
||||
${apiref_SOURCES}
|
||||
DEPENDS
|
||||
${RST_BUILD_FILES}
|
||||
${apiref_SOURCES}
|
||||
)
|
||||
|
||||
|
||||
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${BUILDDIR}")
|
||||
|
||||
# Invokes sphinx-build and prints the given messages when completed
|
||||
function(sphinxbuild builder)
|
||||
set(echo_commands)
|
||||
foreach(message IN LISTS ARGN)
|
||||
list(APPEND echo_commands COMMAND ${CMAKE_COMMAND} -E echo "${message}")
|
||||
endforeach()
|
||||
add_custom_target(${builder}
|
||||
COMMAND "${SPHINXBUILD}" -b ${builder} ${ALLSPHINXOPTS} "${BUILDDIR}/${builder}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
${echo_commands}
|
||||
VERBATIM
|
||||
DEPENDS apiref.rst
|
||||
)
|
||||
endfunction()
|
||||
|
||||
foreach(builder html dirhtml singlehtml)
|
||||
sphinxbuild(${builder}
|
||||
"Build finished. The HTML pages are in ${BUILDDIR}/${builder}.")
|
||||
endforeach()
|
||||
sphinxbuild(pickle "Build finished; now you can process the pickle files.")
|
||||
sphinxbuild(json "Build finished; now you can process the JSON files.")
|
||||
sphinxbuild(htmlhelp
|
||||
"Build finished; now you can run HTML Help Workshop with the"
|
||||
".hhp project file in ${BUILDDIR}/htmlhelp."
|
||||
)
|
||||
sphinxbuild(qthelp
|
||||
"Build finished; now you can run \"qcollectiongenerator\" with the"
|
||||
".qhcp project file in ${BUILDDIR}/qthelp, like this:"
|
||||
"# qcollectiongenerator ${BUILDDIR}/qthelp/nghttp2.qhcp"
|
||||
"To view the help file:"
|
||||
"# assistant -collectionFile ${BUILDDIR}/qthelp/nghttp2.qhc"
|
||||
)
|
||||
sphinxbuild(devhelp
|
||||
"Build finished."
|
||||
"To view the help file:"
|
||||
"# mkdir -p ~/.local/share/devhelp/nghttp2"
|
||||
"# ln -s ${BUILDDIR}/devhelp ~/.local/share/devhelp/nghttp2"
|
||||
"# devhelp"
|
||||
)
|
||||
sphinxbuild(epub "Build finished. The epub file is in ${BUILDDIR}/epub.")
|
||||
sphinxbuild(latex
|
||||
"Build finished; the LaTeX files are in ${BUILDDIR}/latex."
|
||||
"Run `make' in that directory to run these through (pdf)latex"
|
||||
"(use `make latexpdf' here to do that automatically)."
|
||||
)
|
||||
|
||||
# Invoke the Makefile generated by sphinx
|
||||
add_custom_target(latexpdf
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "Running LaTeX files through pdflatex..."
|
||||
COMMAND make -C "${BUILDDIR}/latex" all-pdf
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "pdflatex finished; the PDF files are in ${BUILDDIR}/latex."
|
||||
DEPENDS latex
|
||||
)
|
||||
|
||||
sphinxbuild(text "Build finished. The text files are in ${BUILDDIR}/text.")
|
||||
sphinxbuild(man "Build finished. The manual pages are in ${BUILDDIR}/man.")
|
||||
sphinxbuild(changes "The overview file is in ${BUILDDIR}/changes.")
|
||||
sphinxbuild(linkcheck
|
||||
"Link check complete; look for any errors in the above output"
|
||||
"or in ${BUILDDIR}/linkcheck/output.txt."
|
||||
)
|
||||
sphinxbuild(doctest
|
||||
"Testing of doctests in the sources finished, look at the"
|
||||
"results in ${BUILDDIR}/doctest/output.txt."
|
||||
)
|
||||
|
||||
foreach(_man_page IN LISTS MAN_PAGES)
|
||||
install(FILES ${_man_page}
|
||||
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
|
||||
)
|
||||
endforeach()
|
||||
@@ -37,6 +37,7 @@ APIDOCS= \
|
||||
nghttp2_hd_deflate_get_num_table_entries.rst \
|
||||
nghttp2_hd_deflate_get_table_entry.rst \
|
||||
nghttp2_hd_deflate_hd.rst \
|
||||
nghttp2_hd_deflate_hd_vec.rst \
|
||||
nghttp2_hd_deflate_new.rst \
|
||||
nghttp2_hd_deflate_new2.rst \
|
||||
nghttp2_hd_inflate_change_table_size.rst \
|
||||
@@ -47,13 +48,19 @@ APIDOCS= \
|
||||
nghttp2_hd_inflate_get_num_table_entries.rst \
|
||||
nghttp2_hd_inflate_get_table_entry.rst \
|
||||
nghttp2_hd_inflate_hd.rst \
|
||||
nghttp2_hd_inflate_hd2.rst \
|
||||
nghttp2_hd_inflate_new.rst \
|
||||
nghttp2_hd_inflate_new2.rst \
|
||||
nghttp2_http2_strerror.rst \
|
||||
nghttp2_is_fatal.rst \
|
||||
nghttp2_nv_compare_name.rst \
|
||||
nghttp2_option_del.rst \
|
||||
nghttp2_option_new.rst \
|
||||
nghttp2_option_set_builtin_recv_extension_type.rst \
|
||||
nghttp2_option_set_max_deflate_dynamic_table_size.rst \
|
||||
nghttp2_option_set_max_reserved_remote_streams.rst \
|
||||
nghttp2_option_set_max_send_header_block_length.rst \
|
||||
nghttp2_option_set_no_auto_ping_ack.rst \
|
||||
nghttp2_option_set_no_auto_window_update.rst \
|
||||
nghttp2_option_set_no_http_messaging.rst \
|
||||
nghttp2_option_set_no_recv_client_magic.rst \
|
||||
@@ -63,11 +70,15 @@ APIDOCS= \
|
||||
nghttp2_priority_spec_check_default.rst \
|
||||
nghttp2_priority_spec_default_init.rst \
|
||||
nghttp2_priority_spec_init.rst \
|
||||
nghttp2_rcbuf_decref.rst \
|
||||
nghttp2_rcbuf_get_buf.rst \
|
||||
nghttp2_rcbuf_incref.rst \
|
||||
nghttp2_select_next_protocol.rst \
|
||||
nghttp2_session_callbacks_del.rst \
|
||||
nghttp2_session_callbacks_new.rst \
|
||||
nghttp2_session_callbacks_set_before_frame_send_callback.rst \
|
||||
nghttp2_session_callbacks_set_data_source_read_length_callback.rst \
|
||||
nghttp2_session_callbacks_set_error_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_begin_frame_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \
|
||||
@@ -76,7 +87,10 @@ APIDOCS= \
|
||||
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_header_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_header_callback2.rst \
|
||||
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_invalid_header_callback.rst \
|
||||
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst \
|
||||
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
||||
nghttp2_session_callbacks_set_pack_extension_callback.rst \
|
||||
nghttp2_session_callbacks_set_recv_callback.rst \
|
||||
@@ -84,6 +98,9 @@ APIDOCS= \
|
||||
nghttp2_session_callbacks_set_send_callback.rst \
|
||||
nghttp2_session_callbacks_set_send_data_callback.rst \
|
||||
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
|
||||
nghttp2_session_change_stream_priority.rst \
|
||||
nghttp2_session_check_request_allowed.rst \
|
||||
nghttp2_session_check_server_session.rst \
|
||||
nghttp2_session_client_new.rst \
|
||||
nghttp2_session_client_new2.rst \
|
||||
nghttp2_session_client_new3.rst \
|
||||
@@ -95,7 +112,11 @@ APIDOCS= \
|
||||
nghttp2_session_find_stream.rst \
|
||||
nghttp2_session_get_effective_local_window_size.rst \
|
||||
nghttp2_session_get_effective_recv_data_length.rst \
|
||||
nghttp2_session_get_hd_deflate_dynamic_table_size.rst \
|
||||
nghttp2_session_get_hd_inflate_dynamic_table_size.rst \
|
||||
nghttp2_session_get_last_proc_stream_id.rst \
|
||||
nghttp2_session_get_local_settings.rst \
|
||||
nghttp2_session_get_local_window_size.rst \
|
||||
nghttp2_session_get_next_stream_id.rst \
|
||||
nghttp2_session_get_outbound_queue_size.rst \
|
||||
nghttp2_session_get_remote_settings.rst \
|
||||
@@ -104,20 +125,19 @@ APIDOCS= \
|
||||
nghttp2_session_get_stream_effective_local_window_size.rst \
|
||||
nghttp2_session_get_stream_effective_recv_data_length.rst \
|
||||
nghttp2_session_get_stream_local_close.rst \
|
||||
nghttp2_session_get_stream_local_window_size.rst \
|
||||
nghttp2_session_get_stream_remote_close.rst \
|
||||
nghttp2_session_get_stream_remote_window_size.rst \
|
||||
nghttp2_session_get_stream_user_data.rst \
|
||||
nghttp2_session_mem_recv.rst \
|
||||
nghttp2_session_mem_send.rst \
|
||||
nghttp2_session_recv.rst \
|
||||
nghttp2_session_change_stream_priority.rst \
|
||||
nghttp2_session_check_request_allowed.rst \
|
||||
nghttp2_session_check_server_session.rst \
|
||||
nghttp2_session_resume_data.rst \
|
||||
nghttp2_session_send.rst \
|
||||
nghttp2_session_server_new.rst \
|
||||
nghttp2_session_server_new2.rst \
|
||||
nghttp2_session_server_new3.rst \
|
||||
nghttp2_session_set_local_window_size.rst \
|
||||
nghttp2_session_set_next_stream_id.rst \
|
||||
nghttp2_session_set_stream_user_data.rst \
|
||||
nghttp2_session_terminate_session.rst \
|
||||
@@ -126,6 +146,7 @@ APIDOCS= \
|
||||
nghttp2_session_upgrade2.rst \
|
||||
nghttp2_session_want_read.rst \
|
||||
nghttp2_session_want_write.rst \
|
||||
nghttp2_set_debug_vprintf_callback.rst \
|
||||
nghttp2_stream_get_first_child.rst \
|
||||
nghttp2_stream_get_next_sibling.rst \
|
||||
nghttp2_stream_get_parent.rst \
|
||||
@@ -134,6 +155,7 @@ APIDOCS= \
|
||||
nghttp2_stream_get_sum_dependency_weight.rst \
|
||||
nghttp2_stream_get_weight.rst \
|
||||
nghttp2_strerror.rst \
|
||||
nghttp2_submit_altsvc.rst \
|
||||
nghttp2_submit_data.rst \
|
||||
nghttp2_submit_extension.rst \
|
||||
nghttp2_submit_goaway.rst \
|
||||
@@ -159,6 +181,7 @@ RST_FILES = \
|
||||
h2load.1.rst
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
mkapiref.py \
|
||||
$(RST_FILES) \
|
||||
$(APIDOCS) \
|
||||
|
||||
@@ -15,6 +15,7 @@ from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx import version_info
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.locale import l_, _
|
||||
from sphinx.domains import Domain, ObjType, Index
|
||||
@@ -231,8 +232,8 @@ class RubyObject(ObjectDescription):
|
||||
|
||||
indextext = self.get_index_text(modname, name_cls)
|
||||
if indextext:
|
||||
self.indexnode['entries'].append(('single', indextext,
|
||||
fullname, fullname))
|
||||
self.indexnode['entries'].append(
|
||||
_make_index('single', indextext, fullname, fullname))
|
||||
|
||||
def before_content(self):
|
||||
# needed for automatic qualification of members (reset in subclasses)
|
||||
@@ -415,11 +416,19 @@ class RubyModule(Directive):
|
||||
# modindex currently
|
||||
if not noindex:
|
||||
indextext = _('%s (module)') % modname
|
||||
inode = addnodes.index(entries=[('single', indextext,
|
||||
'module-' + modname, modname)])
|
||||
inode = addnodes.index(entries=[_make_index(
|
||||
'single', indextext, 'module-' + modname, modname)])
|
||||
ret.append(inode)
|
||||
return ret
|
||||
|
||||
def _make_index(entrytype, entryname, target, ignored, key=None):
|
||||
# Sphinx 1.4 introduced backward incompatible changes, it now
|
||||
# requires 5 tuples. Last one is categorization key. See
|
||||
# http://www.sphinx-doc.org/en/stable/extdev/nodes.html#sphinx.addnodes.index
|
||||
if version_info >= (1, 4, 0, '', 0):
|
||||
return (entrytype, entryname, target, ignored, key)
|
||||
else:
|
||||
return (entrytype, entryname, target, ignored)
|
||||
|
||||
class RubyCurrentModule(Directive):
|
||||
"""
|
||||
|
||||
1
doc/_themes/sphinx_rtd_theme/layout.html
vendored
1
doc/_themes/sphinx_rtd_theme/layout.html
vendored
@@ -81,6 +81,7 @@
|
||||
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
{% block extrabody %} {% endblock %}
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
{# SIDE NAV, TOGGLES ON MOBILE #}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@ _h2load()
|
||||
_get_comp_words_by_ref cur prev
|
||||
case $cur in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --requests --base-uri --h1 --threads --npn-list --rate-period --data --version --connection-inactivity-timeout --timing-script-file --max-concurrent-streams --connection-active-timeout --input-file --header --window-bits --help ' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --header-table-size --requests --base-uri --h1 --threads --npn-list --rate-period --data --version --connection-inactivity-timeout --timing-script-file --encoder-header-table-size --max-concurrent-streams --connection-active-timeout --input-file --help --window-bits --header ' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
@@ -8,7 +8,7 @@ _nghttp()
|
||||
_get_comp_words_by_ref cur prev
|
||||
case $cur in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W '--no-push --verbose --no-dep --get-assets --har --header-table-size --multiply --padding --hexdump --max-concurrent-streams --continuation --connection-window-bits --peer-max-concurrent-streams --timeout --data --no-content-length --version --color --cert --upgrade --remote-name --trailer --weight --help --key --null-out --window-bits --stat --header ' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W '--no-push --verbose --no-dep --get-assets --har --header-table-size --multiply --encoder-header-table-size --padding --hexdump --max-concurrent-streams --continuation --connection-window-bits --peer-max-concurrent-streams --timeout --data --no-content-length --version --color --cert --upgrade --remote-name --trailer --weight --help --key --null-out --window-bits --expect-continue --stat --header ' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
@@ -8,7 +8,7 @@ _nghttpd()
|
||||
_get_comp_words_by_ref cur prev
|
||||
case $cur in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --padding --hexdump --max-concurrent-streams --no-tls --connection-window-bits --mime-types-file --no-content-length --workers --version --color --early-response --dh-param-file --trailer --address --window-bits --verify-client --help ' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --encoder-header-table-size --padding --hexdump --max-concurrent-streams --no-tls --connection-window-bits --mime-types-file --no-content-length --workers --version --color --early-response --dh-param-file --trailer --address --window-bits --verify-client --help ' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
@@ -8,7 +8,7 @@ _nghttpx()
|
||||
_get_comp_words_by_ref cur prev
|
||||
case $cur in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W '--worker-read-rate --frontend-no-tls --frontend-http2-dump-response-header --backend-http1-connections-per-frontend --tls-ticket-key-file --verify-client-cacert --include --max-response-header-fields --backend-request-buffer --max-request-header-fields --backend-http2-connection-window-bits --conf --worker-write-burst --npn-list --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --stream-read-timeout --tls-ticket-key-memcached --forwarded-for --accesslog-syslog --frontend-http2-read-timeout --listener-disable-timeout --frontend-http2-connection-window-bits --ciphers --strip-incoming-x-forwarded-for --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --backend-http1-connections-per-host --rlimit-nofile --tls-dyn-rec-warmup-threshold --tls-ticket-key-memcached-cert-file --ocsp-update-interval --forwarded-by --tls-session-cache-memcached-private-key-file --backend-write-timeout --client --tls-ticket-key-memcached-max-retry --http2-no-cookie-crumbling --worker-read-burst --client-proxy --http2-bridge --accesslog-format --errorlog-syslog --request-header-field-buffer --errorlog-file --http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend --insecure --log-level --host-rewrite --tls-session-cache-memcached-tls --tls-proto-list --backend-http2-connections-per-worker --tls-ticket-key-memcached-interval --dh-param-file --worker-frontend-connections --backend-http1-tls --syslog-facility --fastopen --no-location-rewrite --tls-ticket-key-memcached-tls --tls-session-cache-memcached --no-ocsp --backend-response-buffer --workers --add-forwarded --frontend-http2-window-bits --worker-write-rate --add-request-header --backend-tls-sni-field --subcert --help --frontend-frame-debug --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --user --add-x-forwarded-for --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --no-server-push --backend-http2-window-bits --response-header-field-buffer --tls-ticket-key-memcached-address-family --padding --tls-session-cache-memcached-address-family --stream-write-timeout --cacert --tls-ticket-key-memcached-private-key-file --backend-address-family --version --add-response-header --backend-read-timeout --frontend --accesslog-file --http2-proxy --backend-no-tls --client-private-key-file --client-cert-file --accept-proxy-protocol --tls-dyn-rec-idle-timeout --verify-client --read-rate --strip-incoming-forwarded ' -- "$cur" ) )
|
||||
COMPREPLY=( $( compgen -W '--worker-read-rate --include --frontend-http2-dump-response-header --tls-ticket-key-file --verify-client-cacert --max-response-header-fields --backend-http2-window-size --backend-request-buffer --max-request-header-fields --fastopen --tls-ticket-key-memcached --conf --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --stream-read-timeout --backend-connect-timeout --forwarded-for --accesslog-syslog --frontend-http2-read-timeout --listener-disable-timeout --ciphers --strip-incoming-x-forwarded-for --no-server-rewrite --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --rlimit-nofile --tls-ticket-key-memcached-cert-file --ocsp-update-interval --forwarded-by --tls-session-cache-memcached-private-key-file --error-page --backend-write-timeout --tls-dyn-rec-warmup-threshold --tls-ticket-key-memcached-max-retry --frontend-http2-window-size --http2-no-cookie-crumbling --worker-read-burst --dh-param-file --accesslog-format --errorlog-syslog --request-header-field-buffer --api-max-request-body --frontend-http2-decoder-dynamic-table-size --errorlog-file --frontend-http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend --server-name --insecure --backend-max-backoff --log-level --host-rewrite --tls-proto-list --tls-ticket-key-memcached-interval --frontend-http2-setting-timeout --frontend-http2-connection-window-size --worker-frontend-connections --syslog-facility --no-server-push --no-location-rewrite --tls-session-cache-memcached --no-ocsp --frontend-http2-encoder-dynamic-table-size --workers --add-forwarded --worker-write-rate --add-request-header --backend-http2-settings-timeout --subcert --ecdh-curves --no-kqueue --help --frontend-frame-debug --tls-sct-dir --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --backend-http2-decoder-dynamic-table-size --user --add-x-forwarded-for --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --backend-connections-per-host --response-header-field-buffer --tls-ticket-key-memcached-address-family --padding --tls-session-cache-memcached-address-family --stream-write-timeout --cacert --tls-ticket-key-memcached-private-key-file --backend-address-family --backend-http2-connection-window-size --version --add-response-header --backend-read-timeout --frontend-http2-optimize-window-size --frontend --accesslog-file --http2-proxy --backend-http2-encoder-dynamic-table-size --client-private-key-file --client-cert-file --accept-proxy-protocol --tls-dyn-rec-idle-timeout --frontend-http2-optimize-write-buffer-size --verify-client --backend-response-buffer --read-rate --backend-connections-per-frontend --strip-incoming-forwarded ' -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
_filedir
|
||||
|
||||
30
doc/h2load.1
30
doc/h2load.1
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "H2LOAD" "1" "February 25, 2016" "1.8.0" "nghttp2"
|
||||
.TH "H2LOAD" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
|
||||
.SH NAME
|
||||
h2load \- HTTP/2 benchmarking tool
|
||||
.
|
||||
@@ -138,7 +138,9 @@ Default: \fBh2c\fP
|
||||
.TP
|
||||
.B \-d, \-\-data=<PATH>
|
||||
Post FILE to server. The request method is changed to
|
||||
POST.
|
||||
POST. For http/1.1 connection, if \fI\%\-d\fP is used, the
|
||||
maximum number of in\-flight pipelined requests is set to
|
||||
1.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -149,7 +151,7 @@ representing the number of connections to be made per
|
||||
rate period. The maximum number of connections to be
|
||||
made is given in \fI\%\-c\fP option. This rate will be
|
||||
distributed among threads as evenly as possible. For
|
||||
example, with \fB\-t2\fP and \fB\-r4\fP, each thread gets 2
|
||||
example, with \fI\%\-t\fP2 and \fI\%\-r\fP4, each thread gets 2
|
||||
connections per period. When the rate is 0, the program
|
||||
will run as it normally does, creating connections at
|
||||
whatever variable rate it wants. The default value for
|
||||
@@ -240,6 +242,23 @@ http/1.1 for both http and https URI.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-header\-table\-size=<SIZE>
|
||||
Specify decoder header table size.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-encoder\-header\-table\-size=<SIZE>
|
||||
Specify encoder header table size. The decoder (server)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which server specified.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-v, \-\-verbose
|
||||
Output debug information.
|
||||
.UNINDENT
|
||||
@@ -254,6 +273,9 @@ Display version information and exit.
|
||||
Display this help and exit.
|
||||
.UNINDENT
|
||||
.sp
|
||||
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
||||
10 * 1024). Units are K, M and G (powers of 1024).
|
||||
.sp
|
||||
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
||||
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
||||
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
||||
@@ -412,7 +434,7 @@ performance. To set smaller flow control window, use \fI\%\-w\fP and
|
||||
window size described in HTTP/2 and SPDY protocol specification.
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fInghttpx(1)\fP
|
||||
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -74,14 +74,14 @@ OPTIONS
|
||||
.. option:: -w, --window-bits=<N>
|
||||
|
||||
Sets the stream level initial window size to (2\*\*<N>)-1.
|
||||
For SPDY, 2**<N> is used instead.
|
||||
For SPDY, 2\*\*<N> is used instead.
|
||||
|
||||
Default: ``30``
|
||||
|
||||
.. option:: -W, --connection-window-bits=<N>
|
||||
|
||||
Sets the connection level initial window size to
|
||||
(2**<N>)-1. For SPDY, if <N> is strictly less than 16,
|
||||
(2\*\*<N>)-1. For SPDY, if <N> is strictly less than 16,
|
||||
this option is ignored. Otherwise 2\*\*<N> is used for
|
||||
SPDY.
|
||||
|
||||
@@ -108,7 +108,9 @@ OPTIONS
|
||||
.. option:: -d, --data=<PATH>
|
||||
|
||||
Post FILE to server. The request method is changed to
|
||||
POST.
|
||||
POST. For http/1.1 connection, if :option:`-d` is used, the
|
||||
maximum number of in-flight pipelined requests is set to
|
||||
1.
|
||||
|
||||
.. option:: -r, --rate=<N>
|
||||
|
||||
@@ -118,7 +120,7 @@ OPTIONS
|
||||
rate period. The maximum number of connections to be
|
||||
made is given in :option:`-c` option. This rate will be
|
||||
distributed among threads as evenly as possible. For
|
||||
example, with :option:`-t2` and :option:`\-r4`, each thread gets 2
|
||||
example, with :option:`-t`\2 and :option:`-r`\4, each thread gets 2
|
||||
connections per period. When the rate is 0, the program
|
||||
will run as it normally does, creating connections at
|
||||
whatever variable rate it wants. The default value for
|
||||
@@ -200,6 +202,21 @@ OPTIONS
|
||||
:option:`--no-tls-proto`\=http/1.1, which effectively force
|
||||
http/1.1 for both http and https URI.
|
||||
|
||||
.. option:: --header-table-size=<SIZE>
|
||||
|
||||
Specify decoder header table size.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --encoder-header-table-size=<SIZE>
|
||||
|
||||
Specify encoder header table size. The decoder (server)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which server specified.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: -v, --verbose
|
||||
|
||||
Output debug information.
|
||||
@@ -214,6 +231,9 @@ OPTIONS
|
||||
|
||||
|
||||
|
||||
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
||||
10 * 1024). Units are K, M and G (powers of 1024).
|
||||
|
||||
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
||||
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
||||
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
||||
|
||||
29
doc/nghttp.1
29
doc/nghttp.1
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTP" "1" "February 25, 2016" "1.8.0" "nghttp2"
|
||||
.TH "NGHTTP" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttp \- HTTP/2 client
|
||||
.
|
||||
@@ -142,10 +142,13 @@ HTTP upgrade request is performed with OPTIONS method.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-p, \-\-weight=<WEIGHT>
|
||||
Sets priority group weight. The valid value range is
|
||||
Sets weight of given URI. This option can be used
|
||||
multiple times, and N\-th \fI\%\-p\fP option sets weight of N\-th
|
||||
URI in the command line. If the number of \fI\%\-p\fP option is
|
||||
less than the number of URI, the last \fI\%\-p\fP option value is
|
||||
repeated. If there is no \fI\%\-p\fP option, default weight, 16,
|
||||
is assumed. The valid value range is
|
||||
[1, 256], inclusive.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -167,6 +170,14 @@ multiple header table size change.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-encoder\-header\-table\-size=<SIZE>
|
||||
Specify encoder header table size. The decoder (server)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which server specified.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-b, \-\-padding=<N>
|
||||
Add at most <N> bytes to a frame payload as padding.
|
||||
Specify 0 to disable padding.
|
||||
@@ -217,6 +228,14 @@ accepts.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-expect\-continue
|
||||
Perform an Expect/Continue handshake: wait to send DATA
|
||||
(up to a short timeout) until the server sends a 100
|
||||
Continue interim response. This option is ignored unless
|
||||
combined with the \fI\%\-d\fP option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-version
|
||||
Display version information and exit.
|
||||
.UNINDENT
|
||||
@@ -292,7 +311,7 @@ stream 11 with the weight 12. The other resources (e.g., icon) depend
|
||||
on stream 11 with the weight 2.
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fInghttpd(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
||||
\fBnghttpd(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -107,11 +107,14 @@ OPTIONS
|
||||
|
||||
.. option:: -p, --weight=<WEIGHT>
|
||||
|
||||
Sets priority group weight. The valid value range is
|
||||
Sets weight of given URI. This option can be used
|
||||
multiple times, and N-th :option:`-p` option sets weight of N-th
|
||||
URI in the command line. If the number of :option:`-p` option is
|
||||
less than the number of URI, the last :option:`-p` option value is
|
||||
repeated. If there is no :option:`-p` option, default weight, 16,
|
||||
is assumed. The valid value range is
|
||||
[1, 256], inclusive.
|
||||
|
||||
Default: ``16``
|
||||
|
||||
.. option:: -M, --peer-max-concurrent-streams=<N>
|
||||
|
||||
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||
@@ -128,6 +131,13 @@ OPTIONS
|
||||
frame payload before the last value, to simulate
|
||||
multiple header table size change.
|
||||
|
||||
.. option:: --encoder-header-table-size=<SIZE>
|
||||
|
||||
Specify encoder header table size. The decoder (server)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which server specified.
|
||||
|
||||
.. option:: -b, --padding=<N>
|
||||
|
||||
Add at most <N> bytes to a frame payload as padding.
|
||||
@@ -169,6 +179,13 @@ OPTIONS
|
||||
The number of concurrent pushed streams this client
|
||||
accepts.
|
||||
|
||||
.. option:: --expect-continue
|
||||
|
||||
Perform an Expect/Continue handshake: wait to send DATA
|
||||
(up to a short timeout) until the server sends a 100
|
||||
Continue interim response. This option is ignored unless
|
||||
combined with the :option:`-d` option.
|
||||
|
||||
.. option:: --version
|
||||
|
||||
Display version information and exit.
|
||||
@@ -201,7 +218,9 @@ implementation.
|
||||
|
||||
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
||||
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
||||
tree::
|
||||
tree:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
+-----+
|
||||
|id=0 |
|
||||
|
||||
@@ -12,7 +12,9 @@ implementation.
|
||||
|
||||
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
||||
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
||||
tree::
|
||||
tree:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
+-----+
|
||||
|id=0 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPD" "1" "February 25, 2016" "1.8.0" "nghttp2"
|
||||
.TH "NGHTTPD" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpd \- HTTP/2 server
|
||||
.
|
||||
@@ -99,6 +99,14 @@ Specify decoder header table size.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-encoder\-header\-table\-size=<SIZE>
|
||||
Specify encoder header table size. The decoder (client)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which client specified.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-color
|
||||
Force colored log output.
|
||||
.UNINDENT
|
||||
@@ -209,7 +217,7 @@ The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
||||
10 * 1024). Units are K, M and G (powers of 1024).
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fInghttp(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
||||
\fBnghttp(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -70,6 +70,13 @@ OPTIONS
|
||||
|
||||
Specify decoder header table size.
|
||||
|
||||
.. option:: --encoder-header-table-size=<SIZE>
|
||||
|
||||
Specify encoder header table size. The decoder (client)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which client specified.
|
||||
|
||||
.. option:: --color
|
||||
|
||||
Force colored log output.
|
||||
|
||||
657
doc/nghttpx.1
657
doc/nghttpx.1
@@ -1,6 +1,6 @@
|
||||
.\" Man page generated from reStructuredText.
|
||||
.
|
||||
.TH "NGHTTPX" "1" "February 25, 2016" "1.8.0" "nghttp2"
|
||||
.TH "NGHTTPX" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
|
||||
.SH NAME
|
||||
nghttpx \- HTTP/2 proxy
|
||||
.
|
||||
@@ -39,15 +39,15 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B <PRIVATE_KEY>
|
||||
Set path to server\(aqs private key. Required unless \fI\%\-p\fP,
|
||||
\fI\%\-\-client\fP or \fI\%\-\-frontend\-no\-tls\fP are given.
|
||||
Set path to server\(aqs private key. Required unless
|
||||
"no\-tls" parameter is used in \fI\%\-\-frontend\fP option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B <CERT>
|
||||
Set path to server\(aqs certificate. Required unless \fI\%\-p\fP,
|
||||
\fI\%\-\-client\fP or \fI\%\-\-frontend\-no\-tls\fP are given. To make OCSP
|
||||
stapling work, this must be absolute path.
|
||||
Set path to server\(aqs certificate. Required unless
|
||||
"no\-tls" parameter is used in \fI\%\-\-frontend\fP option. To
|
||||
make OCSP stapling work, this must be an absolute path.
|
||||
.UNINDENT
|
||||
.SH OPTIONS
|
||||
.sp
|
||||
@@ -55,38 +55,46 @@ The options are categorized into several groups.
|
||||
.SS Connections
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;<PATTERN>[:...]]
|
||||
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
|
||||
Set backend host and port. The multiple backend
|
||||
addresses are accepted by repeating this option. UNIX
|
||||
domain socket can be specified by prefixing path name
|
||||
with "unix:" (e.g., unix:/var/run/backend.sock).
|
||||
.sp
|
||||
Optionally, if <PATTERN>s are given, the backend address
|
||||
is only used if request matches the pattern. If \fI\%\-s\fP or
|
||||
\fI\%\-p\fP is used, <PATTERN>s are ignored. The pattern
|
||||
matching is closely designed to ServeMux in net/http
|
||||
package of Go programming language. <PATTERN> consists
|
||||
of path, host + path or just host. The path must start
|
||||
with "\fI/\fP". If it ends with "\fI/\fP", it matches all request
|
||||
path in its subtree. To deal with the request to the
|
||||
directory without trailing slash, the path which ends
|
||||
with "\fI/\fP" also matches the request path which only lacks
|
||||
trailing \(aq\fI/\fP\(aq (e.g., path "\fI/foo/\fP" matches request path
|
||||
"\fI/foo\fP"). If it does not end with "\fI/\fP", it performs exact
|
||||
match against the request path. If host is given, it
|
||||
performs exact match against the request host. If host
|
||||
alone is given, "\fI/\fP" is appended to it, so that it
|
||||
matches all request paths under the host (e.g.,
|
||||
specifying "nghttp2.org" equals to "nghttp2.org/").
|
||||
is only used if request matches the pattern. If
|
||||
\fI\%\-\-http2\-proxy\fP is used, <PATTERN>s are ignored. The
|
||||
pattern matching is closely designed to ServeMux in
|
||||
net/http package of Go programming language. <PATTERN>
|
||||
consists of path, host + path or just host. The path
|
||||
must start with "\fI/\fP". If it ends with "\fI/\fP", it matches
|
||||
all request path in its subtree. To deal with the
|
||||
request to the directory without trailing slash, the
|
||||
path which ends with "\fI/\fP" also matches the request path
|
||||
which only lacks trailing \(aq\fI/\fP\(aq (e.g., path "\fI/foo/\fP"
|
||||
matches request path "\fI/foo\fP"). If it does not end with
|
||||
"\fI/\fP", it performs exact match against the request path.
|
||||
If host is given, it performs exact match against the
|
||||
request host. If host alone is given, "\fI/\fP" is appended
|
||||
to it, so that it matches all request paths under the
|
||||
host (e.g., specifying "nghttp2.org" equals to
|
||||
"nghttp2.org/").
|
||||
.sp
|
||||
Patterns with host take precedence over patterns with
|
||||
just path. Then, longer patterns take precedence over
|
||||
shorter ones, breaking a tie by the order of the
|
||||
appearance in the configuration.
|
||||
shorter ones.
|
||||
.sp
|
||||
If <PATTERN> is omitted, "\fI/\fP" is used as pattern, which
|
||||
matches all request paths (catch\-all pattern). The
|
||||
catch\-all backend must be given.
|
||||
Host can include "*" in the left most position to
|
||||
indicate wildcard match (only suffix match is done).
|
||||
The "*" must match at least one character. For example,
|
||||
host pattern "*.nghttp2.org" matches against
|
||||
"www.nghttp2.org" and "git.ngttp2.org", but does not
|
||||
match against "nghttp2.org". The exact hosts match
|
||||
takes precedence over the wildcard hosts match.
|
||||
.sp
|
||||
If <PATTERN> is omitted or empty string, "\fI/\fP" is used as
|
||||
pattern, which matches all request paths (catch\-all
|
||||
pattern). The catch\-all backend must be given.
|
||||
.sp
|
||||
When doing a match, nghttpx made some normalization to
|
||||
pattern, request host and path. For host part, they are
|
||||
@@ -109,6 +117,64 @@ and \fI\%\-b\fP\(aq127.0.0.1,8080;www.nghttp2.org\(aq.
|
||||
The backend addresses sharing same <PATTERN> are grouped
|
||||
together forming load balancing group.
|
||||
.sp
|
||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||
The parameters are delimited by ";". The available
|
||||
parameters are: "proto=<PROTO>", "tls",
|
||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
|
||||
"affinity=<METHOD>". The parameter consists of keyword,
|
||||
and optionally followed by "=" and value. For example,
|
||||
the parameter "proto=h2" consists of the keyword "proto"
|
||||
and value "h2". The parameter "tls" consists of the
|
||||
keyword "tls" without value. Each parameter is
|
||||
described as follows.
|
||||
.sp
|
||||
The backend application protocol can be specified using
|
||||
optional "proto" parameter, and in the form of
|
||||
"proto=<PROTO>". <PROTO> should be one of the following
|
||||
list without quotes: "h2", "http/1.1". The default
|
||||
value of <PROTO> is "http/1.1". Note that usually "h2"
|
||||
refers to HTTP/2 over TLS. But in this option, it may
|
||||
mean HTTP/2 over cleartext TCP unless "tls" keyword is
|
||||
used (see below).
|
||||
.sp
|
||||
TLS can be enabled by specifying optional "tls"
|
||||
parameter. TLS is not enabled by default.
|
||||
.sp
|
||||
With "sni=<SNI_HOST>" parameter, it can override the TLS
|
||||
SNI field value with given <SNI_HOST>. This will
|
||||
default to the backend <HOST> name
|
||||
.sp
|
||||
The feature to detect whether backend is online or
|
||||
offline can be enabled using optional "fall" and "rise"
|
||||
parameters. Using "fall=<N>" parameter, if nghttpx
|
||||
cannot connect to a this backend <N> times in a row,
|
||||
this backend is assumed to be offline, and it is
|
||||
excluded from load balancing. If <N> is 0, this backend
|
||||
never be excluded from load balancing whatever times
|
||||
nghttpx cannot connect to it, and this is the default.
|
||||
There is also "rise=<N>" parameter. After backend was
|
||||
excluded from load balancing group, nghttpx periodically
|
||||
attempts to make a connection to the failed backend, and
|
||||
if the connection is made successfully <N> times in a
|
||||
row, the backend is assumed to be online, and it is now
|
||||
eligible for load balancing target. If <N> is 0, a
|
||||
backend is permanently offline, once it goes in that
|
||||
state, and this is the default behaviour.
|
||||
.sp
|
||||
The session affinity is enabled using
|
||||
"affinity=<METHOD>" parameter. If "ip" is given in
|
||||
<METHOD>, client IP based session affinity is enabled.
|
||||
If "none" is given in <METHOD>, session affinity is
|
||||
disabled, and this is the default. The session affinity
|
||||
is enabled per <PATTERN>. If at least one backend has
|
||||
"affinity" parameter, and its <METHOD> is not "none",
|
||||
session affinity is enabled for all backend servers
|
||||
sharing the same <PATTERN>. It is advised to set
|
||||
"affinity" parameter to all backend explicitly if
|
||||
session affinity is desired. The session affinity may
|
||||
break if one of the backend gets unreachable, or backend
|
||||
settings are reloaded or replaced by API.
|
||||
.sp
|
||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||
not contain these characters. Since ";" has special
|
||||
meaning in shell, the option value must be quoted.
|
||||
@@ -117,7 +183,7 @@ Default: \fB127.0.0.1,80\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)
|
||||
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
|
||||
Set frontend host and port. If <HOST> is \(aq*\(aq, it
|
||||
assumes all addresses including both IPv4 and IPv6.
|
||||
UNIX domain socket can be specified by prefixing path
|
||||
@@ -125,6 +191,25 @@ name with "unix:" (e.g., unix:/var/run/nghttpx.sock).
|
||||
This option can be used multiple times to listen to
|
||||
multiple addresses.
|
||||
.sp
|
||||
This option can take 0 or more parameters, which are
|
||||
described below. Note that "api" and "healthmon"
|
||||
parameters are mutually exclusive.
|
||||
.sp
|
||||
Optionally, TLS can be disabled by specifying "no\-tls"
|
||||
parameter. TLS is enabled by default.
|
||||
.sp
|
||||
To make this frontend as API endpoint, specify "api"
|
||||
parameter. This is disabled by default. It is
|
||||
important to limit the access to the API frontend.
|
||||
Otherwise, someone may change the backend server, and
|
||||
break your services, or expose confidential information
|
||||
to the outside the world.
|
||||
.sp
|
||||
To make this frontend as health monitor endpoint,
|
||||
specify "healthmon" parameter. This is disabled by
|
||||
default. Any requests which come through this address
|
||||
are replied with 200 HTTP status, without no body.
|
||||
.sp
|
||||
Default: \fB*,3000\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -165,22 +250,6 @@ be specified by \fI\%\-\-backend\-read\-timeout\fP and
|
||||
.B \-\-accept\-proxy\-protocol
|
||||
Accept PROXY protocol version 1 on frontend connection.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-no\-tls
|
||||
Disable SSL/TLS on backend connections. For HTTP/2
|
||||
backend connections, TLS is enabled by default. For
|
||||
HTTP/1 backend connections, TLS is disabled by default,
|
||||
and can be enabled by \fI\%\-\-backend\-http1\-tls\fP option. If
|
||||
both \fI\%\-\-backend\-no\-tls\fP and \fI\%\-\-backend\-http1\-tls\fP options
|
||||
are used, \fI\%\-\-backend\-no\-tls\fP has the precedence.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http1\-tls
|
||||
Enable SSL/TLS on backend HTTP/1 connections. See also
|
||||
\fI\%\-\-backend\-no\-tls\fP option.
|
||||
.UNINDENT
|
||||
.SS Performance
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -269,37 +338,27 @@ Default: \fB0\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-connections\-per\-worker=<N>
|
||||
Set maximum number of backend HTTP/2 physical
|
||||
connections per worker. If pattern is used in \fI\%\-b\fP
|
||||
option, this limit is applied to each pattern group (in
|
||||
other words, each pattern group can have maximum <N>
|
||||
HTTP/2 connections). The default value is 0, which
|
||||
means that the value is adjusted to the number of
|
||||
backend addresses. If pattern is used, this adjustment
|
||||
is done for each pattern group.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http1\-connections\-per\-host=<N>
|
||||
Set maximum number of backend concurrent HTTP/1
|
||||
connections per origin host. This option is meaningful
|
||||
when \fI\%\-s\fP option is used. The origin host is determined
|
||||
by authority portion of request URI (or :authority
|
||||
header field for HTTP/2). To limit the number of
|
||||
connections per frontend for default mode, use
|
||||
\fI\%\-\-backend\-http1\-connections\-per\-frontend\fP\&.
|
||||
.B \-\-backend\-connections\-per\-host=<N>
|
||||
Set maximum number of backend concurrent connections
|
||||
(and/or streams in case of HTTP/2) per origin host.
|
||||
This option is meaningful when \fI\%\-\-http2\-proxy\fP option is
|
||||
used. The origin host is determined by authority
|
||||
portion of request URI (or :authority header field for
|
||||
HTTP/2). To limit the number of connections per
|
||||
frontend for default mode, use
|
||||
\fI\%\-\-backend\-connections\-per\-frontend\fP\&.
|
||||
.sp
|
||||
Default: \fB8\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http1\-connections\-per\-frontend=<N>
|
||||
Set maximum number of backend concurrent HTTP/1
|
||||
connections per frontend. This option is only used for
|
||||
default mode. 0 means unlimited. To limit the number
|
||||
of connections per host for HTTP/2 or SPDY proxy mode
|
||||
(\-s option), use \fI\%\-\-backend\-http1\-connections\-per\-host\fP\&.
|
||||
.B \-\-backend\-connections\-per\-frontend=<N>
|
||||
Set maximum number of backend concurrent connections
|
||||
(and/or streams in case of HTTP/2) per frontend. This
|
||||
option is only used for default mode. 0 means
|
||||
unlimited. To limit the number of connections per host
|
||||
with \fI\%\-\-http2\-proxy\fP option, use
|
||||
\fI\%\-\-backend\-connections\-per\-host\fP\&.
|
||||
.sp
|
||||
Default: \fB0\fP
|
||||
.UNINDENT
|
||||
@@ -335,6 +394,13 @@ value is 0 then fast open is disabled.
|
||||
.sp
|
||||
Default: \fB0\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-no\-kqueue
|
||||
Don\(aqt use kqueue. This option is only applicable for
|
||||
the platforms which have kqueue. For other platforms,
|
||||
this option will be simply ignored.
|
||||
.UNINDENT
|
||||
.SS Timeout
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -390,6 +456,14 @@ Default: \fB30s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-connect\-timeout=<DURATION>
|
||||
Specify timeout before establishing TCP connection to
|
||||
backend.
|
||||
.sp
|
||||
Default: \fB30s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-keep\-alive\-timeout=<DURATION>
|
||||
Specify keep\-alive timeout for backend connection.
|
||||
.sp
|
||||
@@ -404,6 +478,36 @@ disables this feature.
|
||||
.sp
|
||||
Default: \fB30s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-setting\-timeout=<DURATION>
|
||||
Specify timeout before SETTINGS ACK is received from
|
||||
client.
|
||||
.sp
|
||||
Default: \fB10s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-settings\-timeout=<DURATION>
|
||||
Specify timeout before SETTINGS ACK is received from
|
||||
backend server.
|
||||
.sp
|
||||
Default: \fB10s\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-max\-backoff=<DURATION>
|
||||
Specify maximum backoff interval. This is used when
|
||||
doing health check against offline backend (see "fail"
|
||||
parameter in \fI\%\-\-backend\fP option). It is also used to
|
||||
limit the maximum interval to temporarily disable
|
||||
backend when nghttpx failed to connect to it. These
|
||||
intervals are calculated using exponential backoff, and
|
||||
consecutive failed attempts increase the interval. This
|
||||
option caps its maximum value.
|
||||
.sp
|
||||
Default: \fB2m\fP
|
||||
.UNINDENT
|
||||
.SS SSL/TLS
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -413,6 +517,17 @@ described in OpenSSL ciphers(1).
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-ecdh\-curves=<LIST>
|
||||
Set supported curve list for frontend connections.
|
||||
<LIST> is a colon separated list of curve NID or names
|
||||
in the preference order. The supported curves depend on
|
||||
the linked OpenSSL library. This function requires
|
||||
OpenSSL >= 1.0.2.
|
||||
.sp
|
||||
Default: \fBP\-256:P\-384:P\-521\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-k, \-\-insecure
|
||||
Don\(aqt verify backend server\(aqs certificate if TLS is
|
||||
enabled for backend connections.
|
||||
@@ -435,18 +550,21 @@ password protected it\(aqll be requested interactively.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-subcert=<KEYPATH>:<CERTPATH>
|
||||
.B \-\-subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
|
||||
Specify additional certificate and private key file.
|
||||
nghttpx will choose certificates based on the hostname
|
||||
indicated by client using TLS SNI extension. This
|
||||
option can be used multiple times. To make OCSP
|
||||
stapling work, <CERTPATH> must be absolute path.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-tls\-sni\-field=<HOST>
|
||||
Explicitly set the content of the TLS SNI extension.
|
||||
This will default to the backend HOST name.
|
||||
.sp
|
||||
Additional parameter can be specified in <PARAM>. The
|
||||
available <PARAM> is "sct\-dir=<DIR>".
|
||||
.sp
|
||||
"sct\-dir=<DIR>" specifies the path to directory which
|
||||
contains *.sct files for TLS
|
||||
signed_certificate_timestamp extension (RFC 6962). This
|
||||
feature requires OpenSSL >= 1.0.2. See also
|
||||
\fI\%\-\-tls\-sct\-dir\fP option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -533,7 +651,7 @@ required.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-ticket\-key\-memcached=<HOST>,<PORT>
|
||||
.B \-\-tls\-ticket\-key\-memcached=<HOST>,<PORT>[;tls]
|
||||
Specify address of memcached server to get TLS ticket
|
||||
keys for session resumption. This enables shared TLS
|
||||
ticket key between multiple nghttpx instances. nghttpx
|
||||
@@ -543,7 +661,9 @@ ticket keys from memcached, and use them, possibly
|
||||
replacing current set of keys. It is up to extern TLS
|
||||
ticket key generator to rotate keys frequently. See
|
||||
"TLS SESSION TICKET RESUMPTION" section in manual page
|
||||
to know the data format in memcached entry.
|
||||
to know the data format in memcached entry. Optionally,
|
||||
memcached connection can be encrypted with TLS by
|
||||
specifying "tls" parameter.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -592,12 +712,6 @@ aes\-128\-cbc is used.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-ticket\-key\-memcached\-tls
|
||||
Enable SSL/TLS on memcached connections to get TLS
|
||||
ticket keys.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-ticket\-key\-memcached\-cert\-file=<PATH>
|
||||
Path to client certificate for memcached connections to
|
||||
get TLS ticket keys.
|
||||
@@ -630,10 +744,12 @@ Disable OCSP stapling.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-session\-cache\-memcached=<HOST>,<PORT>
|
||||
.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.
|
||||
multiple nghttpx instances. Optionally, memcached
|
||||
connection can be encrypted with TLS by specifying "tls"
|
||||
parameter.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -648,12 +764,6 @@ Default: \fBauto\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-session\-cache\-memcached\-tls
|
||||
Enable SSL/TLS on memcached connections to store session
|
||||
cache.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-session\-cache\-memcached\-cert\-file=<PATH>
|
||||
Path to client certificate for memcached connections to
|
||||
store session cache.
|
||||
@@ -697,53 +807,69 @@ Allow black listed cipher suite on HTTP/2 connection.
|
||||
See \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for
|
||||
the complete HTTP/2 cipher suites black list.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-tls\-sct\-dir=<DIR>
|
||||
Specifies the directory where *.sct files exist. All
|
||||
*.sct files in <DIR> are read, and sent as
|
||||
extension_data of TLS signed_certificate_timestamp (RFC
|
||||
6962) to client. These *.sct files are for the
|
||||
certificate specified in positional command\-line
|
||||
argument <CERT>, or certificate option in configuration
|
||||
file. For additional certificates, use \fI\%\-\-subcert\fP
|
||||
option. This option requires OpenSSL >= 1.0.2.
|
||||
.UNINDENT
|
||||
.SS HTTP/2 and SPDY
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-c, \-\-http2\-max\-concurrent\-streams=<N>
|
||||
.B \-c, \-\-frontend\-http2\-max\-concurrent\-streams=<N>
|
||||
Set the maximum number of the concurrent streams in one
|
||||
HTTP/2 and SPDY session.
|
||||
frontend HTTP/2 and SPDY session.
|
||||
.sp
|
||||
Default: \(ga\(ga 100\(ga\(ga
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-max\-concurrent\-streams=<N>
|
||||
Set the maximum number of the concurrent streams in one
|
||||
backend HTTP/2 session. This sets maximum number of
|
||||
concurrent opened pushed streams. The maximum number of
|
||||
concurrent requests are set by a remote server.
|
||||
.sp
|
||||
Default: \fB100\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-window\-bits=<N>
|
||||
Sets the per\-stream initial window size of HTTP/2 SPDY
|
||||
frontend connection. For HTTP/2, the size is 2**<N>\-1.
|
||||
For SPDY, the size is 2**<N>.
|
||||
.B \-\-frontend\-http2\-window\-size=<SIZE>
|
||||
Sets the per\-stream initial window size of HTTP/2 and
|
||||
SPDY frontend connection.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB65535\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-connection\-window\-bits=<N>
|
||||
.B \-\-frontend\-http2\-connection\-window\-size=<SIZE>
|
||||
Sets the per\-connection window size of HTTP/2 and SPDY
|
||||
frontend connection. For HTTP/2, the size is
|
||||
2**<N>\-1. For SPDY, the size is 2**<N>.
|
||||
frontend connection. For SPDY connection, the value
|
||||
less than 64KiB is rounded up to 64KiB.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB65535\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-no\-tls
|
||||
Disable SSL/TLS on frontend connections.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-window\-bits=<N>
|
||||
.B \-\-backend\-http2\-window\-size=<SIZE>
|
||||
Sets the initial window size of HTTP/2 backend
|
||||
connection to 2**<N>\-1.
|
||||
connection.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB65535\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-connection\-window\-bits=<N>
|
||||
.B \-\-backend\-http2\-connection\-window\-size=<SIZE>
|
||||
Sets the per\-connection window size of HTTP/2 backend
|
||||
connection to 2**<N>\-1.
|
||||
connection.
|
||||
.sp
|
||||
Default: \fB16\fP
|
||||
Default: \fB2147483647\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -764,52 +890,91 @@ protocol security.
|
||||
Disable HTTP/2 server push. Server push is supported by
|
||||
default mode and HTTP/2 frontend via Link header field.
|
||||
It is also supported if both frontend and backend are
|
||||
HTTP/2 (which implies \fI\%\-\-http2\-bridge\fP or \fI\%\-\-client\fP mode).
|
||||
In this case, server push from backend session is
|
||||
relayed to frontend, and server push via Link header
|
||||
field is also supported. HTTP SPDY frontend does not
|
||||
support server push.
|
||||
HTTP/2 in default mode. In this case, server push from
|
||||
backend session is relayed to frontend, and server push
|
||||
via Link header field is also supported. SPDY frontend
|
||||
does not support server push.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-optimize\-write\-buffer\-size
|
||||
(Experimental) Enable write buffer size optimization in
|
||||
frontend HTTP/2 TLS connection. This optimization aims
|
||||
to reduce write buffer size so that it only contains
|
||||
bytes which can send immediately. This makes server
|
||||
more responsive to prioritized HTTP/2 stream because the
|
||||
buffering of lower priority stream is reduced. This
|
||||
option is only effective on recent Linux platform.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-optimize\-window\-size
|
||||
(Experimental) Automatically tune connection level
|
||||
window size of frontend HTTP/2 TLS connection. If this
|
||||
feature is enabled, connection window size starts with
|
||||
the default window size, 65535 bytes. nghttpx
|
||||
automatically adjusts connection window size based on
|
||||
TCP receiving window size. The maximum window size is
|
||||
capped by the value specified by
|
||||
\fI\%\-\-frontend\-http2\-connection\-window\-size\fP\&. Since the
|
||||
stream is subject to stream level window size, it should
|
||||
be adjusted using \fI\%\-\-frontend\-http2\-window\-size\fP option as
|
||||
well. This option is only effective on recent Linux
|
||||
platform.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the frontend HTTP/2 connection. The decoder (client)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which client specified.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-frontend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the frontend HTTP/2 connection.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the backend HTTP/2 connection. The decoder (backend)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which backend specified.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-backend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the backend HTTP/2 connection.
|
||||
.sp
|
||||
Default: \fB4K\fP
|
||||
.UNINDENT
|
||||
.SS Mode
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B (default mode)
|
||||
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. If
|
||||
\fI\%\-\-frontend\-no\-tls\fP is used, accept HTTP/2 and HTTP/1.1.
|
||||
The incoming HTTP/1.1 connection can be upgraded to
|
||||
HTTP/2 through HTTP Upgrade. The protocol to the
|
||||
backend is HTTP/1.1.
|
||||
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no\-tls"
|
||||
parameter is used in \fI\%\-\-frontend\fP option, accept HTTP/2
|
||||
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
|
||||
connection can be upgraded to HTTP/2 through HTTP
|
||||
Upgrade.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-s, \-\-http2\-proxy
|
||||
Like default mode, but enable secure proxy mode.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-http2\-bridge
|
||||
Like default mode, but communicate with the backend in
|
||||
HTTP/2 over SSL/TLS. Thus the incoming all connections
|
||||
are converted to HTTP/2 connection and relayed to the
|
||||
backend. See \fI\%\-\-backend\-http\-proxy\-uri\fP option if you are
|
||||
behind the proxy and want to connect to the outside
|
||||
HTTP/2 proxy.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-client
|
||||
Accept HTTP/2 and HTTP/1.1 without SSL/TLS. The
|
||||
incoming HTTP/1.1 connection can be upgraded to HTTP/2
|
||||
connection through HTTP Upgrade. The protocol to the
|
||||
backend is HTTP/2. To use nghttpx as a forward proxy,
|
||||
use \fI\%\-p\fP option instead.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-p, \-\-client\-proxy
|
||||
Like \fI\%\-\-client\fP option, but it also requires the request
|
||||
path from frontend must be an absolute URI, suitable for
|
||||
use as a forward proxy.
|
||||
Like default mode, but enable forward proxy. This is so
|
||||
called HTTP/2 proxy mode.
|
||||
.UNINDENT
|
||||
.SS Logging
|
||||
.INDENT 0.0
|
||||
@@ -877,6 +1042,12 @@ $ssl_session_id: session ID for SSL/TLS connection.
|
||||
.IP \(bu 2
|
||||
$ssl_session_reused: "r" if SSL/TLS session was
|
||||
reused. Otherwise, "."
|
||||
.IP \(bu 2
|
||||
$backend_host: backend host used to fulfill the
|
||||
request. "\-" if backend host is not available.
|
||||
.IP \(bu 2
|
||||
$backend_port: backend port used to fulfill the
|
||||
request. "\-" if backend host is not available.
|
||||
.UNINDENT
|
||||
.sp
|
||||
The variable can be enclosed by "{" and "}" for
|
||||
@@ -975,18 +1146,16 @@ is received, it is left unaltered.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-no\-location\-rewrite
|
||||
Don\(aqt rewrite location header field on \fI\%\-\-http2\-bridge\fP,
|
||||
\fI\%\-\-client\fP and default mode. For \fI\%\-\-http2\-proxy\fP and
|
||||
\fI\%\-\-client\-proxy\fP mode, location header field will not be
|
||||
altered regardless of this option.
|
||||
Don\(aqt rewrite location header field in default mode.
|
||||
When \fI\%\-\-http2\-proxy\fP is used, location header field will
|
||||
not be altered regardless of this option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-host\-rewrite
|
||||
Rewrite host and :authority header fields on
|
||||
\fI\%\-\-http2\-bridge\fP, \fI\%\-\-client\fP and default mode. For
|
||||
\fI\%\-\-http2\-proxy\fP and \fI\%\-\-client\-proxy\fP mode, these headers
|
||||
will not be altered regardless of this option.
|
||||
Rewrite host and :authority header fields in default
|
||||
mode. When \fI\%\-\-http2\-proxy\fP is used, these headers will
|
||||
not be altered regardless of this option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1054,6 +1223,38 @@ towards this number.
|
||||
.sp
|
||||
Default: \fB500\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-error\-page=(<CODE>|*)=<PATH>
|
||||
Set file path to custom error page served when nghttpx
|
||||
originally generates HTTP error status code <CODE>.
|
||||
<CODE> must be greater than or equal to 400, and at most
|
||||
599. If "*" is used instead of <CODE>, it matches all
|
||||
HTTP status code. If error status code comes from
|
||||
backend server, the custom error pages are not used.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-server\-name=<NAME>
|
||||
Change server response header field value to <NAME>.
|
||||
.sp
|
||||
Default: \fBnghttpx nghttp2/1.16.0\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-no\-server\-rewrite
|
||||
Don\(aqt rewrite server header field in default mode. When
|
||||
\fI\%\-\-http2\-proxy\fP is used, these headers will not be altered
|
||||
regardless of this option.
|
||||
.UNINDENT
|
||||
.SS API
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \-\-api\-max\-request\-body=<SIZE>
|
||||
Set the maximum size of request body for API request.
|
||||
.sp
|
||||
Default: \fB16K\fP
|
||||
.UNINDENT
|
||||
.SS Debug
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1201,6 +1402,9 @@ Shutdown gracefully. First accept pending connections and stop
|
||||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
.TP
|
||||
.B SIGHUP
|
||||
Reload configuration file given in \fI\%\-\-conf\fP\&.
|
||||
.TP
|
||||
.B SIGUSR1
|
||||
Reopen log files.
|
||||
.TP
|
||||
@@ -1208,7 +1412,11 @@ Reopen log files.
|
||||
Fork and execute nghttpx. It will execute the binary in the same
|
||||
path with same command\-line arguments and environment variables.
|
||||
After new process comes up, sending SIGQUIT to the original process
|
||||
to perform hot swapping.
|
||||
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
|
||||
and SIGHUP is that former is usually used to execute new binary, and
|
||||
the master process is newly spawned. On the other hand, the latter
|
||||
just reloads configuration file, and the same master process
|
||||
continues to exist.
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
@@ -1258,12 +1466,12 @@ associated stream\(aqs status code must be 200.
|
||||
This limitation may be loosened in the future release.
|
||||
.sp
|
||||
nghttpx also supports server push if both frontend and backend are
|
||||
HTTP/2 (which implies \fI\%\-\-http2\-bridge\fP or \fI\%\-\-client\fP).
|
||||
In this case, in addition to server push via Link header field, server
|
||||
push from backend is relayed to frontend HTTP/2 session.
|
||||
HTTP/2 in default mode. In this case, in addition to server push via
|
||||
Link header field, server push from backend is forwarded to frontend
|
||||
HTTP/2 session.
|
||||
.sp
|
||||
HTTP/2 server push will be disabled if \fI\%\-\-http2\-proxy\fP or
|
||||
\fI\%\-\-client\-proxy\fP is used.
|
||||
HTTP/2 server push will be disabled if \fI\%\-\-http2\-proxy\fP is
|
||||
used.
|
||||
.SH UNIX DOMAIN SOCKET
|
||||
.sp
|
||||
nghttpx supports UNIX domain socket with a filename for both frontend
|
||||
@@ -1303,8 +1511,8 @@ 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 \fI\%\-\-tls\-session\-cache\-memcached\-tls\fP
|
||||
option.
|
||||
enable encryption, use \fBtls\fP keyword in
|
||||
\fI\%\-\-tls\-session\-cache\-memcached\fP option.
|
||||
.SS TLS SESSION TICKET RESUMPTION
|
||||
.sp
|
||||
By default, session ticket is shared by all worker threads. The
|
||||
@@ -1350,13 +1558,26 @@ keys. The key appeared first is used as encryption key. All the
|
||||
remaining keys are used as decryption only.
|
||||
.sp
|
||||
By default, connections to memcached server are not encrypted. To
|
||||
enable encryption, use \fI\%\-\-tls\-ticket\-key\-memcached\-tls\fP
|
||||
option.
|
||||
enable encryption, use \fBtls\fP keyword in
|
||||
\fI\%\-\-tls\-ticket\-key\-memcached\fP option.
|
||||
.sp
|
||||
If \fI\%\-\-tls\-ticket\-key\-file\fP is given, encryption key is read
|
||||
from the given file. In this case, nghttpx does not rotate key
|
||||
automatically. To rotate key, one has to restart nghttpx (see
|
||||
SIGNALS).
|
||||
.SH CERTIFICATE TRANSPARENCY
|
||||
.sp
|
||||
nghttpx supports TLS \fBsigned_certificate_timestamp\fP extension (\fI\%RFC
|
||||
6962\fP). The relevant options
|
||||
are \fI\%\-\-tls\-sct\-dir\fP and \fBsct\-dir\fP parameter in
|
||||
\fI\%\-\-subcert\fP\&. They takes a directory, and nghttpx reads all
|
||||
files whose extension is \fB\&.sct\fP under the directory. The \fB*.sct\fP
|
||||
files are encoded as \fBSignedCertificateTimestamp\fP struct described
|
||||
in \fI\%section 3.2 of RFC 69662\fP\&. This format is
|
||||
the same one used by \fI\%nginx\-ct\fP and \fI\%mod_ssl_ct\fP\&.
|
||||
\fI\%ct\-submit\fP can be
|
||||
used to submit certificates to log servers, and obtain the
|
||||
\fBSignedCertificateTimestamp\fP struct which can be used with nghttpx.
|
||||
.SH MRUBY SCRIPTING
|
||||
.sp
|
||||
\fBWARNING:\fP
|
||||
@@ -1426,7 +1647,32 @@ Return the current phase.
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B attribute [R] remote_addr
|
||||
Return IP address of a remote client.
|
||||
Return IP address of a remote client. If connection is made
|
||||
via UNIX domain socket, this returns the string "localhost".
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B attribute [R] server_addr
|
||||
Return address of server that accepted the connection. This
|
||||
is a string which specified in \fI\%\-\-frontend\fP option,
|
||||
excluding port number, and not a resolved IP address. For
|
||||
UNIX domain socket, this is a path to UNIX domain socket.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B attribute [R] server_port
|
||||
Return port number of the server frontend which accepted the
|
||||
connection from client.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B attribute [R] tls_used
|
||||
Return true if TLS is used on the connection.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B attribute [R] tls_sni
|
||||
Return the TLS SNI value which client sent in this connection.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -1469,7 +1715,13 @@ value is assigned.
|
||||
.B attribute [R/W] path
|
||||
Request path, including query component (i.e., /index.html).
|
||||
On assignment, copy of given value is assigned. The path does
|
||||
not include authority component of URI.
|
||||
not include authority component of URI. This may include
|
||||
query component. nghttpx makes certain normalization for
|
||||
path. It decodes percent\-encoding for unreserved characters
|
||||
(see \fI\%https://tools.ietf.org/html/rfc3986#section\-2.3\fP), and
|
||||
resolves ".." and ".". But it may leave characters which
|
||||
should be percent\-encoded as is. So be careful when comparing
|
||||
path against desired string.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
@@ -1502,7 +1754,7 @@ Clear all existing request header fields.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B push uri
|
||||
.B push(uri)
|
||||
Initiate to push resource identified by \fIuri\fP\&. Only HTTP/2
|
||||
protocol supports this feature. For the other protocols, this
|
||||
method is noop. \fIuri\fP can be absolute URI, absolute path or
|
||||
@@ -1632,9 +1884,64 @@ App.new
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH API ENDPOINTS
|
||||
.sp
|
||||
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
|
||||
default, API endpoint is disabled. To enable it, add a dedicated
|
||||
frontend for API using \fI\%\-\-frontend\fP option with "api"
|
||||
parameter. All requests which come from this frontend address, will
|
||||
be treated as API request.
|
||||
.sp
|
||||
The response is normally JSON dictionary, and at least includes the
|
||||
following keys:
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B status
|
||||
The status of the request processing. The following values are
|
||||
defined:
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
.B Success
|
||||
The request was successful.
|
||||
.TP
|
||||
.B Failure
|
||||
The request was failed. No change has been made.
|
||||
.UNINDENT
|
||||
.TP
|
||||
.B code
|
||||
HTTP status code
|
||||
.UNINDENT
|
||||
.sp
|
||||
We wrote "normally", since nghttpx may return ordinal HTML response in
|
||||
some cases where the error has occurred before reaching API endpoint
|
||||
(e.g., header field is too large).
|
||||
.sp
|
||||
The following section describes available API endpoints.
|
||||
.SS PUT /api/v1beta1/backendconfig
|
||||
.sp
|
||||
This API replaces the current backend server settings with the
|
||||
requested ones. The request method should be PUT, but POST is also
|
||||
acceptable. The request body must be nghttpx configuration file
|
||||
format. For configuration file format, see \fI\%FILES\fP section. The
|
||||
line separator inside the request body must be single LF (0x0A).
|
||||
Currently, only \fI\%backend\fP option is parsed, the
|
||||
others are simply ignored. The semantics of this API is replace the
|
||||
current backend with the backend options in request body. Describe
|
||||
the desired set of backend severs, and nghttpx makes it happen. If
|
||||
there is no \fI\%backend\fP option is found in request
|
||||
body, the current set of backend is replaced with the \fI\%backend\fP option\(aqs default value, which is \fB127.0.0.1,80\fP\&.
|
||||
.sp
|
||||
The replacement is done instantly without breaking existing
|
||||
connections or requests. It also avoids any process creation as is
|
||||
the case with hot swapping with signals.
|
||||
.sp
|
||||
The one limitation is that only numeric IP address is allowd in
|
||||
\fI\%backend\fP in request body while non numeric
|
||||
hostname is allowed in command\-line or configuration file is read
|
||||
using \fI\%\-\-conf\fP\&.
|
||||
.SH SEE ALSO
|
||||
.sp
|
||||
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fIh2load(1)\fP
|
||||
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBh2load(1)\fP
|
||||
.SH AUTHOR
|
||||
Tatsuhiro Tsujikawa
|
||||
.SH COPYRIGHT
|
||||
|
||||
@@ -19,14 +19,14 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.
|
||||
.. describe:: <PRIVATE_KEY>
|
||||
|
||||
|
||||
Set path to server's private key. Required unless :option:`-p`\,
|
||||
:option:`--client` or :option:`\--frontend-no-tls` are given.
|
||||
Set path to server's private key. Required unless
|
||||
"no-tls" parameter is used in :option:`--frontend` option.
|
||||
|
||||
.. describe:: <CERT>
|
||||
|
||||
Set path to server's certificate. Required unless :option:`-p`\,
|
||||
:option:`--client` or :option:`\--frontend-no-tls` are given. To make OCSP
|
||||
stapling work, this must be absolute path.
|
||||
Set path to server's certificate. Required unless
|
||||
"no-tls" parameter is used in :option:`--frontend` option. To
|
||||
make OCSP stapling work, this must be an absolute path.
|
||||
|
||||
|
||||
OPTIONS
|
||||
@@ -37,7 +37,8 @@ The options are categorized into several groups.
|
||||
Connections
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;<PATTERN>[:...]]
|
||||
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
|
||||
|
||||
|
||||
Set backend host and port. The multiple backend
|
||||
addresses are accepted by repeating this option. UNIX
|
||||
@@ -45,31 +46,39 @@ Connections
|
||||
with "unix:" (e.g., unix:/var/run/backend.sock).
|
||||
|
||||
Optionally, if <PATTERN>s are given, the backend address
|
||||
is only used if request matches the pattern. If :option:`-s` or
|
||||
:option:`-p` is used, <PATTERN>s are ignored. The pattern
|
||||
matching is closely designed to ServeMux in net/http
|
||||
package of Go programming language. <PATTERN> consists
|
||||
of path, host + path or just host. The path must start
|
||||
with "*/*". If it ends with "*/*", it matches all request
|
||||
path in its subtree. To deal with the request to the
|
||||
directory without trailing slash, the path which ends
|
||||
with "*/*" also matches the request path which only lacks
|
||||
trailing '*/*' (e.g., path "*/foo/*" matches request path
|
||||
"*/foo*"). If it does not end with "*/*", it performs exact
|
||||
match against the request path. If host is given, it
|
||||
performs exact match against the request host. If host
|
||||
alone is given, "*/*" is appended to it, so that it
|
||||
matches all request paths under the host (e.g.,
|
||||
specifying "nghttp2.org" equals to "nghttp2.org/").
|
||||
is only used if request matches the pattern. If
|
||||
:option:`--http2-proxy` is used, <PATTERN>s are ignored. The
|
||||
pattern matching is closely designed to ServeMux in
|
||||
net/http package of Go programming language. <PATTERN>
|
||||
consists of path, host + path or just host. The path
|
||||
must start with "*/*". If it ends with "*/*", it matches
|
||||
all request path in its subtree. To deal with the
|
||||
request to the directory without trailing slash, the
|
||||
path which ends with "*/*" also matches the request path
|
||||
which only lacks trailing '*/*' (e.g., path "*/foo/*"
|
||||
matches request path "*/foo*"). If it does not end with
|
||||
"*/*", it performs exact match against the request path.
|
||||
If host is given, it performs exact match against the
|
||||
request host. If host alone is given, "*/*" is appended
|
||||
to it, so that it matches all request paths under the
|
||||
host (e.g., specifying "nghttp2.org" equals to
|
||||
"nghttp2.org/").
|
||||
|
||||
Patterns with host take precedence over patterns with
|
||||
just path. Then, longer patterns take precedence over
|
||||
shorter ones, breaking a tie by the order of the
|
||||
appearance in the configuration.
|
||||
shorter ones.
|
||||
|
||||
If <PATTERN> is omitted, "*/*" is used as pattern, which
|
||||
matches all request paths (catch-all pattern). The
|
||||
catch-all backend must be given.
|
||||
Host can include "\*" in the left most position to
|
||||
indicate wildcard match (only suffix match is done).
|
||||
The "\*" must match at least one character. For example,
|
||||
host pattern "\*.nghttp2.org" matches against
|
||||
"www.nghttp2.org" and "git.ngttp2.org", but does not
|
||||
match against "nghttp2.org". The exact hosts match
|
||||
takes precedence over the wildcard hosts match.
|
||||
|
||||
If <PATTERN> is omitted or empty string, "*/*" is used as
|
||||
pattern, which matches all request paths (catch-all
|
||||
pattern). The catch-all backend must be given.
|
||||
|
||||
When doing a match, nghttpx made some normalization to
|
||||
pattern, request host and path. For host part, they are
|
||||
@@ -92,6 +101,64 @@ Connections
|
||||
The backend addresses sharing same <PATTERN> are grouped
|
||||
together forming load balancing group.
|
||||
|
||||
Several parameters <PARAM> are accepted after <PATTERN>.
|
||||
The parameters are delimited by ";". The available
|
||||
parameters are: "proto=<PROTO>", "tls",
|
||||
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
|
||||
"affinity=<METHOD>". The parameter consists of keyword,
|
||||
and optionally followed by "=" and value. For example,
|
||||
the parameter "proto=h2" consists of the keyword "proto"
|
||||
and value "h2". The parameter "tls" consists of the
|
||||
keyword "tls" without value. Each parameter is
|
||||
described as follows.
|
||||
|
||||
The backend application protocol can be specified using
|
||||
optional "proto" parameter, and in the form of
|
||||
"proto=<PROTO>". <PROTO> should be one of the following
|
||||
list without quotes: "h2", "http/1.1". The default
|
||||
value of <PROTO> is "http/1.1". Note that usually "h2"
|
||||
refers to HTTP/2 over TLS. But in this option, it may
|
||||
mean HTTP/2 over cleartext TCP unless "tls" keyword is
|
||||
used (see below).
|
||||
|
||||
TLS can be enabled by specifying optional "tls"
|
||||
parameter. TLS is not enabled by default.
|
||||
|
||||
With "sni=<SNI_HOST>" parameter, it can override the TLS
|
||||
SNI field value with given <SNI_HOST>. This will
|
||||
default to the backend <HOST> name
|
||||
|
||||
The feature to detect whether backend is online or
|
||||
offline can be enabled using optional "fall" and "rise"
|
||||
parameters. Using "fall=<N>" parameter, if nghttpx
|
||||
cannot connect to a this backend <N> times in a row,
|
||||
this backend is assumed to be offline, and it is
|
||||
excluded from load balancing. If <N> is 0, this backend
|
||||
never be excluded from load balancing whatever times
|
||||
nghttpx cannot connect to it, and this is the default.
|
||||
There is also "rise=<N>" parameter. After backend was
|
||||
excluded from load balancing group, nghttpx periodically
|
||||
attempts to make a connection to the failed backend, and
|
||||
if the connection is made successfully <N> times in a
|
||||
row, the backend is assumed to be online, and it is now
|
||||
eligible for load balancing target. If <N> is 0, a
|
||||
backend is permanently offline, once it goes in that
|
||||
state, and this is the default behaviour.
|
||||
|
||||
The session affinity is enabled using
|
||||
"affinity=<METHOD>" parameter. If "ip" is given in
|
||||
<METHOD>, client IP based session affinity is enabled.
|
||||
If "none" is given in <METHOD>, session affinity is
|
||||
disabled, and this is the default. The session affinity
|
||||
is enabled per <PATTERN>. If at least one backend has
|
||||
"affinity" parameter, and its <METHOD> is not "none",
|
||||
session affinity is enabled for all backend servers
|
||||
sharing the same <PATTERN>. It is advised to set
|
||||
"affinity" parameter to all backend explicitly if
|
||||
session affinity is desired. The session affinity may
|
||||
break if one of the backend gets unreachable, or backend
|
||||
settings are reloaded or replaced by API.
|
||||
|
||||
Since ";" and ":" are used as delimiter, <PATTERN> must
|
||||
not contain these characters. Since ";" has special
|
||||
meaning in shell, the option value must be quoted.
|
||||
@@ -99,7 +166,7 @@ Connections
|
||||
|
||||
Default: ``127.0.0.1,80``
|
||||
|
||||
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)
|
||||
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
|
||||
|
||||
Set frontend host and port. If <HOST> is '\*', it
|
||||
assumes all addresses including both IPv4 and IPv6.
|
||||
@@ -108,6 +175,26 @@ Connections
|
||||
This option can be used multiple times to listen to
|
||||
multiple addresses.
|
||||
|
||||
This option can take 0 or more parameters, which are
|
||||
described below. Note that "api" and "healthmon"
|
||||
parameters are mutually exclusive.
|
||||
|
||||
Optionally, TLS can be disabled by specifying "no-tls"
|
||||
parameter. TLS is enabled by default.
|
||||
|
||||
To make this frontend as API endpoint, specify "api"
|
||||
parameter. This is disabled by default. It is
|
||||
important to limit the access to the API frontend.
|
||||
Otherwise, someone may change the backend server, and
|
||||
break your services, or expose confidential information
|
||||
to the outside the world.
|
||||
|
||||
To make this frontend as health monitor endpoint,
|
||||
specify "healthmon" parameter. This is disabled by
|
||||
default. Any requests which come through this address
|
||||
are replied with 200 HTTP status, without no body.
|
||||
|
||||
|
||||
Default: ``*,3000``
|
||||
|
||||
.. option:: --backlog=<N>
|
||||
@@ -144,20 +231,6 @@ Connections
|
||||
|
||||
Accept PROXY protocol version 1 on frontend connection.
|
||||
|
||||
.. option:: --backend-no-tls
|
||||
|
||||
Disable SSL/TLS on backend connections. For HTTP/2
|
||||
backend connections, TLS is enabled by default. For
|
||||
HTTP/1 backend connections, TLS is disabled by default,
|
||||
and can be enabled by :option:`--backend-http1-tls` option. If
|
||||
both :option:`--backend-no-tls` and :option:`\--backend-http1-tls` options
|
||||
are used, :option:`--backend-no-tls` has the precedence.
|
||||
|
||||
.. option:: --backend-http1-tls
|
||||
|
||||
Enable SSL/TLS on backend HTTP/1 connections. See also
|
||||
:option:`--backend-no-tls` option.
|
||||
|
||||
|
||||
Performance
|
||||
~~~~~~~~~~~
|
||||
@@ -237,36 +310,27 @@ Performance
|
||||
|
||||
Default: ``0``
|
||||
|
||||
.. option:: --backend-http2-connections-per-worker=<N>
|
||||
.. option:: --backend-connections-per-host=<N>
|
||||
|
||||
Set maximum number of backend HTTP/2 physical
|
||||
connections per worker. If pattern is used in :option:`-b`
|
||||
option, this limit is applied to each pattern group (in
|
||||
other words, each pattern group can have maximum <N>
|
||||
HTTP/2 connections). The default value is 0, which
|
||||
means that the value is adjusted to the number of
|
||||
backend addresses. If pattern is used, this adjustment
|
||||
is done for each pattern group.
|
||||
|
||||
.. option:: --backend-http1-connections-per-host=<N>
|
||||
|
||||
Set maximum number of backend concurrent HTTP/1
|
||||
connections per origin host. This option is meaningful
|
||||
when :option:`-s` option is used. The origin host is determined
|
||||
by authority portion of request URI (or :authority
|
||||
header field for HTTP/2). To limit the number of
|
||||
connections per frontend for default mode, use
|
||||
:option:`--backend-http1-connections-per-frontend`\.
|
||||
Set maximum number of backend concurrent connections
|
||||
(and/or streams in case of HTTP/2) per origin host.
|
||||
This option is meaningful when :option:`--http2-proxy` option is
|
||||
used. The origin host is determined by authority
|
||||
portion of request URI (or :authority header field for
|
||||
HTTP/2). To limit the number of connections per
|
||||
frontend for default mode, use
|
||||
:option:`--backend-connections-per-frontend`\.
|
||||
|
||||
Default: ``8``
|
||||
|
||||
.. option:: --backend-http1-connections-per-frontend=<N>
|
||||
.. option:: --backend-connections-per-frontend=<N>
|
||||
|
||||
Set maximum number of backend concurrent HTTP/1
|
||||
connections per frontend. This option is only used for
|
||||
default mode. 0 means unlimited. To limit the number
|
||||
of connections per host for HTTP/2 or SPDY proxy mode
|
||||
(-s option), use :option:`--backend-http1-connections-per-host`\.
|
||||
Set maximum number of backend concurrent connections
|
||||
(and/or streams in case of HTTP/2) per frontend. This
|
||||
option is only used for default mode. 0 means
|
||||
unlimited. To limit the number of connections per host
|
||||
with :option:`--http2-proxy` option, use
|
||||
:option:`--backend-connections-per-host`\.
|
||||
|
||||
Default: ``0``
|
||||
|
||||
@@ -298,6 +362,13 @@ Performance
|
||||
|
||||
Default: ``0``
|
||||
|
||||
.. option:: --no-kqueue
|
||||
|
||||
Don't use kqueue. This option is only applicable for
|
||||
the platforms which have kqueue. For other platforms,
|
||||
this option will be simply ignored.
|
||||
|
||||
|
||||
Timeout
|
||||
~~~~~~~
|
||||
|
||||
@@ -346,6 +417,13 @@ Timeout
|
||||
|
||||
Default: ``30s``
|
||||
|
||||
.. option:: --backend-connect-timeout=<DURATION>
|
||||
|
||||
Specify timeout before establishing TCP connection to
|
||||
backend.
|
||||
|
||||
Default: ``30s``
|
||||
|
||||
.. option:: --backend-keep-alive-timeout=<DURATION>
|
||||
|
||||
Specify keep-alive timeout for backend connection.
|
||||
@@ -360,6 +438,33 @@ Timeout
|
||||
|
||||
Default: ``30s``
|
||||
|
||||
.. option:: --frontend-http2-setting-timeout=<DURATION>
|
||||
|
||||
Specify timeout before SETTINGS ACK is received from
|
||||
client.
|
||||
|
||||
Default: ``10s``
|
||||
|
||||
.. option:: --backend-http2-settings-timeout=<DURATION>
|
||||
|
||||
Specify timeout before SETTINGS ACK is received from
|
||||
backend server.
|
||||
|
||||
Default: ``10s``
|
||||
|
||||
.. option:: --backend-max-backoff=<DURATION>
|
||||
|
||||
Specify maximum backoff interval. This is used when
|
||||
doing health check against offline backend (see "fail"
|
||||
parameter in :option:`--backend` option). It is also used to
|
||||
limit the maximum interval to temporarily disable
|
||||
backend when nghttpx failed to connect to it. These
|
||||
intervals are calculated using exponential backoff, and
|
||||
consecutive failed attempts increase the interval. This
|
||||
option caps its maximum value.
|
||||
|
||||
Default: ``2m``
|
||||
|
||||
|
||||
SSL/TLS
|
||||
~~~~~~~
|
||||
@@ -369,6 +474,16 @@ SSL/TLS
|
||||
Set allowed cipher list. The format of the string is
|
||||
described in OpenSSL ciphers(1).
|
||||
|
||||
.. option:: --ecdh-curves=<LIST>
|
||||
|
||||
Set supported curve list for frontend connections.
|
||||
<LIST> is a colon separated list of curve NID or names
|
||||
in the preference order. The supported curves depend on
|
||||
the linked OpenSSL library. This function requires
|
||||
OpenSSL >= 1.0.2.
|
||||
|
||||
Default: ``P-256:P-384:P-521``
|
||||
|
||||
.. option:: -k, --insecure
|
||||
|
||||
Don't verify backend server's certificate if TLS is
|
||||
@@ -388,7 +503,7 @@ SSL/TLS
|
||||
private key. If none is given and the private key is
|
||||
password protected it'll be requested interactively.
|
||||
|
||||
.. option:: --subcert=<KEYPATH>:<CERTPATH>
|
||||
.. option:: --subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
|
||||
|
||||
Specify additional certificate and private key file.
|
||||
nghttpx will choose certificates based on the hostname
|
||||
@@ -396,10 +511,14 @@ SSL/TLS
|
||||
option can be used multiple times. To make OCSP
|
||||
stapling work, <CERTPATH> must be absolute path.
|
||||
|
||||
.. option:: --backend-tls-sni-field=<HOST>
|
||||
Additional parameter can be specified in <PARAM>. The
|
||||
available <PARAM> is "sct-dir=<DIR>".
|
||||
|
||||
Explicitly set the content of the TLS SNI extension.
|
||||
This will default to the backend HOST name.
|
||||
"sct-dir=<DIR>" specifies the path to directory which
|
||||
contains \*.sct files for TLS
|
||||
signed_certificate_timestamp extension (RFC 6962). This
|
||||
feature requires OpenSSL >= 1.0.2. See also
|
||||
:option:`--tls-sct-dir` option.
|
||||
|
||||
.. option:: --dh-param-file=<PATH>
|
||||
|
||||
@@ -476,7 +595,7 @@ SSL/TLS
|
||||
ticket key sharing between nghttpx instances is not
|
||||
required.
|
||||
|
||||
.. option:: --tls-ticket-key-memcached=<HOST>,<PORT>
|
||||
.. option:: --tls-ticket-key-memcached=<HOST>,<PORT>[;tls]
|
||||
|
||||
Specify address of memcached server to get TLS ticket
|
||||
keys for session resumption. This enables shared TLS
|
||||
@@ -487,7 +606,9 @@ SSL/TLS
|
||||
replacing current set of keys. It is up to extern TLS
|
||||
ticket key generator to rotate keys frequently. See
|
||||
"TLS SESSION TICKET RESUMPTION" section in manual page
|
||||
to know the data format in memcached entry.
|
||||
to know the data format in memcached entry. Optionally,
|
||||
memcached connection can be encrypted with TLS by
|
||||
specifying "tls" parameter.
|
||||
|
||||
.. option:: --tls-ticket-key-memcached-address-family=(auto|IPv4|IPv6)
|
||||
|
||||
@@ -529,11 +650,6 @@ SSL/TLS
|
||||
either aes-128-cbc or aes-256-cbc. By default,
|
||||
aes-128-cbc is used.
|
||||
|
||||
.. option:: --tls-ticket-key-memcached-tls
|
||||
|
||||
Enable SSL/TLS on memcached connections to get TLS
|
||||
ticket keys.
|
||||
|
||||
.. option:: --tls-ticket-key-memcached-cert-file=<PATH>
|
||||
|
||||
Path to client certificate for memcached connections to
|
||||
@@ -561,11 +677,13 @@ SSL/TLS
|
||||
|
||||
Disable OCSP stapling.
|
||||
|
||||
.. option:: --tls-session-cache-memcached=<HOST>,<PORT>
|
||||
.. 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.
|
||||
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)
|
||||
|
||||
@@ -577,11 +695,6 @@ SSL/TLS
|
||||
|
||||
Default: ``auto``
|
||||
|
||||
.. option:: --tls-session-cache-memcached-tls
|
||||
|
||||
Enable SSL/TLS on memcached connections to store session
|
||||
cache.
|
||||
|
||||
.. option:: --tls-session-cache-memcached-cert-file=<PATH>
|
||||
|
||||
Path to client certificate for memcached connections to
|
||||
@@ -622,50 +735,65 @@ SSL/TLS
|
||||
See https://tools.ietf.org/html/rfc7540#appendix-A for
|
||||
the complete HTTP/2 cipher suites black list.
|
||||
|
||||
.. option:: --tls-sct-dir=<DIR>
|
||||
|
||||
Specifies the directory where \*.sct files exist. All
|
||||
\*.sct files in <DIR> are read, and sent as
|
||||
extension_data of TLS signed_certificate_timestamp (RFC
|
||||
6962) to client. These \*.sct files are for the
|
||||
certificate specified in positional command-line
|
||||
argument <CERT>, or certificate option in configuration
|
||||
file. For additional certificates, use :option:`--subcert`
|
||||
option. This option requires OpenSSL >= 1.0.2.
|
||||
|
||||
|
||||
HTTP/2 and SPDY
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. option:: -c, --http2-max-concurrent-streams=<N>
|
||||
.. option:: -c, --frontend-http2-max-concurrent-streams=<N>
|
||||
|
||||
Set the maximum number of the concurrent streams in one
|
||||
HTTP/2 and SPDY session.
|
||||
frontend HTTP/2 and SPDY session.
|
||||
|
||||
Default: `` 100``
|
||||
|
||||
.. option:: --backend-http2-max-concurrent-streams=<N>
|
||||
|
||||
Set the maximum number of the concurrent streams in one
|
||||
backend HTTP/2 session. This sets maximum number of
|
||||
concurrent opened pushed streams. The maximum number of
|
||||
concurrent requests are set by a remote server.
|
||||
|
||||
Default: ``100``
|
||||
|
||||
.. option:: --frontend-http2-window-bits=<N>
|
||||
.. option:: --frontend-http2-window-size=<SIZE>
|
||||
|
||||
Sets the per-stream initial window size of HTTP/2 SPDY
|
||||
frontend connection. For HTTP/2, the size is 2\*\*<N>-1.
|
||||
For SPDY, the size is 2\*\*<N>.
|
||||
Sets the per-stream initial window size of HTTP/2 and
|
||||
SPDY frontend connection.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``65535``
|
||||
|
||||
.. option:: --frontend-http2-connection-window-bits=<N>
|
||||
.. option:: --frontend-http2-connection-window-size=<SIZE>
|
||||
|
||||
Sets the per-connection window size of HTTP/2 and SPDY
|
||||
frontend connection. For HTTP/2, the size is
|
||||
2**<N>-1. For SPDY, the size is 2\*\*<N>.
|
||||
frontend connection. For SPDY connection, the value
|
||||
less than 64KiB is rounded up to 64KiB.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``65535``
|
||||
|
||||
.. option:: --frontend-no-tls
|
||||
|
||||
Disable SSL/TLS on frontend connections.
|
||||
|
||||
.. option:: --backend-http2-window-bits=<N>
|
||||
.. option:: --backend-http2-window-size=<SIZE>
|
||||
|
||||
Sets the initial window size of HTTP/2 backend
|
||||
connection to 2\*\*<N>-1.
|
||||
connection.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``65535``
|
||||
|
||||
.. option:: --backend-http2-connection-window-bits=<N>
|
||||
.. option:: --backend-http2-connection-window-size=<SIZE>
|
||||
|
||||
Sets the per-connection window size of HTTP/2 backend
|
||||
connection to 2\*\*<N>-1.
|
||||
connection.
|
||||
|
||||
Default: ``16``
|
||||
Default: ``2147483647``
|
||||
|
||||
.. option:: --http2-no-cookie-crumbling
|
||||
|
||||
@@ -683,11 +811,69 @@ HTTP/2 and SPDY
|
||||
Disable HTTP/2 server push. Server push is supported by
|
||||
default mode and HTTP/2 frontend via Link header field.
|
||||
It is also supported if both frontend and backend are
|
||||
HTTP/2 (which implies :option:`--http2-bridge` or :option:`\--client` mode).
|
||||
In this case, server push from backend session is
|
||||
relayed to frontend, and server push via Link header
|
||||
field is also supported. HTTP SPDY frontend does not
|
||||
support server push.
|
||||
HTTP/2 in default mode. In this case, server push from
|
||||
backend session is relayed to frontend, and server push
|
||||
via Link header field is also supported. SPDY frontend
|
||||
does not support server push.
|
||||
|
||||
.. option:: --frontend-http2-optimize-write-buffer-size
|
||||
|
||||
(Experimental) Enable write buffer size optimization in
|
||||
frontend HTTP/2 TLS connection. This optimization aims
|
||||
to reduce write buffer size so that it only contains
|
||||
bytes which can send immediately. This makes server
|
||||
more responsive to prioritized HTTP/2 stream because the
|
||||
buffering of lower priority stream is reduced. This
|
||||
option is only effective on recent Linux platform.
|
||||
|
||||
.. option:: --frontend-http2-optimize-window-size
|
||||
|
||||
(Experimental) Automatically tune connection level
|
||||
window size of frontend HTTP/2 TLS connection. If this
|
||||
feature is enabled, connection window size starts with
|
||||
the default window size, 65535 bytes. nghttpx
|
||||
automatically adjusts connection window size based on
|
||||
TCP receiving window size. The maximum window size is
|
||||
capped by the value specified by
|
||||
:option:`--frontend-http2-connection-window-size`\. Since the
|
||||
stream is subject to stream level window size, it should
|
||||
be adjusted using :option:`--frontend-http2-window-size` option as
|
||||
well. This option is only effective on recent Linux
|
||||
platform.
|
||||
|
||||
.. option:: --frontend-http2-encoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the frontend HTTP/2 connection. The decoder (client)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which client specified.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --frontend-http2-decoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the frontend HTTP/2 connection.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --backend-http2-encoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK encoder
|
||||
in the backend HTTP/2 connection. The decoder (backend)
|
||||
specifies the maximum dynamic table size it accepts.
|
||||
Then the negotiated dynamic table size is the minimum of
|
||||
this option value and the value which backend specified.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
.. option:: --backend-http2-decoder-dynamic-table-size=<SIZE>
|
||||
|
||||
Specify the maximum dynamic table size of HPACK decoder
|
||||
in the backend HTTP/2 connection.
|
||||
|
||||
Default: ``4K``
|
||||
|
||||
|
||||
Mode
|
||||
@@ -696,38 +882,16 @@ Mode
|
||||
.. describe:: (default mode)
|
||||
|
||||
|
||||
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. If
|
||||
:option:`--frontend-no-tls` is used, accept HTTP/2 and HTTP/1.1.
|
||||
The incoming HTTP/1.1 connection can be upgraded to
|
||||
HTTP/2 through HTTP Upgrade. The protocol to the
|
||||
backend is HTTP/1.1.
|
||||
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no-tls"
|
||||
parameter is used in :option:`--frontend` option, accept HTTP/2
|
||||
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
|
||||
connection can be upgraded to HTTP/2 through HTTP
|
||||
Upgrade.
|
||||
|
||||
.. option:: -s, --http2-proxy
|
||||
|
||||
Like default mode, but enable secure proxy mode.
|
||||
|
||||
.. option:: --http2-bridge
|
||||
|
||||
Like default mode, but communicate with the backend in
|
||||
HTTP/2 over SSL/TLS. Thus the incoming all connections
|
||||
are converted to HTTP/2 connection and relayed to the
|
||||
backend. See :option:`--backend-http-proxy-uri` option if you are
|
||||
behind the proxy and want to connect to the outside
|
||||
HTTP/2 proxy.
|
||||
|
||||
.. option:: --client
|
||||
|
||||
Accept HTTP/2 and HTTP/1.1 without SSL/TLS. The
|
||||
incoming HTTP/1.1 connection can be upgraded to HTTP/2
|
||||
connection through HTTP Upgrade. The protocol to the
|
||||
backend is HTTP/2. To use nghttpx as a forward proxy,
|
||||
use :option:`-p` option instead.
|
||||
|
||||
.. option:: -p, --client-proxy
|
||||
|
||||
Like :option:`--client` option, but it also requires the request
|
||||
path from frontend must be an absolute URI, suitable for
|
||||
use as a forward proxy.
|
||||
Like default mode, but enable forward proxy. This is so
|
||||
called HTTP/2 proxy mode.
|
||||
|
||||
|
||||
Logging
|
||||
@@ -778,6 +942,10 @@ Logging
|
||||
* $ssl_session_id: session ID for SSL/TLS connection.
|
||||
* $ssl_session_reused: "r" if SSL/TLS session was
|
||||
reused. Otherwise, "."
|
||||
* $backend_host: backend host used to fulfill the
|
||||
request. "-" if backend host is not available.
|
||||
* $backend_port: backend port used to fulfill the
|
||||
request. "-" if backend host is not available.
|
||||
|
||||
The variable can be enclosed by "{" and "}" for
|
||||
disambiguation (e.g., ${remote_addr}).
|
||||
@@ -868,17 +1036,15 @@ HTTP
|
||||
|
||||
.. option:: --no-location-rewrite
|
||||
|
||||
Don't rewrite location header field on :option:`--http2-bridge`\,
|
||||
:option:`--client` and default mode. For :option:`\--http2-proxy` and
|
||||
:option:`--client-proxy` mode, location header field will not be
|
||||
altered regardless of this option.
|
||||
Don't rewrite location header field in default mode.
|
||||
When :option:`--http2-proxy` is used, location header field will
|
||||
not be altered regardless of this option.
|
||||
|
||||
.. option:: --host-rewrite
|
||||
|
||||
Rewrite host and :authority header fields on
|
||||
:option:`--http2-bridge`\, :option:`--client` and default mode. For
|
||||
:option:`--http2-proxy` and :option:`\--client-proxy` mode, these headers
|
||||
will not be altered regardless of this option.
|
||||
Rewrite host and :authority header fields in default
|
||||
mode. When :option:`--http2-proxy` is used, these headers will
|
||||
not be altered regardless of this option.
|
||||
|
||||
.. option:: --altsvc=<PROTOID,PORT[,HOST,[ORIGIN]]>
|
||||
|
||||
@@ -939,6 +1105,37 @@ HTTP
|
||||
|
||||
Default: ``500``
|
||||
|
||||
.. option:: --error-page=(<CODE>|*)=<PATH>
|
||||
|
||||
Set file path to custom error page served when nghttpx
|
||||
originally generates HTTP error status code <CODE>.
|
||||
<CODE> must be greater than or equal to 400, and at most
|
||||
599. If "\*" is used instead of <CODE>, it matches all
|
||||
HTTP status code. If error status code comes from
|
||||
backend server, the custom error pages are not used.
|
||||
|
||||
.. option:: --server-name=<NAME>
|
||||
|
||||
Change server response header field value to <NAME>.
|
||||
|
||||
Default: ``nghttpx nghttp2/1.16.0``
|
||||
|
||||
.. option:: --no-server-rewrite
|
||||
|
||||
Don't rewrite server header field in default mode. When
|
||||
:option:`--http2-proxy` is used, these headers will not be altered
|
||||
regardless of this option.
|
||||
|
||||
|
||||
API
|
||||
~~~
|
||||
|
||||
.. option:: --api-max-request-body=<SIZE>
|
||||
|
||||
Set the maximum size of request body for API request.
|
||||
|
||||
Default: ``16K``
|
||||
|
||||
|
||||
Debug
|
||||
~~~~~
|
||||
@@ -1077,6 +1274,9 @@ SIGQUIT
|
||||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
|
||||
SIGHUP
|
||||
Reload configuration file given in :option:`--conf`.
|
||||
|
||||
SIGUSR1
|
||||
Reopen log files.
|
||||
|
||||
@@ -1084,7 +1284,11 @@ SIGUSR2
|
||||
Fork and execute nghttpx. It will execute the binary in the same
|
||||
path with same command-line arguments and environment variables.
|
||||
After new process comes up, sending SIGQUIT to the original process
|
||||
to perform hot swapping.
|
||||
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
|
||||
and SIGHUP is that former is usually used to execute new binary, and
|
||||
the master process is newly spawned. On the other hand, the latter
|
||||
just reloads configuration file, and the same master process
|
||||
continues to exist.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -1113,7 +1317,7 @@ backend server and extracts URI-reference with parameter
|
||||
and pushes those URIs to the frontend client. Here is a sample Link
|
||||
header field to initiate server push:
|
||||
|
||||
.. code-block:: http
|
||||
.. code-block:: text
|
||||
|
||||
Link: </fonts/font.woff>; rel=preload
|
||||
Link: </css/theme.css>; rel=preload
|
||||
@@ -1126,12 +1330,12 @@ Currently, the following restriction is applied for server push:
|
||||
This limitation may be loosened in the future release.
|
||||
|
||||
nghttpx also supports server push if both frontend and backend are
|
||||
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
|
||||
In this case, in addition to server push via Link header field, server
|
||||
push from backend is relayed to frontend HTTP/2 session.
|
||||
HTTP/2 in default mode. In this case, in addition to server push via
|
||||
Link header field, server push from backend is forwarded to frontend
|
||||
HTTP/2 session.
|
||||
|
||||
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
|
||||
:option:`--client-proxy` is used.
|
||||
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
|
||||
used.
|
||||
|
||||
UNIX DOMAIN SOCKET
|
||||
------------------
|
||||
@@ -1179,8 +1383,8 @@ 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 :option:`--tls-session-cache-memcached-tls`
|
||||
option.
|
||||
enable encryption, use ``tls`` keyword in
|
||||
:option:`--tls-session-cache-memcached` option.
|
||||
|
||||
TLS SESSION TICKET RESUMPTION
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -1222,14 +1426,32 @@ keys. The key appeared first is used as encryption key. All the
|
||||
remaining keys are used as decryption only.
|
||||
|
||||
By default, connections to memcached server are not encrypted. To
|
||||
enable encryption, use :option:`--tls-ticket-key-memcached-tls`
|
||||
option.
|
||||
enable encryption, use ``tls`` keyword in
|
||||
:option:`--tls-ticket-key-memcached` option.
|
||||
|
||||
If :option:`--tls-ticket-key-file` is given, encryption key is read
|
||||
from the given file. In this case, nghttpx does not rotate key
|
||||
automatically. To rotate key, one has to restart nghttpx (see
|
||||
SIGNALS).
|
||||
|
||||
CERTIFICATE TRANSPARENCY
|
||||
------------------------
|
||||
|
||||
nghttpx supports TLS ``signed_certificate_timestamp`` extension (`RFC
|
||||
6962 <https://tools.ietf.org/html/rfc6962>`_). The relevant options
|
||||
are :option:`--tls-sct-dir` and ``sct-dir`` parameter in
|
||||
:option:`--subcert`. They takes a directory, and nghttpx reads all
|
||||
files whose extension is ``.sct`` under the directory. The ``*.sct``
|
||||
files are encoded as ``SignedCertificateTimestamp`` struct described
|
||||
in `section 3.2 of RFC 69662
|
||||
<https://tools.ietf.org/html/rfc6962#section-3.2>`_. This format is
|
||||
the same one used by `nginx-ct
|
||||
<https://github.com/grahamedgecombe/nginx-ct>`_ and `mod_ssl_ct
|
||||
<https://httpd.apache.org/docs/trunk/mod/mod_ssl_ct.html>`_.
|
||||
`ct-submit <https://github.com/grahamedgecombe/ct-submit>`_ can be
|
||||
used to submit certificates to log servers, and obtain the
|
||||
``SignedCertificateTimestamp`` struct which can be used with nghttpx.
|
||||
|
||||
MRUBY SCRIPTING
|
||||
---------------
|
||||
|
||||
@@ -1293,7 +1515,28 @@ respectively.
|
||||
|
||||
.. rb:attr_reader:: remote_addr
|
||||
|
||||
Return IP address of a remote client.
|
||||
Return IP address of a remote client. If connection is made
|
||||
via UNIX domain socket, this returns the string "localhost".
|
||||
|
||||
.. rb:attr_reader:: server_addr
|
||||
|
||||
Return address of server that accepted the connection. This
|
||||
is a string which specified in :option:`--frontend` option,
|
||||
excluding port number, and not a resolved IP address. For
|
||||
UNIX domain socket, this is a path to UNIX domain socket.
|
||||
|
||||
.. rb:attr_reader:: server_port
|
||||
|
||||
Return port number of the server frontend which accepted the
|
||||
connection from client.
|
||||
|
||||
.. rb:attr_reader:: tls_used
|
||||
|
||||
Return true if TLS is used on the connection.
|
||||
|
||||
.. rb:attr_reader:: tls_sni
|
||||
|
||||
Return the TLS SNI value which client sent in this connection.
|
||||
|
||||
.. rb:class:: Request
|
||||
|
||||
@@ -1329,7 +1572,13 @@ respectively.
|
||||
|
||||
Request path, including query component (i.e., /index.html).
|
||||
On assignment, copy of given value is assigned. The path does
|
||||
not include authority component of URI.
|
||||
not include authority component of URI. This may include
|
||||
query component. nghttpx makes certain normalization for
|
||||
path. It decodes percent-encoding for unreserved characters
|
||||
(see https://tools.ietf.org/html/rfc3986#section-2.3), and
|
||||
resolves ".." and ".". But it may leave characters which
|
||||
should be percent-encoded as is. So be careful when comparing
|
||||
path against desired string.
|
||||
|
||||
.. rb:attr_reader:: headers
|
||||
|
||||
@@ -1356,7 +1605,7 @@ respectively.
|
||||
|
||||
Clear all existing request header fields.
|
||||
|
||||
.. rb:method:: push uri
|
||||
.. rb:method:: push(uri)
|
||||
|
||||
Initiate to push resource identified by *uri*. Only HTTP/2
|
||||
protocol supports this feature. For the other protocols, this
|
||||
@@ -1467,6 +1716,62 @@ addresses:
|
||||
|
||||
App.new
|
||||
|
||||
API ENDPOINTS
|
||||
-------------
|
||||
|
||||
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
|
||||
default, API endpoint is disabled. To enable it, add a dedicated
|
||||
frontend for API using :option:`--frontend` option with "api"
|
||||
parameter. All requests which come from this frontend address, will
|
||||
be treated as API request.
|
||||
|
||||
The response is normally JSON dictionary, and at least includes the
|
||||
following keys:
|
||||
|
||||
status
|
||||
The status of the request processing. The following values are
|
||||
defined:
|
||||
|
||||
Success
|
||||
The request was successful.
|
||||
|
||||
Failure
|
||||
The request was failed. No change has been made.
|
||||
|
||||
code
|
||||
HTTP status code
|
||||
|
||||
We wrote "normally", since nghttpx may return ordinal HTML response in
|
||||
some cases where the error has occurred before reaching API endpoint
|
||||
(e.g., header field is too large).
|
||||
|
||||
The following section describes available API endpoints.
|
||||
|
||||
PUT /api/v1beta1/backendconfig
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This API replaces the current backend server settings with the
|
||||
requested ones. The request method should be PUT, but POST is also
|
||||
acceptable. The request body must be nghttpx configuration file
|
||||
format. For configuration file format, see `FILES`_ section. The
|
||||
line separator inside the request body must be single LF (0x0A).
|
||||
Currently, only :option:`backend <--backend>` option is parsed, the
|
||||
others are simply ignored. The semantics of this API is replace the
|
||||
current backend with the backend options in request body. Describe
|
||||
the desired set of backend severs, and nghttpx makes it happen. If
|
||||
there is no :option:`backend <--backend>` option is found in request
|
||||
body, the current set of backend is replaced with the :option:`backend
|
||||
<--backend>` option's default value, which is ``127.0.0.1,80``.
|
||||
|
||||
The replacement is done instantly without breaking existing
|
||||
connections or requests. It also avoids any process creation as is
|
||||
the case with hot swapping with signals.
|
||||
|
||||
The one limitation is that only numeric IP address is allowd in
|
||||
:option:`backend <--backend>` in request body while non numeric
|
||||
hostname is allowed in command-line or configuration file is read
|
||||
using :option:`--conf`.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
|
||||
136
doc/nghttpx.h2r
136
doc/nghttpx.h2r
@@ -49,6 +49,9 @@ SIGQUIT
|
||||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
|
||||
SIGHUP
|
||||
Reload configuration file given in :option:`--conf`.
|
||||
|
||||
SIGUSR1
|
||||
Reopen log files.
|
||||
|
||||
@@ -56,7 +59,11 @@ SIGUSR2
|
||||
Fork and execute nghttpx. It will execute the binary in the same
|
||||
path with same command-line arguments and environment variables.
|
||||
After new process comes up, sending SIGQUIT to the original process
|
||||
to perform hot swapping.
|
||||
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
|
||||
and SIGHUP is that former is usually used to execute new binary, and
|
||||
the master process is newly spawned. On the other hand, the latter
|
||||
just reloads configuration file, and the same master process
|
||||
continues to exist.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -85,7 +92,7 @@ backend server and extracts URI-reference with parameter
|
||||
and pushes those URIs to the frontend client. Here is a sample Link
|
||||
header field to initiate server push:
|
||||
|
||||
.. code-block:: http
|
||||
.. code-block:: text
|
||||
|
||||
Link: </fonts/font.woff>; rel=preload
|
||||
Link: </css/theme.css>; rel=preload
|
||||
@@ -98,12 +105,12 @@ Currently, the following restriction is applied for server push:
|
||||
This limitation may be loosened in the future release.
|
||||
|
||||
nghttpx also supports server push if both frontend and backend are
|
||||
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
|
||||
In this case, in addition to server push via Link header field, server
|
||||
push from backend is relayed to frontend HTTP/2 session.
|
||||
HTTP/2 in default mode. In this case, in addition to server push via
|
||||
Link header field, server push from backend is forwarded to frontend
|
||||
HTTP/2 session.
|
||||
|
||||
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
|
||||
:option:`--client-proxy` is used.
|
||||
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
|
||||
used.
|
||||
|
||||
UNIX DOMAIN SOCKET
|
||||
------------------
|
||||
@@ -151,8 +158,8 @@ 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 :option:`--tls-session-cache-memcached-tls`
|
||||
option.
|
||||
enable encryption, use ``tls`` keyword in
|
||||
:option:`--tls-session-cache-memcached` option.
|
||||
|
||||
TLS SESSION TICKET RESUMPTION
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -194,14 +201,32 @@ keys. The key appeared first is used as encryption key. All the
|
||||
remaining keys are used as decryption only.
|
||||
|
||||
By default, connections to memcached server are not encrypted. To
|
||||
enable encryption, use :option:`--tls-ticket-key-memcached-tls`
|
||||
option.
|
||||
enable encryption, use ``tls`` keyword in
|
||||
:option:`--tls-ticket-key-memcached` option.
|
||||
|
||||
If :option:`--tls-ticket-key-file` is given, encryption key is read
|
||||
from the given file. In this case, nghttpx does not rotate key
|
||||
automatically. To rotate key, one has to restart nghttpx (see
|
||||
SIGNALS).
|
||||
|
||||
CERTIFICATE TRANSPARENCY
|
||||
------------------------
|
||||
|
||||
nghttpx supports TLS ``signed_certificate_timestamp`` extension (`RFC
|
||||
6962 <https://tools.ietf.org/html/rfc6962>`_). The relevant options
|
||||
are :option:`--tls-sct-dir` and ``sct-dir`` parameter in
|
||||
:option:`--subcert`. They takes a directory, and nghttpx reads all
|
||||
files whose extension is ``.sct`` under the directory. The ``*.sct``
|
||||
files are encoded as ``SignedCertificateTimestamp`` struct described
|
||||
in `section 3.2 of RFC 69662
|
||||
<https://tools.ietf.org/html/rfc6962#section-3.2>`_. This format is
|
||||
the same one used by `nginx-ct
|
||||
<https://github.com/grahamedgecombe/nginx-ct>`_ and `mod_ssl_ct
|
||||
<https://httpd.apache.org/docs/trunk/mod/mod_ssl_ct.html>`_.
|
||||
`ct-submit <https://github.com/grahamedgecombe/ct-submit>`_ can be
|
||||
used to submit certificates to log servers, and obtain the
|
||||
``SignedCertificateTimestamp`` struct which can be used with nghttpx.
|
||||
|
||||
MRUBY SCRIPTING
|
||||
---------------
|
||||
|
||||
@@ -265,7 +290,28 @@ respectively.
|
||||
|
||||
.. rb:attr_reader:: remote_addr
|
||||
|
||||
Return IP address of a remote client.
|
||||
Return IP address of a remote client. If connection is made
|
||||
via UNIX domain socket, this returns the string "localhost".
|
||||
|
||||
.. rb:attr_reader:: server_addr
|
||||
|
||||
Return address of server that accepted the connection. This
|
||||
is a string which specified in :option:`--frontend` option,
|
||||
excluding port number, and not a resolved IP address. For
|
||||
UNIX domain socket, this is a path to UNIX domain socket.
|
||||
|
||||
.. rb:attr_reader:: server_port
|
||||
|
||||
Return port number of the server frontend which accepted the
|
||||
connection from client.
|
||||
|
||||
.. rb:attr_reader:: tls_used
|
||||
|
||||
Return true if TLS is used on the connection.
|
||||
|
||||
.. rb:attr_reader:: tls_sni
|
||||
|
||||
Return the TLS SNI value which client sent in this connection.
|
||||
|
||||
.. rb:class:: Request
|
||||
|
||||
@@ -301,7 +347,13 @@ respectively.
|
||||
|
||||
Request path, including query component (i.e., /index.html).
|
||||
On assignment, copy of given value is assigned. The path does
|
||||
not include authority component of URI.
|
||||
not include authority component of URI. This may include
|
||||
query component. nghttpx makes certain normalization for
|
||||
path. It decodes percent-encoding for unreserved characters
|
||||
(see https://tools.ietf.org/html/rfc3986#section-2.3), and
|
||||
resolves ".." and ".". But it may leave characters which
|
||||
should be percent-encoded as is. So be careful when comparing
|
||||
path against desired string.
|
||||
|
||||
.. rb:attr_reader:: headers
|
||||
|
||||
@@ -328,7 +380,7 @@ respectively.
|
||||
|
||||
Clear all existing request header fields.
|
||||
|
||||
.. rb:method:: push uri
|
||||
.. rb:method:: push(uri)
|
||||
|
||||
Initiate to push resource identified by *uri*. Only HTTP/2
|
||||
protocol supports this feature. For the other protocols, this
|
||||
@@ -439,6 +491,62 @@ addresses:
|
||||
|
||||
App.new
|
||||
|
||||
API ENDPOINTS
|
||||
-------------
|
||||
|
||||
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
|
||||
default, API endpoint is disabled. To enable it, add a dedicated
|
||||
frontend for API using :option:`--frontend` option with "api"
|
||||
parameter. All requests which come from this frontend address, will
|
||||
be treated as API request.
|
||||
|
||||
The response is normally JSON dictionary, and at least includes the
|
||||
following keys:
|
||||
|
||||
status
|
||||
The status of the request processing. The following values are
|
||||
defined:
|
||||
|
||||
Success
|
||||
The request was successful.
|
||||
|
||||
Failure
|
||||
The request was failed. No change has been made.
|
||||
|
||||
code
|
||||
HTTP status code
|
||||
|
||||
We wrote "normally", since nghttpx may return ordinal HTML response in
|
||||
some cases where the error has occurred before reaching API endpoint
|
||||
(e.g., header field is too large).
|
||||
|
||||
The following section describes available API endpoints.
|
||||
|
||||
PUT /api/v1beta1/backendconfig
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This API replaces the current backend server settings with the
|
||||
requested ones. The request method should be PUT, but POST is also
|
||||
acceptable. The request body must be nghttpx configuration file
|
||||
format. For configuration file format, see `FILES`_ section. The
|
||||
line separator inside the request body must be single LF (0x0A).
|
||||
Currently, only :option:`backend <--backend>` option is parsed, the
|
||||
others are simply ignored. The semantics of this API is replace the
|
||||
current backend with the backend options in request body. Describe
|
||||
the desired set of backend severs, and nghttpx makes it happen. If
|
||||
there is no :option:`backend <--backend>` option is found in request
|
||||
body, the current set of backend is replaced with the :option:`backend
|
||||
<--backend>` option's default value, which is ``127.0.0.1,80``.
|
||||
|
||||
The replacement is done instantly without breaking existing
|
||||
connections or requests. It also avoids any process creation as is
|
||||
the case with hot swapping with signals.
|
||||
|
||||
The one limitation is that only numeric IP address is allowd in
|
||||
:option:`backend <--backend>` in request body while non numeric
|
||||
hostname is allowed in command-line or configuration file is read
|
||||
using :option:`--conf`.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ functions, and it also interacts with it via many API function calls.
|
||||
An application can create as many :type:`nghttp2_session` object as it
|
||||
wants. But single :type:`nghttp2_session` object must be used by a
|
||||
single thread at the same time. This is not so hard to enforce since
|
||||
most event-based architecture applicatons use is single thread per
|
||||
most event-based architecture applications use is single thread per
|
||||
core, and handling one connection I/O is done by single thread.
|
||||
|
||||
To feed input to :type:`nghttp2_session` object, one can use
|
||||
@@ -57,6 +57,23 @@ doubt, use `nghttp2_session_mem_send()` since it is simpler. But
|
||||
`nghttp2_session_send()` might be easier to use if the output buffer
|
||||
an application has is fixed sized.
|
||||
|
||||
In general, an application should call `nghttp2_session_mem_send()`
|
||||
when it gets input from underlying connection. Since there is great
|
||||
chance to get something pushed into transmission queue while the call
|
||||
of `nghttp2_session_mem_send()`, it is recommended to call
|
||||
`nghttp2_session_mem_recv()` after `nghttp2_session_mem_send()`.
|
||||
|
||||
There is a question when we are safe to close HTTP/2 session without
|
||||
waiting for the closure of underlying connection. We offer 2 API
|
||||
calls for this: `nghttp2_session_want_read()` and
|
||||
`nghttp2_session_want_write()`. If they both return 0, application
|
||||
can destroy :type:`nghttp2_session`, and then close the underlying
|
||||
connection. But make sure that the buffered output has been
|
||||
transmitted to the peer before closing the connection when
|
||||
`nghttp2_session_mem_send()` is used, since
|
||||
`nghttp2_session_want_write()` does not take into account the
|
||||
transmission of the buffered data outside of :type:`nghttp2_session`.
|
||||
|
||||
Includes
|
||||
--------
|
||||
|
||||
@@ -159,3 +176,300 @@ header field if it is present (this does not include padding bytes).
|
||||
Any deviation results in stream error of type PROTOCOL_ERROR. If
|
||||
error is found in PUSH_PROMISE frame, stream error is raised against
|
||||
promised stream.
|
||||
|
||||
The order of transmission of the HTTP/2 frames
|
||||
----------------------------------------------
|
||||
|
||||
This section describes the internals of libnghttp2 about the
|
||||
scheduling of transmission of HTTP/2 frames. This is pretty much
|
||||
internal stuff, so the details could change in the future versions of
|
||||
the library.
|
||||
|
||||
libnghttp2 categorizes HTTP/2 frames into 4 categories: urgent,
|
||||
regular, syn_stream, and data in the order of higher priority.
|
||||
|
||||
The urgent category includes PING and SETTINGS. They are sent with
|
||||
highest priority. The order inside the category is FIFO.
|
||||
|
||||
The regular category includes frames other than PING, SETTINGS, DATA,
|
||||
and HEADERS which does not create stream (which counts toward
|
||||
concurrent stream limit). The order inside the category is FIFO.
|
||||
|
||||
The syn_stream category includes HEADERS frame which creates stream,
|
||||
that counts toward the concurrent stream limit.
|
||||
|
||||
The data category includes DATA frame, and the scheduling among DATA
|
||||
frames are determined by HTTP/2 dependency tree.
|
||||
|
||||
If the application wants to send frames in the specific order, and the
|
||||
default transmission order does not fit, it has to schedule frames by
|
||||
itself using the callbacks (e.g.,
|
||||
:type:`nghttp2_on_frame_send_callback`).
|
||||
|
||||
RST_STREAM has special side effect when it is submitted by
|
||||
`nghttp2_submit_rst_stream()`. It cancels all pending HEADERS and
|
||||
DATA frames whose stream ID matches the one in the RST_STREAM frame.
|
||||
This may cause unexpected behaviour for the application in some cases.
|
||||
For example, suppose that application wants to send RST_STREAM after
|
||||
sending response HEADERS and DATA. Because of the reason we mentioned
|
||||
above, the following code does not work:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_submit_response(...)
|
||||
nghttp2_submit_rst_stream(...)
|
||||
|
||||
RST_STREAM cancels HEADERS (and DATA), and just RST_STREAM is sent.
|
||||
The correct way is use :type:`nghttp2_on_frame_send_callback`, and
|
||||
after HEADERS and DATA frames are sent, issue
|
||||
`nghttp2_submit_rst_stream()`. FYI,
|
||||
:type:`nghttp2_on_frame_not_send_callback` tells you why frames are
|
||||
not sent.
|
||||
|
||||
Implement user defined HTTP/2 non-critical extensions
|
||||
-----------------------------------------------------
|
||||
|
||||
As of nghttp2 v1.8.0, we have added HTTP/2 non-critical extension
|
||||
framework, which lets application send and receive user defined custom
|
||||
HTTP/2 non-critical extension frames. nghttp2 also offers built-in
|
||||
functionality to send and receive official HTTP/2 extension frames
|
||||
(e.g., ALTSVC frame). For these built-in handler, refer to the next
|
||||
section.
|
||||
|
||||
To send extension frame, use `nghttp2_submit_extension()`, and
|
||||
implement :type:`nghttp2_pack_extension_callback`. The callback
|
||||
implements how to encode data into wire format. The callback must be
|
||||
set to :type:`nghttp2_session_callbacks` using
|
||||
`nghttp2_session_callbacks_set_pack_extension_callback()`.
|
||||
|
||||
For example, we will illustrate how to send `ALTSVC
|
||||
<https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-14>`_ frame.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef struct {
|
||||
const char *origin;
|
||||
const char *field;
|
||||
} alt_svc;
|
||||
|
||||
ssize_t pack_extension_callback(nghttp2_session *session, uint8_t *buf,
|
||||
size_t len, const nghttp2_frame *frame,
|
||||
void *user_data) {
|
||||
const alt_svc *altsvc = (const alt_svc *)frame->ext.payload;
|
||||
size_t originlen = strlen(altsvc->origin);
|
||||
size_t fieldlen = strlen(altsvc->field);
|
||||
|
||||
uint8_t *p;
|
||||
|
||||
if (len < 2 + originlen + fieldlen || originlen > 0xffff) {
|
||||
return NGHTTP2_ERR_CANCEL;
|
||||
}
|
||||
|
||||
p = buf;
|
||||
*p++ = originlen >> 8;
|
||||
*p++ = originlen & 0xff;
|
||||
memcpy(p, altsvc->origin, originlen);
|
||||
p += originlen;
|
||||
memcpy(p, altsvc->field, fieldlen);
|
||||
p += fieldlen;
|
||||
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
This implements :type:`nghttp2_pack_extension_callback`. We have to
|
||||
set this callback to :type:`nghttp2_session_callbacks`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_session_callbacks_set_pack_extension_callback(
|
||||
callbacks, pack_extension_callback);
|
||||
|
||||
To send ALTSVC frame, call `nghttp2_submit_extension()`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
static const alt_svc altsvc = {"example.com", "h2=\":8000\""};
|
||||
|
||||
nghttp2_submit_extension(session, 0xa, NGHTTP2_FLAG_NONE, 0,
|
||||
(void *)&altsvc);
|
||||
|
||||
Notice that ALTSVC is use frame type ``0xa``.
|
||||
|
||||
To receive extension frames, implement 2 callbacks:
|
||||
:type:`nghttp2_unpack_extension_callback` and
|
||||
:type:`nghttp2_on_extension_chunk_recv_callback`.
|
||||
:type:`nghttp2_unpack_extension_callback` implements the way how to
|
||||
decode wire format. :type:`nghttp2_on_extension_chunk_recv_callback`
|
||||
implements how to buffer the incoming extension payload. These
|
||||
callbacks must be set using
|
||||
`nghttp2_session_callbacks_set_unpack_extension_callback()` and
|
||||
`nghttp2_session_callbacks_set_on_extension_chunk_recv_callback()`
|
||||
respectively. The application also must tell the library which
|
||||
extension frame type it is willing to receive using
|
||||
`nghttp2_option_set_user_recv_extension_type()`. Note that the
|
||||
application has to create :type:`nghttp2_option` object for that
|
||||
purpose, and initialize session with it.
|
||||
|
||||
We use ALTSVC again to illustrate how to receive extension frames. We
|
||||
use different ``alt_svc`` struct than the previous one.
|
||||
|
||||
First implement 2 callbacks. We store incoming ALTSVC payload to
|
||||
global variable ``altsvc_buffer``. Don't do this in production code
|
||||
since this is not thread safe:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
typedef struct {
|
||||
const uint8_t *origin;
|
||||
size_t originlen;
|
||||
const uint8_t *field;
|
||||
size_t fieldlen;
|
||||
} alt_svc;
|
||||
|
||||
/* buffers incoming ALTSVC payload */
|
||||
uint8_t altsvc_buffer[4096];
|
||||
/* The length of byte written to altsvc_buffer */
|
||||
size_t altsvc_bufferlen = 0;
|
||||
|
||||
int on_extension_chunk_recv_callback(nghttp2_session *session,
|
||||
const nghttp2_frame_hd *hd,
|
||||
const uint8_t *data, size_t len,
|
||||
void *user_data) {
|
||||
if (sizeof(altsvc_buffer) < altsvc_bufferlen + len) {
|
||||
altsvc_bufferlen = 0;
|
||||
return NGHTTP2_ERR_CANCEL;
|
||||
}
|
||||
|
||||
memcpy(altsvc_buffer + altsvc_bufferlen, data, len);
|
||||
altsvc_bufferlen += len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unpack_extension_callback(nghttp2_session *session, void **payload,
|
||||
const nghttp2_frame_hd *hd, void *user_data) {
|
||||
uint8_t *origin, *field;
|
||||
size_t originlen, fieldlen;
|
||||
uint8_t *p, *end;
|
||||
alt_svc *altsvc;
|
||||
|
||||
if (altsvc_bufferlen < 2) {
|
||||
altsvc_bufferlen = 0;
|
||||
return NGHTTP2_ERR_CANCEL;
|
||||
}
|
||||
|
||||
p = altsvc_buffer;
|
||||
end = altsvc_buffer + altsvc_bufferlen;
|
||||
|
||||
originlen = ((*p) << 8) + *(p + 1);
|
||||
p += 2;
|
||||
|
||||
if (p + originlen > end) {
|
||||
altsvc_bufferlen = 0;
|
||||
return NGHTTP2_ERR_CANCEL;
|
||||
}
|
||||
|
||||
origin = p;
|
||||
field = p + originlen;
|
||||
fieldlen = end - field;
|
||||
|
||||
altsvc = (alt_svc *)malloc(sizeof(alt_svc));
|
||||
altsvc->origin = origin;
|
||||
altsvc->originlen = originlen;
|
||||
altsvc->field = field;
|
||||
altsvc->fieldlen = fieldlen;
|
||||
|
||||
*payload = altsvc;
|
||||
|
||||
altsvc_bufferlen = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Set these callbacks to :type:`nghttp2_session_callbacks`:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
|
||||
callbacks, on_extension_chunk_recv_callback);
|
||||
|
||||
nghttp2_session_callbacks_set_unpack_extension_callback(
|
||||
callbacks, unpack_extension_callback);
|
||||
|
||||
|
||||
In ``unpack_extension_callback`` above, we set unpacked ``alt_svc``
|
||||
object to ``*payload``. nghttp2 library then, calls
|
||||
:type:`nghttp2_on_frame_recv_callback`, and ``*payload`` will be
|
||||
available as ``frame->ext.payload``:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int on_frame_recv_callback(nghttp2_session *session,
|
||||
const nghttp2_frame *frame, void *user_data) {
|
||||
|
||||
switch (frame->hd.type) {
|
||||
...
|
||||
case 0xa: {
|
||||
alt_svc *altsvc = (alt_svc *)frame->ext.payload;
|
||||
fprintf(stderr, "ALTSVC frame received\n");
|
||||
fprintf(stderr, " origin: %.*s\n", (int)altsvc->originlen, altsvc->origin);
|
||||
fprintf(stderr, " field : %.*s\n", (int)altsvc->fieldlen, altsvc->field);
|
||||
free(altsvc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Finally, application should set the extension frame types it is
|
||||
willing to receive:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_option_set_user_recv_extension_type(option, 0xa);
|
||||
|
||||
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
|
||||
its creation:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_session_client_new2(&session, callbacks, user_data, option);
|
||||
|
||||
How to use built-in HTTP/2 extension frame handlers
|
||||
---------------------------------------------------
|
||||
|
||||
In the previous section, we talked about the user defined HTTP/2
|
||||
extension frames. In this section, we talk about HTTP/2 extension
|
||||
frame support built into nghttp2 library.
|
||||
|
||||
As of this writing, nghttp2 supports ALTSVC extension frame. To send
|
||||
ALTSVC frame, use `nghttp2_submit_altsvc()` function.
|
||||
|
||||
To receive ALTSVC frame through built-in functionality, application
|
||||
has to use `nghttp2_option_set_builtin_recv_extension_type()` to
|
||||
indicate the willingness of receiving ALTSVC frame:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
|
||||
|
||||
This is very similar to the case when we used to receive user defined
|
||||
frames.
|
||||
|
||||
If the same frame type is set using
|
||||
`nghttp2_option_set_builtin_recv_extension_type()` and
|
||||
`nghttp2_option_set_user_recv_extension_type()`, the latter takes
|
||||
precedence. Application can implement its own frame handler rather
|
||||
than using built-in handler.
|
||||
|
||||
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
|
||||
its creation, like so:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
nghttp2_session_client_new2(&session, callbacks, user_data, option);
|
||||
|
||||
When ALTSVC is received, :type:`nghttp2_on_frame_recv_callback` will
|
||||
be called as usual.
|
||||
|
||||
|
||||
@@ -17,19 +17,16 @@ installed in the following way. First, let us introduce
|
||||
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
|
||||
for ``ANDROID_HOME``. For example, to install toolchain under
|
||||
``$ANDROID_HOME/toolchain``, do this in the the directory where NDK is
|
||||
unpacked::
|
||||
unpacked:
|
||||
|
||||
$ build/tools/make-standalone-toolchain.sh \
|
||||
--install-dir=$ANDROID_HOME/toolchain \
|
||||
--toolchain=arm-linux-androideabi-4.9 \
|
||||
--llvm-version=3.5 \
|
||||
--platform=android-16
|
||||
.. code-block:: text
|
||||
|
||||
The additional flag ``--system=linux-x86_64`` may be required if you
|
||||
are using x86_64 system.
|
||||
$ build/tools/make_standalone_toolchain.py \
|
||||
--arch arm --api 16 --stl gnustl
|
||||
--install-dir $ANDROID_HOME/toolchain
|
||||
|
||||
The platform level is not important here because we don't use Android
|
||||
specific C/C++ API.
|
||||
The API level (``--api``) is not important here because we don't use
|
||||
Android specific C/C++ API.
|
||||
|
||||
The dependent libraries, such as OpenSSL and libev should be built
|
||||
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
|
||||
@@ -45,7 +42,9 @@ spdylay as well.
|
||||
|
||||
Before running ``android-config`` and ``android-make``,
|
||||
``ANDROID_HOME`` environment variable must be set to point to the
|
||||
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``::
|
||||
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
|
||||
|
||||
@@ -133,24 +132,24 @@ To configure spdylay, use the following script:
|
||||
#!/bin/sh -e
|
||||
|
||||
if [ -z "$ANDROID_HOME" ]; then
|
||||
echo 'No $ANDROID_HOME specified.'
|
||||
exit 1
|
||||
echo 'No $ANDROID_HOME specified.'
|
||||
exit 1
|
||||
fi
|
||||
PREFIX=$ANDROID_HOME/usr/local
|
||||
TOOLCHAIN=$ANDROID_HOME/toolchain
|
||||
PATH=$TOOLCHAIN/bin:$PATH
|
||||
|
||||
./configure \
|
||||
--disable-shared \
|
||||
--host=arm-linux-androideabi \
|
||||
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
||||
--prefix=$PREFIX \
|
||||
--without-libxml2 \
|
||||
--disable-src \
|
||||
--disable-examples \
|
||||
CPPFLAGS="-I$PREFIX/include" \
|
||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||
LDFLAGS="-L$PREFIX/lib"
|
||||
--disable-shared \
|
||||
--host=arm-linux-androideabi \
|
||||
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
||||
--prefix=$PREFIX \
|
||||
--without-libxml2 \
|
||||
--disable-src \
|
||||
--disable-examples \
|
||||
CPPFLAGS="-I$PREFIX/include" \
|
||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||
LDFLAGS="-L$PREFIX/lib"
|
||||
|
||||
And run ``make install`` to build and install.
|
||||
|
||||
@@ -159,6 +158,8 @@ then ``android-make`` to compile nghttp2 source files.
|
||||
|
||||
If all went well, application binaries, such as nghttpx, are created
|
||||
under src directory. Strip debugging information from the binary
|
||||
using the following command::
|
||||
using the following command:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ arm-linux-androideabi-strip src/nghttpx
|
||||
|
||||
@@ -27,7 +27,7 @@ We use clang-format to format source code consistently. The
|
||||
clang-format configuration file .clang-format is located at the root
|
||||
directory. Since clang-format produces slightly different results
|
||||
between versions, we currently use clang-format which comes with
|
||||
clang-3.6.
|
||||
clang-3.9.
|
||||
|
||||
To detect any violation to the coding style, we recommend to setup git
|
||||
pre-commit hook to check coding style of the changes you introduced.
|
||||
@@ -35,7 +35,7 @@ The pre-commit file is located at the root directory. Copy it under
|
||||
.git/hooks and make sure that it is executable. The pre-commit script
|
||||
uses clang-format-diff.py to detect any style errors. If it is not in
|
||||
your PATH or it exists under different name (e.g.,
|
||||
clang-format-diff-3.6 in debian), either add it to PATH variable or
|
||||
clang-format-diff-3.9 in debian), either add it to PATH variable or
|
||||
add git option ``clangformatdiff.binary`` to point to the script.
|
||||
|
||||
For emacs users, integrating clang-format to emacs is very easy.
|
||||
|
||||
@@ -13,10 +13,10 @@ Compiling from source
|
||||
|
||||
h2load is compiled alongside nghttp2 and requires that the
|
||||
``--enable-apps`` flag is passed to ``./configure`` and `required
|
||||
dependencies <https://github.com/tatsuhiro-t/nghttp2#requirements>`_
|
||||
are available during compilation. For details on compiling, see
|
||||
`nghttp2: Building from Git
|
||||
<https://github.com/tatsuhiro-t/nghttp2#building-from-git>`_.
|
||||
dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are
|
||||
available during compilation. For details on compiling, see `nghttp2:
|
||||
Building from Git
|
||||
<https://github.com/nghttp2/nghttp2#building-from-git>`_.
|
||||
|
||||
Basic Usage
|
||||
-----------
|
||||
|
||||
@@ -8,7 +8,8 @@ nghttp2 - HTTP/2 C Library
|
||||
|
||||
This is an implementation of Hypertext Transfer Protocol version 2.
|
||||
|
||||
The project is hosted at `github.com/tatsuhiro-t/nghttp2 <https://github.com/tatsuhiro-t/nghttp2>`_.
|
||||
The project is hosted at `github.com/nghttp2/nghttp2
|
||||
<https://github.com/nghttp2/nghttp2>`_.
|
||||
|
||||
Contents:
|
||||
|
||||
@@ -36,17 +37,18 @@ Contents:
|
||||
asio_http2_server.h
|
||||
asio_http2_client.h
|
||||
asio_http2.h
|
||||
Source <https://github.com/tatsuhiro-t/nghttp2>
|
||||
Issues <https://github.com/tatsuhiro-t/nghttp2/issues>
|
||||
Source <https://github.com/nghttp2/nghttp2>
|
||||
Issues <https://github.com/nghttp2/nghttp2/issues>
|
||||
nghttp2.org <https://nghttp2.org/>
|
||||
|
||||
Released Versions
|
||||
=================
|
||||
|
||||
https://github.com/tatsuhiro-t/nghttp2/releases
|
||||
https://github.com/nghttp2/nghttp2/releases
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* HTTP/2 https://tools.ietf.org/html/rfc7540
|
||||
* HPACK https://tools.ietf.org/html/rfc7541
|
||||
* HTTP Alternative Services https://tools.ietf.org/html/rfc7838
|
||||
|
||||
@@ -12,42 +12,52 @@ use-cases. It also covers some useful options later.
|
||||
Default mode
|
||||
------------
|
||||
|
||||
If nghttpx is invoked without any :option:`--http2-proxy`,
|
||||
:option:`--client`, and :option:`--client-proxy`, it operates in
|
||||
default mode. In this mode, nghttpx frontend listens for HTTP/2
|
||||
requests and translates them to HTTP/1 requests. Thus it works as
|
||||
reverse proxy (gateway) for HTTP/2 clients to HTTP/1 web server. This
|
||||
is also known as "HTTP/2 router". HTTP/1 requests are also supported
|
||||
in frontend as a fallback. If nghttpx is linked with spdylay library
|
||||
and frontend connection is SSL/TLS, the frontend also supports SPDY
|
||||
If nghttpx is invoked without :option:`--http2-proxy`, it operates in
|
||||
default mode. In this mode, it works as reverse proxy (gateway) for
|
||||
both HTTP/2 and HTTP/1 clients to backend servers. This is also known
|
||||
as "HTTP/2 router". If nghttpx is linked with spdylay library and
|
||||
frontend connection is SSL/TLS, the frontend also supports SPDY
|
||||
protocol.
|
||||
|
||||
By default, this mode's frontend connection is encrypted using
|
||||
SSL/TLS. So server's private key and certificate must be supplied to
|
||||
the command line (or through configuration file). In this case, the
|
||||
frontend protocol selection will be done via ALPN or NPN.
|
||||
By default, frontend connection is encrypted using SSL/TLS. So
|
||||
server's private key and certificate must be supplied to the command
|
||||
line (or through configuration file). In this case, the frontend
|
||||
protocol selection will be done via ALPN or NPN.
|
||||
|
||||
With :option:`--frontend-no-tls` option, user can turn off SSL/TLS in
|
||||
frontend connection. In this case, SPDY protocol is not available
|
||||
even if spdylay library is liked to nghttpx. HTTP/2 and HTTP/1 are
|
||||
available on the frontend and a HTTP/1 connection can be upgraded to
|
||||
HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by sending
|
||||
HTTP/2 connection preface is also supported.
|
||||
To turn off encryption on frontend connection, use ``no-tls`` keyword
|
||||
in :option:`--frontend` option. In this case, SPDY protocol is not
|
||||
available even if spdylay library is liked to nghttpx. HTTP/2 and
|
||||
HTTP/1 are available on the frontend, and an HTTP/1 connection can be
|
||||
upgraded to HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by
|
||||
sending HTTP/2 connection preface is also supported.
|
||||
|
||||
By default, backend HTTP/1 connections are not encrypted. To enable
|
||||
TLS on HTTP/1 backend connections, use :option:`--backend-http1-tls`
|
||||
option. This applies to all mode whose backend connections are
|
||||
HTTP/1.
|
||||
nghttpx can listen on multiple frontend addresses. This is achieved
|
||||
by using multiple :option:`--frontend` options. For each frontend
|
||||
address, TLS can be enabled or disabled.
|
||||
|
||||
The backend is supposed to be HTTP/1 Web server. For example, to make
|
||||
By default, backend connections are not encrypted. To enable TLS
|
||||
encryption on backend connections, use ``tls`` keyword in
|
||||
:option:`--backend` option. Using patterns and ``proto`` keyword in
|
||||
:option:`--backend` option, backend application protocol can be
|
||||
specified per host/request path pattern. It means that you can use
|
||||
both HTTP/2 and HTTP/1 in backend connections at the same time. Note
|
||||
that default backend protocol is HTTP/1.1. To use HTTP/2 in backend,
|
||||
you have to specify ``h2`` in ``proto`` keyword in :option:`--backend`
|
||||
explicitly.
|
||||
|
||||
The backend is supposed to be Web server. For example, to make
|
||||
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
|
||||
backend HTTP/1 web server is configured to listen to HTTP/1 request at
|
||||
port 8080 in the same host, run nghttpx command-line like this::
|
||||
backend Web server is configured to listen to HTTP request at port
|
||||
8080 in the same host, run nghttpx command-line like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||
|
||||
Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
|
||||
example, you can send GET request to the server using nghttp::
|
||||
example, you can send GET request to the server using nghttp:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttp -nv https://localhost:8443/
|
||||
|
||||
@@ -58,26 +68,34 @@ If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
|
||||
:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
|
||||
protocols in frontend and backend connections are the same in `default
|
||||
mode`_. The difference is that this mode acts like forward proxy and
|
||||
assumes the backend is HTTP/1 proxy server (e.g., squid, traffic
|
||||
server). So HTTP/1 request must include absolute URI in request line.
|
||||
assumes the backend is HTTP proxy server (e.g., Squid, Apache Traffic
|
||||
Server). HTTP/1 request must include absolute URI in request line.
|
||||
|
||||
By default, frontend connection is encrypted. So this mode is also
|
||||
called secure proxy. If nghttpx is linked with spdylay, it supports
|
||||
SPDY protocols and it works as so called SPDY proxy.
|
||||
|
||||
With :option:`--frontend-no-tls` option, SSL/TLS is turned off in
|
||||
frontend connection, so the connection gets insecure.
|
||||
To turn off encryption on frontend connection, use ``no-tls`` keyword
|
||||
in :option:`--frontend` option.
|
||||
|
||||
The backend must be HTTP/1 proxy server. nghttpx supports multiple
|
||||
backend server addresses. It translates incoming requests to HTTP/1
|
||||
The backend must be HTTP proxy server. nghttpx supports multiple
|
||||
backend server addresses. It translates incoming requests to HTTP
|
||||
request to backend server. The backend server performs real proxy
|
||||
work for each request, for example, dispatching requests to the origin
|
||||
server and caching contents.
|
||||
|
||||
The backend connection is not encrypted by default. To enable
|
||||
encryption, use ``tls`` keyword in :option:`--backend` option. The
|
||||
default backend protocol is HTTP/1.1. To use HTTP/2 in backend
|
||||
connection, use :option:`--backend` option, and specify ``h2`` in
|
||||
``proto`` keyword explicitly.
|
||||
|
||||
For example, to make nghttpx listen to encrypted HTTP/2 requests at
|
||||
port 8443, and a backend HTTP/1 proxy server is configured to listen
|
||||
to HTTP/1 request at port 8080 in the same host, run nghttpx
|
||||
command-line like this::
|
||||
port 8443, and a backend HTTP proxy server is configured to listen to
|
||||
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
|
||||
like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||
|
||||
@@ -106,13 +124,17 @@ to proxy.pac file, something like this:
|
||||
|
||||
file:///path/to/proxy.pac
|
||||
|
||||
For Chromium, use following command-line::
|
||||
For Chromium, use following command-line:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||
|
||||
As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
|
||||
requires to be configured as forward proxy. Here is the minimum
|
||||
configuration items to edit::
|
||||
configuration items to edit:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
CONFIG proxy.config.reverse_proxy.enabled INT 0
|
||||
CONFIG proxy.config.url_remap.remap_required INT 0
|
||||
@@ -122,140 +144,32 @@ Consult Traffic server `documentation
|
||||
to know how to configure traffic server as forward proxy and its
|
||||
security implications.
|
||||
|
||||
Client mode
|
||||
-----------
|
||||
ALPN support
|
||||
------------
|
||||
|
||||
If nghttpx is invoked with :option:`--client` option, it operates in
|
||||
client mode. In this mode, nghttpx listens for plain, unencrypted
|
||||
HTTP/2 and HTTP/1 requests and translates them to encrypted HTTP/2
|
||||
requests to the backend. User cannot enable SSL/TLS in frontend
|
||||
connection.
|
||||
ALPN support requires OpenSSL >= 1.0.2.
|
||||
|
||||
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
|
||||
Upgrade. To disable SSL/TLS in backend connection, use
|
||||
:option:`--backend-no-tls` option.
|
||||
Disable frontend SSL/TLS
|
||||
------------------------
|
||||
|
||||
By default, the number of backend HTTP/2 connections per worker
|
||||
(thread) is determined by number of :option:`--backend` option. To
|
||||
adjust this value, use
|
||||
:option:`--backend-http2-connections-per-worker` option.
|
||||
The frontend connections are encrypted with SSL/TLS by default. To
|
||||
turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend`
|
||||
option. If this option is used, the private key and certificate are
|
||||
not required to run nghttpx.
|
||||
|
||||
The backend server is supporsed to be a HTTP/2 web server (e.g.,
|
||||
nghttpd). The one use-case of this mode is utilize existing HTTP/1
|
||||
clients to test HTTP/2 deployment. Suppose that HTTP/2 web server
|
||||
listens to port 80 without encryption. Then run nghttpx as client
|
||||
mode to access to that web server::
|
||||
Enable backend SSL/TLS
|
||||
----------------------
|
||||
|
||||
$ nghttpx --client -f127.0.0.1,8080 -b127.0.0.1,80 --backend-no-tls
|
||||
|
||||
.. note::
|
||||
|
||||
You may need :option:`--insecure` (or its shorthand :option:`-k`)
|
||||
option if HTTP/2 server enables SSL/TLS and its certificate is
|
||||
self-signed. But please note that it is insecure, and you should
|
||||
know what you are doing.
|
||||
|
||||
Then you can use curl to access HTTP/2 server via nghttpx::
|
||||
|
||||
$ curl http://localhost:8080/
|
||||
|
||||
Client proxy mode
|
||||
-----------------
|
||||
|
||||
If nghttpx is invoked with :option:`--client-proxy` (or its shorthand
|
||||
:option:`-p`) option, it operates in client proxy mode. This mode
|
||||
behaves like `client mode`_, but it works like forward proxy. So
|
||||
HTTP/1 request must include absolute URI in request line.
|
||||
|
||||
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
|
||||
Upgrade. To disable SSL/TLS in backend connection, use
|
||||
:option:`--backend-no-tls` option.
|
||||
|
||||
By default, the number of backend HTTP/2 connections per worker
|
||||
(thread) is determined by number of :option:`--backend` option. To
|
||||
adjust this value, use
|
||||
:option:`--backend-http2-connections-per-worker` option.
|
||||
|
||||
The backend server must be a HTTP/2 proxy. You can use nghttpx in
|
||||
`HTTP/2 proxy mode`_ as backend server. The one use-case of this mode
|
||||
is utilize existing HTTP/1 clients to test HTTP/2 connections between
|
||||
2 proxies. The another use-case is use this mode to aggregate local
|
||||
HTTP/1 connections to one HTTP/2 backend encrypted connection. This
|
||||
makes HTTP/1 clients which does not support secure proxy can use
|
||||
secure HTTP/2 proxy via nghttpx client mode.
|
||||
|
||||
Suppose that HTTP/2 proxy listens to port 8443, just like we saw in
|
||||
`HTTP/2 proxy mode`_. To run nghttpx in client proxy mode to access
|
||||
that server, invoke nghttpx like this::
|
||||
|
||||
$ nghttpx -p -f127.0.0.1,8080 -b127.0.0.1,8443
|
||||
|
||||
.. note::
|
||||
|
||||
You may need :option:`--insecure` (or its shorthand :option:`-k`)
|
||||
option if HTTP/2 server's certificate is self-signed. But please
|
||||
note that it is insecure, and you should know what you are doing.
|
||||
|
||||
Then you can use curl to issue HTTP request via HTTP/2 proxy::
|
||||
|
||||
$ curl --http-proxy=http://localhost:8080 http://www.google.com/
|
||||
|
||||
You can configure web browser to use localhost:8080 as forward
|
||||
proxy.
|
||||
|
||||
HTTP/2 bridge mode
|
||||
------------------
|
||||
|
||||
If nghttpx is invoked with :option:`--http2-bridge` option, it
|
||||
operates in HTTP/2 bridge mode. The supported protocols in frontend
|
||||
connections are the same in `default mode`_. The protocol in backend
|
||||
is HTTP/2 only.
|
||||
|
||||
With :option:`--frontend-no-tls` option, SSL/TLS is turned off in
|
||||
frontend connection, so the connection gets insecure. To disable
|
||||
SSL/TLS in backend connection, use :option:`--backend-no-tls` option.
|
||||
|
||||
By default, the number of backend HTTP/2 connections per worker
|
||||
(thread) is determined by number of :option:`--backend` option. To
|
||||
adjust this value, use
|
||||
:option:`--backend-http2-connections-per-worker` option.
|
||||
|
||||
The backend server is supporsed to be a HTTP/2 web server or HTTP/2
|
||||
proxy. If backend server is HTTP/2 proxy, use
|
||||
:option:`--no-location-rewrite` option to disable rewriting
|
||||
``Location`` header field.
|
||||
|
||||
The use-case of this mode is aggregate the incoming connections to one
|
||||
HTTP/2 connection. One backend HTTP/2 connection is created per
|
||||
worker (thread).
|
||||
|
||||
Disable SSL/TLS
|
||||
---------------
|
||||
|
||||
In `default mode`_, `HTTP/2 proxy mode`_ and `HTTP/2 bridge mode`_,
|
||||
frontend connections are encrypted with SSL/TLS by default. To turn
|
||||
off SSL/TLS, use :option:`--frontend-no-tls` option. If this option
|
||||
is used, the private key and certificate are not required to run
|
||||
nghttpx.
|
||||
|
||||
In `client mode`_, `client proxy mode`_ and `HTTP/2 bridge mode`_,
|
||||
backend connections are encrypted with SSL/TLS by default. To turn
|
||||
off SSL/TLS, use :option:`--backend-no-tls` option.
|
||||
|
||||
Enable SSL/TLS on HTTP/1 backend
|
||||
--------------------------------
|
||||
|
||||
In all modes which use HTTP/1 as backend protocol, backend HTTP/1
|
||||
connection is not encrypted by default. To enable encryption, use
|
||||
:option:`--backend-http1-tls` option.
|
||||
The backend connections are not encrypted by default. To enable
|
||||
SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option.
|
||||
|
||||
Enable SSL/TLS on memcached connection
|
||||
--------------------------------------
|
||||
|
||||
By default, memcached connection is not encrypted. To enable
|
||||
encryption, use :option:`--tls-ticket-key-memcached-tls` for TLS
|
||||
ticket key, and use :option:`--tls-session-cache-memcached-tls` for
|
||||
TLS session cache.
|
||||
encryption, use ``tls`` keyword in
|
||||
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
|
||||
:option:`--tls-session-cache-memcached` for TLS session cache.
|
||||
|
||||
Specifying additional server certificates
|
||||
-----------------------------------------
|
||||
@@ -297,17 +211,17 @@ Rewriting location header field
|
||||
nghttpx automatically rewrites location response header field if the
|
||||
following all conditions satisfy:
|
||||
|
||||
* URI in location header field is not absolute URI or is not https URI.
|
||||
* In the default mode (:option:`--http2-proxy` is not used)
|
||||
* :option:`--no-location-rewrite` is not used
|
||||
* URI in location header field is an absolute URI
|
||||
* URI in location header field includes non empty host component.
|
||||
* host (without port) in URI in location header field must match the
|
||||
host appearing in :authority or host header field.
|
||||
host appearing in ``:authority`` or ``host`` header field.
|
||||
|
||||
When rewrite happens, URI scheme and port are replaced with the ones
|
||||
used in frontend, and host is replaced with which appears in
|
||||
:authority or host request header field. :authority header field has
|
||||
precedence. If the above conditions are not met with the host value
|
||||
in :authority header field, rewrite is retried with the value in host
|
||||
header field.
|
||||
When rewrite happens, URI scheme is replaced with the ones used in
|
||||
frontend, and authority is replaced with which appears in
|
||||
``:authority``, or ``host`` request header field. ``:authority``
|
||||
header field has precedence over ``host``.
|
||||
|
||||
Hot swapping
|
||||
------------
|
||||
@@ -322,6 +236,9 @@ all existing frontend connections are done, the current process will
|
||||
exit. At this point, only new nghttpx process exists and serves
|
||||
incoming requests.
|
||||
|
||||
If you want to just reload configuration file without executing new
|
||||
binary, send SIGHUP to nghttpx master process.
|
||||
|
||||
Re-opening log files
|
||||
--------------------
|
||||
|
||||
@@ -331,6 +248,21 @@ re-open log files, send USR1 signal to nghttpx process. It will
|
||||
re-open files specified by :option:`--accesslog-file` and
|
||||
:option:`--errorlog-file` options.
|
||||
|
||||
Multiple frontend addresses
|
||||
---------------------------
|
||||
|
||||
nghttpx can listen on multiple frontend addresses. To specify them,
|
||||
just use :option:`--frontend` (or its shorthand :option:`-f`) option
|
||||
repeatedly. TLS can be enabled or disabled per frontend address
|
||||
basis. For example, to listen on port 443 with TLS enabled, and on
|
||||
port 80 without TLS:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
frontend=*,443
|
||||
frontend=*,80;no-tls
|
||||
|
||||
|
||||
Multiple backend addresses
|
||||
--------------------------
|
||||
|
||||
@@ -367,7 +299,19 @@ server ``[::1]:8080``, you can write like so:
|
||||
backend=::1,8080;/foo
|
||||
|
||||
Of course, you can specify both host and request path at the same
|
||||
time.
|
||||
time:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
backend=192.168.0.10,8080;example.com/foo
|
||||
|
||||
We can use ``*`` in the left most position of host to achieve wildcard
|
||||
suffix match. If ``*`` is the left most character, then the remaining
|
||||
string should match the request host suffix. ``*`` must match at
|
||||
least one character. For example, ``*.example.com`` matches
|
||||
``www.example.com`` and ``dev.example.com``, and does not match
|
||||
``example.com`` and ``nghttp2.org``. The exact match (without ``*``)
|
||||
always takes precedence over wildcard match.
|
||||
|
||||
One important thing you have to remember is that we have to specify
|
||||
default routing pattern for so called "catch all" pattern. To write
|
||||
@@ -387,5 +331,82 @@ servers ``serv1:3000`` and ``serv2:3000`` for request host
|
||||
backend=serv1,3000;example.com/myservice
|
||||
backend=serv2,3000;example.com/myservice
|
||||
|
||||
For HTTP/2 backend, see also
|
||||
:option:`--backend-http2-connections-per-worker` option.
|
||||
You can also specify backend application protocol in
|
||||
:option:`--backend` option using ``proto`` keyword after pattern.
|
||||
Utilizing this allows ngttpx to route certain request to HTTP/2, other
|
||||
requests to HTTP/1. For example, to route requests to ``/ws/`` in
|
||||
backend HTTP/1.1 connection, and use backend HTTP/2 for other
|
||||
requests, do this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
backend=serv1,3000;/;proto=h2
|
||||
backend=serv1,3000;/ws/;proto=http/1.1
|
||||
|
||||
Note that the backends share the same pattern must have the same
|
||||
backend protocol. The default backend protocol is HTTP/1.1.
|
||||
|
||||
TLS can be enabed per pattern basis:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
backend=serv1,8443;/;proto=h2;tls
|
||||
backend=serv2,8080;/ws/;proto=http/1.1
|
||||
|
||||
In the above case, connection to serv1 will be encrypted by TLS. On
|
||||
the other hand, connection to serv2 will not be encrypted by TLS.
|
||||
|
||||
Migration from nghttpx v1.8.0 or earlier
|
||||
----------------------------------------
|
||||
|
||||
As of nghttpx 1.9.0, ``--frontend-no-tls`` and ``--backend-no-tls``
|
||||
have been removed.
|
||||
|
||||
To disable encryption on frontend connection, use ``no-tls`` keyword
|
||||
in :option:`--frontend` potion:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
frontend=*,3000;no-tls
|
||||
|
||||
The TLS encryption is now disabled on backend connection in all modes
|
||||
by default. To enable encryption on backend connection, use ``tls``
|
||||
keyword in :option:`--backend` option:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
backend=127.0.0.1,8080;tls
|
||||
|
||||
As of nghttpx 1.9.0, ``--http2-bridge``, ``--client`` and
|
||||
``--client-proxy`` options have been removed. These functionality can
|
||||
be used using combinations of options.
|
||||
|
||||
Use following option instead of ``--http2-bridge``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
backend=<ADDR>,<PORT>;;proto=h2;tls
|
||||
|
||||
Use following options instead of ``--client``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
frontend=<ADDR>,<PORT>;no-tls
|
||||
backend=<ADDR>,<PORT>;;proto=h2;tls
|
||||
|
||||
Use following options instead of ``--client-proxy``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
http2-proxy=yes
|
||||
frontend=<ADDR>,<PORT>;no-tls
|
||||
backend=<ADDR>,<PORT>;;proto=h2;tls
|
||||
|
||||
We also removed ``--backend-http2-connections-per-worker`` option. It
|
||||
was present because previously the number of backend h2 connection was
|
||||
statically configured, and defaulted to 1. Now the number of backend
|
||||
h2 connection is increased on demand. We know the maximum number of
|
||||
concurrent streams per connection. When we push as many request as
|
||||
the maximum concurrency to the one connection, we create another new
|
||||
connection so that we can distribute load and avoid delay the request
|
||||
processing. This is done automatically without any configuration.
|
||||
|
||||
@@ -13,7 +13,7 @@ The extension module is called ``nghttp2``.
|
||||
determined by configure script. If the detected Python version is not
|
||||
what you expect, specify a path to Python executable in ``PYTHON``
|
||||
variable as an argument to configure script (e.g., ``./configure
|
||||
PYTHON=/usr/bin/python3.4``).
|
||||
PYTHON=/usr/bin/python3.5``).
|
||||
|
||||
HPACK API
|
||||
---------
|
||||
@@ -136,13 +136,15 @@ HTTP/2 servers
|
||||
|
||||
.. note::
|
||||
|
||||
We use :py:mod:`asyncio` for HTTP/2 server classes. Therefore,
|
||||
Python 3.4 or later is required to use these objects. To
|
||||
explicitly configure nghttp2 build to use Python 3.4, specify the
|
||||
``PYTHON`` variable to the path to Python 3.4 executable when
|
||||
invoking configure script like this::
|
||||
We use :py:mod:`asyncio` for HTTP/2 server classes, and ALPN.
|
||||
Therefore, Python 3.5 or later is required to use these objects.
|
||||
To explicitly configure nghttp2 build to use Python 3.5, specify
|
||||
the ``PYTHON`` variable to the path to Python 3.5 executable when
|
||||
invoking configure script like this:
|
||||
|
||||
$ ./configure PYTHON=/usr/bin/python3.4
|
||||
.. code-block:: text
|
||||
|
||||
$ ./configure PYTHON=/usr/bin/python3.5
|
||||
|
||||
.. py:class:: HTTP2Server(address, RequestHandlerClass, ssl=None)
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ the end of this page. It also resides in the examples directory in
|
||||
the archive or repository.
|
||||
|
||||
This simple client takes a single HTTPS URI and retrieves the resource
|
||||
at the URI. The synopsis is::
|
||||
at the URI. The synopsis is:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ libevent-client HTTPS_URI
|
||||
|
||||
@@ -31,6 +33,17 @@ protocol the library supports::
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
If you are following TLS related RFC, you know that NPN is not the
|
||||
standardized way to negotiate HTTP/2. NPN itself is not event
|
||||
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
|
||||
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
|
||||
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
|
||||
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
|
||||
ALPN support depending on OpenSSL version. OpenSSL's ALPN
|
||||
implementation does not require callback function like the above. But
|
||||
we have to instruct OpenSSL SSL_CTX to use ALPN, which we'll talk
|
||||
about soon.
|
||||
|
||||
The callback is added to the SSL_CTX object using
|
||||
``SSL_CTX_set_next_proto_select_cb()``::
|
||||
|
||||
@@ -46,9 +59,18 @@ The callback is added to the SSL_CTX object using
|
||||
SSL_OP_NO_COMPRESSION |
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
Here we see ``SSL_CTX_get_alpn_protos()`` function call. We instructs
|
||||
OpenSSL to notify the server that we support h2, ALPN identifier for
|
||||
HTTP/2.
|
||||
|
||||
The example client defines a couple of structs:
|
||||
|
||||
We define and use a ``http2_session_data`` structure to store data
|
||||
@@ -124,7 +146,27 @@ underlying network socket::
|
||||
if (events & BEV_EVENT_CONNECTED) {
|
||||
int fd = bufferevent_getfd(bev);
|
||||
int val = 1;
|
||||
const unsigned char *alpn = NULL;
|
||||
unsigned int alpnlen = 0;
|
||||
SSL *ssl;
|
||||
|
||||
fprintf(stderr, "Connected\n");
|
||||
|
||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||
|
||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (alpn == NULL) {
|
||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||
fprintf(stderr, "h2 is not negotiated\n");
|
||||
delete_http2_session_data(session_data);
|
||||
return;
|
||||
}
|
||||
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||
initialize_nghttp2_session(session_data);
|
||||
send_client_connection_header(session_data);
|
||||
@@ -144,6 +186,9 @@ underlying network socket::
|
||||
delete_http2_session_data(session_data);
|
||||
}
|
||||
|
||||
Here we validate that HTTP/2 is negotiated, and if not, drop
|
||||
connection.
|
||||
|
||||
For ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and ``BEV_EVENT_TIMEOUT``
|
||||
events, we just simply tear down the connection.
|
||||
|
||||
|
||||
@@ -78,15 +78,16 @@ header data. To initialize the object, use
|
||||
|
||||
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
|
||||
|
||||
To inflate header data, use `nghttp2_hd_inflate_hd()`::
|
||||
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
|
||||
|
||||
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_nv *nv_out, int *inflate_flags,
|
||||
uint8_t *in, size_t inlen, int in_final);
|
||||
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_nv *nv_out, int *inflate_flags,
|
||||
const uint8_t *in, size_t inlen,
|
||||
int in_final);
|
||||
|
||||
`nghttp2_hd_inflate_hd()` reads a stream of bytes and outputs a single
|
||||
header field at a time. Multiple calls are normally required to read a
|
||||
full stream of bytes and output all of the header fields.
|
||||
`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a
|
||||
single header field at a time. Multiple calls are normally required to
|
||||
read a full stream of bytes and output all of the header fields.
|
||||
|
||||
The *inflater* is the inflater object initialized above. The *nv_out*
|
||||
is a pointer to a :type:`nghttp2_nv` into which one header field may
|
||||
@@ -118,11 +119,7 @@ If *in_final* is zero and the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag is
|
||||
not set, it indicates that all given data was processed. The caller
|
||||
is required to pass additional data.
|
||||
|
||||
It is important to note that the function may produce one or more
|
||||
header fields even if *inlen* is 0 when *in_final* is nonzero, due to
|
||||
differential encoding.
|
||||
|
||||
Example usage of `nghttp2_hd_inflate_hd()` is shown in the
|
||||
Example usage of `nghttp2_hd_inflate_hd2()` is shown in the
|
||||
`inflate_header_block()` function in `deflate.c`_.
|
||||
|
||||
Finally, to delete a :type:`nghttp2_hd_inflater` object, use
|
||||
|
||||
@@ -10,7 +10,9 @@ archive or repository.
|
||||
|
||||
This simple server takes 3 arguments: The port number to listen on,
|
||||
the path to your SSL/TLS private key file, and the path to your
|
||||
certificate file. The synopsis is::
|
||||
certificate file. The synopsis is:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ libevent-server PORT /path/to/server.key /path/to/server.crt
|
||||
|
||||
@@ -25,7 +27,17 @@ application protocols the server supports to a client. In this
|
||||
example program, when creating the ``SSL_CTX`` object, we store the
|
||||
application protocol name in the wire format of NPN in a statically
|
||||
allocated buffer. This is safe because we only create one ``SSL_CTX``
|
||||
object in the program's entire lifetime::
|
||||
object in the program's entire lifetime.
|
||||
|
||||
If you are following TLS related RFC, you know that NPN is not the
|
||||
standardized way to negotiate HTTP/2. NPN itself is not even
|
||||
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
|
||||
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
|
||||
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
|
||||
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
|
||||
ALPN support depending on OpenSSL version. In ALPN, client sends the
|
||||
list of supported application protocols, and server selects one of
|
||||
them. We provide the callback for it::
|
||||
|
||||
static unsigned char next_proto_list[256];
|
||||
static size_t next_proto_list_len;
|
||||
@@ -37,6 +49,22 @@ object in the program's entire lifetime::
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in,
|
||||
unsigned int inlen, void *arg _U_) {
|
||||
int rv;
|
||||
|
||||
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
|
||||
|
||||
if (rv != 1) {
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||
SSL_CTX *ssl_ctx;
|
||||
EC_KEY *ecdh;
|
||||
@@ -51,6 +79,11 @@ object in the program's entire lifetime::
|
||||
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||
|
||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
@@ -64,6 +97,11 @@ OpenSSL implementation, we just assign the pointer to the NPN buffers
|
||||
we filled in earlier. The NPN callback function is set to the
|
||||
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
|
||||
|
||||
In ``alpn_select_proto_cb()``, we use `nghttp2_select_next_protocol()`
|
||||
to select application protocol. The `nghttp2_select_next_protocol()`
|
||||
returns 1 only if it selected h2 (ALPN identifier for HTTP/2), and out
|
||||
parameters were assigned accordingly.
|
||||
|
||||
Next, let's take a look at the main structures used by the example
|
||||
application:
|
||||
|
||||
@@ -167,11 +205,31 @@ underlying network socket::
|
||||
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
||||
http2_session_data *session_data = (http2_session_data *)ptr;
|
||||
if (events & BEV_EVENT_CONNECTED) {
|
||||
const unsigned char *alpn = NULL;
|
||||
unsigned int alpnlen = 0;
|
||||
SSL *ssl;
|
||||
|
||||
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
||||
|
||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||
|
||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (alpn == NULL) {
|
||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
|
||||
delete_http2_session_data(session_data);
|
||||
return;
|
||||
}
|
||||
|
||||
initialize_nghttp2_session(session_data);
|
||||
|
||||
if (send_server_connection_header(session_data) != 0) {
|
||||
if (send_server_connection_header(session_data) != 0 ||
|
||||
session_send(session_data) != 0) {
|
||||
delete_http2_session_data(session_data);
|
||||
return;
|
||||
}
|
||||
@@ -188,6 +246,9 @@ underlying network socket::
|
||||
delete_http2_session_data(session_data);
|
||||
}
|
||||
|
||||
Here we validate that HTTP/2 is negotiated, and if not, drop
|
||||
connection.
|
||||
|
||||
For the ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and
|
||||
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
|
||||
The ``delete_http2_session_data()`` function destroys the
|
||||
|
||||
53
examples/CMakeLists.txt
Normal file
53
examples/CMakeLists.txt
Normal file
@@ -0,0 +1,53 @@
|
||||
if(ENABLE_EXAMPLES)
|
||||
file(GLOB c_sources *.c)
|
||||
set_source_files_properties(${c_sources} PROPERTIES
|
||||
COMPILE_FLAGS "${WARNCFLAGS}")
|
||||
file(GLOB cxx_sources *.cc)
|
||||
set_source_files_properties(${cxx_sources} PROPERTIES
|
||||
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
|
||||
|
||||
include_directories(
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/lib/includes
|
||||
${CMAKE_BINARY_DIR}/lib/includes
|
||||
${CMAKE_SOURCE_DIR}/src/includes
|
||||
${CMAKE_SOURCE_DIR}/third-party
|
||||
|
||||
${LIBEVENT_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
link_libraries(
|
||||
nghttp2
|
||||
${LIBEVENT_OPENSSL_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${APP_LIBRARIES}
|
||||
)
|
||||
|
||||
add_executable(client client.c $<TARGET_OBJECTS:http-parser>)
|
||||
add_executable(libevent-client libevent-client.c $<TARGET_OBJECTS:http-parser>)
|
||||
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:http-parser>)
|
||||
add_executable(deflate deflate.c $<TARGET_OBJECTS:http-parser>)
|
||||
|
||||
if(ENABLE_TINY_NGHTTPD)
|
||||
add_executable(tiny-nghttpd tiny-nghttpd.c $<TARGET_OBJECTS:http-parser>)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ASIO_LIB)
|
||||
foreach(name asio-sv asio-sv2 asio-cl asio-cl2)
|
||||
add_executable(${name} ${name}.cc $<TARGET_OBJECTS:http-parser>)
|
||||
target_include_directories(${name} PRIVATE
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
target_link_libraries(${name}
|
||||
nghttp2
|
||||
nghttp2_asio
|
||||
${JEMALLOC_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${APP_LIBRARIES}
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
@@ -21,6 +21,8 @@
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
if ENABLE_EXAMPLES
|
||||
|
||||
AM_CFLAGS = $(WARNCFLAGS)
|
||||
|
||||
@@ -66,13 +66,13 @@ enum { IO_NONE, WANT_READ, WANT_WRITE };
|
||||
|
||||
#define MAKE_NV(NAME, VALUE) \
|
||||
{ \
|
||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||
NGHTTP2_NV_FLAG_NONE \
|
||||
}
|
||||
|
||||
#define MAKE_NV_CS(NAME, VALUE) \
|
||||
{ \
|
||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
|
||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
|
||||
NGHTTP2_NV_FLAG_NONE \
|
||||
}
|
||||
|
||||
@@ -219,9 +219,9 @@ static int on_frame_send_callback(nghttp2_session *session,
|
||||
const nghttp2_nv *nva = frame->headers.nva;
|
||||
printf("[INFO] C ----------------------------> S (HEADERS)\n");
|
||||
for (i = 0; i < frame->headers.nvlen; ++i) {
|
||||
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
||||
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
||||
printf(": ");
|
||||
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
||||
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
@@ -249,9 +249,9 @@ static int on_frame_recv_callback(nghttp2_session *session,
|
||||
if (req) {
|
||||
printf("[INFO] C <---------------------------- S (HEADERS)\n");
|
||||
for (i = 0; i < frame->headers.nvlen; ++i) {
|
||||
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
||||
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
||||
printf(": ");
|
||||
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
||||
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
@@ -457,11 +457,12 @@ static void ctl_poll(struct pollfd *pollfd, struct Connection *connection) {
|
||||
static void submit_request(struct Connection *connection, struct Request *req) {
|
||||
int32_t stream_id;
|
||||
/* Make sure that the last item is NULL */
|
||||
const nghttp2_nv nva[] = {
|
||||
MAKE_NV(":method", "GET"), MAKE_NV_CS(":path", req->path),
|
||||
MAKE_NV(":scheme", "https"), MAKE_NV_CS(":authority", req->hostport),
|
||||
MAKE_NV("accept", "*/*"),
|
||||
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
|
||||
const nghttp2_nv nva[] = {MAKE_NV(":method", "GET"),
|
||||
MAKE_NV_CS(":path", req->path),
|
||||
MAKE_NV(":scheme", "https"),
|
||||
MAKE_NV_CS(":authority", req->hostport),
|
||||
MAKE_NV("accept", "*/*"),
|
||||
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
|
||||
|
||||
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
|
||||
sizeof(nva) / sizeof(nva[0]), NULL, req);
|
||||
@@ -562,7 +563,11 @@ static void fetch_uri(const struct URI *uri) {
|
||||
diec("nghttp2_session_client_new", rv);
|
||||
}
|
||||
|
||||
nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
|
||||
rv = nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
|
||||
|
||||
if (rv != 0) {
|
||||
diec("nghttp2_submit_settings", rv);
|
||||
}
|
||||
|
||||
/* Submit the HTTP request to the outbound queue. */
|
||||
submit_request(&connection, &req);
|
||||
@@ -691,9 +696,6 @@ int main(int argc, char **argv) {
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &act, 0);
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
OPENSSL_config(NULL);
|
||||
#endif /* OPENSSL_IS_BORINGSSL */
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#define MAKE_NV(K, V) \
|
||||
{ \
|
||||
(uint8_t *) K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
|
||||
(uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
|
||||
NGHTTP2_NV_FLAG_NONE \
|
||||
}
|
||||
|
||||
@@ -109,9 +109,9 @@ static void deflate(nghttp2_hd_deflater *deflater,
|
||||
printf("Input (%zu byte(s)):\n\n", sum);
|
||||
|
||||
for (i = 0; i < nvlen; ++i) {
|
||||
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
||||
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
||||
printf(": ");
|
||||
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
||||
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@@ -186,9 +186,9 @@ int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
|
||||
inlen -= proclen;
|
||||
|
||||
if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
|
||||
fwrite(nv.name, nv.namelen, 1, stderr);
|
||||
fwrite(nv.name, 1, nv.namelen, stderr);
|
||||
fprintf(stderr, ": ");
|
||||
fwrite(nv.value, nv.valuelen, 1, stderr);
|
||||
fwrite(nv.value, 1, nv.valuelen, stderr);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -179,9 +179,9 @@ static void delete_http2_session_data(http2_session_data *session_data) {
|
||||
|
||||
static void print_header(FILE *f, const uint8_t *name, size_t namelen,
|
||||
const uint8_t *value, size_t valuelen) {
|
||||
fwrite(name, namelen, 1, f);
|
||||
fwrite(name, 1, namelen, f);
|
||||
fprintf(f, ": ");
|
||||
fwrite(value, valuelen, 1, f);
|
||||
fwrite(value, 1, valuelen, f);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ static int on_data_chunk_recv_callback(nghttp2_session *session _U_,
|
||||
void *user_data) {
|
||||
http2_session_data *session_data = (http2_session_data *)user_data;
|
||||
if (session_data->stream_data->stream_id == stream_id) {
|
||||
fwrite(data, len, 1, stdout);
|
||||
fwrite(data, 1, len, stdout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -322,6 +322,11 @@ static SSL_CTX *create_ssl_ctx(void) {
|
||||
SSL_OP_NO_COMPRESSION |
|
||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
@@ -378,13 +383,13 @@ static void send_client_connection_header(http2_session_data *session_data) {
|
||||
|
||||
#define MAKE_NV(NAME, VALUE, VALUELEN) \
|
||||
{ \
|
||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
|
||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
|
||||
NGHTTP2_NV_FLAG_NONE \
|
||||
}
|
||||
|
||||
#define MAKE_NV2(NAME, VALUE) \
|
||||
{ \
|
||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||
NGHTTP2_NV_FLAG_NONE \
|
||||
}
|
||||
|
||||
@@ -475,7 +480,27 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
|
||||
if (events & BEV_EVENT_CONNECTED) {
|
||||
int fd = bufferevent_getfd(bev);
|
||||
int val = 1;
|
||||
const unsigned char *alpn = NULL;
|
||||
unsigned int alpnlen = 0;
|
||||
SSL *ssl;
|
||||
|
||||
fprintf(stderr, "Connected\n");
|
||||
|
||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||
|
||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (alpn == NULL) {
|
||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||
fprintf(stderr, "h2 is not negotiated\n");
|
||||
delete_http2_session_data(session_data);
|
||||
return;
|
||||
}
|
||||
|
||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||
initialize_nghttp2_session(session_data);
|
||||
send_client_connection_header(session_data);
|
||||
@@ -569,9 +594,6 @@ int main(int argc, char **argv) {
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &act, NULL);
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
OPENSSL_config(NULL);
|
||||
#endif /* OPENSSL_IS_BORINGSSL */
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
|
||||
#define MAKE_NV(NAME, VALUE) \
|
||||
{ \
|
||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||
NGHTTP2_NV_FLAG_NONE \
|
||||
}
|
||||
|
||||
@@ -116,6 +116,22 @@ static int next_proto_cb(SSL *s _U_, const unsigned char **data,
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
|
||||
unsigned char *outlen, const unsigned char *in,
|
||||
unsigned int inlen, void *arg _U_) {
|
||||
int rv;
|
||||
|
||||
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
|
||||
|
||||
if (rv != 1) {
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
/* Create SSL_CTX. */
|
||||
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||
SSL_CTX *ssl_ctx;
|
||||
@@ -152,6 +168,11 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||
|
||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
return ssl_ctx;
|
||||
}
|
||||
|
||||
@@ -640,11 +661,31 @@ static void writecb(struct bufferevent *bev, void *ptr) {
|
||||
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
||||
http2_session_data *session_data = (http2_session_data *)ptr;
|
||||
if (events & BEV_EVENT_CONNECTED) {
|
||||
const unsigned char *alpn = NULL;
|
||||
unsigned int alpnlen = 0;
|
||||
SSL *ssl;
|
||||
|
||||
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
||||
|
||||
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||
|
||||
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (alpn == NULL) {
|
||||
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||
}
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
|
||||
delete_http2_session_data(session_data);
|
||||
return;
|
||||
}
|
||||
|
||||
initialize_nghttp2_session(session_data);
|
||||
|
||||
if (send_server_connection_header(session_data) != 0) {
|
||||
if (send_server_connection_header(session_data) != 0 ||
|
||||
session_send(session_data) != 0) {
|
||||
delete_http2_session_data(session_data);
|
||||
return;
|
||||
}
|
||||
@@ -740,9 +781,6 @@ int main(int argc, char **argv) {
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &act, NULL);
|
||||
|
||||
#ifndef OPENSSL_IS_BORINGSSL
|
||||
OPENSSL_config(NULL);
|
||||
#endif /* OPENSSL_IS_BORINGSSL */
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
|
||||
@@ -62,67 +62,11 @@ HEADERS = [
|
||||
('vary', 58),
|
||||
('via', 59),
|
||||
('www-authenticate', 60),
|
||||
('accept-ch', None),
|
||||
('accept-datetime', None),
|
||||
('accept-features', None),
|
||||
('accept-patch', None),
|
||||
('access-control-allow-credentials', None),
|
||||
('access-control-allow-headers', None),
|
||||
('access-control-allow-methods', None),
|
||||
('access-control-expose-headers', None),
|
||||
('access-control-max-age', None),
|
||||
('access-control-request-headers', None),
|
||||
('access-control-request-method', None),
|
||||
('alt-svc', None),
|
||||
('alternates', None),
|
||||
('connection', None),
|
||||
('content-md5', None),
|
||||
('content-security-policy', None),
|
||||
('content-security-policy-report-only', None),
|
||||
('dnt', None),
|
||||
('forwarded', None),
|
||||
('front-end-https', None),
|
||||
('keep-alive', None),
|
||||
('last-event-id', None),
|
||||
('negotiate', None),
|
||||
('origin', None),
|
||||
('p3p', None),
|
||||
('pragma', None),
|
||||
('proxy-connection', None),
|
||||
('public-key-pins', None),
|
||||
('sec-websocket-extensions', None),
|
||||
('sec-websocket-key', None),
|
||||
('sec-websocket-origin', None),
|
||||
('sec-websocket-protocol', None),
|
||||
('sec-websocket-version', None),
|
||||
('set-cookie2', None),
|
||||
('status', None),
|
||||
('tcn', None),
|
||||
('te', None),
|
||||
('trailer', None),
|
||||
('tsv', None),
|
||||
('connection', None),
|
||||
('keep-alive',None),
|
||||
('proxy-connection', None),
|
||||
('upgrade', None),
|
||||
('upgrade-insecure-requests', None),
|
||||
('variant-vary', None),
|
||||
('warning', None),
|
||||
('x-api-version', None),
|
||||
('x-att-deviceid', None),
|
||||
('x-cache', None),
|
||||
('x-cache-lookup', None),
|
||||
('x-content-duration', None),
|
||||
('x-content-security-policy', None),
|
||||
('x-content-type-options', None),
|
||||
('x-dnsprefetch-control', None),
|
||||
('x-forwarded-for', None),
|
||||
('x-forwarded-host', None),
|
||||
('x-forwarded-proto', None),
|
||||
('x-frame-options', None),
|
||||
('x-powered-by', None),
|
||||
('x-requested-with', None),
|
||||
('x-ua-compatible', None),
|
||||
('x-wap-profile', None),
|
||||
('x-webkit-csp', None),
|
||||
('x-xss-protection', None),
|
||||
]
|
||||
|
||||
def to_enum_hd(k):
|
||||
@@ -144,7 +88,8 @@ def build_header(headers):
|
||||
c = k[-1]
|
||||
if c not in ent:
|
||||
ent[c] = []
|
||||
ent[c].append(k)
|
||||
if k not in ent[c]:
|
||||
ent[c].append(k)
|
||||
|
||||
return res
|
||||
|
||||
@@ -162,7 +107,7 @@ def gen_enum():
|
||||
|
||||
def gen_index_header():
|
||||
print '''\
|
||||
static inline int lookup_token(const uint8_t *name, size_t namelen) {
|
||||
static int32_t lookup_token(const uint8_t *name, size_t namelen) {
|
||||
switch (namelen) {'''
|
||||
b = build_header(HEADERS)
|
||||
for size in sorted(b.keys()):
|
||||
@@ -177,7 +122,7 @@ static inline int lookup_token(const uint8_t *name, size_t namelen) {
|
||||
case '{}':'''.format(c)
|
||||
for k in headers:
|
||||
print '''\
|
||||
if (lstreq("{}", name, {})) {{
|
||||
if (memeq("{}", name, {})) {{
|
||||
return {};
|
||||
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
|
||||
print '''\
|
||||
|
||||
@@ -122,7 +122,33 @@ OPTIONS = [
|
||||
"tls-ticket-key-memcached-cert-file",
|
||||
"tls-ticket-key-memcached-private-key-file",
|
||||
"tls-ticket-key-memcached-address-family",
|
||||
"backend-address-family"
|
||||
"backend-address-family",
|
||||
"frontend-http2-max-concurrent-streams",
|
||||
"backend-http2-max-concurrent-streams",
|
||||
"backend-connections-per-frontend",
|
||||
"backend-tls",
|
||||
"backend-connections-per-host",
|
||||
"error-page",
|
||||
"no-kqueue",
|
||||
"frontend-http2-settings-timeout",
|
||||
"backend-http2-settings-timeout",
|
||||
"api-max-request-body",
|
||||
"backend-max-backoff",
|
||||
"server-name",
|
||||
"no-server-rewrite",
|
||||
"frontend-http2-optimize-write-buffer-size",
|
||||
"frontend-http2-optimize-window-size",
|
||||
"frontend-http2-window-size",
|
||||
"frontend-http2-connection-window-size",
|
||||
"backend-http2-window-size",
|
||||
"backend-http2-connection-window-size",
|
||||
"frontend-http2-encoder-dynamic-table-size",
|
||||
"frontend-http2-decoder-dynamic-table-size",
|
||||
"backend-http2-encoder-dynamic-table-size",
|
||||
"backend-http2-decoder-dynamic-table-size",
|
||||
"ecdh-curves",
|
||||
"tls-sct-dir",
|
||||
"backend-connect-timeout",
|
||||
]
|
||||
|
||||
LOGVARS = [
|
||||
@@ -141,6 +167,8 @@ LOGVARS = [
|
||||
"ssl_protocol",
|
||||
"ssl_session_id",
|
||||
"ssl_session_reused",
|
||||
"backend_host",
|
||||
"backend_port",
|
||||
]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
10
help2rst.py
10
help2rst.py
@@ -160,13 +160,15 @@ DESCRIPTION
|
||||
print(line.strip())
|
||||
|
||||
def format_text(text):
|
||||
# escape *
|
||||
if len(text) > len(arg_indent):
|
||||
text = text[:len(arg_indent) + 1] + re.sub(r'\*', r'\*', text[len(arg_indent) + 1:])
|
||||
# escape *, but don't escape * if it is used as bullet list.
|
||||
m = re.match(r'^\s*\*\s+', text)
|
||||
if m:
|
||||
text = text[:len(m.group(0))] + re.sub(r'\*', r'\*', text[len(m.group(0)):])
|
||||
else:
|
||||
text = re.sub(r'\*', r'\*', text)
|
||||
# markup option reference
|
||||
text = re.sub(r'(^|\s)(-[a-zA-Z0-9-]+)', r'\1:option:`\2`', text)
|
||||
text = re.sub(r'(^|\s)(-[a-zA-Z0-9]|--[a-zA-Z0-9-]+)',
|
||||
r'\1:option:`\2`', text)
|
||||
# sphinx does not like markup like ':option:`-f`='. We need
|
||||
# backslash between ` and =.
|
||||
text = re.sub(r'(:option:`.*?`)(\S)', r'\1\\\2', text)
|
||||
|
||||
1
integration-tests/.gitignore
vendored
1
integration-tests/.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
# generated files
|
||||
config.go
|
||||
setenv
|
||||
|
||||
48
integration-tests/CMakeLists.txt
Normal file
48
integration-tests/CMakeLists.txt
Normal file
@@ -0,0 +1,48 @@
|
||||
set(GO_FILES
|
||||
nghttpx_http1_test.go
|
||||
nghttpx_http2_test.go
|
||||
nghttpx_spdy_test.go
|
||||
server_tester.go
|
||||
)
|
||||
|
||||
# XXX unused
|
||||
set(EXTRA_DIST
|
||||
${GO_FILES}
|
||||
server.key
|
||||
server.crt
|
||||
alt-server.key
|
||||
alt-server.crt
|
||||
setenv
|
||||
req-set-header.rb
|
||||
resp-set-header.rb
|
||||
req-return.rb
|
||||
resp-return.rb
|
||||
)
|
||||
|
||||
add_custom_target(itprep
|
||||
COMMAND go get -d -v golang.org/x/net/http2
|
||||
COMMAND go get -d -v github.com/tatsuhiro-t/go-nghttp2
|
||||
COMMAND go get -d -v github.com/tatsuhiro-t/spdy
|
||||
COMMAND go get -d -v golang.org/x/net/websocket
|
||||
)
|
||||
|
||||
# 'go test' requires both config.go and the test files in the same directory.
|
||||
# For out-of-tree builds, config.go is normally not placed next to the source
|
||||
# files, so copy the tests to the build directory as a workaround.
|
||||
set(GO_BUILD_FILES)
|
||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
foreach(gofile IN LISTS GO_FILES)
|
||||
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${gofile}")
|
||||
add_custom_command(OUTPUT "${outfile}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${gofile}" "${outfile}"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${gofile}"
|
||||
)
|
||||
list(APPEND GO_BUILD_FILES "${outfile}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
add_custom_target(it
|
||||
COMMAND sh setenv go test -v
|
||||
DEPENDS ${GO_BUILD_FILES}
|
||||
)
|
||||
@@ -28,6 +28,7 @@ GO_FILES = \
|
||||
server_tester.go
|
||||
|
||||
EXTRA_DIST = \
|
||||
CMakeLists.txt \
|
||||
$(GO_FILES) \
|
||||
server.key \
|
||||
server.crt \
|
||||
@@ -39,12 +40,12 @@ EXTRA_DIST = \
|
||||
req-return.rb \
|
||||
resp-return.rb
|
||||
|
||||
itprep-local:
|
||||
itprep:
|
||||
go get -d -v golang.org/x/net/http2
|
||||
go get -d -v github.com/tatsuhiro-t/go-nghttp2
|
||||
go get -d -v github.com/tatsuhiro-t/spdy
|
||||
go get -d -v golang.org/x/net/websocket
|
||||
|
||||
it-local:
|
||||
it:
|
||||
for i in $(GO_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
|
||||
sh setenv go test -v
|
||||
|
||||
@@ -3,6 +3,7 @@ package nghttp2
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"golang.org/x/net/websocket"
|
||||
@@ -103,26 +104,26 @@ Content-Length: 0
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1H1ConnectFailure tests that server handles the situation that
|
||||
// connection attempt to HTTP/1 backend failed.
|
||||
func TestH1H1ConnectFailure(t *testing.T) {
|
||||
st := newServerTester(nil, t, noopHandler)
|
||||
defer st.Close()
|
||||
// // TestH1H1ConnectFailure tests that server handles the situation that
|
||||
// // connection attempt to HTTP/1 backend failed.
|
||||
// func TestH1H1ConnectFailure(t *testing.T) {
|
||||
// st := newServerTester(nil, t, noopHandler)
|
||||
// defer st.Close()
|
||||
|
||||
// shutdown backend server to simulate backend connect failure
|
||||
st.ts.Close()
|
||||
// // shutdown backend server to simulate backend connect failure
|
||||
// st.ts.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1H1ConnectFailure",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
want := 503
|
||||
if got := res.status; got != want {
|
||||
t.Errorf("status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
// res, err := st.http1(requestParam{
|
||||
// name: "TestH1H1ConnectFailure",
|
||||
// })
|
||||
// if err != nil {
|
||||
// t.Fatalf("Error st.http1() = %v", err)
|
||||
// }
|
||||
// want := 503
|
||||
// if got := res.status; got != want {
|
||||
// t.Errorf("status: %v; want %v", got, want)
|
||||
// }
|
||||
// }
|
||||
|
||||
// TestH1H1GracefulShutdown tests graceful shutdown.
|
||||
func TestH1H1GracefulShutdown(t *testing.T) {
|
||||
@@ -159,8 +160,9 @@ func TestH1H1GracefulShutdown(t *testing.T) {
|
||||
}
|
||||
|
||||
want := io.EOF
|
||||
if _, err := st.conn.Read(nil); err == nil || err != want {
|
||||
t.Errorf("st.conn.Read(): %v; want %v", err, want)
|
||||
b := make([]byte, 256)
|
||||
if _, err := st.conn.Read(b); err == nil || err != want {
|
||||
t.Errorf("st.conn.Read(): %v; want %v, %v", err, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -531,26 +533,26 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1H2ConnectFailure tests that server handles the situation that
|
||||
// connection attempt to HTTP/2 backend failed.
|
||||
func TestH1H2ConnectFailure(t *testing.T) {
|
||||
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||
defer st.Close()
|
||||
// // TestH1H2ConnectFailure tests that server handles the situation that
|
||||
// // connection attempt to HTTP/2 backend failed.
|
||||
// func TestH1H2ConnectFailure(t *testing.T) {
|
||||
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||
// defer st.Close()
|
||||
|
||||
// simulate backend connect attempt failure
|
||||
st.ts.Close()
|
||||
// // simulate backend connect attempt failure
|
||||
// st.ts.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1H2ConnectFailure",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
want := 503
|
||||
if got := res.status; got != want {
|
||||
t.Errorf("status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
// res, err := st.http1(requestParam{
|
||||
// name: "TestH1H2ConnectFailure",
|
||||
// })
|
||||
// if err != nil {
|
||||
// t.Fatalf("Error st.http1() = %v", err)
|
||||
// }
|
||||
// want := 503
|
||||
// if got := res.status; got != want {
|
||||
// t.Errorf("status: %v; want %v", got, want)
|
||||
// }
|
||||
// }
|
||||
|
||||
// TestH1H2NoHost tests that server rejects request without Host
|
||||
// header field for HTTP/2 backend.
|
||||
@@ -793,3 +795,197 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
|
||||
t.Errorf("body = %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1APIBackendconfig exercise backendconfig API endpoint routine
|
||||
// for successful case.
|
||||
func TestH1APIBackendconfig(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1APIBackendconfig",
|
||||
path: "/api/v1beta1/backendconfig",
|
||||
method: "PUT",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Success"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 200; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1APIBackendconfigQuery exercise backendconfig API endpoint
|
||||
// routine with query.
|
||||
func TestH1APIBackendconfigQuery(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1APIBackendconfigQuery",
|
||||
path: "/api/v1beta1/backendconfig?foo=bar",
|
||||
method: "PUT",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Success"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 200; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||
// routine with bad method.
|
||||
func TestH1APIBackendconfigBadMethod(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1APIBackendconfigBadMethod",
|
||||
path: "/api/v1beta1/backendconfig",
|
||||
method: "GET",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 405; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Failure"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 405; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1APINotFound exercise backendconfig API endpoint routine when
|
||||
// API endpoint is not found.
|
||||
func TestH1APINotFound(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1APINotFound",
|
||||
path: "/api/notfound",
|
||||
method: "GET",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 404; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Failure"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 404; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1Healthmon tests health monitor endpoint.
|
||||
func TestH1Healthmon(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3011)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http1(requestParam{
|
||||
name: "TestH1Healthmon",
|
||||
path: "/alpha/bravo",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http1() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH1ResponseBeforeRequestEnd tests the situation where response
|
||||
// ends before request body finishes.
|
||||
func TestH1ResponseBeforeRequestEnd(t *testing.T) {
|
||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatal("request should not be forwarded")
|
||||
})
|
||||
defer st.Close()
|
||||
|
||||
if _, err := io.WriteString(st.conn, fmt.Sprintf(`POST / HTTP/1.1
|
||||
Host: %v
|
||||
Test-Case: TestH1ResponseBeforeRequestEnd
|
||||
Content-Length: 1000000
|
||||
|
||||
`, st.authority)); err != nil {
|
||||
t.Fatalf("Error io.WriteString() = %v", err)
|
||||
}
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error http.ReadResponse() = %v", err)
|
||||
}
|
||||
|
||||
if got, want := resp.StatusCode, 404; got != want {
|
||||
t.Errorf("status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package nghttp2
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
@@ -568,26 +569,26 @@ func TestH2H1InvalidRequestCL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2H1ConnectFailure tests that server handles the situation that
|
||||
// connection attempt to HTTP/1 backend failed.
|
||||
func TestH2H1ConnectFailure(t *testing.T) {
|
||||
st := newServerTester(nil, t, noopHandler)
|
||||
defer st.Close()
|
||||
// // TestH2H1ConnectFailure tests that server handles the situation that
|
||||
// // connection attempt to HTTP/1 backend failed.
|
||||
// func TestH2H1ConnectFailure(t *testing.T) {
|
||||
// st := newServerTester(nil, t, noopHandler)
|
||||
// defer st.Close()
|
||||
|
||||
// shutdown backend server to simulate backend connect failure
|
||||
st.ts.Close()
|
||||
// // shutdown backend server to simulate backend connect failure
|
||||
// st.ts.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2H1ConnectFailure",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
want := 503
|
||||
if got := res.status; got != want {
|
||||
t.Errorf("status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
// res, err := st.http2(requestParam{
|
||||
// name: "TestH2H1ConnectFailure",
|
||||
// })
|
||||
// if err != nil {
|
||||
// t.Fatalf("Error st.http2() = %v", err)
|
||||
// }
|
||||
// want := 503
|
||||
// if got := res.status; got != want {
|
||||
// t.Errorf("status: %v; want %v", got, want)
|
||||
// }
|
||||
// }
|
||||
|
||||
// TestH2H1InvalidMethod tests that server rejects invalid method with
|
||||
// 501.
|
||||
@@ -1486,26 +1487,26 @@ func TestH2H2InvalidResponseCL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2H2ConnectFailure tests that server handles the situation that
|
||||
// connection attempt to HTTP/2 backend failed.
|
||||
func TestH2H2ConnectFailure(t *testing.T) {
|
||||
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||
defer st.Close()
|
||||
// // TestH2H2ConnectFailure tests that server handles the situation that
|
||||
// // connection attempt to HTTP/2 backend failed.
|
||||
// func TestH2H2ConnectFailure(t *testing.T) {
|
||||
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||
// defer st.Close()
|
||||
|
||||
// simulate backend connect attempt failure
|
||||
st.ts.Close()
|
||||
// // simulate backend connect attempt failure
|
||||
// st.ts.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2H2ConnectFailure",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
want := 503
|
||||
if got := res.status; got != want {
|
||||
t.Errorf("status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
// res, err := st.http2(requestParam{
|
||||
// name: "TestH2H2ConnectFailure",
|
||||
// })
|
||||
// if err != nil {
|
||||
// t.Fatalf("Error st.http2() = %v", err)
|
||||
// }
|
||||
// want := 503
|
||||
// if got := res.status; got != want {
|
||||
// t.Errorf("status: %v; want %v", got, want)
|
||||
// }
|
||||
// }
|
||||
|
||||
// TestH2H2HostRewrite tests that server rewrites host header field
|
||||
func TestH2H2HostRewrite(t *testing.T) {
|
||||
@@ -1843,3 +1844,190 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
|
||||
t.Errorf("body = %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2APIBackendconfig exercise backendconfig API endpoint routine
|
||||
// for successful case.
|
||||
func TestH2APIBackendconfig(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2APIBackendconfig",
|
||||
path: "/api/v1beta1/backendconfig",
|
||||
method: "PUT",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Success"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 200; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2APIBackendconfigQuery exercise backendconfig API endpoint
|
||||
// routine with query.
|
||||
func TestH2APIBackendconfigQuery(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2APIBackendconfigQuery",
|
||||
path: "/api/v1beta1/backendconfig?foo=bar",
|
||||
method: "PUT",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Success"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 200; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||
// routine with bad method.
|
||||
func TestH2APIBackendconfigBadMethod(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2APIBackendconfigBadMethod",
|
||||
path: "/api/v1beta1/backendconfig",
|
||||
method: "GET",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 405; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Failure"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 405; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2APINotFound exercise backendconfig API endpoint routine when
|
||||
// API endpoint is not found.
|
||||
func TestH2APINotFound(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2APINotFound",
|
||||
path: "/api/notfound",
|
||||
method: "GET",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 404; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Failure"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 404; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2Healthmon tests health monitor endpoint.
|
||||
func TestH2Healthmon(t *testing.T) {
|
||||
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3011)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2Healthmon",
|
||||
path: "/alpha/bravo",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestH2ResponseBeforeRequestEnd tests the situation where response
|
||||
// ends before request body finishes.
|
||||
func TestH2ResponseBeforeRequestEnd(t *testing.T) {
|
||||
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatal("request should not be forwarded")
|
||||
})
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.http2(requestParam{
|
||||
name: "TestH2ResponseBeforeRequestEnd",
|
||||
noEndStream: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.http2() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 404; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package nghttp2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/tatsuhiro-t/spdy"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"net/http"
|
||||
@@ -384,26 +385,26 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3H2ConnectFailure tests that server handles the situation that
|
||||
// connection attempt to HTTP/2 backend failed.
|
||||
func TestS3H2ConnectFailure(t *testing.T) {
|
||||
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
|
||||
defer st.Close()
|
||||
// // TestS3H2ConnectFailure tests that server handles the situation that
|
||||
// // connection attempt to HTTP/2 backend failed.
|
||||
// func TestS3H2ConnectFailure(t *testing.T) {
|
||||
// st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
|
||||
// defer st.Close()
|
||||
|
||||
// simulate backend connect attempt failure
|
||||
st.ts.Close()
|
||||
// // simulate backend connect attempt failure
|
||||
// st.ts.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3H2ConnectFailure",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
want := 503
|
||||
if got := res.status; got != want {
|
||||
t.Errorf("status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
// res, err := st.spdy(requestParam{
|
||||
// name: "TestS3H2ConnectFailure",
|
||||
// })
|
||||
// if err != nil {
|
||||
// t.Fatalf("Error st.spdy() = %v", err)
|
||||
// }
|
||||
// want := 503
|
||||
// if got := res.status; got != want {
|
||||
// t.Errorf("status: %v; want %v", got, want)
|
||||
// }
|
||||
// }
|
||||
|
||||
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
|
||||
// custom response.
|
||||
@@ -474,3 +475,190 @@ func TestS3H2RespPhaseReturn(t *testing.T) {
|
||||
t.Errorf("body = %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3APIBackendconfig exercise backendconfig API endpoint routine
|
||||
// for successful case.
|
||||
func TestS3APIBackendconfig(t *testing.T) {
|
||||
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3APIBackendconfig",
|
||||
path: "/api/v1beta1/backendconfig",
|
||||
method: "PUT",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Success"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 200; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3APIBackendconfigQuery exercise backendconfig API endpoint
|
||||
// routine with query.
|
||||
func TestS3APIBackendconfigQuery(t *testing.T) {
|
||||
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3APIBackendconfigQuery",
|
||||
path: "/api/v1beta1/backendconfig?foo=bar",
|
||||
method: "PUT",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Success"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 200; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||
// routine with bad method.
|
||||
func TestS3APIBackendconfigBadMethod(t *testing.T) {
|
||||
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3APIBackendconfigBadMethod",
|
||||
path: "/api/v1beta1/backendconfig",
|
||||
method: "GET",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 405; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Failure"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 405; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3APINotFound exercise backendconfig API endpoint routine when
|
||||
// API endpoint is not found.
|
||||
func TestS3APINotFound(t *testing.T) {
|
||||
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3010)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3APINotFound",
|
||||
path: "/api/notfound",
|
||||
method: "GET",
|
||||
body: []byte(`# comment
|
||||
backend=127.0.0.1,3011
|
||||
|
||||
`),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 404; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
|
||||
var apiResp APIResponse
|
||||
err = json.Unmarshal(res.body, &apiResp)
|
||||
if err != nil {
|
||||
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||
}
|
||||
if got, want := apiResp.Status, "Failure"; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
if got, want := apiResp.Code, 404; got != want {
|
||||
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3Healthmon tests health monitor endpoint.
|
||||
func TestS3Healthmon(t *testing.T) {
|
||||
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3011;healthmon"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("request should not be forwarded")
|
||||
}, 3011)
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3Healthmon",
|
||||
path: "/alpha/bravo",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 200; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestS3ResponseBeforeRequestEnd tests the situation where response
|
||||
// ends before request body finishes.
|
||||
func TestS3ResponseBeforeRequestEnd(t *testing.T) {
|
||||
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatal("request should not be forwarded")
|
||||
})
|
||||
defer st.Close()
|
||||
|
||||
res, err := st.spdy(requestParam{
|
||||
name: "TestS3ResponseBeforeRequestEnd",
|
||||
noEndStream: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Error st.spdy() = %v", err)
|
||||
}
|
||||
if got, want := res.status, 404; got != want {
|
||||
t.Errorf("res.status: %v; want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"github.com/tatsuhiro-t/go-nghttp2"
|
||||
"github.com/tatsuhiro-t/spdy"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/hpack"
|
||||
"golang.org/x/net/websocket"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@@ -30,7 +30,7 @@ const (
|
||||
serverBin = buildDir + "/src/nghttpx"
|
||||
serverPort = 3009
|
||||
testDir = sourceDir + "/integration-tests"
|
||||
logDir = buildDir + "/integration-tests"
|
||||
logDir = buildDir + "/integration-tests"
|
||||
)
|
||||
|
||||
func pair(name, value string) hpack.HeaderField {
|
||||
@@ -66,34 +66,47 @@ type serverTester struct {
|
||||
// newServerTester creates test context for plain TCP frontend
|
||||
// connection.
|
||||
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
||||
return newServerTesterInternal(args, t, handler, false, nil)
|
||||
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
|
||||
}
|
||||
|
||||
func newServerTesterConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
|
||||
return newServerTesterInternal(args, t, handler, false, port, nil)
|
||||
}
|
||||
|
||||
func newServerTesterHandler(args []string, t *testing.T, handler http.Handler) *serverTester {
|
||||
return newServerTesterInternal(args, t, handler, false, nil)
|
||||
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
|
||||
}
|
||||
|
||||
// newServerTester creates test context for TLS frontend connection.
|
||||
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
||||
return newServerTesterInternal(args, t, handler, true, nil)
|
||||
return newServerTesterInternal(args, t, handler, true, serverPort, nil)
|
||||
}
|
||||
|
||||
func newServerTesterTLSConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
|
||||
return newServerTesterInternal(args, t, handler, true, port, nil)
|
||||
}
|
||||
|
||||
// newServerTester creates test context for TLS frontend connection
|
||||
// with given clientConfig
|
||||
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
|
||||
return newServerTesterInternal(args, t, handler, true, clientConfig)
|
||||
return newServerTesterInternal(args, t, handler, true, serverPort, clientConfig)
|
||||
}
|
||||
|
||||
// newServerTesterInternal creates test context. If frontendTLS is
|
||||
// true, set up TLS frontend connection.
|
||||
func newServerTesterInternal(args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
|
||||
// true, set up TLS frontend connection. connectPort is the server
|
||||
// side port where client connection is made.
|
||||
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, connectPort int, clientConfig *tls.Config) *serverTester {
|
||||
ts := httptest.NewUnstartedServer(handler)
|
||||
|
||||
args := []string{}
|
||||
|
||||
backendTLS := false
|
||||
for _, k := range args {
|
||||
for _, k := range src_args {
|
||||
switch k {
|
||||
case "--http2-bridge":
|
||||
backendTLS = true
|
||||
default:
|
||||
args = append(args, k)
|
||||
}
|
||||
}
|
||||
if backendTLS {
|
||||
@@ -102,9 +115,9 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
||||
// NextProtos separately for ts.TLS. NextProtos set
|
||||
// in nghttp2.ConfigureServer is effectively ignored.
|
||||
ts.TLS = new(tls.Config)
|
||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2-14")
|
||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
|
||||
ts.StartTLS()
|
||||
args = append(args, "-k")
|
||||
args = append(args, "-k", "--backend-tls")
|
||||
} else {
|
||||
ts.Start()
|
||||
}
|
||||
@@ -112,8 +125,6 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
||||
if frontendTLS {
|
||||
scheme = "https"
|
||||
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
||||
} else {
|
||||
args = append(args, "--frontend-no-tls")
|
||||
}
|
||||
|
||||
backendURL, err := url.Parse(ts.URL)
|
||||
@@ -124,10 +135,19 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
||||
// URL.Host looks like "127.0.0.1:8080", but we want
|
||||
// "127.0.0.1,8080"
|
||||
b := "-b" + strings.Replace(backendURL.Host, ":", ",", -1)
|
||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v", serverPort), b,
|
||||
if backendTLS {
|
||||
b += ";;proto=h2;tls"
|
||||
}
|
||||
|
||||
noTLS := "no-tls"
|
||||
if frontendTLS {
|
||||
noTLS = ""
|
||||
}
|
||||
|
||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
|
||||
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
||||
|
||||
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)
|
||||
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
|
||||
|
||||
st := &serverTester{
|
||||
cmd: exec.Command(serverBin, args...),
|
||||
@@ -149,6 +169,8 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
||||
|
||||
retry := 0
|
||||
for {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
var conn net.Conn
|
||||
var err error
|
||||
if frontendTLS {
|
||||
@@ -159,7 +181,7 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
||||
tlsConfig = clientConfig
|
||||
}
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
tlsConfig.NextProtos = []string{"h2-14", "spdy/3.1"}
|
||||
tlsConfig.NextProtos = []string{"h2", "spdy/3.1"}
|
||||
conn, err = tls.Dial("tcp", authority, tlsConfig)
|
||||
} else {
|
||||
conn, err = net.Dial("tcp", authority)
|
||||
@@ -170,7 +192,6 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
||||
st.Close()
|
||||
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
|
||||
}
|
||||
time.Sleep(150 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
if frontendTLS {
|
||||
@@ -276,6 +297,7 @@ type requestParam struct {
|
||||
body []byte // request body
|
||||
trailer []hpack.HeaderField // trailer part
|
||||
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
|
||||
noEndStream bool // true if END_STREAM should not be sent
|
||||
}
|
||||
|
||||
// wrapper for request body to set trailer part
|
||||
@@ -359,8 +381,9 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
|
||||
if err != nil {
|
||||
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
|
||||
}
|
||||
u.Path = rp.path
|
||||
reqURL = u.String()
|
||||
u.Path = ""
|
||||
u.RawQuery = ""
|
||||
reqURL = u.String() + rp.path
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, reqURL, body)
|
||||
@@ -449,7 +472,7 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
|
||||
}
|
||||
|
||||
var synStreamFlags spdy.ControlFlags
|
||||
if len(rp.body) == 0 {
|
||||
if len(rp.body) == 0 && !rp.noEndStream {
|
||||
synStreamFlags = spdy.ControlFlagFin
|
||||
}
|
||||
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
|
||||
@@ -463,9 +486,13 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
|
||||
}
|
||||
|
||||
if len(rp.body) != 0 {
|
||||
var dataFlags spdy.DataFlags
|
||||
if !rp.noEndStream {
|
||||
dataFlags = spdy.DataFlagFin
|
||||
}
|
||||
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
|
||||
StreamId: id,
|
||||
Flags: spdy.DataFlagFin,
|
||||
Flags: dataFlags,
|
||||
Data: rp.body,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
@@ -578,7 +605,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
||||
|
||||
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
||||
StreamID: id,
|
||||
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
|
||||
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0 && !rp.noEndStream,
|
||||
EndHeaders: true,
|
||||
BlockFragment: st.headerBlkBuf.Bytes(),
|
||||
})
|
||||
@@ -588,7 +615,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
||||
|
||||
if len(rp.body) != 0 {
|
||||
// TODO we assume rp.body fits in 1 frame
|
||||
if err := st.fr.WriteData(id, len(rp.trailer) == 0, rp.body); err != nil {
|
||||
if err := st.fr.WriteData(id, len(rp.trailer) == 0 && !rp.noEndStream, rp.body); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -735,3 +762,8 @@ func cloneHeader(h http.Header) http.Header {
|
||||
}
|
||||
|
||||
func noopHandler(w http.ResponseWriter, r *http.Request) {}
|
||||
|
||||
type APIResponse struct {
|
||||
Status string `json:"status,omitempty"`
|
||||
Code int `json:"code,omitempty"`
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
libdir="@abs_top_builddir@/lib"
|
||||
if [ -d "$libdir/.libs" ]; then
|
||||
libdir="$libdir/.libs"
|
||||
fi
|
||||
|
||||
export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
|
||||
export CGO_LDFLAGS="-L@abs_top_builddir@/lib/.libs"
|
||||
export LD_LIBRARY_PATH="@abs_top_builddir@/lib/.libs"
|
||||
export CGO_LDFLAGS="-L$libdir"
|
||||
export LD_LIBRARY_PATH="$libdir"
|
||||
export GODEBUG=cgocheck=0
|
||||
"$@"
|
||||
|
||||
52
lib/CMakeLists.txt
Normal file
52
lib/CMakeLists.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
add_subdirectory(includes)
|
||||
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/includes"
|
||||
)
|
||||
|
||||
add_definitions(-DBUILDING_NGHTTP2)
|
||||
|
||||
set(NGHTTP2_SOURCES
|
||||
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
|
||||
nghttp2_frame.c
|
||||
nghttp2_buf.c
|
||||
nghttp2_stream.c nghttp2_outbound_item.c
|
||||
nghttp2_session.c nghttp2_submit.c
|
||||
nghttp2_helper.c
|
||||
nghttp2_npn.c
|
||||
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
|
||||
nghttp2_version.c
|
||||
nghttp2_priority_spec.c
|
||||
nghttp2_option.c
|
||||
nghttp2_callbacks.c
|
||||
nghttp2_mem.c
|
||||
nghttp2_http.c
|
||||
nghttp2_rcbuf.c
|
||||
nghttp2_debug.c
|
||||
)
|
||||
|
||||
# Public shared library
|
||||
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES})
|
||||
set_target_properties(nghttp2 PROPERTIES
|
||||
COMPILE_FLAGS "${WARNCFLAGS}"
|
||||
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||
C_VISIBILITY_PRESET hidden
|
||||
)
|
||||
|
||||
if(HAVE_CUNIT)
|
||||
# Static library (for unittests because of symbol visibility)
|
||||
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
|
||||
set_target_properties(nghttp2_static PROPERTIES
|
||||
COMPILE_FLAGS "${WARNCFLAGS}"
|
||||
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||
ARCHIVE_OUTPUT_NAME nghttp2
|
||||
)
|
||||
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
|
||||
endif()
|
||||
|
||||
install(TARGETS nghttp2
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
@@ -22,7 +22,7 @@
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
SUBDIRS = includes
|
||||
|
||||
EXTRA_DIST = Makefile.msvc
|
||||
EXTRA_DIST = Makefile.msvc CMakeLists.txt
|
||||
|
||||
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
||||
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
||||
@@ -47,7 +47,9 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
||||
nghttp2_option.c \
|
||||
nghttp2_callbacks.c \
|
||||
nghttp2_mem.c \
|
||||
nghttp2_http.c
|
||||
nghttp2_http.c \
|
||||
nghttp2_rcbuf.c \
|
||||
nghttp2_debug.c
|
||||
|
||||
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||
nghttp2_frame.h \
|
||||
@@ -61,7 +63,9 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||
nghttp2_option.h \
|
||||
nghttp2_callbacks.h \
|
||||
nghttp2_mem.h \
|
||||
nghttp2_http.h
|
||||
nghttp2_http.h \
|
||||
nghttp2_rcbuf.h \
|
||||
nghttp2_debug.h
|
||||
|
||||
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
||||
libnghttp2_la_LDFLAGS = -no-undefined \
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
#
|
||||
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
USE_CYTHON := 1
|
||||
#USE_CYTHON := 0
|
||||
USE_CYTHON := 0
|
||||
#USE_CYTHON := 1
|
||||
|
||||
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -r -e 's/(-DEV)?], //g')
|
||||
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -e 's/-DEV//g' -e 's/], //g')
|
||||
_VERSION := $(subst ., ,$(_VERSION))
|
||||
VER_MAJOR := $(word 1,$(_VERSION))
|
||||
VER_MINOR := $(word 2,$(_VERSION))
|
||||
VER_MICRO := $(word 3,$(_VERSION))
|
||||
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO)
|
||||
VERSION_NUM := ($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO)
|
||||
VERSION_NUM := (($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO))
|
||||
|
||||
GENERATED := 'Generated by $(realpath Makefile.MSVC)'
|
||||
|
||||
@@ -90,7 +90,8 @@ NGHTTP2_SRC := nghttp2_pq.c \
|
||||
nghttp2_option.c \
|
||||
nghttp2_callbacks.c \
|
||||
nghttp2_mem.c \
|
||||
nghttp2_http.c
|
||||
nghttp2_http.c \
|
||||
nghttp2_rcbuf.c
|
||||
|
||||
NGHTTP2_OBJ_R := $(addprefix $(OBJ_DIR)/r_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
||||
NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
||||
@@ -101,7 +102,7 @@ NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
||||
clean_nghttp2_pyd_0 clean_nghttp2_pyd_1
|
||||
|
||||
|
||||
all: intro $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
|
||||
all: intro includes/nghttp2/nghttp2ver.h $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
|
||||
@echo 'Welcome to NgHTTP2 (release + debug).'
|
||||
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
|
||||
|
||||
@@ -193,17 +194,17 @@ $(OBJ_DIR)/d_%.obj: %.c $(THIS_MAKEFILE)
|
||||
@echo
|
||||
|
||||
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
||||
$(RC) -nologo -D_RELEASE -Fo $@ $<
|
||||
$(RC) -D_RELEASE -Fo $@ $<
|
||||
@echo
|
||||
|
||||
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
||||
$(RC) -nologo -D_DEBUG -Fo $@ $<
|
||||
$(RC) -D_DEBUG -Fo $@ $<
|
||||
@echo
|
||||
|
||||
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
|
||||
sed < includes/nghttp2/nghttp2ver.h.in \
|
||||
-e 's/@PACKAGE_VERSION@/$(VERSION)/g' \
|
||||
-e 's/@PACKAGE_VERSION_NUM@/($(VERSION_NUM))/g' > $@
|
||||
-e 's/@PACKAGE_VERSION_NUM@/$(VERSION_NUM)/g' > $@
|
||||
touch --reference=includes/nghttp2/nghttp2ver.h.in $@
|
||||
|
||||
|
||||
|
||||
4
lib/includes/CMakeLists.txt
Normal file
4
lib/includes/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
install(FILES
|
||||
nghttp2/nghttp2.h
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/nghttp2/nghttp2ver.h"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nghttp2")
|
||||
@@ -20,4 +20,7 @@
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
EXTRA_DIST = CMakeLists.txt
|
||||
|
||||
nobase_include_HEADERS = nghttp2/nghttp2.h nghttp2/nghttp2ver.h
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nghttp2_helper.h"
|
||||
#include "nghttp2_debug.h"
|
||||
|
||||
void nghttp2_buf_init(nghttp2_buf *buf) {
|
||||
buf->begin = NULL;
|
||||
@@ -223,13 +224,54 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||
size_t veclen, nghttp2_mem *mem) {
|
||||
size_t i = 0;
|
||||
nghttp2_buf_chain *cur_chain;
|
||||
nghttp2_buf_chain *head_chain;
|
||||
nghttp2_buf_chain **dst_chain = &head_chain;
|
||||
|
||||
if (veclen == 0) {
|
||||
return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
|
||||
}
|
||||
|
||||
head_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain) * veclen);
|
||||
if (head_chain == NULL) {
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < veclen; ++i) {
|
||||
cur_chain = &head_chain[i];
|
||||
cur_chain->next = NULL;
|
||||
nghttp2_buf_wrap_init(&cur_chain->buf, vec[i].base, vec[i].len);
|
||||
|
||||
*dst_chain = cur_chain;
|
||||
dst_chain = &cur_chain->next;
|
||||
}
|
||||
|
||||
bufs->mem = mem;
|
||||
bufs->offset = 0;
|
||||
|
||||
bufs->head = head_chain;
|
||||
bufs->cur = bufs->head;
|
||||
|
||||
/* We don't use chunk_length since no allocation is expected. */
|
||||
bufs->chunk_length = 0;
|
||||
bufs->chunk_used = veclen;
|
||||
bufs->max_chunk = veclen;
|
||||
bufs->chunk_keep = veclen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
|
||||
if (bufs == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||
bufs->head = NULL;
|
||||
if (bufs->head) {
|
||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
||||
@@ -256,12 +298,6 @@ size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static size_t bufs_avail(nghttp2_bufs *bufs) {
|
||||
return nghttp2_buf_avail(&bufs->cur->buf) +
|
||||
(bufs->chunk_length - bufs->offset) *
|
||||
(bufs->max_chunk - bufs->chunk_used);
|
||||
}
|
||||
|
||||
static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
||||
int rv;
|
||||
nghttp2_buf_chain *chain;
|
||||
@@ -281,9 +317,8 @@ static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
DEBUGF(fprintf(stderr,
|
||||
"new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
||||
bufs->chunk_length, bufs, bufs->chunk_used));
|
||||
DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
||||
bufs->chunk_length, bufs, bufs->chunk_used);
|
||||
|
||||
++bufs->chunk_used;
|
||||
|
||||
@@ -301,10 +336,6 @@ int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) {
|
||||
nghttp2_buf *buf;
|
||||
const uint8_t *p;
|
||||
|
||||
if (bufs_avail(bufs) < len) {
|
||||
return NGHTTP2_ERR_BUFFER_ERROR;
|
||||
}
|
||||
|
||||
p = data;
|
||||
|
||||
while (len) {
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef struct {
|
||||
|
||||
/*
|
||||
* Initializes the |buf|. No memory is allocated in this function. Use
|
||||
* nghttp2_buf_reserve() or nghttp2_buf_reserve2() to allocate memory.
|
||||
* nghttp2_buf_reserve() to allocate memory.
|
||||
*/
|
||||
void nghttp2_buf_init(nghttp2_buf *buf);
|
||||
|
||||
@@ -138,7 +138,9 @@ typedef struct {
|
||||
nghttp2_buf_chain *cur;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* The buffer capacity of each buf */
|
||||
/* The buffer capacity of each buf. This field may be 0 if
|
||||
nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
|
||||
functions. */
|
||||
size_t chunk_length;
|
||||
/* The maximum number of nghttp2_buf_chain */
|
||||
size_t max_chunk;
|
||||
@@ -197,10 +199,13 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
||||
/*
|
||||
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
||||
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
||||
* is fixed and no allocate extra chunk buffer is allocated. In other
|
||||
* is fixed and no extra chunk buffer is allocated. In other
|
||||
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
||||
* for |bufs|, use nghttp2_bufs_wrap_free().
|
||||
*
|
||||
* Don't use the function which performs allocation, such as
|
||||
* nghttp2_bufs_realloc().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
@@ -210,6 +215,25 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
||||
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |bufs| using supplied |veclen| size of buf vector
|
||||
* |vec|. The number of buffers is fixed and no extra chunk buffer is
|
||||
* allocated. In other words, max_chunk = chunk_keep = |in_len|. To
|
||||
* free the resource allocated for |bufs|, use
|
||||
* nghttp2_bufs_wrap_free().
|
||||
*
|
||||
* Don't use the function which performs allocation, such as
|
||||
* nghttp2_bufs_realloc().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||
size_t veclen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees any related resource to the |bufs|. This function does not
|
||||
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||
@@ -312,8 +336,8 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Copies all data stored in |bufs| to the contagious buffer. This
|
||||
* function allocates the contagious memory to store all data in
|
||||
* Copies all data stored in |bufs| to the contiguous buffer. This
|
||||
* function allocates the contiguous memory to store all data in
|
||||
* |bufs| and assigns it to |*out|.
|
||||
*
|
||||
* The contents of |bufs| is left unchanged.
|
||||
@@ -381,7 +405,7 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
||||
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
||||
|
||||
/*
|
||||
* Returns the buffer length of |bufs|.
|
||||
* Returns the total buffer length of |bufs|.
|
||||
*/
|
||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||
|
||||
|
||||
@@ -104,6 +104,24 @@ void nghttp2_session_callbacks_set_on_header_callback(
|
||||
cbs->on_header_callback = on_header_callback;
|
||||
}
|
||||
|
||||
void nghttp2_session_callbacks_set_on_header_callback2(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_on_header_callback2 on_header_callback2) {
|
||||
cbs->on_header_callback2 = on_header_callback2;
|
||||
}
|
||||
|
||||
void nghttp2_session_callbacks_set_on_invalid_header_callback(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_on_invalid_header_callback on_invalid_header_callback) {
|
||||
cbs->on_invalid_header_callback = on_invalid_header_callback;
|
||||
}
|
||||
|
||||
void nghttp2_session_callbacks_set_on_invalid_header_callback2(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) {
|
||||
cbs->on_invalid_header_callback2 = on_invalid_header_callback2;
|
||||
}
|
||||
|
||||
void nghttp2_session_callbacks_set_select_padding_callback(
|
||||
nghttp2_session_callbacks *cbs,
|
||||
nghttp2_select_padding_callback select_padding_callback) {
|
||||
@@ -145,3 +163,8 @@ void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
|
||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) {
|
||||
cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback;
|
||||
}
|
||||
|
||||
void nghttp2_session_callbacks_set_error_callback(
|
||||
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
|
||||
cbs->error_callback = error_callback;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,14 @@ struct nghttp2_session_callbacks {
|
||||
* received.
|
||||
*/
|
||||
nghttp2_on_header_callback on_header_callback;
|
||||
nghttp2_on_header_callback2 on_header_callback2;
|
||||
/**
|
||||
* Callback function invoked when a invalid header name/value pair
|
||||
* is received which is silently ignored if these callbacks are not
|
||||
* set.
|
||||
*/
|
||||
nghttp2_on_invalid_header_callback on_invalid_header_callback;
|
||||
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
|
||||
/**
|
||||
* Callback function invoked when the library asks application how
|
||||
* many padding bytes are required for the transmission of the given
|
||||
@@ -110,6 +118,7 @@ struct nghttp2_session_callbacks {
|
||||
nghttp2_pack_extension_callback pack_extension_callback;
|
||||
nghttp2_unpack_extension_callback unpack_extension_callback;
|
||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
||||
nghttp2_error_callback error_callback;
|
||||
};
|
||||
|
||||
#endif /* NGHTTP2_CALLBACKS_H */
|
||||
|
||||
58
lib/nghttp2_debug.c
Normal file
58
lib/nghttp2_debug.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include "nghttp2_debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
|
||||
static void nghttp2_default_debug_vfprintf_callback(const char *fmt,
|
||||
va_list args) {
|
||||
vfprintf(stderr, fmt, args);
|
||||
}
|
||||
|
||||
static nghttp2_debug_vprintf_callback static_debug_vprintf_callback =
|
||||
nghttp2_default_debug_vfprintf_callback;
|
||||
|
||||
void nghttp2_debug_vprintf(const char *format, ...) {
|
||||
if (static_debug_vprintf_callback) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
static_debug_vprintf_callback(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp2_set_debug_vprintf_callback(
|
||||
nghttp2_debug_vprintf_callback debug_vprintf_callback) {
|
||||
static_debug_vprintf_callback = debug_vprintf_callback;
|
||||
}
|
||||
|
||||
#else /* !DEBUGBUILD */
|
||||
|
||||
void nghttp2_set_debug_vprintf_callback(
|
||||
nghttp2_debug_vprintf_callback debug_vprintf_callback _U_) {}
|
||||
|
||||
#endif /* !DEBUGBUILD */
|
||||
43
lib/nghttp2_debug.h
Normal file
43
lib/nghttp2_debug.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2016 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_DEBUG_H
|
||||
#define NGHTTP2_DEBUG_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
|
||||
void nghttp2_debug_vprintf(const char *format, ...);
|
||||
#else
|
||||
#define DEBUGF(...) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* NGHTTP2_DEBUG_H */
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "nghttp2_helper.h"
|
||||
#include "nghttp2_net.h"
|
||||
#include "nghttp2_priority_spec.h"
|
||||
#include "nghttp2_debug.h"
|
||||
|
||||
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) {
|
||||
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
|
||||
@@ -193,6 +194,30 @@ void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
||||
|
||||
void nghttp2_frame_extension_free(nghttp2_extension *frame _U_) {}
|
||||
|
||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
||||
uint8_t *origin, size_t origin_len,
|
||||
uint8_t *field_value, size_t field_value_len) {
|
||||
nghttp2_ext_altsvc *altsvc;
|
||||
|
||||
nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
|
||||
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
|
||||
|
||||
altsvc = frame->payload;
|
||||
altsvc->origin = origin;
|
||||
altsvc->origin_len = origin_len;
|
||||
altsvc->field_value = field_value;
|
||||
altsvc->field_value_len = field_value_len;
|
||||
}
|
||||
|
||||
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
|
||||
nghttp2_ext_altsvc *altsvc;
|
||||
|
||||
altsvc = frame->payload;
|
||||
/* We use the same buffer for altsvc->origin and
|
||||
altsvc->field_value. */
|
||||
nghttp2_mem_free(mem, altsvc->origin);
|
||||
}
|
||||
|
||||
size_t nghttp2_frame_priority_len(uint8_t flags) {
|
||||
if (flags & NGHTTP2_FLAG_PRIORITY) {
|
||||
return NGHTTP2_PRIORITY_SPECLEN;
|
||||
@@ -228,8 +253,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
||||
hd = *frame_hd;
|
||||
hd.length = nghttp2_buf_len(buf);
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n",
|
||||
hd.length));
|
||||
DEBUGF("send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n", hd.length);
|
||||
|
||||
/* We have multiple frame buffers, which means one or more
|
||||
CONTINUATION frame is involved. Remove END_HEADERS flag from the
|
||||
@@ -254,8 +278,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
||||
|
||||
hd.length = nghttp2_buf_len(buf);
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: int CONTINUATION, payloadlen=%zu\n",
|
||||
hd.length));
|
||||
DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length);
|
||||
|
||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||
@@ -266,8 +289,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
||||
/* Set END_HEADERS flag for last CONTINUATION */
|
||||
hd.flags = NGHTTP2_FLAG_END_HEADERS;
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: last CONTINUATION, payloadlen=%zu\n",
|
||||
hd.length));
|
||||
DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length);
|
||||
|
||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||
@@ -439,25 +461,11 @@ size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
|
||||
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
|
||||
}
|
||||
|
||||
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv, nghttp2_mem *mem) {
|
||||
size_t payloadlen = niv * sizeof(nghttp2_settings_entry);
|
||||
|
||||
if (niv == 0) {
|
||||
frame->iv = NULL;
|
||||
} else {
|
||||
frame->iv = nghttp2_mem_malloc(mem, payloadlen);
|
||||
|
||||
if (frame->iv == NULL) {
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
|
||||
memcpy(frame->iv, iv, payloadlen);
|
||||
}
|
||||
|
||||
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv) {
|
||||
frame->iv = iv;
|
||||
frame->niv = niv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
||||
@@ -668,6 +676,79 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
||||
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
||||
}
|
||||
|
||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
|
||||
int rv;
|
||||
nghttp2_buf *buf;
|
||||
nghttp2_ext_altsvc *altsvc;
|
||||
|
||||
altsvc = frame->payload;
|
||||
|
||||
buf = &bufs->head->buf;
|
||||
|
||||
assert(nghttp2_buf_avail(buf) >=
|
||||
2 + altsvc->origin_len + altsvc->field_value_len);
|
||||
|
||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||
|
||||
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
|
||||
|
||||
nghttp2_put_uint16be(buf->last, (uint16_t)altsvc->origin_len);
|
||||
buf->last += 2;
|
||||
|
||||
rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
|
||||
|
||||
assert(rv == 0);
|
||||
|
||||
rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
|
||||
|
||||
assert(rv == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
||||
size_t origin_len, uint8_t *payload,
|
||||
size_t payloadlen) {
|
||||
nghttp2_ext_altsvc *altsvc;
|
||||
uint8_t *p;
|
||||
|
||||
altsvc = frame->payload;
|
||||
p = payload;
|
||||
|
||||
altsvc->origin = p;
|
||||
|
||||
p += origin_len;
|
||||
|
||||
altsvc->origin_len = origin_len;
|
||||
|
||||
altsvc->field_value = p;
|
||||
altsvc->field_value_len = (size_t)(payload + payloadlen - p);
|
||||
}
|
||||
|
||||
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem) {
|
||||
uint8_t *buf;
|
||||
size_t origin_len;
|
||||
|
||||
if (payloadlen < 2) {
|
||||
return NGHTTP2_FRAME_SIZE_ERROR;
|
||||
}
|
||||
|
||||
origin_len = nghttp2_get_uint16(payload);
|
||||
|
||||
buf = nghttp2_mem_malloc(mem, payloadlen - 2);
|
||||
if (!buf) {
|
||||
return NGHTTP2_ERR_NOMEM;
|
||||
}
|
||||
|
||||
nghttp2_cpymem(buf, payload + 2, payloadlen - 2);
|
||||
|
||||
nghttp2_frame_unpack_altsvc_payload(frame, origin_len, buf, payloadlen - 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
||||
size_t niv, nghttp2_mem *mem) {
|
||||
nghttp2_settings_entry *iv_copy;
|
||||
@@ -847,7 +928,7 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
|
||||
size_t trail_padlen;
|
||||
size_t newlen;
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: padlen=%zu, shift left 1 bytes\n", padlen));
|
||||
DEBUGF("send: padlen=%zu, shift left 1 bytes\n", padlen);
|
||||
|
||||
memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
|
||||
|
||||
@@ -877,7 +958,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||
nghttp2_buf *buf;
|
||||
|
||||
if (padlen == 0) {
|
||||
DEBUGF(fprintf(stderr, "send: padlen = 0, nothing to do\n"));
|
||||
DEBUGF("send: padlen = 0, nothing to do\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -911,8 +992,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||
hd->length += padlen;
|
||||
hd->flags |= NGHTTP2_FLAG_PADDED;
|
||||
|
||||
DEBUGF(fprintf(stderr, "send: final payloadlen=%zu, padlen=%zu\n", hd->length,
|
||||
padlen));
|
||||
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -52,14 +52,12 @@
|
||||
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
||||
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
||||
|
||||
/* Number of inbound buffer */
|
||||
#define NGHTTP2_FRAMEBUF_MAX_NUM 5
|
||||
|
||||
/* The default length of DATA frame payload. */
|
||||
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
||||
|
||||
/* Maximum headers payload length, calculated in compressed form.
|
||||
This applies to transmission only. */
|
||||
/* Maximum headers block size to send, calculated using
|
||||
nghttp2_hd_deflate_bound(). This is the default value, and can be
|
||||
overridden by nghttp2_option_set_max_send_header_block_size(). */
|
||||
#define NGHTTP2_MAX_HEADERSLEN 65536
|
||||
|
||||
/* The number of bytes for each SETTINGS entry */
|
||||
@@ -72,7 +70,7 @@
|
||||
#define NGHTTP2_MAX_PADLEN 256
|
||||
|
||||
/* Union of extension frame payload */
|
||||
typedef union { int dummy; } nghttp2_ext_frame_payload;
|
||||
typedef union { nghttp2_ext_altsvc altsvc; } nghttp2_ext_frame_payload;
|
||||
|
||||
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
|
||||
|
||||
@@ -215,18 +213,12 @@ void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Makes a copy of |iv| in frame->settings.iv. The |niv| is assigned
|
||||
* to frame->settings.niv.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* Initializes payload of frame->settings. The |frame| takes
|
||||
* ownership of |iv|.
|
||||
*/
|
||||
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv, nghttp2_mem *mem);
|
||||
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv);
|
||||
|
||||
/*
|
||||
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
|
||||
@@ -367,6 +359,45 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs ALTSVC frame |frame| in wire frame format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
||||
|
||||
/*
|
||||
* Unpacks ALTSVC wire format into |frame|. The |payload| of
|
||||
* |payloadlen| bytes contains frame payload. This function assumes
|
||||
* that frame->payload points to the nghttp2_ext_altsvc object.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
||||
size_t origin_len, uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Unpacks ALTSVC wire format into |frame|. This function only exists
|
||||
* for unit test. After allocating buffer for fields, this function
|
||||
* internally calls nghttp2_frame_unpack_altsvc_payload().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The payload is too small.
|
||||
*/
|
||||
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
||||
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
||||
@@ -445,6 +476,25 @@ void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
||||
|
||||
void nghttp2_frame_extension_free(nghttp2_extension *frame);
|
||||
|
||||
/*
|
||||
* Initializes ALTSVC frame |frame| with given values. This function
|
||||
* assumes that frame->payload points to nghttp2_ext_altsvc object.
|
||||
* Also |origin| and |field_value| are allocated in single buffer,
|
||||
* starting |origin|. On success, this function takes ownership of
|
||||
* |origin|, so caller must not free it.
|
||||
*/
|
||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
||||
uint8_t *origin, size_t origin_len,
|
||||
uint8_t *field_value, size_t field_value_len);
|
||||
|
||||
/*
|
||||
* Frees up resources under |frame|. This function does not free
|
||||
* nghttp2_ext_altsvc object pointed by frame->payload. This function
|
||||
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
|
||||
* other fields must be allocated in the same buffer with origin.
|
||||
*/
|
||||
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Returns the number of padding bytes after payload. The total
|
||||
* padding length is given in the |padlen|. The returned value does
|
||||
|
||||
1460
lib/nghttp2_hd.c
1460
lib/nghttp2_hd.c
File diff suppressed because it is too large
Load Diff
196
lib/nghttp2_hd.h
196
lib/nghttp2_hd.h
@@ -34,6 +34,7 @@
|
||||
#include "nghttp2_hd_huffman.h"
|
||||
#include "nghttp2_buf.h"
|
||||
#include "nghttp2_mem.h"
|
||||
#include "nghttp2_rcbuf.h"
|
||||
|
||||
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
||||
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
||||
@@ -105,88 +106,36 @@ typedef enum {
|
||||
NGHTTP2_TOKEN_VARY = 58,
|
||||
NGHTTP2_TOKEN_VIA = 59,
|
||||
NGHTTP2_TOKEN_WWW_AUTHENTICATE = 60,
|
||||
NGHTTP2_TOKEN_ACCEPT_CH,
|
||||
NGHTTP2_TOKEN_ACCEPT_DATETIME,
|
||||
NGHTTP2_TOKEN_ACCEPT_FEATURES,
|
||||
NGHTTP2_TOKEN_ACCEPT_PATCH,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_CREDENTIALS,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_HEADERS,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_METHODS,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_EXPOSE_HEADERS,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_MAX_AGE,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_REQUEST_HEADERS,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_REQUEST_METHOD,
|
||||
NGHTTP2_TOKEN_ALT_SVC,
|
||||
NGHTTP2_TOKEN_ALTERNATES,
|
||||
NGHTTP2_TOKEN_CONNECTION,
|
||||
NGHTTP2_TOKEN_CONTENT_MD5,
|
||||
NGHTTP2_TOKEN_CONTENT_SECURITY_POLICY,
|
||||
NGHTTP2_TOKEN_CONTENT_SECURITY_POLICY_REPORT_ONLY,
|
||||
NGHTTP2_TOKEN_DNT,
|
||||
NGHTTP2_TOKEN_FORWARDED,
|
||||
NGHTTP2_TOKEN_FRONT_END_HTTPS,
|
||||
NGHTTP2_TOKEN_KEEP_ALIVE,
|
||||
NGHTTP2_TOKEN_LAST_EVENT_ID,
|
||||
NGHTTP2_TOKEN_NEGOTIATE,
|
||||
NGHTTP2_TOKEN_ORIGIN,
|
||||
NGHTTP2_TOKEN_P3P,
|
||||
NGHTTP2_TOKEN_PRAGMA,
|
||||
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
||||
NGHTTP2_TOKEN_PUBLIC_KEY_PINS,
|
||||
NGHTTP2_TOKEN_SEC_WEBSOCKET_EXTENSIONS,
|
||||
NGHTTP2_TOKEN_SEC_WEBSOCKET_KEY,
|
||||
NGHTTP2_TOKEN_SEC_WEBSOCKET_ORIGIN,
|
||||
NGHTTP2_TOKEN_SEC_WEBSOCKET_PROTOCOL,
|
||||
NGHTTP2_TOKEN_SEC_WEBSOCKET_VERSION,
|
||||
NGHTTP2_TOKEN_SET_COOKIE2,
|
||||
NGHTTP2_TOKEN_STATUS,
|
||||
NGHTTP2_TOKEN_TCN,
|
||||
NGHTTP2_TOKEN_TE,
|
||||
NGHTTP2_TOKEN_TRAILER,
|
||||
NGHTTP2_TOKEN_TSV,
|
||||
NGHTTP2_TOKEN_CONNECTION,
|
||||
NGHTTP2_TOKEN_KEEP_ALIVE,
|
||||
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
||||
NGHTTP2_TOKEN_UPGRADE,
|
||||
NGHTTP2_TOKEN_UPGRADE_INSECURE_REQUESTS,
|
||||
NGHTTP2_TOKEN_VARIANT_VARY,
|
||||
NGHTTP2_TOKEN_WARNING,
|
||||
NGHTTP2_TOKEN_X_API_VERSION,
|
||||
NGHTTP2_TOKEN_X_ATT_DEVICEID,
|
||||
NGHTTP2_TOKEN_X_CACHE,
|
||||
NGHTTP2_TOKEN_X_CACHE_LOOKUP,
|
||||
NGHTTP2_TOKEN_X_CONTENT_DURATION,
|
||||
NGHTTP2_TOKEN_X_CONTENT_SECURITY_POLICY,
|
||||
NGHTTP2_TOKEN_X_CONTENT_TYPE_OPTIONS,
|
||||
NGHTTP2_TOKEN_X_DNSPREFETCH_CONTROL,
|
||||
NGHTTP2_TOKEN_X_FORWARDED_FOR,
|
||||
NGHTTP2_TOKEN_X_FORWARDED_HOST,
|
||||
NGHTTP2_TOKEN_X_FORWARDED_PROTO,
|
||||
NGHTTP2_TOKEN_X_FRAME_OPTIONS,
|
||||
NGHTTP2_TOKEN_X_POWERED_BY,
|
||||
NGHTTP2_TOKEN_X_REQUESTED_WITH,
|
||||
NGHTTP2_TOKEN_X_UA_COMPATIBLE,
|
||||
NGHTTP2_TOKEN_X_WAP_PROFILE,
|
||||
NGHTTP2_TOKEN_X_WEBKIT_CSP,
|
||||
NGHTTP2_TOKEN_X_XSS_PROTECTION,
|
||||
} nghttp2_token;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_FLAG_NONE = 0,
|
||||
/* Indicates name was dynamically allocated and must be freed */
|
||||
NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
|
||||
/* Indicates value was dynamically allocated and must be freed */
|
||||
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
|
||||
/* Indicates that the name was gifted to the entry and no copying
|
||||
necessary. */
|
||||
NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 2,
|
||||
/* Indicates that the value was gifted to the entry and no copying
|
||||
necessary. */
|
||||
NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 3
|
||||
} nghttp2_hd_flags;
|
||||
|
||||
struct nghttp2_hd_entry;
|
||||
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
|
||||
|
||||
typedef struct {
|
||||
/* The buffer containing header field name. NULL-termination is
|
||||
guaranteed. */
|
||||
nghttp2_rcbuf *name;
|
||||
/* The buffer containing header field value. NULL-termination is
|
||||
guaranteed. */
|
||||
nghttp2_rcbuf *value;
|
||||
/* nghttp2_token value for name. It could be -1 if we have no token
|
||||
for that header field name. */
|
||||
int32_t token;
|
||||
/* Bitwise OR of one or more of nghttp2_nv_flag. */
|
||||
uint8_t flags;
|
||||
} nghttp2_hd_nv;
|
||||
|
||||
struct nghttp2_hd_entry {
|
||||
nghttp2_nv nv;
|
||||
/* The header field name/value pair */
|
||||
nghttp2_hd_nv nv;
|
||||
/* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
|
||||
APIs to keep backward compatibility. */
|
||||
nghttp2_nv cnv;
|
||||
/* The next entry which shares same bucket in hash table. */
|
||||
nghttp2_hd_entry *next;
|
||||
/* The sequence number. We will increment it by one whenever we
|
||||
@@ -194,14 +143,17 @@ struct nghttp2_hd_entry {
|
||||
uint32_t seq;
|
||||
/* The hash value for header name (nv.name). */
|
||||
uint32_t hash;
|
||||
/* nghttp2_token value for nv.name. It could be -1 if we have no
|
||||
token for that header field name. */
|
||||
int token;
|
||||
/* Reference count */
|
||||
uint8_t ref;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
/* The entry used for static header table. */
|
||||
typedef struct {
|
||||
nghttp2_rcbuf name;
|
||||
nghttp2_rcbuf value;
|
||||
nghttp2_nv cnv;
|
||||
int32_t token;
|
||||
uint32_t hash;
|
||||
} nghttp2_hd_static_entry;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_hd_entry **buffer;
|
||||
size_t mask;
|
||||
@@ -275,24 +227,18 @@ struct nghttp2_hd_deflater {
|
||||
|
||||
struct nghttp2_hd_inflater {
|
||||
nghttp2_hd_context ctx;
|
||||
/* header buffer */
|
||||
nghttp2_bufs nvbufs;
|
||||
/* Stores current state of huffman decoding */
|
||||
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
||||
/* Pointer to the nghttp2_hd_entry which is used current header
|
||||
emission. This is required because in some cases the
|
||||
ent_keep->ref == 0 and we have to keep track of it. */
|
||||
nghttp2_hd_entry *ent_keep;
|
||||
/* Pointer to the name/value pair buffer which is used in the
|
||||
current header emission. */
|
||||
uint8_t *nv_keep;
|
||||
/* header buffer */
|
||||
nghttp2_buf namebuf, valuebuf;
|
||||
nghttp2_rcbuf *namercbuf, *valuercbuf;
|
||||
/* Pointer to the name/value pair which are used in the current
|
||||
header emission. */
|
||||
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
|
||||
/* The number of bytes to read */
|
||||
size_t left;
|
||||
/* The index in indexed repr or indexed name */
|
||||
size_t index;
|
||||
/* The length of new name encoded in literal. For huffman encoded
|
||||
string, this is the length after it is decoded. */
|
||||
size_t newnamelen;
|
||||
/* The maximum header table size the inflater supports. This is the
|
||||
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
||||
size_t settings_hd_table_bufsize_max;
|
||||
@@ -312,24 +258,16 @@ struct nghttp2_hd_inflater {
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
|
||||
* set in the |flags|, the content pointed by the |name| with length
|
||||
* |namelen| is copied. Likewise, if NGHTTP2_HD_FLAG_VALUE_ALLOC bit
|
||||
* set in the |flags|, the content pointed by the |value| with length
|
||||
* |valuelen| is copied. The |token| is enum number looked up by
|
||||
* |name|. It could be -1 if we don't have that enum value.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* Initializes the |ent| members. The reference counts of nv->name
|
||||
* and nv->value are increased by one for each.
|
||||
*/
|
||||
int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags, uint8_t *name,
|
||||
size_t namelen, uint8_t *value, size_t valuelen,
|
||||
int token, nghttp2_mem *mem);
|
||||
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
|
||||
|
||||
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent, nghttp2_mem *mem);
|
||||
/*
|
||||
* This function decreases the reference counts of nv->name and
|
||||
* nv->value.
|
||||
*/
|
||||
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
|
||||
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
@@ -350,7 +288,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
*
|
||||
* The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
|
||||
* The encoder only uses up to |max_deflate_dynamic_table_size| bytes
|
||||
* for header table even if the larger value is specified later in
|
||||
* nghttp2_hd_change_table_size().
|
||||
*
|
||||
@@ -361,7 +299,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||
size_t deflate_hd_table_bufsize_max,
|
||||
size_t max_deflate_dynamic_table_size,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
@@ -410,16 +348,14 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
|
||||
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
||||
|
||||
/*
|
||||
* Similar to nghttp2_hd_inflate_hd(), but this takes additional
|
||||
* output parameter |token|. On successful header emission, it
|
||||
* contains nghttp2_token value for nv_out->name. It could be -1 if
|
||||
* we don't have enum value for the name. Other than that return
|
||||
* values and semantics are the same as nghttp2_hd_inflate_hd().
|
||||
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
|
||||
* instead of nghttp2_nv as output parameter |nv_out|. Other than
|
||||
* that return values and semantics are the same as
|
||||
* nghttp2_hd_inflate_hd().
|
||||
*/
|
||||
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_nv *nv_out, int *inflate_flags,
|
||||
int *token, uint8_t *in, size_t inlen,
|
||||
int in_final);
|
||||
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_hd_nv *nv_out, int *inflate_flags,
|
||||
const uint8_t *in, size_t inlen, int in_final);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||
@@ -433,11 +369,10 @@ int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
||||
|
||||
/* For unittesting purpose */
|
||||
nghttp2_hd_entry *nghttp2_hd_table_get(nghttp2_hd_context *context,
|
||||
size_t index);
|
||||
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
||||
|
||||
/* For unittesting purpose */
|
||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
|
||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
|
||||
uint32_t initial, size_t shift, uint8_t *in,
|
||||
uint8_t *last, size_t prefix);
|
||||
|
||||
@@ -470,14 +405,13 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
|
||||
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
||||
|
||||
/*
|
||||
* Decodes the given data |src| with length |srclen|. The |ctx| must
|
||||
* Decodes the given data |src| with length |srclen|. The |ctx| must
|
||||
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
|
||||
* will be added to |dest|. This function may expand |dest| as
|
||||
* needed. The caller is responsible to release the memory of |dest|
|
||||
* by calling nghttp2_bufs_free().
|
||||
* will be written to |buf|. This function assumes that |buf| has the
|
||||
* enough room to store the decoded byte string.
|
||||
*
|
||||
* The caller must set the |final| to nonzero if the given input is
|
||||
* the final block.
|
||||
* The caller must set the |fin| to nonzero if the given input is the
|
||||
* final block.
|
||||
*
|
||||
* This function returns the number of read bytes from the |in|.
|
||||
*
|
||||
@@ -486,13 +420,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Maximum buffer capacity size exceeded.
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* Decoding process has failed.
|
||||
*/
|
||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
nghttp2_bufs *bufs, const uint8_t *src,
|
||||
size_t srclen, int final);
|
||||
nghttp2_buf *buf, const uint8_t *src,
|
||||
size_t srclen, int fin);
|
||||
|
||||
#endif /* NGHTTP2_HD_H */
|
||||
|
||||
@@ -64,15 +64,44 @@ static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr,
|
||||
code <<= 8 - (nbits & 0x7);
|
||||
}
|
||||
|
||||
/* we lose at most 3 bytes, but it is not critical in practice */
|
||||
if (*avail_ptr < (nbits + 7) / 8) {
|
||||
rv = nghttp2_bufs_advance(bufs);
|
||||
/* slow path */
|
||||
if (nbits > 24) {
|
||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 24));
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
nbits -= 8;
|
||||
}
|
||||
if (nbits > 16) {
|
||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 16));
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
nbits -= 8;
|
||||
}
|
||||
if (nbits > 8) {
|
||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 8));
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
nbits -= 8;
|
||||
}
|
||||
if (nbits == 8) {
|
||||
rv = nghttp2_bufs_addb(bufs, (uint8_t)code);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
||||
return 8;
|
||||
}
|
||||
|
||||
rv = nghttp2_bufs_addb_hold(bufs, (uint8_t)code);
|
||||
if (rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
||||
/* we assume that we at least 3 buffer space available */
|
||||
assert(*avail_ptr >= 3);
|
||||
return (ssize_t)(8 - nbits);
|
||||
}
|
||||
|
||||
/* fast path, since most code is less than 8 */
|
||||
@@ -166,31 +195,10 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
|
||||
ctx->accept = 1;
|
||||
}
|
||||
|
||||
/* Use macro to make the code simpler..., but error case is tricky.
|
||||
We spent most of the CPU in decoding, so we are doing this
|
||||
thing. */
|
||||
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
|
||||
do { \
|
||||
if ((avail)) { \
|
||||
nghttp2_bufs_fast_addb((bufs), (sym)); \
|
||||
--(avail); \
|
||||
} else { \
|
||||
rv = nghttp2_bufs_addb((bufs), (sym)); \
|
||||
if (rv != 0) { \
|
||||
return rv; \
|
||||
} \
|
||||
(avail) = nghttp2_bufs_cur_avail((bufs)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
nghttp2_bufs *bufs, const uint8_t *src,
|
||||
nghttp2_buf *buf, const uint8_t *src,
|
||||
size_t srclen, int final) {
|
||||
size_t i;
|
||||
int rv;
|
||||
size_t avail;
|
||||
|
||||
avail = nghttp2_bufs_cur_avail(bufs);
|
||||
|
||||
/* We use the decoding algorithm described in
|
||||
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
||||
@@ -202,8 +210,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
return NGHTTP2_ERR_HEADER_COMP;
|
||||
}
|
||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
||||
/* this is macro, and may return from this function on error */
|
||||
hd_huff_decode_sym_emit(bufs, t->sym, avail);
|
||||
*buf->last++ = t->sym;
|
||||
}
|
||||
|
||||
t = &huff_decode_table[t->state][src[i] & 0xf];
|
||||
@@ -211,8 +218,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
return NGHTTP2_ERR_HEADER_COMP;
|
||||
}
|
||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
||||
/* this is macro, and may return from this function on error */
|
||||
hd_huff_decode_sym_emit(bufs, t->sym, avail);
|
||||
*buf->last++ = t->sym;
|
||||
}
|
||||
|
||||
ctx->state = t->state;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -189,8 +189,8 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
||||
account it in *delta_ptr. */
|
||||
*recv_window_size_ptr = recv_reduction_delta;
|
||||
}
|
||||
/* recv_reduction_delta must be paied from *delta_ptr, since it
|
||||
was added in window size reduction (see below). */
|
||||
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
||||
added in window size reduction (see below). */
|
||||
*delta_ptr -= recv_reduction_delta;
|
||||
|
||||
return 0;
|
||||
@@ -213,6 +213,38 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr) {
|
||||
int32_t recv_reduction_delta;
|
||||
int32_t delta;
|
||||
|
||||
delta = *delta_ptr;
|
||||
|
||||
assert(delta >= 0);
|
||||
|
||||
/* The delta size is strictly more than received bytes. Increase
|
||||
local_window_size by that difference |delta|. */
|
||||
if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
|
||||
return NGHTTP2_ERR_FLOW_CONTROL;
|
||||
}
|
||||
|
||||
*local_window_size_ptr += delta;
|
||||
/* If there is recv_reduction due to earlier window_size
|
||||
reduction, we have to adjust it too. */
|
||||
recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
|
||||
*recv_reduction_ptr -= recv_reduction_delta;
|
||||
|
||||
*recv_window_size_ptr += recv_reduction_delta;
|
||||
|
||||
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
||||
added in window size reduction (see below). */
|
||||
*delta_ptr -= recv_reduction_delta;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nghttp2_should_send_window_update(int32_t local_window_size,
|
||||
int32_t recv_window_size) {
|
||||
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
|
||||
@@ -306,58 +338,70 @@ const char *nghttp2_strerror(int error_code) {
|
||||
|
||||
/* Generated by gennmchartbl.py */
|
||||
static int VALID_HD_NAME_CHARS[] = {
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
||||
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
|
||||
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
||||
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
||||
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
||||
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
|
||||
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */,
|
||||
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
|
||||
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
||||
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
|
||||
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
|
||||
0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
|
||||
0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
|
||||
0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
||||
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
|
||||
0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
|
||||
0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */,
|
||||
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
||||
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
||||
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
||||
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */,
|
||||
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
|
||||
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
|
||||
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
|
||||
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
|
||||
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
|
||||
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
|
||||
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
|
||||
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
|
||||
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
|
||||
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
|
||||
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
|
||||
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
|
||||
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
|
||||
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
|
||||
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
|
||||
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
|
||||
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
|
||||
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
|
||||
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
|
||||
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
|
||||
0 /* 0xff */
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
||||
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
||||
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
|
||||
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
||||
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
||||
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
|
||||
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
|
||||
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
|
||||
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
||||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
|
||||
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
|
||||
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
|
||||
0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
|
||||
0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
|
||||
0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
||||
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
|
||||
0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
|
||||
0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
|
||||
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
|
||||
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
||||
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
||||
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
||||
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
||||
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
|
||||
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
|
||||
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
|
||||
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
|
||||
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
|
||||
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
|
||||
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
|
||||
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
|
||||
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
|
||||
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
|
||||
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
|
||||
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
|
||||
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
|
||||
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
|
||||
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
|
||||
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
|
||||
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
|
||||
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
|
||||
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
|
||||
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
|
||||
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
|
||||
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
|
||||
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
|
||||
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
|
||||
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
|
||||
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
|
||||
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
|
||||
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
|
||||
};
|
||||
|
||||
int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
||||
@@ -382,58 +426,70 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
||||
|
||||
/* Generated by genvchartbl.py */
|
||||
static int VALID_HD_VALUE_CHARS[] = {
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
||||
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 1 /* HT */,
|
||||
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
||||
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
||||
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
||||
0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 1 /* " */,
|
||||
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
|
||||
1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
|
||||
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
||||
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */,
|
||||
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
|
||||
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
|
||||
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
|
||||
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
|
||||
1 /* Z */, 1 /* [ */, 1 /* \ */, 1 /* ] */, 1 /* ^ */,
|
||||
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
||||
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
||||
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
||||
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */,
|
||||
1 /* } */, 1 /* ~ */, 0 /* DEL */, 1 /* 0x80 */, 1 /* 0x81 */,
|
||||
1 /* 0x82 */, 1 /* 0x83 */, 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */,
|
||||
1 /* 0x87 */, 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
||||
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, 1 /* 0x90 */,
|
||||
1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, 1 /* 0x94 */, 1 /* 0x95 */,
|
||||
1 /* 0x96 */, 1 /* 0x97 */, 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */,
|
||||
1 /* 0x9b */, 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
||||
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, 1 /* 0xa4 */,
|
||||
1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, 1 /* 0xa8 */, 1 /* 0xa9 */,
|
||||
1 /* 0xaa */, 1 /* 0xab */, 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */,
|
||||
1 /* 0xaf */, 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
||||
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, 1 /* 0xb8 */,
|
||||
1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, 1 /* 0xbc */, 1 /* 0xbd */,
|
||||
1 /* 0xbe */, 1 /* 0xbf */, 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */,
|
||||
1 /* 0xc3 */, 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
||||
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, 1 /* 0xcc */,
|
||||
1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, 1 /* 0xd0 */, 1 /* 0xd1 */,
|
||||
1 /* 0xd2 */, 1 /* 0xd3 */, 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */,
|
||||
1 /* 0xd7 */, 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
|
||||
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, 1 /* 0xe0 */,
|
||||
1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, 1 /* 0xe4 */, 1 /* 0xe5 */,
|
||||
1 /* 0xe6 */, 1 /* 0xe7 */, 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */,
|
||||
1 /* 0xeb */, 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
|
||||
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, 1 /* 0xf4 */,
|
||||
1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, 1 /* 0xf8 */, 1 /* 0xf9 */,
|
||||
1 /* 0xfa */, 1 /* 0xfb */, 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */,
|
||||
1 /* 0xff */
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
||||
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
||||
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
|
||||
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
||||
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
||||
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||
1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
|
||||
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
|
||||
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
|
||||
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
||||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
|
||||
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
||||
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
||||
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
||||
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
|
||||
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
|
||||
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
|
||||
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
|
||||
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
||||
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
||||
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
||||
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
||||
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
|
||||
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
|
||||
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
|
||||
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
|
||||
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
||||
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
|
||||
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
|
||||
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
|
||||
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
|
||||
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
||||
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
|
||||
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
|
||||
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
|
||||
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
|
||||
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
||||
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
|
||||
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
|
||||
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
|
||||
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
|
||||
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
||||
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
|
||||
1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
|
||||
1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
|
||||
1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
|
||||
1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
|
||||
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
|
||||
1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
|
||||
1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
|
||||
1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
|
||||
1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
|
||||
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
|
||||
1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
|
||||
1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
|
||||
1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
|
||||
};
|
||||
|
||||
int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
||||
@@ -451,3 +507,38 @@ uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
|
||||
|
||||
return dest + len;
|
||||
}
|
||||
|
||||
const char *nghttp2_http2_strerror(uint32_t error_code) {
|
||||
switch (error_code) {
|
||||
case NGHTTP2_NO_ERROR:
|
||||
return "NO_ERROR";
|
||||
case NGHTTP2_PROTOCOL_ERROR:
|
||||
return "PROTOCOL_ERROR";
|
||||
case NGHTTP2_INTERNAL_ERROR:
|
||||
return "INTERNAL_ERROR";
|
||||
case NGHTTP2_FLOW_CONTROL_ERROR:
|
||||
return "FLOW_CONTROL_ERROR";
|
||||
case NGHTTP2_SETTINGS_TIMEOUT:
|
||||
return "SETTINGS_TIMEOUT";
|
||||
case NGHTTP2_STREAM_CLOSED:
|
||||
return "STREAM_CLOSED";
|
||||
case NGHTTP2_FRAME_SIZE_ERROR:
|
||||
return "FRAME_SIZE_ERROR";
|
||||
case NGHTTP2_REFUSED_STREAM:
|
||||
return "REFUSED_STREAM";
|
||||
case NGHTTP2_CANCEL:
|
||||
return "CANCEL";
|
||||
case NGHTTP2_COMPRESSION_ERROR:
|
||||
return "COMPRESSION_ERROR";
|
||||
case NGHTTP2_CONNECT_ERROR:
|
||||
return "CONNECT_ERROR";
|
||||
case NGHTTP2_ENHANCE_YOUR_CALM:
|
||||
return "ENHANCE_YOUR_CALM";
|
||||
case NGHTTP2_INADEQUATE_SECURITY:
|
||||
return "INADEQUATE_SECURITY";
|
||||
case NGHTTP2_HTTP_1_1_REQUIRED:
|
||||
return "HTTP_1_1_REQUIRED";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,22 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr);
|
||||
|
||||
/*
|
||||
* This function works like nghttp2_adjust_local_window_size(). The
|
||||
* difference is that this function assumes *delta_ptr >= 0, and
|
||||
* *recv_window_size_ptr is not decreased by *delta_ptr.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FLOW_CONTROL
|
||||
* local_window_size overflow or gets negative.
|
||||
*/
|
||||
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr);
|
||||
|
||||
/*
|
||||
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
||||
* be sent.
|
||||
|
||||
@@ -82,12 +82,12 @@ static int lws(const uint8_t *s, size_t n) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_nv *nv,
|
||||
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
|
||||
int flag) {
|
||||
if (stream->http_flags & flag) {
|
||||
return 0;
|
||||
}
|
||||
if (lws(nv->value, nv->valuelen)) {
|
||||
if (lws(nv->value->base, nv->value->len)) {
|
||||
return 0;
|
||||
}
|
||||
stream->http_flags = (uint16_t)(stream->http_flags | flag);
|
||||
@@ -112,16 +112,16 @@ static int check_path(nghttp2_stream *stream) {
|
||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
|
||||
}
|
||||
|
||||
static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
int token, int trailer) {
|
||||
if (nv->name[0] == ':') {
|
||||
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
||||
int trailer) {
|
||||
if (nv->name->base[0] == ':') {
|
||||
if (trailer ||
|
||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
switch (nv->token) {
|
||||
case NGHTTP2_TOKEN__AUTHORITY:
|
||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
@@ -131,16 +131,16 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
switch (nv->valuelen) {
|
||||
switch (nv->value->len) {
|
||||
case 4:
|
||||
if (lstreq("HEAD", nv->value, nv->valuelen)) {
|
||||
if (lstreq("HEAD", nv->value->base, nv->value->len)) {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
switch (nv->value[6]) {
|
||||
switch (nv->value->base[6]) {
|
||||
case 'T':
|
||||
if (lstreq("CONNECT", nv->value, nv->valuelen)) {
|
||||
if (lstreq("CONNECT", nv->value->base, nv->value->len)) {
|
||||
if (stream->stream_id % 2 == 0) {
|
||||
/* we won't allow CONNECT for push */
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
@@ -153,7 +153,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
if (lstreq("OPTIONS", nv->value, nv->valuelen)) {
|
||||
if (lstreq("OPTIONS", nv->value->base, nv->value->len)) {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
|
||||
}
|
||||
break;
|
||||
@@ -168,9 +168,9 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
if (nv->value[0] == '/') {
|
||||
if (nv->value->base[0] == '/') {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
|
||||
} else if (nv->valuelen == 1 && nv->value[0] == '*') {
|
||||
} else if (nv->value->len == 1 && nv->value->base[0] == '*') {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
|
||||
}
|
||||
break;
|
||||
@@ -181,8 +181,8 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
if ((nv->valuelen == 4 && memieq("http", nv->value, 4)) ||
|
||||
(nv->valuelen == 5 && memieq("https", nv->value, 5))) {
|
||||
if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) ||
|
||||
(nv->value->len == 5 && memieq("https", nv->value->base, 5))) {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
|
||||
}
|
||||
break;
|
||||
@@ -195,7 +195,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
if (stream->content_length != -1) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
stream->content_length = parse_uint(nv->value, nv->valuelen);
|
||||
stream->content_length = parse_uint(nv->value->base, nv->value->len);
|
||||
if (stream->content_length == -1) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
@@ -209,41 +209,41 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
case NGHTTP2_TOKEN_UPGRADE:
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
case NGHTTP2_TOKEN_TE:
|
||||
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
|
||||
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (nv->name[0] == ':') {
|
||||
if (nv->name->base[0] == ':') {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
if (nv->name[0] != ':') {
|
||||
if (nv->name->base[0] != ':') {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
int token, int trailer) {
|
||||
if (nv->name[0] == ':') {
|
||||
static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
||||
int trailer) {
|
||||
if (nv->name->base[0] == ':') {
|
||||
if (trailer ||
|
||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
switch (token) {
|
||||
switch (nv->token) {
|
||||
case NGHTTP2_TOKEN__STATUS: {
|
||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
if (nv->valuelen != 3) {
|
||||
if (nv->value->len != 3) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
stream->status_code = (int16_t)parse_uint(nv->value, nv->valuelen);
|
||||
stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len);
|
||||
if (stream->status_code == -1) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
@@ -253,7 +253,7 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
if (stream->content_length != -1) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
stream->content_length = parse_uint(nv->value, nv->valuelen);
|
||||
stream->content_length = parse_uint(nv->value->base, nv->value->len);
|
||||
if (stream->content_length == -1) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
@@ -267,17 +267,17 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
case NGHTTP2_TOKEN_UPGRADE:
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
case NGHTTP2_TOKEN_TE:
|
||||
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
|
||||
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (nv->name[0] == ':') {
|
||||
if (nv->name->base[0] == ':') {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
}
|
||||
|
||||
if (nv->name[0] != ':') {
|
||||
if (nv->name->base[0] != ':') {
|
||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
||||
}
|
||||
|
||||
@@ -286,58 +286,70 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
||||
|
||||
/* Generated by genauthroitychartbl.py */
|
||||
static char VALID_AUTHORITY_CHARS[] = {
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
||||
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
|
||||
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
||||
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
||||
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
||||
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
|
||||
0 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
|
||||
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
|
||||
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
||||
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 1 /* @ */,
|
||||
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
|
||||
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
|
||||
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
|
||||
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
|
||||
1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 0 /* ^ */,
|
||||
1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
||||
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
||||
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
||||
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
|
||||
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
|
||||
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
|
||||
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
|
||||
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
|
||||
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
|
||||
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
|
||||
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
|
||||
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
|
||||
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
|
||||
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
|
||||
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
|
||||
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
|
||||
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
|
||||
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
|
||||
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
|
||||
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
|
||||
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
|
||||
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
|
||||
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
|
||||
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
|
||||
0 /* 0xff */
|
||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
||||
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
||||
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
|
||||
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
||||
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
||||
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||
0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */,
|
||||
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
|
||||
1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
|
||||
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
||||
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
|
||||
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
||||
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
||||
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
||||
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
|
||||
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
|
||||
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
|
||||
0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */,
|
||||
0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
||||
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
||||
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
||||
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
||||
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
|
||||
0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
|
||||
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
|
||||
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
|
||||
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
|
||||
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
|
||||
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
|
||||
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
|
||||
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
|
||||
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
|
||||
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
|
||||
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
|
||||
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
|
||||
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
|
||||
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
|
||||
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
|
||||
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
|
||||
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
|
||||
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
|
||||
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
|
||||
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
|
||||
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
|
||||
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
|
||||
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
|
||||
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
|
||||
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
|
||||
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
|
||||
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
|
||||
};
|
||||
|
||||
static int check_authority(const uint8_t *value, size_t len) {
|
||||
@@ -375,7 +387,7 @@ static int check_scheme(const uint8_t *value, size_t len) {
|
||||
}
|
||||
|
||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
nghttp2_frame *frame, nghttp2_nv *nv, int token,
|
||||
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
||||
int trailer) {
|
||||
int rv;
|
||||
|
||||
@@ -386,14 +398,14 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
this, we may disrupt many web sites and/or libraries. So we
|
||||
become conservative here, and just ignore those illegal regular
|
||||
headers. */
|
||||
if (!nghttp2_check_header_name(nv->name, nv->namelen)) {
|
||||
if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) {
|
||||
size_t i;
|
||||
if (nv->namelen > 0 && nv->name[0] == ':') {
|
||||
if (nv->name->len > 0 && nv->name->base[0] == ':') {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
/* header field name must be lower-cased without exception */
|
||||
for (i = 0; i < nv->namelen; ++i) {
|
||||
uint8_t c = nv->name[i];
|
||||
for (i = 0; i < nv->name->len; ++i) {
|
||||
uint8_t c = nv->name->base[i];
|
||||
if ('A' <= c && c <= 'Z') {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
@@ -405,17 +417,18 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
return NGHTTP2_ERR_IGN_HTTP_HEADER;
|
||||
}
|
||||
|
||||
if (token == NGHTTP2_TOKEN__AUTHORITY || token == NGHTTP2_TOKEN_HOST) {
|
||||
rv = check_authority(nv->value, nv->valuelen);
|
||||
} else if (token == NGHTTP2_TOKEN__SCHEME) {
|
||||
rv = check_scheme(nv->value, nv->valuelen);
|
||||
if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
|
||||
nv->token == NGHTTP2_TOKEN_HOST) {
|
||||
rv = check_authority(nv->value->base, nv->value->len);
|
||||
} else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
|
||||
rv = check_scheme(nv->value->base, nv->value->len);
|
||||
} else {
|
||||
rv = nghttp2_check_header_value(nv->value, nv->valuelen);
|
||||
rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
|
||||
}
|
||||
|
||||
if (rv == 0) {
|
||||
assert(nv->namelen > 0);
|
||||
if (nv->name[0] == ':') {
|
||||
assert(nv->name->len > 0);
|
||||
if (nv->name->base[0] == ':') {
|
||||
return NGHTTP2_ERR_HTTP_HEADER;
|
||||
}
|
||||
/* When ignoring regular headers, we set this flag so that we
|
||||
@@ -426,10 +439,10 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
}
|
||||
|
||||
if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
||||
return http_request_on_header(stream, nv, token, trailer);
|
||||
return http_request_on_header(stream, nv, trailer);
|
||||
}
|
||||
|
||||
return http_response_on_header(stream, nv, token, trailer);
|
||||
return http_response_on_header(stream, nv, trailer);
|
||||
}
|
||||
|
||||
int nghttp2_http_on_request_headers(nghttp2_stream *stream,
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
/*
|
||||
* This function is called when HTTP header field |nv| in |frame| is
|
||||
* received for |stream|. This function will validate |nv| against
|
||||
* the current state of stream. The |token| is nghttp2_token value
|
||||
* for nv->name, or -1 if we don't have enum value for the name.
|
||||
* the current state of stream.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
@@ -49,7 +48,7 @@
|
||||
* if it was not received because of compatibility reasons.
|
||||
*/
|
||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
nghttp2_frame *frame, nghttp2_nv *nv, int token,
|
||||
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
||||
int trailer);
|
||||
|
||||
/*
|
||||
|
||||
@@ -29,15 +29,9 @@
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* Macros, types and constants for internal use */
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(x) x
|
||||
#else
|
||||
#define DEBUGF(x) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
/* Macros, types and constants for internal use */
|
||||
|
||||
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
||||
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
||||
|
||||
@@ -170,20 +170,18 @@ nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
|
||||
|
||||
int nghttp2_map_remove(nghttp2_map *map, key_type key) {
|
||||
uint32_t h;
|
||||
nghttp2_map_entry *entry, *prev;
|
||||
nghttp2_map_entry **dst;
|
||||
|
||||
h = hash(key, map->tablelen);
|
||||
prev = NULL;
|
||||
for (entry = map->table[h]; entry; entry = entry->next) {
|
||||
if (entry->key == key) {
|
||||
if (prev == NULL) {
|
||||
map->table[h] = entry->next;
|
||||
} else {
|
||||
prev->next = entry->next;
|
||||
}
|
||||
--map->size;
|
||||
return 0;
|
||||
|
||||
for (dst = &map->table[h]; *dst; dst = &(*dst)->next) {
|
||||
if ((*dst)->key != key) {
|
||||
continue;
|
||||
}
|
||||
prev = entry;
|
||||
|
||||
*dst = (*dst)->next;
|
||||
--map->size;
|
||||
return 0;
|
||||
}
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ void nghttp2_mem_free(nghttp2_mem *mem, void *ptr) {
|
||||
mem->free(ptr, mem->mem_user_data);
|
||||
}
|
||||
|
||||
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data) {
|
||||
free_func(ptr, mem_user_data);
|
||||
}
|
||||
|
||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) {
|
||||
return mem->calloc(nmemb, size, mem->mem_user_data);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ nghttp2_mem *nghttp2_mem_default(void);
|
||||
|mem|. */
|
||||
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
|
||||
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
|
||||
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
|
||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
||||
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ static int select_next_protocol(unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen,
|
||||
const char *key, unsigned int keylen) {
|
||||
unsigned int i;
|
||||
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in [i] + 1)) {
|
||||
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) {
|
||||
if (memcmp(&in[i], key, keylen) == 0) {
|
||||
*out = (unsigned char *)&in[i + 1];
|
||||
*outlen = in[i];
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
#include "nghttp2_option.h"
|
||||
|
||||
#include "nghttp2_session.h"
|
||||
|
||||
int nghttp2_option_new(nghttp2_option **option_ptr) {
|
||||
*option_ptr = calloc(1, sizeof(nghttp2_option));
|
||||
|
||||
@@ -63,6 +65,10 @@ void nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option,
|
||||
option->max_reserved_remote_streams = val;
|
||||
}
|
||||
|
||||
static void set_ext_type(uint8_t *ext_types, uint8_t type) {
|
||||
ext_types[type / 8] = (uint8_t)(ext_types[type / 8] | (1 << (type & 0x7)));
|
||||
}
|
||||
|
||||
void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
|
||||
uint8_t type) {
|
||||
if (type < 10) {
|
||||
@@ -70,6 +76,34 @@ void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
|
||||
}
|
||||
|
||||
option->opt_set_mask |= NGHTTP2_OPT_USER_RECV_EXT_TYPES;
|
||||
option->user_recv_ext_types[type / 8] =
|
||||
(uint8_t)(option->user_recv_ext_types[type / 8] | (1 << (type & 0x7)));
|
||||
set_ext_type(option->user_recv_ext_types, type);
|
||||
}
|
||||
|
||||
void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
|
||||
uint8_t type) {
|
||||
switch (type) {
|
||||
case NGHTTP2_ALTSVC:
|
||||
option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
|
||||
option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC;
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) {
|
||||
option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK;
|
||||
option->no_auto_ping_ack = val;
|
||||
}
|
||||
|
||||
void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
|
||||
size_t val) {
|
||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH;
|
||||
option->max_send_header_block_length = val;
|
||||
}
|
||||
|
||||
void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
|
||||
size_t val) {
|
||||
option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE;
|
||||
option->max_deflate_dynamic_table_size = val;
|
||||
}
|
||||
|
||||
@@ -60,13 +60,25 @@ typedef enum {
|
||||
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
|
||||
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
||||
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
||||
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5
|
||||
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
|
||||
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
|
||||
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
|
||||
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
|
||||
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
|
||||
} nghttp2_option_flag;
|
||||
|
||||
/**
|
||||
* Struct to store option values for nghttp2_session.
|
||||
*/
|
||||
struct nghttp2_option {
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
||||
*/
|
||||
size_t max_send_header_block_length;
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
|
||||
*/
|
||||
size_t max_deflate_dynamic_table_size;
|
||||
/**
|
||||
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
||||
* are specified.
|
||||
@@ -80,6 +92,10 @@ struct nghttp2_option {
|
||||
* NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS
|
||||
*/
|
||||
uint32_t max_reserved_remote_streams;
|
||||
/**
|
||||
* NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
|
||||
*/
|
||||
uint32_t builtin_recv_ext_types;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE
|
||||
*/
|
||||
@@ -92,6 +108,10 @@ struct nghttp2_option {
|
||||
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
||||
*/
|
||||
int no_http_messaging;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_AUTO_PING_ACK
|
||||
*/
|
||||
int no_auto_ping_ack;
|
||||
/**
|
||||
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
|
||||
*/
|
||||
|
||||
@@ -72,9 +72,25 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
|
||||
case NGHTTP2_WINDOW_UPDATE:
|
||||
nghttp2_frame_window_update_free(&frame->window_update);
|
||||
break;
|
||||
default:
|
||||
nghttp2_frame_extension_free(&frame->ext);
|
||||
break;
|
||||
default: {
|
||||
nghttp2_ext_aux_data *aux_data;
|
||||
|
||||
aux_data = &item->aux_data.ext;
|
||||
|
||||
if (aux_data->builtin == 0) {
|
||||
nghttp2_frame_extension_free(&frame->ext);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (frame->hd.type) {
|
||||
case NGHTTP2_ALTSVC:
|
||||
nghttp2_frame_altsvc_free(&frame->ext, mem);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user