mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-08 02:58:53 +08:00
Compare commits
1070 Commits
hpack-8bit
...
asio_threa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1f4dafd73 | ||
|
|
13fc54c6a9 | ||
|
|
36a2023310 | ||
|
|
51e474c097 | ||
|
|
0df13452aa | ||
|
|
aad3e275d1 | ||
|
|
1649948e78 | ||
|
|
6d3e010ae7 | ||
|
|
7dddac081e | ||
|
|
588dd33241 | ||
|
|
2d9be885ec | ||
|
|
14ccb24be5 | ||
|
|
025ec85144 | ||
|
|
bd97886d8e | ||
|
|
0b1ddad62b | ||
|
|
540853bde8 | ||
|
|
c757f7d848 | ||
|
|
052f3a3871 | ||
|
|
2ae83e871b | ||
|
|
1cc08c0a51 | ||
|
|
16be89f9cc | ||
|
|
b72c5f104e | ||
|
|
7e6eb7e02a | ||
|
|
712b08e8ed | ||
|
|
fbf156d22d | ||
|
|
965a0e87e5 | ||
|
|
2b55ca1ce6 | ||
|
|
534c01896c | ||
|
|
c25197ac40 | ||
|
|
becae65257 | ||
|
|
ba9f2c3ae2 | ||
|
|
0387525b77 | ||
|
|
5311185333 | ||
|
|
2fc2a27ac1 | ||
|
|
db938afd66 | ||
|
|
89ddc47616 | ||
|
|
90b7849af1 | ||
|
|
3176e872b3 | ||
|
|
16206d5f67 | ||
|
|
0f33749790 | ||
|
|
5e7e4c0cc0 | ||
|
|
25503ad763 | ||
|
|
8f513fceca | ||
|
|
91af4ed70d | ||
|
|
685e926494 | ||
|
|
a2afd393ed | ||
|
|
4e9098bccf | ||
|
|
33aa327ef5 | ||
|
|
9067ff5eee | ||
|
|
efeede4192 | ||
|
|
6a8749873f | ||
|
|
b1b8308555 | ||
|
|
9b574a5a76 | ||
|
|
0567f1f038 | ||
|
|
4be5de1163 | ||
|
|
9db1c9467c | ||
|
|
3444b42d44 | ||
|
|
6595ae26ea | ||
|
|
41d8a3ac09 | ||
|
|
175001a8d9 | ||
|
|
7cf9e00283 | ||
|
|
8a3eb3f066 | ||
|
|
7e1a0d204b | ||
|
|
cbca2e35b5 | ||
|
|
fc9bdf024f | ||
|
|
3f97e6cd3a | ||
|
|
4fa150c494 | ||
|
|
e8b2508036 | ||
|
|
ac399e41ac | ||
|
|
95dd908834 | ||
|
|
9c7e54d9b5 | ||
|
|
3c03024881 | ||
|
|
36dfc0a56a | ||
|
|
55bf6cdb15 | ||
|
|
0abc220013 | ||
|
|
c28900990a | ||
|
|
5108193d7b | ||
|
|
79a24f5dd9 | ||
|
|
83c759572c | ||
|
|
1a07fb000b | ||
|
|
4aab15999d | ||
|
|
441982674f | ||
|
|
8256c6e070 | ||
|
|
ae87a44b94 | ||
|
|
87d1692e27 | ||
|
|
1d2f008656 | ||
|
|
b064d8a9ff | ||
|
|
528af200b6 | ||
|
|
c6827a7dac | ||
|
|
55ecb082ee | ||
|
|
5f2cf461e6 | ||
|
|
b313386988 | ||
|
|
3933280d29 | ||
|
|
2b6073900f | ||
|
|
d1ba43a69f | ||
|
|
a0779edec4 | ||
|
|
d70fefe72f | ||
|
|
b52db072f1 | ||
|
|
ab0b98db61 | ||
|
|
4245d98653 | ||
|
|
93b4866f5b | ||
|
|
25df164219 | ||
|
|
ba03c082e9 | ||
|
|
bcfa333322 | ||
|
|
c4aeadd57d | ||
|
|
e6b4454e48 | ||
|
|
3226d21609 | ||
|
|
3d20c2dce6 | ||
|
|
cd83d70e7b | ||
|
|
a0ce5ea9ab | ||
|
|
3c600c103f | ||
|
|
841ac75c3e | ||
|
|
80a96817aa | ||
|
|
ecc05e0a1a | ||
|
|
359730af54 | ||
|
|
e9cb19c80e | ||
|
|
049e064e28 | ||
|
|
0463928a1e | ||
|
|
02d34c8c4c | ||
|
|
46acf32c41 | ||
|
|
cab0a76795 | ||
|
|
0c76cebbfc | ||
|
|
5029b85b25 | ||
|
|
0b71d9b828 | ||
|
|
464d7c4ec6 | ||
|
|
ed21b631ae | ||
|
|
950e2d9954 | ||
|
|
71c054a789 | ||
|
|
d2f456e5b1 | ||
|
|
30a44b26d3 | ||
|
|
7dff758f8b | ||
|
|
bd3ececdd8 | ||
|
|
77416b0ac2 | ||
|
|
fce9efd341 | ||
|
|
928fda1d70 | ||
|
|
2d9d654507 | ||
|
|
7398e57174 | ||
|
|
503ec82f4d | ||
|
|
22bd9fb530 | ||
|
|
e007b6b031 | ||
|
|
c487cd888f | ||
|
|
fd403a85c8 | ||
|
|
a06a8c36a4 | ||
|
|
0967ee9cb9 | ||
|
|
d66d34f9b9 | ||
|
|
264a98d106 | ||
|
|
7c11d2d9bb | ||
|
|
b58d7b406f | ||
|
|
5ed9e4c83b | ||
|
|
e7da2a669e | ||
|
|
d66377d4b6 | ||
|
|
77a324fa46 | ||
|
|
38b5cad4e3 | ||
|
|
29014643a9 | ||
|
|
0872f6babe | ||
|
|
b6a9cf9ffa | ||
|
|
5645cad577 | ||
|
|
85ba33c08f | ||
|
|
ff64f64e1d | ||
|
|
bdd3425028 | ||
|
|
70e02cddd3 | ||
|
|
d1c0a17cc2 | ||
|
|
35c5cbbc21 | ||
|
|
2ff31bdd2b | ||
|
|
2fa3d34af1 | ||
|
|
fa3452ec68 | ||
|
|
7451f2f212 | ||
|
|
e9ab75a386 | ||
|
|
d83949bc88 | ||
|
|
50f42a80c9 | ||
|
|
00bd76fc3d | ||
|
|
93ea6b581e | ||
|
|
8e52a5c7f3 | ||
|
|
0aa35e574a | ||
|
|
5a81f2441f | ||
|
|
2b75aff32e | ||
|
|
f4474d57ec | ||
|
|
d0310c8aee | ||
|
|
8471c9e92e | ||
|
|
f5a4c9d971 | ||
|
|
a0dd8918eb | ||
|
|
baa9b1cac0 | ||
|
|
38443d2195 | ||
|
|
208d71561a | ||
|
|
25fbc7b435 | ||
|
|
6bd95d885d | ||
|
|
c171097dea | ||
|
|
6bcdb178a5 | ||
|
|
5e10cc4cad | ||
|
|
95e6c875f0 | ||
|
|
6eb2829ee8 | ||
|
|
6ad9ddcdea | ||
|
|
e082b7be72 | ||
|
|
da01d8dedb | ||
|
|
ca6f6511f2 | ||
|
|
ee8440408c | ||
|
|
9cd695a1db | ||
|
|
4b45906f46 | ||
|
|
d448eb54f9 | ||
|
|
65739fe754 | ||
|
|
0344c962f8 | ||
|
|
46d1e6bb55 | ||
|
|
04606b9339 | ||
|
|
7bb083e69e | ||
|
|
3a831fa95c | ||
|
|
5b9cacc2d7 | ||
|
|
10a84f3e3d | ||
|
|
c42715ed6a | ||
|
|
177d51ddab | ||
|
|
6c882e1ece | ||
|
|
f09c5c4bf9 | ||
|
|
08a9a2eca9 | ||
|
|
19f1785cde | ||
|
|
109de15c1f | ||
|
|
8b64e7b4e1 | ||
|
|
a5d66e71d0 | ||
|
|
3de2654223 | ||
|
|
d49bd50908 | ||
|
|
4130c68db1 | ||
|
|
ad3dac81a2 | ||
|
|
0cf6848646 | ||
|
|
e9d562f987 | ||
|
|
bc0f501dd3 | ||
|
|
a591001e7b | ||
|
|
eaa9229d72 | ||
|
|
1d5cde1c6b | ||
|
|
de03c41111 | ||
|
|
19340da8d4 | ||
|
|
5e99531b4d | ||
|
|
bef3d47c16 | ||
|
|
b8f7b474b4 | ||
|
|
1fb291d0e1 | ||
|
|
bc3dc6b765 | ||
|
|
ee7c36c022 | ||
|
|
857791dbb9 | ||
|
|
3c3267ea7d | ||
|
|
d654664fb2 | ||
|
|
1a37044d3c | ||
|
|
00a8c378d4 | ||
|
|
7549341081 | ||
|
|
5db8473f12 | ||
|
|
00b89f10bd | ||
|
|
281df33f40 | ||
|
|
e6ae681f07 | ||
|
|
7e681dc98f | ||
|
|
412c8f9e67 | ||
|
|
2795da840c | ||
|
|
175c7886ea | ||
|
|
4a4b2cf538 | ||
|
|
2c2188c09d | ||
|
|
1f07c24a2e | ||
|
|
e038625881 | ||
|
|
cdb1d6b462 | ||
|
|
1b4ccd0d51 | ||
|
|
8babaac8c3 | ||
|
|
d1624d6929 | ||
|
|
e4472b5aec | ||
|
|
9439ba75d3 | ||
|
|
9254c563ca | ||
|
|
35594e09df | ||
|
|
96ff3be5e6 | ||
|
|
3d5d76ba74 | ||
|
|
8c1e155f44 | ||
|
|
dba0d2791c | ||
|
|
f310e82fc8 | ||
|
|
1240e55bb6 | ||
|
|
75039c573c | ||
|
|
4b5179a544 | ||
|
|
8efccddcf4 | ||
|
|
97843e3874 | ||
|
|
5dd2704051 | ||
|
|
de7b7fd440 | ||
|
|
1037d3ad26 | ||
|
|
c4368a9416 | ||
|
|
fdc1eb526b | ||
|
|
99a91e3172 | ||
|
|
272cfa320e | ||
|
|
f5285d1f5a | ||
|
|
ede6104900 | ||
|
|
5aec60fbeb | ||
|
|
e1a865c406 | ||
|
|
5e03b6a0db | ||
|
|
b85924bf70 | ||
|
|
19707aac55 | ||
|
|
9ad873fc06 | ||
|
|
8a9810ed32 | ||
|
|
68a6d8c50b | ||
|
|
600605400c | ||
|
|
97aa4dabc8 | ||
|
|
a6f487240d | ||
|
|
da135416bb | ||
|
|
13eb881e5e | ||
|
|
82c84d163b | ||
|
|
a526183928 | ||
|
|
60222ae7c3 | ||
|
|
2052a1a4bd | ||
|
|
183be9cac9 | ||
|
|
69b53b9aaa | ||
|
|
02b9fcd332 | ||
|
|
231d739b10 | ||
|
|
e1dfff8929 | ||
|
|
db1716ae93 | ||
|
|
4cdc74c957 | ||
|
|
2c17ec3df8 | ||
|
|
e464b10fc3 | ||
|
|
03ba399176 | ||
|
|
751d66a397 | ||
|
|
3ec71bf5a2 | ||
|
|
f19b0724a3 | ||
|
|
a7e0a69f97 | ||
|
|
e532e20491 | ||
|
|
3e1cfa8e99 | ||
|
|
a100df9cae | ||
|
|
56284b1e15 | ||
|
|
f267e400fa | ||
|
|
8bac5899cc | ||
|
|
f4016644a9 | ||
|
|
d9bc6d04f7 | ||
|
|
743fc4a3c3 | ||
|
|
392256e542 | ||
|
|
905e16cb99 | ||
|
|
9d4e8eeb12 | ||
|
|
8099dd9558 | ||
|
|
a3a6b91c5f | ||
|
|
d9bb3448bf | ||
|
|
d508a0c72c | ||
|
|
bc31146c1f | ||
|
|
1ad7d5e366 | ||
|
|
456038e3de | ||
|
|
9aa26970be | ||
|
|
20c39fa843 | ||
|
|
f5a2f1da25 | ||
|
|
27b250ac8e | ||
|
|
b14375ec63 | ||
|
|
6858cda366 | ||
|
|
8a703d21ae | ||
|
|
1dabe43ff4 | ||
|
|
900aef10da | ||
|
|
ded576f423 | ||
|
|
136aae725f | ||
|
|
a60c3f8939 | ||
|
|
99dc31ff1a | ||
|
|
7673848325 | ||
|
|
0f8a5ffc23 | ||
|
|
fddb019baf | ||
|
|
72bf7d4af0 | ||
|
|
581e0938a9 | ||
|
|
1064e017c6 | ||
|
|
79b07f0ce2 | ||
|
|
cd471a989a | ||
|
|
0ea44072a3 | ||
|
|
6ba1abac6c | ||
|
|
0110d2f9f8 | ||
|
|
baa0f60dc8 | ||
|
|
69aa70086a | ||
|
|
13d3f785bd | ||
|
|
39c068974d | ||
|
|
0d4d1a63d4 | ||
|
|
833cd962a1 | ||
|
|
8103f43b65 | ||
|
|
1c8a672a8d | ||
|
|
4749e66c67 | ||
|
|
25ea41972a | ||
|
|
7d66188910 | ||
|
|
979c99eaea | ||
|
|
cf7f87c2ad | ||
|
|
bd0c1edaa6 | ||
|
|
c7ef021b4b | ||
|
|
00c80a15c0 | ||
|
|
8f47b68a95 | ||
|
|
d9139fc286 | ||
|
|
e693f75670 | ||
|
|
759f6c0b39 | ||
|
|
3e0d73c01d | ||
|
|
5cf21ec187 | ||
|
|
62e1d1c952 | ||
|
|
6ae58cc22e | ||
|
|
874ef1ac54 | ||
|
|
5f65460944 | ||
|
|
41b2745dad | ||
|
|
30f9f9ef87 | ||
|
|
4807e71b7d | ||
|
|
09c647fd1b | ||
|
|
d0fea96e69 | ||
|
|
b8883101d3 | ||
|
|
508c88f659 | ||
|
|
40d217beb1 | ||
|
|
e36caef006 | ||
|
|
9b864380a5 | ||
|
|
0e1d0400d8 | ||
|
|
afdd51ff15 | ||
|
|
488c3588d9 | ||
|
|
4f02b191d1 | ||
|
|
8acef2711b | ||
|
|
c6111b3792 | ||
|
|
c4d36aeff7 | ||
|
|
f50596e355 | ||
|
|
abf81b5bb7 | ||
|
|
8579b8a968 | ||
|
|
8df2c357d9 | ||
|
|
4c381611a1 | ||
|
|
7dfd6ab1ad | ||
|
|
0c7d48dede | ||
|
|
4639a66e53 | ||
|
|
65cc2f0515 | ||
|
|
4eb7f98449 | ||
|
|
2d8059a9a5 | ||
|
|
a3d22b6db9 | ||
|
|
3f31424ee2 | ||
|
|
e0119452a3 | ||
|
|
60cae325bc | ||
|
|
16c46114dc | ||
|
|
862175b21c | ||
|
|
e7e3d77c53 | ||
|
|
af9aeee752 | ||
|
|
ad3d43b8be | ||
|
|
210a5c4f01 | ||
|
|
d8822f2a8e | ||
|
|
b7a72b1e5a | ||
|
|
2f106dc96b | ||
|
|
f619286ca3 | ||
|
|
271f7fbbb6 | ||
|
|
318235db33 | ||
|
|
8ab079ccc2 | ||
|
|
a4d2104c3c | ||
|
|
44672e437a | ||
|
|
fb3d6f68a8 | ||
|
|
d7c9015d8b | ||
|
|
54f640f3e1 | ||
|
|
e2906025c8 | ||
|
|
9a8e9815c9 | ||
|
|
8c3e864989 | ||
|
|
22570b7260 | ||
|
|
fb49182c29 | ||
|
|
b9b648e0ed | ||
|
|
494775a25d | ||
|
|
1214f9e23b | ||
|
|
a54cda22ab | ||
|
|
f4a4abd180 | ||
|
|
c9559b5c0d | ||
|
|
af5b354685 | ||
|
|
3c1c2c4aad | ||
|
|
767ed255ca | ||
|
|
aa0023b3c1 | ||
|
|
3bdc143474 | ||
|
|
8b50cc0ece | ||
|
|
a24c94e92a | ||
|
|
a00442bee6 | ||
|
|
f857b63986 | ||
|
|
cbd72da9a1 | ||
|
|
7506a93179 | ||
|
|
53e1623ab3 | ||
|
|
0cb0bdabec | ||
|
|
ed8d5f04bb | ||
|
|
33153010c5 | ||
|
|
2c500b62fd | ||
|
|
30f26a2b9d | ||
|
|
ca39c71ac3 | ||
|
|
2bbe4422d2 | ||
|
|
5d3535126e | ||
|
|
d2addbc1ed | ||
|
|
110ca3131a | ||
|
|
fd7d3c57d7 | ||
|
|
179561e4be | ||
|
|
903e0077aa | ||
|
|
3fadad1bf3 | ||
|
|
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 | ||
|
|
d1f9f9a3aa | ||
|
|
2415a22757 | ||
|
|
887d4d2a41 | ||
|
|
1c8e625045 | ||
|
|
36e931e0d7 | ||
|
|
31d4077638 | ||
|
|
c098b4ac70 | ||
|
|
32446a5197 | ||
|
|
40c1b29f36 | ||
|
|
bc933e9981 | ||
|
|
ba34e911e1 | ||
|
|
8aac5d6af2 | ||
|
|
56bdfd1df2 | ||
|
|
dbffb8995b | ||
|
|
ebfae904ab | ||
|
|
827abb57e9 | ||
|
|
9aee43f7d8 | ||
|
|
34bf153653 | ||
|
|
2782ef67de | ||
|
|
9d15f9b00d | ||
|
|
3e72711e23 | ||
|
|
f4bb8776d0 | ||
|
|
95ffb4565f | ||
|
|
f3a415f623 | ||
|
|
936d4aca1a | ||
|
|
216ae0a328 | ||
|
|
9672bc322f | ||
|
|
b68be1e1fb | ||
|
|
f2a7275700 | ||
|
|
177d0a513f | ||
|
|
dfc02843b6 | ||
|
|
11c8803b92 | ||
|
|
c9a4f293a1 | ||
|
|
61579ad20f | ||
|
|
9678daa46a | ||
|
|
23ecfd412d | ||
|
|
3ff148811b | ||
|
|
6f1347fc8b | ||
|
|
1703201084 | ||
|
|
7921029e33 | ||
|
|
b7159f80b2 | ||
|
|
9c874bf9b5 | ||
|
|
9ab5ef3b5b | ||
|
|
f0b5a8db8c | ||
|
|
4814d14db5 | ||
|
|
77e8190b6c | ||
|
|
f4b2a4ab00 | ||
|
|
a909eb6b23 | ||
|
|
3dd57e1f59 | ||
|
|
1b67b2d33e | ||
|
|
9bc6dc7113 | ||
|
|
f407f7f406 | ||
|
|
094168a58f | ||
|
|
474ecc4b47 | ||
|
|
0afc21c9d8 | ||
|
|
63e43bff99 | ||
|
|
8c46d9181f | ||
|
|
cc92ebf471 | ||
|
|
02b7116d42 | ||
|
|
aa3373a107 | ||
|
|
7aabc6b125 | ||
|
|
466e4b7a1e | ||
|
|
76a425226f | ||
|
|
2b707bff27 | ||
|
|
9055323b67 | ||
|
|
67804cfc8c | ||
|
|
2344932b45 | ||
|
|
35ebdd35bc | ||
|
|
ac81003669 | ||
|
|
c999987baf | ||
|
|
529a59d309 | ||
|
|
52f6417813 | ||
|
|
c96cf1b303 | ||
|
|
660bc389e6 | ||
|
|
bfc26e8299 | ||
|
|
47106c0756 | ||
|
|
49fa914db5 | ||
|
|
93eabc642b | ||
|
|
2d273f8237 | ||
|
|
a53f0f0a17 | ||
|
|
1bd98dcf4f | ||
|
|
eebed206c9 | ||
|
|
fe74600a5f | ||
|
|
08e2d7cdb3 | ||
|
|
503f0a29a7 | ||
|
|
ee285fa5da | ||
|
|
8c562bd38d | ||
|
|
15adc23277 | ||
|
|
a2ec695ec9 | ||
|
|
55b270587b | ||
|
|
5297136bc0 | ||
|
|
61bb6428fd | ||
|
|
ccd2d34160 | ||
|
|
ea6eed10c7 | ||
|
|
7a86758edb | ||
|
|
90d66ea4a9 | ||
|
|
5b21c39bb2 | ||
|
|
744e80d579 | ||
|
|
3842fe175c | ||
|
|
900667a998 | ||
|
|
147e098827 | ||
|
|
5819d03c68 | ||
|
|
90f5bf796d | ||
|
|
2b63980758 | ||
|
|
65d33c553c | ||
|
|
2593036053 | ||
|
|
a6effb4d23 | ||
|
|
17215002a1 | ||
|
|
0e469ed221 | ||
|
|
093eb51f8c | ||
|
|
5f1866fd6b | ||
|
|
d8c8a4631d | ||
|
|
6b12f17f44 | ||
|
|
eb0c82d91f | ||
|
|
7adfa5dea7 | ||
|
|
17758126fa | ||
|
|
b440f585bc | ||
|
|
63a13ccb18 | ||
|
|
72877379ec | ||
|
|
8449958425 | ||
|
|
9037641592 | ||
|
|
c0078ab45a | ||
|
|
3a41e4dd1a | ||
|
|
3297a303bf | ||
|
|
f1580f95d4 | ||
|
|
1e150bcf61 | ||
|
|
ca371e3ba9 | ||
|
|
61dda40b44 | ||
|
|
5ad753b90c | ||
|
|
0a1beea13a | ||
|
|
00e722f02c | ||
|
|
ff22862b9d | ||
|
|
b2264ad57e | ||
|
|
b0227d4051 | ||
|
|
28b643e531 | ||
|
|
82f942c3a3 | ||
|
|
e4a727f86c | ||
|
|
b624ca6dcd | ||
|
|
ba4c268172 | ||
|
|
00175eac33 | ||
|
|
396dde1347 | ||
|
|
042a59117d | ||
|
|
b8717208c7 | ||
|
|
304ff6a6f9 | ||
|
|
fc39f2d9d2 | ||
|
|
e14da859b6 | ||
|
|
0248d979fe | ||
|
|
0caefe20ef | ||
|
|
9c84f60ba0 | ||
|
|
83cc2511e3 | ||
|
|
eb4e402aae | ||
|
|
5d611d2e24 | ||
|
|
837e716306 | ||
|
|
061a557839 | ||
|
|
d9893d014c | ||
|
|
3785cf07ba |
@@ -1,57 +1,94 @@
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: LLVM
|
|
||||||
AccessModifierOffset: -2
|
AccessModifierOffset: -2
|
||||||
ConstructorInitializerIndentWidth: 4
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
AlignEscapedNewlinesLeft: false
|
AlignEscapedNewlinesLeft: false
|
||||||
|
AlignOperands: true
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: false
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: All
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakTemplateDeclarations: false
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
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
|
BreakBeforeTernaryOperators: true
|
||||||
BreakConstructorInitializersBeforeComma: false
|
BreakConstructorInitializersBeforeComma: false
|
||||||
BinPackParameters: true
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 80
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
DerivePointerAlignment: false
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
ExperimentalAutoDetectBinPacking: false
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^(<|"(gtest|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
IncludeIsMainRegex: '$'
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
|
IndentWidth: 2
|
||||||
IndentWrappedFunctionNames: false
|
IndentWrappedFunctionNames: false
|
||||||
IndentFunctionDeclarationAfterType: false
|
JavaScriptQuotes: Leave
|
||||||
MaxEmptyLinesToKeep: 1
|
JavaScriptWrapImports: true
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
NamespaceIndentation: None
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ObjCSpaceBeforeProtocolList: true
|
||||||
PenaltyBreakBeforeFirstCallParameter: 19
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
PenaltyBreakComment: 300
|
PenaltyBreakComment: 300
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
Cpp11BracedListStyle: true
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
Standard: Cpp11
|
Standard: Cpp11
|
||||||
IndentWidth: 2
|
|
||||||
TabWidth: 8
|
TabWidth: 8
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
BreakBeforeBraces: Attach
|
|
||||||
SpacesInParentheses: false
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
|
||||||
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
DisableFormat: false
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
16
.gitignore
vendored
16
.gitignore
vendored
@@ -29,6 +29,22 @@ missing
|
|||||||
stamp-h1
|
stamp-h1
|
||||||
test-driver
|
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`
|
# test logs generated by `make check`
|
||||||
*.log
|
*.log
|
||||||
*.trs
|
*.trs
|
||||||
|
|||||||
29
.travis.yml
29
.travis.yml
@@ -1,3 +1,7 @@
|
|||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- CI_BUILD=cmake
|
||||||
|
- CI_BUILD=autotools
|
||||||
language: cpp
|
language: cpp
|
||||||
compiler:
|
compiler:
|
||||||
- clang
|
- clang
|
||||||
@@ -7,6 +11,7 @@ addons:
|
|||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- ubuntu-toolchain-r-test
|
- ubuntu-toolchain-r-test
|
||||||
|
- george-edison55-precise-backports
|
||||||
packages:
|
packages:
|
||||||
- g++-4.9
|
- g++-4.9
|
||||||
- libstdc++-4.9-dev
|
- libstdc++-4.9-dev
|
||||||
@@ -23,11 +28,15 @@ addons:
|
|||||||
- libevent-dev
|
- libevent-dev
|
||||||
- libjansson-dev
|
- libjansson-dev
|
||||||
- libjemalloc-dev
|
- libjemalloc-dev
|
||||||
|
- libc-ares-dev
|
||||||
|
- cmake
|
||||||
|
- cmake-data
|
||||||
before_install:
|
before_install:
|
||||||
- $CC --version
|
- $CC --version
|
||||||
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
|
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
|
||||||
- $CC --version
|
- $CC --version
|
||||||
- go version
|
- go version
|
||||||
|
- cmake --version
|
||||||
before_script:
|
before_script:
|
||||||
# First build spdylay, since integration tests require it.
|
# First build spdylay, since integration tests require it.
|
||||||
# spdylay is going to be built under third-party/spdylay
|
# spdylay is going to be built under third-party/spdylay
|
||||||
@@ -35,18 +44,22 @@ before_script:
|
|||||||
- git clone https://github.com/tatsuhiro-t/spdylay.git
|
- git clone https://github.com/tatsuhiro-t/spdylay.git
|
||||||
- cd spdylay
|
- cd spdylay
|
||||||
- autoreconf -i
|
- autoreconf -i
|
||||||
|
# Don't use ASAN for spdylay since failmalloc does not work with it.
|
||||||
- ./configure --disable-src --disable-examples
|
- ./configure --disable-src --disable-examples
|
||||||
- make check
|
- make check
|
||||||
- export SPDYLAY_HOME=$PWD
|
- export SPDYLAY_HOME=$PWD
|
||||||
- cd ../..
|
- cd ../..
|
||||||
# Now build nghttp2
|
# Now build nghttp2
|
||||||
- autoreconf -i
|
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
|
||||||
- git submodule update --init
|
- 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:
|
script:
|
||||||
- make
|
- if [ "$CI_BUILD" = "autotools" ]; then make distcheck; fi
|
||||||
- make check
|
- if [ "$CI_BUILD" = "cmake" ]; then make check; fi
|
||||||
- cd integration-tests
|
# As of April, 23, 2016, golang http2 build fails, probably because
|
||||||
- export GOPATH="$PWD/integration-tests/golang"
|
# the default go version is too old.
|
||||||
- make itprep-local
|
# - cd integration-tests
|
||||||
- make it-local
|
# - export GOPATH="$PWD/integration-tests/golang"
|
||||||
|
# - make itprep
|
||||||
|
# - make it
|
||||||
|
|||||||
92
AUTHORS
92
AUTHORS
@@ -1 +1,91 @@
|
|||||||
Tatsuhiro Tsujikawa <t-tujikawa at users dot sourceforge dot net>
|
nghttp2 project was started as a fork of spdylay project [1]. Both
|
||||||
|
projects were started by Tatsuhiro Tsujikawa, who is still the main
|
||||||
|
author of these projects. Meanwhile, we have many contributions, and
|
||||||
|
we are not here without them. We sincerely thank you to all who made
|
||||||
|
a contribution. Here is the all individuals/organizations who
|
||||||
|
contributed to nghttp2 and spdylay project at which we forked. These
|
||||||
|
names are retrieved from git commit log. If you have made a
|
||||||
|
contribution, but you are missing in the list, please let us know via
|
||||||
|
github issues [2].
|
||||||
|
|
||||||
|
[1] https://github.com/tatsuhiro-t/spdylay
|
||||||
|
[2] https://github.com/nghttp2/nghttp2/issues
|
||||||
|
|
||||||
|
--------
|
||||||
|
|
||||||
|
187j3x1
|
||||||
|
Alek Storm
|
||||||
|
Alex Nalivko
|
||||||
|
Alexis La Goutte
|
||||||
|
Anders Bakken
|
||||||
|
Andreas Pohl
|
||||||
|
Andy Davies
|
||||||
|
Ant Bryan
|
||||||
|
Benedikt Christoph Wolters
|
||||||
|
Bernard Spil
|
||||||
|
Brian Card
|
||||||
|
Brian Suh
|
||||||
|
Daniel Stenberg
|
||||||
|
Dave Reisner
|
||||||
|
David Beitey
|
||||||
|
David Weekly
|
||||||
|
Etienne Cimon
|
||||||
|
Fabian Möller
|
||||||
|
Fabian Wiesel
|
||||||
|
Gabi Davar
|
||||||
|
Google Inc.
|
||||||
|
Jacob Champion
|
||||||
|
Jan-E
|
||||||
|
Janusz Dziemidowicz
|
||||||
|
Jay Satiro
|
||||||
|
Jianqing Wang
|
||||||
|
Jim Morrison
|
||||||
|
José F. Calcerrada
|
||||||
|
Kamil Dudka
|
||||||
|
Kazuho Oku
|
||||||
|
Kenny (kang-yen) Peng
|
||||||
|
Kenny Peng
|
||||||
|
Kit Chan
|
||||||
|
Kyle Schomp
|
||||||
|
Lucas Pardue
|
||||||
|
MATSUMOTO Ryosuke
|
||||||
|
Matt Rudary
|
||||||
|
Mike Conlen
|
||||||
|
Mike Frysinger
|
||||||
|
Nicholas Hurley
|
||||||
|
Nora Shoemaker
|
||||||
|
Peeyush Aggarwal
|
||||||
|
Peter Wu
|
||||||
|
Piotr Sikora
|
||||||
|
Raul Gutierrez Segales
|
||||||
|
Remo E
|
||||||
|
Reza Tavakoli
|
||||||
|
Ross Smith II
|
||||||
|
Scott Mitchell
|
||||||
|
Stefan Eissing
|
||||||
|
Stephen Ludin
|
||||||
|
Sunpoet Po-Chuan Hsieh
|
||||||
|
Svante Signell
|
||||||
|
Syohei YOSHIDA
|
||||||
|
Tatsuhiko Kubo
|
||||||
|
Tatsuhiro Tsujikawa
|
||||||
|
Tom Harwood
|
||||||
|
Tomasz Buchert
|
||||||
|
Vernon Tang
|
||||||
|
Viacheslav Biriukov
|
||||||
|
Viktor Szépe
|
||||||
|
Wenfeng Liu
|
||||||
|
Xiaoguang Sun
|
||||||
|
Zhuoyun Wei
|
||||||
|
acesso
|
||||||
|
ayanamist
|
||||||
|
bxshi
|
||||||
|
dalf
|
||||||
|
es
|
||||||
|
fangdingjun
|
||||||
|
kumagi
|
||||||
|
makovich
|
||||||
|
mod-h2-dev
|
||||||
|
moparisthebest
|
||||||
|
snnn
|
||||||
|
yuuki-kodama
|
||||||
|
|||||||
526
CMakeLists.txt
Normal file
526
CMakeLists.txt
Normal file
@@ -0,0 +1,526 @@
|
|||||||
|
# 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.19.90)
|
||||||
|
|
||||||
|
# See versioning rule:
|
||||||
|
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
|
set(LT_CURRENT 26)
|
||||||
|
set(LT_REVISION 4)
|
||||||
|
set(LT_AGE 12)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
include(Version)
|
||||||
|
|
||||||
|
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
|
||||||
|
set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}")
|
||||||
|
set(PACKAGE_VERSION "${PROJECT_VERSION}")
|
||||||
|
HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH})
|
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||||
|
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE)
|
||||||
|
|
||||||
|
# Include "None" as option to disable any additional (optimization) flags,
|
||||||
|
# relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by
|
||||||
|
# default). These strings are presented in cmake-gui.
|
||||||
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||||
|
"None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
# For Python bindings and documentation
|
||||||
|
# (Must be called before PythonLibs for matching versions.)
|
||||||
|
find_package(PythonInterp)
|
||||||
|
|
||||||
|
# Auto-detection of features that can be toggled
|
||||||
|
find_package(OpenSSL 1.0.1)
|
||||||
|
find_package(Libev 4.11)
|
||||||
|
find_package(Libcares 1.7.5)
|
||||||
|
find_package(ZLIB 1.2.3)
|
||||||
|
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
|
||||||
|
set(ENABLE_APP_DEFAULT ON)
|
||||||
|
else()
|
||||||
|
set(ENABLE_APP_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
find_package(Jansson 2.5)
|
||||||
|
set(ENABLE_HPACK_TOOLS_DEFAULT ${JANSSON_FOUND})
|
||||||
|
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
||||||
|
find_package(Libevent 2.0.8 COMPONENTS libevent openssl)
|
||||||
|
set(ENABLE_EXAMPLES_DEFAULT ${LIBEVENT_OPENSSL_FOUND})
|
||||||
|
find_package(Cython)
|
||||||
|
find_package(PythonLibs)
|
||||||
|
if(CYTHON_FOUND AND PYTHONLIBS_FOUND)
|
||||||
|
set(ENABLE_PYTHON_BINDINGS_DEFAULT ON)
|
||||||
|
else()
|
||||||
|
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(LibXml2 2.7.7)
|
||||||
|
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
|
||||||
|
find_package(Jemalloc)
|
||||||
|
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
|
||||||
|
find_package(Spdylay 1.3.2)
|
||||||
|
set(WITH_SPDYLAY_DEFAULT ${SPDYLAY_FOUND})
|
||||||
|
|
||||||
|
include(CMakeOptions.txt)
|
||||||
|
|
||||||
|
if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_EXAMPLES OR
|
||||||
|
ENABLE_PYTHON_BINDINGS))
|
||||||
|
# Remember when disabled options are disabled for later diagnostics.
|
||||||
|
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1)
|
||||||
|
else()
|
||||||
|
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0)
|
||||||
|
endif()
|
||||||
|
if(ENABLE_LIB_ONLY)
|
||||||
|
set(ENABLE_APP OFF)
|
||||||
|
set(ENABLE_HPACK_TOOLS OFF)
|
||||||
|
set(ENABLE_EXAMPLES OFF)
|
||||||
|
set(ENABLE_PYTHON_BINDINGS OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Do not disable assertions based on CMAKE_BUILD_TYPE.
|
||||||
|
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
|
||||||
|
foreach(_lang C CXX)
|
||||||
|
string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
|
||||||
|
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" "" ${_var} "${${_var}}")
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#
|
||||||
|
# If we're running GCC or clang define _U_ to be "__attribute__((unused))"
|
||||||
|
# so we can use _U_ to flag unused function parameters and not get warnings
|
||||||
|
# about them. Otherwise, define _U_ to be an empty string so that _U_ used
|
||||||
|
# to flag an unused function parameters will compile with other compilers.
|
||||||
|
#
|
||||||
|
# XXX - similar hints for other compilers?
|
||||||
|
#
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
set(HINT_UNUSED_PARAM "__attribute__((unused))")
|
||||||
|
set(HINT_NORETURN "__attribute__((noreturn))")
|
||||||
|
else()
|
||||||
|
set(HINT_UNUSED_PARAM)
|
||||||
|
set(HINT_NORETURN)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(ExtractValidFlags)
|
||||||
|
foreach(_cxx1x_flag -std=c++11 -std=c++0x)
|
||||||
|
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
|
||||||
|
if(_cxx1x_flag_supported)
|
||||||
|
set(CXX1XCXXFLAGS ${_cxx1x_flag})
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
include(CMakePushCheckState)
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
cmake_push_check_state()
|
||||||
|
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
|
||||||
|
# Check that std::future is available.
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <vector>
|
||||||
|
#include <future>
|
||||||
|
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
|
||||||
|
# Check that std::map::emplace is available for g++-4.7.
|
||||||
|
check_cxx_source_compiles("
|
||||||
|
#include <map>
|
||||||
|
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
|
||||||
|
cmake_pop_check_state()
|
||||||
|
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
# Additional libraries required for programs under src directory.
|
||||||
|
set(APP_LIBRARIES)
|
||||||
|
|
||||||
|
if(ENABLE_PYTHON_BINDINGS)
|
||||||
|
if(NOT (CYTHON_FOUND AND PYTHONLIBS_FOUND))
|
||||||
|
message(FATAL_ERROR "python bindings were requested "
|
||||||
|
"(ENABLE_PYTHON_BINDINGS=1) but dependencies are not met.")
|
||||||
|
endif()
|
||||||
|
if(NOT PYTHON_VERSION_STRING STREQUAL PYTHONLIBS_VERSION_STRING)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Python executable and library must have the same version!"
|
||||||
|
" Found Python ${PYTHON_VERSION_STRING} and"
|
||||||
|
" PythonLibs ${PYTHONLIBS_VERSION_STRING}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_THREAD_PREFER_PTHREAD 1)
|
||||||
|
find_package(Threads)
|
||||||
|
if(CMAKE_USE_PTHREADS_INIT)
|
||||||
|
list(APPEND APP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
|
||||||
|
endif()
|
||||||
|
# XXX android and C++, is this still needed in cmake?
|
||||||
|
# case "$host" in
|
||||||
|
# *android*)
|
||||||
|
# android_build=yes
|
||||||
|
# # android does not need -pthread, but needs followng 3 libs for C++
|
||||||
|
# APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
|
||||||
|
|
||||||
|
# dl: openssl requires libdl when it is statically linked.
|
||||||
|
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
|
||||||
|
# APP_LIBRARIES if it is really specific to OpenSSL?
|
||||||
|
|
||||||
|
find_package(CUnit 2.1)
|
||||||
|
enable_testing()
|
||||||
|
set(HAVE_CUNIT ${CUNIT_FOUND})
|
||||||
|
if(HAVE_CUNIT)
|
||||||
|
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# openssl (for src)
|
||||||
|
set(HAVE_OPENSSL ${OPENSSL_FOUND})
|
||||||
|
if(OPENSSL_FOUND)
|
||||||
|
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
|
set(OPENSSL_INCLUDE_DIRS "")
|
||||||
|
set(OPENSSL_LIBRARIES "")
|
||||||
|
endif()
|
||||||
|
# libev (for src)
|
||||||
|
set(HAVE_LIBEV ${LIBEV_FOUND})
|
||||||
|
set(HAVE_ZLIB ${ZLIB_FOUND})
|
||||||
|
set(HAVE_LIBEVENT_OPENSSL ${LIBEVENT_FOUND})
|
||||||
|
if(LIBEVENT_FOUND)
|
||||||
|
# Must both link the core and openssl libraries.
|
||||||
|
set(LIBEVENT_OPENSSL_LIBRARIES ${LIBEVENT_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
# libc-ares (for src)
|
||||||
|
set(HAVE_LIBCARES ${LIBCARES_FOUND})
|
||||||
|
if(LIBCARES_FOUND)
|
||||||
|
set(LIBCARES_INCLUDE_DIRS ${LIBCARES_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
|
set(LIBCARES_INCLUDE_DIRS "")
|
||||||
|
set(LIBCARES_LIBRARIES "")
|
||||||
|
endif()
|
||||||
|
# jansson (for src/nghttp, src/deflatehd and src/inflatehd)
|
||||||
|
set(HAVE_JANSSON ${JANSSON_FOUND})
|
||||||
|
# libxml2 (for src/nghttp)
|
||||||
|
set(HAVE_LIBXML2 ${LIBXML2_FOUND})
|
||||||
|
if(LIBXML2_FOUND)
|
||||||
|
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
|
set(LIBXML2_INCLUDE_DIRS "")
|
||||||
|
set(LIBXML2_LIBRARIES "")
|
||||||
|
endif()
|
||||||
|
# jemalloc
|
||||||
|
set(HAVE_JEMALLOC ${JEMALLOC_FOUND})
|
||||||
|
# spdylay (for src/nghttpx and src/h2load)
|
||||||
|
set(HAVE_SPDYLAY ${SPDYLAY_FOUND})
|
||||||
|
|
||||||
|
if(ENABLE_ASIO_LIB)
|
||||||
|
find_package(Boost 1.54.0 REQUIRED system thread)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
|
||||||
|
if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
|
||||||
|
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# HPACK tools requires jansson
|
||||||
|
if(ENABLE_HPACK_TOOLS AND NOT HAVE_JANSSON)
|
||||||
|
message(FATAL_ERROR "HPACK tools were requested (ENABLE_HPACK_TOOLS=1) but dependencies are not met.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# C++ library libnghttp2_asio
|
||||||
|
if(ENABLE_EXAMPLES AND NOT (OPENSSL_FOUND AND LIBEVENT_OPENSSL_FOUND))
|
||||||
|
message(FATAL_ERROR "examples were requested (ENABLE_EXAMPLES=1) but dependencies are not met.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# third-party http-parser only be built when needed
|
||||||
|
if(ENABLE_EXAMPLES OR ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_ASIO_LIB)
|
||||||
|
set(ENABLE_THIRD_PARTY 1)
|
||||||
|
# mruby (for src/nghttpx)
|
||||||
|
set(HAVE_MRUBY ${WITH_MRUBY})
|
||||||
|
set(HAVE_NEVERBLEED ${WITH_NEVERBLEED})
|
||||||
|
else()
|
||||||
|
set(HAVE_MRUBY 0)
|
||||||
|
set(HAVE_NEVERBLEED 0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
|
||||||
|
check_include_file("fcntl.h" HAVE_FCNTL_H)
|
||||||
|
check_include_file("inttypes.h" HAVE_INTTYPES_H)
|
||||||
|
check_include_file("limits.h" HAVE_LIMITS_H)
|
||||||
|
check_include_file("netdb.h" HAVE_NETDB_H)
|
||||||
|
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
|
||||||
|
check_include_file("pwd.h" HAVE_PWD_H)
|
||||||
|
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
|
||||||
|
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
|
||||||
|
check_include_file("syslog.h" HAVE_SYSLOG_H)
|
||||||
|
check_include_file("time.h" HAVE_TIME_H)
|
||||||
|
check_include_file("unistd.h" HAVE_UNISTD_H)
|
||||||
|
|
||||||
|
include(CheckTypeSize)
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
# AC_TYPE_SIZE_T
|
||||||
|
check_type_size("ssize_t" SIZEOF_SSIZE_T)
|
||||||
|
if(SIZEOF_SSIZE_T STREQUAL "")
|
||||||
|
# ssize_t is a signed type in POSIX storing at least -1.
|
||||||
|
# Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools).
|
||||||
|
set(ssize_t int)
|
||||||
|
endif()
|
||||||
|
# AC_TYPE_UINT8_T
|
||||||
|
# AC_TYPE_UINT16_T
|
||||||
|
# AC_TYPE_UINT32_T
|
||||||
|
# AC_TYPE_UINT64_T
|
||||||
|
# AC_TYPE_INT8_T
|
||||||
|
# AC_TYPE_INT16_T
|
||||||
|
# AC_TYPE_INT32_T
|
||||||
|
# AC_TYPE_INT64_T
|
||||||
|
# AC_TYPE_OFF_T
|
||||||
|
# AC_TYPE_PID_T
|
||||||
|
# AC_TYPE_UID_T
|
||||||
|
# XXX To support inline for crappy compilers, see https://cmake.org/Wiki/CMakeTestInline
|
||||||
|
# AC_C_INLINE
|
||||||
|
# XXX is AC_SYS_LARGEFILE still needed for modern systems?
|
||||||
|
# add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||||
|
|
||||||
|
include(CheckStructHasMember)
|
||||||
|
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
|
||||||
|
|
||||||
|
# Check size of pointer to decide we need 8 bytes alignment adjustment.
|
||||||
|
check_type_size("int *" SIZEOF_INT_P)
|
||||||
|
check_type_size("time_t" SIZEOF_TIME_T)
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
include(CheckFunctionExists)
|
||||||
|
check_function_exists(_Exit HAVE__EXIT)
|
||||||
|
check_function_exists(accept4 HAVE_ACCEPT4)
|
||||||
|
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
# XXX does this correctly detect initgroups (un)availability on cygwin?
|
||||||
|
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
|
||||||
|
if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
|
||||||
|
# FreeBSD declares initgroups() in unistd.h
|
||||||
|
check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2)
|
||||||
|
if(HAVE_DECL_INITGROUPS2)
|
||||||
|
set(HAVE_DECL_INITGROUPS 1)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(WARNCFLAGS)
|
||||||
|
set(WARNCXXFLAGS)
|
||||||
|
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||||
|
if(ENABLE_WERROR)
|
||||||
|
set(WARNCFLAGS /WX)
|
||||||
|
set(WARNCXXFLAGS /WX)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
if(ENABLE_WERROR)
|
||||||
|
extract_valid_c_flags(WARNCFLAGS -Werror)
|
||||||
|
extract_valid_c_flags(WARNCXXFLAGS -Werror)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# For C compiler
|
||||||
|
extract_valid_c_flags(WARNCFLAGS
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wmissing-prototypes
|
||||||
|
-Wstrict-prototypes
|
||||||
|
-Wmissing-declarations
|
||||||
|
-Wpointer-arith
|
||||||
|
-Wdeclaration-after-statement
|
||||||
|
-Wformat-security
|
||||||
|
-Wwrite-strings
|
||||||
|
-Wshadow
|
||||||
|
-Winline
|
||||||
|
-Wnested-externs
|
||||||
|
-Wfloat-equal
|
||||||
|
-Wundef
|
||||||
|
-Wendif-labels
|
||||||
|
-Wempty-body
|
||||||
|
-Wcast-align
|
||||||
|
-Wclobbered
|
||||||
|
-Wvla
|
||||||
|
-Wpragmas
|
||||||
|
-Wunreachable-code
|
||||||
|
-Waddress
|
||||||
|
-Wattributes
|
||||||
|
-Wdiv-by-zero
|
||||||
|
-Wshorten-64-to-32
|
||||||
|
|
||||||
|
-Wconversion
|
||||||
|
-Wextended-offsetof
|
||||||
|
-Wformat-nonliteral
|
||||||
|
-Wlanguage-extension-token
|
||||||
|
-Wmissing-field-initializers
|
||||||
|
-Wmissing-noreturn
|
||||||
|
-Wmissing-variable-declarations
|
||||||
|
# Not used because we cannot change public structs
|
||||||
|
# -Wpadded
|
||||||
|
-Wsign-conversion
|
||||||
|
# Not used because this basically disallows default case
|
||||||
|
# -Wswitch-enum
|
||||||
|
-Wunreachable-code-break
|
||||||
|
-Wunused-macros
|
||||||
|
-Wunused-parameter
|
||||||
|
-Wredundant-decls
|
||||||
|
# Only work with Clang for the moment
|
||||||
|
-Wheader-guard
|
||||||
|
# This is required because we pass format string as "const char*.
|
||||||
|
-Wno-format-nonliteral
|
||||||
|
)
|
||||||
|
|
||||||
|
extract_valid_cxx_flags(WARNCXXFLAGS
|
||||||
|
# For C++ compiler
|
||||||
|
-Wall
|
||||||
|
-Wformat-security
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_DEBUG)
|
||||||
|
set(DEBUGBUILD 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Some platform does not have working std::future. We disable
|
||||||
|
# threading for those platforms.
|
||||||
|
if(NOT ENABLE_THREADS OR NOT HAVE_STD_FUTURE)
|
||||||
|
set(NOTHREADS 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-DHAVE_CONFIG_H)
|
||||||
|
configure_file(cmakeconfig.h.in config.h)
|
||||||
|
# autotools-compatible names
|
||||||
|
# Sphinx expects relative paths in the .rst files. Use the fact that the files
|
||||||
|
# below are all one directory level deep.
|
||||||
|
file(RELATIVE_PATH top_srcdir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
# libnghttp2.pc (pkg-config file)
|
||||||
|
set(prefix "${CMAKE_INSTALL_PREFIX}")
|
||||||
|
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
|
||||||
|
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
|
||||||
|
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
|
||||||
|
set(VERSION "${PACKAGE_VERSION}")
|
||||||
|
# For init scripts and systemd service file (in contrib/)
|
||||||
|
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
|
||||||
|
set(sbindir "${CMAKE_INSTALL_FULL_SBINDIR}")
|
||||||
|
foreach(name
|
||||||
|
lib/libnghttp2.pc
|
||||||
|
lib/includes/nghttp2/nghttp2ver.h
|
||||||
|
src/libnghttp2_asio.pc
|
||||||
|
python/setup.py
|
||||||
|
integration-tests/config.go
|
||||||
|
integration-tests/setenv
|
||||||
|
doc/conf.py
|
||||||
|
doc/index.rst
|
||||||
|
doc/package_README.rst
|
||||||
|
doc/tutorial-client.rst
|
||||||
|
doc/tutorial-server.rst
|
||||||
|
doc/tutorial-hpack.rst
|
||||||
|
doc/nghttpx-howto.rst
|
||||||
|
doc/h2load-howto.rst
|
||||||
|
doc/libnghttp2_asio.rst
|
||||||
|
doc/python-apiref.rst
|
||||||
|
doc/building-android-binary.rst
|
||||||
|
doc/nghttp2.h.rst
|
||||||
|
doc/nghttp2ver.h.rst
|
||||||
|
doc/asio_http2.h.rst
|
||||||
|
doc/asio_http2_server.h.rst
|
||||||
|
doc/asio_http2_client.h.rst
|
||||||
|
doc/contribute.rst
|
||||||
|
)
|
||||||
|
configure_file("${name}.in" "${name}" @ONLY)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
|
||||||
|
)
|
||||||
|
# For use in src/CMakeLists.txt
|
||||||
|
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
|
||||||
|
|
||||||
|
install(FILES README.rst DESTINATION "${CMAKE_INSTALL_DOCDIR}")
|
||||||
|
|
||||||
|
add_subdirectory(lib)
|
||||||
|
#add_subdirectory(lib/includes)
|
||||||
|
add_subdirectory(third-party)
|
||||||
|
add_subdirectory(src)
|
||||||
|
#add_subdirectory(src/includes)
|
||||||
|
add_subdirectory(examples)
|
||||||
|
add_subdirectory(python)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
#add_subdirectory(tests/testdata)
|
||||||
|
add_subdirectory(integration-tests)
|
||||||
|
add_subdirectory(doc)
|
||||||
|
add_subdirectory(contrib)
|
||||||
|
add_subdirectory(script)
|
||||||
|
|
||||||
|
|
||||||
|
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
|
||||||
|
message(STATUS "summary of build options:
|
||||||
|
|
||||||
|
Package version: ${VERSION}
|
||||||
|
Library version: ${LT_CURRENT}:${LT_REVISION}:${LT_AGE}
|
||||||
|
Install prefix: ${CMAKE_INSTALL_PREFIX}
|
||||||
|
Target system: ${CMAKE_SYSTEM_NAME}
|
||||||
|
Compiler:
|
||||||
|
Build type: ${CMAKE_BUILD_TYPE}
|
||||||
|
C compiler: ${CMAKE_C_COMPILER}
|
||||||
|
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
|
||||||
|
C++ compiler: ${CMAKE_CXX_COMPILER}
|
||||||
|
CXXFLAGS: ${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
|
||||||
|
WARNCFLAGS: ${WARNCFLAGS}
|
||||||
|
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||||
|
Python:
|
||||||
|
Python: ${PYTHON_EXECUTABLE}
|
||||||
|
PYTHON_VERSION: ${PYTHON_VERSION_STRING}
|
||||||
|
Library version:${PYTHONLIBS_VERSION_STRING}
|
||||||
|
Cython: ${CYTHON_EXECUTABLE}
|
||||||
|
Test:
|
||||||
|
CUnit: ${HAVE_CUNIT} (LIBS='${CUNIT_LIBRARIES}')
|
||||||
|
Failmalloc: ${ENABLE_FAILMALLOC}
|
||||||
|
Libs:
|
||||||
|
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
|
||||||
|
Libxml2: ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
|
||||||
|
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
|
||||||
|
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
|
||||||
|
Libevent(SSL): ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
|
||||||
|
Spdylay: ${HAVE_SPDYLAY} (LIBS='${SPDYLAY_LIBRARIES}')
|
||||||
|
Jansson: ${HAVE_JANSSON} (LIBS='${JANSSON_LIBRARIES}')
|
||||||
|
Jemalloc: ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
|
||||||
|
Zlib: ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
|
||||||
|
Boost::System: ${Boost_SYSTEM_LIBRARY}
|
||||||
|
Boost::Thread: ${Boost_THREAD_LIBRARY}
|
||||||
|
Third-party:
|
||||||
|
http-parser: ${ENABLE_THIRD_PARTY}
|
||||||
|
MRuby: ${HAVE_MRUBY}
|
||||||
|
Neverbleed: ${HAVE_NEVERBLEED}
|
||||||
|
Features:
|
||||||
|
Applications: ${ENABLE_APP}
|
||||||
|
HPACK tools: ${ENABLE_HPACK_TOOLS}
|
||||||
|
Libnghttp2_asio:${ENABLE_ASIO_LIB}
|
||||||
|
Examples: ${ENABLE_EXAMPLES}
|
||||||
|
Python bindings:${ENABLE_PYTHON_BINDINGS}
|
||||||
|
Threading: ${ENABLE_THREADS}
|
||||||
|
")
|
||||||
|
if(ENABLE_LIB_ONLY_DISABLED_OTHERS)
|
||||||
|
message("Only the library will be built. To build other components "
|
||||||
|
"(such as applications and examples), set ENABLE_LIB_ONLY=OFF.")
|
||||||
|
endif()
|
||||||
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:
|
||||||
1
COPYING
1
COPYING
@@ -1,6 +1,7 @@
|
|||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
|
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
|
||||||
|
Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ RUN HOST=arm-linux-androideabi \
|
|||||||
make install
|
make install
|
||||||
|
|
||||||
WORKDIR /root/build
|
WORKDIR /root/build
|
||||||
RUN git clone https://github.com/tatsuhiro-t/nghttp2
|
RUN git clone https://github.com/nghttp2/nghttp2
|
||||||
WORKDIR /root/build/nghttp2
|
WORKDIR /root/build/nghttp2
|
||||||
RUN autoreconf -i && \
|
RUN autoreconf -i && \
|
||||||
./configure \
|
./configure \
|
||||||
|
|||||||
15
Makefile.am
15
Makefile.am
@@ -33,7 +33,20 @@ ACLOCAL_AMFLAGS = -I m4
|
|||||||
dist_doc_DATA = README.rst
|
dist_doc_DATA = README.rst
|
||||||
|
|
||||||
EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
|
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 \
|
||||||
|
cmake/FindLibcares.cmake
|
||||||
|
|
||||||
.PHONY: clang-format
|
.PHONY: clang-format
|
||||||
|
|
||||||
|
|||||||
228
README.rst
228
README.rst
@@ -58,13 +58,19 @@ To build the documentation, you need to install:
|
|||||||
|
|
||||||
* sphinx (http://sphinx-doc.org/)
|
* sphinx (http://sphinx-doc.org/)
|
||||||
|
|
||||||
To build and run the application programs (``nghttp``, ``nghttpd`` and
|
If you need libnghttp2 (C library) only, then the above packages are
|
||||||
``nghttpx``) in the ``src`` directory, the following packages are
|
all you need. Use ``--enable-lib-only`` to ensure that only
|
||||||
required:
|
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
|
* OpenSSL >= 1.0.1
|
||||||
* libev >= 4.15
|
* libev >= 4.11
|
||||||
* zlib >= 1.2.3
|
* zlib >= 1.2.3
|
||||||
|
* libc-ares >= 1.7.5
|
||||||
|
|
||||||
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
|
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
|
||||||
LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more
|
LibreSSL >= 2.2.0 can be used instead of OpenSSL, but OpenSSL has more
|
||||||
@@ -93,6 +99,11 @@ To mitigate heap fragmentation in long running server programs
|
|||||||
|
|
||||||
* jemalloc
|
* jemalloc
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Alpine Linux currently does not support malloc replacement
|
||||||
|
due to musl limitations. See details in issue `#762 <https://github.com/nghttp2/nghttp2/issues/762>`_.
|
||||||
|
|
||||||
libnghttp2_asio C++ library requires the following packages:
|
libnghttp2_asio C++ library requires the following packages:
|
||||||
|
|
||||||
* libboost-dev >= 1.54.0
|
* libboost-dev >= 1.54.0
|
||||||
@@ -104,14 +115,17 @@ The Python bindings require the following packages:
|
|||||||
* python >= 2.7
|
* python >= 2.7
|
||||||
* python-setuptools
|
* 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 \
|
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 \
|
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
|
||||||
libjemalloc-dev cython python3-dev python-setuptools
|
libc-ares-dev libjemalloc-dev cython python3-dev python-setuptools
|
||||||
|
|
||||||
spdylay is not packaged in Ubuntu, so you need to build it yourself:
|
From Ubuntu 15.10, spdylay has been available as a package named
|
||||||
http://tatsuhiro-t.github.io/spdylay/
|
`libspdylay-dev`. For the earlier Ubuntu release, you need to build
|
||||||
|
it yourself: http://tatsuhiro-t.github.io/spdylay/
|
||||||
|
|
||||||
To enable mruby support for nghttpx, `mruby
|
To enable mruby support for nghttpx, `mruby
|
||||||
<https://github.com/mruby/mruby>`_ is required. We need to build
|
<https://github.com/mruby/mruby>`_ is required. We need to build
|
||||||
@@ -137,8 +151,11 @@ Building from git
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
Building from git is easy, but please be sure that at least autoconf 2.68 is
|
Building from git is easy, but please be sure that at least autoconf 2.68 is
|
||||||
used::
|
used:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
$ git submodule update --init
|
||||||
$ autoreconf -i
|
$ autoreconf -i
|
||||||
$ automake
|
$ automake
|
||||||
$ autoconf
|
$ autoconf
|
||||||
@@ -149,8 +166,7 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
To enable mruby support in nghttpx, run ``git submodule update
|
To enable mruby support in nghttpx, and use ``--with-mruby``
|
||||||
--init`` before running configure script, and use ``--with-mruby``
|
|
||||||
configure option.
|
configure option.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@@ -160,6 +176,34 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
|
|||||||
them from crashing. A patch is welcome to make multi threading work
|
them from crashing. A patch is welcome to make multi threading work
|
||||||
on Mac OS X platform.
|
on Mac OS X platform.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
To compile the associated applications (nghttp, nghttpd, nghttpx
|
||||||
|
and h2load), you must use the ``--enable-app`` configure option and
|
||||||
|
ensure that the specified requirements above are met. Normally,
|
||||||
|
configure script checks required dependencies to build these
|
||||||
|
applications, and enable ``--enable-app`` automatically, so you
|
||||||
|
don't have to use it explicitly. But if you found that
|
||||||
|
applications were not built, then using ``--enable-app`` may find
|
||||||
|
that cause, such as the missing dependency.
|
||||||
|
|
||||||
|
Notes for building on Windows (MSVC)
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
The easiest way to build native Windows nghttp2 dll is use `cmake
|
||||||
|
<https://cmake.org/>`_. The free version of `Visual C++ Build Tools
|
||||||
|
<http://landinghub.visualstudio.com/visual-cpp-build-tools>`_ works
|
||||||
|
fine.
|
||||||
|
|
||||||
|
1. Install cmake for windows
|
||||||
|
2. Open "Visual C++ ... Native Build Tool Command Prompt", and inside
|
||||||
|
nghttp2 directly, run ``cmake``.
|
||||||
|
3. Then run ``cmake --build`` to build library.
|
||||||
|
4. nghttp2.dll, nghttp2.lib, nghttp2.exp are placed under lib directory.
|
||||||
|
|
||||||
|
Note that the above steps most likely produce nghttp2 library only.
|
||||||
|
No bundled applications are compiled.
|
||||||
|
|
||||||
Notes for building on Windows (Mingw/Cygwin)
|
Notes for building on Windows (Mingw/Cygwin)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
@@ -176,7 +220,9 @@ Secondly, you need to undefine the macro ``__STRICT_ANSI__``, if you
|
|||||||
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
|
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
|
||||||
available.
|
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 CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
|
||||||
$ export CXXFLAGS=$CFLAGS
|
$ export CXXFLAGS=$CFLAGS
|
||||||
@@ -194,7 +240,9 @@ Building the documentation
|
|||||||
|
|
||||||
Documentation is still incomplete.
|
Documentation is still incomplete.
|
||||||
|
|
||||||
To build the documentation, run::
|
To build the documentation, run:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ make html
|
$ make html
|
||||||
|
|
||||||
@@ -223,12 +271,16 @@ its testing framework. We depend on the following libraries:
|
|||||||
* https://github.com/tatsuhiro-t/spdy
|
* https://github.com/tatsuhiro-t/spdy
|
||||||
|
|
||||||
To download the above packages, after settings ``GOPATH``, run the
|
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
|
$ make itprep
|
||||||
|
|
||||||
To run the tests, run the following command under
|
To run the tests, run the following command under
|
||||||
``integration-tests`` directory::
|
``integration-tests`` directory:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ make it
|
$ make it
|
||||||
|
|
||||||
@@ -349,7 +401,9 @@ nghttp - client
|
|||||||
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
|
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
|
||||||
|
|
||||||
It has verbose output mode for framing information. Here is sample
|
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
|
$ nghttp -nv https://nghttp2.org
|
||||||
[ 0.190] Connected
|
[ 0.190] Connected
|
||||||
@@ -432,7 +486,9 @@ output from ``nghttp`` client::
|
|||||||
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
|
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
|
||||||
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(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
|
$ nghttp -nvu http://nghttp2.org
|
||||||
[ 0.011] Connected
|
[ 0.011] Connected
|
||||||
@@ -528,7 +584,9 @@ The HTTP Upgrade is performed like so::
|
|||||||
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
|
||||||
|
|
||||||
Using the ``-s`` option, ``nghttp`` prints out some timing information for
|
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/
|
$ nghttp -nas https://nghttp2.org/
|
||||||
***** Statistics *****
|
***** Statistics *****
|
||||||
@@ -572,7 +630,9 @@ HTTP/2 connections. No HTTP Upgrade is supported.
|
|||||||
The ``-p`` option allows users to configure server push.
|
The ``-p`` option allows users to configure server push.
|
||||||
|
|
||||||
Just like ``nghttp``, it has a verbose output mode for framing
|
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
|
$ nghttpd --no-tls -v 8080
|
||||||
IPv4: listen 0.0.0.0:8080
|
IPv4: listen 0.0.0.0:8080
|
||||||
@@ -635,6 +695,14 @@ nghttpx - proxy
|
|||||||
HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
|
HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
|
||||||
push.
|
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
|
``nghttpx`` implements `important performance-oriented features
|
||||||
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
|
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
|
||||||
session IDs, session tickets (with automatic key rotation), OCSP
|
session IDs, session tickets (with automatic key rotation), OCSP
|
||||||
@@ -643,46 +711,42 @@ HTTP/2. ``nghttpx`` also offers the functionality to share session
|
|||||||
cache and ticket keys among multiple ``nghttpx`` instances via
|
cache and ticket keys among multiple ``nghttpx`` instances via
|
||||||
memcached.
|
memcached.
|
||||||
|
|
||||||
``nghttpx`` has several operational modes:
|
``nghttpx`` has 2 operation modes:
|
||||||
|
|
||||||
================== ============================ ============== =============
|
================== ====================== ================ =============
|
||||||
Mode option Frontend Backend Note
|
Mode option Frontend Backend Note
|
||||||
================== ============================ ============== =============
|
================== ====================== ================ =============
|
||||||
default mode HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 Reverse proxy
|
default mode HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
|
||||||
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 SPDY proxy
|
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
|
||||||
``--http2-bridge`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/2 (TLS)
|
================== ====================== ================ =============
|
||||||
``--client`` HTTP/2, HTTP/1.1 HTTP/2 (TLS)
|
|
||||||
``--client-proxy`` HTTP/2, HTTP/1.1 HTTP/2 (TLS) Forward proxy
|
|
||||||
================== ============================ ============== =============
|
|
||||||
|
|
||||||
The interesting mode at the moment is the default mode. It works like
|
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
|
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.
|
deployed as a SSL/TLS terminator for existing web server.
|
||||||
|
|
||||||
The default mode, ``--http2-proxy`` and ``--http2-bridge`` modes use
|
In all modes, the frontend connections are encrypted by SSL/TLS by
|
||||||
SSL/TLS in the frontend connection by default. To disable SSL/TLS,
|
default. To disable encryption, use the ``no-tls`` keyword in
|
||||||
use the ``--frontend-no-tls`` option. If that option is used, SPDY is
|
``--frontend`` option. If encryption is disabled, SPDY is disabled in
|
||||||
disabled in the frontend and incoming HTTP/1.1 connections can be
|
the frontend and incoming HTTP/1.1 connections can be upgraded to
|
||||||
upgraded to HTTP/2 through HTTP Upgrade. In these modes, HTTP/1
|
HTTP/2 through HTTP Upgrade. On the other hard, backend connections
|
||||||
backend connections are cleartext by default. To enable TLS, use
|
are not encrypted by default. To encrypt backend connections, use
|
||||||
``--backend-http1-tls`` opiton.
|
``tls`` keyword in ``--backend`` option.
|
||||||
|
|
||||||
The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use
|
|
||||||
SSL/TLS in the backend connection by default. To disable SSL/TLS, use
|
|
||||||
the ``--backend-no-tls`` option.
|
|
||||||
|
|
||||||
``nghttpx`` supports a configuration file. See the ``--conf`` option and
|
``nghttpx`` supports a configuration file. See the ``--conf`` option and
|
||||||
sample configuration file ``nghttpx.conf.sample``.
|
sample configuration file ``nghttpx.conf.sample``.
|
||||||
|
|
||||||
In the default mode, (without any of ``--http2-proxy``,
|
In the default mode, ``nghttpx`` works as reverse proxy to the backend
|
||||||
``--http2-bridge``, ``--client-proxy`` and ``--client`` options),
|
server:
|
||||||
``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]
|
[reverse proxy]
|
||||||
|
|
||||||
With the ``--http2-proxy`` option, it works as a so called secure proxy (aka
|
With the ``--http2-proxy`` option, it works as forward proxy, and it
|
||||||
SPDY proxy)::
|
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
|
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
|
||||||
[secure proxy] (e.g., Squid, ATS)
|
[secure proxy] (e.g., Squid, ATS)
|
||||||
@@ -690,9 +754,9 @@ SPDY proxy)::
|
|||||||
The ``Client`` in the above example needs to be configured to use
|
The ``Client`` in the above example needs to be configured to use
|
||||||
``nghttpx`` as secure proxy.
|
``nghttpx`` as secure proxy.
|
||||||
|
|
||||||
At the time of this writing, Chrome is the only browser which supports
|
At the time of this writing, both Chrome and Firefox support secure
|
||||||
secure proxy. One way to configure Chrome to use a secure proxy is
|
HTTP/2 proxy. One way to configure Chrome to use a secure proxy is to
|
||||||
to create a proxy.pac script like this:
|
create a proxy.pac script like this:
|
||||||
|
|
||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
@@ -704,42 +768,18 @@ to create a proxy.pac script like this:
|
|||||||
machine nghttpx is running on. Please note that Chrome requires a valid
|
machine nghttpx is running on. Please note that Chrome requires a valid
|
||||||
certificate for secure proxy.
|
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
|
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||||
|
|
||||||
With ``--http2-bridge``, it accepts HTTP/2, SPDY and HTTP/1.1
|
The backend HTTP/2 connections can be tunneled through an HTTP proxy.
|
||||||
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 proxy is specified using ``--backend-http-proxy-uri``. The
|
The proxy is specified using ``--backend-http-proxy-uri``. The
|
||||||
following figure illustrates the example of the ``--http2-bridge`` and
|
following figure illustrates how nghttpx talks to the outside HTTP/2
|
||||||
``--backend-http-proxy-uri`` options to talk to the outside HTTP/2
|
proxy through an HTTP proxy:
|
||||||
proxy through an HTTP proxy::
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
|
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
|
||||||
|
|
||||||
@@ -753,7 +793,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
|
The SPDY support is enabled if the program was built with the spdylay
|
||||||
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
|
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
|
||||||
(https://github.com/lighttpd/weighttp). The typical usage is as
|
(https://github.com/lighttpd/weighttp). The typical usage is as
|
||||||
follows::
|
follows:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ h2load -n100000 -c100 -m100 https://localhost:8443/
|
$ h2load -n100000 -c100 -m100 https://localhost:8443/
|
||||||
starting benchmark...
|
starting benchmark...
|
||||||
@@ -841,7 +883,9 @@ Example:
|
|||||||
With the ``-t`` option, the program can accept more familiar HTTP/1 style
|
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:
|
header field blocks. Each header set is delimited by an empty line:
|
||||||
|
|
||||||
Example::
|
Example:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
:method: GET
|
:method: GET
|
||||||
:scheme: https
|
:scheme: https
|
||||||
@@ -1337,7 +1381,7 @@ The extension module is called ``nghttp2``.
|
|||||||
determined by the ``configure`` script. If the detected Python version is not
|
determined by the ``configure`` script. If the detected Python version is not
|
||||||
what you expect, specify a path to Python executable in a ``PYTHON``
|
what you expect, specify a path to Python executable in a ``PYTHON``
|
||||||
variable as an argument to configure script (e.g., ``./configure
|
variable as an argument to configure script (e.g., ``./configure
|
||||||
PYTHON=/usr/bin/python3.4``).
|
PYTHON=/usr/bin/python3.5``).
|
||||||
|
|
||||||
The following example code illustrates basic usage of the HPACK compressor
|
The following example code illustrates basic usage of the HPACK compressor
|
||||||
and decompressor in Python:
|
and decompressor in Python:
|
||||||
@@ -1467,6 +1511,17 @@ See `Contribution Guidelines
|
|||||||
<https://nghttp2.org/documentation/contribute.html>`_ for more
|
<https://nghttp2.org/documentation/contribute.html>`_ for more
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
Reporting vulnerability
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
If you find a vulnerability in our software, please send the email to
|
||||||
|
"tatsuhiro.t at gmail dot com" about its details instead of submitting
|
||||||
|
issues on github issue page. It is a standard practice not to
|
||||||
|
disclose vulnerability information publicly until a fixed version is
|
||||||
|
released, or mitigation is worked out.
|
||||||
|
|
||||||
|
In the future, we may setup a dedicated mail address for this purpose.
|
||||||
|
|
||||||
Release schedule
|
Release schedule
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
@@ -1479,3 +1534,8 @@ severe security bug fixes.
|
|||||||
|
|
||||||
We have no plan to break API compatibility changes involving soname
|
We have no plan to break API compatibility changes involving soname
|
||||||
bump, so MAJOR version will stay 1 for the foreseeable future.
|
bump, so MAJOR version will stay 1 for the foreseeable future.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
|
||||||
|
The MIT License
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ PATH="$TOOLCHAIN"/bin:"$PATH"
|
|||||||
--without-libxml2 \
|
--without-libxml2 \
|
||||||
--disable-python-bindings \
|
--disable-python-bindings \
|
||||||
--disable-examples \
|
--disable-examples \
|
||||||
--enable-werror \
|
--disable-threads \
|
||||||
CC="$TOOLCHAIN"/bin/clang \
|
CC="$TOOLCHAIN"/bin/arm-linux-androideabi-clang \
|
||||||
CXX="$TOOLCHAIN"/bin/clang++ \
|
CXX="$TOOLCHAIN"/bin/arm-linux-androideabi-clang++ \
|
||||||
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
CPPFLAGS="-fPIE -I$PREFIX/include" \
|
||||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||||
LDFLAGS="-fPIE -pie -L$PREFIX/lib"
|
LDFLAGS="-fPIE -pie -L$PREFIX/lib"
|
||||||
|
|||||||
53
appveyor.yml
Normal file
53
appveyor.yml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Notes:
|
||||||
|
# - Minimal appveyor.yml file is an empty file. All sections are optional.
|
||||||
|
# - Indent each level of configuration with 2 spaces. Do not use tabs!
|
||||||
|
# - All section names are case-sensitive.
|
||||||
|
# - Section names should be unique on each level.
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# general configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
# version format
|
||||||
|
#version: 0.10.{build}
|
||||||
|
|
||||||
|
# branches to build
|
||||||
|
branches:
|
||||||
|
# blacklist
|
||||||
|
except:
|
||||||
|
- gh-pages
|
||||||
|
|
||||||
|
# Do not build on tags (GitHub only)
|
||||||
|
skip_tags: true
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# environment configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
os: Windows Server 2012
|
||||||
|
|
||||||
|
# scripts that run after cloning repository
|
||||||
|
install:
|
||||||
|
# install Win-Flex-Bison
|
||||||
|
#- cmd: cinst winflexbison -y
|
||||||
|
|
||||||
|
#---------------------------------#
|
||||||
|
# build configuration #
|
||||||
|
#---------------------------------#
|
||||||
|
|
||||||
|
# scripts to run before build
|
||||||
|
before_build:
|
||||||
|
- cmd: cmake .
|
||||||
|
|
||||||
|
# scripts to run *after* solution is built and *before* automatic packaging occurs (web apps, NuGet packages, Azure Cloud Services)
|
||||||
|
# before_package:
|
||||||
|
|
||||||
|
# scripts to run after build
|
||||||
|
# after_build:
|
||||||
|
|
||||||
|
# to run your custom scripts instead of automatic MSBuild
|
||||||
|
build_script:
|
||||||
|
- cmd: cmake --build .
|
||||||
|
|
||||||
|
# to disable automatic builds
|
||||||
|
# build: off
|
||||||
52
author.py
Executable file
52
author.py
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# script to extract commit author's name from standard input. The
|
||||||
|
# input should be <AUTHOR>:<EMAIL>, one per line.
|
||||||
|
# This script expects the input is created by git-log command:
|
||||||
|
#
|
||||||
|
# git log --format=%aN:%aE
|
||||||
|
#
|
||||||
|
# This script removes duplicates based on email address, breaking a
|
||||||
|
# tie with longer author name. Among the all author names extract the
|
||||||
|
# previous step, we remove duplicate by case-insensitive match.
|
||||||
|
#
|
||||||
|
# So we can do this in one line:
|
||||||
|
#
|
||||||
|
# git log --format=%aN:%aE | sort | uniq | ./author.py > authors
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
edict = {}
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
author, email = line.strip().split(':', 1)
|
||||||
|
if email in edict:
|
||||||
|
an = edict[email]
|
||||||
|
if len(an) < len(author) or an > author:
|
||||||
|
sys.stderr.write(
|
||||||
|
'eliminated {} in favor of {}\n'.format(an, author))
|
||||||
|
edict[email] = author
|
||||||
|
else:
|
||||||
|
sys.stderr.write(
|
||||||
|
'eliminated {} in favor of {}\n'.format(author, an))
|
||||||
|
else:
|
||||||
|
edict[email] = author
|
||||||
|
|
||||||
|
names = list(sorted(edict.values()))
|
||||||
|
|
||||||
|
ndict = {}
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
lowname = name.lower()
|
||||||
|
if lowname in ndict:
|
||||||
|
an = ndict[lowname]
|
||||||
|
if an > name:
|
||||||
|
sys.stderr.write('eliminated {} in favor of {}\n'.format(an, name))
|
||||||
|
ndict[lowname] = name
|
||||||
|
else:
|
||||||
|
sys.stderr.write('eliminated {} in favor of {}\n'.format(name, an))
|
||||||
|
else:
|
||||||
|
ndict[lowname] = name
|
||||||
|
|
||||||
|
for name in sorted(ndict.values()):
|
||||||
|
print name
|
||||||
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)
|
||||||
40
cmake/FindLibcares.cmake
Normal file
40
cmake/FindLibcares.cmake
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# - Try to find libcares
|
||||||
|
# Once done this will define
|
||||||
|
# LIBCARES_FOUND - System has libcares
|
||||||
|
# LIBCARES_INCLUDE_DIRS - The libcares include directories
|
||||||
|
# LIBCARES_LIBRARIES - The libraries needed to use libcares
|
||||||
|
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
pkg_check_modules(PC_LIBCARES QUIET libcares)
|
||||||
|
|
||||||
|
find_path(LIBCARES_INCLUDE_DIR
|
||||||
|
NAMES ares.h
|
||||||
|
HINTS ${PC_LIBCARES_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
find_library(LIBCARES_LIBRARY
|
||||||
|
NAMES cares
|
||||||
|
HINTS ${PC_LIBCARES_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(LIBCARES_INCLUDE_DIR)
|
||||||
|
set(_version_regex "^#define[ \t]+ARES_VERSION_STR[ \t]+\"([^\"]+)\".*")
|
||||||
|
file(STRINGS "${LIBCARES_INCLUDE_DIR}/ares_version.h"
|
||||||
|
LIBCARES_VERSION REGEX "${_version_regex}")
|
||||||
|
string(REGEX REPLACE "${_version_regex}" "\\1"
|
||||||
|
LIBCARES_VERSION "${LIBCARES_VERSION}")
|
||||||
|
unset(_version_regex)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set LIBCARES_FOUND to TRUE
|
||||||
|
# if all listed variables are TRUE and the requested version matches.
|
||||||
|
find_package_handle_standard_args(Libcares REQUIRED_VARS
|
||||||
|
LIBCARES_LIBRARY LIBCARES_INCLUDE_DIR
|
||||||
|
VERSION_VAR LIBCARES_VERSION)
|
||||||
|
|
||||||
|
if(LIBCARES_FOUND)
|
||||||
|
set(LIBCARES_LIBRARIES ${LIBCARES_LIBRARY})
|
||||||
|
set(LIBCARES_INCLUDE_DIRS ${LIBCARES_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced(LIBCARES_INCLUDE_DIR LIBCARES_LIBRARY)
|
||||||
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
|
||||||
130
configure.ac
130
configure.ac
@@ -25,7 +25,7 @@ dnl Do not change user variables!
|
|||||||
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
|
||||||
|
|
||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
AC_INIT([nghttp2], [1.8.0-DEV], [t-tujikawa@users.sourceforge.net])
|
AC_INIT([nghttp2], [1.20.0-DEV], [t-tujikawa@users.sourceforge.net])
|
||||||
AC_CONFIG_AUX_DIR([.])
|
AC_CONFIG_AUX_DIR([.])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
@@ -40,15 +40,13 @@ AC_CANONICAL_TARGET
|
|||||||
|
|
||||||
AM_INIT_AUTOMAKE([subdir-objects])
|
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])])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
dnl See versioning rule:
|
dnl See versioning rule:
|
||||||
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
AC_SUBST(LT_CURRENT, 18)
|
AC_SUBST(LT_CURRENT, 26)
|
||||||
AC_SUBST(LT_REVISION, 1)
|
AC_SUBST(LT_REVISION, 4)
|
||||||
AC_SUBST(LT_AGE, 4)
|
AC_SUBST(LT_AGE, 12)
|
||||||
|
|
||||||
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
|
||||||
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
|
||||||
@@ -76,7 +74,7 @@ AC_ARG_ENABLE([threads],
|
|||||||
|
|
||||||
AC_ARG_ENABLE([app],
|
AC_ARG_ENABLE([app],
|
||||||
[AS_HELP_STRING([--enable-app],
|
[AS_HELP_STRING([--enable-app],
|
||||||
[Build applications (nghttp, nghttpd and nghttpx) [default=check]])],
|
[Build applications (nghttp, nghttpd, nghttpx and h2load) [default=check]])],
|
||||||
[request_app=$enableval], [request_app=check])
|
[request_app=$enableval], [request_app=check])
|
||||||
|
|
||||||
AC_ARG_ENABLE([hpack-tools],
|
AC_ARG_ENABLE([hpack-tools],
|
||||||
@@ -185,8 +183,8 @@ if test "x$GCC" = "xyes" -o "x$CC" = "xclang" ; then
|
|||||||
AC_DEFINE([_U_], [__attribute__((unused))], [Hint to the compiler that a function parameters is not used])
|
AC_DEFINE([_U_], [__attribute__((unused))], [Hint to the compiler that a function parameters is not used])
|
||||||
AC_DEFINE([NGHTTP2_NORETURN], [__attribute__((noreturn))], [Hint to the compiler that a function never return])
|
AC_DEFINE([NGHTTP2_NORETURN], [__attribute__((noreturn))], [Hint to the compiler that a function never return])
|
||||||
else
|
else
|
||||||
AC_DEFINE([_U_], , [Hint to the compiler that a function parameters is not use AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
|
AC_DEFINE([_U_], , [Hint to the compiler that a function parameter is not used])
|
||||||
d])
|
AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
save_CXXFLAGS="$CXXFLAGS"
|
save_CXXFLAGS="$CXXFLAGS"
|
||||||
@@ -236,6 +234,41 @@ std::map<int, int>().emplace(1, 2);
|
|||||||
[have_std_map_emplace=no
|
[have_std_map_emplace=no
|
||||||
AC_MSG_RESULT([no])])
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
|
# Check that std::atomic_* overloads for std::shared_ptr are
|
||||||
|
# available.
|
||||||
|
AC_MSG_CHECKING([whether std::atomic_* overloads for std::shared_ptr are available])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[[
|
||||||
|
#include <memory>
|
||||||
|
]],
|
||||||
|
[[
|
||||||
|
auto a = std::make_shared<int>(1000000007);
|
||||||
|
auto p = std::atomic_load(&a);
|
||||||
|
++*p;
|
||||||
|
std::atomic_store(&a, p);
|
||||||
|
]])],
|
||||||
|
[AC_DEFINE([HAVE_ATOMIC_STD_SHARED_PTR], [1],
|
||||||
|
[Define to 1 if you have the std::atomic_* overloads for std::shared_ptr.])
|
||||||
|
have_atomic_std_shared_ptr=yes
|
||||||
|
AC_MSG_RESULT([yes])],
|
||||||
|
[have_atomic_std_shared_ptr=no
|
||||||
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
|
# Check that thread_local storage specifier is available
|
||||||
|
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
,
|
||||||
|
[[
|
||||||
|
thread_local int a = 0;
|
||||||
|
(void)a;
|
||||||
|
]])],
|
||||||
|
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
|
||||||
|
[Define to 1 if you have thread_local storage specifier.])
|
||||||
|
have_thread_local=yes
|
||||||
|
AC_MSG_RESULT([yes])],
|
||||||
|
[have_Thread_local=no
|
||||||
|
AC_MSG_RESULT([no])])
|
||||||
|
|
||||||
CXXFLAGS=$save_CXXFLAGS
|
CXXFLAGS=$save_CXXFLAGS
|
||||||
|
|
||||||
AC_LANG_POP()
|
AC_LANG_POP()
|
||||||
@@ -248,7 +281,7 @@ TESTLDADD=
|
|||||||
# Additional libraries required for programs under src directory.
|
# Additional libraries required for programs under src directory.
|
||||||
APPLDFLAGS=
|
APPLDFLAGS=
|
||||||
|
|
||||||
case "$host" in
|
case "$host_os" in
|
||||||
*android*)
|
*android*)
|
||||||
android_build=yes
|
android_build=yes
|
||||||
# android does not need -pthread, but needs followng 3 libs for C++
|
# android does not need -pthread, but needs followng 3 libs for C++
|
||||||
@@ -260,6 +293,12 @@ case "$host" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
case "$host_os" in
|
||||||
|
*solaris*)
|
||||||
|
APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
# zlib
|
# zlib
|
||||||
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
|
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
|
||||||
|
|
||||||
@@ -331,6 +370,13 @@ if test "x${have_openssl}" = "xno"; then
|
|||||||
AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
|
AC_MSG_NOTICE($OPENSSL_PKG_ERRORS)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# c-ares (for src)
|
||||||
|
PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.5], [have_libcares=yes],
|
||||||
|
[have_libcares=no])
|
||||||
|
if test "x${have_libcares}" = "xno"; then
|
||||||
|
AC_MSG_NOTICE($LIBCARES_PKG_ERRORS)
|
||||||
|
fi
|
||||||
|
|
||||||
# libevent_openssl (for examples)
|
# libevent_openssl (for examples)
|
||||||
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
# 2.0.8 is required because we use evconnlistener_set_error_cb()
|
||||||
PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
|
PKG_CHECK_MODULES([LIBEVENT_OPENSSL], [libevent_openssl >= 2.0.8],
|
||||||
@@ -350,12 +396,12 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# libxml2 (for src/nghttp)
|
# libxml2 (for src/nghttp)
|
||||||
have_libxml2=no
|
PKG_CHECK_MODULES([LIBXML2], [libxml-2.0 >= 2.7.7],
|
||||||
if test "x${request_libxml2}" != "xno"; then
|
[have_libxml2=yes], [have_libxml2=no])
|
||||||
AM_PATH_XML2(2.7.7, [have_libxml2=yes], [have_libxml2=no])
|
if test "x${have_libxml2}" = "xyes"; then
|
||||||
if test "x${have_libxml2}" = "xyes"; then
|
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
|
||||||
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
|
else
|
||||||
fi
|
AC_MSG_NOTICE($LIBXML2_PKG_ERRORS)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "x${request_libxml2}" = "xyes" &&
|
if test "x${request_libxml2}" = "xyes" &&
|
||||||
@@ -437,13 +483,14 @@ if test "x${request_asio_lib}" = "xyes"; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL
|
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL,
|
||||||
# and libev
|
# libev, and libc-ares.
|
||||||
enable_app=no
|
enable_app=no
|
||||||
if test "x${request_app}" != "xno" &&
|
if test "x${request_app}" != "xno" &&
|
||||||
test "x${have_zlib}" = "xyes" &&
|
test "x${have_zlib}" = "xyes" &&
|
||||||
test "x${have_openssl}" = "xyes" &&
|
test "x${have_openssl}" = "xyes" &&
|
||||||
test "x${have_libev}" = "xyes"; then
|
test "x${have_libev}" = "xyes" &&
|
||||||
|
test "x${have_libcares}" = "xyes"; then
|
||||||
enable_app=yes
|
enable_app=yes
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -598,6 +645,26 @@ AC_SYS_LARGEFILE
|
|||||||
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes],
|
AC_CHECK_MEMBER([struct tm.tm_gmtoff], [have_struct_tm_tm_gmtoff=yes],
|
||||||
[have_struct_tm_tm_gmtoff=no], [[#include <time.h>]])
|
[have_struct_tm_tm_gmtoff=no], [[#include <time.h>]])
|
||||||
|
|
||||||
|
AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
|
||||||
|
[AC_DEFINE([HAVE_SOCKADDR_IN_SIN_LEN],[1],
|
||||||
|
[Define to 1 if struct sockaddr_in has sin_len member.])],
|
||||||
|
[],
|
||||||
|
[[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
]])
|
||||||
|
|
||||||
|
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_len],
|
||||||
|
[AC_DEFINE([HAVE_SOCKADDR_IN6_SIN6_LEN],[1],
|
||||||
|
[Define to 1 if struct sockaddr_in6 has sin6_len member.])],
|
||||||
|
[],
|
||||||
|
[[
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
]])
|
||||||
|
|
||||||
if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
|
if test "x$have_struct_tm_tm_gmtoff" = "xyes"; then
|
||||||
AC_DEFINE([HAVE_STRUCT_TM_TM_GMTOFF], [1],
|
AC_DEFINE([HAVE_STRUCT_TM_TM_GMTOFF], [1],
|
||||||
[Define to 1 if you have `struct tm.tm_gmtoff` member.])
|
[Define to 1 if you have `struct tm.tm_gmtoff` member.])
|
||||||
@@ -651,15 +718,13 @@ AC_CHECK_FUNC([timerfd_create],
|
|||||||
|
|
||||||
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
|
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
|
||||||
# cygwin disables initgroups due to feature test macro magic with our
|
# cygwin disables initgroups due to feature test macro magic with our
|
||||||
# configuration.
|
# configuration. FreeBSD declares initgroups() in unistd.h.
|
||||||
AC_CHECK_DECLS([initgroups], [], [], [[#include <grp.h>]])
|
AC_CHECK_DECLS([initgroups], [], [], [[
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
# Checks for epoll availability, primarily for examples/tiny-nghttpd
|
# include <unistd.h>
|
||||||
AX_HAVE_EPOLL([have_epoll=yes], [have_epoll=no])
|
#endif
|
||||||
|
#include <grp.h>
|
||||||
AM_CONDITIONAL([ENABLE_TINY_NGHTTPD],
|
]])
|
||||||
[ test "x${have_epoll}" = "xyes" &&
|
|
||||||
test "x${have_timerfd_create}" = "xyes"])
|
|
||||||
|
|
||||||
save_CFLAGS=$CFLAGS
|
save_CFLAGS=$CFLAGS
|
||||||
save_CXXFLAGS=$CXXFLAGS
|
save_CXXFLAGS=$CXXFLAGS
|
||||||
@@ -714,12 +779,17 @@ if test "x$werror" != "xno"; then
|
|||||||
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
|
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
|
||||||
# Only work with Clang for the moment
|
# Only work with Clang for the moment
|
||||||
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
|
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
|
||||||
|
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CFLAGS="$CFLAGS -Wsometimes-uninitialized"])
|
||||||
|
|
||||||
|
# This is required because we pass format string as "const char*.
|
||||||
|
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
|
||||||
|
|
||||||
# For C++ compiler
|
# For C++ compiler
|
||||||
AC_LANG_PUSH(C++)
|
AC_LANG_PUSH(C++)
|
||||||
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
|
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
|
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
|
||||||
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
|
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
|
||||||
|
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
|
||||||
AC_LANG_POP()
|
AC_LANG_POP()
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -816,6 +886,7 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
C preprocessor: ${CPP}
|
C preprocessor: ${CPP}
|
||||||
CPPFLAGS: ${CPPFLAGS}
|
CPPFLAGS: ${CPPFLAGS}
|
||||||
WARNCFLAGS: ${WARNCFLAGS}
|
WARNCFLAGS: ${WARNCFLAGS}
|
||||||
|
WARNCXXFLAGS: ${WARNCXXFLAGS}
|
||||||
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
|
||||||
EXTRACFLAG: ${EXTRACFLAG}
|
EXTRACFLAG: ${EXTRACFLAG}
|
||||||
LIBS: ${LIBS}
|
LIBS: ${LIBS}
|
||||||
@@ -835,8 +906,9 @@ AC_MSG_NOTICE([summary of build options:
|
|||||||
Failmalloc: ${enable_failmalloc}
|
Failmalloc: ${enable_failmalloc}
|
||||||
Libs:
|
Libs:
|
||||||
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
|
OpenSSL: ${have_openssl} (CFLAGS='${OPENSSL_CFLAGS}' LIBS='${OPENSSL_LIBS}')
|
||||||
Libxml2: ${have_libxml2} (CFLAGS='${XML_CPPFLAGS}' LIBS='${XML_LIBS}')
|
Libxml2: ${have_libxml2} (CFLAGS='${LIBXML2_CPPFLAGS}' LIBS='${LIBXML2_LIBS}')
|
||||||
Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
|
Libev: ${have_libev} (CFLAGS='${LIBEV_CFLAGS}' LIBS='${LIBEV_LIBS}')
|
||||||
|
Libc-ares ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
|
||||||
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
|
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')
|
||||||
Spdylay: ${have_spdylay} (CFLAGS='${LIBSPDYLAY_CFLAGS}' LIBS='${LIBSPDYLAY_LIBS}')
|
Spdylay: ${have_spdylay} (CFLAGS='${LIBSPDYLAY_CFLAGS}' LIBS='${LIBSPDYLAY_LIBS}')
|
||||||
Jansson: ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_LIBS}')
|
Jansson: ${have_jansson} (CFLAGS='${JANSSON_CFLAGS}' LIBS='${JANSSON_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
|
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'
|
edit = sed -e 's|@bindir[@]|$(bindir)|g'
|
||||||
|
|
||||||
nghttpx-init: %: $(srcdir)/%.in
|
nghttpx-init: $(srcdir)/nghttpx-init.in
|
||||||
rm -f $@ $@.tmp
|
rm -f $@ $@.tmp
|
||||||
$(edit) $< > $@.tmp
|
$(edit) $< > $@.tmp
|
||||||
chmod +x $@.tmp
|
chmod +x $@.tmp
|
||||||
mv $@.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) $< > $@
|
$(edit) $< > $@
|
||||||
|
|
||||||
$(configfiles): Makefile
|
$(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_num_table_entries.rst \
|
||||||
nghttp2_hd_deflate_get_table_entry.rst \
|
nghttp2_hd_deflate_get_table_entry.rst \
|
||||||
nghttp2_hd_deflate_hd.rst \
|
nghttp2_hd_deflate_hd.rst \
|
||||||
|
nghttp2_hd_deflate_hd_vec.rst \
|
||||||
nghttp2_hd_deflate_new.rst \
|
nghttp2_hd_deflate_new.rst \
|
||||||
nghttp2_hd_deflate_new2.rst \
|
nghttp2_hd_deflate_new2.rst \
|
||||||
nghttp2_hd_inflate_change_table_size.rst \
|
nghttp2_hd_inflate_change_table_size.rst \
|
||||||
@@ -47,39 +48,59 @@ APIDOCS= \
|
|||||||
nghttp2_hd_inflate_get_num_table_entries.rst \
|
nghttp2_hd_inflate_get_num_table_entries.rst \
|
||||||
nghttp2_hd_inflate_get_table_entry.rst \
|
nghttp2_hd_inflate_get_table_entry.rst \
|
||||||
nghttp2_hd_inflate_hd.rst \
|
nghttp2_hd_inflate_hd.rst \
|
||||||
|
nghttp2_hd_inflate_hd2.rst \
|
||||||
nghttp2_hd_inflate_new.rst \
|
nghttp2_hd_inflate_new.rst \
|
||||||
nghttp2_hd_inflate_new2.rst \
|
nghttp2_hd_inflate_new2.rst \
|
||||||
|
nghttp2_http2_strerror.rst \
|
||||||
nghttp2_is_fatal.rst \
|
nghttp2_is_fatal.rst \
|
||||||
nghttp2_nv_compare_name.rst \
|
nghttp2_nv_compare_name.rst \
|
||||||
nghttp2_option_del.rst \
|
nghttp2_option_del.rst \
|
||||||
nghttp2_option_new.rst \
|
nghttp2_option_new.rst \
|
||||||
|
nghttp2_option_set_builtin_recv_extension_type.rst \
|
||||||
|
nghttp2_option_set_max_deflate_dynamic_table_size.rst \
|
||||||
nghttp2_option_set_max_reserved_remote_streams.rst \
|
nghttp2_option_set_max_reserved_remote_streams.rst \
|
||||||
|
nghttp2_option_set_max_send_header_block_length.rst \
|
||||||
|
nghttp2_option_set_no_auto_ping_ack.rst \
|
||||||
nghttp2_option_set_no_auto_window_update.rst \
|
nghttp2_option_set_no_auto_window_update.rst \
|
||||||
nghttp2_option_set_no_http_messaging.rst \
|
nghttp2_option_set_no_http_messaging.rst \
|
||||||
nghttp2_option_set_no_recv_client_magic.rst \
|
nghttp2_option_set_no_recv_client_magic.rst \
|
||||||
nghttp2_option_set_peer_max_concurrent_streams.rst \
|
nghttp2_option_set_peer_max_concurrent_streams.rst \
|
||||||
|
nghttp2_option_set_user_recv_extension_type.rst \
|
||||||
nghttp2_pack_settings_payload.rst \
|
nghttp2_pack_settings_payload.rst \
|
||||||
nghttp2_priority_spec_check_default.rst \
|
nghttp2_priority_spec_check_default.rst \
|
||||||
nghttp2_priority_spec_default_init.rst \
|
nghttp2_priority_spec_default_init.rst \
|
||||||
nghttp2_priority_spec_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_select_next_protocol.rst \
|
||||||
nghttp2_session_callbacks_del.rst \
|
nghttp2_session_callbacks_del.rst \
|
||||||
nghttp2_session_callbacks_new.rst \
|
nghttp2_session_callbacks_new.rst \
|
||||||
nghttp2_session_callbacks_set_before_frame_send_callback.rst \
|
nghttp2_session_callbacks_set_before_frame_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_data_source_read_length_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_frame_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
|
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \
|
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \
|
||||||
|
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst \
|
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
|
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
|
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_on_header_callback.rst \
|
nghttp2_session_callbacks_set_on_header_callback.rst \
|
||||||
|
nghttp2_session_callbacks_set_on_header_callback2.rst \
|
||||||
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
|
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
|
||||||
|
nghttp2_session_callbacks_set_on_invalid_header_callback.rst \
|
||||||
|
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst \
|
||||||
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
|
||||||
|
nghttp2_session_callbacks_set_pack_extension_callback.rst \
|
||||||
nghttp2_session_callbacks_set_recv_callback.rst \
|
nghttp2_session_callbacks_set_recv_callback.rst \
|
||||||
nghttp2_session_callbacks_set_select_padding_callback.rst \
|
nghttp2_session_callbacks_set_select_padding_callback.rst \
|
||||||
nghttp2_session_callbacks_set_send_callback.rst \
|
nghttp2_session_callbacks_set_send_callback.rst \
|
||||||
nghttp2_session_callbacks_set_send_data_callback.rst \
|
nghttp2_session_callbacks_set_send_data_callback.rst \
|
||||||
|
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
|
||||||
|
nghttp2_session_change_stream_priority.rst \
|
||||||
|
nghttp2_session_check_request_allowed.rst \
|
||||||
|
nghttp2_session_check_server_session.rst \
|
||||||
nghttp2_session_client_new.rst \
|
nghttp2_session_client_new.rst \
|
||||||
nghttp2_session_client_new2.rst \
|
nghttp2_session_client_new2.rst \
|
||||||
nghttp2_session_client_new3.rst \
|
nghttp2_session_client_new3.rst \
|
||||||
@@ -91,7 +112,11 @@ APIDOCS= \
|
|||||||
nghttp2_session_find_stream.rst \
|
nghttp2_session_find_stream.rst \
|
||||||
nghttp2_session_get_effective_local_window_size.rst \
|
nghttp2_session_get_effective_local_window_size.rst \
|
||||||
nghttp2_session_get_effective_recv_data_length.rst \
|
nghttp2_session_get_effective_recv_data_length.rst \
|
||||||
|
nghttp2_session_get_hd_deflate_dynamic_table_size.rst \
|
||||||
|
nghttp2_session_get_hd_inflate_dynamic_table_size.rst \
|
||||||
nghttp2_session_get_last_proc_stream_id.rst \
|
nghttp2_session_get_last_proc_stream_id.rst \
|
||||||
|
nghttp2_session_get_local_settings.rst \
|
||||||
|
nghttp2_session_get_local_window_size.rst \
|
||||||
nghttp2_session_get_next_stream_id.rst \
|
nghttp2_session_get_next_stream_id.rst \
|
||||||
nghttp2_session_get_outbound_queue_size.rst \
|
nghttp2_session_get_outbound_queue_size.rst \
|
||||||
nghttp2_session_get_remote_settings.rst \
|
nghttp2_session_get_remote_settings.rst \
|
||||||
@@ -100,20 +125,19 @@ APIDOCS= \
|
|||||||
nghttp2_session_get_stream_effective_local_window_size.rst \
|
nghttp2_session_get_stream_effective_local_window_size.rst \
|
||||||
nghttp2_session_get_stream_effective_recv_data_length.rst \
|
nghttp2_session_get_stream_effective_recv_data_length.rst \
|
||||||
nghttp2_session_get_stream_local_close.rst \
|
nghttp2_session_get_stream_local_close.rst \
|
||||||
|
nghttp2_session_get_stream_local_window_size.rst \
|
||||||
nghttp2_session_get_stream_remote_close.rst \
|
nghttp2_session_get_stream_remote_close.rst \
|
||||||
nghttp2_session_get_stream_remote_window_size.rst \
|
nghttp2_session_get_stream_remote_window_size.rst \
|
||||||
nghttp2_session_get_stream_user_data.rst \
|
nghttp2_session_get_stream_user_data.rst \
|
||||||
nghttp2_session_mem_recv.rst \
|
nghttp2_session_mem_recv.rst \
|
||||||
nghttp2_session_mem_send.rst \
|
nghttp2_session_mem_send.rst \
|
||||||
nghttp2_session_recv.rst \
|
nghttp2_session_recv.rst \
|
||||||
nghttp2_session_change_stream_priority.rst \
|
|
||||||
nghttp2_session_check_request_allowed.rst \
|
|
||||||
nghttp2_session_check_server_session.rst \
|
|
||||||
nghttp2_session_resume_data.rst \
|
nghttp2_session_resume_data.rst \
|
||||||
nghttp2_session_send.rst \
|
nghttp2_session_send.rst \
|
||||||
nghttp2_session_server_new.rst \
|
nghttp2_session_server_new.rst \
|
||||||
nghttp2_session_server_new2.rst \
|
nghttp2_session_server_new2.rst \
|
||||||
nghttp2_session_server_new3.rst \
|
nghttp2_session_server_new3.rst \
|
||||||
|
nghttp2_session_set_local_window_size.rst \
|
||||||
nghttp2_session_set_next_stream_id.rst \
|
nghttp2_session_set_next_stream_id.rst \
|
||||||
nghttp2_session_set_stream_user_data.rst \
|
nghttp2_session_set_stream_user_data.rst \
|
||||||
nghttp2_session_terminate_session.rst \
|
nghttp2_session_terminate_session.rst \
|
||||||
@@ -122,6 +146,7 @@ APIDOCS= \
|
|||||||
nghttp2_session_upgrade2.rst \
|
nghttp2_session_upgrade2.rst \
|
||||||
nghttp2_session_want_read.rst \
|
nghttp2_session_want_read.rst \
|
||||||
nghttp2_session_want_write.rst \
|
nghttp2_session_want_write.rst \
|
||||||
|
nghttp2_set_debug_vprintf_callback.rst \
|
||||||
nghttp2_stream_get_first_child.rst \
|
nghttp2_stream_get_first_child.rst \
|
||||||
nghttp2_stream_get_next_sibling.rst \
|
nghttp2_stream_get_next_sibling.rst \
|
||||||
nghttp2_stream_get_parent.rst \
|
nghttp2_stream_get_parent.rst \
|
||||||
@@ -130,7 +155,9 @@ APIDOCS= \
|
|||||||
nghttp2_stream_get_sum_dependency_weight.rst \
|
nghttp2_stream_get_sum_dependency_weight.rst \
|
||||||
nghttp2_stream_get_weight.rst \
|
nghttp2_stream_get_weight.rst \
|
||||||
nghttp2_strerror.rst \
|
nghttp2_strerror.rst \
|
||||||
|
nghttp2_submit_altsvc.rst \
|
||||||
nghttp2_submit_data.rst \
|
nghttp2_submit_data.rst \
|
||||||
|
nghttp2_submit_extension.rst \
|
||||||
nghttp2_submit_goaway.rst \
|
nghttp2_submit_goaway.rst \
|
||||||
nghttp2_submit_headers.rst \
|
nghttp2_submit_headers.rst \
|
||||||
nghttp2_submit_ping.rst \
|
nghttp2_submit_ping.rst \
|
||||||
@@ -145,15 +172,19 @@ APIDOCS= \
|
|||||||
nghttp2_submit_window_update.rst \
|
nghttp2_submit_window_update.rst \
|
||||||
nghttp2_version.rst
|
nghttp2_version.rst
|
||||||
|
|
||||||
EXTRA_DIST = \
|
RST_FILES = \
|
||||||
mkapiref.py \
|
|
||||||
README.rst \
|
README.rst \
|
||||||
programmers-guide.rst \
|
programmers-guide.rst \
|
||||||
$(APIDOCS) \
|
|
||||||
nghttp.1.rst \
|
nghttp.1.rst \
|
||||||
nghttpd.1.rst \
|
nghttpd.1.rst \
|
||||||
nghttpx.1.rst \
|
nghttpx.1.rst \
|
||||||
h2load.1.rst \
|
h2load.1.rst
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
CMakeLists.txt \
|
||||||
|
mkapiref.py \
|
||||||
|
$(RST_FILES) \
|
||||||
|
$(APIDOCS) \
|
||||||
sources/index.rst \
|
sources/index.rst \
|
||||||
sources/tutorial-client.rst \
|
sources/tutorial-client.rst \
|
||||||
sources/tutorial-server.rst \
|
sources/tutorial-server.rst \
|
||||||
@@ -227,13 +258,15 @@ help:
|
|||||||
|
|
||||||
apiref.rst: \
|
apiref.rst: \
|
||||||
$(top_builddir)/lib/includes/nghttp2/nghttp2ver.h \
|
$(top_builddir)/lib/includes/nghttp2/nghttp2ver.h \
|
||||||
$(top_builddir)/lib/includes/nghttp2/nghttp2.h
|
$(top_srcdir)/lib/includes/nghttp2/nghttp2.h
|
||||||
|
for i in $(RST_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
|
||||||
$(PYTHON) $(top_srcdir)/doc/mkapiref.py \
|
$(PYTHON) $(top_srcdir)/doc/mkapiref.py \
|
||||||
apiref.rst macros.rst enums.rst types.rst . $^
|
apiref.rst macros.rst enums.rst types.rst . $^
|
||||||
|
|
||||||
$(APIDOCS): apiref.rst
|
$(APIDOCS): apiref.rst
|
||||||
|
|
||||||
clean-local:
|
clean-local:
|
||||||
|
[ $(srcdir) = $(builddir) ] || for i in $(RST_FILES); do [ -e $(builddir)/$$i ] && rm -f $(builddir)/$$i; done
|
||||||
-rm -f apiref.rst
|
-rm -f apiref.rst
|
||||||
-rm -f $(APIDOCS)
|
-rm -f $(APIDOCS)
|
||||||
-rm -rf $(BUILDDIR)/*
|
-rm -rf $(BUILDDIR)/*
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from docutils import nodes
|
|||||||
from docutils.parsers.rst import directives
|
from docutils.parsers.rst import directives
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx import version_info
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.locale import l_, _
|
from sphinx.locale import l_, _
|
||||||
from sphinx.domains import Domain, ObjType, Index
|
from sphinx.domains import Domain, ObjType, Index
|
||||||
@@ -231,8 +232,8 @@ class RubyObject(ObjectDescription):
|
|||||||
|
|
||||||
indextext = self.get_index_text(modname, name_cls)
|
indextext = self.get_index_text(modname, name_cls)
|
||||||
if indextext:
|
if indextext:
|
||||||
self.indexnode['entries'].append(('single', indextext,
|
self.indexnode['entries'].append(
|
||||||
fullname, fullname))
|
_make_index('single', indextext, fullname, fullname))
|
||||||
|
|
||||||
def before_content(self):
|
def before_content(self):
|
||||||
# needed for automatic qualification of members (reset in subclasses)
|
# needed for automatic qualification of members (reset in subclasses)
|
||||||
@@ -415,11 +416,19 @@ class RubyModule(Directive):
|
|||||||
# modindex currently
|
# modindex currently
|
||||||
if not noindex:
|
if not noindex:
|
||||||
indextext = _('%s (module)') % modname
|
indextext = _('%s (module)') % modname
|
||||||
inode = addnodes.index(entries=[('single', indextext,
|
inode = addnodes.index(entries=[_make_index(
|
||||||
'module-' + modname, modname)])
|
'single', indextext, 'module-' + modname, modname)])
|
||||||
ret.append(inode)
|
ret.append(inode)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _make_index(entrytype, entryname, target, ignored, key=None):
|
||||||
|
# Sphinx 1.4 introduced backward incompatible changes, it now
|
||||||
|
# requires 5 tuples. Last one is categorization key. See
|
||||||
|
# http://www.sphinx-doc.org/en/stable/extdev/nodes.html#sphinx.addnodes.index
|
||||||
|
if version_info >= (1, 4, 0, '', 0):
|
||||||
|
return (entrytype, entryname, target, ignored, key)
|
||||||
|
else:
|
||||||
|
return (entrytype, entryname, target, ignored)
|
||||||
|
|
||||||
class RubyCurrentModule(Directive):
|
class RubyCurrentModule(Directive):
|
||||||
"""
|
"""
|
||||||
|
|||||||
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">
|
<body class="wy-body-for-nav" role="document">
|
||||||
|
|
||||||
|
{% block extrabody %} {% endblock %}
|
||||||
<div class="wy-grid-for-nav">
|
<div class="wy-grid-for-nav">
|
||||||
|
|
||||||
{# SIDE NAV, TOGGLES ON MOBILE #}
|
{# 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
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --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
|
_filedir
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ _nghttp()
|
|||||||
_get_comp_words_by_ref cur prev
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--no-push --verbose --no-dep --get-assets --har --header-table-size --multiply --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
|
_filedir
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ _nghttpd()
|
|||||||
_get_comp_words_by_ref cur prev
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --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
|
_filedir
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ _nghttpx()
|
|||||||
_get_comp_words_by_ref cur prev
|
_get_comp_words_by_ref cur prev
|
||||||
case $cur in
|
case $cur in
|
||||||
-*)
|
-*)
|
||||||
COMPREPLY=( $( compgen -W '--worker-read-rate --frontend-no-tls --frontend-http2-dump-response-header --backend-http1-connections-per-frontend --tls-ticket-key-file --verify-client-cacert --include --max-response-header-fields --backend-request-buffer --max-request-header-fields --backend-http2-connection-window-bits --backend-tls-session-cache-per-worker --conf --worker-write-burst --npn-list --fetch-ocsp-response-file --no-http2-cipher-black-list --mruby-file --stream-read-timeout --tls-ticket-key-memcached --forwarded-for --accesslog-syslog --frontend-http2-read-timeout --listener-disable-timeout --frontend-http2-connection-window-bits --ciphers --strip-incoming-x-forwarded-for --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --backend-http1-connections-per-host --rlimit-nofile --tls-dyn-rec-warmup-threshold --no-via --ocsp-update-interval --backend-write-timeout --client --tls-ticket-key-memcached-max-retry --http2-no-cookie-crumbling --worker-read-burst --client-proxy --http2-bridge --accesslog-format --errorlog-syslog --request-header-field-buffer --errorlog-file --http2-max-concurrent-streams --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend-ipv4 --backend-ipv6 --backend --insecure --log-level --host-rewrite --tls-proto-list --backend-http2-connections-per-worker --tls-ticket-key-memcached-interval --dh-param-file --worker-frontend-connections --backend-http1-tls --syslog-facility --fastopen --no-location-rewrite --tls-session-cache-memcached --no-ocsp --backend-response-buffer --workers --add-forwarded --frontend-http2-window-bits --worker-write-rate --add-request-header --backend-tls-sni-field --subcert --help --frontend-frame-debug --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --user --add-x-forwarded-for --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --no-server-push --backend-http2-window-bits --response-header-field-buffer --padding --stream-write-timeout --cacert --forwarded-by --version --add-response-header --backend-read-timeout --frontend --accesslog-file --http2-proxy --backend-no-tls --client-private-key-file --client-cert-file --accept-proxy-protocol --tls-dyn-rec-idle-timeout --verify-client --read-rate --strip-incoming-forwarded ' -- "$cur" ) )
|
COMPREPLY=( $( compgen -W '--worker-read-rate --include --frontend-http2-dump-response-header --tls-ticket-key-file --verify-client-cacert --max-response-header-fields --backend-http2-window-size --frontend-keep-alive-timeout --backend-request-buffer --max-request-header-fields --fastopen --backend-connect-timeout --conf --dns-lookup-timeout --backend-http2-max-concurrent-streams --worker-write-burst --npn-list --dns-max-try --fetch-ocsp-response-file --no-via --tls-session-cache-memcached-cert-file --no-http2-cipher-black-list --mruby-file --client-no-http2-cipher-black-list --stream-read-timeout --client-ciphers --forwarded-for --accesslog-syslog --dns-cache-timeout --frontend-http2-read-timeout --listener-disable-timeout --ciphers --client-psk-secrets --strip-incoming-x-forwarded-for --no-server-rewrite --private-key-passwd-file --backend-keep-alive-timeout --backend-http-proxy-uri --rlimit-nofile --tls-ticket-key-memcached-cert-file --ocsp-update-interval --forwarded-by --tls-session-cache-memcached-private-key-file --error-page --backend-write-timeout --tls-dyn-rec-warmup-threshold --tls-ticket-key-memcached-max-retry --frontend-http2-window-size --http2-no-cookie-crumbling --worker-read-burst --dh-param-file --accesslog-format --errorlog-syslog --request-header-field-buffer --api-max-request-body --frontend-http2-decoder-dynamic-table-size --errorlog-file --frontend-http2-max-concurrent-streams --psk-secrets --frontend-write-timeout --tls-ticket-key-cipher --read-burst --backend --server-name --insecure --backend-max-backoff --log-level --host-rewrite --tls-proto-list --tls-ticket-key-memcached-interval --frontend-http2-setting-timeout --frontend-http2-connection-window-size --worker-frontend-connections --syslog-facility --no-server-push --no-location-rewrite --tls-session-cache-memcached --no-ocsp --frontend-http2-encoder-dynamic-table-size --workers --add-forwarded --worker-write-rate --add-request-header --backend-http2-settings-timeout --subcert --ecdh-curves --no-kqueue --help --frontend-frame-debug --tls-sct-dir --pid-file --frontend-http2-dump-request-header --daemon --write-rate --altsvc --backend-http2-decoder-dynamic-table-size --user --add-x-forwarded-for --frontend-read-timeout --tls-ticket-key-memcached-max-fail --backlog --write-burst --backend-connections-per-host --response-header-field-buffer --tls-ticket-key-memcached-address-family --padding --tls-session-cache-memcached-address-family --stream-write-timeout --cacert --tls-ticket-key-memcached-private-key-file --accesslog-write-early --backend-address-family --backend-http2-connection-window-size --version --add-response-header --backend-read-timeout --frontend-http2-optimize-window-size --frontend --accesslog-file --http2-proxy --backend-http2-encoder-dynamic-table-size --client-private-key-file --client-cert-file --tls-ticket-key-memcached --tls-dyn-rec-idle-timeout --frontend-http2-optimize-write-buffer-size --verify-client --backend-response-buffer --read-rate --backend-connections-per-frontend --strip-incoming-forwarded ' -- "$cur" ) )
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
_filedir
|
_filedir
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import sys, os
|
|||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
#sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
sys.path.append(os.path.abspath('_exts'))
|
sys.path.append(os.path.abspath('@top_srcdir@/doc/_exts'))
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
32
doc/h2load.1
32
doc/h2load.1
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "H2LOAD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
|
.TH "H2LOAD" "1" "Jan 25, 2017" "1.19.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
h2load \- HTTP/2 benchmarking tool
|
h2load \- HTTP/2 benchmarking tool
|
||||||
.
|
.
|
||||||
@@ -123,6 +123,8 @@ Add/Override a header to the requests.
|
|||||||
.B \-\-ciphers=<SUITE>
|
.B \-\-ciphers=<SUITE>
|
||||||
Set allowed cipher list. The format of the string is
|
Set allowed cipher list. The format of the string is
|
||||||
described in OpenSSL ciphers(1).
|
described in OpenSSL ciphers(1).
|
||||||
|
.sp
|
||||||
|
Default: \fBECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:ECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-AES128\-SHA256:ECDHE\-RSA\-AES128\-SHA256:ECDHE\-ECDSA\-AES128\-SHA:ECDHE\-RSA\-AES256\-SHA384:ECDHE\-RSA\-AES128\-SHA:ECDHE\-ECDSA\-AES256\-SHA384:ECDHE\-ECDSA\-AES256\-SHA:ECDHE\-RSA\-AES256\-SHA:DHE\-RSA\-AES128\-SHA256:DHE\-RSA\-AES128\-SHA:DHE\-RSA\-AES256\-SHA256:DHE\-RSA\-AES256\-SHA:ECDHE\-ECDSA\-DES\-CBC3\-SHA:ECDHE\-RSA\-DES\-CBC3\-SHA:EDH\-RSA\-DES\-CBC3\-SHA:AES128\-GCM\-SHA256:AES256\-GCM\-SHA384:AES128\-SHA256:AES256\-SHA256:AES128\-SHA:AES256\-SHA:DES\-CBC3\-SHA:!DSS\fP
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -138,7 +140,9 @@ Default: \fBh2c\fP
|
|||||||
.TP
|
.TP
|
||||||
.B \-d, \-\-data=<PATH>
|
.B \-d, \-\-data=<PATH>
|
||||||
Post FILE to server. The request method is changed to
|
Post FILE to server. The request method is changed to
|
||||||
POST.
|
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
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -149,7 +153,7 @@ representing the number of connections to be made per
|
|||||||
rate period. The maximum number of connections to be
|
rate period. The maximum number of connections to be
|
||||||
made is given in \fI\%\-c\fP option. This rate will be
|
made is given in \fI\%\-c\fP option. This rate will be
|
||||||
distributed among threads as evenly as possible. For
|
distributed among threads as evenly as possible. For
|
||||||
example, with \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
|
connections per period. When the rate is 0, the program
|
||||||
will run as it normally does, creating connections at
|
will run as it normally does, creating connections at
|
||||||
whatever variable rate it wants. The default value for
|
whatever variable rate it wants. The default value for
|
||||||
@@ -240,6 +244,23 @@ http/1.1 for both http and https URI.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-header\-table\-size=<SIZE>
|
||||||
|
Specify decoder header table size.
|
||||||
|
.sp
|
||||||
|
Default: \fB4K\fP
|
||||||
|
.UNINDENT
|
||||||
|
.INDENT 0.0
|
||||||
|
.TP
|
||||||
|
.B \-\-encoder\-header\-table\-size=<SIZE>
|
||||||
|
Specify encoder header table size. The decoder (server)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which server specified.
|
||||||
|
.sp
|
||||||
|
Default: \fB4K\fP
|
||||||
|
.UNINDENT
|
||||||
|
.INDENT 0.0
|
||||||
|
.TP
|
||||||
.B \-v, \-\-verbose
|
.B \-v, \-\-verbose
|
||||||
Output debug information.
|
Output debug information.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -254,6 +275,9 @@ Display version information and exit.
|
|||||||
Display this help and exit.
|
Display this help and exit.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.sp
|
.sp
|
||||||
|
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
||||||
|
10 * 1024). Units are K, M and G (powers of 1024).
|
||||||
|
.sp
|
||||||
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
||||||
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
||||||
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
||||||
@@ -412,7 +436,7 @@ performance. To set smaller flow control window, use \fI\%\-w\fP and
|
|||||||
window size described in HTTP/2 and SPDY protocol specification.
|
window size described in HTTP/2 and SPDY protocol specification.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fInghttpx(1)\fP
|
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -74,14 +74,14 @@ OPTIONS
|
|||||||
.. option:: -w, --window-bits=<N>
|
.. option:: -w, --window-bits=<N>
|
||||||
|
|
||||||
Sets the stream level initial window size to (2\*\*<N>)-1.
|
Sets the stream level initial window size to (2\*\*<N>)-1.
|
||||||
For SPDY, 2**<N> is used instead.
|
For SPDY, 2\*\*<N> is used instead.
|
||||||
|
|
||||||
Default: ``30``
|
Default: ``30``
|
||||||
|
|
||||||
.. option:: -W, --connection-window-bits=<N>
|
.. option:: -W, --connection-window-bits=<N>
|
||||||
|
|
||||||
Sets the connection level initial window size to
|
Sets the connection level initial window size to
|
||||||
(2**<N>)-1. For SPDY, if <N> is strictly less than 16,
|
(2\*\*<N>)-1. For SPDY, if <N> is strictly less than 16,
|
||||||
this option is ignored. Otherwise 2\*\*<N> is used for
|
this option is ignored. Otherwise 2\*\*<N> is used for
|
||||||
SPDY.
|
SPDY.
|
||||||
|
|
||||||
@@ -96,6 +96,8 @@ OPTIONS
|
|||||||
Set allowed cipher list. The format of the string is
|
Set allowed cipher list. The format of the string is
|
||||||
described in OpenSSL ciphers(1).
|
described in OpenSSL ciphers(1).
|
||||||
|
|
||||||
|
Default: ``ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS``
|
||||||
|
|
||||||
.. option:: -p, --no-tls-proto=<PROTOID>
|
.. option:: -p, --no-tls-proto=<PROTOID>
|
||||||
|
|
||||||
Specify ALPN identifier of the protocol to be used when
|
Specify ALPN identifier of the protocol to be used when
|
||||||
@@ -108,7 +110,9 @@ OPTIONS
|
|||||||
.. option:: -d, --data=<PATH>
|
.. option:: -d, --data=<PATH>
|
||||||
|
|
||||||
Post FILE to server. The request method is changed to
|
Post FILE to server. The request method is changed to
|
||||||
POST.
|
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>
|
.. option:: -r, --rate=<N>
|
||||||
|
|
||||||
@@ -118,7 +122,7 @@ OPTIONS
|
|||||||
rate period. The maximum number of connections to be
|
rate period. The maximum number of connections to be
|
||||||
made is given in :option:`-c` option. This rate will be
|
made is given in :option:`-c` option. This rate will be
|
||||||
distributed among threads as evenly as possible. For
|
distributed among threads as evenly as possible. For
|
||||||
example, with :option:`-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
|
connections per period. When the rate is 0, the program
|
||||||
will run as it normally does, creating connections at
|
will run as it normally does, creating connections at
|
||||||
whatever variable rate it wants. The default value for
|
whatever variable rate it wants. The default value for
|
||||||
@@ -200,6 +204,21 @@ OPTIONS
|
|||||||
:option:`--no-tls-proto`\=http/1.1, which effectively force
|
:option:`--no-tls-proto`\=http/1.1, which effectively force
|
||||||
http/1.1 for both http and https URI.
|
http/1.1 for both http and https URI.
|
||||||
|
|
||||||
|
.. option:: --header-table-size=<SIZE>
|
||||||
|
|
||||||
|
Specify decoder header table size.
|
||||||
|
|
||||||
|
Default: ``4K``
|
||||||
|
|
||||||
|
.. option:: --encoder-header-table-size=<SIZE>
|
||||||
|
|
||||||
|
Specify encoder header table size. The decoder (server)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which server specified.
|
||||||
|
|
||||||
|
Default: ``4K``
|
||||||
|
|
||||||
.. option:: -v, --verbose
|
.. option:: -v, --verbose
|
||||||
|
|
||||||
Output debug information.
|
Output debug information.
|
||||||
@@ -214,6 +233,9 @@ OPTIONS
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
|
||||||
|
10 * 1024). Units are K, M and G (powers of 1024).
|
||||||
|
|
||||||
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
The <DURATION> argument is an integer and an optional unit (e.g., 1s
|
||||||
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
|
||||||
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
(hours, minutes, seconds and milliseconds, respectively). If a unit
|
||||||
|
|||||||
29
doc/nghttp.1
29
doc/nghttp.1
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "NGHTTP" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
|
.TH "NGHTTP" "1" "Jan 25, 2017" "1.19.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttp \- HTTP/2 client
|
nghttp \- HTTP/2 client
|
||||||
.
|
.
|
||||||
@@ -142,10 +142,13 @@ HTTP upgrade request is performed with OPTIONS method.
|
|||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
.B \-p, \-\-weight=<WEIGHT>
|
.B \-p, \-\-weight=<WEIGHT>
|
||||||
Sets 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.
|
[1, 256], inclusive.
|
||||||
.sp
|
|
||||||
Default: \fB16\fP
|
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
@@ -167,6 +170,14 @@ multiple header table size change.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-encoder\-header\-table\-size=<SIZE>
|
||||||
|
Specify encoder header table size. The decoder (server)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which server specified.
|
||||||
|
.UNINDENT
|
||||||
|
.INDENT 0.0
|
||||||
|
.TP
|
||||||
.B \-b, \-\-padding=<N>
|
.B \-b, \-\-padding=<N>
|
||||||
Add at most <N> bytes to a frame payload as padding.
|
Add at most <N> bytes to a frame payload as padding.
|
||||||
Specify 0 to disable padding.
|
Specify 0 to disable padding.
|
||||||
@@ -217,6 +228,14 @@ accepts.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.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
|
.B \-\-version
|
||||||
Display version information and exit.
|
Display version information and exit.
|
||||||
.UNINDENT
|
.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.
|
on stream 11 with the weight 2.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
\fInghttpd(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
\fBnghttpd(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -107,11 +107,14 @@ OPTIONS
|
|||||||
|
|
||||||
.. option:: -p, --weight=<WEIGHT>
|
.. 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.
|
[1, 256], inclusive.
|
||||||
|
|
||||||
Default: ``16``
|
|
||||||
|
|
||||||
.. option:: -M, --peer-max-concurrent-streams=<N>
|
.. option:: -M, --peer-max-concurrent-streams=<N>
|
||||||
|
|
||||||
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
|
Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||||
@@ -128,6 +131,13 @@ OPTIONS
|
|||||||
frame payload before the last value, to simulate
|
frame payload before the last value, to simulate
|
||||||
multiple header table size change.
|
multiple header table size change.
|
||||||
|
|
||||||
|
.. option:: --encoder-header-table-size=<SIZE>
|
||||||
|
|
||||||
|
Specify encoder header table size. The decoder (server)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which server specified.
|
||||||
|
|
||||||
.. option:: -b, --padding=<N>
|
.. option:: -b, --padding=<N>
|
||||||
|
|
||||||
Add at most <N> bytes to a frame payload as padding.
|
Add at most <N> bytes to a frame payload as padding.
|
||||||
@@ -169,6 +179,13 @@ OPTIONS
|
|||||||
The number of concurrent pushed streams this client
|
The number of concurrent pushed streams this client
|
||||||
accepts.
|
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
|
.. option:: --version
|
||||||
|
|
||||||
Display version information and exit.
|
Display version information and exit.
|
||||||
@@ -201,7 +218,9 @@ implementation.
|
|||||||
|
|
||||||
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
||||||
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
||||||
tree::
|
tree:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
+-----+
|
+-----+
|
||||||
|id=0 |
|
|id=0 |
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ implementation.
|
|||||||
|
|
||||||
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
When connection is established, nghttp sends 5 PRIORITY frames to idle
|
||||||
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
streams 3, 5, 7, 9 and 11 to create "anchor" nodes in dependency
|
||||||
tree::
|
tree:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
+-----+
|
+-----+
|
||||||
|id=0 |
|
|id=0 |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
.\" Man page generated from reStructuredText.
|
.\" Man page generated from reStructuredText.
|
||||||
.
|
.
|
||||||
.TH "NGHTTPD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
|
.TH "NGHTTPD" "1" "Jan 25, 2017" "1.19.0" "nghttp2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
nghttpd \- HTTP/2 server
|
nghttpd \- HTTP/2 server
|
||||||
.
|
.
|
||||||
@@ -99,6 +99,14 @@ Specify decoder header table size.
|
|||||||
.UNINDENT
|
.UNINDENT
|
||||||
.INDENT 0.0
|
.INDENT 0.0
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-encoder\-header\-table\-size=<SIZE>
|
||||||
|
Specify encoder header table size. The decoder (client)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which client specified.
|
||||||
|
.UNINDENT
|
||||||
|
.INDENT 0.0
|
||||||
|
.TP
|
||||||
.B \-\-color
|
.B \-\-color
|
||||||
Force colored log output.
|
Force colored log output.
|
||||||
.UNINDENT
|
.UNINDENT
|
||||||
@@ -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).
|
10 * 1024). Units are K, M and G (powers of 1024).
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.sp
|
.sp
|
||||||
\fInghttp(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
|
\fBnghttp(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
Tatsuhiro Tsujikawa
|
Tatsuhiro Tsujikawa
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ OPTIONS
|
|||||||
|
|
||||||
Specify decoder header table size.
|
Specify decoder header table size.
|
||||||
|
|
||||||
|
.. option:: --encoder-header-table-size=<SIZE>
|
||||||
|
|
||||||
|
Specify encoder header table size. The decoder (client)
|
||||||
|
specifies the maximum dynamic table size it accepts.
|
||||||
|
Then the negotiated dynamic table size is the minimum of
|
||||||
|
this option value and the value which client specified.
|
||||||
|
|
||||||
.. option:: --color
|
.. option:: --color
|
||||||
|
|
||||||
Force colored log output.
|
Force colored log output.
|
||||||
|
|||||||
880
doc/nghttpx.1
880
doc/nghttpx.1
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
163
doc/nghttpx.h2r
163
doc/nghttpx.h2r
@@ -41,6 +41,33 @@ FILES
|
|||||||
:option:`--conf` option cannot be used in the configuration file and
|
:option:`--conf` option cannot be used in the configuration file and
|
||||||
will be ignored if specified.
|
will be ignored if specified.
|
||||||
|
|
||||||
|
Error log
|
||||||
|
Error log is written to stderr by default. It can be configured
|
||||||
|
using :option:`--errorlog-file`. The format of log message is as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
<datetime> <master-pid> <current-pid> <thread-id> <level> (<filename>:<line>) <msg>
|
||||||
|
|
||||||
|
<datetime>
|
||||||
|
It is a conbination of date and time when the log is written. It
|
||||||
|
is in ISO 8601 format.
|
||||||
|
|
||||||
|
<master-pid>
|
||||||
|
It is a master process ID.
|
||||||
|
|
||||||
|
<current-pid>
|
||||||
|
It is a process ID which writes this log.
|
||||||
|
|
||||||
|
<thread-id>
|
||||||
|
It is a thread ID which writes this log. It would be unique
|
||||||
|
within <current-pid>.
|
||||||
|
|
||||||
|
<filename> and <line>
|
||||||
|
They are source file name, and line number which produce this log.
|
||||||
|
|
||||||
|
<msg>
|
||||||
|
It is a log message body.
|
||||||
|
|
||||||
SIGNALS
|
SIGNALS
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -49,6 +76,9 @@ SIGQUIT
|
|||||||
accepting connection. After all connections are handled, nghttpx
|
accepting connection. After all connections are handled, nghttpx
|
||||||
exits.
|
exits.
|
||||||
|
|
||||||
|
SIGHUP
|
||||||
|
Reload configuration file given in :option:`--conf`.
|
||||||
|
|
||||||
SIGUSR1
|
SIGUSR1
|
||||||
Reopen log files.
|
Reopen log files.
|
||||||
|
|
||||||
@@ -56,7 +86,11 @@ SIGUSR2
|
|||||||
Fork and execute nghttpx. It will execute the binary in the same
|
Fork and execute nghttpx. It will execute the binary in the same
|
||||||
path with same command-line arguments and environment variables.
|
path with same command-line arguments and environment variables.
|
||||||
After new process comes up, sending SIGQUIT to the original process
|
After new process comes up, sending SIGQUIT to the original process
|
||||||
to perform hot swapping.
|
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::
|
.. note::
|
||||||
|
|
||||||
@@ -85,7 +119,7 @@ backend server and extracts URI-reference with parameter
|
|||||||
and pushes those URIs to the frontend client. Here is a sample Link
|
and pushes those URIs to the frontend client. Here is a sample Link
|
||||||
header field to initiate server push:
|
header field to initiate server push:
|
||||||
|
|
||||||
.. code-block:: http
|
.. code-block:: text
|
||||||
|
|
||||||
Link: </fonts/font.woff>; rel=preload
|
Link: </fonts/font.woff>; rel=preload
|
||||||
Link: </css/theme.css>; rel=preload
|
Link: </css/theme.css>; rel=preload
|
||||||
@@ -98,12 +132,12 @@ Currently, the following restriction is applied for server push:
|
|||||||
This limitation may be loosened in the future release.
|
This limitation may be loosened in the future release.
|
||||||
|
|
||||||
nghttpx also supports server push if both frontend and backend are
|
nghttpx also supports server push if both frontend and backend are
|
||||||
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
|
HTTP/2 in default mode. In this case, in addition to server push via
|
||||||
In this case, in addition to server push via Link header field, server
|
Link header field, server push from backend is forwarded to frontend
|
||||||
push from backend is relayed to frontend HTTP/2 session.
|
HTTP/2 session.
|
||||||
|
|
||||||
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
|
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
|
||||||
:option:`--client-proxy` is used.
|
used.
|
||||||
|
|
||||||
UNIX DOMAIN SOCKET
|
UNIX DOMAIN SOCKET
|
||||||
------------------
|
------------------
|
||||||
@@ -150,6 +184,10 @@ insert serialized session data to memcached with
|
|||||||
as a memcached entry key, with expiry time 12 hours. Session timeout
|
as a memcached entry key, with expiry time 12 hours. Session timeout
|
||||||
is set to 12 hours.
|
is set to 12 hours.
|
||||||
|
|
||||||
|
By default, connections to memcached server are not encrypted. To
|
||||||
|
enable encryption, use ``tls`` keyword in
|
||||||
|
:option:`--tls-session-cache-memcached` option.
|
||||||
|
|
||||||
TLS SESSION TICKET RESUMPTION
|
TLS SESSION TICKET RESUMPTION
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@@ -189,11 +227,33 @@ used, LEN must be 48. If
|
|||||||
keys. The key appeared first is used as encryption key. All the
|
keys. The key appeared first is used as encryption key. All the
|
||||||
remaining keys are used as decryption only.
|
remaining keys are used as decryption only.
|
||||||
|
|
||||||
|
By default, connections to memcached server are not encrypted. To
|
||||||
|
enable encryption, use ``tls`` keyword in
|
||||||
|
:option:`--tls-ticket-key-memcached` option.
|
||||||
|
|
||||||
If :option:`--tls-ticket-key-file` is given, encryption key is read
|
If :option:`--tls-ticket-key-file` is given, encryption key is read
|
||||||
from the given file. In this case, nghttpx does not rotate key
|
from the given file. In this case, nghttpx does not rotate key
|
||||||
automatically. To rotate key, one has to restart nghttpx (see
|
automatically. To rotate key, one has to restart nghttpx (see
|
||||||
SIGNALS).
|
SIGNALS).
|
||||||
|
|
||||||
|
CERTIFICATE TRANSPARENCY
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
nghttpx supports TLS ``signed_certificate_timestamp`` extension (`RFC
|
||||||
|
6962 <https://tools.ietf.org/html/rfc6962>`_). The relevant options
|
||||||
|
are :option:`--tls-sct-dir` and ``sct-dir`` parameter in
|
||||||
|
:option:`--subcert`. They takes a directory, and nghttpx reads all
|
||||||
|
files whose extension is ``.sct`` under the directory. The ``*.sct``
|
||||||
|
files are encoded as ``SignedCertificateTimestamp`` struct described
|
||||||
|
in `section 3.2 of RFC 69662
|
||||||
|
<https://tools.ietf.org/html/rfc6962#section-3.2>`_. This format is
|
||||||
|
the same one used by `nginx-ct
|
||||||
|
<https://github.com/grahamedgecombe/nginx-ct>`_ and `mod_ssl_ct
|
||||||
|
<https://httpd.apache.org/docs/trunk/mod/mod_ssl_ct.html>`_.
|
||||||
|
`ct-submit <https://github.com/grahamedgecombe/ct-submit>`_ can be
|
||||||
|
used to submit certificates to log servers, and obtain the
|
||||||
|
``SignedCertificateTimestamp`` struct which can be used with nghttpx.
|
||||||
|
|
||||||
MRUBY SCRIPTING
|
MRUBY SCRIPTING
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
@@ -257,7 +317,28 @@ respectively.
|
|||||||
|
|
||||||
.. rb:attr_reader:: remote_addr
|
.. 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
|
.. rb:class:: Request
|
||||||
|
|
||||||
@@ -293,7 +374,13 @@ respectively.
|
|||||||
|
|
||||||
Request path, including query component (i.e., /index.html).
|
Request path, including query component (i.e., /index.html).
|
||||||
On assignment, copy of given value is assigned. The path does
|
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
|
.. rb:attr_reader:: headers
|
||||||
|
|
||||||
@@ -320,7 +407,7 @@ respectively.
|
|||||||
|
|
||||||
Clear all existing request header fields.
|
Clear all existing request header fields.
|
||||||
|
|
||||||
.. rb:method:: push uri
|
.. rb:method:: push(uri)
|
||||||
|
|
||||||
Initiate to push resource identified by *uri*. Only HTTP/2
|
Initiate to push resource identified by *uri*. Only HTTP/2
|
||||||
protocol supports this feature. For the other protocols, this
|
protocol supports this feature. For the other protocols, this
|
||||||
@@ -431,6 +518,62 @@ addresses:
|
|||||||
|
|
||||||
App.new
|
App.new
|
||||||
|
|
||||||
|
API ENDPOINTS
|
||||||
|
-------------
|
||||||
|
|
||||||
|
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
|
||||||
|
default, API endpoint is disabled. To enable it, add a dedicated
|
||||||
|
frontend for API using :option:`--frontend` option with "api"
|
||||||
|
parameter. All requests which come from this frontend address, will
|
||||||
|
be treated as API request.
|
||||||
|
|
||||||
|
The response is normally JSON dictionary, and at least includes the
|
||||||
|
following keys:
|
||||||
|
|
||||||
|
status
|
||||||
|
The status of the request processing. The following values are
|
||||||
|
defined:
|
||||||
|
|
||||||
|
Success
|
||||||
|
The request was successful.
|
||||||
|
|
||||||
|
Failure
|
||||||
|
The request was failed. No change has been made.
|
||||||
|
|
||||||
|
code
|
||||||
|
HTTP status code
|
||||||
|
|
||||||
|
We wrote "normally", since nghttpx may return ordinal HTML response in
|
||||||
|
some cases where the error has occurred before reaching API endpoint
|
||||||
|
(e.g., header field is too large).
|
||||||
|
|
||||||
|
The following section describes available API endpoints.
|
||||||
|
|
||||||
|
POST /api/v1beta1/backendconfig
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This API replaces the current backend server settings with the
|
||||||
|
requested ones. The request method should be POST, but PUT is also
|
||||||
|
acceptable. The request body must be nghttpx configuration file
|
||||||
|
format. For configuration file format, see `FILES`_ section. The
|
||||||
|
line separator inside the request body must be single LF (0x0A).
|
||||||
|
Currently, only :option:`backend <--backend>` option is parsed, the
|
||||||
|
others are simply ignored. The semantics of this API is replace the
|
||||||
|
current backend with the backend options in request body. Describe
|
||||||
|
the desired set of backend severs, and nghttpx makes it happen. If
|
||||||
|
there is no :option:`backend <--backend>` option is found in request
|
||||||
|
body, the current set of backend is replaced with the :option:`backend
|
||||||
|
<--backend>` option's default value, which is ``127.0.0.1,80``.
|
||||||
|
|
||||||
|
The replacement is done instantly without breaking existing
|
||||||
|
connections or requests. It also avoids any process creation as is
|
||||||
|
the case with hot swapping with signals.
|
||||||
|
|
||||||
|
The one limitation is that only numeric IP address is allowd in
|
||||||
|
:option:`backend <--backend>` in request body unless "dns" parameter
|
||||||
|
is used while non numeric hostname is allowed in command-line or
|
||||||
|
configuration file is read using :option:`--conf`.
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,79 @@
|
|||||||
Programmers' Guide
|
Programmers' Guide
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
Architecture
|
||||||
|
------------
|
||||||
|
|
||||||
|
The most notable point in nghttp2 library architecture is it does not
|
||||||
|
perform any I/O. nghttp2 only performs HTTP/2 protocol stuff based on
|
||||||
|
input byte strings. It will calls callback functions set by
|
||||||
|
applications while processing input. The output of nghttp2 is just
|
||||||
|
byte string. An application is responsible to send these output to
|
||||||
|
the remote peer. The callback functions may be called while producing
|
||||||
|
output.
|
||||||
|
|
||||||
|
Not doing I/O makes embedding nghttp2 library in the existing code
|
||||||
|
base very easy. Usually, the existing applications have its own I/O
|
||||||
|
event loops. It is very hard to use nghttp2 in that situation if
|
||||||
|
nghttp2 does its own I/O. It also makes light weight language wrapper
|
||||||
|
for nghttp2 easy with the same reason. The down side is that an
|
||||||
|
application author has to write more code to write complete
|
||||||
|
application using nghttp2. This is especially true for simple "toy"
|
||||||
|
application. For the real applications, however, this is not the
|
||||||
|
case. This is because you probably want to support HTTP/1 which
|
||||||
|
nghttp2 does not provide, and to do that, you will need to write your
|
||||||
|
own HTTP/1 stack or use existing third-party library, and bind them
|
||||||
|
together with nghttp2 and I/O event loop. In this point, not
|
||||||
|
performing I/O in nghttp2 has more point than doing it.
|
||||||
|
|
||||||
|
The primary object that an application uses is :type:`nghttp2_session`
|
||||||
|
object, which is opaque struct and its details are hidden in order to
|
||||||
|
ensure the upgrading its internal architecture without breaking the
|
||||||
|
backward compatibility. An application can set callbacks to
|
||||||
|
:type:`nghttp2_session` object through the dedicated object and
|
||||||
|
functions, and it also interacts with it via many API function calls.
|
||||||
|
|
||||||
|
An application can create as many :type:`nghttp2_session` object as it
|
||||||
|
wants. But single :type:`nghttp2_session` object must be used by a
|
||||||
|
single thread at the same time. This is not so hard to enforce since
|
||||||
|
most event-based architecture applications use is single thread per
|
||||||
|
core, and handling one connection I/O is done by single thread.
|
||||||
|
|
||||||
|
To feed input to :type:`nghttp2_session` object, one can use
|
||||||
|
`nghttp2_session_recv()` or `nghttp2_session_mem_recv()` functions.
|
||||||
|
They behave similarly, and the difference is that
|
||||||
|
`nghttp2_session_recv()` will use :type:`nghttp2_read_callback` to get
|
||||||
|
input. On the other hand, `nghttp2_session_mem_recv()` will take
|
||||||
|
input as its parameter. If in doubt, use `nghttp2_session_mem_recv()`
|
||||||
|
since it is simpler, and could be faster since it avoids calling
|
||||||
|
callback function.
|
||||||
|
|
||||||
|
To get output from :type:`nghttp2_session` object, one can use
|
||||||
|
`nghttp2_session_send()` or `nghttp2_session_mem_send()`. The
|
||||||
|
difference between them is that the former uses
|
||||||
|
:type:`nghttp2_send_callback` to pass output to an application. On
|
||||||
|
the other hand, the latter returns the output to the caller. If in
|
||||||
|
doubt, use `nghttp2_session_mem_send()` since it is simpler. But
|
||||||
|
`nghttp2_session_send()` might be easier to use if the output buffer
|
||||||
|
an application has is fixed sized.
|
||||||
|
|
||||||
|
In general, an application should call `nghttp2_session_mem_send()`
|
||||||
|
when it gets input from underlying connection. Since there is great
|
||||||
|
chance to get something pushed into transmission queue while the call
|
||||||
|
of `nghttp2_session_mem_send()`, it is recommended to call
|
||||||
|
`nghttp2_session_mem_recv()` after `nghttp2_session_mem_send()`.
|
||||||
|
|
||||||
|
There is a question when we are safe to close HTTP/2 session without
|
||||||
|
waiting for the closure of underlying connection. We offer 2 API
|
||||||
|
calls for this: `nghttp2_session_want_read()` and
|
||||||
|
`nghttp2_session_want_write()`. If they both return 0, application
|
||||||
|
can destroy :type:`nghttp2_session`, and then close the underlying
|
||||||
|
connection. But make sure that the buffered output has been
|
||||||
|
transmitted to the peer before closing the connection when
|
||||||
|
`nghttp2_session_mem_send()` is used, since
|
||||||
|
`nghttp2_session_want_write()` does not take into account the
|
||||||
|
transmission of the buffered data outside of :type:`nghttp2_session`.
|
||||||
|
|
||||||
Includes
|
Includes
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -100,6 +173,308 @@ parsed as 64 bit signed integer. The sum of data length in the
|
|||||||
following DATA frames must match with the number in "Content-Length"
|
following DATA frames must match with the number in "Content-Length"
|
||||||
header field if it is present (this does not include padding bytes).
|
header field if it is present (this does not include padding bytes).
|
||||||
|
|
||||||
|
RFC 7230 says that server must not send "Content-Length" in any
|
||||||
|
response with 1xx, and 204 status code. It also says that
|
||||||
|
"Content-Length" is not allowed in any response with 200 status code
|
||||||
|
to a CONNECT request. nghttp2 enforces them as well.
|
||||||
|
|
||||||
Any deviation results in stream error of type PROTOCOL_ERROR. If
|
Any deviation results in stream error of type PROTOCOL_ERROR. If
|
||||||
error is found in PUSH_PROMISE frame, stream error is raised against
|
error is found in PUSH_PROMISE frame, stream error is raised against
|
||||||
promised stream.
|
promised stream.
|
||||||
|
|
||||||
|
The order of transmission of the HTTP/2 frames
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
This section describes the internals of libnghttp2 about the
|
||||||
|
scheduling of transmission of HTTP/2 frames. This is pretty much
|
||||||
|
internal stuff, so the details could change in the future versions of
|
||||||
|
the library.
|
||||||
|
|
||||||
|
libnghttp2 categorizes HTTP/2 frames into 4 categories: urgent,
|
||||||
|
regular, syn_stream, and data in the order of higher priority.
|
||||||
|
|
||||||
|
The urgent category includes PING and SETTINGS. They are sent with
|
||||||
|
highest priority. The order inside the category is FIFO.
|
||||||
|
|
||||||
|
The regular category includes frames other than PING, SETTINGS, DATA,
|
||||||
|
and HEADERS which does not create stream (which counts toward
|
||||||
|
concurrent stream limit). The order inside the category is FIFO.
|
||||||
|
|
||||||
|
The syn_stream category includes HEADERS frame which creates stream,
|
||||||
|
that counts toward the concurrent stream limit.
|
||||||
|
|
||||||
|
The data category includes DATA frame, and the scheduling among DATA
|
||||||
|
frames are determined by HTTP/2 dependency tree.
|
||||||
|
|
||||||
|
If the application wants to send frames in the specific order, and the
|
||||||
|
default transmission order does not fit, it has to schedule frames by
|
||||||
|
itself using the callbacks (e.g.,
|
||||||
|
:type:`nghttp2_on_frame_send_callback`).
|
||||||
|
|
||||||
|
RST_STREAM has special side effect when it is submitted by
|
||||||
|
`nghttp2_submit_rst_stream()`. It cancels all pending HEADERS and
|
||||||
|
DATA frames whose stream ID matches the one in the RST_STREAM frame.
|
||||||
|
This may cause unexpected behaviour for the application in some cases.
|
||||||
|
For example, suppose that application wants to send RST_STREAM after
|
||||||
|
sending response HEADERS and DATA. Because of the reason we mentioned
|
||||||
|
above, the following code does not work:
|
||||||
|
|
||||||
|
.. code-block:: c
|
||||||
|
|
||||||
|
nghttp2_submit_response(...)
|
||||||
|
nghttp2_submit_rst_stream(...)
|
||||||
|
|
||||||
|
RST_STREAM cancels HEADERS (and DATA), and just RST_STREAM is sent.
|
||||||
|
The correct way is use :type:`nghttp2_on_frame_send_callback`, and
|
||||||
|
after HEADERS and DATA frames are sent, issue
|
||||||
|
`nghttp2_submit_rst_stream()`. FYI,
|
||||||
|
:type:`nghttp2_on_frame_not_send_callback` tells you why frames are
|
||||||
|
not sent.
|
||||||
|
|
||||||
|
Implement user defined HTTP/2 non-critical extensions
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
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,24 +17,22 @@ installed in the following way. First, let us introduce
|
|||||||
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
|
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
|
||||||
for ``ANDROID_HOME``. For example, to install toolchain under
|
for ``ANDROID_HOME``. For example, to install toolchain under
|
||||||
``$ANDROID_HOME/toolchain``, do this in the the directory where NDK is
|
``$ANDROID_HOME/toolchain``, do this in the the directory where NDK is
|
||||||
unpacked::
|
unpacked:
|
||||||
|
|
||||||
$ build/tools/make-standalone-toolchain.sh \
|
.. code-block:: text
|
||||||
--install-dir=$ANDROID_HOME/toolchain \
|
|
||||||
--toolchain=arm-linux-androideabi-4.9 \
|
|
||||||
--llvm-version=3.5 \
|
|
||||||
--platform=android-16
|
|
||||||
|
|
||||||
The additional flag ``--system=linux-x86_64`` may be required if you
|
$ build/tools/make_standalone_toolchain.py \
|
||||||
are using x86_64 system.
|
--arch arm --api 16 --stl gnustl \
|
||||||
|
--install-dir $ANDROID_HOME/toolchain
|
||||||
|
|
||||||
The platform level is not important here because we don't use Android
|
The API level (``--api``) is not important here because we don't use
|
||||||
specific C/C++ API.
|
Android specific C/C++ API.
|
||||||
|
|
||||||
The dependent libraries, such as OpenSSL and libev should be built
|
The dependent libraries, such as OpenSSL, libev, and c-ares should be
|
||||||
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
|
built with the toolchain and installed under
|
||||||
We recommend to build these libraries as static library to make the
|
``$ANDROID_HOME/usr/local``. We recommend to build these libraries as
|
||||||
deployment easier. libxml2 support is currently disabled.
|
static library to make the deployment easier. libxml2 support is
|
||||||
|
currently disabled.
|
||||||
|
|
||||||
Although zlib comes with Android NDK, it seems not to be a part of
|
Although zlib comes with Android NDK, it seems not to be a part of
|
||||||
public API, so we have to built it for our own. That also provides us
|
public API, so we have to built it for our own. That also provides us
|
||||||
@@ -45,7 +43,9 @@ spdylay as well.
|
|||||||
|
|
||||||
Before running ``android-config`` and ``android-make``,
|
Before running ``android-config`` and ``android-make``,
|
||||||
``ANDROID_HOME`` environment variable must be set to point to the
|
``ANDROID_HOME`` environment variable must be set to point to the
|
||||||
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``::
|
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
|
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
|
||||||
|
|
||||||
@@ -97,6 +97,26 @@ patch, to configure libev, use the following script:
|
|||||||
|
|
||||||
And run ``make install`` to build and install.
|
And run ``make install`` to build and install.
|
||||||
|
|
||||||
|
To configure c-ares, use the following script:
|
||||||
|
|
||||||
|
.. code-block:: sh
|
||||||
|
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
if [ -z "$ANDROID_HOME" ]; then
|
||||||
|
echo 'No $ANDROID_HOME specified.'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
PREFIX=$ANDROID_HOME/usr/local
|
||||||
|
TOOLCHAIN=$ANDROID_HOME/toolchain
|
||||||
|
PATH=$TOOLCHAIN/bin:$PATH
|
||||||
|
|
||||||
|
./configure \
|
||||||
|
--host=arm-linux-androideabi \
|
||||||
|
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
||||||
|
--prefix=$PREFIX \
|
||||||
|
--disable-shared
|
||||||
|
|
||||||
To configure zlib, use the following script:
|
To configure zlib, use the following script:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
@@ -133,24 +153,24 @@ To configure spdylay, use the following script:
|
|||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
if [ -z "$ANDROID_HOME" ]; then
|
if [ -z "$ANDROID_HOME" ]; then
|
||||||
echo 'No $ANDROID_HOME specified.'
|
echo 'No $ANDROID_HOME specified.'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
PREFIX=$ANDROID_HOME/usr/local
|
PREFIX=$ANDROID_HOME/usr/local
|
||||||
TOOLCHAIN=$ANDROID_HOME/toolchain
|
TOOLCHAIN=$ANDROID_HOME/toolchain
|
||||||
PATH=$TOOLCHAIN/bin:$PATH
|
PATH=$TOOLCHAIN/bin:$PATH
|
||||||
|
|
||||||
./configure \
|
./configure \
|
||||||
--disable-shared \
|
--disable-shared \
|
||||||
--host=arm-linux-androideabi \
|
--host=arm-linux-androideabi \
|
||||||
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
|
||||||
--prefix=$PREFIX \
|
--prefix=$PREFIX \
|
||||||
--without-libxml2 \
|
--without-libxml2 \
|
||||||
--disable-src \
|
--disable-src \
|
||||||
--disable-examples \
|
--disable-examples \
|
||||||
CPPFLAGS="-I$PREFIX/include" \
|
CPPFLAGS="-I$PREFIX/include" \
|
||||||
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
|
||||||
LDFLAGS="-L$PREFIX/lib"
|
LDFLAGS="-L$PREFIX/lib"
|
||||||
|
|
||||||
And run ``make install`` to build and install.
|
And run ``make install`` to build and install.
|
||||||
|
|
||||||
@@ -159,6 +179,8 @@ then ``android-make`` to compile nghttp2 source files.
|
|||||||
|
|
||||||
If all went well, application binaries, such as nghttpx, are created
|
If all went well, application binaries, such as nghttpx, are created
|
||||||
under src directory. Strip debugging information from the binary
|
under src directory. Strip debugging information from the binary
|
||||||
using the following command::
|
using the following command:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ arm-linux-androideabi-strip src/nghttpx
|
$ arm-linux-androideabi-strip src/nghttpx
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ We use clang-format to format source code consistently. The
|
|||||||
clang-format configuration file .clang-format is located at the root
|
clang-format configuration file .clang-format is located at the root
|
||||||
directory. Since clang-format produces slightly different results
|
directory. Since clang-format produces slightly different results
|
||||||
between versions, we currently use clang-format which comes with
|
between versions, we currently use clang-format which comes with
|
||||||
clang-3.6.
|
clang-3.9.
|
||||||
|
|
||||||
To detect any violation to the coding style, we recommend to setup git
|
To detect any violation to the coding style, we recommend to setup git
|
||||||
pre-commit hook to check coding style of the changes you introduced.
|
pre-commit hook to check coding style of the changes you introduced.
|
||||||
@@ -35,7 +35,7 @@ The pre-commit file is located at the root directory. Copy it under
|
|||||||
.git/hooks and make sure that it is executable. The pre-commit script
|
.git/hooks and make sure that it is executable. The pre-commit script
|
||||||
uses clang-format-diff.py to detect any style errors. If it is not in
|
uses clang-format-diff.py to detect any style errors. If it is not in
|
||||||
your PATH or it exists under different name (e.g.,
|
your PATH or it exists under different name (e.g.,
|
||||||
clang-format-diff-3.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.
|
add git option ``clangformatdiff.binary`` to point to the script.
|
||||||
|
|
||||||
For emacs users, integrating clang-format to emacs is very easy.
|
For emacs users, integrating clang-format to emacs is very easy.
|
||||||
|
|||||||
@@ -1,33 +1,43 @@
|
|||||||
|
.. program:: h2load
|
||||||
|
|
||||||
h2load - HTTP/2 benchmarking tool - HOW-TO
|
h2load - HTTP/2 benchmarking tool - HOW-TO
|
||||||
==========================================
|
==========================================
|
||||||
|
|
||||||
h2load is benchmarking tool for HTTP/2 and HTTP/1.1. If built with
|
:doc:`h2load.1` is benchmarking tool for HTTP/2 and HTTP/1.1. If
|
||||||
spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it also
|
built with spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it
|
||||||
supports SPDY protocol. It supports SSL/TLS and clear text for all
|
also supports SPDY protocol. It supports SSL/TLS and clear text for
|
||||||
supported protocols.
|
all supported protocols.
|
||||||
|
|
||||||
|
Compiling from source
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
h2load is compiled alongside nghttp2 and requires that the
|
||||||
|
``--enable-apps`` flag is passed to ``./configure`` and `required
|
||||||
|
dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are
|
||||||
|
available during compilation. For details on compiling, see `nghttp2:
|
||||||
|
Building from Git
|
||||||
|
<https://github.com/nghttp2/nghttp2#building-from-git>`_.
|
||||||
|
|
||||||
Basic Usage
|
Basic Usage
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
In order to set benchmark settings, specify following 3 options.
|
In order to set benchmark settings, specify following 3 options.
|
||||||
|
|
||||||
``-n``
|
:option:`-n`
|
||||||
The number of total requests. Default: 1
|
The number of total requests. Default: 1
|
||||||
|
|
||||||
``-c``
|
:option:`-c`
|
||||||
The number of concurrent clients. Default: 1
|
The number of concurrent clients. Default: 1
|
||||||
|
|
||||||
``-m``
|
:option:`-m`
|
||||||
The max concurrent streams to issue per client.
|
The max concurrent streams to issue per client. Default: 1
|
||||||
If ``auto`` is given, the number of given URIs is used.
|
|
||||||
Default: ``auto``
|
|
||||||
|
|
||||||
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
|
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
|
||||||
You can set specific protocols in ``--npn-list`` option. For
|
You can set specific protocols in :option:`--npn-list` option. For
|
||||||
cleartext connection, the default protocol is HTTP/2. To change the
|
cleartext connection, the default protocol is HTTP/2. To change the
|
||||||
protocol in cleartext connection, use ``--no-tls-proto`` option. For
|
protocol in cleartext connection, use :option:`--no-tls-proto` option.
|
||||||
convenience, ``--h1`` option forces HTTP/1.1 for both cleartext and
|
For convenience, :option:`--h1` option forces HTTP/1.1 for both
|
||||||
SSL/TLS connections.
|
cleartext and SSL/TLS connections.
|
||||||
|
|
||||||
Here is a command-line to perform benchmark to URI \https://localhost
|
Here is a command-line to perform benchmark to URI \https://localhost
|
||||||
using total 100000 requests, 100 concurrent clients and 10 max
|
using total 100000 requests, 100 concurrent clients and 10 max
|
||||||
@@ -62,11 +72,11 @@ benchmarking results. By default, h2load uses large enough flow
|
|||||||
control window, which effectively disables flow control. To adjust
|
control window, which effectively disables flow control. To adjust
|
||||||
receiver flow control window size, there are following options:
|
receiver flow control window size, there are following options:
|
||||||
|
|
||||||
``-w``
|
:option:`-w`
|
||||||
Sets the stream level initial window size to
|
Sets the stream level initial window size to
|
||||||
(2**<N>)-1. For SPDY, 2**<N> is used instead.
|
(2**<N>)-1. For SPDY, 2**<N> is used instead.
|
||||||
|
|
||||||
``-W``
|
:option:`-W`
|
||||||
Sets the connection level initial window size to
|
Sets the connection level initial window size to
|
||||||
(2**<N>)-1. For SPDY, if <N> is strictly less
|
(2**<N>)-1. For SPDY, if <N> is strictly less
|
||||||
than 16, this option is ignored. Otherwise
|
than 16, this option is ignored. Otherwise
|
||||||
@@ -76,17 +86,17 @@ Multi-Threading
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
Sometimes benchmarking client itself becomes a bottleneck. To remedy
|
Sometimes benchmarking client itself becomes a bottleneck. To remedy
|
||||||
this situation, use ``-t`` option to specify the number of native
|
this situation, use :option:`-t` option to specify the number of native
|
||||||
thread to use.
|
thread to use.
|
||||||
|
|
||||||
``-t``
|
:option:`-t`
|
||||||
The number of native threads. Default: 1
|
The number of native threads. Default: 1
|
||||||
|
|
||||||
Selecting protocol for clear text
|
Selecting protocol for clear text
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
By default, if \http:// URI is given, HTTP/2 protocol is used. To
|
By default, if \http:// URI is given, HTTP/2 protocol is used. To
|
||||||
change the protocol to use for clear text, use ``-p`` option.
|
change the protocol to use for clear text, use :option:`-p` option.
|
||||||
|
|
||||||
Multiple URIs
|
Multiple URIs
|
||||||
-------------
|
-------------
|
||||||
@@ -97,3 +107,12 @@ If multiple URIs are specified, they are used in round robin manner.
|
|||||||
|
|
||||||
Please note that h2load uses scheme, host and port in the first URI
|
Please note that h2load uses scheme, host and port in the first URI
|
||||||
and ignores those parts in the rest of the URIs.
|
and ignores those parts in the rest of the URIs.
|
||||||
|
|
||||||
|
UNIX domain socket
|
||||||
|
------------------
|
||||||
|
|
||||||
|
To request against UNIX domain socket, use :option:`--base-uri`, and
|
||||||
|
specify ``unix:`` followed by the path to UNIX domain socket. For
|
||||||
|
example, if UNIX domain socket is ``/tmp/nghttpx.sock``, use
|
||||||
|
``--base-uri=unix:/tmp/nghttpx.sock``. h2load uses scheme, host and
|
||||||
|
port in the first URI in command-line or input file.
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ nghttp2 - HTTP/2 C Library
|
|||||||
|
|
||||||
This is an implementation of Hypertext Transfer Protocol version 2.
|
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:
|
Contents:
|
||||||
|
|
||||||
@@ -36,17 +37,18 @@ Contents:
|
|||||||
asio_http2_server.h
|
asio_http2_server.h
|
||||||
asio_http2_client.h
|
asio_http2_client.h
|
||||||
asio_http2.h
|
asio_http2.h
|
||||||
Source <https://github.com/tatsuhiro-t/nghttp2>
|
Source <https://github.com/nghttp2/nghttp2>
|
||||||
Issues <https://github.com/tatsuhiro-t/nghttp2/issues>
|
Issues <https://github.com/nghttp2/nghttp2/issues>
|
||||||
nghttp2.org <https://nghttp2.org/>
|
nghttp2.org <https://nghttp2.org/>
|
||||||
|
|
||||||
Released Versions
|
Released Versions
|
||||||
=================
|
=================
|
||||||
|
|
||||||
https://github.com/tatsuhiro-t/nghttp2/releases
|
https://github.com/nghttp2/nghttp2/releases
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
* HTTP/2 https://tools.ietf.org/html/rfc7540
|
* HTTP/2 https://tools.ietf.org/html/rfc7540
|
||||||
* HPACK https://tools.ietf.org/html/rfc7541
|
* HPACK https://tools.ietf.org/html/rfc7541
|
||||||
|
* HTTP Alternative Services https://tools.ietf.org/html/rfc7838
|
||||||
|
|||||||
@@ -1,79 +1,101 @@
|
|||||||
|
.. program:: nghttpx
|
||||||
|
|
||||||
nghttpx - HTTP/2 proxy - HOW-TO
|
nghttpx - HTTP/2 proxy - HOW-TO
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
nghttpx is a proxy translating protocols between HTTP/2 and other
|
:doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and
|
||||||
protocols (e.g., HTTP/1, SPDY). It operates in several modes and each
|
other protocols (e.g., HTTP/1, SPDY). It operates in several modes
|
||||||
mode may require additional programs to work with. This article
|
and each mode may require additional programs to work with. This
|
||||||
describes each operation mode and explains the intended use-cases. It
|
article describes each operation mode and explains the intended
|
||||||
also covers some useful options later.
|
use-cases. It also covers some useful options later.
|
||||||
|
|
||||||
Default mode
|
Default mode
|
||||||
------------
|
------------
|
||||||
|
|
||||||
If nghttpx is invoked without any ``-s``, ``-p`` and ``--client``, it
|
If nghttpx is invoked without :option:`--http2-proxy`, it operates in
|
||||||
operates in default mode. In this mode, nghttpx frontend listens for
|
default mode. In this mode, it works as reverse proxy (gateway) for
|
||||||
HTTP/2 requests and translates them to HTTP/1 requests. Thus it works
|
both HTTP/2 and HTTP/1 clients to backend servers. This is also known
|
||||||
as reverse proxy (gateway) for HTTP/2 clients to HTTP/1 web server.
|
as "HTTP/2 router". If nghttpx is linked with spdylay library and
|
||||||
This is also known as "HTTP/2 router". HTTP/1 requests are also
|
frontend connection is SSL/TLS, the frontend also supports SPDY
|
||||||
supported in frontend as a fallback. If nghttpx is linked with
|
protocol.
|
||||||
spdylay library and frontend connection is SSL/TLS, the frontend also
|
|
||||||
supports SPDY protocol.
|
|
||||||
|
|
||||||
By default, this mode's frontend connection is encrypted using
|
By default, frontend connection is encrypted using SSL/TLS. So
|
||||||
SSL/TLS. So server's private key and certificate must be supplied to
|
server's private key and certificate must be supplied to the command
|
||||||
the command line (or through configuration file). In this case, the
|
line (or through configuration file). In this case, the frontend
|
||||||
frontend protocol selection will be done via ALPN or NPN.
|
protocol selection will be done via ALPN or NPN.
|
||||||
|
|
||||||
With ``--frontend-no-tls`` option, user can turn off SSL/TLS in
|
To turn off encryption on frontend connection, use ``no-tls`` keyword
|
||||||
frontend connection. In this case, SPDY protocol is not available
|
in :option:`--frontend` option. In this case, SPDY protocol is not
|
||||||
even if spdylay library is liked to nghttpx. HTTP/2 and HTTP/1 are
|
available even if spdylay library is liked to nghttpx. HTTP/2 and
|
||||||
available on the frontend and a HTTP/1 connection can be upgraded to
|
HTTP/1 are available on the frontend, and an HTTP/1 connection can be
|
||||||
HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by sending
|
upgraded to HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by
|
||||||
HTTP/2 connection preface is also supported.
|
sending HTTP/2 connection preface is also supported.
|
||||||
|
|
||||||
By default, backend HTTP/1 connections are not encrypted. To enable
|
nghttpx can listen on multiple frontend addresses. This is achieved
|
||||||
TLS on HTTP/1 backend connections, use ``--backend-http1-tls`` option.
|
by using multiple :option:`--frontend` options. For each frontend
|
||||||
This applies to all mode whose backend connections are HTTP/1.
|
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
|
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
|
backend Web server is configured to listen to HTTP request at port
|
||||||
port 8080 in the same host, run nghttpx command-line like this::
|
8080 in the same host, run nghttpx command-line like this:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||||
|
|
||||||
Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
|
Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
|
||||||
example, you can send GET request to the server using nghttp::
|
example, you can send GET request to the server using nghttp:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ nghttp -nv https://localhost:8443/
|
$ nghttp -nv https://localhost:8443/
|
||||||
|
|
||||||
HTTP/2 proxy mode
|
HTTP/2 proxy mode
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
If nghttpx is invoked with ``-s`` option, it operates in HTTP/2 proxy
|
If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
|
||||||
mode. The supported protocols in frontend and backend connections are
|
:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
|
||||||
the same in `default mode`_. The difference is that this mode acts
|
protocols in frontend and backend connections are the same in `default
|
||||||
like forward proxy and assumes the backend is HTTP/1 proxy server
|
mode`_. The difference is that this mode acts like forward proxy and
|
||||||
(e.g., squid, traffic server). So HTTP/1 request must include
|
assumes the backend is HTTP proxy server (e.g., Squid, Apache Traffic
|
||||||
absolute URI in request line.
|
Server). HTTP/1 request must include absolute URI in request line.
|
||||||
|
|
||||||
By default, frontend connection is encrypted. So this mode is also
|
By default, frontend connection is encrypted. So this mode is also
|
||||||
called secure proxy. If nghttpx is linked with spdylay, it supports
|
called secure proxy. If nghttpx is linked with spdylay, it supports
|
||||||
SPDY protocols and it works as so called SPDY proxy.
|
SPDY protocols and it works as so called SPDY proxy.
|
||||||
|
|
||||||
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
|
To turn off encryption on frontend connection, use ``no-tls`` keyword
|
||||||
connection, so the connection gets insecure.
|
in :option:`--frontend` option.
|
||||||
|
|
||||||
The backend must be HTTP/1 proxy server. nghttpx supports multiple
|
The backend must be HTTP proxy server. nghttpx supports multiple
|
||||||
backend server addresses. It translates incoming requests to HTTP/1
|
backend server addresses. It translates incoming requests to HTTP
|
||||||
request to backend server. The backend server performs real proxy
|
request to backend server. The backend server performs real proxy
|
||||||
work for each request, for example, dispatching requests to the origin
|
work for each request, for example, dispatching requests to the origin
|
||||||
server and caching contents.
|
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
|
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
|
port 8443, and a backend HTTP proxy server is configured to listen to
|
||||||
to HTTP/1 request at port 8080 in the same host, run nghttpx
|
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
|
||||||
command-line like this::
|
like this:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
|
||||||
|
|
||||||
@@ -96,152 +118,78 @@ Chromium require valid certificate for secure proxy.
|
|||||||
For Firefox, open Preference window and select Advanced then click
|
For Firefox, open Preference window and select Advanced then click
|
||||||
Network tab. Clicking Connection Settings button will show the
|
Network tab. Clicking Connection Settings button will show the
|
||||||
dialog. Select "Automatic proxy configuration URL" and enter the path
|
dialog. Select "Automatic proxy configuration URL" and enter the path
|
||||||
to proxy.pac file, something like this::
|
to proxy.pac file, something like this:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
file:///path/to/proxy.pac
|
file:///path/to/proxy.pac
|
||||||
|
|
||||||
For Chromium, use following command-line::
|
For Chromium, use following command-line:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
|
||||||
|
|
||||||
As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
|
As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
|
||||||
requires to be configured as forward proxy. Here is the minimum
|
requires to be configured as forward proxy. Here is the minimum
|
||||||
configuration items to edit::
|
configuration items to edit:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
CONFIG proxy.config.reverse_proxy.enabled INT 0
|
CONFIG proxy.config.reverse_proxy.enabled INT 0
|
||||||
CONFIG proxy.config.url_remap.remap_required INT 0
|
CONFIG proxy.config.url_remap.remap_required INT 0
|
||||||
|
|
||||||
Consult Traffic server `documentation
|
Consult Traffic server `documentation
|
||||||
<https://docs.trafficserver.apache.org/en/latest/admin/forward-proxy.en.html>`_
|
<http://trafficserver.readthedocs.org/en/latest/admin-guide/configuration/transparent-forward-proxying.en.html>`_
|
||||||
to know how to configure traffic server as forward proxy and its
|
to know how to configure traffic server as forward proxy and its
|
||||||
security implications.
|
security implications.
|
||||||
|
|
||||||
Client mode
|
ALPN support
|
||||||
-----------
|
------------
|
||||||
|
|
||||||
If nghttpx is invoked with ``--client`` option, it operates in client
|
ALPN support requires OpenSSL >= 1.0.2.
|
||||||
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.
|
|
||||||
|
|
||||||
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
|
Disable frontend SSL/TLS
|
||||||
Upgrade. To disable SSL/TLS in backend connection, use
|
------------------------
|
||||||
``--backend-no-tls`` option.
|
|
||||||
|
|
||||||
By default, the number of backend HTTP/2 connections per worker
|
The frontend connections are encrypted with SSL/TLS by default. To
|
||||||
(thread) is determined by number of ``-b`` option. To adjust this
|
turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend`
|
||||||
value, use ``--backend-http2-connections-per-worker`` option.
|
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.,
|
Enable backend SSL/TLS
|
||||||
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::
|
|
||||||
|
|
||||||
$ nghttpx --client -f127.0.0.1,8080 -b127.0.0.1,80 --backend-no-tls
|
The backend connections are not encrypted by default. To enable
|
||||||
|
SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option.
|
||||||
|
|
||||||
.. note::
|
Enable SSL/TLS on memcached connection
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
You may need ``-k`` option if HTTP/2 server enables SSL/TLS and
|
By default, memcached connection is not encrypted. To enable
|
||||||
its certificate is self-signed. But please note that it is
|
encryption, use ``tls`` keyword in
|
||||||
insecure.
|
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
|
||||||
|
:option:`--tls-session-cache-memcached` for TLS session cache.
|
||||||
|
|
||||||
Then you can use curl to access HTTP/2 server via nghttpx::
|
Specifying additional server certificates
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
$ curl http://localhost:8080/
|
nghttpx accepts additional server private key and certificate pairs
|
||||||
|
using :option:`--subcert` option. It can be used multiple times.
|
||||||
Client proxy mode
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
If nghttpx is invoked with ``-p`` option, it operates in client proxy
|
|
||||||
mode. This mode behaves like `client mode`_, but it works like
|
|
||||||
forward proxy. So HTTP/1 request must include absolute URI in request
|
|
||||||
line.
|
|
||||||
|
|
||||||
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
|
|
||||||
Upgrade. To disable SSL/TLS in backend connection, use
|
|
||||||
``--backend-no-tls`` option.
|
|
||||||
|
|
||||||
By default, the number of backend HTTP/2 connections per worker
|
|
||||||
(thread) is determined by number of ``-b`` option. To adjust this
|
|
||||||
value, use ``--backend-http2-connections-per-worker`` option.
|
|
||||||
|
|
||||||
The backend server must be a HTTP/2 proxy. You can use nghttpx in
|
|
||||||
`HTTP/2 proxy mode`_ as backend server. The one use-case of this mode
|
|
||||||
is utilize existing HTTP/1 clients to test HTTP/2 connections between
|
|
||||||
2 proxies. The another use-case is use this mode to aggregate local
|
|
||||||
HTTP/1 connections to one HTTP/2 backend encrypted connection. This
|
|
||||||
makes HTTP/1 clients which does not support secure proxy can use
|
|
||||||
secure HTTP/2 proxy via nghttpx client mode.
|
|
||||||
|
|
||||||
Suppose that HTTP/2 proxy listens to port 8443, just like we saw in
|
|
||||||
`HTTP/2 proxy mode`_. To run nghttpx in client proxy mode to access
|
|
||||||
that server, invoke nghttpx like this::
|
|
||||||
|
|
||||||
$ nghttpx -p -f127.0.0.1,8080 -b127.0.0.1,8443
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
You may need ``-k`` option if HTTP/2 server's certificate is
|
|
||||||
self-signed. But please note that it is insecure.
|
|
||||||
|
|
||||||
Then you can use curl to issue HTTP request via HTTP/2 proxy::
|
|
||||||
|
|
||||||
$ curl --http-proxy=http://localhost:8080 http://www.google.com/
|
|
||||||
|
|
||||||
You can configure web browser to use localhost:8080 as forward
|
|
||||||
proxy.
|
|
||||||
|
|
||||||
HTTP/2 bridge mode
|
|
||||||
------------------
|
|
||||||
|
|
||||||
If nghttpx is invoked with ``--http2-bridge`` option, it operates in
|
|
||||||
HTTP/2 bridge mode. The supported protocols in frontend connections
|
|
||||||
are the same in `default mode`_. The protocol in backend is HTTP/2
|
|
||||||
only.
|
|
||||||
|
|
||||||
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
|
|
||||||
connection, so the connection gets insecure. To disable SSL/TLS in
|
|
||||||
backend connection, use ``--backend-no-tls`` option.
|
|
||||||
|
|
||||||
By default, the number of backend HTTP/2 connections per worker
|
|
||||||
(thread) is determined by number of ``-b`` option. To adjust this
|
|
||||||
value, use ``--backend-http2-connections-per-worker`` option.
|
|
||||||
|
|
||||||
The backend server is supporsed to be a HTTP/2 web server or HTTP/2
|
|
||||||
proxy. If backend server is HTTP/2 proxy, use
|
|
||||||
``--no-location-rewrite`` and ``--no-host-rewrite`` options to disable
|
|
||||||
rewriting location, host and :authority header field.
|
|
||||||
|
|
||||||
The use-case of this mode is aggregate the incoming connections to one
|
|
||||||
HTTP/2 connection. One backend HTTP/2 connection is created per
|
|
||||||
worker (thread).
|
|
||||||
|
|
||||||
Disable SSL/TLS
|
|
||||||
---------------
|
|
||||||
|
|
||||||
In `default mode`_, `HTTP/2 proxy mode`_ and `HTTP/2 bridge mode`_,
|
|
||||||
frontend connections are encrypted with SSL/TLS by default. To turn
|
|
||||||
off SSL/TLS, use ``--frontend-no-tls`` option. If this option is
|
|
||||||
used, the private key and certificate are not required to run nghttpx.
|
|
||||||
|
|
||||||
In `client mode`_, `client proxy mode`_ and `HTTP/2 bridge mode`_,
|
|
||||||
backend connections are encrypted with SSL/TLS by default. To turn
|
|
||||||
off SSL/TLS, use ``--backend-no-tls`` option.
|
|
||||||
|
|
||||||
Specifying additional CA certificate
|
Specifying additional CA certificate
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
By default, nghttpx tries to read CA certificate from system. But
|
By default, nghttpx tries to read CA certificate from system. But
|
||||||
depending on the system you use, this may fail or is not supported.
|
depending on the system you use, this may fail or is not supported.
|
||||||
To specify CA certificate manually, use ``--cacert`` option. The
|
To specify CA certificate manually, use :option:`--cacert` option.
|
||||||
specified file must be PEM format and can contain multiple
|
The specified file must be PEM format and can contain multiple
|
||||||
certificates.
|
certificates.
|
||||||
|
|
||||||
By default, nghttpx validates server's certificate. If you want to
|
By default, nghttpx validates server's certificate. If you want to
|
||||||
turn off this validation, knowing this is really insecure and what you
|
turn off this validation, knowing this is really insecure and what you
|
||||||
are doing, you can use ``-k`` option to disable certificate
|
are doing, you can use :option:`--insecure` option to disable
|
||||||
validation.
|
certificate validation.
|
||||||
|
|
||||||
Read/write rate limit
|
Read/write rate limit
|
||||||
---------------------
|
---------------------
|
||||||
@@ -250,9 +198,9 @@ nghttpx supports transfer rate limiting on frontend connections. You
|
|||||||
can do rate limit per frontend connection for reading and writing
|
can do rate limit per frontend connection for reading and writing
|
||||||
individually.
|
individually.
|
||||||
|
|
||||||
To perform rate limit for reading, use ``--read-rate`` and
|
To perform rate limit for reading, use :option:`--read-rate` and
|
||||||
``--read-burst`` options. For writing, use ``--write-rate`` and
|
:option:`--read-burst` options. For writing, use
|
||||||
``--write-burst``.
|
:option:`--write-rate` and :option:`--write-burst`.
|
||||||
|
|
||||||
Please note that rate limit is performed on top of TCP and nothing to
|
Please note that rate limit is performed on top of TCP and nothing to
|
||||||
do with HTTP/2 flow control.
|
do with HTTP/2 flow control.
|
||||||
@@ -263,17 +211,17 @@ Rewriting location header field
|
|||||||
nghttpx automatically rewrites location response header field if the
|
nghttpx automatically rewrites location response header field if the
|
||||||
following all conditions satisfy:
|
following all conditions satisfy:
|
||||||
|
|
||||||
* 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.
|
* URI in location header field includes non empty host component.
|
||||||
* host (without port) in URI in location header field must match the
|
* host (without port) in URI in location header field must match the
|
||||||
host appearing in :authority or host header field.
|
host appearing in ``:authority`` or ``host`` header field.
|
||||||
|
|
||||||
When rewrite happens, URI scheme and port are replaced with the ones
|
When rewrite happens, URI scheme is replaced with the ones used in
|
||||||
used in frontend, and host is replaced with which appears in
|
frontend, and authority is replaced with which appears in
|
||||||
:authority or host request header field. :authority header field has
|
``:authority``, or ``host`` request header field. ``:authority``
|
||||||
precedence. If the above conditions are not met with the host value
|
header field has precedence over ``host``.
|
||||||
in :authority header field, rewrite is retried with the value in host
|
|
||||||
header field.
|
|
||||||
|
|
||||||
Hot swapping
|
Hot swapping
|
||||||
------------
|
------------
|
||||||
@@ -288,20 +236,266 @@ all existing frontend connections are done, the current process will
|
|||||||
exit. At this point, only new nghttpx process exists and serves
|
exit. At this point, only new nghttpx process exists and serves
|
||||||
incoming requests.
|
incoming requests.
|
||||||
|
|
||||||
|
If you want to just reload configuration file without executing new
|
||||||
|
binary, send SIGHUP to nghttpx master process.
|
||||||
|
|
||||||
Re-opening log files
|
Re-opening log files
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
When rotating log files, it is desirable to re-open log files after
|
When rotating log files, it is desirable to re-open log files after
|
||||||
log rotation daemon renamed existing log files. To tell nghttpx to
|
log rotation daemon renamed existing log files. To tell nghttpx to
|
||||||
re-open log files, send USR1 signal to nghttpx process. It will
|
re-open log files, send USR1 signal to nghttpx process. It will
|
||||||
re-open files specified by ``--accesslog-file`` and
|
re-open files specified by :option:`--accesslog-file` and
|
||||||
``--errorlog-file`` options.
|
: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
|
Multiple backend addresses
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
nghttpx supports multiple backend addresses. To specify them, just
|
nghttpx supports multiple backend addresses. To specify them, just
|
||||||
use ``-b`` option repeatedly. For example, to use backend1:8080 and
|
use :option:`--backend` (or its shorthand :option:`-b`) option
|
||||||
backend2:8080, use command-line like this: ``-bbackend1,8080
|
repeatedly. For example, to use ``192.168.0.10:8080`` and
|
||||||
-bbackend2,8080``. For HTTP/2 backend, see also
|
``192.168.0.11:8080``, use command-line like this:
|
||||||
``--backend-http2-connections-per-worker`` option.
|
``-b192.168.0.10,8080 -b192.168.0.11,8080``. In configuration file,
|
||||||
|
this looks like:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=192.168.0.10,8080
|
||||||
|
backend=192.168.0.11,8008
|
||||||
|
|
||||||
|
nghttpx can route request to different backend according to request
|
||||||
|
host and path. For example, to route request destined to host
|
||||||
|
``doc.example.com`` to backend server ``docserv:3000``, you can write
|
||||||
|
like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=docserv,3000;doc.example.com/
|
||||||
|
|
||||||
|
When you write this option in command-line, you should enclose
|
||||||
|
argument with single or double quotes, since the character ``;`` has a
|
||||||
|
special meaning in shell.
|
||||||
|
|
||||||
|
To route, request to request path whose prefix is ``/foo`` to backend
|
||||||
|
server ``[::1]:8080``, you can write like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=::1,8080;/foo
|
||||||
|
|
||||||
|
Of course, you can specify both host and request path at the same
|
||||||
|
time:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=192.168.0.10,8080;example.com/foo
|
||||||
|
|
||||||
|
We can use ``*`` in the left most position of host to achieve wildcard
|
||||||
|
suffix match. If ``*`` is the left most character, then the remaining
|
||||||
|
string should match the request host suffix. ``*`` must match at
|
||||||
|
least one character. For example, ``*.example.com`` matches
|
||||||
|
``www.example.com`` and ``dev.example.com``, and does not match
|
||||||
|
``example.com`` and ``nghttp2.org``. The exact match (without ``*``)
|
||||||
|
always takes precedence over wildcard match.
|
||||||
|
|
||||||
|
One important thing you have to remember is that we have to specify
|
||||||
|
default routing pattern for so called "catch all" pattern. To write
|
||||||
|
"catch all" pattern, just specify backend server address, without
|
||||||
|
pattern.
|
||||||
|
|
||||||
|
Usually, host is the value of ``Host`` header field. In HTTP/2, the
|
||||||
|
value of ``:authority`` pseudo header field is used.
|
||||||
|
|
||||||
|
When you write multiple backend addresses sharing the same routing
|
||||||
|
pattern, they are used as load balancing. For example, to use 2
|
||||||
|
servers ``serv1:3000`` and ``serv2:3000`` for request host
|
||||||
|
``example.com`` and path ``/myservice``, you can write like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=serv1,3000;example.com/myservice
|
||||||
|
backend=serv2,3000;example.com/myservice
|
||||||
|
|
||||||
|
You can also specify backend application protocol in
|
||||||
|
:option:`--backend` option using ``proto`` keyword after pattern.
|
||||||
|
Utilizing this allows ngttpx to route certain request to HTTP/2, other
|
||||||
|
requests to HTTP/1. For example, to route requests to ``/ws/`` in
|
||||||
|
backend HTTP/1.1 connection, and use backend HTTP/2 for other
|
||||||
|
requests, do this:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=serv1,3000;/;proto=h2
|
||||||
|
backend=serv1,3000;/ws/;proto=http/1.1
|
||||||
|
|
||||||
|
The default backend protocol is HTTP/1.1.
|
||||||
|
|
||||||
|
TLS can be enabled per pattern basis:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=serv1,8443;/;proto=h2;tls
|
||||||
|
backend=serv2,8080;/ws/;proto=http/1.1
|
||||||
|
|
||||||
|
In the above case, connection to serv1 will be encrypted by TLS. On
|
||||||
|
the other hand, connection to serv2 will not be encrypted by TLS.
|
||||||
|
|
||||||
|
Dynamic hostname lookup
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
By default, nghttpx performs backend hostname lookup at start up, or
|
||||||
|
configuration reload, and keeps using them in its entire session. To
|
||||||
|
make nghttpx perform hostname lookup dynamically, use ``dns``
|
||||||
|
parameter in :option:`--backend` option, like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
backend=foo.example.com;;dns
|
||||||
|
|
||||||
|
nghttpx will cache resolved addresses for certain period of time. To
|
||||||
|
change this cache period, use :option:`--dns-cache-timeout`.
|
||||||
|
|
||||||
|
Enable PROXY protocol
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
PROXY protocol can be enabled per frontend. In order to enable PROXY
|
||||||
|
protocol, use ``proxyproto`` parameter in :option:`--frontend` option,
|
||||||
|
like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
frontend=*,443;proxyproto
|
||||||
|
|
||||||
|
PSK cipher suites
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
nghttpx supports pre-shared key (PSK) cipher suites for both frontend
|
||||||
|
and backend TLS connections. For frontend connection, use
|
||||||
|
:option:`--psk-secrets` option to specify a file which contains PSK
|
||||||
|
identity and secrets. The format of the file is
|
||||||
|
``<identity>:<hex-secret>``, where ``<identity>`` is PSK identity, and
|
||||||
|
``<hex-secret>`` is PSK secret in hex, like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
client1:9567800e065e078085c241d54a01c6c3f24b3bab71a606600f4c6ad2c134f3b9
|
||||||
|
client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99
|
||||||
|
|
||||||
|
nghttpx server accepts any of the identity and secret pairs in the
|
||||||
|
file. The default cipher suite list does not contain PSK cipher
|
||||||
|
suites. In order to use PSK, PSK cipher suite must be enabled by
|
||||||
|
using :option:`--ciphers` option. The desired PSK cipher suite may be
|
||||||
|
listed in `HTTP/2 cipher black list
|
||||||
|
<https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use
|
||||||
|
such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
|
||||||
|
using :option:`--no-http2-cipher-black-list` option. But you should
|
||||||
|
understand its implications.
|
||||||
|
|
||||||
|
At the time of writing, even if only PSK cipher suites are specified
|
||||||
|
in :option:`--ciphers` option, certificate and private key are still
|
||||||
|
required.
|
||||||
|
|
||||||
|
For backend connection, use :option:`--client-psk-secrets` option to
|
||||||
|
specify a file which contains single PSK identity and secret. The
|
||||||
|
format is the same as the file used by :option:`--psk-secrets`
|
||||||
|
described above, but only first identity and secret pair is solely
|
||||||
|
used, like so:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
client2:b1376c3f8f6dcf7c886c5bdcceecd1e6f1d708622b6ddd21bda26ebd0c0bca99
|
||||||
|
|
||||||
|
The default cipher suite list does not contain PSK cipher suites. In
|
||||||
|
order to use PSK, PSK cipher suite must be enabled by using
|
||||||
|
:option:`--client-ciphers` option. The desired PSK cipher suite may
|
||||||
|
be listed in `HTTP/2 cipher black list
|
||||||
|
<https://tools.ietf.org/html/rfc7540#appendix-A>`_. In order to use
|
||||||
|
such PSK cipher suite with HTTP/2, disable HTTP/2 cipher black list by
|
||||||
|
using :option:`--client-no-http2-cipher-black-list` option. But you
|
||||||
|
should understand its implications.
|
||||||
|
|
||||||
|
Migration from nghttpx v1.18.x or earlier
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
As of nghttpx v1.19.0, :option:`--ciphers` option only changes cipher
|
||||||
|
list for frontend TLS connection. In order to change cipher list for
|
||||||
|
backend connection, use :option:`--client-ciphers` option.
|
||||||
|
|
||||||
|
Similarly, :option:`--no-http2-cipher-black-list` option only disables
|
||||||
|
HTTP/2 cipher black list for frontend connection. In order to disable
|
||||||
|
HTTP/2 cipher black list for backend connection, use
|
||||||
|
:option:`--client-no-http2-cipher-black-list` option.
|
||||||
|
|
||||||
|
``--accept-proxy-protocol`` option was deprecated. Instead, use
|
||||||
|
``proxyproto`` parameter in :option:`--frontend` option to enable
|
||||||
|
PROXY protocol support per frontend.
|
||||||
|
|
||||||
|
Migration from nghttpx v1.8.0 or earlier
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
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
|
determined by configure script. If the detected Python version is not
|
||||||
what you expect, specify a path to Python executable in ``PYTHON``
|
what you expect, specify a path to Python executable in ``PYTHON``
|
||||||
variable as an argument to configure script (e.g., ``./configure
|
variable as an argument to configure script (e.g., ``./configure
|
||||||
PYTHON=/usr/bin/python3.4``).
|
PYTHON=/usr/bin/python3.5``).
|
||||||
|
|
||||||
HPACK API
|
HPACK API
|
||||||
---------
|
---------
|
||||||
@@ -136,13 +136,15 @@ HTTP/2 servers
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
We use :py:mod:`asyncio` for HTTP/2 server classes. Therefore,
|
We use :py:mod:`asyncio` for HTTP/2 server classes, and ALPN.
|
||||||
Python 3.4 or later is required to use these objects. To
|
Therefore, Python 3.5 or later is required to use these objects.
|
||||||
explicitly configure nghttp2 build to use Python 3.4, specify the
|
To explicitly configure nghttp2 build to use Python 3.5, specify
|
||||||
``PYTHON`` variable to the path to Python 3.4 executable when
|
the ``PYTHON`` variable to the path to Python 3.5 executable when
|
||||||
invoking configure script like this::
|
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)
|
.. 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.
|
the archive or repository.
|
||||||
|
|
||||||
This simple client takes a single HTTPS URI and retrieves the resource
|
This simple client takes a single HTTPS URI and retrieves the resource
|
||||||
at the URI. The synopsis is::
|
at the URI. The synopsis is:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ libevent-client HTTPS_URI
|
$ libevent-client HTTPS_URI
|
||||||
|
|
||||||
@@ -31,6 +33,17 @@ protocol the library supports::
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
If you are following TLS related RFC, you know that NPN is not the
|
||||||
|
standardized way to negotiate HTTP/2. NPN itself is not event
|
||||||
|
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
|
||||||
|
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
|
||||||
|
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
|
||||||
|
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
|
||||||
|
ALPN support depending on OpenSSL version. OpenSSL's ALPN
|
||||||
|
implementation does not require callback function like the above. But
|
||||||
|
we have to instruct OpenSSL SSL_CTX to use ALPN, which we'll talk
|
||||||
|
about soon.
|
||||||
|
|
||||||
The callback is added to the SSL_CTX object using
|
The callback is added to the SSL_CTX object using
|
||||||
``SSL_CTX_set_next_proto_select_cb()``::
|
``SSL_CTX_set_next_proto_select_cb()``::
|
||||||
|
|
||||||
@@ -46,9 +59,18 @@ The callback is added to the SSL_CTX object using
|
|||||||
SSL_OP_NO_COMPRESSION |
|
SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Here we see ``SSL_CTX_get_alpn_protos()`` function call. We instructs
|
||||||
|
OpenSSL to notify the server that we support h2, ALPN identifier for
|
||||||
|
HTTP/2.
|
||||||
|
|
||||||
The example client defines a couple of structs:
|
The example client defines a couple of structs:
|
||||||
|
|
||||||
We define and use a ``http2_session_data`` structure to store data
|
We define and use a ``http2_session_data`` structure to store data
|
||||||
@@ -124,7 +146,27 @@ underlying network socket::
|
|||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
int fd = bufferevent_getfd(bev);
|
int fd = bufferevent_getfd(bev);
|
||||||
int val = 1;
|
int val = 1;
|
||||||
|
const unsigned char *alpn = NULL;
|
||||||
|
unsigned int alpnlen = 0;
|
||||||
|
SSL *ssl;
|
||||||
|
|
||||||
fprintf(stderr, "Connected\n");
|
fprintf(stderr, "Connected\n");
|
||||||
|
|
||||||
|
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||||
|
|
||||||
|
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
if (alpn == NULL) {
|
||||||
|
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||||
|
fprintf(stderr, "h2 is not negotiated\n");
|
||||||
|
delete_http2_session_data(session_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
send_client_connection_header(session_data);
|
send_client_connection_header(session_data);
|
||||||
@@ -144,6 +186,9 @@ underlying network socket::
|
|||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Here we validate that HTTP/2 is negotiated, and if not, drop
|
||||||
|
connection.
|
||||||
|
|
||||||
For ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and ``BEV_EVENT_TIMEOUT``
|
For ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and ``BEV_EVENT_TIMEOUT``
|
||||||
events, we just simply tear down the connection.
|
events, we just simply tear down the connection.
|
||||||
|
|
||||||
|
|||||||
@@ -78,15 +78,16 @@ header data. To initialize the object, use
|
|||||||
|
|
||||||
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
|
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
|
||||||
|
|
||||||
To inflate header data, use `nghttp2_hd_inflate_hd()`::
|
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
|
||||||
|
|
||||||
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
|
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
||||||
nghttp2_nv *nv_out, int *inflate_flags,
|
nghttp2_nv *nv_out, int *inflate_flags,
|
||||||
uint8_t *in, size_t inlen, int in_final);
|
const uint8_t *in, size_t inlen,
|
||||||
|
int in_final);
|
||||||
|
|
||||||
`nghttp2_hd_inflate_hd()` reads a stream of bytes and outputs a single
|
`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a
|
||||||
header field at a time. Multiple calls are normally required to read a
|
single header field at a time. Multiple calls are normally required to
|
||||||
full stream of bytes and output all of the header fields.
|
read a full stream of bytes and output all of the header fields.
|
||||||
|
|
||||||
The *inflater* is the inflater object initialized above. The *nv_out*
|
The *inflater* is the inflater object initialized above. The *nv_out*
|
||||||
is a pointer to a :type:`nghttp2_nv` into which one header field may
|
is a pointer to a :type:`nghttp2_nv` into which one header field may
|
||||||
@@ -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
|
not set, it indicates that all given data was processed. The caller
|
||||||
is required to pass additional data.
|
is required to pass additional data.
|
||||||
|
|
||||||
It is important to note that the function may produce one or more
|
Example usage of `nghttp2_hd_inflate_hd2()` is shown in the
|
||||||
header fields even if *inlen* is 0 when *in_final* is nonzero, due to
|
|
||||||
differential encoding.
|
|
||||||
|
|
||||||
Example usage of `nghttp2_hd_inflate_hd()` is shown in the
|
|
||||||
`inflate_header_block()` function in `deflate.c`_.
|
`inflate_header_block()` function in `deflate.c`_.
|
||||||
|
|
||||||
Finally, to delete a :type:`nghttp2_hd_inflater` object, use
|
Finally, to delete a :type:`nghttp2_hd_inflater` object, use
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ archive or repository.
|
|||||||
|
|
||||||
This simple server takes 3 arguments: The port number to listen on,
|
This simple server takes 3 arguments: The port number to listen on,
|
||||||
the path to your SSL/TLS private key file, and the path to your
|
the path to your SSL/TLS private key file, and the path to your
|
||||||
certificate file. The synopsis is::
|
certificate file. The synopsis is:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ libevent-server PORT /path/to/server.key /path/to/server.crt
|
$ libevent-server PORT /path/to/server.key /path/to/server.crt
|
||||||
|
|
||||||
@@ -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
|
example program, when creating the ``SSL_CTX`` object, we store the
|
||||||
application protocol name in the wire format of NPN in a statically
|
application protocol name in the wire format of NPN in a statically
|
||||||
allocated buffer. This is safe because we only create one ``SSL_CTX``
|
allocated buffer. This is safe because we only create one ``SSL_CTX``
|
||||||
object in the program's entire lifetime::
|
object in the program's entire lifetime.
|
||||||
|
|
||||||
|
If you are following TLS related RFC, you know that NPN is not the
|
||||||
|
standardized way to negotiate HTTP/2. NPN itself is not even
|
||||||
|
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
|
||||||
|
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
|
||||||
|
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
|
||||||
|
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
|
||||||
|
ALPN support depending on OpenSSL version. In ALPN, client sends the
|
||||||
|
list of supported application protocols, and server selects one of
|
||||||
|
them. We provide the callback for it::
|
||||||
|
|
||||||
static unsigned char next_proto_list[256];
|
static unsigned char next_proto_list[256];
|
||||||
static size_t next_proto_list_len;
|
static size_t next_proto_list_len;
|
||||||
@@ -37,6 +49,22 @@ object in the program's entire lifetime::
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
|
||||||
|
unsigned char *outlen, const unsigned char *in,
|
||||||
|
unsigned int inlen, void *arg _U_) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
|
||||||
|
|
||||||
|
if (rv != 1) {
|
||||||
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
EC_KEY *ecdh;
|
EC_KEY *ecdh;
|
||||||
@@ -51,6 +79,11 @@ object in the program's entire lifetime::
|
|||||||
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||||
|
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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
|
we filled in earlier. The NPN callback function is set to the
|
||||||
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
|
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
|
||||||
|
|
||||||
|
In ``alpn_select_proto_cb()``, we use `nghttp2_select_next_protocol()`
|
||||||
|
to select application protocol. The `nghttp2_select_next_protocol()`
|
||||||
|
returns 1 only if it selected h2 (ALPN identifier for HTTP/2), and out
|
||||||
|
parameters were assigned accordingly.
|
||||||
|
|
||||||
Next, let's take a look at the main structures used by the example
|
Next, let's take a look at the main structures used by the example
|
||||||
application:
|
application:
|
||||||
|
|
||||||
@@ -167,11 +205,31 @@ underlying network socket::
|
|||||||
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
||||||
http2_session_data *session_data = (http2_session_data *)ptr;
|
http2_session_data *session_data = (http2_session_data *)ptr;
|
||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
|
const unsigned char *alpn = NULL;
|
||||||
|
unsigned int alpnlen = 0;
|
||||||
|
SSL *ssl;
|
||||||
|
|
||||||
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
||||||
|
|
||||||
|
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||||
|
|
||||||
|
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
if (alpn == NULL) {
|
||||||
|
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||||
|
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
|
||||||
|
delete_http2_session_data(session_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
|
|
||||||
if (send_server_connection_header(session_data) != 0) {
|
if (send_server_connection_header(session_data) != 0 ||
|
||||||
|
session_send(session_data) != 0) {
|
||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -188,6 +246,9 @@ underlying network socket::
|
|||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Here we validate that HTTP/2 is negotiated, and if not, drop
|
||||||
|
connection.
|
||||||
|
|
||||||
For the ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and
|
For the ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and
|
||||||
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
|
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
|
||||||
The ``delete_http2_session_data()`` function destroys the
|
The ``delete_http2_session_data()`` function destroys the
|
||||||
|
|||||||
49
examples/CMakeLists.txt
Normal file
49
examples/CMakeLists.txt
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
if(ENABLE_EXAMPLES)
|
||||||
|
file(GLOB c_sources *.c)
|
||||||
|
set_source_files_properties(${c_sources} PROPERTIES
|
||||||
|
COMPILE_FLAGS "${WARNCFLAGS}")
|
||||||
|
file(GLOB cxx_sources *.cc)
|
||||||
|
set_source_files_properties(${cxx_sources} PROPERTIES
|
||||||
|
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${CMAKE_SOURCE_DIR}
|
||||||
|
${CMAKE_SOURCE_DIR}/lib/includes
|
||||||
|
${CMAKE_BINARY_DIR}/lib/includes
|
||||||
|
${CMAKE_SOURCE_DIR}/src/includes
|
||||||
|
${CMAKE_SOURCE_DIR}/third-party
|
||||||
|
|
||||||
|
${LIBEVENT_INCLUDE_DIRS}
|
||||||
|
${OPENSSL_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
link_libraries(
|
||||||
|
nghttp2
|
||||||
|
${LIBEVENT_OPENSSL_LIBRARIES}
|
||||||
|
${OPENSSL_LIBRARIES}
|
||||||
|
${APP_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(client client.c $<TARGET_OBJECTS:http-parser>)
|
||||||
|
add_executable(libevent-client libevent-client.c $<TARGET_OBJECTS:http-parser>)
|
||||||
|
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:http-parser>)
|
||||||
|
add_executable(deflate deflate.c $<TARGET_OBJECTS:http-parser>)
|
||||||
|
|
||||||
|
if(ENABLE_ASIO_LIB)
|
||||||
|
foreach(name asio-sv asio-sv2 asio-cl asio-cl2)
|
||||||
|
add_executable(${name} ${name}.cc $<TARGET_OBJECTS:http-parser>)
|
||||||
|
target_include_directories(${name} PRIVATE
|
||||||
|
${OPENSSL_INCLUDE_DIRS}
|
||||||
|
${Boost_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
target_link_libraries(${name}
|
||||||
|
nghttp2
|
||||||
|
nghttp2_asio
|
||||||
|
${JEMALLOC_LIBRARIES}
|
||||||
|
${OPENSSL_LIBRARIES}
|
||||||
|
${Boost_LIBRARIES}
|
||||||
|
${APP_LIBRARIES}
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
EXTRA_DIST = CMakeLists.txt
|
||||||
|
|
||||||
if ENABLE_EXAMPLES
|
if ENABLE_EXAMPLES
|
||||||
|
|
||||||
AM_CFLAGS = $(WARNCFLAGS)
|
AM_CFLAGS = $(WARNCFLAGS)
|
||||||
@@ -49,14 +51,6 @@ libevent_server_SOURCES = libevent-server.c
|
|||||||
|
|
||||||
deflate_SOURCES = deflate.c
|
deflate_SOURCES = deflate.c
|
||||||
|
|
||||||
if ENABLE_TINY_NGHTTPD
|
|
||||||
|
|
||||||
noinst_PROGRAMS += tiny-nghttpd
|
|
||||||
|
|
||||||
tiny_nghttpd_SOURCES = tiny-nghttpd.c
|
|
||||||
|
|
||||||
endif # ENABLE_TINY_NGHTTPD
|
|
||||||
|
|
||||||
if ENABLE_ASIO_LIB
|
if ENABLE_ASIO_LIB
|
||||||
|
|
||||||
noinst_PROGRAMS += asio-sv asio-sv2 asio-cl asio-cl2
|
noinst_PROGRAMS += asio-sv asio-sv2 asio-cl asio-cl2
|
||||||
|
|||||||
@@ -36,12 +36,25 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <nghttp2/asio_http2_server.h>
|
#include <nghttp2/asio_http2_server.h>
|
||||||
|
|
||||||
using namespace nghttp2::asio_http2;
|
using namespace nghttp2::asio_http2;
|
||||||
using namespace nghttp2::asio_http2::server;
|
using namespace nghttp2::asio_http2::server;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void run_forever(boost::asio::io_service &io_service, size_t num_threads) {
|
||||||
|
std::vector<std::thread> ts;
|
||||||
|
for (size_t i = 0; i < num_threads; ++i) {
|
||||||
|
ts.emplace_back([&io_service]() { io_service.run(); });
|
||||||
|
}
|
||||||
|
for (auto &t : ts) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
try {
|
try {
|
||||||
// Check command line arguments.
|
// Check command line arguments.
|
||||||
@@ -58,9 +71,9 @@ int main(int argc, char *argv[]) {
|
|||||||
std::string port = argv[2];
|
std::string port = argv[2];
|
||||||
std::size_t num_threads = std::stoi(argv[3]);
|
std::size_t num_threads = std::stoi(argv[3]);
|
||||||
|
|
||||||
http2 server;
|
boost::asio::io_service io_service;
|
||||||
|
|
||||||
server.num_threads(num_threads);
|
http2 server(io_service);
|
||||||
|
|
||||||
server.handle("/", [](const request &req, const response &res) {
|
server.handle("/", [](const request &req, const response &res) {
|
||||||
res.write_head(200, {{"foo", {"bar"}}});
|
res.write_head(200, {{"foo", {"bar"}}});
|
||||||
@@ -136,11 +149,16 @@ int main(int argc, char *argv[]) {
|
|||||||
if (server.listen_and_serve(ec, tls, addr, port)) {
|
if (server.listen_and_serve(ec, tls, addr, port)) {
|
||||||
std::cerr << "error: " << ec.message() << std::endl;
|
std::cerr << "error: " << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_forever(io_service, num_threads);
|
||||||
} else {
|
} else {
|
||||||
if (server.listen_and_serve(ec, addr, port)) {
|
if (server.listen_and_serve(ec, addr, port)) {
|
||||||
std::cerr << "error: " << ec.message() << std::endl;
|
std::cerr << "error: " << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_forever(io_service, num_threads);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
std::cerr << "exception: " << e.what() << "\n";
|
std::cerr << "exception: " << e.what() << "\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,12 +43,25 @@
|
|||||||
#endif // HAVE_FCNTL_H
|
#endif // HAVE_FCNTL_H
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include <nghttp2/asio_http2_server.h>
|
#include <nghttp2/asio_http2_server.h>
|
||||||
|
|
||||||
using namespace nghttp2::asio_http2;
|
using namespace nghttp2::asio_http2;
|
||||||
using namespace nghttp2::asio_http2::server;
|
using namespace nghttp2::asio_http2::server;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void run_forever(boost::asio::io_service &io_service, size_t num_threads) {
|
||||||
|
std::vector<std::thread> ts;
|
||||||
|
for (size_t i = 0; i < num_threads; ++i) {
|
||||||
|
ts.emplace_back([&io_service]() { io_service.run(); });
|
||||||
|
}
|
||||||
|
for (auto &t : ts) {
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
try {
|
try {
|
||||||
// Check command line arguments.
|
// Check command line arguments.
|
||||||
@@ -65,9 +78,9 @@ int main(int argc, char *argv[]) {
|
|||||||
std::size_t num_threads = std::stoi(argv[3]);
|
std::size_t num_threads = std::stoi(argv[3]);
|
||||||
std::string docroot = argv[4];
|
std::string docroot = argv[4];
|
||||||
|
|
||||||
http2 server;
|
boost::asio::io_service io_service;
|
||||||
|
|
||||||
server.num_threads(num_threads);
|
http2 server(io_service);
|
||||||
|
|
||||||
server.handle("/", [&docroot](const request &req, const response &res) {
|
server.handle("/", [&docroot](const request &req, const response &res) {
|
||||||
auto path = percent_decode(req.uri().path);
|
auto path = percent_decode(req.uri().path);
|
||||||
@@ -112,10 +125,14 @@ int main(int argc, char *argv[]) {
|
|||||||
if (server.listen_and_serve(ec, tls, addr, port)) {
|
if (server.listen_and_serve(ec, tls, addr, port)) {
|
||||||
std::cerr << "error: " << ec.message() << std::endl;
|
std::cerr << "error: " << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_forever(io_service, num_threads);
|
||||||
} else {
|
} else {
|
||||||
if (server.listen_and_serve(ec, addr, port)) {
|
if (server.listen_and_serve(ec, addr, port)) {
|
||||||
std::cerr << "error: " << ec.message() << std::endl;
|
std::cerr << "error: " << ec.message() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_forever(io_service, num_threads);
|
||||||
}
|
}
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
std::cerr << "exception: " << e.what() << "\n";
|
std::cerr << "exception: " << e.what() << "\n";
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ enum { IO_NONE, WANT_READ, WANT_WRITE };
|
|||||||
|
|
||||||
#define MAKE_NV(NAME, VALUE) \
|
#define MAKE_NV(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_NV_CS(NAME, VALUE) \
|
#define MAKE_NV_CS(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
|
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,9 +219,9 @@ static int on_frame_send_callback(nghttp2_session *session,
|
|||||||
const nghttp2_nv *nva = frame->headers.nva;
|
const nghttp2_nv *nva = frame->headers.nva;
|
||||||
printf("[INFO] C ----------------------------> S (HEADERS)\n");
|
printf("[INFO] C ----------------------------> S (HEADERS)\n");
|
||||||
for (i = 0; i < frame->headers.nvlen; ++i) {
|
for (i = 0; i < frame->headers.nvlen; ++i) {
|
||||||
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
||||||
printf(": ");
|
printf(": ");
|
||||||
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,9 +249,9 @@ static int on_frame_recv_callback(nghttp2_session *session,
|
|||||||
if (req) {
|
if (req) {
|
||||||
printf("[INFO] C <---------------------------- S (HEADERS)\n");
|
printf("[INFO] C <---------------------------- S (HEADERS)\n");
|
||||||
for (i = 0; i < frame->headers.nvlen; ++i) {
|
for (i = 0; i < frame->headers.nvlen; ++i) {
|
||||||
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
||||||
printf(": ");
|
printf(": ");
|
||||||
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,8 +289,6 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_OUTLEN 4096
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The implementation of nghttp2_on_data_chunk_recv_callback type. We
|
* The implementation of nghttp2_on_data_chunk_recv_callback type. We
|
||||||
* use this function to print the received response body.
|
* use this function to print the received response body.
|
||||||
@@ -459,11 +457,12 @@ static void ctl_poll(struct pollfd *pollfd, struct Connection *connection) {
|
|||||||
static void submit_request(struct Connection *connection, struct Request *req) {
|
static void submit_request(struct Connection *connection, struct Request *req) {
|
||||||
int32_t stream_id;
|
int32_t stream_id;
|
||||||
/* Make sure that the last item is NULL */
|
/* Make sure that the last item is NULL */
|
||||||
const nghttp2_nv nva[] = {
|
const nghttp2_nv nva[] = {MAKE_NV(":method", "GET"),
|
||||||
MAKE_NV(":method", "GET"), MAKE_NV_CS(":path", req->path),
|
MAKE_NV_CS(":path", req->path),
|
||||||
MAKE_NV(":scheme", "https"), MAKE_NV_CS(":authority", req->hostport),
|
MAKE_NV(":scheme", "https"),
|
||||||
MAKE_NV("accept", "*/*"),
|
MAKE_NV_CS(":authority", req->hostport),
|
||||||
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
|
MAKE_NV("accept", "*/*"),
|
||||||
|
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
|
||||||
|
|
||||||
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
|
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
|
||||||
sizeof(nva) / sizeof(nva[0]), NULL, req);
|
sizeof(nva) / sizeof(nva[0]), NULL, req);
|
||||||
@@ -564,7 +563,11 @@ static void fetch_uri(const struct URI *uri) {
|
|||||||
diec("nghttp2_session_client_new", rv);
|
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 the HTTP request to the outbound queue. */
|
||||||
submit_request(&connection, &req);
|
submit_request(&connection, &req);
|
||||||
@@ -693,9 +696,6 @@ int main(int argc, char **argv) {
|
|||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, 0);
|
sigaction(SIGPIPE, &act, 0);
|
||||||
|
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
|
||||||
OPENSSL_config(NULL);
|
|
||||||
#endif /* OPENSSL_IS_BORINGSSL */
|
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
#define MAKE_NV(K, V) \
|
#define MAKE_NV(K, V) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *) K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
|
(uint8_t *)K, (uint8_t *)V, sizeof(K) - 1, sizeof(V) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +109,9 @@ static void deflate(nghttp2_hd_deflater *deflater,
|
|||||||
printf("Input (%zu byte(s)):\n\n", sum);
|
printf("Input (%zu byte(s)):\n\n", sum);
|
||||||
|
|
||||||
for (i = 0; i < nvlen; ++i) {
|
for (i = 0; i < nvlen; ++i) {
|
||||||
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
|
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
|
||||||
printf(": ");
|
printf(": ");
|
||||||
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
|
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,9 +186,9 @@ int inflate_header_block(nghttp2_hd_inflater *inflater, uint8_t *in,
|
|||||||
inlen -= proclen;
|
inlen -= proclen;
|
||||||
|
|
||||||
if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
|
if (inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
|
||||||
fwrite(nv.name, nv.namelen, 1, stderr);
|
fwrite(nv.name, 1, nv.namelen, stderr);
|
||||||
fprintf(stderr, ": ");
|
fprintf(stderr, ": ");
|
||||||
fwrite(nv.value, nv.valuelen, 1, stderr);
|
fwrite(nv.value, 1, nv.valuelen, stderr);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,9 +179,9 @@ static void delete_http2_session_data(http2_session_data *session_data) {
|
|||||||
|
|
||||||
static void print_header(FILE *f, const uint8_t *name, size_t namelen,
|
static void print_header(FILE *f, const uint8_t *name, size_t namelen,
|
||||||
const uint8_t *value, size_t valuelen) {
|
const uint8_t *value, size_t valuelen) {
|
||||||
fwrite(name, namelen, 1, f);
|
fwrite(name, 1, namelen, f);
|
||||||
fprintf(f, ": ");
|
fprintf(f, ": ");
|
||||||
fwrite(value, valuelen, 1, f);
|
fwrite(value, 1, valuelen, f);
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,7 +272,7 @@ static int on_data_chunk_recv_callback(nghttp2_session *session _U_,
|
|||||||
void *user_data) {
|
void *user_data) {
|
||||||
http2_session_data *session_data = (http2_session_data *)user_data;
|
http2_session_data *session_data = (http2_session_data *)user_data;
|
||||||
if (session_data->stream_data->stream_id == stream_id) {
|
if (session_data->stream_data->stream_id == stream_id) {
|
||||||
fwrite(data, len, 1, stdout);
|
fwrite(data, 1, len, stdout);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -287,7 +287,7 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (session_data->stream_data->stream_id == stream_id) {
|
if (session_data->stream_data->stream_id == stream_id) {
|
||||||
fprintf(stderr, "Stream %d closed with error_code=%d\n", stream_id,
|
fprintf(stderr, "Stream %d closed with error_code=%u\n", stream_id,
|
||||||
error_code);
|
error_code);
|
||||||
rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR);
|
rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
@@ -322,6 +322,11 @@ static SSL_CTX *create_ssl_ctx(void) {
|
|||||||
SSL_OP_NO_COMPRESSION |
|
SSL_OP_NO_COMPRESSION |
|
||||||
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
||||||
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, NULL);
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
SSL_CTX_set_alpn_protos(ssl_ctx, (const unsigned char *)"\x02h2", 3);
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,13 +383,13 @@ static void send_client_connection_header(http2_session_data *session_data) {
|
|||||||
|
|
||||||
#define MAKE_NV(NAME, VALUE, VALUELEN) \
|
#define MAKE_NV(NAME, VALUE, VALUELEN) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
|
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, VALUELEN, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAKE_NV2(NAME, VALUE) \
|
#define MAKE_NV2(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,7 +480,27 @@ static void eventcb(struct bufferevent *bev, short events, void *ptr) {
|
|||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
int fd = bufferevent_getfd(bev);
|
int fd = bufferevent_getfd(bev);
|
||||||
int val = 1;
|
int val = 1;
|
||||||
|
const unsigned char *alpn = NULL;
|
||||||
|
unsigned int alpnlen = 0;
|
||||||
|
SSL *ssl;
|
||||||
|
|
||||||
fprintf(stderr, "Connected\n");
|
fprintf(stderr, "Connected\n");
|
||||||
|
|
||||||
|
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||||
|
|
||||||
|
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
if (alpn == NULL) {
|
||||||
|
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||||
|
fprintf(stderr, "h2 is not negotiated\n");
|
||||||
|
delete_http2_session_data(session_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
send_client_connection_header(session_data);
|
send_client_connection_header(session_data);
|
||||||
@@ -569,9 +594,6 @@ int main(int argc, char **argv) {
|
|||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, NULL);
|
sigaction(SIGPIPE, &act, NULL);
|
||||||
|
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
|
||||||
OPENSSL_config(NULL);
|
|
||||||
#endif /* OPENSSL_IS_BORINGSSL */
|
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
|
|
||||||
#define MAKE_NV(NAME, VALUE) \
|
#define MAKE_NV(NAME, VALUE) \
|
||||||
{ \
|
{ \
|
||||||
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
|
||||||
NGHTTP2_NV_FLAG_NONE \
|
NGHTTP2_NV_FLAG_NONE \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,6 +116,22 @@ static int next_proto_cb(SSL *s _U_, const unsigned char **data,
|
|||||||
return SSL_TLSEXT_ERR_OK;
|
return SSL_TLSEXT_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
|
||||||
|
unsigned char *outlen, const unsigned char *in,
|
||||||
|
unsigned int inlen, void *arg _U_) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
|
||||||
|
|
||||||
|
if (rv != 1) {
|
||||||
|
return SSL_TLSEXT_ERR_NOACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SSL_TLSEXT_ERR_OK;
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
/* Create SSL_CTX. */
|
/* Create SSL_CTX. */
|
||||||
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
|
||||||
SSL_CTX *ssl_ctx;
|
SSL_CTX *ssl_ctx;
|
||||||
@@ -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;
|
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
|
||||||
|
|
||||||
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
return ssl_ctx;
|
return ssl_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -640,11 +661,31 @@ static void writecb(struct bufferevent *bev, void *ptr) {
|
|||||||
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
|
||||||
http2_session_data *session_data = (http2_session_data *)ptr;
|
http2_session_data *session_data = (http2_session_data *)ptr;
|
||||||
if (events & BEV_EVENT_CONNECTED) {
|
if (events & BEV_EVENT_CONNECTED) {
|
||||||
|
const unsigned char *alpn = NULL;
|
||||||
|
unsigned int alpnlen = 0;
|
||||||
|
SSL *ssl;
|
||||||
|
|
||||||
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
fprintf(stderr, "%s connected\n", session_data->client_addr);
|
||||||
|
|
||||||
|
ssl = bufferevent_openssl_get_ssl(session_data->bev);
|
||||||
|
|
||||||
|
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
if (alpn == NULL) {
|
||||||
|
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
|
||||||
|
}
|
||||||
|
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||||
|
|
||||||
|
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
|
||||||
|
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
|
||||||
|
delete_http2_session_data(session_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
initialize_nghttp2_session(session_data);
|
initialize_nghttp2_session(session_data);
|
||||||
|
|
||||||
if (send_server_connection_header(session_data) != 0) {
|
if (send_server_connection_header(session_data) != 0 ||
|
||||||
|
session_send(session_data) != 0) {
|
||||||
delete_http2_session_data(session_data);
|
delete_http2_session_data(session_data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -740,9 +781,6 @@ int main(int argc, char **argv) {
|
|||||||
act.sa_handler = SIG_IGN;
|
act.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &act, NULL);
|
sigaction(SIGPIPE, &act, NULL);
|
||||||
|
|
||||||
#ifndef OPENSSL_IS_BORINGSSL
|
|
||||||
OPENSSL_config(NULL);
|
|
||||||
#endif /* OPENSSL_IS_BORINGSSL */
|
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -88,7 +88,8 @@ def build_header(headers):
|
|||||||
c = k[-1]
|
c = k[-1]
|
||||||
if c not in ent:
|
if c not in ent:
|
||||||
ent[c] = []
|
ent[c] = []
|
||||||
ent[c].append(k)
|
if k not in ent[c]:
|
||||||
|
ent[c].append(k)
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ def gen_enum():
|
|||||||
|
|
||||||
def gen_index_header():
|
def gen_index_header():
|
||||||
print '''\
|
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) {'''
|
switch (namelen) {'''
|
||||||
b = build_header(HEADERS)
|
b = build_header(HEADERS)
|
||||||
for size in sorted(b.keys()):
|
for size in sorted(b.keys()):
|
||||||
@@ -121,7 +122,7 @@ static inline int lookup_token(const uint8_t *name, size_t namelen) {
|
|||||||
case '{}':'''.format(c)
|
case '{}':'''.format(c)
|
||||||
for k in headers:
|
for k in headers:
|
||||||
print '''\
|
print '''\
|
||||||
if (lstreq("{}", name, {})) {{
|
if (memeq("{}", name, {})) {{
|
||||||
return {};
|
return {};
|
||||||
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
|
}}'''.format(k[:-1], size - 1, to_enum_hd(k))
|
||||||
print '''\
|
print '''\
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ OPTIONS = [
|
|||||||
"tls-ticket-key-cipher",
|
"tls-ticket-key-cipher",
|
||||||
"host-rewrite",
|
"host-rewrite",
|
||||||
"tls-session-cache-memcached",
|
"tls-session-cache-memcached",
|
||||||
|
"tls-session-cache-memcached-tls",
|
||||||
"tls-ticket-key-memcached",
|
"tls-ticket-key-memcached",
|
||||||
"tls-ticket-key-memcached-interval",
|
"tls-ticket-key-memcached-interval",
|
||||||
"tls-ticket-key-memcached-max-retry",
|
"tls-ticket-key-memcached-max-retry",
|
||||||
@@ -114,7 +115,49 @@ OPTIONS = [
|
|||||||
"max-header-fields",
|
"max-header-fields",
|
||||||
"no-http2-cipher-black-list",
|
"no-http2-cipher-black-list",
|
||||||
"backend-http1-tls",
|
"backend-http1-tls",
|
||||||
"backend-tls-session-cache-per-worker"
|
"tls-session-cache-memcached-cert-file",
|
||||||
|
"tls-session-cache-memcached-private-key-file",
|
||||||
|
"tls-session-cache-memcached-address-family",
|
||||||
|
"tls-ticket-key-memcached-tls",
|
||||||
|
"tls-ticket-key-memcached-cert-file",
|
||||||
|
"tls-ticket-key-memcached-private-key-file",
|
||||||
|
"tls-ticket-key-memcached-address-family",
|
||||||
|
"backend-address-family",
|
||||||
|
"frontend-http2-max-concurrent-streams",
|
||||||
|
"backend-http2-max-concurrent-streams",
|
||||||
|
"backend-connections-per-frontend",
|
||||||
|
"backend-tls",
|
||||||
|
"backend-connections-per-host",
|
||||||
|
"error-page",
|
||||||
|
"no-kqueue",
|
||||||
|
"frontend-http2-settings-timeout",
|
||||||
|
"backend-http2-settings-timeout",
|
||||||
|
"api-max-request-body",
|
||||||
|
"backend-max-backoff",
|
||||||
|
"server-name",
|
||||||
|
"no-server-rewrite",
|
||||||
|
"frontend-http2-optimize-write-buffer-size",
|
||||||
|
"frontend-http2-optimize-window-size",
|
||||||
|
"frontend-http2-window-size",
|
||||||
|
"frontend-http2-connection-window-size",
|
||||||
|
"backend-http2-window-size",
|
||||||
|
"backend-http2-connection-window-size",
|
||||||
|
"frontend-http2-encoder-dynamic-table-size",
|
||||||
|
"frontend-http2-decoder-dynamic-table-size",
|
||||||
|
"backend-http2-encoder-dynamic-table-size",
|
||||||
|
"backend-http2-decoder-dynamic-table-size",
|
||||||
|
"ecdh-curves",
|
||||||
|
"tls-sct-dir",
|
||||||
|
"backend-connect-timeout",
|
||||||
|
"dns-cache-timeout",
|
||||||
|
"dns-lookup-timeout",
|
||||||
|
"dns-max-try",
|
||||||
|
"frontend-keep-alive-timeout",
|
||||||
|
"psk-secrets",
|
||||||
|
"client-psk-secrets",
|
||||||
|
"client-no-http2-cipher-black-list",
|
||||||
|
"client-ciphers",
|
||||||
|
"accesslog-write-early",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
@@ -133,6 +176,8 @@ LOGVARS = [
|
|||||||
"ssl_protocol",
|
"ssl_protocol",
|
||||||
"ssl_session_id",
|
"ssl_session_id",
|
||||||
"ssl_session_reused",
|
"ssl_session_reused",
|
||||||
|
"backend_host",
|
||||||
|
"backend_port",
|
||||||
]
|
]
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
10
help2rst.py
10
help2rst.py
@@ -160,13 +160,15 @@ DESCRIPTION
|
|||||||
print(line.strip())
|
print(line.strip())
|
||||||
|
|
||||||
def format_text(text):
|
def format_text(text):
|
||||||
# escape *
|
# escape *, but don't escape * if it is used as bullet list.
|
||||||
if len(text) > len(arg_indent):
|
m = re.match(r'^\s*\*\s+', text)
|
||||||
text = text[:len(arg_indent) + 1] + re.sub(r'\*', r'\*', text[len(arg_indent) + 1:])
|
if m:
|
||||||
|
text = text[:len(m.group(0))] + re.sub(r'\*', r'\*', text[len(m.group(0)):])
|
||||||
else:
|
else:
|
||||||
text = re.sub(r'\*', r'\*', text)
|
text = re.sub(r'\*', r'\*', text)
|
||||||
# markup option reference
|
# markup option reference
|
||||||
text = re.sub(r'(^|\s)(-[a-zA-Z0-9-]+)', 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
|
# sphinx does not like markup like ':option:`-f`='. We need
|
||||||
# backslash between ` and =.
|
# backslash between ` and =.
|
||||||
text = re.sub(r'(:option:`.*?`)(\S)', r'\1\\\2', text)
|
text = re.sub(r'(:option:`.*?`)(\S)', r'\1\\\2', text)
|
||||||
|
|||||||
1
integration-tests/.gitignore
vendored
1
integration-tests/.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
# generated files
|
# generated files
|
||||||
config.go
|
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}
|
||||||
|
)
|
||||||
@@ -21,11 +21,15 @@
|
|||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
EXTRA_DIST = \
|
GO_FILES = \
|
||||||
nghttpx_http1_test.go \
|
nghttpx_http1_test.go \
|
||||||
nghttpx_http2_test.go \
|
nghttpx_http2_test.go \
|
||||||
nghttpx_spdy_test.go \
|
nghttpx_spdy_test.go \
|
||||||
server_tester.go \
|
server_tester.go
|
||||||
|
|
||||||
|
EXTRA_DIST = \
|
||||||
|
CMakeLists.txt \
|
||||||
|
$(GO_FILES) \
|
||||||
server.key \
|
server.key \
|
||||||
server.crt \
|
server.crt \
|
||||||
alt-server.key \
|
alt-server.key \
|
||||||
@@ -36,11 +40,12 @@ EXTRA_DIST = \
|
|||||||
req-return.rb \
|
req-return.rb \
|
||||||
resp-return.rb
|
resp-return.rb
|
||||||
|
|
||||||
itprep-local:
|
itprep:
|
||||||
go get -d -v golang.org/x/net/http2
|
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/go-nghttp2
|
||||||
go get -d -v github.com/tatsuhiro-t/spdy
|
go get -d -v github.com/tatsuhiro-t/spdy
|
||||||
go get -d -v golang.org/x/net/websocket
|
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
|
sh setenv go test -v
|
||||||
|
|||||||
@@ -2,4 +2,5 @@ package nghttp2
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
buildDir = "@top_builddir@"
|
buildDir = "@top_builddir@"
|
||||||
|
sourceDir = "@top_srcdir@"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package nghttp2
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
@@ -103,26 +104,26 @@ Content-Length: 0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH1H1ConnectFailure tests that server handles the situation that
|
// // TestH1H1ConnectFailure tests that server handles the situation that
|
||||||
// connection attempt to HTTP/1 backend failed.
|
// // connection attempt to HTTP/1 backend failed.
|
||||||
func TestH1H1ConnectFailure(t *testing.T) {
|
// func TestH1H1ConnectFailure(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
// st := newServerTester(nil, t, noopHandler)
|
||||||
defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// shutdown backend server to simulate backend connect failure
|
// // shutdown backend server to simulate backend connect failure
|
||||||
st.ts.Close()
|
// st.ts.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
// res, err := st.http1(requestParam{
|
||||||
name: "TestH1H1ConnectFailure",
|
// name: "TestH1H1ConnectFailure",
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Fatalf("Error st.http1() = %v", err)
|
// t.Fatalf("Error st.http1() = %v", err)
|
||||||
}
|
// }
|
||||||
want := 503
|
// want := 503
|
||||||
if got := res.status; got != want {
|
// if got := res.status; got != want {
|
||||||
t.Errorf("status: %v; want %v", got, want)
|
// t.Errorf("status: %v; want %v", got, want)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TestH1H1GracefulShutdown tests graceful shutdown.
|
// TestH1H1GracefulShutdown tests graceful shutdown.
|
||||||
func TestH1H1GracefulShutdown(t *testing.T) {
|
func TestH1H1GracefulShutdown(t *testing.T) {
|
||||||
@@ -159,8 +160,9 @@ func TestH1H1GracefulShutdown(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
want := io.EOF
|
want := io.EOF
|
||||||
if _, err := st.conn.Read(nil); err == nil || err != want {
|
b := make([]byte, 256)
|
||||||
t.Errorf("st.conn.Read(): %v; want %v", err, want)
|
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
|
// // TestH1H2ConnectFailure tests that server handles the situation that
|
||||||
// connection attempt to HTTP/2 backend failed.
|
// // connection attempt to HTTP/2 backend failed.
|
||||||
func TestH1H2ConnectFailure(t *testing.T) {
|
// func TestH1H2ConnectFailure(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||||
defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// simulate backend connect attempt failure
|
// // simulate backend connect attempt failure
|
||||||
st.ts.Close()
|
// st.ts.Close()
|
||||||
|
|
||||||
res, err := st.http1(requestParam{
|
// res, err := st.http1(requestParam{
|
||||||
name: "TestH1H2ConnectFailure",
|
// name: "TestH1H2ConnectFailure",
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Fatalf("Error st.http1() = %v", err)
|
// t.Fatalf("Error st.http1() = %v", err)
|
||||||
}
|
// }
|
||||||
want := 503
|
// want := 503
|
||||||
if got := res.status; got != want {
|
// if got := res.status; got != want {
|
||||||
t.Errorf("status: %v; want %v", got, want)
|
// t.Errorf("status: %v; want %v", got, want)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TestH1H2NoHost tests that server rejects request without Host
|
// TestH1H2NoHost tests that server rejects request without Host
|
||||||
// header field for HTTP/2 backend.
|
// header field for HTTP/2 backend.
|
||||||
@@ -793,3 +795,221 @@ func TestH1H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %v; want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestH1H2TE tests that "te: trailers" header is forwarded to HTTP/2
|
||||||
|
// backend server by stripping other encodings.
|
||||||
|
func TestH1H2TE(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--http2-bridge"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if got, want := r.Header.Get("te"), "trailers"; got != want {
|
||||||
|
t.Errorf("te: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH1H2TE",
|
||||||
|
header: []hpack.HeaderField{
|
||||||
|
pair("te", "foo,trailers,bar"),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH1APIBackendconfig exercise backendconfig API endpoint routine
|
||||||
|
// for successful case.
|
||||||
|
func TestH1APIBackendconfig(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH1APIBackendconfig",
|
||||||
|
path: "/api/v1beta1/backendconfig",
|
||||||
|
method: "PUT",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Success"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 200; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH1APIBackendconfigQuery exercise backendconfig API endpoint
|
||||||
|
// routine with query.
|
||||||
|
func TestH1APIBackendconfigQuery(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH1APIBackendconfigQuery",
|
||||||
|
path: "/api/v1beta1/backendconfig?foo=bar",
|
||||||
|
method: "PUT",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Success"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 200; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH1APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||||
|
// routine with bad method.
|
||||||
|
func TestH1APIBackendconfigBadMethod(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH1APIBackendconfigBadMethod",
|
||||||
|
path: "/api/v1beta1/backendconfig",
|
||||||
|
method: "GET",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 405; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Failure"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 405; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH1APINotFound exercise backendconfig API endpoint routine when
|
||||||
|
// API endpoint is not found.
|
||||||
|
func TestH1APINotFound(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH1APINotFound",
|
||||||
|
path: "/api/notfound",
|
||||||
|
method: "GET",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 404; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Failure"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 404; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH1Healthmon tests health monitor endpoint.
|
||||||
|
func TestH1Healthmon(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3011)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http1(requestParam{
|
||||||
|
name: "TestH1Healthmon",
|
||||||
|
path: "/alpha/bravo",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http1() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH1ResponseBeforeRequestEnd tests the situation where response
|
||||||
|
// ends before request body finishes.
|
||||||
|
func TestH1ResponseBeforeRequestEnd(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("request should not be forwarded")
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
if _, err := io.WriteString(st.conn, fmt.Sprintf(`POST / HTTP/1.1
|
||||||
|
Host: %v
|
||||||
|
Test-Case: TestH1ResponseBeforeRequestEnd
|
||||||
|
Content-Length: 1000000
|
||||||
|
|
||||||
|
`, st.authority)); err != nil {
|
||||||
|
t.Fatalf("Error io.WriteString() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error http.ReadResponse() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := resp.StatusCode, 404; got != want {
|
||||||
|
t.Errorf("status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package nghttp2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/http2"
|
"golang.org/x/net/http2"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
@@ -568,26 +569,26 @@ func TestH2H1InvalidRequestCL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH2H1ConnectFailure tests that server handles the situation that
|
// // TestH2H1ConnectFailure tests that server handles the situation that
|
||||||
// connection attempt to HTTP/1 backend failed.
|
// // connection attempt to HTTP/1 backend failed.
|
||||||
func TestH2H1ConnectFailure(t *testing.T) {
|
// func TestH2H1ConnectFailure(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
// st := newServerTester(nil, t, noopHandler)
|
||||||
defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// shutdown backend server to simulate backend connect failure
|
// // shutdown backend server to simulate backend connect failure
|
||||||
st.ts.Close()
|
// st.ts.Close()
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
// res, err := st.http2(requestParam{
|
||||||
name: "TestH2H1ConnectFailure",
|
// name: "TestH2H1ConnectFailure",
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Fatalf("Error st.http2() = %v", err)
|
// t.Fatalf("Error st.http2() = %v", err)
|
||||||
}
|
// }
|
||||||
want := 503
|
// want := 503
|
||||||
if got := res.status; got != want {
|
// if got := res.status; got != want {
|
||||||
t.Errorf("status: %v; want %v", got, want)
|
// t.Errorf("status: %v; want %v", got, want)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TestH2H1InvalidMethod tests that server rejects invalid method with
|
// TestH2H1InvalidMethod tests that server rejects invalid method with
|
||||||
// 501.
|
// 501.
|
||||||
@@ -1368,6 +1369,42 @@ func TestH2H1ProxyProtocolV1InvalidID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestH2H1ExternalDNS tests that DNS resolution using external DNS
|
||||||
|
// with HTTP/1 backend works.
|
||||||
|
func TestH2H1ExternalDNS(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--external-dns"}, t, noopHandler)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H1ExternalDNS",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H1DNS tests that DNS resolution without external DNS with
|
||||||
|
// HTTP/1 backend works.
|
||||||
|
func TestH2H1DNS(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--dns"}, t, noopHandler)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H1DNS",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestH2H1GracefulShutdown tests graceful shutdown.
|
// TestH2H1GracefulShutdown tests graceful shutdown.
|
||||||
func TestH2H1GracefulShutdown(t *testing.T) {
|
func TestH2H1GracefulShutdown(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(nil, t, noopHandler)
|
||||||
@@ -1486,26 +1523,26 @@ func TestH2H2InvalidResponseCL(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH2H2ConnectFailure tests that server handles the situation that
|
// // TestH2H2ConnectFailure tests that server handles the situation that
|
||||||
// connection attempt to HTTP/2 backend failed.
|
// // connection attempt to HTTP/2 backend failed.
|
||||||
func TestH2H2ConnectFailure(t *testing.T) {
|
// func TestH2H2ConnectFailure(t *testing.T) {
|
||||||
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
|
||||||
defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// simulate backend connect attempt failure
|
// // simulate backend connect attempt failure
|
||||||
st.ts.Close()
|
// st.ts.Close()
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
// res, err := st.http2(requestParam{
|
||||||
name: "TestH2H2ConnectFailure",
|
// name: "TestH2H2ConnectFailure",
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Fatalf("Error st.http2() = %v", err)
|
// t.Fatalf("Error st.http2() = %v", err)
|
||||||
}
|
// }
|
||||||
want := 503
|
// want := 503
|
||||||
if got := res.status; got != want {
|
// if got := res.status; got != want {
|
||||||
t.Errorf("status: %v; want %v", got, want)
|
// t.Errorf("status: %v; want %v", got, want)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TestH2H2HostRewrite tests that server rewrites host header field
|
// TestH2H2HostRewrite tests that server rewrites host header field
|
||||||
func TestH2H2HostRewrite(t *testing.T) {
|
func TestH2H2HostRewrite(t *testing.T) {
|
||||||
@@ -1843,3 +1880,226 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %v; want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestH2H2ExternalDNS tests that DNS resolution using external DNS
|
||||||
|
// with HTTP/2 backend works.
|
||||||
|
func TestH2H2ExternalDNS(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--http2-bridge", "--external-dns"}, t, noopHandler)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H2ExternalDNS",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2H2DNS tests that DNS resolution without external DNS with
|
||||||
|
// HTTP/2 backend works.
|
||||||
|
func TestH2H2DNS(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--http2-bridge", "--dns"}, t, noopHandler)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2H2DNS",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("status = %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2APIBackendconfig exercise backendconfig API endpoint routine
|
||||||
|
// for successful case.
|
||||||
|
func TestH2APIBackendconfig(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2APIBackendconfig",
|
||||||
|
path: "/api/v1beta1/backendconfig",
|
||||||
|
method: "PUT",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Success"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 200; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2APIBackendconfigQuery exercise backendconfig API endpoint
|
||||||
|
// routine with query.
|
||||||
|
func TestH2APIBackendconfigQuery(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2APIBackendconfigQuery",
|
||||||
|
path: "/api/v1beta1/backendconfig?foo=bar",
|
||||||
|
method: "PUT",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Success"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 200; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||||
|
// routine with bad method.
|
||||||
|
func TestH2APIBackendconfigBadMethod(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2APIBackendconfigBadMethod",
|
||||||
|
path: "/api/v1beta1/backendconfig",
|
||||||
|
method: "GET",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 405; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Failure"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 405; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2APINotFound exercise backendconfig API endpoint routine when
|
||||||
|
// API endpoint is not found.
|
||||||
|
func TestH2APINotFound(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2APINotFound",
|
||||||
|
path: "/api/notfound",
|
||||||
|
method: "GET",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 404; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Failure"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 404; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2Healthmon tests health monitor endpoint.
|
||||||
|
func TestH2Healthmon(t *testing.T) {
|
||||||
|
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3011)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2Healthmon",
|
||||||
|
path: "/alpha/bravo",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestH2ResponseBeforeRequestEnd tests the situation where response
|
||||||
|
// ends before request body finishes.
|
||||||
|
func TestH2ResponseBeforeRequestEnd(t *testing.T) {
|
||||||
|
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("request should not be forwarded")
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.http2(requestParam{
|
||||||
|
name: "TestH2ResponseBeforeRequestEnd",
|
||||||
|
noEndStream: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.http2() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 404; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package nghttp2
|
package nghttp2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"github.com/tatsuhiro-t/spdy"
|
"github.com/tatsuhiro-t/spdy"
|
||||||
"golang.org/x/net/http2/hpack"
|
"golang.org/x/net/http2/hpack"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -384,26 +385,26 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestS3H2ConnectFailure tests that server handles the situation that
|
// // TestS3H2ConnectFailure tests that server handles the situation that
|
||||||
// connection attempt to HTTP/2 backend failed.
|
// // connection attempt to HTTP/2 backend failed.
|
||||||
func TestS3H2ConnectFailure(t *testing.T) {
|
// func TestS3H2ConnectFailure(t *testing.T) {
|
||||||
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
|
// st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
|
||||||
defer st.Close()
|
// defer st.Close()
|
||||||
|
|
||||||
// simulate backend connect attempt failure
|
// // simulate backend connect attempt failure
|
||||||
st.ts.Close()
|
// st.ts.Close()
|
||||||
|
|
||||||
res, err := st.spdy(requestParam{
|
// res, err := st.spdy(requestParam{
|
||||||
name: "TestS3H2ConnectFailure",
|
// name: "TestS3H2ConnectFailure",
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Fatalf("Error st.spdy() = %v", err)
|
// t.Fatalf("Error st.spdy() = %v", err)
|
||||||
}
|
// }
|
||||||
want := 503
|
// want := 503
|
||||||
if got := res.status; got != want {
|
// if got := res.status; got != want {
|
||||||
t.Errorf("status: %v; want %v", got, want)
|
// t.Errorf("status: %v; want %v", got, want)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
|
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
|
||||||
// custom response.
|
// custom response.
|
||||||
@@ -474,3 +475,190 @@ func TestS3H2RespPhaseReturn(t *testing.T) {
|
|||||||
t.Errorf("body = %v; want %v", got, want)
|
t.Errorf("body = %v; want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestS3APIBackendconfig exercise backendconfig API endpoint routine
|
||||||
|
// for successful case.
|
||||||
|
func TestS3APIBackendconfig(t *testing.T) {
|
||||||
|
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.spdy(requestParam{
|
||||||
|
name: "TestS3APIBackendconfig",
|
||||||
|
path: "/api/v1beta1/backendconfig",
|
||||||
|
method: "PUT",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Success"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 200; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestS3APIBackendconfigQuery exercise backendconfig API endpoint
|
||||||
|
// routine with query.
|
||||||
|
func TestS3APIBackendconfigQuery(t *testing.T) {
|
||||||
|
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.spdy(requestParam{
|
||||||
|
name: "TestS3APIBackendconfigQuery",
|
||||||
|
path: "/api/v1beta1/backendconfig?foo=bar",
|
||||||
|
method: "PUT",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Success"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 200; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestS3APIBackendconfigBadMethod exercise backendconfig API endpoint
|
||||||
|
// routine with bad method.
|
||||||
|
func TestS3APIBackendconfigBadMethod(t *testing.T) {
|
||||||
|
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.spdy(requestParam{
|
||||||
|
name: "TestS3APIBackendconfigBadMethod",
|
||||||
|
path: "/api/v1beta1/backendconfig",
|
||||||
|
method: "GET",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 405; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Failure"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 405; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestS3APINotFound exercise backendconfig API endpoint routine when
|
||||||
|
// API endpoint is not found.
|
||||||
|
func TestS3APINotFound(t *testing.T) {
|
||||||
|
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3010;api"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3010)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.spdy(requestParam{
|
||||||
|
name: "TestS3APINotFound",
|
||||||
|
path: "/api/notfound",
|
||||||
|
method: "GET",
|
||||||
|
body: []byte(`# comment
|
||||||
|
backend=127.0.0.1,3011
|
||||||
|
|
||||||
|
`),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 404; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiResp APIResponse
|
||||||
|
err = json.Unmarshal(res.body, &apiResp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error unmarshaling API response: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Status, "Failure"; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
if got, want := apiResp.Code, 404; got != want {
|
||||||
|
t.Errorf("apiResp.Status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestS3Healthmon tests health monitor endpoint.
|
||||||
|
func TestS3Healthmon(t *testing.T) {
|
||||||
|
st := newServerTesterTLSConnectPort([]string{"--npn-list=spdy/3.1", "-f127.0.0.1,3011;healthmon"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatalf("request should not be forwarded")
|
||||||
|
}, 3011)
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.spdy(requestParam{
|
||||||
|
name: "TestS3Healthmon",
|
||||||
|
path: "/alpha/bravo",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 200; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestS3ResponseBeforeRequestEnd tests the situation where response
|
||||||
|
// ends before request body finishes.
|
||||||
|
func TestS3ResponseBeforeRequestEnd(t *testing.T) {
|
||||||
|
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Fatal("request should not be forwarded")
|
||||||
|
})
|
||||||
|
defer st.Close()
|
||||||
|
|
||||||
|
res, err := st.spdy(requestParam{
|
||||||
|
name: "TestS3ResponseBeforeRequestEnd",
|
||||||
|
noEndStream: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error st.spdy() = %v", err)
|
||||||
|
}
|
||||||
|
if got, want := res.status, 404; got != want {
|
||||||
|
t.Errorf("res.status: %v; want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"golang.org/x/net/http2"
|
|
||||||
"golang.org/x/net/http2/hpack"
|
|
||||||
"github.com/tatsuhiro-t/go-nghttp2"
|
"github.com/tatsuhiro-t/go-nghttp2"
|
||||||
"github.com/tatsuhiro-t/spdy"
|
"github.com/tatsuhiro-t/spdy"
|
||||||
|
"golang.org/x/net/http2"
|
||||||
|
"golang.org/x/net/http2/hpack"
|
||||||
"golang.org/x/net/websocket"
|
"golang.org/x/net/websocket"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -29,7 +29,8 @@ import (
|
|||||||
const (
|
const (
|
||||||
serverBin = buildDir + "/src/nghttpx"
|
serverBin = buildDir + "/src/nghttpx"
|
||||||
serverPort = 3009
|
serverPort = 3009
|
||||||
testDir = buildDir + "/integration-tests"
|
testDir = sourceDir + "/integration-tests"
|
||||||
|
logDir = buildDir + "/integration-tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
func pair(name, value string) hpack.HeaderField {
|
func pair(name, value string) hpack.HeaderField {
|
||||||
@@ -65,34 +66,57 @@ type serverTester struct {
|
|||||||
// newServerTester creates test context for plain TCP frontend
|
// newServerTester creates test context for plain TCP frontend
|
||||||
// connection.
|
// connection.
|
||||||
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, false, 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 {
|
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.
|
// newServerTester creates test context for TLS frontend connection.
|
||||||
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, true, 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
|
// newServerTester creates test context for TLS frontend connection
|
||||||
// with given clientConfig
|
// with given clientConfig
|
||||||
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
|
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
|
||||||
return newServerTesterInternal(args, t, handler, true, clientConfig)
|
return newServerTesterInternal(args, t, handler, true, serverPort, clientConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newServerTesterInternal creates test context. If frontendTLS is
|
// newServerTesterInternal creates test context. If frontendTLS is
|
||||||
// true, set up TLS frontend connection.
|
// true, set up TLS frontend connection. connectPort is the server
|
||||||
func newServerTesterInternal(args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
|
// 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)
|
ts := httptest.NewUnstartedServer(handler)
|
||||||
|
|
||||||
|
args := []string{}
|
||||||
|
|
||||||
backendTLS := false
|
backendTLS := false
|
||||||
for _, k := range args {
|
dns := false
|
||||||
|
externalDNS := false
|
||||||
|
acceptProxyProtocol := false
|
||||||
|
for _, k := range src_args {
|
||||||
switch k {
|
switch k {
|
||||||
case "--http2-bridge":
|
case "--http2-bridge":
|
||||||
backendTLS = true
|
backendTLS = true
|
||||||
|
case "--dns":
|
||||||
|
dns = true
|
||||||
|
case "--external-dns":
|
||||||
|
dns = true
|
||||||
|
externalDNS = true
|
||||||
|
case "--accept-proxy-protocol":
|
||||||
|
acceptProxyProtocol = true
|
||||||
|
default:
|
||||||
|
args = append(args, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if backendTLS {
|
if backendTLS {
|
||||||
@@ -101,7 +125,7 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
|||||||
// NextProtos separately for ts.TLS. NextProtos set
|
// NextProtos separately for ts.TLS. NextProtos set
|
||||||
// in nghttp2.ConfigureServer is effectively ignored.
|
// in nghttp2.ConfigureServer is effectively ignored.
|
||||||
ts.TLS = new(tls.Config)
|
ts.TLS = new(tls.Config)
|
||||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2-14")
|
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
|
||||||
ts.StartTLS()
|
ts.StartTLS()
|
||||||
args = append(args, "-k")
|
args = append(args, "-k")
|
||||||
} else {
|
} else {
|
||||||
@@ -111,8 +135,6 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
|||||||
if frontendTLS {
|
if frontendTLS {
|
||||||
scheme = "https"
|
scheme = "https"
|
||||||
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
args = append(args, testDir+"/server.key", testDir+"/server.crt")
|
||||||
} else {
|
|
||||||
args = append(args, "--frontend-no-tls")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backendURL, err := url.Parse(ts.URL)
|
backendURL, err := url.Parse(ts.URL)
|
||||||
@@ -122,11 +144,39 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
|||||||
|
|
||||||
// URL.Host looks like "127.0.0.1:8080", but we want
|
// URL.Host looks like "127.0.0.1:8080", but we want
|
||||||
// "127.0.0.1,8080"
|
// "127.0.0.1,8080"
|
||||||
b := "-b" + strings.Replace(backendURL.Host, ":", ",", -1)
|
b := "-b"
|
||||||
args = append(args, fmt.Sprintf("-f127.0.0.1,%v", serverPort), b,
|
if !externalDNS {
|
||||||
"--errorlog-file="+testDir+"/log.txt", "-LINFO")
|
b += fmt.Sprintf("%v;", strings.Replace(backendURL.Host, ":", ",", -1))
|
||||||
|
} else {
|
||||||
|
sep := strings.LastIndex(backendURL.Host, ":")
|
||||||
|
if sep == -1 {
|
||||||
|
t.Fatalf("backendURL.Host %v does not contain separator ':'", backendURL.Host)
|
||||||
|
}
|
||||||
|
// We use awesome service xip.io.
|
||||||
|
b += fmt.Sprintf("%v.xip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
|
||||||
|
}
|
||||||
|
|
||||||
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)
|
if backendTLS {
|
||||||
|
b += ";proto=h2;tls"
|
||||||
|
}
|
||||||
|
if dns {
|
||||||
|
b += ";dns"
|
||||||
|
}
|
||||||
|
|
||||||
|
noTLS := ";no-tls"
|
||||||
|
if frontendTLS {
|
||||||
|
noTLS = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var proxyProto string
|
||||||
|
if acceptProxyProtocol {
|
||||||
|
proxyProto = ";proxyproto"
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, fmt.Sprintf("-f127.0.0.1,%v%v%v", serverPort, noTLS, proxyProto), b,
|
||||||
|
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
|
||||||
|
|
||||||
|
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
|
||||||
|
|
||||||
st := &serverTester{
|
st := &serverTester{
|
||||||
cmd: exec.Command(serverBin, args...),
|
cmd: exec.Command(serverBin, args...),
|
||||||
@@ -148,6 +198,8 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
|||||||
|
|
||||||
retry := 0
|
retry := 0
|
||||||
for {
|
for {
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
var conn net.Conn
|
var conn net.Conn
|
||||||
var err error
|
var err error
|
||||||
if frontendTLS {
|
if frontendTLS {
|
||||||
@@ -158,7 +210,7 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
|||||||
tlsConfig = clientConfig
|
tlsConfig = clientConfig
|
||||||
}
|
}
|
||||||
tlsConfig.InsecureSkipVerify = true
|
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)
|
conn, err = tls.Dial("tcp", authority, tlsConfig)
|
||||||
} else {
|
} else {
|
||||||
conn, err = net.Dial("tcp", authority)
|
conn, err = net.Dial("tcp", authority)
|
||||||
@@ -169,7 +221,6 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
|
|||||||
st.Close()
|
st.Close()
|
||||||
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
|
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
|
||||||
}
|
}
|
||||||
time.Sleep(150 * time.Millisecond)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if frontendTLS {
|
if frontendTLS {
|
||||||
@@ -275,6 +326,7 @@ type requestParam struct {
|
|||||||
body []byte // request body
|
body []byte // request body
|
||||||
trailer []hpack.HeaderField // trailer part
|
trailer []hpack.HeaderField // trailer part
|
||||||
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
|
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
|
||||||
|
noEndStream bool // true if END_STREAM should not be sent
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrapper for request body to set trailer part
|
// wrapper for request body to set trailer part
|
||||||
@@ -358,8 +410,9 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
|
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
|
||||||
}
|
}
|
||||||
u.Path = rp.path
|
u.Path = ""
|
||||||
reqURL = u.String()
|
u.RawQuery = ""
|
||||||
|
reqURL = u.String() + rp.path
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest(method, reqURL, body)
|
req, err := http.NewRequest(method, reqURL, body)
|
||||||
@@ -448,7 +501,7 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var synStreamFlags spdy.ControlFlags
|
var synStreamFlags spdy.ControlFlags
|
||||||
if len(rp.body) == 0 {
|
if len(rp.body) == 0 && !rp.noEndStream {
|
||||||
synStreamFlags = spdy.ControlFlagFin
|
synStreamFlags = spdy.ControlFlagFin
|
||||||
}
|
}
|
||||||
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
|
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
|
||||||
@@ -462,9 +515,13 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(rp.body) != 0 {
|
if len(rp.body) != 0 {
|
||||||
|
var dataFlags spdy.DataFlags
|
||||||
|
if !rp.noEndStream {
|
||||||
|
dataFlags = spdy.DataFlagFin
|
||||||
|
}
|
||||||
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
|
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
|
||||||
StreamId: id,
|
StreamId: id,
|
||||||
Flags: spdy.DataFlagFin,
|
Flags: dataFlags,
|
||||||
Data: rp.body,
|
Data: rp.body,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -577,7 +634,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
|||||||
|
|
||||||
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
|
||||||
StreamID: id,
|
StreamID: id,
|
||||||
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
|
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0 && !rp.noEndStream,
|
||||||
EndHeaders: true,
|
EndHeaders: true,
|
||||||
BlockFragment: st.headerBlkBuf.Bytes(),
|
BlockFragment: st.headerBlkBuf.Bytes(),
|
||||||
})
|
})
|
||||||
@@ -587,7 +644,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
|
|||||||
|
|
||||||
if len(rp.body) != 0 {
|
if len(rp.body) != 0 {
|
||||||
// TODO we assume rp.body fits in 1 frame
|
// TODO we assume rp.body fits in 1 frame
|
||||||
if err := st.fr.WriteData(id, len(rp.trailer) == 0, rp.body); err != nil {
|
if err := st.fr.WriteData(id, len(rp.trailer) == 0 && !rp.noEndStream, rp.body); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -734,3 +791,8 @@ func cloneHeader(h http.Header) http.Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func noopHandler(w http.ResponseWriter, r *http.Request) {}
|
func noopHandler(w http.ResponseWriter, r *http.Request) {}
|
||||||
|
|
||||||
|
type APIResponse struct {
|
||||||
|
Status string `json:"status,omitempty"`
|
||||||
|
Code int `json:"code,omitempty"`
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
#!/bin/sh -e
|
#!/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_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
|
||||||
export CGO_LDFLAGS="-L@abs_top_builddir@/lib/.libs"
|
export CGO_LDFLAGS="-L$libdir"
|
||||||
export LD_LIBRARY_PATH="@abs_top_builddir@/lib/.libs"
|
export LD_LIBRARY_PATH="$libdir"
|
||||||
|
export GODEBUG=cgocheck=0
|
||||||
"$@"
|
"$@"
|
||||||
|
|||||||
63
lib/CMakeLists.txt
Normal file
63
lib/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
add_subdirectory(includes)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/includes"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(-DBUILDING_NGHTTP2)
|
||||||
|
|
||||||
|
set(NGHTTP2_SOURCES
|
||||||
|
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
|
||||||
|
nghttp2_frame.c
|
||||||
|
nghttp2_buf.c
|
||||||
|
nghttp2_stream.c nghttp2_outbound_item.c
|
||||||
|
nghttp2_session.c nghttp2_submit.c
|
||||||
|
nghttp2_helper.c
|
||||||
|
nghttp2_npn.c
|
||||||
|
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
|
||||||
|
nghttp2_version.c
|
||||||
|
nghttp2_priority_spec.c
|
||||||
|
nghttp2_option.c
|
||||||
|
nghttp2_callbacks.c
|
||||||
|
nghttp2_mem.c
|
||||||
|
nghttp2_http.c
|
||||||
|
nghttp2_rcbuf.c
|
||||||
|
nghttp2_debug.c
|
||||||
|
)
|
||||||
|
|
||||||
|
set(NGHTTP2_RES "")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
configure_file(
|
||||||
|
version.rc.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/version.rc
|
||||||
|
@ONLY)
|
||||||
|
|
||||||
|
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Public shared library
|
||||||
|
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES} ${NGHTTP2_RES})
|
||||||
|
set_target_properties(nghttp2 PROPERTIES
|
||||||
|
COMPILE_FLAGS "${WARNCFLAGS}"
|
||||||
|
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||||
|
C_VISIBILITY_PRESET hidden
|
||||||
|
)
|
||||||
|
|
||||||
|
if(HAVE_CUNIT)
|
||||||
|
# Static library (for unittests because of symbol visibility)
|
||||||
|
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
|
||||||
|
set_target_properties(nghttp2_static PROPERTIES
|
||||||
|
COMPILE_FLAGS "${WARNCFLAGS}"
|
||||||
|
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
|
||||||
|
ARCHIVE_OUTPUT_NAME nghttp2
|
||||||
|
)
|
||||||
|
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS nghttp2
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
|
||||||
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
SUBDIRS = includes
|
SUBDIRS = includes
|
||||||
|
|
||||||
EXTRA_DIST = Makefile.msvc
|
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
|
||||||
|
|
||||||
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
|
||||||
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
|
||||||
@@ -47,7 +47,9 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
|
|||||||
nghttp2_option.c \
|
nghttp2_option.c \
|
||||||
nghttp2_callbacks.c \
|
nghttp2_callbacks.c \
|
||||||
nghttp2_mem.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 \
|
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
|
||||||
nghttp2_frame.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_option.h \
|
||||||
nghttp2_callbacks.h \
|
nghttp2_callbacks.h \
|
||||||
nghttp2_mem.h \
|
nghttp2_mem.h \
|
||||||
nghttp2_http.h
|
nghttp2_http.h \
|
||||||
|
nghttp2_rcbuf.h \
|
||||||
|
nghttp2_debug.h
|
||||||
|
|
||||||
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
|
||||||
libnghttp2_la_LDFLAGS = -no-undefined \
|
libnghttp2_la_LDFLAGS = -no-undefined \
|
||||||
|
|||||||
@@ -12,16 +12,16 @@
|
|||||||
#
|
#
|
||||||
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
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))
|
_VERSION := $(subst ., ,$(_VERSION))
|
||||||
VER_MAJOR := $(word 1,$(_VERSION))
|
VER_MAJOR := $(word 1,$(_VERSION))
|
||||||
VER_MINOR := $(word 2,$(_VERSION))
|
VER_MINOR := $(word 2,$(_VERSION))
|
||||||
VER_MICRO := $(word 3,$(_VERSION))
|
VER_MICRO := $(word 3,$(_VERSION))
|
||||||
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO)
|
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)'
|
GENERATED := 'Generated by $(realpath Makefile.MSVC)'
|
||||||
|
|
||||||
@@ -90,7 +90,8 @@ NGHTTP2_SRC := nghttp2_pq.c \
|
|||||||
nghttp2_option.c \
|
nghttp2_option.c \
|
||||||
nghttp2_callbacks.c \
|
nghttp2_callbacks.c \
|
||||||
nghttp2_mem.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_R := $(addprefix $(OBJ_DIR)/r_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
|
||||||
NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(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
|
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 'Welcome to NgHTTP2 (release + debug).'
|
||||||
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
|
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
|
||||||
|
|
||||||
@@ -193,17 +194,17 @@ $(OBJ_DIR)/d_%.obj: %.c $(THIS_MAKEFILE)
|
|||||||
@echo
|
@echo
|
||||||
|
|
||||||
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
||||||
$(RC) -nologo -D_RELEASE -Fo $@ $<
|
$(RC) -D_RELEASE -Fo $@ $<
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
|
||||||
$(RC) -nologo -D_DEBUG -Fo $@ $<
|
$(RC) -D_DEBUG -Fo $@ $<
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
|
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
|
||||||
sed < includes/nghttp2/nghttp2ver.h.in \
|
sed < includes/nghttp2/nghttp2ver.h.in \
|
||||||
-e 's/@PACKAGE_VERSION@/$(VERSION)/g' \
|
-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 $@
|
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
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
EXTRA_DIST = CMakeLists.txt
|
||||||
|
|
||||||
nobase_include_HEADERS = nghttp2/nghttp2.h nghttp2/nghttp2ver.h
|
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 <stdio.h>
|
||||||
|
|
||||||
#include "nghttp2_helper.h"
|
#include "nghttp2_helper.h"
|
||||||
|
#include "nghttp2_debug.h"
|
||||||
|
|
||||||
void nghttp2_buf_init(nghttp2_buf *buf) {
|
void nghttp2_buf_init(nghttp2_buf *buf) {
|
||||||
buf->begin = NULL;
|
buf->begin = NULL;
|
||||||
@@ -223,13 +224,54 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||||
|
size_t veclen, nghttp2_mem *mem) {
|
||||||
|
size_t i = 0;
|
||||||
|
nghttp2_buf_chain *cur_chain;
|
||||||
|
nghttp2_buf_chain *head_chain;
|
||||||
|
nghttp2_buf_chain **dst_chain = &head_chain;
|
||||||
|
|
||||||
|
if (veclen == 0) {
|
||||||
|
return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
head_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain) * veclen);
|
||||||
|
if (head_chain == NULL) {
|
||||||
|
return NGHTTP2_ERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < veclen; ++i) {
|
||||||
|
cur_chain = &head_chain[i];
|
||||||
|
cur_chain->next = NULL;
|
||||||
|
nghttp2_buf_wrap_init(&cur_chain->buf, vec[i].base, vec[i].len);
|
||||||
|
|
||||||
|
*dst_chain = cur_chain;
|
||||||
|
dst_chain = &cur_chain->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufs->mem = mem;
|
||||||
|
bufs->offset = 0;
|
||||||
|
|
||||||
|
bufs->head = head_chain;
|
||||||
|
bufs->cur = bufs->head;
|
||||||
|
|
||||||
|
/* We don't use chunk_length since no allocation is expected. */
|
||||||
|
bufs->chunk_length = 0;
|
||||||
|
bufs->chunk_used = veclen;
|
||||||
|
bufs->max_chunk = veclen;
|
||||||
|
bufs->chunk_keep = veclen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
|
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
|
||||||
if (bufs == NULL) {
|
if (bufs == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nghttp2_mem_free(bufs->mem, bufs->head);
|
if (bufs->head) {
|
||||||
bufs->head = NULL;
|
nghttp2_mem_free(bufs->mem, bufs->head);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
|
||||||
@@ -256,12 +298,6 @@ size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t bufs_avail(nghttp2_bufs *bufs) {
|
|
||||||
return nghttp2_buf_avail(&bufs->cur->buf) +
|
|
||||||
(bufs->chunk_length - bufs->offset) *
|
|
||||||
(bufs->max_chunk - bufs->chunk_used);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
||||||
int rv;
|
int rv;
|
||||||
nghttp2_buf_chain *chain;
|
nghttp2_buf_chain *chain;
|
||||||
@@ -281,9 +317,8 @@ static int bufs_alloc_chain(nghttp2_bufs *bufs) {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr,
|
DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
||||||
"new buffer %zu bytes allocated for bufs %p, used %zu\n",
|
bufs->chunk_length, bufs, bufs->chunk_used);
|
||||||
bufs->chunk_length, bufs, bufs->chunk_used));
|
|
||||||
|
|
||||||
++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;
|
nghttp2_buf *buf;
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
|
|
||||||
if (bufs_avail(bufs) < len) {
|
|
||||||
return NGHTTP2_ERR_BUFFER_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = data;
|
p = data;
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ typedef struct {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes the |buf|. No memory is allocated in this function. Use
|
* 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);
|
void nghttp2_buf_init(nghttp2_buf *buf);
|
||||||
|
|
||||||
@@ -138,7 +138,9 @@ typedef struct {
|
|||||||
nghttp2_buf_chain *cur;
|
nghttp2_buf_chain *cur;
|
||||||
/* Memory allocator */
|
/* Memory allocator */
|
||||||
nghttp2_mem *mem;
|
nghttp2_mem *mem;
|
||||||
/* The buffer capacity of each buf */
|
/* 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;
|
size_t chunk_length;
|
||||||
/* The maximum number of nghttp2_buf_chain */
|
/* The maximum number of nghttp2_buf_chain */
|
||||||
size_t max_chunk;
|
size_t max_chunk;
|
||||||
@@ -197,10 +199,13 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
|||||||
/*
|
/*
|
||||||
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
||||||
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
||||||
* is fixed and no 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
|
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
||||||
* for |bufs|, use nghttp2_bufs_wrap_free().
|
* for |bufs|, use nghttp2_bufs_wrap_free().
|
||||||
*
|
*
|
||||||
|
* Don't use the function which performs allocation, such as
|
||||||
|
* nghttp2_bufs_realloc().
|
||||||
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
*
|
*
|
||||||
@@ -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,
|
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||||
nghttp2_mem *mem);
|
nghttp2_mem *mem);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes |bufs| using supplied |veclen| size of buf vector
|
||||||
|
* |vec|. The number of buffers is fixed and no extra chunk buffer is
|
||||||
|
* allocated. In other words, max_chunk = chunk_keep = |in_len|. To
|
||||||
|
* free the resource allocated for |bufs|, use
|
||||||
|
* nghttp2_bufs_wrap_free().
|
||||||
|
*
|
||||||
|
* Don't use the function which performs allocation, such as
|
||||||
|
* nghttp2_bufs_realloc().
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_NOMEM
|
||||||
|
* Out of memory.
|
||||||
|
*/
|
||||||
|
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
|
||||||
|
size_t veclen, nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frees any related resource to the |bufs|. This function does not
|
* Frees any related resource to the |bufs|. This function does not
|
||||||
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||||
@@ -312,8 +336,8 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copies all data stored in |bufs| to the contagious buffer. This
|
* Copies all data stored in |bufs| to the contiguous buffer. This
|
||||||
* function allocates the contagious memory to store all data in
|
* function allocates the contiguous memory to store all data in
|
||||||
* |bufs| and assigns it to |*out|.
|
* |bufs| and assigns it to |*out|.
|
||||||
*
|
*
|
||||||
* The contents of |bufs| is left unchanged.
|
* 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)
|
#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);
|
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;
|
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(
|
void nghttp2_session_callbacks_set_select_padding_callback(
|
||||||
nghttp2_session_callbacks *cbs,
|
nghttp2_session_callbacks *cbs,
|
||||||
nghttp2_select_padding_callback select_padding_callback) {
|
nghttp2_select_padding_callback select_padding_callback) {
|
||||||
@@ -127,3 +145,26 @@ void nghttp2_session_callbacks_set_send_data_callback(
|
|||||||
nghttp2_send_data_callback send_data_callback) {
|
nghttp2_send_data_callback send_data_callback) {
|
||||||
cbs->send_data_callback = send_data_callback;
|
cbs->send_data_callback = send_data_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nghttp2_session_callbacks_set_pack_extension_callback(
|
||||||
|
nghttp2_session_callbacks *cbs,
|
||||||
|
nghttp2_pack_extension_callback pack_extension_callback) {
|
||||||
|
cbs->pack_extension_callback = pack_extension_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_session_callbacks_set_unpack_extension_callback(
|
||||||
|
nghttp2_session_callbacks *cbs,
|
||||||
|
nghttp2_unpack_extension_callback unpack_extension_callback) {
|
||||||
|
cbs->unpack_extension_callback = unpack_extension_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
|
||||||
|
nghttp2_session_callbacks *cbs,
|
||||||
|
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) {
|
||||||
|
cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_session_callbacks_set_error_callback(
|
||||||
|
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
|
||||||
|
cbs->error_callback = error_callback;
|
||||||
|
}
|
||||||
|
|||||||
@@ -91,6 +91,14 @@ struct nghttp2_session_callbacks {
|
|||||||
* received.
|
* received.
|
||||||
*/
|
*/
|
||||||
nghttp2_on_header_callback on_header_callback;
|
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
|
* Callback function invoked when the library asks application how
|
||||||
* many padding bytes are required for the transmission of the given
|
* many padding bytes are required for the transmission of the given
|
||||||
@@ -107,6 +115,10 @@ struct nghttp2_session_callbacks {
|
|||||||
*/
|
*/
|
||||||
nghttp2_on_begin_frame_callback on_begin_frame_callback;
|
nghttp2_on_begin_frame_callback on_begin_frame_callback;
|
||||||
nghttp2_send_data_callback send_data_callback;
|
nghttp2_send_data_callback send_data_callback;
|
||||||
|
nghttp2_pack_extension_callback pack_extension_callback;
|
||||||
|
nghttp2_unpack_extension_callback unpack_extension_callback;
|
||||||
|
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
||||||
|
nghttp2_error_callback error_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NGHTTP2_CALLBACKS_H */
|
#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_helper.h"
|
||||||
#include "nghttp2_net.h"
|
#include "nghttp2_net.h"
|
||||||
#include "nghttp2_priority_spec.h"
|
#include "nghttp2_priority_spec.h"
|
||||||
|
#include "nghttp2_debug.h"
|
||||||
|
|
||||||
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) {
|
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) {
|
||||||
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
|
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
|
||||||
@@ -184,6 +185,39 @@ void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
|
|||||||
|
|
||||||
void nghttp2_frame_data_free(nghttp2_data *frame _U_) {}
|
void nghttp2_frame_data_free(nghttp2_data *frame _U_) {}
|
||||||
|
|
||||||
|
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
||||||
|
uint8_t flags, int32_t stream_id,
|
||||||
|
void *payload) {
|
||||||
|
nghttp2_frame_hd_init(&frame->hd, 0, type, flags, stream_id);
|
||||||
|
frame->payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_frame_extension_free(nghttp2_extension *frame _U_) {}
|
||||||
|
|
||||||
|
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
||||||
|
uint8_t *origin, size_t origin_len,
|
||||||
|
uint8_t *field_value, size_t field_value_len) {
|
||||||
|
nghttp2_ext_altsvc *altsvc;
|
||||||
|
|
||||||
|
nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
|
||||||
|
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
|
||||||
|
|
||||||
|
altsvc = frame->payload;
|
||||||
|
altsvc->origin = origin;
|
||||||
|
altsvc->origin_len = origin_len;
|
||||||
|
altsvc->field_value = field_value;
|
||||||
|
altsvc->field_value_len = field_value_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
|
||||||
|
nghttp2_ext_altsvc *altsvc;
|
||||||
|
|
||||||
|
altsvc = frame->payload;
|
||||||
|
/* We use the same buffer for altsvc->origin and
|
||||||
|
altsvc->field_value. */
|
||||||
|
nghttp2_mem_free(mem, altsvc->origin);
|
||||||
|
}
|
||||||
|
|
||||||
size_t nghttp2_frame_priority_len(uint8_t flags) {
|
size_t nghttp2_frame_priority_len(uint8_t flags) {
|
||||||
if (flags & NGHTTP2_FLAG_PRIORITY) {
|
if (flags & NGHTTP2_FLAG_PRIORITY) {
|
||||||
return NGHTTP2_PRIORITY_SPECLEN;
|
return NGHTTP2_PRIORITY_SPECLEN;
|
||||||
@@ -219,8 +253,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
|||||||
hd = *frame_hd;
|
hd = *frame_hd;
|
||||||
hd.length = nghttp2_buf_len(buf);
|
hd.length = nghttp2_buf_len(buf);
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n",
|
DEBUGF("send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n", hd.length);
|
||||||
hd.length));
|
|
||||||
|
|
||||||
/* We have multiple frame buffers, which means one or more
|
/* We have multiple frame buffers, which means one or more
|
||||||
CONTINUATION frame is involved. Remove END_HEADERS flag from the
|
CONTINUATION frame is involved. Remove END_HEADERS flag from the
|
||||||
@@ -245,8 +278,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
|||||||
|
|
||||||
hd.length = nghttp2_buf_len(buf);
|
hd.length = nghttp2_buf_len(buf);
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "send: int CONTINUATION, payloadlen=%zu\n",
|
DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length);
|
||||||
hd.length));
|
|
||||||
|
|
||||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||||
@@ -257,8 +289,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
|
|||||||
/* Set END_HEADERS flag for last CONTINUATION */
|
/* Set END_HEADERS flag for last CONTINUATION */
|
||||||
hd.flags = NGHTTP2_FLAG_END_HEADERS;
|
hd.flags = NGHTTP2_FLAG_END_HEADERS;
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "send: last CONTINUATION, payloadlen=%zu\n",
|
DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length);
|
||||||
hd.length));
|
|
||||||
|
|
||||||
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
buf->pos -= NGHTTP2_FRAME_HDLEN;
|
||||||
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
|
||||||
@@ -430,25 +461,11 @@ size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
|
|||||||
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
|
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||||
nghttp2_settings_entry *iv,
|
nghttp2_settings_entry *iv,
|
||||||
size_t niv, nghttp2_mem *mem) {
|
size_t niv) {
|
||||||
size_t payloadlen = niv * sizeof(nghttp2_settings_entry);
|
frame->iv = iv;
|
||||||
|
|
||||||
if (niv == 0) {
|
|
||||||
frame->iv = NULL;
|
|
||||||
} else {
|
|
||||||
frame->iv = nghttp2_mem_malloc(mem, payloadlen);
|
|
||||||
|
|
||||||
if (frame->iv == NULL) {
|
|
||||||
return NGHTTP2_ERR_NOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(frame->iv, iv, payloadlen);
|
|
||||||
}
|
|
||||||
|
|
||||||
frame->niv = niv;
|
frame->niv = niv;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
||||||
@@ -659,6 +676,79 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
|||||||
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
|
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,
|
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
||||||
size_t niv, nghttp2_mem *mem) {
|
size_t niv, nghttp2_mem *mem) {
|
||||||
nghttp2_settings_entry *iv_copy;
|
nghttp2_settings_entry *iv_copy;
|
||||||
@@ -779,7 +869,9 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
|||||||
p->name = nva[i].name;
|
p->name = nva[i].name;
|
||||||
p->namelen = nva[i].namelen;
|
p->namelen = nva[i].namelen;
|
||||||
} else {
|
} else {
|
||||||
memcpy(data, nva[i].name, nva[i].namelen);
|
if (nva[i].namelen) {
|
||||||
|
memcpy(data, nva[i].name, nva[i].namelen);
|
||||||
|
}
|
||||||
p->name = data;
|
p->name = data;
|
||||||
p->namelen = nva[i].namelen;
|
p->namelen = nva[i].namelen;
|
||||||
data[p->namelen] = '\0';
|
data[p->namelen] = '\0';
|
||||||
@@ -791,7 +883,9 @@ int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
|||||||
p->value = nva[i].value;
|
p->value = nva[i].value;
|
||||||
p->valuelen = nva[i].valuelen;
|
p->valuelen = nva[i].valuelen;
|
||||||
} else {
|
} else {
|
||||||
memcpy(data, nva[i].value, nva[i].valuelen);
|
if (nva[i].valuelen) {
|
||||||
|
memcpy(data, nva[i].value, nva[i].valuelen);
|
||||||
|
}
|
||||||
p->value = data;
|
p->value = data;
|
||||||
p->valuelen = nva[i].valuelen;
|
p->valuelen = nva[i].valuelen;
|
||||||
data[p->valuelen] = '\0';
|
data[p->valuelen] = '\0';
|
||||||
@@ -838,7 +932,7 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
|
|||||||
size_t trail_padlen;
|
size_t trail_padlen;
|
||||||
size_t newlen;
|
size_t newlen;
|
||||||
|
|
||||||
DEBUGF(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);
|
memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
|
||||||
|
|
||||||
@@ -868,7 +962,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|||||||
nghttp2_buf *buf;
|
nghttp2_buf *buf;
|
||||||
|
|
||||||
if (padlen == 0) {
|
if (padlen == 0) {
|
||||||
DEBUGF(fprintf(stderr, "send: padlen = 0, nothing to do\n"));
|
DEBUGF("send: padlen = 0, nothing to do\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -902,8 +996,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
|||||||
hd->length += padlen;
|
hd->length += padlen;
|
||||||
hd->flags |= NGHTTP2_FLAG_PADDED;
|
hd->flags |= NGHTTP2_FLAG_PADDED;
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "send: final payloadlen=%zu, padlen=%zu\n", hd->length,
|
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
|
||||||
padlen));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,14 +52,12 @@
|
|||||||
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
||||||
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
||||||
|
|
||||||
/* Number of inbound buffer */
|
|
||||||
#define NGHTTP2_FRAMEBUF_MAX_NUM 5
|
|
||||||
|
|
||||||
/* The default length of DATA frame payload. */
|
/* The default length of DATA frame payload. */
|
||||||
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
||||||
|
|
||||||
/* Maximum headers payload length, calculated in compressed form.
|
/* Maximum headers block size to send, calculated using
|
||||||
This applies to transmission only. */
|
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
|
#define NGHTTP2_MAX_HEADERSLEN 65536
|
||||||
|
|
||||||
/* The number of bytes for each SETTINGS entry */
|
/* The number of bytes for each SETTINGS entry */
|
||||||
@@ -72,7 +70,7 @@
|
|||||||
#define NGHTTP2_MAX_PADLEN 256
|
#define NGHTTP2_MAX_PADLEN 256
|
||||||
|
|
||||||
/* Union of extension frame payload */
|
/* 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);
|
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);
|
const uint8_t *payload);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Makes a copy of |iv| in frame->settings.iv. The |niv| is assigned
|
* Initializes payload of frame->settings. The |frame| takes
|
||||||
* to frame->settings.niv.
|
* ownership of |iv|.
|
||||||
*
|
|
||||||
* This function returns 0 if it succeeds or one of the following
|
|
||||||
* negative error codes:
|
|
||||||
*
|
|
||||||
* NGHTTP2_ERR_NOMEM
|
|
||||||
* Out of memory.
|
|
||||||
*/
|
*/
|
||||||
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||||
nghttp2_settings_entry *iv,
|
nghttp2_settings_entry *iv,
|
||||||
size_t niv, nghttp2_mem *mem);
|
size_t niv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
|
* 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,
|
const uint8_t *payload,
|
||||||
size_t payloadlen);
|
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
|
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
||||||
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
||||||
@@ -439,6 +470,31 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
|
|||||||
|
|
||||||
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
||||||
|
|
||||||
|
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
||||||
|
uint8_t flags, int32_t stream_id,
|
||||||
|
void *payload);
|
||||||
|
|
||||||
|
void nghttp2_frame_extension_free(nghttp2_extension *frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes ALTSVC frame |frame| with given values. This function
|
||||||
|
* assumes that frame->payload points to nghttp2_ext_altsvc object.
|
||||||
|
* Also |origin| and |field_value| are allocated in single buffer,
|
||||||
|
* starting |origin|. On success, this function takes ownership of
|
||||||
|
* |origin|, so caller must not free it.
|
||||||
|
*/
|
||||||
|
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
||||||
|
uint8_t *origin, size_t origin_len,
|
||||||
|
uint8_t *field_value, size_t field_value_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frees up resources under |frame|. This function does not free
|
||||||
|
* nghttp2_ext_altsvc object pointed by frame->payload. This function
|
||||||
|
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
|
||||||
|
* other fields must be allocated in the same buffer with origin.
|
||||||
|
*/
|
||||||
|
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the number of padding bytes after payload. The total
|
* Returns the number of padding bytes after payload. The total
|
||||||
* padding length is given in the |padlen|. The returned value does
|
* padding length is given in the |padlen|. The returned value does
|
||||||
|
|||||||
1185
lib/nghttp2_hd.c
1185
lib/nghttp2_hd.c
File diff suppressed because it is too large
Load Diff
136
lib/nghttp2_hd.h
136
lib/nghttp2_hd.h
@@ -34,6 +34,7 @@
|
|||||||
#include "nghttp2_hd_huffman.h"
|
#include "nghttp2_hd_huffman.h"
|
||||||
#include "nghttp2_buf.h"
|
#include "nghttp2_buf.h"
|
||||||
#include "nghttp2_mem.h"
|
#include "nghttp2_mem.h"
|
||||||
|
#include "nghttp2_rcbuf.h"
|
||||||
|
|
||||||
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
||||||
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
||||||
@@ -109,28 +110,32 @@ typedef enum {
|
|||||||
NGHTTP2_TOKEN_CONNECTION,
|
NGHTTP2_TOKEN_CONNECTION,
|
||||||
NGHTTP2_TOKEN_KEEP_ALIVE,
|
NGHTTP2_TOKEN_KEEP_ALIVE,
|
||||||
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
||||||
NGHTTP2_TOKEN_UPGRADE
|
NGHTTP2_TOKEN_UPGRADE,
|
||||||
} nghttp2_token;
|
} 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;
|
struct nghttp2_hd_entry;
|
||||||
typedef struct nghttp2_hd_entry 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 {
|
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. */
|
/* The next entry which shares same bucket in hash table. */
|
||||||
nghttp2_hd_entry *next;
|
nghttp2_hd_entry *next;
|
||||||
/* The sequence number. We will increment it by one whenever we
|
/* The sequence number. We will increment it by one whenever we
|
||||||
@@ -138,14 +143,17 @@ struct nghttp2_hd_entry {
|
|||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
/* The hash value for header name (nv.name). */
|
/* The hash value for header name (nv.name). */
|
||||||
uint32_t hash;
|
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 {
|
typedef struct {
|
||||||
nghttp2_hd_entry **buffer;
|
nghttp2_hd_entry **buffer;
|
||||||
size_t mask;
|
size_t mask;
|
||||||
@@ -219,24 +227,18 @@ struct nghttp2_hd_deflater {
|
|||||||
|
|
||||||
struct nghttp2_hd_inflater {
|
struct nghttp2_hd_inflater {
|
||||||
nghttp2_hd_context ctx;
|
nghttp2_hd_context ctx;
|
||||||
/* header buffer */
|
|
||||||
nghttp2_bufs nvbufs;
|
|
||||||
/* Stores current state of huffman decoding */
|
/* Stores current state of huffman decoding */
|
||||||
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
||||||
/* Pointer to the nghttp2_hd_entry which is used current header
|
/* header buffer */
|
||||||
emission. This is required because in some cases the
|
nghttp2_buf namebuf, valuebuf;
|
||||||
ent_keep->ref == 0 and we have to keep track of it. */
|
nghttp2_rcbuf *namercbuf, *valuercbuf;
|
||||||
nghttp2_hd_entry *ent_keep;
|
/* Pointer to the name/value pair which are used in the current
|
||||||
/* Pointer to the name/value pair buffer which is used in the
|
header emission. */
|
||||||
current header emission. */
|
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
|
||||||
uint8_t *nv_keep;
|
|
||||||
/* The number of bytes to read */
|
/* The number of bytes to read */
|
||||||
size_t left;
|
size_t left;
|
||||||
/* The index in indexed repr or indexed name */
|
/* The index in indexed repr or indexed name */
|
||||||
size_t index;
|
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
|
/* The maximum header table size the inflater supports. This is the
|
||||||
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
||||||
size_t settings_hd_table_bufsize_max;
|
size_t settings_hd_table_bufsize_max;
|
||||||
@@ -256,24 +258,16 @@ struct nghttp2_hd_inflater {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
|
* Initializes the |ent| members. The reference counts of nv->name
|
||||||
* set in the |flags|, the content pointed by the |name| with length
|
* and nv->value are increased by one for each.
|
||||||
* |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.
|
|
||||||
*/
|
*/
|
||||||
int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags, uint8_t *name,
|
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
|
||||||
size_t namelen, uint8_t *value, size_t valuelen,
|
|
||||||
int token, nghttp2_mem *mem);
|
|
||||||
|
|
||||||
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.
|
* Initializes |deflater| for deflating name/values pairs.
|
||||||
@@ -294,7 +288,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
|||||||
/*
|
/*
|
||||||
* Initializes |deflater| for deflating name/values pairs.
|
* Initializes |deflater| for deflating name/values pairs.
|
||||||
*
|
*
|
||||||
* The encoder only uses up to |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
|
* for header table even if the larger value is specified later in
|
||||||
* nghttp2_hd_change_table_size().
|
* nghttp2_hd_change_table_size().
|
||||||
*
|
*
|
||||||
@@ -305,7 +299,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
|||||||
* Out of memory.
|
* Out of memory.
|
||||||
*/
|
*/
|
||||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||||
size_t deflate_hd_table_bufsize_max,
|
size_t max_deflate_dynamic_table_size,
|
||||||
nghttp2_mem *mem);
|
nghttp2_mem *mem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -354,16 +348,14 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
|
|||||||
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Similar to nghttp2_hd_inflate_hd(), but this takes additional
|
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
|
||||||
* output parameter |token|. On successful header emission, it
|
* instead of nghttp2_nv as output parameter |nv_out|. Other than
|
||||||
* contains nghttp2_token value for nv_out->name. It could be -1 if
|
* that return values and semantics are the same as
|
||||||
* we don't have enum value for the name. Other than that return
|
* nghttp2_hd_inflate_hd().
|
||||||
* values and semantics are the same as nghttp2_hd_inflate_hd().
|
|
||||||
*/
|
*/
|
||||||
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
|
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
|
||||||
nghttp2_nv *nv_out, int *inflate_flags,
|
nghttp2_hd_nv *nv_out, int *inflate_flags,
|
||||||
int *token, uint8_t *in, size_t inlen,
|
const uint8_t *in, size_t inlen, int in_final);
|
||||||
int in_final);
|
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||||
@@ -377,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);
|
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* For unittesting purpose */
|
||||||
nghttp2_hd_entry *nghttp2_hd_table_get(nghttp2_hd_context *context,
|
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
||||||
size_t index);
|
|
||||||
|
|
||||||
/* For unittesting purpose */
|
/* 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,
|
uint32_t initial, size_t shift, uint8_t *in,
|
||||||
uint8_t *last, size_t prefix);
|
uint8_t *last, size_t prefix);
|
||||||
|
|
||||||
@@ -414,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);
|
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
|
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
|
||||||
* will be added to |dest|. This function may expand |dest| as
|
* will be written to |buf|. This function assumes that |buf| has the
|
||||||
* needed. The caller is responsible to release the memory of |dest|
|
* enough room to store the decoded byte string.
|
||||||
* by calling nghttp2_bufs_free().
|
|
||||||
*
|
*
|
||||||
* The caller must set the |final| to nonzero if the given input is
|
* The caller must set the |fin| to nonzero if the given input is the
|
||||||
* the final block.
|
* final block.
|
||||||
*
|
*
|
||||||
* This function returns the number of read bytes from the |in|.
|
* This function returns the number of read bytes from the |in|.
|
||||||
*
|
*
|
||||||
@@ -430,13 +420,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
|||||||
*
|
*
|
||||||
* NGHTTP2_ERR_NOMEM
|
* NGHTTP2_ERR_NOMEM
|
||||||
* Out of memory.
|
* Out of memory.
|
||||||
* NGHTTP2_ERR_BUFFER_ERROR
|
|
||||||
* Maximum buffer capacity size exceeded.
|
|
||||||
* NGHTTP2_ERR_HEADER_COMP
|
* NGHTTP2_ERR_HEADER_COMP
|
||||||
* Decoding process has failed.
|
* Decoding process has failed.
|
||||||
*/
|
*/
|
||||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||||
nghttp2_bufs *bufs, const uint8_t *src,
|
nghttp2_buf *buf, const uint8_t *src,
|
||||||
size_t srclen, int final);
|
size_t srclen, int fin);
|
||||||
|
|
||||||
#endif /* NGHTTP2_HD_H */
|
#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);
|
code <<= 8 - (nbits & 0x7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we lose at most 3 bytes, but it is not critical in practice */
|
|
||||||
if (*avail_ptr < (nbits + 7) / 8) {
|
if (*avail_ptr < (nbits + 7) / 8) {
|
||||||
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) {
|
if (rv != 0) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
|
||||||
/* we assume that we at least 3 buffer space available */
|
return (ssize_t)(8 - nbits);
|
||||||
assert(*avail_ptr >= 3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fast path, since most code is less than 8 */
|
/* 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;
|
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,
|
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 srclen, int final) {
|
||||||
size_t i;
|
size_t i;
|
||||||
int rv;
|
|
||||||
size_t avail;
|
|
||||||
|
|
||||||
avail = nghttp2_bufs_cur_avail(bufs);
|
|
||||||
|
|
||||||
/* We use the decoding algorithm described in
|
/* We use the decoding algorithm described in
|
||||||
http://graphics.ics.uci.edu/pub/Prefix.pdf */
|
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;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
if (t->flags & NGHTTP2_HUFF_SYM) {
|
||||||
/* this is macro, and may return from this function on error */
|
*buf->last++ = t->sym;
|
||||||
hd_huff_decode_sym_emit(bufs, t->sym, avail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t = &huff_decode_table[t->state][src[i] & 0xf];
|
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;
|
return NGHTTP2_ERR_HEADER_COMP;
|
||||||
}
|
}
|
||||||
if (t->flags & NGHTTP2_HUFF_SYM) {
|
if (t->flags & NGHTTP2_HUFF_SYM) {
|
||||||
/* this is macro, and may return from this function on error */
|
*buf->last++ = t->sym;
|
||||||
hd_huff_decode_sym_emit(bufs, t->sym, avail);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->state = t->state;
|
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. */
|
account it in *delta_ptr. */
|
||||||
*recv_window_size_ptr = recv_reduction_delta;
|
*recv_window_size_ptr = recv_reduction_delta;
|
||||||
}
|
}
|
||||||
/* recv_reduction_delta must be paied from *delta_ptr, since it
|
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
||||||
was added in window size reduction (see below). */
|
added in window size reduction (see below). */
|
||||||
*delta_ptr -= recv_reduction_delta;
|
*delta_ptr -= recv_reduction_delta;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -213,6 +213,38 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||||
|
int32_t *recv_window_size_ptr,
|
||||||
|
int32_t *recv_reduction_ptr,
|
||||||
|
int32_t *delta_ptr) {
|
||||||
|
int32_t recv_reduction_delta;
|
||||||
|
int32_t delta;
|
||||||
|
|
||||||
|
delta = *delta_ptr;
|
||||||
|
|
||||||
|
assert(delta >= 0);
|
||||||
|
|
||||||
|
/* The delta size is strictly more than received bytes. Increase
|
||||||
|
local_window_size by that difference |delta|. */
|
||||||
|
if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
|
||||||
|
return NGHTTP2_ERR_FLOW_CONTROL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*local_window_size_ptr += delta;
|
||||||
|
/* If there is recv_reduction due to earlier window_size
|
||||||
|
reduction, we have to adjust it too. */
|
||||||
|
recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
|
||||||
|
*recv_reduction_ptr -= recv_reduction_delta;
|
||||||
|
|
||||||
|
*recv_window_size_ptr += recv_reduction_delta;
|
||||||
|
|
||||||
|
/* recv_reduction_delta must be paid from *delta_ptr, since it was
|
||||||
|
added in window size reduction (see below). */
|
||||||
|
*delta_ptr -= recv_reduction_delta;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int nghttp2_should_send_window_update(int32_t local_window_size,
|
int nghttp2_should_send_window_update(int32_t local_window_size,
|
||||||
int32_t recv_window_size) {
|
int32_t recv_window_size) {
|
||||||
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
|
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
|
||||||
@@ -288,6 +320,8 @@ const char *nghttp2_strerror(int error_code) {
|
|||||||
return "Stream was refused";
|
return "Stream was refused";
|
||||||
case NGHTTP2_ERR_INTERNAL:
|
case NGHTTP2_ERR_INTERNAL:
|
||||||
return "Internal error";
|
return "Internal error";
|
||||||
|
case NGHTTP2_ERR_CANCEL:
|
||||||
|
return "Cancel";
|
||||||
case NGHTTP2_ERR_NOMEM:
|
case NGHTTP2_ERR_NOMEM:
|
||||||
return "Out of memory";
|
return "Out of memory";
|
||||||
case NGHTTP2_ERR_CALLBACK_FAILURE:
|
case NGHTTP2_ERR_CALLBACK_FAILURE:
|
||||||
@@ -304,58 +338,70 @@ const char *nghttp2_strerror(int error_code) {
|
|||||||
|
|
||||||
/* Generated by gennmchartbl.py */
|
/* Generated by gennmchartbl.py */
|
||||||
static int VALID_HD_NAME_CHARS[] = {
|
static int VALID_HD_NAME_CHARS[] = {
|
||||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
||||||
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
|
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
||||||
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
|
||||||
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||||
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
||||||
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
|
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
||||||
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||||
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */,
|
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
|
||||||
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
|
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||||
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
|
||||||
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
|
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
|
||||||
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
|
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
||||||
0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
|
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||||
0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
|
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
|
||||||
0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
|
||||||
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
|
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
|
||||||
0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
|
0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
|
||||||
0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */,
|
0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
|
||||||
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
|
||||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
|
||||||
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
|
||||||
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
|
||||||
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
|
||||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */,
|
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||||
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
|
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
||||||
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
|
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
||||||
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
||||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
|
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
||||||
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
|
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||||
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
|
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
|
||||||
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
|
||||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
|
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
|
||||||
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
|
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
|
||||||
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
|
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||||
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
|
||||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
|
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
|
||||||
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
|
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
|
||||||
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
|
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
|
||||||
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
|
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
|
||||||
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
|
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
|
||||||
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
|
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
|
||||||
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
|
||||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
|
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||||
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
|
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
|
||||||
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
|
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
|
||||||
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
|
||||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
|
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
|
||||||
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
|
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||||
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
|
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
|
||||||
0 /* 0xff */
|
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) {
|
int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
||||||
@@ -380,58 +426,70 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) {
|
|||||||
|
|
||||||
/* Generated by genvchartbl.py */
|
/* Generated by genvchartbl.py */
|
||||||
static int VALID_HD_VALUE_CHARS[] = {
|
static int VALID_HD_VALUE_CHARS[] = {
|
||||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
||||||
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 1 /* HT */,
|
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
||||||
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
|
||||||
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||||
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
||||||
0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 1 /* " */,
|
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
||||||
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
|
1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
|
||||||
1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
|
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||||
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
|
||||||
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
|
||||||
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */,
|
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
||||||
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
|
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||||
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
|
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||||
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
|
||||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
|
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
||||||
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
|
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
||||||
1 /* Z */, 1 /* [ */, 1 /* \ */, 1 /* ] */, 1 /* ^ */,
|
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
||||||
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
|
||||||
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
|
||||||
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
|
||||||
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
|
||||||
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */,
|
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||||
1 /* } */, 1 /* ~ */, 0 /* DEL */, 1 /* 0x80 */, 1 /* 0x81 */,
|
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
||||||
1 /* 0x82 */, 1 /* 0x83 */, 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */,
|
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
||||||
1 /* 0x87 */, 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
||||||
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, 1 /* 0x90 */,
|
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
||||||
1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, 1 /* 0x94 */, 1 /* 0x95 */,
|
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||||
1 /* 0x96 */, 1 /* 0x97 */, 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */,
|
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
|
||||||
1 /* 0x9b */, 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
|
||||||
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, 1 /* 0xa4 */,
|
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
|
||||||
1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, 1 /* 0xa8 */, 1 /* 0xa9 */,
|
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
|
||||||
1 /* 0xaa */, 1 /* 0xab */, 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */,
|
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
|
||||||
1 /* 0xaf */, 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
|
||||||
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, 1 /* 0xb8 */,
|
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
|
||||||
1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, 1 /* 0xbc */, 1 /* 0xbd */,
|
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
|
||||||
1 /* 0xbe */, 1 /* 0xbf */, 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */,
|
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
|
||||||
1 /* 0xc3 */, 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
|
||||||
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, 1 /* 0xcc */,
|
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
|
||||||
1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, 1 /* 0xd0 */, 1 /* 0xd1 */,
|
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
|
||||||
1 /* 0xd2 */, 1 /* 0xd3 */, 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */,
|
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
|
||||||
1 /* 0xd7 */, 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
|
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
|
||||||
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, 1 /* 0xe0 */,
|
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
|
||||||
1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, 1 /* 0xe4 */, 1 /* 0xe5 */,
|
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
|
||||||
1 /* 0xe6 */, 1 /* 0xe7 */, 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */,
|
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
|
||||||
1 /* 0xeb */, 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
|
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
|
||||||
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, 1 /* 0xf4 */,
|
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
|
||||||
1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, 1 /* 0xf8 */, 1 /* 0xf9 */,
|
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
|
||||||
1 /* 0xfa */, 1 /* 0xfb */, 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */,
|
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
|
||||||
1 /* 0xff */
|
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) {
|
int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
||||||
@@ -445,7 +503,46 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
|
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
|
||||||
|
if (len == 0) {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(dest, src, len);
|
memcpy(dest, src, len);
|
||||||
|
|
||||||
return dest + 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 *recv_reduction_ptr,
|
||||||
int32_t *delta_ptr);
|
int32_t *delta_ptr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function works like nghttp2_adjust_local_window_size(). The
|
||||||
|
* difference is that this function assumes *delta_ptr >= 0, and
|
||||||
|
* *recv_window_size_ptr is not decreased by *delta_ptr.
|
||||||
|
*
|
||||||
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
|
* negative error codes:
|
||||||
|
*
|
||||||
|
* NGHTTP2_ERR_FLOW_CONTROL
|
||||||
|
* local_window_size overflow or gets negative.
|
||||||
|
*/
|
||||||
|
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||||
|
int32_t *recv_window_size_ptr,
|
||||||
|
int32_t *recv_reduction_ptr,
|
||||||
|
int32_t *delta_ptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
||||||
* be sent.
|
* be sent.
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ static int lws(const uint8_t *s, size_t n) {
|
|||||||
return 1;
|
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) {
|
int flag) {
|
||||||
if (stream->http_flags & flag) {
|
if (stream->http_flags & flag) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (lws(nv->value, nv->valuelen)) {
|
if (lws(nv->value->base, nv->value->len)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
stream->http_flags = (uint16_t)(stream->http_flags | flag);
|
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)));
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
||||||
int token, int trailer) {
|
int trailer) {
|
||||||
if (nv->name[0] == ':') {
|
if (nv->name->base[0] == ':') {
|
||||||
if (trailer ||
|
if (trailer ||
|
||||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (token) {
|
switch (nv->token) {
|
||||||
case NGHTTP2_TOKEN__AUTHORITY:
|
case NGHTTP2_TOKEN__AUTHORITY:
|
||||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
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)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
switch (nv->valuelen) {
|
switch (nv->value->len) {
|
||||||
case 4:
|
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;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
switch (nv->value[6]) {
|
switch (nv->value->base[6]) {
|
||||||
case 'T':
|
case 'T':
|
||||||
if (lstreq("CONNECT", nv->value, nv->valuelen)) {
|
if (lstreq("CONNECT", nv->value->base, nv->value->len)) {
|
||||||
if (stream->stream_id % 2 == 0) {
|
if (stream->stream_id % 2 == 0) {
|
||||||
/* we won't allow CONNECT for push */
|
/* we won't allow CONNECT for push */
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
@@ -153,7 +153,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'S':
|
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;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
|
||||||
}
|
}
|
||||||
break;
|
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)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
if (nv->value[0] == '/') {
|
if (nv->value->base[0] == '/') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
|
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;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
|
||||||
}
|
}
|
||||||
break;
|
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)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
if ((nv->valuelen == 4 && memieq("http", nv->value, 4)) ||
|
if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) ||
|
||||||
(nv->valuelen == 5 && memieq("https", nv->value, 5))) {
|
(nv->value->len == 5 && memieq("https", nv->value->base, 5))) {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -195,7 +195,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
|||||||
if (stream->content_length != -1) {
|
if (stream->content_length != -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
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) {
|
if (stream->content_length == -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
@@ -209,51 +209,70 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
|||||||
case NGHTTP2_TOKEN_UPGRADE:
|
case NGHTTP2_TOKEN_UPGRADE:
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
case NGHTTP2_TOKEN_TE:
|
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;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (nv->name[0] == ':') {
|
if (nv->name->base[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv->name[0] != ':') {
|
if (nv->name->base[0] != ':') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
|
||||||
int token, int trailer) {
|
int trailer) {
|
||||||
if (nv->name[0] == ':') {
|
if (nv->name->base[0] == ':') {
|
||||||
if (trailer ||
|
if (trailer ||
|
||||||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (token) {
|
switch (nv->token) {
|
||||||
case NGHTTP2_TOKEN__STATUS: {
|
case NGHTTP2_TOKEN__STATUS: {
|
||||||
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
|
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
if (nv->valuelen != 3) {
|
if (nv->value->len != 3) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
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) {
|
if (stream->status_code == -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NGHTTP2_TOKEN_CONTENT_LENGTH: {
|
case NGHTTP2_TOKEN_CONTENT_LENGTH: {
|
||||||
|
if (stream->status_code == 204) {
|
||||||
|
/* content-length header field in 204 response is prohibited by
|
||||||
|
RFC 7230. But some widely used servers send content-length:
|
||||||
|
0. Until they get fixed, we ignore it. */
|
||||||
|
if (stream->content_length != -1) {
|
||||||
|
/* Found multiple content-length field */
|
||||||
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
|
}
|
||||||
|
if (!lstrieq("0", nv->value->base, nv->value->len)) {
|
||||||
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
|
}
|
||||||
|
stream->content_length = 0;
|
||||||
|
return NGHTTP2_ERR_REMOVE_HTTP_HEADER;
|
||||||
|
}
|
||||||
|
if (stream->status_code / 100 == 1 ||
|
||||||
|
(stream->status_code == 200 &&
|
||||||
|
(stream->http_flags & NGHTTP2_HTTP_FLAG_METH_CONNECT))) {
|
||||||
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
|
}
|
||||||
if (stream->content_length != -1) {
|
if (stream->content_length != -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
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) {
|
if (stream->content_length == -1) {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
@@ -267,17 +286,17 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
|||||||
case NGHTTP2_TOKEN_UPGRADE:
|
case NGHTTP2_TOKEN_UPGRADE:
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
case NGHTTP2_TOKEN_TE:
|
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;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (nv->name[0] == ':') {
|
if (nv->name->base[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nv->name[0] != ':') {
|
if (nv->name->base[0] != ':') {
|
||||||
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,58 +305,70 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
|
|||||||
|
|
||||||
/* Generated by genauthroitychartbl.py */
|
/* Generated by genauthroitychartbl.py */
|
||||||
static char VALID_AUTHORITY_CHARS[] = {
|
static char VALID_AUTHORITY_CHARS[] = {
|
||||||
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
|
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
|
||||||
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
|
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
|
||||||
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
|
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
|
||||||
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
|
||||||
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
|
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
|
||||||
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
|
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
|
||||||
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
|
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
|
||||||
0 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
|
||||||
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
|
0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */,
|
||||||
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
|
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
|
||||||
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
|
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
|
||||||
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
|
||||||
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 1 /* @ */,
|
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
|
||||||
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
|
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
|
||||||
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
|
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
|
||||||
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
|
||||||
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
|
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
|
||||||
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
|
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
|
||||||
1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 0 /* ^ */,
|
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
|
||||||
1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
|
||||||
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
|
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
|
||||||
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
|
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
|
||||||
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
|
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
|
||||||
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */,
|
||||||
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
|
0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
|
||||||
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
|
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
|
||||||
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
|
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
|
||||||
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
|
||||||
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
|
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
|
||||||
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
|
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
|
||||||
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
|
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
|
||||||
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
|
||||||
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
|
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
|
||||||
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
|
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
|
||||||
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
|
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
|
||||||
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
|
||||||
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
|
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
|
||||||
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
|
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
|
||||||
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
|
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
|
||||||
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
|
||||||
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
|
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
|
||||||
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
|
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
|
||||||
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
|
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
|
||||||
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
|
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
|
||||||
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
|
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
|
||||||
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
|
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
|
||||||
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
|
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
|
||||||
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
|
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
|
||||||
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
|
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
|
||||||
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
|
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
|
||||||
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
|
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
|
||||||
0 /* 0xff */
|
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) {
|
static int check_authority(const uint8_t *value, size_t len) {
|
||||||
@@ -375,7 +406,7 @@ static int check_scheme(const uint8_t *value, size_t len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
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 trailer) {
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
@@ -386,14 +417,14 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|||||||
this, we may disrupt many web sites and/or libraries. So we
|
this, we may disrupt many web sites and/or libraries. So we
|
||||||
become conservative here, and just ignore those illegal regular
|
become conservative here, and just ignore those illegal regular
|
||||||
headers. */
|
headers. */
|
||||||
if (!nghttp2_check_header_name(nv->name, nv->namelen)) {
|
if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) {
|
||||||
size_t i;
|
size_t i;
|
||||||
if (nv->namelen > 0 && nv->name[0] == ':') {
|
if (nv->name->len > 0 && nv->name->base[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
/* header field name must be lower-cased without exception */
|
/* header field name must be lower-cased without exception */
|
||||||
for (i = 0; i < nv->namelen; ++i) {
|
for (i = 0; i < nv->name->len; ++i) {
|
||||||
uint8_t c = nv->name[i];
|
uint8_t c = nv->name->base[i];
|
||||||
if ('A' <= c && c <= 'Z') {
|
if ('A' <= c && c <= 'Z') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
@@ -405,17 +436,18 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|||||||
return NGHTTP2_ERR_IGN_HTTP_HEADER;
|
return NGHTTP2_ERR_IGN_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == NGHTTP2_TOKEN__AUTHORITY || token == NGHTTP2_TOKEN_HOST) {
|
if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
|
||||||
rv = check_authority(nv->value, nv->valuelen);
|
nv->token == NGHTTP2_TOKEN_HOST) {
|
||||||
} else if (token == NGHTTP2_TOKEN__SCHEME) {
|
rv = check_authority(nv->value->base, nv->value->len);
|
||||||
rv = check_scheme(nv->value, nv->valuelen);
|
} else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
|
||||||
|
rv = check_scheme(nv->value->base, nv->value->len);
|
||||||
} else {
|
} else {
|
||||||
rv = nghttp2_check_header_value(nv->value, nv->valuelen);
|
rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rv == 0) {
|
if (rv == 0) {
|
||||||
assert(nv->namelen > 0);
|
assert(nv->name->len > 0);
|
||||||
if (nv->name[0] == ':') {
|
if (nv->name->base[0] == ':') {
|
||||||
return NGHTTP2_ERR_HTTP_HEADER;
|
return NGHTTP2_ERR_HTTP_HEADER;
|
||||||
}
|
}
|
||||||
/* When ignoring regular headers, we set this flag so that we
|
/* When ignoring regular headers, we set this flag so that we
|
||||||
@@ -426,10 +458,10 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
|
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,
|
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
|
* This function is called when HTTP header field |nv| in |frame| is
|
||||||
* received for |stream|. This function will validate |nv| against
|
* received for |stream|. This function will validate |nv| against
|
||||||
* the current state of stream. The |token| is nghttp2_token value
|
* the current state of stream.
|
||||||
* for nv->name, or -1 if we don't have enum value for the name.
|
|
||||||
*
|
*
|
||||||
* This function returns 0 if it succeeds, or one of the following
|
* This function returns 0 if it succeeds, or one of the following
|
||||||
* negative error codes:
|
* negative error codes:
|
||||||
@@ -49,7 +48,7 @@
|
|||||||
* if it was not received because of compatibility reasons.
|
* if it was not received because of compatibility reasons.
|
||||||
*/
|
*/
|
||||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
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 trailer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user