Compare commits

...

529 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
0344c962f8 Add missing nghttp2_set_debug_vprintf_callback.rst to APIDOCS 2016-10-24 21:14:15 +09:00
Tatsuhiro Tsujikawa
46d1e6bb55 nghttpx: Increase block size of connection wide allocator to 512 2016-10-24 21:06:37 +09:00
Tatsuhiro Tsujikawa
04606b9339 Update man pages 2016-10-24 20:40:51 +09:00
Tatsuhiro Tsujikawa
7bb083e69e Bump up version number to 1.16.0, LT revision to 26:0:12 2016-10-24 20:37:56 +09:00
Tatsuhiro Tsujikawa
3a831fa95c nghttpx: Fix file descriptor leak in read_tls_sct_from_dir 2016-10-24 20:30:30 +09:00
Tatsuhiro Tsujikawa
5b9cacc2d7 nghttpx: Discard iaddrs early 2016-10-23 19:55:58 +09:00
Tatsuhiro Tsujikawa
10a84f3e3d nghttpx: Rename errbuf for neverbleed as nb_errbuf for clarification 2016-10-23 19:26:22 +09:00
Tatsuhiro Tsujikawa
c42715ed6a nghttpx: Fix compile error with --disable-threads 2016-10-23 19:26:22 +09:00
Tatsuhiro Tsujikawa
177d51ddab nghttpx: Use thread_local if it is available 2016-10-23 19:26:22 +09:00
Tatsuhiro Tsujikawa
6c882e1ece asio: Avoid repeated call of io_service::post 2016-10-20 22:12:31 +09:00
Tatsuhiro Tsujikawa
f09c5c4bf9 xsi_strerror: Use stddef.h so that we can use size_t 2016-10-19 23:50:28 +09:00
Tatsuhiro Tsujikawa
08a9a2eca9 asio: Fix bug when end() is called outside nghttp2 callback 2016-10-19 23:17:43 +09:00
Tatsuhiro Tsujikawa
19f1785cde nghttpx: Avoid extra allocation on look up host key 2016-10-18 22:19:53 +09:00
Tatsuhiro Tsujikawa
109de15c1f doc: Mention --no-location-rewrite in "Rewriting location header field" section 2016-10-17 22:02:49 +09:00
Tatsuhiro Tsujikawa
8b64e7b4e1 src: Add XSI-compliant version strerror_r 2016-10-16 22:47:56 +09:00
Tatsuhiro Tsujikawa
a5d66e71d0 Update http-parser to feae95a3a69f111bc1897b9048d9acbc290992f9 2016-10-16 17:57:45 +09:00
Tatsuhiro Tsujikawa
3de2654223 src: Add noexcept to move constructor and assignment operator 2016-10-15 18:51:22 +09:00
Tatsuhiro Tsujikawa
d49bd50908 Apply clang-format-diff only to lib, src, examples and tests 2016-10-15 18:40:45 +09:00
Tatsuhiro Tsujikawa
4130c68db1 Merge branch 'clang-format-3.9' 2016-10-15 18:39:15 +09:00
Tatsuhiro Tsujikawa
ad3dac81a2 Update doc 2016-10-15 18:37:03 +09:00
Tatsuhiro Tsujikawa
0cf6848646 clang-format-3.9 2016-10-15 18:36:04 +09:00
Tatsuhiro Tsujikawa
e9d562f987 Update .clang-format for clang-format-3.9 2016-10-15 18:25:36 +09:00
Tatsuhiro Tsujikawa
bc0f501dd3 Replace final with fin to make clang-format-3.9 happy 2016-10-15 18:25:13 +09:00
Tatsuhiro Tsujikawa
a591001e7b Update doc 2016-10-15 18:18:52 +09:00
Tatsuhiro Tsujikawa
eaa9229d72 Update doc 2016-10-15 18:16:15 +09:00
Tatsuhiro Tsujikawa
1d5cde1c6b Add missing nghttp2_debug.h 2016-10-14 23:13:42 +09:00
Tatsuhiro Tsujikawa
de03c41111 Merge branch 'Andersbakken-set_nghttp2_debug_callback' 2016-10-14 23:03:00 +09:00
Tatsuhiro Tsujikawa
19340da8d4 Re-format debug text output 2016-10-14 22:59:05 +09:00
Tatsuhiro Tsujikawa
5e99531b4d clang-format 2016-10-14 22:59:05 +09:00
Tatsuhiro Tsujikawa
bef3d47c16 Rename functions and nghttp2_debug.h to move debug macro there 2016-10-14 22:59:05 +09:00
Tatsuhiro Tsujikawa
b8f7b474b4 Fix autotools build 2016-10-14 22:04:02 +09:00
Tatsuhiro Tsujikawa
1fb291d0e1 Merge branch 'set_nghttp2_debug_callback' of https://github.com/Andersbakken/nghttp2 into Andersbakken-set_nghttp2_debug_callback 2016-10-14 21:58:13 +09:00
Anders Bakken
bc3dc6b765 Add set_nghttp2_debug_callback to take advantage of DEBUGF statements in
when building DEBUGBUILD.
2016-10-13 13:24:26 -07:00
Tatsuhiro Tsujikawa
ee7c36c022 Merge pull request #707 from Andersbakken/current
Make it possible to include nghttp2/CMakeLists.txt in another project
2016-10-13 21:16:14 +09:00
Anders Bakken
857791dbb9 Make it possible to include nghttp2/CMakeLists.txt in another project
using add_subdirectory.

CMAKE_SOURCE_DIR/CMAKE_BINARY_DIR points to the top level
CMakeLists.txt. This isn't necessarily nghttp2/CMakeLists.txt.
2016-10-12 08:23:20 -07:00
Tatsuhiro Tsujikawa
3c3267ea7d Update bash_completion 2016-10-11 23:03:11 +09:00
Tatsuhiro Tsujikawa
d654664fb2 Update man pages 2016-10-11 23:02:55 +09:00
Tatsuhiro Tsujikawa
1a37044d3c nghttpx: Use pre-allocated buffer for timestamp string 2016-10-11 22:32:26 +09:00
Tatsuhiro Tsujikawa
00a8c378d4 nghttpx: Add --backend-connect-timeout option 2016-10-10 22:50:41 +09:00
Tatsuhiro Tsujikawa
7549341081 Fix typo 2016-10-10 15:35:12 +09:00
Tatsuhiro Tsujikawa
5db8473f12 Fix build error with OpenSSL < 1.0.2 (again) 2016-10-09 19:34:32 +09:00
Tatsuhiro Tsujikawa
00b89f10bd Fix build error with OpenSSL < 1.0.2 2016-10-09 18:54:18 +09:00
Tatsuhiro Tsujikawa
281df33f40 Update bash_completion 2016-10-09 18:45:17 +09:00
Tatsuhiro Tsujikawa
e6ae681f07 Update man pages 2016-10-09 18:44:33 +09:00
Tatsuhiro Tsujikawa
7e681dc98f help2rst.py: Fix * escape 2016-10-09 18:43:36 +09:00
Tatsuhiro Tsujikawa
412c8f9e67 nghttpx: Add TLS signed_certificate_timestamp extension support 2016-10-09 18:43:36 +09:00
Tatsuhiro Tsujikawa
2795da840c nghttpx: Apply timeout for incoming header block 2016-10-09 17:18:43 +09:00
Tatsuhiro Tsujikawa
175c7886ea nghttpx: Update doc 2016-10-09 17:18:29 +09:00
Tatsuhiro Tsujikawa
4a4b2cf538 nghttpx: Embed Process into OCSPUpdateContext 2016-10-08 15:26:13 +09:00
Tatsuhiro Tsujikawa
2c2188c09d nghttpx: Refactor ocsp command execution
We have now generic read-only command execution in shrpx_exec.{h,cc}.
2016-10-08 15:22:11 +09:00
Tatsuhiro Tsujikawa
1f07c24a2e Update bash_completion 2016-10-08 11:46:16 +09:00
Tatsuhiro Tsujikawa
e038625881 Update man pages 2016-10-08 11:46:03 +09:00
Tatsuhiro Tsujikawa
cdb1d6b462 nghttpx: Add P-384 and P-521 to the default of --ecdh-curves option 2016-10-08 11:44:03 +09:00
Tatsuhiro Tsujikawa
1b4ccd0d51 nghttpx: Don't call get_config() repeatedly 2016-10-08 11:37:18 +09:00
Tatsuhiro Tsujikawa
8babaac8c3 nghttpx: Add --ecdh-curves option to specify list of named curves
This option requires OpenSSL >= 1.0.2.  With OpenSSL 1.0.2, the
default value is "P-256".  With OpenSSL 1.1.0 or later, the default
value is "X25519:P-256".
2016-10-08 10:50:56 +09:00
Tatsuhiro Tsujikawa
d1624d6929 h2load: Format default value of header table size with unit 2016-10-06 23:16:30 +09:00
Tatsuhiro Tsujikawa
e4472b5aec h2load: Add --header-table-size and --encoder-header-table-size options 2016-10-06 22:26:31 +09:00
Tatsuhiro Tsujikawa
9439ba75d3 nghttpx: Fix heap-use-after-free when executing new binary 2016-10-04 00:32:02 +09:00
Tatsuhiro Tsujikawa
9254c563ca Fix compile error with gcc 2016-10-03 22:52:14 +09:00
Tatsuhiro Tsujikawa
35594e09df Merge branch 'nghttpx-more-block-allocator' 2016-10-03 22:12:28 +09:00
Tatsuhiro Tsujikawa
96ff3be5e6 nghttpx: Use allocator of new config since this may happen multiple times 2016-10-03 22:09:46 +09:00
Tatsuhiro Tsujikawa
3d5d76ba74 nghttpx: Update doc 2016-10-03 22:09:46 +09:00
Tatsuhiro Tsujikawa
8c1e155f44 nghttpx: Make it simple to calculate length 2016-10-03 22:09:46 +09:00
Tatsuhiro Tsujikawa
dba0d2791c nghttpx: Use emplace_back instead of push_back 2016-10-03 22:09:46 +09:00
Tatsuhiro Tsujikawa
f310e82fc8 nghttpx: Update doc 2016-10-03 22:09:46 +09:00
Tatsuhiro Tsujikawa
1240e55bb6 nghttpx: Use const ref 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
75039c573c base64: Assert that input is multiple of 4 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
4b5179a544 nghttpx: Fix bug in util::make_hostport 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
8efccddcf4 nghttpx: Use StringRef for HttpProxy 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
97843e3874 nghttpx: Use StringRef for tls_proto_list 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
5dd2704051 nghttpx: Use StringRef for tls.npn_list 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
de7b7fd440 nghttpx: Use StringRef for tls.subcerts 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
1037d3ad26 nghttpx: Use StringRef for tls.ticket.files 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
c4368a9416 nghttpx: Use StringRef for AltSvc fields 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
fdc1eb526b nghttpx: Use HeaderRefs for add_request_headers and add_response_headers 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
99a91e3172 nghttpx: Add BlockAllocator to Config object 2016-10-03 22:09:45 +09:00
Tatsuhiro Tsujikawa
272cfa320e nghttpx: Use BlockAllocator per DownstreamConfig 2016-10-02 22:28:43 +09:00
Tatsuhiro Tsujikawa
f5285d1f5a nghttpx: Add BlockAllocator to SharedDownstreamAddr 2016-10-02 22:28:43 +09:00
Tatsuhiro Tsujikawa
ede6104900 nghttpx: Increase block size for connection wide BlockAllocator 2016-10-02 22:28:43 +09:00
Tatsuhiro Tsujikawa
5aec60fbeb nghtpx: Add BlockAllocator version of base64 2016-10-02 22:28:43 +09:00
Tatsuhiro Tsujikawa
e1a865c406 nghttpx: Add BlockAllocator version of util::formax_hex 2016-10-02 22:28:42 +09:00
Tatsuhiro Tsujikawa
5e03b6a0db nghttpx: Use BlockAllocator for util::quote_string 2016-10-02 00:07:26 +09:00
Tatsuhiro Tsujikawa
b85924bf70 nghttpx: Use BlockAllocator to encode alt-svc token 2016-10-02 00:00:46 +09:00
Tatsuhiro Tsujikawa
19707aac55 nghttpx: Use StringRef for sni_name_ 2016-10-01 22:54:17 +09:00
Tatsuhiro Tsujikawa
9ad873fc06 nghttpx: Remove unused function declaration 2016-10-01 22:54:17 +09:00
Tatsuhiro Tsujikawa
8a9810ed32 nghttpx: Add BlockAllocator to ClientHandler 2016-10-01 22:54:17 +09:00
Tatsuhiro Tsujikawa
68a6d8c50b nghttpx: Realloc header buffer 2016-10-01 22:52:02 +09:00
Tatsuhiro Tsujikawa
600605400c nghttpx: Don't send RST_STREAM CANCEL to a pushed stream repeatedly 2016-09-27 23:49:01 +09:00
Tatsuhiro Tsujikawa
97aa4dabc8 Bump up version number to 1.16.0-DEV 2016-09-25 12:17:45 +09:00
Tatsuhiro Tsujikawa
a6f487240d Add missing rst entry 2016-09-25 11:44:24 +09:00
Tatsuhiro Tsujikawa
da135416bb Update man pages 2016-09-25 11:39:14 +09:00
Tatsuhiro Tsujikawa
13eb881e5e Bump up version number to 1.15.0, LT revision to 25:0:11 2016-09-25 11:36:15 +09:00
Tatsuhiro Tsujikawa
82c84d163b doc: Add missing rst files to CMakeLists.txt 2016-09-24 22:14:35 +09:00
Tatsuhiro Tsujikawa
a526183928 doc: Sort rst files 2016-09-24 22:14:28 +09:00
Tatsuhiro Tsujikawa
60222ae7c3 Update doc 2016-09-24 10:42:50 +09:00
Tatsuhiro Tsujikawa
2052a1a4bd Document how libnghttp2 schedules HTTP/2 frames internally 2016-09-23 22:41:49 +09:00
Tatsuhiro Tsujikawa
183be9cac9 Fix typo 2016-09-23 22:23:48 +09:00
Tatsuhiro Tsujikawa
69b53b9aaa nghttpx: Handle graceful shutdown with client IP affinity enabled 2016-09-22 23:17:49 +09:00
Tatsuhiro Tsujikawa
02b9fcd332 integration: Fix test failure with go1.7.1 2016-09-22 20:47:51 +09:00
Tatsuhiro Tsujikawa
231d739b10 nghttpx: Improve performance with h1 backend when request body is involved 2016-09-22 20:46:50 +09:00
Tatsuhiro Tsujikawa
e1dfff8929 Use std::atomic_* overloads for std::shared_ptr if available 2016-09-20 22:39:01 +09:00
Tatsuhiro Tsujikawa
db1716ae93 Fix -Wexpansion-to-defined warning with clang-3.9
The error message was:

warning: macro expansion producing 'defined' has undefined
behavior [-Wexpansion-to-defined]

http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160118/147239.html
2016-09-19 22:07:03 +09:00
Tatsuhiro Tsujikawa
4cdc74c957 Update bash_completion 2016-09-18 22:44:33 +09:00
Tatsuhiro Tsujikawa
2c17ec3df8 Update man pages 2016-09-18 22:44:19 +09:00
Tatsuhiro Tsujikawa
e464b10fc3 Merge branch 'set-max-deflate-dynamic-table-size' 2016-09-18 22:13:56 +09:00
Tatsuhiro Tsujikawa
03ba399176 nghttpx: Update doc 2016-09-17 22:38:06 +09:00
Tatsuhiro Tsujikawa
751d66a397 nghttpd: Check maximum value of -c option 2016-09-17 22:38:05 +09:00
Tatsuhiro Tsujikawa
3ec71bf5a2 nghttpd: Add --encoder-header-table-size option 2016-09-17 22:38:05 +09:00
Tatsuhiro Tsujikawa
f19b0724a3 nghttp: Check maximum value of -c option 2016-09-17 22:38:05 +09:00
Tatsuhiro Tsujikawa
a7e0a69f97 nghttp: Add --encoder-header-table-size option 2016-09-17 22:38:05 +09:00
Tatsuhiro Tsujikawa
e532e20491 Merge branch 'master' into set-max-deflate-dynamic-table-size 2016-09-17 22:02:41 +09:00
Tatsuhiro Tsujikawa
3e1cfa8e99 nghttpx: Don't check downstream existence since dconn is one-to-one with it 2016-09-15 22:11:26 +09:00
Tatsuhiro Tsujikawa
a100df9cae nghttpx: Remove redundant check using get_downstream_stream_id 2016-09-15 22:06:52 +09:00
Tatsuhiro Tsujikawa
56284b1e15 nghttpx: Fix regression introduced in f267e400fa 2016-09-15 22:03:04 +09:00
Tatsuhiro Tsujikawa
f267e400fa nghttpx: Migrate backend stream to another h2 session on graceful shutdown 2016-09-15 00:53:41 +09:00
Tatsuhiro Tsujikawa
8bac5899cc nghttpx: Handle h2 backend error per Downstream
Previously we wrongly handles stream per connection when h2 backend
failed or closed.  If upstream is h2 or spdy, streams which are not
associated to the failed h2 backend are also handled, which is
unnecessary.
2016-09-14 22:18:38 +09:00
Tatsuhiro Tsujikawa
f4016644a9 nghttpx: Add option to specify HPACK encoder/decoder dynamic table size 2016-09-12 22:53:02 +09:00
Tatsuhiro Tsujikawa
d9bc6d04f7 nghttpx: Log client address 2016-09-11 23:30:33 +09:00
Tatsuhiro Tsujikawa
743fc4a3c3 Use the similar naming scheme for table size as 392256e542 2016-09-11 22:25:01 +09:00
Tatsuhiro Tsujikawa
392256e542 Add nghttp2_option_set_max_deflate_dynamic_table_size() API function
nghttp2_option_set_max_deflate_dynamic_table_size function sets the
maximum dynamic table size for header block deflater.  The default
value is 4KiB.
2016-09-11 22:13:59 +09:00
Tatsuhiro Tsujikawa
905e16cb99 Simplify session_after_frame_sent1 2016-09-11 17:18:08 +09:00
Tatsuhiro Tsujikawa
9d4e8eeb12 Simplify code
Move DATA frame handling code to switch-case of frame type.
2016-09-11 17:00:04 +09:00
Tatsuhiro Tsujikawa
8099dd9558 Mention --enable-lib-only configure option in README 2016-09-11 13:34:34 +09:00
Tatsuhiro Tsujikawa
a3a6b91c5f src: Rename OPENSSL_101_API macro as OPENSSL_1_1_API 2016-09-11 00:38:20 +09:00
Tatsuhiro Tsujikawa
d9bb3448bf Update man pages 2016-09-10 22:15:56 +09:00
Tatsuhiro Tsujikawa
d508a0c72c nghttpx: Defer validation of request form after mruby handler 2016-09-10 22:09:13 +09:00
Tatsuhiro Tsujikawa
bc31146c1f nghttpx: Add tls_sni to mruby Nghttpx::Env class
tls_sni returns TLS SNI value which client sent in this TLS
connection.
2016-09-10 22:08:34 +09:00
Tatsuhiro Tsujikawa
1ad7d5e366 nghttpx: Fix compile error gcc (again) 2016-09-10 17:13:01 +09:00
Tatsuhiro Tsujikawa
456038e3de nghttpx: Fix compile error with gcc 2016-09-10 16:51:35 +09:00
Tatsuhiro Tsujikawa
9aa26970be nghttpx: Comment out TCP logging since it is too verbose 2016-09-10 16:49:15 +09:00
Tatsuhiro Tsujikawa
20c39fa843 nghttpx: Use default connection window size with window size optimization 2016-09-10 16:45:28 +09:00
Tatsuhiro Tsujikawa
f5a2f1da25 nghttpx: Add --frontend-http2-window-size option, and its family
We added --frontend-http2-window-size,
--frontend-http2-connection-window-size, --backend-http2-window-size,
and --backend-http2-connection-window-size option to replace existing
*-bits options.  The old options are not flexible because they only
specify number of bits.  Now we can specify integer value, with
possible g, m, and k unit.  The old options are still available for
backend compatibility, but are deprecated.
2016-09-10 16:27:48 +09:00
Tatsuhiro Tsujikawa
27b250ac8e nghttpx: Add experimental TCP optimization for h2 frontend 2016-09-10 16:27:48 +09:00
Tatsuhiro Tsujikawa
b14375ec63 Bump up LT revision to 24:1:10 due to v1.14.1 release
This also fixes LT revision in CMakeLists.txt, which was not updated
in v1.14.0 release.
2016-09-10 12:52:37 +09:00
Tatsuhiro Tsujikawa
6858cda366 Fix GOAWAY race with new incoming stream on server side
Revert part of 16c46114dc to fix race
condition that incoming stream after sending GOAWAY causes connection
error.  The strict stream handling introduced in the above commit does
not handle several cases well (e.g., GOAWAY race, and refusing streams
because of concurrency limit).
2016-09-09 22:08:34 +09:00
Tatsuhiro Tsujikawa
8a703d21ae Update neverbleed 2016-09-08 21:19:24 +09:00
Tatsuhiro Tsujikawa
1dabe43ff4 nghttpx: Workaround for std::make_shared bug in Xcode7, 7.1, and 7.2
std::make_shared in Xcode 7, 7.1, and 7.2 does not perform
value-initialization, and causes undefined behaviour if struct does
not have user defined default constructor.  This workaround explicitly
defines user defined default constructor, and initializes values.
2016-09-04 23:30:24 +09:00
Tatsuhiro Tsujikawa
900aef10da Update neverbleed 2016-09-04 17:43:07 +09:00
Tatsuhiro Tsujikawa
ded576f423 nghttpx: Fix bug that bytes are doubly counted for TLS connections 2016-09-04 17:28:50 +09:00
Tatsuhiro Tsujikawa
136aae725f nghttpx: Add --no-server-rewrite option not to rewrite server header field 2016-08-31 23:47:15 +09:00
Tatsuhiro Tsujikawa
a60c3f8939 Add -Wsometimes-uninitialized to warn flags 2016-08-30 23:47:07 +09:00
Tatsuhiro Tsujikawa
99dc31ff1a nghttpx: Retry if backend h1 connection cannot be established due to timeout 2016-08-30 23:37:49 +09:00
Tatsuhiro Tsujikawa
7673848325 Add -lsocket -lnsl to APPLDFLAGS for solaris build
As suggested in GH-674
2016-08-30 21:25:47 +09:00
Tatsuhiro Tsujikawa
0f8a5ffc23 Merge branch 'http2-debug-state-api' 2016-08-28 22:33:24 +09:00
Tatsuhiro Tsujikawa
fddb019baf Merge branch 'master' into http2-debug-state-api 2016-08-28 22:20:04 +09:00
Tatsuhiro Tsujikawa
72bf7d4af0 Merge branch 'pause-from-data-source-read-callback' 2016-08-28 22:18:29 +09:00
Tatsuhiro Tsujikawa
581e0938a9 Allow NGHTTP2_ERR_PAUSE from nghttp2_data_source_read_callback 2016-08-28 21:57:10 +09:00
Tatsuhiro Tsujikawa
1064e017c6 nghttpx: Reset stream if invalid header field is received in h2 2016-08-28 00:49:38 +09:00
Tatsuhiro Tsujikawa
79b07f0ce2 Update doc 2016-08-28 00:47:38 +09:00
Tatsuhiro Tsujikawa
cd471a989a python: Support ALPN, require Python 3.5
This commit also fixes the bug that SETTINGS timer continues after
connection was closed.
2016-08-28 00:11:59 +09:00
Tatsuhiro Tsujikawa
0ea44072a3 Enable ASAN in travis autotools build 2016-08-27 22:14:54 +09:00
Tatsuhiro Tsujikawa
6ba1abac6c src: Only consider openssl 1.1.0 final 2016-08-27 00:45:16 +09:00
Tatsuhiro Tsujikawa
0110d2f9f8 Fix compile error with openssl 1.1.0 2016-08-27 00:02:03 +09:00
Tatsuhiro Tsujikawa
baa0f60dc8 Add API to get current HPACK dynamic table size 2016-08-26 23:02:51 +09:00
Tatsuhiro Tsujikawa
69aa70086a Merge branch 'master' into http2-debug-state-api 2016-08-26 22:54:59 +09:00
Tatsuhiro Tsujikawa
13d3f785bd Make ImmutableString(const std::string&) explicit 2016-08-26 22:52:08 +09:00
Tatsuhiro Tsujikawa
39c068974d Make ImmutableString(const char*) explicit 2016-08-26 22:40:59 +09:00
Tatsuhiro Tsujikawa
0d4d1a63d4 nghttpx: Add --server-name option to change server response header field 2016-08-26 22:28:09 +09:00
Tatsuhiro Tsujikawa
833cd962a1 Bump up version number to 1.15.0-DEV 2016-08-25 23:25:42 +09:00
Tatsuhiro Tsujikawa
8103f43b65 doc: Add missing APIDOCS entry 2016-08-25 23:19:35 +09:00
Tatsuhiro Tsujikawa
1c8a672a8d Update man pages 2016-08-25 22:57:56 +09:00
Tatsuhiro Tsujikawa
4749e66c67 nghttpx: Disallow copying Config 2016-08-25 22:55:12 +09:00
Tatsuhiro Tsujikawa
25ea41972a Bump up version number to 1.14.0, LT revision to 24:0:10 2016-08-25 22:41:17 +09:00
Tatsuhiro Tsujikawa
7d66188910 Add author.py
This script prints out the commit author from `git log` output.  Used
to update AUTHORS file.
2016-08-25 22:37:18 +09:00
Tatsuhiro Tsujikawa
979c99eaea Update AUTHORS 2016-08-25 22:36:05 +09:00
Tatsuhiro Tsujikawa
cf7f87c2ad nghttpx: Log error code from getsockopt(SO_ERROR) on first write event 2016-08-25 00:25:03 +09:00
Tatsuhiro Tsujikawa
bd0c1edaa6 Merge branch 'weliu-master' 2016-08-24 00:58:49 +09:00
Tatsuhiro Tsujikawa
c7ef021b4b Merge branch 'master' of https://github.com/weliu/nghttp2 into weliu-master 2016-08-24 00:58:15 +09:00
Wenfeng Liu
00c80a15c0 lib: Make emit_header() return void since it always succeed. 2016-08-23 13:40:14 +00:00
Tatsuhiro Tsujikawa
8f47b68a95 nghttpx: Set do_signal_write_ when TLS handshake was completed 2016-08-23 21:36:43 +09:00
Tatsuhiro Tsujikawa
d9139fc286 asio: Fix reserved size 2016-08-22 22:30:25 +09:00
Tatsuhiro Tsujikawa
e693f75670 Add nghttp2_session_get_local_settings() API function 2016-08-21 19:33:01 +09:00
Tatsuhiro Tsujikawa
759f6c0b39 Update doc 2016-08-21 19:17:51 +09:00
Tatsuhiro Tsujikawa
3e0d73c01d Add missing document entries 2016-08-21 19:11:23 +09:00
Tatsuhiro Tsujikawa
5cf21ec187 Add APIs to return the number of data that remote endpoint can send
2 APIs are added.  nghttp2_session_get_local_window_size() returns the
amount of data that the remote endpoint can send without receiving
connection level WINDOW_UPDATE.
nghttp2_session_get_stream_local_window_size() returns the amount of
data that the remote endpoint can send without receiving stream level
WINDOW_UPDATE.
2016-08-21 19:01:51 +09:00
Tatsuhiro Tsujikawa
62e1d1c952 Fix typo 2016-08-21 13:29:29 +09:00
Tatsuhiro Tsujikawa
6ae58cc22e Document how to report vulnerability 2016-08-21 12:18:31 +09:00
Tatsuhiro Tsujikawa
874ef1ac54 Add License section in README 2016-08-21 11:29:21 +09:00
Tatsuhiro Tsujikawa
5f65460944 nghttpx: Don't change pushed stream's priority
There is a discussion in httpbis mailing list which argues that
dependency tree is for client, and changing it in server side is not
what client expects.
https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0416.html

Currently, we make pushed stream depend on the parent stream of
associated stream (that is main HTML in most of the cases), so that
associated stream and pushed stream become siblings.  In this case, we
also observed that these resources complete each other to get its
parent weight.  This means that the delivery of associated stream is
delayed by pushed streams.

So at this moment, it is not a good idea to change pushed stream
priority in a way we do currently.
2016-08-20 22:09:18 +09:00
Tatsuhiro Tsujikawa
41b2745dad nghttpx: Log backend connection failure in WARN level 2016-08-19 16:25:05 +09:00
Tatsuhiro Tsujikawa
30f9f9ef87 nghttpx: Guard with LOG_ENABLED(INFO) 2016-08-19 16:24:48 +09:00
Tatsuhiro Tsujikawa
4807e71b7d nghttpx: Fix bug that api and healthmon params do not work with http2 proxy 2016-08-18 22:31:53 +09:00
Tatsuhiro Tsujikawa
09c647fd1b Update doc 2016-08-18 21:26:58 +09:00
Tatsuhiro Tsujikawa
d0fea96e69 Allow nonuniform buffer size in nghttp2_hd_deflate_hd_vec() 2016-08-18 21:23:17 +09:00
Tatsuhiro Tsujikawa
b8883101d3 deflatehd: Call nghttp2_hd_deflate_change_table_size only if table size is changed from default 2016-08-18 17:19:24 +09:00
Tatsuhiro Tsujikawa
508c88f659 Add test for nghttp2_hd_deflate_hd_vec with 1 byte chunk 2016-08-17 22:59:48 +09:00
Tatsuhiro Tsujikawa
40d217beb1 Remove bufs_avail 2016-08-17 22:56:40 +09:00
Tatsuhiro Tsujikawa
e36caef006 Merge branch 'hpack-vec' 2016-08-17 21:09:44 +09:00
Tatsuhiro Tsujikawa
9b864380a5 Use nghttp2_vec in nghttp2_hd_deflate_hd_vec
This change is for the future enhancement where we loose the
requirement about the chunk size for each buffer.
2016-08-17 21:09:29 +09:00
Tatsuhiro Tsujikawa
0e1d0400d8 Use whole chunk when performing huffman encoding 2016-08-17 21:05:04 +09:00
Tatsuhiro Tsujikawa
afdd51ff15 Merge branch 'weliu-master' 2016-08-17 20:51:24 +09:00
Wenfeng Liu
488c3588d9 lib: Malloc nghttp2_buf_chain array once in nghttp2_bufs_wrap_init2()
to simplify logic
2016-08-17 20:48:03 +09:00
Tatsuhiro Tsujikawa
4f02b191d1 Merge branch 'weliu-master' 2016-08-16 13:03:13 +09:00
Tatsuhiro Tsujikawa
8acef2711b Use pointer-to-pointer idiom to construct linked list 2016-08-16 13:02:24 +09:00
Tatsuhiro Tsujikawa
c6111b3792 Add test for nghttp2_hd_deflate_hd_vec 2016-08-16 11:11:06 +09:00
Tatsuhiro Tsujikawa
c4d36aeff7 Make parameters const pointer 2016-08-16 10:55:51 +09:00
Tatsuhiro Tsujikawa
f50596e355 Merge branch 'master' of https://github.com/weliu/nghttp2 into weliu-master 2016-08-16 09:59:50 +09:00
Wenfeng Liu
abf81b5bb7 lib: Add nghttp2_hd_deflate_hd_vec() deflate API to support multiple bufs input 2016-08-15 10:28:45 +00:00
Tatsuhiro Tsujikawa
8579b8a968 Merge pull request #646 from nghttp2/invalid-header-cb
Add nghttp2_on_invalid_header_callback
2016-08-15 11:13:20 +09:00
Tatsuhiro Tsujikawa
8df2c357d9 nghttp: Adjust weight according to Firefox stable 2016-08-11 21:59:34 +09:00
Tatsuhiro Tsujikawa
4c381611a1 More doc about HPACK decoding API 2016-08-11 11:47:53 +09:00
Tatsuhiro Tsujikawa
7dfd6ab1ad Merge branch 'weliu-master' 2016-08-11 11:34:03 +09:00
Tatsuhiro Tsujikawa
0c7d48dede Make result type of hd_inflate_commit_indexed void 2016-08-11 11:33:09 +09:00
Tatsuhiro Tsujikawa
4639a66e53 Merge branch 'master' of https://github.com/weliu/nghttp2 into weliu-master 2016-08-11 11:30:51 +09:00
Wenfeng Liu
65cc2f0515 lib: since hd_inflate_commit_indexed() always return 0, remove the
return value check in nghttp2_hd_inflate_hd_nv().
2016-08-11 02:00:43 +00:00
Tatsuhiro Tsujikawa
4eb7f98449 Remove old doc about differential encoding in HPACK 2016-08-10 21:32:36 +09:00
Wenfeng Liu
2d8059a9a5 Merge pull request #1 from nghttp2/master
Merge from nghttp2/nghttp2
2016-08-10 10:39:33 +08:00
Tatsuhiro Tsujikawa
a3d22b6db9 Merge branch 'weliu-master' 2016-08-09 22:05:12 +09:00
Tatsuhiro Tsujikawa
3f31424ee2 Merge branch 'master' of https://github.com/weliu/nghttp2 into weliu-master 2016-08-09 22:01:10 +09:00
Wenfeng Liu
e0119452a3 Use memeq() instead of lstreq() in lookup_token(). 2016-08-09 04:15:38 +00:00
Tatsuhiro Tsujikawa
60cae325bc Search dynamic table first for optimization 2016-08-08 00:27:16 +09:00
Tatsuhiro Tsujikawa
16c46114dc More strict stream state handling
Previously, in server side, we used closed streams to detect the error
that the misbehaving client sends a frame on the incoming stream it
explicitly closed.  With this commit, we make a further step, and
detect one more error case.  Since we retain closed streams as long as
the sum of its size and the number of opened streams are equal or less
than max concurrent streams, we can safely say that if we get a frame
which is sent on the stream that is not found in either closed or
opened stream, it is already closed or has not existed.  Then we can
send GOAWAY.

The previous code shrinks closed streams when we closed another
stream, but now it is removed.  It is enough to adjust closed streams
when new incoming stream is created.

While creating this commit, we noticed that
NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS is defined as INT32_MAX.  But
since SETTINGS can contain value up to UINT32_MAX, it is not enough.
However, since the stream ID space is limited to INT32_MAX, it is high
enough.  We could keep this value, but this time we deprecate
NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS macro.  While it is in public
header, the effect of deprecating it is negligible because of the
reason we wrote above, and usually application sets much smaller value
(say, 100) as SETTINGS_MAX_CONCURRENT_STREAMS.
2016-08-07 19:31:00 +09:00
Tatsuhiro Tsujikawa
862175b21c Merge branch 'weliu-master' 2016-08-06 22:44:10 +09:00
Tatsuhiro Tsujikawa
e7e3d77c53 Merge branch 'master' of https://github.com/weliu/nghttp2 into weliu-master 2016-08-06 22:42:22 +09:00
Wenfeng Liu
af9aeee752 1. Modify genlibtokenlookup.py to remove redundant header comparisons.
2. Remove inline qualifier of lookup_token() in genlibtokenlookup.py.
2016-08-05 09:56:15 +00:00
Tatsuhiro Tsujikawa
ad3d43b8be nghttpx: Add access log variable for backend host and port
Use $backend_host and $backend_port.  $backend_host is backend host
name given in --backend option.  It could be a path to UNIX domain
socket.
2016-08-05 00:04:47 +09:00
Tatsuhiro Tsujikawa
210a5c4f01 nghttpx: Use copy instead of const reference of backend group 2016-08-04 23:11:45 +09:00
Tatsuhiro Tsujikawa
d8822f2a8e Merge branch 'weliu-master' 2016-08-04 22:25:49 +09:00
Tatsuhiro Tsujikawa
b7a72b1e5a Merge branch 'master' of https://github.com/weliu/nghttp2 into weliu-master 2016-08-04 22:25:25 +09:00
Tatsuhiro Tsujikawa
2f106dc96b Fix wrong tree operation to avoid cycle
https://tools.ietf.org/html/rfc7540#section-5.3.3 explains how to
transform dependency tree to avoid circular dependency.  Previously,
we wrongly always moved the dependent stream under the root stream.
The correct destination is the parent stream of the stream to
reprioritize.  This commit fixes this bug.
2016-08-04 22:20:07 +09:00
Wenfeng Liu
f619286ca3 Make get_max_index() return the max index in frame, so we don't need
to do extra calculation
2016-08-04 01:26:13 +00:00
Tatsuhiro Tsujikawa
271f7fbbb6 Add nghttp2_on_invalid_header_callback
nghttp2_on_invalid_header_callback is similar to
nghttp2_on_header_callback, but the former is only called when the
invalid header field is received which is silently ignored when the
callback is not set.  With this callback, application inspects the
incoming invalid field, and it also can reset stream from this
callback by returning NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE, or using
nghttp2_submit_rst_stream() directly with the error code of choice.

We also added nghttp2_on_invalid_header_callback2, which uses
reference counted header fields.
2016-08-04 00:03:58 +09:00
Tatsuhiro Tsujikawa
318235db33 Log frame's stream ID for header debug logging
Previously, for PUSH_PROMISE frame, we logged its promised stream ID.
But it is saner to use just frame's ID in this context.
2016-08-03 00:17:38 +09:00
Tatsuhiro Tsujikawa
8ab079ccc2 Call error callback when invalid header field is received and ignored
We have a code to call error callback when invalid header is received
and it is treated as stream error.  But we didn't if the incoming
header is invalid, but just ignored.  This generosity is required to
handle public Internet connections especially when nghttp2 is used as
forward proxy.
2016-08-03 00:13:37 +09:00
Tatsuhiro Tsujikawa
a4d2104c3c Revert "Output availability of ALPN in configure summary"
This reverts commit f4a4abd180.
2016-08-02 22:00:00 +09:00
Tatsuhiro Tsujikawa
44672e437a Update man pages 2016-07-31 21:16:34 +09:00
Tatsuhiro Tsujikawa
fb3d6f68a8 Merge branch 'nghttpx-reload' 2016-07-31 21:03:13 +09:00
Tatsuhiro Tsujikawa
d7c9015d8b Update doc 2016-07-31 20:59:06 +09:00
Tatsuhiro Tsujikawa
54f640f3e1 nghttpx: Update doc 2016-07-31 20:50:07 +09:00
Tatsuhiro Tsujikawa
e2906025c8 nghttpx: Don't exit from save_pid and set_alpn_prefs 2016-07-31 20:35:10 +09:00
Tatsuhiro Tsujikawa
9a8e9815c9 nghttpx: Cleanup 2016-07-31 20:26:03 +09:00
Tatsuhiro Tsujikawa
8c3e864989 nghttpx: Define ~Config for automatic clean up with std::unique_ptr
Now config global is backed with std::unique_ptr.  configuration
swapping dance is now a bit cleaner, but YMMV.
2016-07-31 19:01:29 +09:00
Tatsuhiro Tsujikawa
22570b7260 nghttpx: Close fd when error occurred in reload operation
This commit also fixes the bug that old configuration is still used
for worker process.  The another bug fix is that inherited, but not
used fd is not closed in worker process.  That makes reloading next
configuration fail if it contains the address which are leaked into
worker process.
2016-07-31 18:47:03 +09:00
Tatsuhiro Tsujikawa
fb49182c29 nghttpx: Move original_argv, argv, argc, and cmdcfgs to StartupConfig 2016-07-31 16:34:55 +09:00
Tatsuhiro Tsujikawa
b9b648e0ed nghttpx: Remove last_worker_pid from Config
The last_worker_pid is known by inspecting the last entry of
worker_processes.
2016-07-31 16:20:00 +09:00
Tatsuhiro Tsujikawa
494775a25d nghttpx: Rename SignalServer with WorkerProcess 2016-07-31 16:16:23 +09:00
Tatsuhiro Tsujikawa
1214f9e23b nghttpx: Reload configuration with SIGHUP
This commit implements configuration reloading with SIGHUP.
There are rough edges left:

* Rename SignalServer with more meaningful name, say, WorkerProcess.
* We should introduce global configuration object which is not
  affected by configuration reloading.  It should hold cmdcfgs, argc,
  argv, and last worker PID.
* We should close the listener file descriptor when some operation was
  failed after that.
2016-07-31 15:57:41 +09:00
Tatsuhiro Tsujikawa
a54cda22ab nghttpx: Do creation of InheritedAddr in a dedicated function for reuse 2016-07-31 00:35:15 +09:00
Tatsuhiro Tsujikawa
f4a4abd180 Output availability of ALPN in configure summary 2016-07-29 19:50:36 +09:00
Tatsuhiro Tsujikawa
c9559b5c0d Document about ALPN in nghttpx howto 2016-07-29 19:37:52 +09:00
Tatsuhiro Tsujikawa
af5b354685 nghttp: next_weight_idx is enough to be an local variable 2016-07-29 19:36:05 +09:00
Tatsuhiro Tsujikawa
3c1c2c4aad nghttp: Allow multiple -p option
The N-th -p options sets N-th URI's weight.  If the number of -p is
less than the number of URIs, the last -p value is repeated.  If no -p
is set, use default weight, 16.
2016-07-27 05:10:27 +09:00
Tatsuhiro Tsujikawa
767ed255ca Bump up version number to 1.14.0-DEV 2016-07-21 22:53:26 +09:00
Tatsuhiro Tsujikawa
aa0023b3c1 Update man pages 2016-07-21 21:24:01 +09:00
Tatsuhiro Tsujikawa
3bdc143474 Bump up version number to 1.13.0, LT revision to 23:0:9 2016-07-21 21:20:52 +09:00
Tatsuhiro Tsujikawa
8b50cc0ece Update doc 2016-07-21 21:18:21 +09:00
Tatsuhiro Tsujikawa
a24c94e92a Update doc 2016-07-18 00:25:59 +09:00
Tatsuhiro Tsujikawa
a00442bee6 Work with Android NDK r12b
clang + libc++ does not work, it still requires libc++_shared.so
runtime even if -lstdc++ is used, which supposed to link with static
version of libc++.
2016-07-17 23:41:41 +09:00
Tatsuhiro Tsujikawa
f857b63986 Fix warning with Sphinx 1.4 2016-07-16 19:34:39 +09:00
Tatsuhiro Tsujikawa
cbd72da9a1 Update man pages 2016-07-16 19:10:34 +09:00
Tatsuhiro Tsujikawa
7506a93179 doc: Fix Sphinx build warnings 2016-07-16 19:08:38 +09:00
Tatsuhiro Tsujikawa
53e1623ab3 Update doc
It was markdown, we should use reST.
2016-07-16 12:51:04 +09:00
Tatsuhiro Tsujikawa
0cb0bdabec Update doc 2016-07-13 22:01:31 +09:00
Tatsuhiro Tsujikawa
ed8d5f04bb Update doc 2016-07-10 19:07:03 +09:00
Tatsuhiro Tsujikawa
33153010c5 nghttpx: Retry memcached connection
Previously, we didn't retry request on connection failure.  Sometimes
we hit the edge case where connection is about to lost just when we
write request.  To avoid this situation, we now retry request to
failed attempt.  We also add ConnectBlocker to MemcachedConnection not
to attempt to connect to memcached if connection could not be made
previously.
2016-07-08 23:41:53 +09:00
Tatsuhiro Tsujikawa
2c500b62fd Update doc 2016-07-07 23:26:15 +09:00
Tatsuhiro Tsujikawa
30f26a2b9d nghttpx: Explicitly cast to uint32_t for hash calculation 2016-07-06 23:58:53 +09:00
Tatsuhiro Tsujikawa
ca39c71ac3 examples: Fix compile error with OpenSSL v1.1.0-beta2 2016-07-06 23:32:50 +09:00
Tatsuhiro Tsujikawa
2bbe4422d2 nghttpx: Use consistent hashing for client IP based session affinity
We use technique described in https://github.com/RJ/ketama
2016-07-06 23:31:10 +09:00
Tomasz Buchert
5d3535126e Fix FTBFS on armel by explicitly including the <mutex> header. 2016-07-05 00:04:23 +09:00
Tatsuhiro Tsujikawa
d2addbc1ed Add test for canceling PUSH_PROMISE 2016-07-02 21:19:54 +09:00
Tatsuhiro Tsujikawa
110ca3131a Cancel frame transmission from before_frame_send_callback
We define the behaviour when NGHTTP2_ERR_CANCEL is returned from
before_frame_send_callback.  That is to cancel the frame passed to the
callback.
2016-07-02 19:21:08 +09:00
Tatsuhiro Tsujikawa
fd7d3c57d7 nghttpx: Use faster version of power
In our use case, x and y is quite small, and there is no chance for
overflow, and y is always integer.
2016-06-27 22:42:28 +09:00
Tatsuhiro Tsujikawa
179561e4be nghttpx: Cast to double to fix build with gcc 4.8 on Solaris 11 2016-06-27 22:33:25 +09:00
Tatsuhiro Tsujikawa
903e0077aa nghttpx: Fix build error with libressl 2016-06-27 22:29:07 +09:00
Tatsuhiro Tsujikawa
3fadad1bf3 Bump up version number to 1.13.0-DEV 2016-06-26 22:44:40 +09:00
Tatsuhiro Tsujikawa
acb5d45a88 Update man pages 2016-06-26 22:33:46 +09:00
Tatsuhiro Tsujikawa
6fd4dd99da nghttpx: Update doc 2016-06-26 22:33:17 +09:00
Tatsuhiro Tsujikawa
1bcf13b28b Update man pages 2016-06-26 20:01:25 +09:00
Tatsuhiro Tsujikawa
c7210908df Bump up version number to 1.12.0 2016-06-26 19:58:44 +09:00
Tatsuhiro Tsujikawa
ad7cded2f4 examples: Check return value from nghttp2_submit_settings 2016-06-26 19:57:29 +09:00
Tatsuhiro Tsujikawa
7d847d8796 Update bash_completion 2016-06-26 00:04:28 +09:00
Tatsuhiro Tsujikawa
ab9cc37ca0 Update man pages 2016-06-26 00:04:17 +09:00
Tatsuhiro Tsujikawa
65095c448d nghttpx: Fix compile error with gcc -Werror=comment 2016-06-25 23:57:40 +09:00
Tatsuhiro Tsujikawa
76e188e368 nghttpx: Fix compile error with gcc 2016-06-25 23:57:26 +09:00
Tatsuhiro Tsujikawa
0613a16c11 nghttpx: Fix compile error without --with-mruby 2016-06-25 23:56:46 +09:00
Tatsuhiro Tsujikawa
aced5b3b6c nghttpx: Fix memory leak from CertLookupTree 2016-06-25 23:47:22 +09:00
Tatsuhiro Tsujikawa
97d8bb16e6 nghttpx: Update doc 2016-06-25 23:37:29 +09:00
Tatsuhiro Tsujikawa
3e14f0d8a5 nghttpx: Fix compile error with openssl 1.0.1
openssl lacks SSL_CTX_get0_certificates().
2016-06-25 23:35:37 +09:00
Tatsuhiro Tsujikawa
f7c0d48152 nghttpx: Rewrite CertLookupTree using Router 2016-06-25 22:52:01 +09:00
Tatsuhiro Tsujikawa
2a4733857f nghttpx: Reduce TTFB with large number of incoming connections
To reduce TTFB with large number of incoming connections, we now
intentionally accept one connection at a time, so that it does not
delay the TTFB of the existing connection.  This is significant
especially for TLS connections.
2016-06-25 11:50:33 +09:00
Tatsuhiro Tsujikawa
3c1efeff55 nghttpx: Don't reset read timer on write in LiveCheck 2016-06-24 22:25:43 +09:00
Tatsuhiro Tsujikawa
532f801fbd nghttpx: Don't reset read timer on write in memcached connection 2016-06-24 00:11:29 +09:00
Tatsuhiro Tsujikawa
cbced219ec nghttpx: Rewrite read timer handling
For HTTP/2, read timer starts when there is no downstream, and timer
stops when there is at least one downstream.  For HTTP/1, read timer
starts when request handling finished, and timer stops when request
handling starts.
2016-06-24 00:04:39 +09:00
Tatsuhiro Tsujikawa
66ca8272ca nghttpx: Clean up neverbleed AF_UNIX socket 2016-06-23 23:04:47 +09:00
Tatsuhiro Tsujikawa
f945653ba9 integration: Add tests for the case where response ends before request
This commit also fixes the rare issue that connection is not made
properly because of race between nghttpx process and TCP client
connection.
2016-06-23 22:21:12 +09:00
Tatsuhiro Tsujikawa
fdc27c9f0e Specify 1 for 2nd parameter of fwrite as a convention 2016-06-22 23:29:09 +09:00
Tatsuhiro Tsujikawa
3aa0ebbbd6 Revert "Robust handling for ssize_t on Win32 platform"
This reverts commit c42296acf1.
2016-06-22 21:29:34 +09:00
Tatsuhiro Tsujikawa
aa16412850 nghttpx: Add --backend-max-backoff option 2016-06-22 00:13:43 +09:00
Tatsuhiro Tsujikawa
e2bdf1d734 nghttpx: Enforce the fact that api and healthmon are mutually exclusive 2016-06-21 22:44:26 +09:00
Tatsuhiro Tsujikawa
4aa79763be Clarify code path when appending inflight_settings 2016-06-21 22:32:08 +09:00
Tatsuhiro Tsujikawa
057db65657 Rewrite session_append_inflight_settings 2016-06-21 22:30:21 +09:00
Tatsuhiro Tsujikawa
c42296acf1 Robust handling for ssize_t on Win32 platform
Now we define NGHTTP2_SSIZE_T which is typedef-ed to the appropriate
type depending on the platform (x86/x86_64).

See GH-616 for details
2016-06-21 22:06:20 +09:00
Tatsuhiro Tsujikawa
d6def22ad5 Update tutorials according to the updated tutorial client/server sources 2016-06-19 23:03:04 +09:00
Tatsuhiro Tsujikawa
cdd72bad77 examples: Add ALPN support to tutorial client/server
This commit adds ALPN support to tutorial client/server.  It also adds
a code to check h2 was negotiated, if not, drop connection.

For tutorial server, now it sends connection preface just after TLS
handshake was made without waiting for the client connection preface.
2016-06-19 22:32:47 +09:00
Tatsuhiro Tsujikawa
123752a032 nghttpx: Handle error from push_upload_data and end_upload_data
We have to gracefully handle the case where response ends before
request body is fully received.
2016-06-17 22:32:15 +09:00
Tatsuhiro Tsujikawa
ec5e438a7c nghttpx: Make backend fail with TLS handshake failure, including ALPN mismatch 2016-06-17 00:53:38 +09:00
Tatsuhiro Tsujikawa
c0b6b9a282 nghttpx: Use 16KiB buffer for reading to match TLS record size 2016-06-17 00:50:40 +09:00
Tatsuhiro Tsujikawa
1fb3d71f77 Update man pages 2016-06-17 00:26:29 +09:00
Tatsuhiro Tsujikawa
43d595b7f3 integration: Add tests for healthmon 2016-06-17 00:24:14 +09:00
Tatsuhiro Tsujikawa
fa8bccbae2 nghttpx: Move api enabled to APIConfig 2016-06-17 00:09:15 +09:00
Tatsuhiro Tsujikawa
56e7cd4be2 nghttpx: Add healthmon parameter to -f option to enable health monitor mode 2016-06-17 00:00:37 +09:00
Tatsuhiro Tsujikawa
af9662f971 nghttpx: Make API processing one of alternative mode 2016-06-16 23:30:35 +09:00
Tatsuhiro Tsujikawa
af4e262d47 nghttpx: Use AI_NUMERICSERV 2016-06-16 23:06:17 +09:00
Tatsuhiro Tsujikawa
96218a1078 nghttpx: Fast backend replacement on multi thread environment 2016-06-16 23:04:06 +09:00
Tatsuhiro Tsujikawa
50c9c3358a nghttpx: Silence logging 2016-06-16 22:12:42 +09:00
Tatsuhiro Tsujikawa
6f025619de nghttpx: Use dedicated worker for API processing
Some API processing is very slow (e.g., getaddrinfo).  To avoid to
slow down regular request handling, if multi threaded configuration is
enabled, we allocate dedicated worker for API.
2016-06-16 21:22:36 +09:00
Tatsuhiro Tsujikawa
7e31340045 nghttpx: Receive reference of std::mt19937, not making a copy 2016-06-16 21:11:39 +09:00
Tatsuhiro Tsujikawa
cddb411495 nghttpx: Fix bug that backend never return to online 2016-06-16 00:57:26 +09:00
Tatsuhiro Tsujikawa
92572203e7 nghttpx: Fix stack buffer overflow with API call 2016-06-16 00:39:11 +09:00
Tatsuhiro Tsujikawa
57259481c8 Fix typo 2016-06-15 00:42:03 +09:00
Tatsuhiro Tsujikawa
c7b0e04498 Add nghttp2_option_set_max_send_header_block_length API function
This function sets the maximum length of header block (a set of header
fields per HEADERS frame) to send.  The length of given set of header
fields is calculated using nghttp2_hd_deflate_bound().  Previously,
this is hard-coded, and is 64KiB.
2016-06-15 00:05:15 +09:00
Tatsuhiro Tsujikawa
47fa56fd0a Update man pages 2016-06-14 00:26:36 +09:00
Tatsuhiro Tsujikawa
fd09d8b861 integration: Rename method names 2016-06-14 00:19:27 +09:00
Tatsuhiro Tsujikawa
d48d399fb3 nghttpx: Allow query in API endpoint 2016-06-13 22:11:26 +09:00
Tatsuhiro Tsujikawa
34468eccc4 Update doc 2016-06-13 21:19:01 +09:00
Tatsuhiro Tsujikawa
81bfb84b32 nghttpx: Rename backend/replace API as backendconfig 2016-06-13 21:17:53 +09:00
Tatsuhiro Tsujikawa
11bca9a98a h2load: Document the behaviour when -d is used with HTTP/1.1 connection 2016-06-12 18:56:32 +09:00
Tatsuhiro Tsujikawa
2868370f9e h2load: http1: Send header + body in one packet 2016-06-12 18:54:06 +09:00
Tatsuhiro Tsujikawa
9f6c947a87 h2load: Use memchunks 2016-06-12 18:50:52 +09:00
Tatsuhiro Tsujikawa
1a2dc1e822 h2load: Add content-length header field for HTTP/2 and SPDY as well 2016-06-12 17:52:47 +09:00
Tatsuhiro Tsujikawa
9bdf214f48 Merge branch 'h2load-http1-upload' 2016-06-12 17:45:42 +09:00
Tatsuhiro Tsujikawa
7469139dda h2load: Implement HTTP/1 upload
h2load has supported uploading a file quite a while, but it turns out
that it worked with HTTP/2 and SPDY only.  HTTP/1 with upload did not
work.  This commit fixes this bug, and implement HTTP/1 upload.  Due
to architectural limitation of h2load, when -d option is used, the
number of in-flight pipe-lined requests is set to 1.
2016-06-12 17:42:12 +09:00
Tatsuhiro Tsujikawa
51c7a13cee Merge branch 'nghttpx-rev-wildcard-router' 2016-06-11 18:47:27 +09:00
Tatsuhiro Tsujikawa
c06e8c89ff nghttpx: Use BlockAllocator in match_downstream_addr_group 2016-06-11 18:41:43 +09:00
Tatsuhiro Tsujikawa
a809da68a3 nghttpx: Aggregate router configuration into one struct 2016-06-11 18:25:38 +09:00
Tatsuhiro Tsujikawa
084206bace nghttpx: Handle edge case wildcard pattern and add tests
Suppose the wildcard patterns follows:

- *.nghttp2.org/foo
- *.img.nghttp2.org/bar

Previously, s.img.nghttp2.org/foo does not match anything.  Now it
matches first pattern.
2016-06-11 13:33:59 +09:00
Tatsuhiro Tsujikawa
288449b9bc nghttpx: Rewrite wildcard router 2016-06-10 23:43:44 +09:00
Tatsuhiro Tsujikawa
11e66510e4 Update man pages 2016-06-09 23:36:30 +09:00
Tatsuhiro Tsujikawa
38f4f50e93 nghttpx: Erase wildcard patterns with http2 proxy enabled 2016-06-09 23:32:27 +09:00
Tatsuhiro Tsujikawa
d36afb7cdb Merge branch 'nghttpx-session-affinity' 2016-06-09 23:23:56 +09:00
Tatsuhiro Tsujikawa
f9897f8ccd nghttpx: Fix bugs and crash when affinity is enabled 2016-06-09 23:17:41 +09:00
Tatsuhiro Tsujikawa
143d0b69b7 nghttpx: Implement client IP based session affinity 2016-06-09 22:35:59 +09:00
Tatsuhiro Tsujikawa
ac97c122d4 nghttpx: Fix memory leak 2016-06-06 00:16:25 +09:00
Tatsuhiro Tsujikawa
7751f4fb3b Add API integration tests with http/1.1 and SPDY 2016-06-05 23:36:04 +09:00
Tatsuhiro Tsujikawa
3cd0b87685 nghttpx: Make API endpoint work with SPDY 2016-06-05 23:35:30 +09:00
Tatsuhiro Tsujikawa
2867f03861 nghttpx: Close TODO comments 2016-06-05 23:02:50 +09:00
Tatsuhiro Tsujikawa
8248598601 Add integration tests for nghttpx API endpoint 2016-06-05 22:51:28 +09:00
Tatsuhiro Tsujikawa
4ef3f9d11c Update doc 2016-06-05 13:17:48 +09:00
Tatsuhiro Tsujikawa
c3817913ee Update man pages 2016-06-04 18:58:04 +09:00
Tatsuhiro Tsujikawa
6214c1b4b6 Update doc 2016-06-04 18:57:46 +09:00
Tatsuhiro Tsujikawa
2499b36801 Update bash_completion 2016-06-04 18:53:27 +09:00
Tatsuhiro Tsujikawa
d196639aed Update man pages 2016-06-04 18:53:13 +09:00
Tatsuhiro Tsujikawa
2c33da36cc Merge branch 'nghttpx-api-endpoint' 2016-06-04 18:51:56 +09:00
Tatsuhiro Tsujikawa
708c99c052 nghttpx: Describe api parameter in --frontend option 2016-06-04 18:48:16 +09:00
Tatsuhiro Tsujikawa
fbdfecc143 Add nghttpx API section 2016-06-04 18:42:30 +09:00
Tatsuhiro Tsujikawa
d3495405d9 nghttpx: Change API endpoint URI 2016-06-04 18:37:37 +09:00
Tatsuhiro Tsujikawa
aad2a24a22 nghttpx: Use JSON for API resposne body 2016-06-04 18:18:07 +09:00
Tatsuhiro Tsujikawa
27fa9c3c12 nghttpx: Only allow POST and PUT for API request 2016-06-04 17:55:48 +09:00
Tatsuhiro Tsujikawa
92db6820d8 nghttpx: Close API request connection for 400 and 413 response 2016-06-04 17:43:48 +09:00
Tatsuhiro Tsujikawa
851cbd49f4 nghttpx: Only parse backend option for API request for now 2016-06-04 17:43:37 +09:00
Tatsuhiro Tsujikawa
8288f5713b nghttpx: Add --api-max-request-body option to set maximum API request body size 2016-06-04 17:24:54 +09:00
Tatsuhiro Tsujikawa
951ef0c6d5 nghttpx: Fix typo 2016-06-04 17:23:47 +09:00
Tatsuhiro Tsujikawa
9653ae98a6 nghttpx: Send 100-continue for API request 2016-06-04 17:23:21 +09:00
Tatsuhiro Tsujikawa
d837887af6 nghttpx: Avoid copy 2016-06-04 16:23:50 +09:00
Tatsuhiro Tsujikawa
2a504224de nghttpx: Rename BlockAllocator::destroy as BlockAllocator::reset 2016-06-04 16:23:31 +09:00
Tatsuhiro Tsujikawa
d0bf247419 nghttpx: Refactor graceful shutdown in Http2Upstream
Instead of using bool flag, just stop prepare watcher.
2016-06-04 12:43:17 +09:00
Tatsuhiro Tsujikawa
9237d30e34 nghttpx: Remove flow_control_ from Http2Session
This is a legacy of SPDY era where it can disable flow control.
2016-06-04 12:38:39 +09:00
Tatsuhiro Tsujikawa
ef3fa23b2e nghttpx: Send GOAWAY for retired h2 backend connection 2016-06-04 12:36:22 +09:00
Tatsuhiro Tsujikawa
cb7269f334 nghttpx: Close and disallow h1 backend connection on backend replacement 2016-06-04 12:16:31 +09:00
Tatsuhiro Tsujikawa
0ca7c4cb38 nghttpx: Send notice to replace downstream via ConnectionHandler 2016-06-04 01:02:57 +09:00
Tatsuhiro Tsujikawa
43913838b4 nghttpx: Retain memory in Router 2016-06-03 23:52:44 +09:00
Tatsuhiro Tsujikawa
845aa7a710 nghttpx: Share downstream config object
This is the unit of sharing configurations to change
2016-06-03 19:57:43 +09:00
Tatsuhiro Tsujikawa
fe58614b23 nghttpx: Use std::shared_ptr for downstream addresses so that we can swap them 2016-06-03 01:20:49 +09:00
Tatsuhiro Tsujikawa
2fd095d036 nghttpx: Share the code to configure backends 2016-06-03 00:22:55 +09:00
Tatsuhiro Tsujikawa
09150a7927 nghttpx: Pass pointer to Config object to store parsed configurations 2016-06-02 23:59:59 +09:00
Tatsuhiro Tsujikawa
667c8b0e27 nghttpx: Add APIDownstreamConnection to handle API request
For those connections via frontend with api parameter, they use solely
APIDownstreamConnection.

In this commit, APIDownstreamConnection just consumes all request
body, and do nothing.  The next few commits implements our first API
endpoint: /v1/api/dynamicconfig.
2016-06-02 23:50:56 +09:00
Tatsuhiro Tsujikawa
2a0d0e798b nghttpx: Add api parameter to --frontend option to mark API endpoint 2016-06-02 23:50:00 +09:00
Tatsuhiro Tsujikawa
8b6947eda5 Merge pull request #605 from alagoutte/misc
fix warning: declaration of 'free' shadows a global declaration
2016-06-02 00:22:47 +09:00
Alexis La Goutte
88e635e0b9 fix warning: declaration of 'free' shadows a global declaration
With some old OS X release
2016-06-01 08:45:13 +02:00
Tatsuhiro Tsujikawa
3753b47475 src: Fix compiler warnings 2016-05-31 21:26:21 +09:00
Tatsuhiro Tsujikawa
be06f1d428 Add missing rst file 2016-05-30 00:13:04 +09:00
Tatsuhiro Tsujikawa
e4dc6cf432 src: Use nghttp2_session_set_local_window_size() 2016-05-29 23:34:38 +09:00
Tatsuhiro Tsujikawa
204f9a3ec7 Add nghttp2_session_set_local_window_size() API function 2016-05-29 23:13:11 +09:00
Tatsuhiro Tsujikawa
f68dc02d6b nghttpx: Remove unused private field from Connection object 2016-05-28 22:46:56 +09:00
Tatsuhiro Tsujikawa
2ca3bf7a7e nghttpx: Fix bug that timeout on h1 backend makes that backend unavailable 2016-05-28 22:41:24 +09:00
Tatsuhiro Tsujikawa
43b045e84c nghttpx: Fix compile error with gcc 2016-05-28 19:50:36 +09:00
Tatsuhiro Tsujikawa
852a320586 nghttpx: Cleanup code where request content-length is involved 2016-05-28 16:44:04 +09:00
Tatsuhiro Tsujikawa
631f977236 Update http-parser to f2c26ee500ab3921010fa7ec66243365611e77dd 2016-05-28 12:17:17 +09:00
Tatsuhiro Tsujikawa
046ec307c3 Bump up version number to 1.12.0-DEV 2016-05-26 23:04:46 +09:00
Tatsuhiro Tsujikawa
50083f0d22 Update man pages 2016-05-26 22:35:51 +09:00
Tatsuhiro Tsujikawa
c4fba5139c Bump up version number to 1.11.0, LT revision to 22:0:8 2016-05-26 22:33:17 +09:00
Tatsuhiro Tsujikawa
81b3e3811b nghttpx: Fix bug that 503 is returned if backend proto is not mixed 2016-05-26 04:49:36 +00:00
Tatsuhiro Tsujikawa
26eb983cf0 nghttpx: Fix bug that h2 is used while there is no h2 backend 2016-05-26 00:14:11 +09:00
Tatsuhiro Tsujikawa
e0491c2ee8 nghttpx: Refactor protocol selection in backend 2016-05-25 23:07:04 +09:00
Tatsuhiro Tsujikawa
fce7908fe6 Merge branch 'mix-backend-proto-tls' 2016-05-24 23:49:21 +09:00
Tatsuhiro Tsujikawa
2a4bf9f615 nghttpx: Allow mixed protocol and TLS settings among backends under same pattern 2016-05-24 23:36:43 +09:00
Tatsuhiro Tsujikawa
45f7c17932 nghttpx: Make backend fail if connect attempt is timed out 2016-05-24 21:59:24 +09:00
Tatsuhiro Tsujikawa
f2a1fadda9 nghttpx: Make backend fail if connect operation was timed out 2016-05-24 21:24:30 +09:00
Tatsuhiro Tsujikawa
98396f00ff nghttpx: Cleane up bit more of save_pid() 2016-05-24 01:32:11 +09:00
Tatsuhiro Tsujikawa
e7d5cfff30 nghttpx: Fix crash introduced in the previous commit 2016-05-24 00:10:53 +09:00
Tatsuhiro Tsujikawa
c308be39de nghttpx: Write PID in temporary file then rename
Write PID in temporary file first.  Then rename it as the real
destination.  It will avoid the issue that the external process may
read the empty PID file because of race condition.
2016-05-23 22:39:38 +09:00
Tatsuhiro Tsujikawa
65135bc319 nghttpx: Check null just in case 2016-05-22 21:57:24 +09:00
Tatsuhiro Tsujikawa
944297df28 Update bash_completion 2016-05-21 14:26:31 +09:00
Tatsuhiro Tsujikawa
f725e419e8 Update man pages 2016-05-21 14:25:03 +09:00
Tatsuhiro Tsujikawa
0fca352114 nghttpx: Make SETTINGS timeout value configurable
SETTINGS timeout can be configurable using
--frontend-http2-settings-timeout and
--backend-http2-settings-timeout.
2016-05-21 14:13:57 +09:00
Tatsuhiro Tsujikawa
9a3461e2b6 nghttpx: Use ev_timer_start intead of ev_timer_again for settings_timer_
Since we only use it once, we don't have to use ev_timer_again, and
stop timer manually.
2016-05-21 13:48:41 +09:00
Tatsuhiro Tsujikawa
0b9ee38db6 nghttpx: Handle corner case where session is going down just after ACK recved 2016-05-21 13:44:53 +09:00
Tatsuhiro Tsujikawa
a224aba577 nghttpx: No need to check activeness of SETTINGS ACK timer
We don't have to check activeness of SETTINGS ACK timer since we only
send SETTINGS frame without ACK only once per session at the moment.
2016-05-21 13:18:22 +09:00
Tatsuhiro Tsujikawa
9f770fec36 nghttpx: Save PID file after it is ready to accept connections 2016-05-21 10:42:09 +09:00
Tatsuhiro Tsujikawa
c39a669671 Merge branch 'nghttpx-settings-timeout-as-failure' 2016-05-21 10:41:52 +09:00
Tatsuhiro Tsujikawa
e6dfd4ff27 nghttpx: Call downstream_failure rather than on_failure in HTTP/1 backend 2016-05-21 10:34:47 +09:00
Tatsuhiro Tsujikawa
e99f3c58f7 nghttpx: Call downstream_failure where it should be
Also, we say connection succeeded only when we got SETTINGS ACK from
peer, rather than when we just connected to the peer in TCP or TLS.
2016-05-21 10:30:09 +09:00
Tatsuhiro Tsujikawa
2a3b6c11eb nghttpx: Don't restart SETTINGS timer, and fix log message in HTTP/2 frontend 2016-05-21 10:29:11 +09:00
Tatsuhiro Tsujikawa
e26d6a2b27 nghttpx: Don't re-enter offline if it is already in offline mode 2016-05-21 10:28:16 +09:00
Tatsuhiro Tsujikawa
dce7288658 nghttpx: Wait for SETTINGS ACK to make sure that backend h2 server is alive 2016-05-21 00:30:54 +09:00
Tatsuhiro Tsujikawa
d1968c4465 nghttpx: Treat backend failure if SETTINGS is not received within timeout 2016-05-19 23:12:34 +09:00
Tatsuhiro Tsujikawa
863fbffda4 Fix typo 2016-05-18 01:25:37 +09:00
Tatsuhiro Tsujikawa
629f1e6f0f nghttpx: Add connection: close to mruby response in graceful shutdown period 2016-05-18 01:21:23 +09:00
Tatsuhiro Tsujikawa
7a3c656adf nghttpx: Refactor 2016-05-15 21:05:20 +09:00
Tatsuhiro Tsujikawa
2a96d433ec Add nghttp2_hd_inflate_hd2() and deprecate nghttp2_hd_inflate_hd()
The difference between them are former has const qualifier to the |in|
parameter, which is desirable since it is effectively read-only.
2016-05-14 18:25:20 +09:00
Tatsuhiro Tsujikawa
796160cb77 nghttpx: Don't add chunked encoded response body for HEAD request 2016-05-14 17:47:58 +09:00
Tatsuhiro Tsujikawa
5c82a36072 nghttpd: Set content-length in status response 2016-05-14 17:29:50 +09:00
Tatsuhiro Tsujikawa
b011012d8f nghttpx: Use NGHTTP2_DATA_FLAG_NO_COPY for backend HTTP/2 session 2016-05-14 17:17:27 +09:00
Tatsuhiro Tsujikawa
8026bdd45a nghttpx: Don't keep backend connection if request buffer is not empty 2016-05-14 17:16:50 +09:00
Tatsuhiro Tsujikawa
5ff6da11b1 Refactor map remove 2016-05-14 11:34:51 +09:00
Tatsuhiro Tsujikawa
de3f2951b3 h2load: Robust error handling in POST data 2016-05-14 00:40:35 +09:00
Tatsuhiro Tsujikawa
d00788ceeb nghttp: More robust error handling while reading file 2016-05-14 00:23:44 +09:00
Tatsuhiro Tsujikawa
e0df95a1d8 nghttp: Eliminate zero length DATA frame at the end if possible 2016-05-14 00:18:22 +09:00
Tatsuhiro Tsujikawa
6d22898936 src: Compile with OpenSSL 1.1.0-pre5
* don't use CRYPTO_LOCK stuff (they are sorted out by openssl, and no
  application intervention is required, just like boringSSL)
* don't use OPENSSL_config
* use provided API to access BIO member
2016-05-07 16:18:58 +09:00
Tatsuhiro Tsujikawa
15a9dfbaea nghttpd: Enable kqueue if it is available on the running platform 2016-05-06 23:45:56 +09:00
Tatsuhiro Tsujikawa
c6facaf662 h2load: Enable kqueue if it is available in the running platform 2016-05-06 23:40:55 +09:00
Tatsuhiro Tsujikawa
60e443b90b h2load: Fix crash on exit on FreeBSD 2016-05-06 23:38:15 +09:00
Tatsuhiro Tsujikawa
d39335829d nghttpx: Enable kqueue by default
We enabled libev kqueue backend in nghttpx by default.  Since it might
not work on some platforms, we also added --no-kqueue option to
disable it.
2016-05-06 23:10:09 +09:00
Tatsuhiro Tsujikawa
5d4f3f36e3 Fix bug that PING flags are ignored in nghttp2_submit_ping 2016-05-05 23:11:10 +09:00
Tatsuhiro Tsujikawa
752b5b3d44 nghttpx: Just call execv instead of execve 2016-05-05 23:08:42 +09:00
Tatsuhiro Tsujikawa
70e8dc3761 ngttpx: Pass environ to execve 2016-05-02 23:39:14 +09:00
Tatsuhiro Tsujikawa
0ee80be995 Update man pages 2016-04-29 23:27:20 +09:00
Tatsuhiro Tsujikawa
3712c89a66 nghttpx: Use parameter instead of keyword for consistency 2016-04-29 22:47:49 +09:00
Tatsuhiro Tsujikawa
8e33f0a535 Update doc 2016-04-29 22:45:47 +09:00
Tatsuhiro Tsujikawa
fd801864e3 nghttpx: Add sni keyword to --backend option
The --backend-tls-sni-field is deprecated in favor of sni keyword.
--backend-tls-sni-field still works, and it overrides all sni keyword
in --backend option.  But it will be removed in the future release.
2016-04-29 14:42:18 +09:00
Tatsuhiro Tsujikawa
99f7e7e2a5 nghttpx: Add mruby env.server_addr and env.tls_used attributes 2016-04-29 12:17:25 +09:00
Tatsuhiro Tsujikawa
6c999e6fb5 nghttpx: Enable TLS session cache again in memcached connection 2016-04-28 22:57:34 +09:00
Tatsuhiro Tsujikawa
4aa4fe56e1 nghttpx: Destroy SSL object, and always lookup TLS session cache 2016-04-28 22:25:55 +09:00
Tatsuhiro Tsujikawa
09b97a3313 nghttpx: Add mruby env.server_port to return frontend server side port 2016-04-28 00:19:30 +09:00
Tatsuhiro Tsujikawa
d2f4e4e325 nghttpx: Always expect response trailer fields 2016-04-27 23:00:36 +09:00
Tatsuhiro Tsujikawa
dba0f35ee1 Avoid 0-length DATA if NGHTTP2_DATA_FLAG_NO_END_STREAM is set 2016-04-27 22:57:19 +09:00
Tatsuhiro Tsujikawa
2d2b72d4eb nghttpx: Don't add 0-length DATA when response HEADERS bears END_STREAM flag 2016-04-27 21:19:28 +09:00
Tatsuhiro Tsujikawa
b39ad3135d nghttpx: Don't use CN if we have dNSName or iPAddress field 2016-04-26 22:32:55 +09:00
Tatsuhiro Tsujikawa
13f97ccf45 integration: Workaround runtime error: cgo argument has Go pointer to Go pointer 2016-04-25 23:16:36 +09:00
Tatsuhiro Tsujikawa
43bbcd35aa Update releasechk 2016-04-25 22:41:48 +09:00
Tatsuhiro Tsujikawa
220f49b157 Bump up version number to 1.11.0-DEV 2016-04-25 22:41:48 +09:00
Tatsuhiro Tsujikawa
918ca4ca7c Update man pages 2016-04-25 22:02:56 +09:00
Tatsuhiro Tsujikawa
7d7dc830ef Bump up version number to 1.10.0, LT revision to 21:0:7 2016-04-25 22:01:26 +09:00
Tatsuhiro Tsujikawa
f939000ad9 Update man pages 2016-04-25 21:58:37 +09:00
Tatsuhiro Tsujikawa
4b34bc583d Update AUTHORS 2016-04-25 21:53:03 +09:00
Tatsuhiro Tsujikawa
91fce2f0e6 Merge branch 'bsuh-master' 2016-04-25 21:51:45 +09:00
Brian Suh
5487b64fa6 nghttpx: Fix downstream connect callback called early 2016-04-24 20:49:38 -07:00
Tatsuhiro Tsujikawa
b27107385e Update AUTHORS 2016-04-24 18:00:41 +09:00
Tatsuhiro Tsujikawa
3d00dd6537 nghttpx: Fix erroneous division by sizeof(...) 2016-04-24 17:42:24 +09:00
Tatsuhiro Tsujikawa
e85bc70bef clang-format 2016-04-24 13:49:57 +09:00
Tatsuhiro Tsujikawa
b0e98718f5 src: Handle return value of getsockopt 2016-04-24 00:42:11 +09:00
Tatsuhiro Tsujikawa
3d4a4cb617 Disable integration tests due to golang build failure 2016-04-23 20:50:49 +09:00
Tatsuhiro Tsujikawa
86777defa8 nghttpx: Workaround for some older gcc4.9 2016-04-23 18:20:50 +09:00
Tatsuhiro Tsujikawa
52b455cfeb Mention the removal of --backend-http2-connections-per-worker in migration guide 2016-04-23 00:46:10 +09:00
Tatsuhiro Tsujikawa
add182b495 Merge branch 'meconlen-data_unset' 2016-04-23 00:35:55 +09:00
Tatsuhiro Tsujikawa
3d948fd3d7 Zero fill in nghttp2_session_mem_send 2016-04-23 00:32:23 +09:00
Mike Conlen
e04e24c1c2 in nghttp2_session_send() data is declared uninitialized and used
after a call to nghttp2_session_mem_send_internal() which should
set it, however in nghttp2_session_mem_send_internal() it is
possible to return before setting the pointer.

This change initializes the variable to NULL where delcared and
sets the variable in nghttp2_session_mem_send_internal() to
NULL before possibly returning rather than after.

both options are not necessary but are both ideal practice
2016-04-21 22:53:19 +00:00
Tatsuhiro Tsujikawa
68059ccda9 nghttp: Use nghttp2_session_mem_recv 2016-04-21 23:30:35 +09:00
Tatsuhiro Tsujikawa
bc2b941866 nghttpx: Wildcard match for CN 2016-04-21 22:53:07 +09:00
Tatsuhiro Tsujikawa
9b81eec944 nghttpx: Remove trailing "." from SAN DNS name and CN 2016-04-21 22:44:26 +09:00
Tatsuhiro Tsujikawa
00bf701600 nghttpx: Truncate too long -b option signature 2016-04-18 23:45:33 +09:00
Tatsuhiro Tsujikawa
5339c1774c nghttpx: Log when backend group is shared 2016-04-16 22:04:35 +09:00
Tatsuhiro Tsujikawa
e41d8c2f62 Update man pages 2016-04-16 19:12:12 +09:00
Tatsuhiro Tsujikawa
73740477fb Update doc 2016-04-16 18:58:18 +09:00
Tatsuhiro Tsujikawa
f86a9d654d Update doc 2016-04-16 18:52:32 +09:00
Tatsuhiro Tsujikawa
6f52da834b nghttpx: Fix bug that server push from mruby script did not work 2016-04-16 18:52:14 +09:00
Tatsuhiro Tsujikawa
4041d1eb26 Don't send ALTSVC if stream is closing 2016-04-15 00:59:05 +09:00
Tatsuhiro Tsujikawa
81f81e6b70 nghttpx: Error handling without assert 2016-04-13 19:22:32 +09:00
Tatsuhiro Tsujikawa
a16daf109b nghttpx: Try next HTTP/1 backend address when connection cannot be made 2016-04-13 00:38:21 +09:00
Tatsuhiro Tsujikawa
b6708a4b87 nghttpx: Retry next HTTP/2 backend address when connection cannot be made 2016-04-13 00:38:08 +09:00
Tatsuhiro Tsujikawa
bda352bf73 Update http-parser 2016-04-11 23:14:15 +09:00
Tatsuhiro Tsujikawa
ca261a7971 Update sphinx_rtd_theme 2016-04-11 23:05:05 +09:00
Tatsuhiro Tsujikawa
0819716332 Update doc 2016-04-11 23:00:38 +09:00
Tatsuhiro Tsujikawa
a14cea6363 nghttpx: Enable link header field based push for non-final response 2016-04-10 18:58:54 +09:00
Tatsuhiro Tsujikawa
2cac7bb838 Update bash_completion 2016-04-10 17:00:11 +09:00
Tatsuhiro Tsujikawa
65378f80ea Update man pages 2016-04-10 16:59:57 +09:00
Tatsuhiro Tsujikawa
40f3779eb1 Pass unknown SETTINGS values to nghttp2_on_frame_recv_callback 2016-04-10 16:36:04 +09:00
Tatsuhiro Tsujikawa
d88f962565 Add test for altsvc frame 2016-04-09 22:32:48 +09:00
Tatsuhiro Tsujikawa
9c0bd8c60a Fix compile error (again) with gcc and --enable-werror 2016-04-09 22:01:15 +09:00
Tatsuhiro Tsujikawa
9e64d10223 nghttpx: Move fall/rise configuration to --backend option
This commit removes --backend-fall and --backend-rise options.  The
these configurations are now set as fall and rise parameters in
--backend option.
2016-04-09 21:58:08 +09:00
Tatsuhiro Tsujikawa
94c8a8fbde doc: Add missing rst files for cleaning 2016-04-09 19:43:10 +09:00
Tatsuhiro Tsujikawa
16647622f5 Fix compile error with gcc and --enable-werror 2016-04-09 19:37:35 +09:00
Tatsuhiro Tsujikawa
9028512a5f Merge branch 'altsvc' 2016-04-09 19:29:17 +09:00
Tatsuhiro Tsujikawa
3086d65657 altsvc: Update doc 2016-04-09 19:27:09 +09:00
Tatsuhiro Tsujikawa
d4144a7475 altsvc: Add tests, ignore altsvc if stream does not exist 2016-04-09 19:14:15 +09:00
Tatsuhiro Tsujikawa
6638ca9333 altsvc: Reduce bitfield size 2016-04-09 18:23:15 +09:00
Tatsuhiro Tsujikawa
b924ef5fff altsvc: Discard altsvc when it is received by server in earlier point 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
df56f55f84 Assign nghttp2_frame.ext.payload early 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
31595c2416 Embed nghttp2_ext_frame_payload into nghttp2_outbound_item 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
795ee8c20f altsvc: Receive ALTSVC frame 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
efbd48b122 altsvc: Add tx tests 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
9b4089c244 src: Log ALTSVC 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
8b5a85ae1d altsvc: Add error handling about origin and stream_id 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
ecabef2dc7 altsvc: Add ALTSVC frame support 2016-04-08 23:25:56 +09:00
Tatsuhiro Tsujikawa
4a6fc6cede src: Add missing source file to CMakeLists.txt 2016-04-08 23:19:54 +09:00
Tatsuhiro Tsujikawa
287d4e35f3 Merge branch 'nghttpx-downstream-live-check' 2016-04-08 23:07:30 +09:00
Tatsuhiro Tsujikawa
a803be9171 nghttpx: Check negotiated ALPN in LiveCheck 2016-04-08 23:07:17 +09:00
Tatsuhiro Tsujikawa
ece3654139 nghttpx: Remove unused function declaration 2016-04-08 23:07:17 +09:00
Tatsuhiro Tsujikawa
bf5392dafe nghttpx: Use exponential backoff between failed connection attempts in LiveCheck 2016-04-08 23:07:17 +09:00
Tatsuhiro Tsujikawa
7bc35044c7 nghttpx: Add --backend-fall and --backend-rise options
These options are analogous to fall and rise parameter found in
haproxy.
2016-04-08 23:07:17 +09:00
Tatsuhiro Tsujikawa
f9b872ab78 nghttpx: Detect online/offline state of backend servers 2016-04-08 23:07:17 +09:00
Tatsuhiro Tsujikawa
ffddefc177 nghttpx: Refactor handling of negotiated ALPN 2016-04-08 23:06:37 +09:00
Tatsuhiro Tsujikawa
2a59c832c1 nghttpx: Set 0 to next_proto_len explicitly for clarification 2016-04-08 23:03:42 +09:00
Tatsuhiro Tsujikawa
ea5f424dec nghttpx: Use gRPC's exponential backoff algorithm 2016-04-05 22:31:27 +09:00
Tatsuhiro Tsujikawa
46514074a4 nghttpx: Better load balancing between backend HTTP/2 servers 2016-04-03 15:09:01 +09:00
Tatsuhiro Tsujikawa
1816af4fb2 Update authors 2016-04-03 10:26:00 +09:00
Tatsuhiro Tsujikawa
b1662a31f4 nghttpx: Fix crash with backend failure 2016-04-03 00:23:44 +09:00
Tatsuhiro Tsujikawa
5974abad75 Run error callback when peer does not send initial SETTINGS frame 2016-04-02 18:20:49 +09:00
Tatsuhiro Tsujikawa
344541dd89 nghttpx: Better distribute load to backend h2 servers 2016-04-02 00:02:48 +09:00
Tatsuhiro Tsujikawa
c17b3b8517 clang-format 2016-03-31 20:06:14 +09:00
Tatsuhiro Tsujikawa
b26503f51c Merge branch 'jchampio-dev/expect-continue' 2016-03-31 20:05:08 +09:00
Tatsuhiro Tsujikawa
2b22ec42c7 Merge branch 'dev/expect-continue' of https://github.com/jchampio/nghttp2 into jchampio-dev/expect-continue 2016-03-31 20:00:27 +09:00
Jacob Champion
dfdeeb3815 nghttp: only stop ContinueTimers if they exist
Fix a crash on disconnect if --expect-continue isn't actually in use.
2016-03-29 16:02:10 -07:00
Jacob Champion
4bed7854b5 nghttp: move ownership of ContinueTimer to Request
Each Request now owns its own (optional) ContinueTimer for
Expect/Continue handshakes. This removes the need for
shared_ptr/weak_ptr logic.
2016-03-29 13:11:27 -07:00
Jacob Champion
aa64e7ad3c nghttp: stop ContinueTimers on response or reset
If the stream itself is reset, or the server sends a final response
immediately, any Expect/Continue handshake should be cancelled.
2016-03-29 12:41:28 -07:00
Tatsuhiro Tsujikawa
8667bbb823 Don't send WINDOW_UPDATE if session is being closed 2016-03-29 23:30:55 +09:00
Tatsuhiro Tsujikawa
1fef49aaa4 Merge branch 'tsing-patch-1' 2016-03-29 22:11:58 +09:00
Tatsuhiro Tsujikawa
e30edb096a clang-format 2016-03-29 22:11:42 +09:00
Tatsuhiro Tsujikawa
cdb466956d nghttpx: One more fix for usage help 2016-03-29 22:10:30 +09:00
Jianqing Wang
199600af73 Fix error messages on deprecated mode 2016-03-29 12:09:52 +08:00
Jacob Champion
edb874e659 nghttp: move ContinueTimer start to on_frame_send
The ContinueTimer could expire before the full HEADERS frame was
actually sent. By moving the call to timer->start() to the
on_frame_send_callback(), this race is fixed.
2016-03-28 15:24:20 -07:00
Tatsuhiro Tsujikawa
fe0843be88 nghttpx: Fix bug that logger wrote string which was not NULL-terminated 2016-03-28 22:22:26 +09:00
Tatsuhiro Tsujikawa
ff07018720 nghttpx: Fix bug that proxy with HTTP/1.1 CONNECT did not work
This was a regression in 5fbe4cc225.
2016-03-28 22:05:38 +09:00
Tatsuhiro Tsujikawa
402eccf06d Bump up version number to 1.10.0-DEV 2016-03-27 22:29:09 +09:00
Jacob Champion
3b7b6a660e nghttp: prevent ContinueTimer double-invocation
If a 100 Continue interim response was received after the continue
timeout was reached, dispatch_continue() would force a double submission
of DATA frames. This patch prevents dispatch_continue() from doing
anything if the timer callback has already been invoked. This makes
ContinueTimer a single-shot mechanism, as originally intended.
2016-03-23 09:09:13 -07:00
Jacob Champion
1bc5cf5ee4 nghttp: time out on long Expect/Continue waits
To deal with servers that don't conform to RFC 7231 (or, potentially,
connections with a large round-trip time), don't wait forever for a 100
Continue status to come back. Currently, the timeout is hard-coded to
one second.

A ContinueTimer encapsulates the handshake timeout logic for a single
request. Somewhat counterintuitively, ContinueTimers are owned by the
HttpClient instead of the Request object, because their lifetime must be
bound to the life of the connection (which is owned by the HttpClient
and not the Requests). A Request is associated with its corresponding
ContinueTimer through a std::weak_ptr.
2016-03-22 13:10:00 -07:00
Jacob Champion
f4c7ebcbca nghttp: implement Expect/Continue handshake
Requests that expect a 100 Continue will not submit their DATA frames
until the server sends the interim response.
2016-03-22 13:10:00 -07:00
Jacob Champion
feb3d1b478 nghttp: add an --expect-continue option
Add a placeholder for the expect-continue option, which will perform an
Expect/Continue handshake for DATA uploads.
2016-03-22 13:10:00 -07:00
226 changed files with 21761 additions and 9815 deletions

View File

@@ -1,57 +1,94 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakTemplateDeclarations: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '$'
IndentCaseLabels: false
IndentWidth: 2
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: true
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
IndentWidth: 2
TabWidth: 8
UseTab: Never
BreakBeforeBraces: Attach
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
...

View File

@@ -43,6 +43,7 @@ before_script:
- git clone https://github.com/tatsuhiro-t/spdylay.git
- cd spdylay
- autoreconf -i
# Don't use ASAN for spdylay since failmalloc does not work with it.
- ./configure --disable-src --disable-examples
- make check
- export SPDYLAY_HOME=$PWD
@@ -50,12 +51,13 @@ before_script:
# Now build nghttp2
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
- git submodule update --init
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"; fi
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay" CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address; fi
- if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DSPDYLAY_INCLUDE_DIR="$SPDYLAY_HOME/lib/includes" -DSPDYLAY_LIBRARY="$SPDYLAY_HOME/lib/.libs/libspdylay.so"; fi
script:
- make
- make check
- cd integration-tests
- export GOPATH="$PWD/integration-tests/golang"
- make itprep
- make it
# As of April, 23, 2016, golang http2 build fails, probably because
# the default go version is too old.
# - cd integration-tests
# - export GOPATH="$PWD/integration-tests/golang"
# - make itprep
# - make it

View File

@@ -23,6 +23,7 @@ Andy Davies
Ant Bryan
Bernard Spil
Brian Card
Brian Suh
Daniel Stenberg
Dave Reisner
David Beitey
@@ -31,9 +32,11 @@ Etienne Cimon
Fabian Möller
Fabian Wiesel
Gabi Davar
Jacob Champion
Jan-E
Janusz Dziemidowicz
Jay Satiro
Jianqing Wang
Jim Morrison
José F. Calcerrada
Kamil Dudka
@@ -44,6 +47,7 @@ Kit Chan
Kyle Schomp
Lucas Pardue
MATSUMOTO Ryosuke
Mike Conlen
Mike Frysinger
Nicholas Hurley
Nora Shoemaker
@@ -67,6 +71,7 @@ Tomasz Buchert
Vernon Tang
Viacheslav Biriukov
Viktor Szépe
Wenfeng Liu
Xiaoguang Sun
Zhuoyun Wei
acesso

View File

@@ -24,15 +24,15 @@
cmake_minimum_required(VERSION 3.0)
# XXX using 1.8.90 instead of 1.9.0-DEV
project(nghttp2 VERSION 1.9.1)
project(nghttp2 VERSION 1.16.0)
# See versioning rule:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
set(LT_CURRENT 20)
set(LT_CURRENT 26)
set(LT_REVISION 0)
set(LT_AGE 6)
set(LT_AGE 12)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(Version)
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
@@ -408,10 +408,10 @@ configure_file(cmakeconfig.h.in config.h)
# autotools-compatible names
# Sphinx expects relative paths in the .rst files. Use the fact that the files
# below are all one directory level deep.
file(RELATIVE_PATH top_srcdir "${CMAKE_BINARY_DIR}/dir" "${CMAKE_SOURCE_DIR}")
file(RELATIVE_PATH top_builddir "${CMAKE_BINARY_DIR}/dir" "${CMAKE_BINARY_DIR}")
set(abs_top_srcdir "${CMAKE_SOURCE_DIR}")
set(abs_top_builddir "${CMAKE_BINARY_DIR}")
file(RELATIVE_PATH top_srcdir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_SOURCE_DIR}")
file(RELATIVE_PATH top_builddir "${CMAKE_CURRENT_BINARY_DIR}/dir" "${CMAKE_CURRENT_BINARY_DIR}")
set(abs_top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set(abs_top_builddir "${CMAKE_CURRENT_BINARY_DIR}")
# libnghttp2.pc (pkg-config file)
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
@@ -450,7 +450,7 @@ foreach(name
endforeach()
include_directories(
"${CMAKE_BINARY_DIR}" # for config.h
"${CMAKE_CURRENT_BINARY_DIR}" # for config.h
)
# For use in src/CMakeLists.txt
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")

View File

@@ -58,6 +58,11 @@ To build the documentation, you need to install:
* sphinx (http://sphinx-doc.org/)
If you need libnghttp2 (C library) only, then the above packages are
all you need. Use ``--enable-lib-only`` to ensure that only
libnghttp2 is built. This avoids potential build error related to
building bundled applications.
To build and run the application programs (``nghttp``, ``nghttpd``,
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
are required:
@@ -104,7 +109,9 @@ The Python bindings require the following packages:
* python >= 2.7
* python-setuptools
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages::
If you are using Ubuntu 14.04 LTS (trusty) or Debian 7.0 (wheezy) and above run the following to install the needed packages:
.. code-block:: text
sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \
zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \
@@ -138,7 +145,9 @@ Building from git
-----------------
Building from git is easy, but please be sure that at least autoconf 2.68 is
used::
used:
.. code-block:: text
$ autoreconf -i
$ automake
@@ -172,6 +181,23 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
applications were not built, then using ``--enable-app`` may find
that cause, such as the missing dependency.
Notes for building on Windows (MSVC)
------------------------------------
The easiest way to build native Windows nghttp2 dll is use `cmake
<https://cmake.org/>`_. The free version of `Visual C++ Build Tools
<http://landinghub.visualstudio.com/visual-cpp-build-tools>`_ works
fine.
1. Install cmake for windows
2. Open "Visual C++ ... Native Build Tool Command Prompt", and inside
nghttp2 directly, run ``cmake``.
3. Then run ``cmake --build`` to build library.
4. nghttp2.dll, nghttp2.lib, nghttp2.exp are placed under lib directory.
Note that the above steps most likely produce nghttp2 library only.
No bundled applications are compiled.
Notes for building on Windows (Mingw/Cygwin)
--------------------------------------------
@@ -188,7 +214,9 @@ Secondly, you need to undefine the macro ``__STRICT_ANSI__``, if you
not, the functions ``fdopen``, ``fileno`` and ``strptime`` will not
available.
the sample command like this::
the sample command like this:
.. code-block:: text
$ export CFLAGS="-U__STRICT_ANSI__ -I$libev_PREFIX/include -L$libev_PREFIX/lib"
$ export CXXFLAGS=$CFLAGS
@@ -206,7 +234,9 @@ Building the documentation
Documentation is still incomplete.
To build the documentation, run::
To build the documentation, run:
.. code-block:: text
$ make html
@@ -235,12 +265,16 @@ its testing framework. We depend on the following libraries:
* https://github.com/tatsuhiro-t/spdy
To download the above packages, after settings ``GOPATH``, run the
following command under ``integration-tests`` directory::
following command under ``integration-tests`` directory:
.. code-block:: text
$ make itprep
To run the tests, run the following command under
``integration-tests`` directory::
``integration-tests`` directory:
.. code-block:: text
$ make it
@@ -361,7 +395,9 @@ nghttp - client
with prior knowledge, HTTP Upgrade and NPN/ALPN TLS extension.
It has verbose output mode for framing information. Here is sample
output from ``nghttp`` client::
output from ``nghttp`` client:
.. code-block:: text
$ nghttp -nv https://nghttp2.org
[ 0.190] Connected
@@ -444,7 +480,9 @@ output from ``nghttp`` client::
[ 0.228] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
The HTTP Upgrade is performed like so::
The HTTP Upgrade is performed like so:
.. code-block:: text
$ nghttp -nvu http://nghttp2.org
[ 0.011] Connected
@@ -540,7 +578,9 @@ The HTTP Upgrade is performed like so::
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
Using the ``-s`` option, ``nghttp`` prints out some timing information for
requests, sorted by completion time::
requests, sorted by completion time:
.. code-block:: text
$ nghttp -nas https://nghttp2.org/
***** Statistics *****
@@ -584,7 +624,9 @@ HTTP/2 connections. No HTTP Upgrade is supported.
The ``-p`` option allows users to configure server push.
Just like ``nghttp``, it has a verbose output mode for framing
information. Here is sample output from ``nghttpd``::
information. Here is sample output from ``nghttpd``:
.. code-block:: text
$ nghttpd --no-tls -v 8080
IPv4: listen 0.0.0.0:8080
@@ -688,13 +730,17 @@ are not encrypted by default. To encrypt backend connections, use
sample configuration file ``nghttpx.conf.sample``.
In the default mode, ``nghttpx`` works as reverse proxy to the backend
server::
server:
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
[reverse proxy]
With the ``--http2-proxy`` option, it works as forward proxy, and it
is so called secure HTTP/2 proxy (aka 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
[secure proxy] (e.g., Squid, ATS)
@@ -716,14 +762,18 @@ create a proxy.pac script like this:
machine nghttpx is running on. Please note that Chrome requires a valid
certificate for secure proxy.
Then run Chrome with the following arguments::
Then run Chrome with the following arguments:
.. code-block:: text
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
The backend HTTP/2 connections can be tunneled through an HTTP proxy.
The proxy is specified using ``--backend-http-proxy-uri``. The
following figure illustrates how nghttpx talks to the outside HTTP/2
proxy through an HTTP proxy::
proxy through an HTTP proxy:
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
@@ -737,7 +787,9 @@ The ``h2load`` program is a benchmarking tool for HTTP/2 and SPDY.
The SPDY support is enabled if the program was built with the spdylay
library. The UI of ``h2load`` is heavily inspired by ``weighttp``
(https://github.com/lighttpd/weighttp). The typical usage is as
follows::
follows:
.. code-block:: text
$ h2load -n100000 -c100 -m100 https://localhost:8443/
starting benchmark...
@@ -825,7 +877,9 @@ Example:
With the ``-t`` option, the program can accept more familiar HTTP/1 style
header field blocks. Each header set is delimited by an empty line:
Example::
Example:
.. code-block:: text
:method: GET
:scheme: https
@@ -1321,7 +1375,7 @@ The extension module is called ``nghttp2``.
determined by the ``configure`` script. If the detected Python version is not
what you expect, specify a path to Python executable in a ``PYTHON``
variable as an argument to configure script (e.g., ``./configure
PYTHON=/usr/bin/python3.4``).
PYTHON=/usr/bin/python3.5``).
The following example code illustrates basic usage of the HPACK compressor
and decompressor in Python:
@@ -1451,6 +1505,17 @@ See `Contribution Guidelines
<https://nghttp2.org/documentation/contribute.html>`_ for more
details.
Reporting vulnerability
-----------------------
If you find a vulnerability in our software, please send the email to
"tatsuhiro.t at gmail dot com" about its details instead of submitting
issues on github issue page. It is a standard practice not to
disclose vulnerability information publicly until a fixed version is
released, or mitigation is worked out.
In the future, we may setup a dedicated mail address for this purpose.
Release schedule
----------------
@@ -1463,3 +1528,8 @@ severe security bug fixes.
We have no plan to break API compatibility changes involving soname
bump, so MAJOR version will stay 1 for the foreseeable future.
License
-------
The MIT License

View File

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

52
author.py Executable file
View 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

View File

@@ -25,7 +25,7 @@ dnl Do not change user variables!
dnl http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
AC_PREREQ(2.61)
AC_INIT([nghttp2], [1.9.1], [t-tujikawa@users.sourceforge.net])
AC_INIT([nghttp2], [1.16.0], [t-tujikawa@users.sourceforge.net])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
@@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl See versioning rule:
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
AC_SUBST(LT_CURRENT, 20)
AC_SUBST(LT_CURRENT, 26)
AC_SUBST(LT_REVISION, 0)
AC_SUBST(LT_AGE, 6)
AC_SUBST(LT_AGE, 12)
major=`echo $PACKAGE_VERSION |cut -d. -f1 | sed -e "s/[^0-9]//g"`
minor=`echo $PACKAGE_VERSION |cut -d. -f2 | sed -e "s/[^0-9]//g"`
@@ -234,6 +234,41 @@ std::map<int, int>().emplace(1, 2);
[have_std_map_emplace=no
AC_MSG_RESULT([no])])
# Check that std::atomic_* overloads for std::shared_ptr are
# available.
AC_MSG_CHECKING([whether std::atomic_* overloads for std::shared_ptr are available])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <memory>
]],
[[
auto a = std::make_shared<int>(1000000007);
auto p = std::atomic_load(&a);
++*p;
std::atomic_store(&a, p);
]])],
[AC_DEFINE([HAVE_ATOMIC_STD_SHARED_PTR], [1],
[Define to 1 if you have the std::atomic_* overloads for std::shared_ptr.])
have_atomic_std_shared_ptr=yes
AC_MSG_RESULT([yes])],
[have_atomic_std_shared_ptr=no
AC_MSG_RESULT([no])])
# Check that thread_local storage specifier is available
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
,
[[
thread_local int a = 0;
(void)a;
]])],
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
[Define to 1 if you have thread_local storage specifier.])
have_thread_local=yes
AC_MSG_RESULT([yes])],
[have_Thread_local=no
AC_MSG_RESULT([no])])
CXXFLAGS=$save_CXXFLAGS
AC_LANG_POP()
@@ -246,7 +281,7 @@ TESTLDADD=
# Additional libraries required for programs under src directory.
APPLDFLAGS=
case "$host" in
case "$host_os" in
*android*)
android_build=yes
# android does not need -pthread, but needs followng 3 libs for C++
@@ -258,6 +293,12 @@ case "$host" in
;;
esac
case "$host_os" in
*solaris*)
APPLDFLAGS="$APPLDFLAGS -lsocket -lnsl"
;;
esac
# zlib
PKG_CHECK_MODULES([ZLIB], [zlib >= 1.2.3], [have_zlib=yes], [have_zlib=no])
@@ -720,6 +761,7 @@ if test "x$werror" != "xno"; then
AX_CHECK_COMPILE_FLAG([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"])
# Only work with Clang for the moment
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CFLAGS="$CFLAGS -Wsometimes-uninitialized"])
# This is required because we pass format string as "const char*.
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
@@ -729,6 +771,7 @@ if test "x$werror" != "xno"; then
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])
AX_CHECK_COMPILE_FLAG([-Werror], [CXXFLAGS="$CXXFLAGS -Werror"])
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
AC_LANG_POP()
fi
@@ -825,6 +868,7 @@ AC_MSG_NOTICE([summary of build options:
C preprocessor: ${CPP}
CPPFLAGS: ${CPPFLAGS}
WARNCFLAGS: ${WARNCFLAGS}
WARNCXXFLAGS: ${WARNCXXFLAGS}
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
EXTRACFLAG: ${EXTRACFLAG}
LIBS: ${LIBS}

View File

@@ -13,6 +13,7 @@ set(APIDOCS
nghttp2_hd_deflate_get_num_table_entries.rst
nghttp2_hd_deflate_get_table_entry.rst
nghttp2_hd_deflate_hd.rst
nghttp2_hd_deflate_hd_vec.rst
nghttp2_hd_deflate_new.rst
nghttp2_hd_deflate_new2.rst
nghttp2_hd_inflate_change_table_size.rst
@@ -23,6 +24,7 @@ set(APIDOCS
nghttp2_hd_inflate_get_num_table_entries.rst
nghttp2_hd_inflate_get_table_entry.rst
nghttp2_hd_inflate_hd.rst
nghttp2_hd_inflate_hd2.rst
nghttp2_hd_inflate_new.rst
nghttp2_hd_inflate_new2.rst
nghttp2_http2_strerror.rst
@@ -30,7 +32,10 @@ set(APIDOCS
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
@@ -53,13 +58,15 @@ set(APIDOCS
nghttp2_session_callbacks_set_on_begin_frame_callback.rst
nghttp2_session_callbacks_set_on_begin_headers_callback.rst
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst
nghttp2_session_callbacks_set_on_frame_recv_callback.rst
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst
nghttp2_session_callbacks_set_on_frame_send_callback.rst
nghttp2_session_callbacks_set_on_header_callback.rst
nghttp2_session_callbacks_set_on_header_callback2.rst
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst
nghttp2_session_callbacks_set_on_invalid_header_callback.rst
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst
nghttp2_session_callbacks_set_on_stream_close_callback.rst
nghttp2_session_callbacks_set_pack_extension_callback.rst
nghttp2_session_callbacks_set_recv_callback.rst
@@ -67,6 +74,9 @@ set(APIDOCS
nghttp2_session_callbacks_set_send_callback.rst
nghttp2_session_callbacks_set_send_data_callback.rst
nghttp2_session_callbacks_set_unpack_extension_callback.rst
nghttp2_session_change_stream_priority.rst
nghttp2_session_check_request_allowed.rst
nghttp2_session_check_server_session.rst
nghttp2_session_client_new.rst
nghttp2_session_client_new2.rst
nghttp2_session_client_new3.rst
@@ -78,7 +88,11 @@ set(APIDOCS
nghttp2_session_find_stream.rst
nghttp2_session_get_effective_local_window_size.rst
nghttp2_session_get_effective_recv_data_length.rst
nghttp2_session_get_hd_deflate_dynamic_table_size.rst
nghttp2_session_get_hd_inflate_dynamic_table_size.rst
nghttp2_session_get_last_proc_stream_id.rst
nghttp2_session_get_local_settings.rst
nghttp2_session_get_local_window_size.rst
nghttp2_session_get_next_stream_id.rst
nghttp2_session_get_outbound_queue_size.rst
nghttp2_session_get_remote_settings.rst
@@ -87,20 +101,19 @@ set(APIDOCS
nghttp2_session_get_stream_effective_local_window_size.rst
nghttp2_session_get_stream_effective_recv_data_length.rst
nghttp2_session_get_stream_local_close.rst
nghttp2_session_get_stream_local_window_size.rst
nghttp2_session_get_stream_remote_close.rst
nghttp2_session_get_stream_remote_window_size.rst
nghttp2_session_get_stream_user_data.rst
nghttp2_session_mem_recv.rst
nghttp2_session_mem_send.rst
nghttp2_session_recv.rst
nghttp2_session_change_stream_priority.rst
nghttp2_session_check_request_allowed.rst
nghttp2_session_check_server_session.rst
nghttp2_session_resume_data.rst
nghttp2_session_send.rst
nghttp2_session_server_new.rst
nghttp2_session_server_new2.rst
nghttp2_session_server_new3.rst
nghttp2_session_set_local_window_size.rst
nghttp2_session_set_next_stream_id.rst
nghttp2_session_set_stream_user_data.rst
nghttp2_session_terminate_session.rst
@@ -109,6 +122,7 @@ set(APIDOCS
nghttp2_session_upgrade2.rst
nghttp2_session_want_read.rst
nghttp2_session_want_write.rst
nghttp2_set_debug_vprintf_callback.rst
nghttp2_stream_get_first_child.rst
nghttp2_stream_get_next_sibling.rst
nghttp2_stream_get_parent.rst
@@ -117,6 +131,7 @@ set(APIDOCS
nghttp2_stream_get_sum_dependency_weight.rst
nghttp2_stream_get_weight.rst
nghttp2_strerror.rst
nghttp2_submit_altsvc.rst
nghttp2_submit_data.rst
nghttp2_submit_extension.rst
nghttp2_submit_goaway.rst

View File

@@ -37,6 +37,7 @@ APIDOCS= \
nghttp2_hd_deflate_get_num_table_entries.rst \
nghttp2_hd_deflate_get_table_entry.rst \
nghttp2_hd_deflate_hd.rst \
nghttp2_hd_deflate_hd_vec.rst \
nghttp2_hd_deflate_new.rst \
nghttp2_hd_deflate_new2.rst \
nghttp2_hd_inflate_change_table_size.rst \
@@ -47,6 +48,7 @@ APIDOCS= \
nghttp2_hd_inflate_get_num_table_entries.rst \
nghttp2_hd_inflate_get_table_entry.rst \
nghttp2_hd_inflate_hd.rst \
nghttp2_hd_inflate_hd2.rst \
nghttp2_hd_inflate_new.rst \
nghttp2_hd_inflate_new2.rst \
nghttp2_http2_strerror.rst \
@@ -54,7 +56,10 @@ APIDOCS= \
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 \
@@ -84,6 +89,8 @@ APIDOCS= \
nghttp2_session_callbacks_set_on_header_callback.rst \
nghttp2_session_callbacks_set_on_header_callback2.rst \
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
nghttp2_session_callbacks_set_on_invalid_header_callback.rst \
nghttp2_session_callbacks_set_on_invalid_header_callback2.rst \
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback.rst \
nghttp2_session_callbacks_set_recv_callback.rst \
@@ -91,6 +98,9 @@ APIDOCS= \
nghttp2_session_callbacks_set_send_callback.rst \
nghttp2_session_callbacks_set_send_data_callback.rst \
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
nghttp2_session_change_stream_priority.rst \
nghttp2_session_check_request_allowed.rst \
nghttp2_session_check_server_session.rst \
nghttp2_session_client_new.rst \
nghttp2_session_client_new2.rst \
nghttp2_session_client_new3.rst \
@@ -102,7 +112,11 @@ APIDOCS= \
nghttp2_session_find_stream.rst \
nghttp2_session_get_effective_local_window_size.rst \
nghttp2_session_get_effective_recv_data_length.rst \
nghttp2_session_get_hd_deflate_dynamic_table_size.rst \
nghttp2_session_get_hd_inflate_dynamic_table_size.rst \
nghttp2_session_get_last_proc_stream_id.rst \
nghttp2_session_get_local_settings.rst \
nghttp2_session_get_local_window_size.rst \
nghttp2_session_get_next_stream_id.rst \
nghttp2_session_get_outbound_queue_size.rst \
nghttp2_session_get_remote_settings.rst \
@@ -111,20 +125,19 @@ APIDOCS= \
nghttp2_session_get_stream_effective_local_window_size.rst \
nghttp2_session_get_stream_effective_recv_data_length.rst \
nghttp2_session_get_stream_local_close.rst \
nghttp2_session_get_stream_local_window_size.rst \
nghttp2_session_get_stream_remote_close.rst \
nghttp2_session_get_stream_remote_window_size.rst \
nghttp2_session_get_stream_user_data.rst \
nghttp2_session_mem_recv.rst \
nghttp2_session_mem_send.rst \
nghttp2_session_recv.rst \
nghttp2_session_change_stream_priority.rst \
nghttp2_session_check_request_allowed.rst \
nghttp2_session_check_server_session.rst \
nghttp2_session_resume_data.rst \
nghttp2_session_send.rst \
nghttp2_session_server_new.rst \
nghttp2_session_server_new2.rst \
nghttp2_session_server_new3.rst \
nghttp2_session_set_local_window_size.rst \
nghttp2_session_set_next_stream_id.rst \
nghttp2_session_set_stream_user_data.rst \
nghttp2_session_terminate_session.rst \
@@ -133,6 +146,7 @@ APIDOCS= \
nghttp2_session_upgrade2.rst \
nghttp2_session_want_read.rst \
nghttp2_session_want_write.rst \
nghttp2_set_debug_vprintf_callback.rst \
nghttp2_stream_get_first_child.rst \
nghttp2_stream_get_next_sibling.rst \
nghttp2_stream_get_parent.rst \
@@ -141,6 +155,7 @@ APIDOCS= \
nghttp2_stream_get_sum_dependency_weight.rst \
nghttp2_stream_get_weight.rst \
nghttp2_strerror.rst \
nghttp2_submit_altsvc.rst \
nghttp2_submit_data.rst \
nghttp2_submit_extension.rst \
nghttp2_submit_goaway.rst \

View File

@@ -15,6 +15,7 @@ from docutils import nodes
from docutils.parsers.rst import directives
from sphinx import addnodes
from sphinx import version_info
from sphinx.roles import XRefRole
from sphinx.locale import l_, _
from sphinx.domains import Domain, ObjType, Index
@@ -231,8 +232,8 @@ class RubyObject(ObjectDescription):
indextext = self.get_index_text(modname, name_cls)
if indextext:
self.indexnode['entries'].append(('single', indextext,
fullname, fullname))
self.indexnode['entries'].append(
_make_index('single', indextext, fullname, fullname))
def before_content(self):
# needed for automatic qualification of members (reset in subclasses)
@@ -415,11 +416,19 @@ class RubyModule(Directive):
# modindex currently
if not noindex:
indextext = _('%s (module)') % modname
inode = addnodes.index(entries=[('single', indextext,
'module-' + modname, modname)])
inode = addnodes.index(entries=[_make_index(
'single', indextext, 'module-' + modname, modname)])
ret.append(inode)
return ret
def _make_index(entrytype, entryname, target, ignored, key=None):
# Sphinx 1.4 introduced backward incompatible changes, it now
# requires 5 tuples. Last one is categorization key. See
# http://www.sphinx-doc.org/en/stable/extdev/nodes.html#sphinx.addnodes.index
if version_info >= (1, 4, 0, '', 0):
return (entrytype, entryname, target, ignored, key)
else:
return (entrytype, entryname, target, ignored)
class RubyCurrentModule(Directive):
"""

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,7 @@ _h2load()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--connection-window-bits --clients --verbose --ciphers --rate --no-tls-proto --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

View File

@@ -8,7 +8,7 @@ _nghttp()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--no-push --verbose --no-dep --get-assets --har --header-table-size --multiply --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

View File

@@ -8,7 +8,7 @@ _nghttpd()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--htdocs --verbose --daemon --echo-upload --error-gzip --push --header-table-size --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

View File

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

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "H2LOAD" "1" "March 27, 2016" "1.9.1" "nghttp2"
.TH "H2LOAD" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
.SH NAME
h2load \- HTTP/2 benchmarking tool
.
@@ -138,7 +138,9 @@ Default: \fBh2c\fP
.TP
.B \-d, \-\-data=<PATH>
Post FILE to server. The request method is changed to
POST.
POST. For http/1.1 connection, if \fI\%\-d\fP is used, the
maximum number of in\-flight pipelined requests is set to
1.
.UNINDENT
.INDENT 0.0
.TP
@@ -149,7 +151,7 @@ representing the number of connections to be made per
rate period. The maximum number of connections to be
made is given in \fI\%\-c\fP option. This rate will be
distributed among threads as evenly as possible. For
example, with \fB\-t2\fP and \fB\-r4\fP, each thread gets 2
example, with \fI\%\-t\fP2 and \fI\%\-r\fP4, each thread gets 2
connections per period. When the rate is 0, the program
will run as it normally does, creating connections at
whatever variable rate it wants. The default value for
@@ -240,6 +242,23 @@ http/1.1 for both http and https URI.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-header\-table\-size=<SIZE>
Specify decoder header table size.
.sp
Default: \fB4K\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-encoder\-header\-table\-size=<SIZE>
Specify encoder header table size. The decoder (server)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which server specified.
.sp
Default: \fB4K\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-v, \-\-verbose
Output debug information.
.UNINDENT
@@ -254,6 +273,9 @@ Display version information and exit.
Display this help and exit.
.UNINDENT
.sp
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
10 * 1024). Units are K, M and G (powers of 1024).
.sp
The <DURATION> argument is an integer and an optional unit (e.g., 1s
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
(hours, minutes, seconds and milliseconds, respectively). If a unit
@@ -412,7 +434,7 @@ performance. To set smaller flow control window, use \fI\%\-w\fP and
window size described in HTTP/2 and SPDY protocol specification.
.SH SEE ALSO
.sp
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fInghttpx(1)\fP
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBnghttpx(1)\fP
.SH AUTHOR
Tatsuhiro Tsujikawa
.SH COPYRIGHT

View File

@@ -74,14 +74,14 @@ OPTIONS
.. option:: -w, --window-bits=<N>
Sets the stream level initial window size to (2\*\*<N>)-1.
For SPDY, 2**<N> is used instead.
For SPDY, 2\*\*<N> is used instead.
Default: ``30``
.. option:: -W, --connection-window-bits=<N>
Sets the connection level initial window size to
(2**<N>)-1. For SPDY, if <N> is strictly less than 16,
(2\*\*<N>)-1. For SPDY, if <N> is strictly less than 16,
this option is ignored. Otherwise 2\*\*<N> is used for
SPDY.
@@ -108,7 +108,9 @@ OPTIONS
.. option:: -d, --data=<PATH>
Post FILE to server. The request method is changed to
POST.
POST. For http/1.1 connection, if :option:`-d` is used, the
maximum number of in-flight pipelined requests is set to
1.
.. option:: -r, --rate=<N>
@@ -118,7 +120,7 @@ OPTIONS
rate period. The maximum number of connections to be
made is given in :option:`-c` option. This rate will be
distributed among threads as evenly as possible. For
example, with :option:`-t2` and :option:`\-r4`, each thread gets 2
example, with :option:`-t`\2 and :option:`-r`\4, each thread gets 2
connections per period. When the rate is 0, the program
will run as it normally does, creating connections at
whatever variable rate it wants. The default value for
@@ -200,6 +202,21 @@ OPTIONS
:option:`--no-tls-proto`\=http/1.1, which effectively force
http/1.1 for both http and https URI.
.. option:: --header-table-size=<SIZE>
Specify decoder header table size.
Default: ``4K``
.. option:: --encoder-header-table-size=<SIZE>
Specify encoder header table size. The decoder (server)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which server specified.
Default: ``4K``
.. option:: -v, --verbose
Output debug information.
@@ -214,6 +231,9 @@ OPTIONS
The <SIZE> argument is an integer and an optional unit (e.g., 10K is
10 * 1024). Units are K, M and G (powers of 1024).
The <DURATION> argument is an integer and an optional unit (e.g., 1s
is 1 second and 500ms is 500 milliseconds). Units are h, m, s or ms
(hours, minutes, seconds and milliseconds, respectively). If a unit

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPD" "1" "March 27, 2016" "1.9.1" "nghttp2"
.TH "NGHTTPD" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
.SH NAME
nghttpd \- HTTP/2 server
.
@@ -99,6 +99,14 @@ Specify decoder header table size.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-encoder\-header\-table\-size=<SIZE>
Specify encoder header table size. The decoder (client)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which client specified.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-color
Force colored log output.
.UNINDENT
@@ -209,7 +217,7 @@ The <SIZE> argument is an integer and an optional unit (e.g., 10K is
10 * 1024). Units are K, M and G (powers of 1024).
.SH SEE ALSO
.sp
\fInghttp(1)\fP, \fInghttpx(1)\fP, \fIh2load(1)\fP
\fBnghttp(1)\fP, \fBnghttpx(1)\fP, \fBh2load(1)\fP
.SH AUTHOR
Tatsuhiro Tsujikawa
.SH COPYRIGHT

View File

@@ -70,6 +70,13 @@ OPTIONS
Specify decoder header table size.
.. option:: --encoder-header-table-size=<SIZE>
Specify encoder header table size. The decoder (client)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which client specified.
.. option:: --color
Force colored log output.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPX" "1" "March 27, 2016" "1.9.1" "nghttp2"
.TH "NGHTTPX" "1" "Oct 24, 2016" "1.16.0" "nghttp2"
.SH NAME
nghttpx \- HTTP/2 proxy
.
@@ -40,14 +40,14 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.
.TP
.B <PRIVATE_KEY>
Set path to server\(aqs private key. Required unless
"no\-tls" keyword is used in \fI\%\-\-frontend\fP option.
"no\-tls" parameter is used in \fI\%\-\-frontend\fP option.
.UNINDENT
.INDENT 0.0
.TP
.B <CERT>
Set path to server\(aqs certificate. Required unless
"no\-tls" keyword is used in \fI\%\-\-frontend\fP option. To make
OCSP stapling work, this must be an absolute path.
"no\-tls" parameter is used in \fI\%\-\-frontend\fP option. To
make OCSP stapling work, this must be an absolute path.
.UNINDENT
.SH OPTIONS
.sp
@@ -55,7 +55,7 @@ The options are categorized into several groups.
.SS Connections
.INDENT 0.0
.TP
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][;proto=<PROTO>][;tls]]
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
Set backend host and port. The multiple backend
addresses are accepted by repeating this option. UNIX
domain socket can be specified by prefixing path name
@@ -117,17 +117,63 @@ and \fI\%\-b\fP\(aq127.0.0.1,8080;www.nghttp2.org\(aq.
The backend addresses sharing same <PATTERN> are grouped
together forming load balancing group.
.sp
Optionally, backend application protocol can be
specified in <PROTO>. All that share the same <PATTERN>
must have the same <PROTO> value if it is given.
<PROTO> should be one of the following list without
quotes: "h2", "http/1.1". The default value of <PROTO>
is "http/1.1". Note that usually "h2" refers to HTTP/2
over TLS. But in this option, it may mean HTTP/2 over
cleartext TCP unless "tls" keyword is used (see below).
Several parameters <PARAM> are accepted after <PATTERN>.
The parameters are delimited by ";". The available
parameters are: "proto=<PROTO>", "tls",
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
"affinity=<METHOD>". The parameter consists of keyword,
and optionally followed by "=" and value. For example,
the parameter "proto=h2" consists of the keyword "proto"
and value "h2". The parameter "tls" consists of the
keyword "tls" without value. Each parameter is
described as follows.
.sp
Optionally, TLS can be enabled by specifying "tls"
keyword. TLS is not enabled by default.
The backend application protocol can be specified using
optional "proto" parameter, and in the form of
"proto=<PROTO>". <PROTO> should be one of the following
list without quotes: "h2", "http/1.1". The default
value of <PROTO> is "http/1.1". Note that usually "h2"
refers to HTTP/2 over TLS. But in this option, it may
mean HTTP/2 over cleartext TCP unless "tls" keyword is
used (see below).
.sp
TLS can be enabled by specifying optional "tls"
parameter. TLS is not enabled by default.
.sp
With "sni=<SNI_HOST>" parameter, it can override the TLS
SNI field value with given <SNI_HOST>. This will
default to the backend <HOST> name
.sp
The feature to detect whether backend is online or
offline can be enabled using optional "fall" and "rise"
parameters. Using "fall=<N>" parameter, if nghttpx
cannot connect to a this backend <N> times in a row,
this backend is assumed to be offline, and it is
excluded from load balancing. If <N> is 0, this backend
never be excluded from load balancing whatever times
nghttpx cannot connect to it, and this is the default.
There is also "rise=<N>" parameter. After backend was
excluded from load balancing group, nghttpx periodically
attempts to make a connection to the failed backend, and
if the connection is made successfully <N> times in a
row, the backend is assumed to be online, and it is now
eligible for load balancing target. If <N> is 0, a
backend is permanently offline, once it goes in that
state, and this is the default behaviour.
.sp
The session affinity is enabled using
"affinity=<METHOD>" parameter. If "ip" is given in
<METHOD>, client IP based session affinity is enabled.
If "none" is given in <METHOD>, session affinity is
disabled, and this is the default. The session affinity
is enabled per <PATTERN>. If at least one backend has
"affinity" parameter, and its <METHOD> is not "none",
session affinity is enabled for all backend servers
sharing the same <PATTERN>. It is advised to set
"affinity" parameter to all backend explicitly if
session affinity is desired. The session affinity may
break if one of the backend gets unreachable, or backend
settings are reloaded or replaced by API.
.sp
Since ";" and ":" are used as delimiter, <PATTERN> must
not contain these characters. Since ";" has special
@@ -137,7 +183,7 @@ Default: \fB127.0.0.1,80\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[;no\-tls]
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
Set frontend host and port. If <HOST> is \(aq*\(aq, it
assumes all addresses including both IPv4 and IPv6.
UNIX domain socket can be specified by prefixing path
@@ -145,8 +191,24 @@ name with "unix:" (e.g., unix:/var/run/nghttpx.sock).
This option can be used multiple times to listen to
multiple addresses.
.sp
This option can take 0 or more parameters, which are
described below. Note that "api" and "healthmon"
parameters are mutually exclusive.
.sp
Optionally, TLS can be disabled by specifying "no\-tls"
keyword. TLS is enabled by default.
parameter. TLS is enabled by default.
.sp
To make this frontend as API endpoint, specify "api"
parameter. This is disabled by default. It is
important to limit the access to the API frontend.
Otherwise, someone may change the backend server, and
break your services, or expose confidential information
to the outside the world.
.sp
To make this frontend as health monitor endpoint,
specify "healthmon" parameter. This is disabled by
default. Any requests which come through this address
are replied with 200 HTTP status, without no body.
.sp
Default: \fB*,3000\fP
.UNINDENT
@@ -332,6 +394,13 @@ value is 0 then fast open is disabled.
.sp
Default: \fB0\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-kqueue
Don\(aqt use kqueue. This option is only applicable for
the platforms which have kqueue. For other platforms,
this option will be simply ignored.
.UNINDENT
.SS Timeout
.INDENT 0.0
.TP
@@ -387,6 +456,14 @@ Default: \fB30s\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-connect\-timeout=<DURATION>
Specify timeout before establishing TCP connection to
backend.
.sp
Default: \fB30s\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-keep\-alive\-timeout=<DURATION>
Specify keep\-alive timeout for backend connection.
.sp
@@ -401,6 +478,36 @@ disables this feature.
.sp
Default: \fB30s\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-setting\-timeout=<DURATION>
Specify timeout before SETTINGS ACK is received from
client.
.sp
Default: \fB10s\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-settings\-timeout=<DURATION>
Specify timeout before SETTINGS ACK is received from
backend server.
.sp
Default: \fB10s\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-max\-backoff=<DURATION>
Specify maximum backoff interval. This is used when
doing health check against offline backend (see "fail"
parameter in \fI\%\-\-backend\fP option). It is also used to
limit the maximum interval to temporarily disable
backend when nghttpx failed to connect to it. These
intervals are calculated using exponential backoff, and
consecutive failed attempts increase the interval. This
option caps its maximum value.
.sp
Default: \fB2m\fP
.UNINDENT
.SS SSL/TLS
.INDENT 0.0
.TP
@@ -410,6 +517,17 @@ described in OpenSSL ciphers(1).
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ecdh\-curves=<LIST>
Set supported curve list for frontend connections.
<LIST> is a colon separated list of curve NID or names
in the preference order. The supported curves depend on
the linked OpenSSL library. This function requires
OpenSSL >= 1.0.2.
.sp
Default: \fBP\-256:P\-384:P\-521\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-k, \-\-insecure
Don\(aqt verify backend server\(aqs certificate if TLS is
enabled for backend connections.
@@ -432,18 +550,21 @@ password protected it\(aqll be requested interactively.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-subcert=<KEYPATH>:<CERTPATH>
.B \-\-subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. This
option can be used multiple times. To make OCSP
stapling work, <CERTPATH> must be absolute path.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-tls\-sni\-field=<HOST>
Explicitly set the content of the TLS SNI extension.
This will default to the backend HOST name.
.sp
Additional parameter can be specified in <PARAM>. The
available <PARAM> is "sct\-dir=<DIR>".
.sp
"sct\-dir=<DIR>" specifies the path to directory which
contains *.sct files for TLS
signed_certificate_timestamp extension (RFC 6962). This
feature requires OpenSSL >= 1.0.2. See also
\fI\%\-\-tls\-sct\-dir\fP option.
.UNINDENT
.INDENT 0.0
.TP
@@ -542,7 +663,7 @@ ticket key generator to rotate keys frequently. See
"TLS SESSION TICKET RESUMPTION" section in manual page
to know the data format in memcached entry. Optionally,
memcached connection can be encrypted with TLS by
specifying "tls" keyword.
specifying "tls" parameter.
.UNINDENT
.INDENT 0.0
.TP
@@ -628,7 +749,7 @@ Specify address of memcached server to store session
cache. This enables shared session cache between
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying "tls"
keyword.
parameter.
.UNINDENT
.INDENT 0.0
.TP
@@ -686,6 +807,18 @@ Allow black listed cipher suite on HTTP/2 connection.
See \fI\%https://tools.ietf.org/html/rfc7540#appendix\-A\fP for
the complete HTTP/2 cipher suites black list.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-sct\-dir=<DIR>
Specifies the directory where *.sct files exist. All
*.sct files in <DIR> are read, and sent as
extension_data of TLS signed_certificate_timestamp (RFC
6962) to client. These *.sct files are for the
certificate specified in positional command\-line
argument <CERT>, or certificate option in configuration
file. For additional certificates, use \fI\%\-\-subcert\fP
option. This option requires OpenSSL >= 1.0.2.
.UNINDENT
.SS HTTP/2 and SPDY
.INDENT 0.0
.TP
@@ -707,37 +840,36 @@ Default: \fB100\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-window\-bits=<N>
Sets the per\-stream initial window size of HTTP/2 SPDY
frontend connection. For HTTP/2, the size is 2**<N>\-1.
For SPDY, the size is 2**<N>.
.B \-\-frontend\-http2\-window\-size=<SIZE>
Sets the per\-stream initial window size of HTTP/2 and
SPDY frontend connection.
.sp
Default: \fB16\fP
Default: \fB65535\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-connection\-window\-bits=<N>
.B \-\-frontend\-http2\-connection\-window\-size=<SIZE>
Sets the per\-connection window size of HTTP/2 and SPDY
frontend connection. For HTTP/2, the size is
2**<N>\-1. For SPDY, the size is 2**<N>.
frontend connection. For SPDY connection, the value
less than 64KiB is rounded up to 64KiB.
.sp
Default: \fB16\fP
Default: \fB65535\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-window\-bits=<N>
.B \-\-backend\-http2\-window\-size=<SIZE>
Sets the initial window size of HTTP/2 backend
connection to 2**<N>\-1.
connection.
.sp
Default: \fB16\fP
Default: \fB65535\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-connection\-window\-bits=<N>
.B \-\-backend\-http2\-connection\-window\-size=<SIZE>
Sets the per\-connection window size of HTTP/2 backend
connection to 2**<N>\-1.
connection.
.sp
Default: \fB30\fP
Default: \fB2147483647\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -763,13 +895,78 @@ backend session is relayed to frontend, and server push
via Link header field is also supported. SPDY frontend
does not support server push.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-optimize\-write\-buffer\-size
(Experimental) Enable write buffer size optimization in
frontend HTTP/2 TLS connection. This optimization aims
to reduce write buffer size so that it only contains
bytes which can send immediately. This makes server
more responsive to prioritized HTTP/2 stream because the
buffering of lower priority stream is reduced. This
option is only effective on recent Linux platform.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-optimize\-window\-size
(Experimental) Automatically tune connection level
window size of frontend HTTP/2 TLS connection. If this
feature is enabled, connection window size starts with
the default window size, 65535 bytes. nghttpx
automatically adjusts connection window size based on
TCP receiving window size. The maximum window size is
capped by the value specified by
\fI\%\-\-frontend\-http2\-connection\-window\-size\fP\&. Since the
stream is subject to stream level window size, it should
be adjusted using \fI\%\-\-frontend\-http2\-window\-size\fP option as
well. This option is only effective on recent Linux
platform.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
Specify the maximum dynamic table size of HPACK encoder
in the frontend HTTP/2 connection. The decoder (client)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which client specified.
.sp
Default: \fB4K\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
Specify the maximum dynamic table size of HPACK decoder
in the frontend HTTP/2 connection.
.sp
Default: \fB4K\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-encoder\-dynamic\-table\-size=<SIZE>
Specify the maximum dynamic table size of HPACK encoder
in the backend HTTP/2 connection. The decoder (backend)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which backend specified.
.sp
Default: \fB4K\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-decoder\-dynamic\-table\-size=<SIZE>
Specify the maximum dynamic table size of HPACK decoder
in the backend HTTP/2 connection.
.sp
Default: \fB4K\fP
.UNINDENT
.SS Mode
.INDENT 0.0
.TP
.B (default mode)
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no\-tls"
keyword is used in \fI\%\-\-frontend\fP option, accept HTTP/2 and
HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
parameter is used in \fI\%\-\-frontend\fP option, accept HTTP/2
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
connection can be upgraded to HTTP/2 through HTTP
Upgrade.
.UNINDENT
@@ -845,6 +1042,12 @@ $ssl_session_id: session ID for SSL/TLS connection.
.IP \(bu 2
$ssl_session_reused: "r" if SSL/TLS session was
reused. Otherwise, "."
.IP \(bu 2
$backend_host: backend host used to fulfill the
request. "\-" if backend host is not available.
.IP \(bu 2
$backend_port: backend port used to fulfill the
request. "\-" if backend host is not available.
.UNINDENT
.sp
The variable can be enclosed by "{" and "}" for
@@ -1030,6 +1233,28 @@ originally generates HTTP error status code <CODE>.
HTTP status code. If error status code comes from
backend server, the custom error pages are not used.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-server\-name=<NAME>
Change server response header field value to <NAME>.
.sp
Default: \fBnghttpx nghttp2/1.16.0\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-server\-rewrite
Don\(aqt rewrite server header field in default mode. When
\fI\%\-\-http2\-proxy\fP is used, these headers will not be altered
regardless of this option.
.UNINDENT
.SS API
.INDENT 0.0
.TP
.B \-\-api\-max\-request\-body=<SIZE>
Set the maximum size of request body for API request.
.sp
Default: \fB16K\fP
.UNINDENT
.SS Debug
.INDENT 0.0
.TP
@@ -1177,6 +1402,9 @@ Shutdown gracefully. First accept pending connections and stop
accepting connection. After all connections are handled, nghttpx
exits.
.TP
.B SIGHUP
Reload configuration file given in \fI\%\-\-conf\fP\&.
.TP
.B SIGUSR1
Reopen log files.
.TP
@@ -1184,7 +1412,11 @@ Reopen log files.
Fork and execute nghttpx. It will execute the binary in the same
path with same command\-line arguments and environment variables.
After new process comes up, sending SIGQUIT to the original process
to perform hot swapping.
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
and SIGHUP is that former is usually used to execute new binary, and
the master process is newly spawned. On the other hand, the latter
just reloads configuration file, and the same master process
continues to exist.
.UNINDENT
.sp
\fBNOTE:\fP
@@ -1333,6 +1565,19 @@ If \fI\%\-\-tls\-ticket\-key\-file\fP is given, encryption key is read
from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
SIGNALS).
.SH CERTIFICATE TRANSPARENCY
.sp
nghttpx supports TLS \fBsigned_certificate_timestamp\fP extension (\fI\%RFC
6962\fP). The relevant options
are \fI\%\-\-tls\-sct\-dir\fP and \fBsct\-dir\fP parameter in
\fI\%\-\-subcert\fP\&. They takes a directory, and nghttpx reads all
files whose extension is \fB\&.sct\fP under the directory. The \fB*.sct\fP
files are encoded as \fBSignedCertificateTimestamp\fP struct described
in \fI\%section 3.2 of RFC 69662\fP\&. This format is
the same one used by \fI\%nginx\-ct\fP and \fI\%mod_ssl_ct\fP\&.
\fI\%ct\-submit\fP can be
used to submit certificates to log servers, and obtain the
\fBSignedCertificateTimestamp\fP struct which can be used with nghttpx.
.SH MRUBY SCRIPTING
.sp
\fBWARNING:\fP
@@ -1402,7 +1647,32 @@ Return the current phase.
.INDENT 7.0
.TP
.B attribute [R] remote_addr
Return IP address of a remote client.
Return IP address of a remote client. If connection is made
via UNIX domain socket, this returns the string "localhost".
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] server_addr
Return address of server that accepted the connection. This
is a string which specified in \fI\%\-\-frontend\fP option,
excluding port number, and not a resolved IP address. For
UNIX domain socket, this is a path to UNIX domain socket.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] server_port
Return port number of the server frontend which accepted the
connection from client.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_used
Return true if TLS is used on the connection.
.UNINDENT
.INDENT 7.0
.TP
.B attribute [R] tls_sni
Return the TLS SNI value which client sent in this connection.
.UNINDENT
.UNINDENT
.INDENT 0.0
@@ -1445,7 +1715,13 @@ value is assigned.
.B attribute [R/W] path
Request path, including query component (i.e., /index.html).
On assignment, copy of given value is assigned. The path does
not include authority component of URI.
not include authority component of URI. This may include
query component. nghttpx makes certain normalization for
path. It decodes percent\-encoding for unreserved characters
(see \fI\%https://tools.ietf.org/html/rfc3986#section\-2.3\fP), and
resolves ".." and ".". But it may leave characters which
should be percent\-encoded as is. So be careful when comparing
path against desired string.
.UNINDENT
.INDENT 7.0
.TP
@@ -1478,7 +1754,7 @@ Clear all existing request header fields.
.UNINDENT
.INDENT 7.0
.TP
.B push uri
.B push(uri)
Initiate to push resource identified by \fIuri\fP\&. Only HTTP/2
protocol supports this feature. For the other protocols, this
method is noop. \fIuri\fP can be absolute URI, absolute path or
@@ -1608,9 +1884,64 @@ App.new
.fi
.UNINDENT
.UNINDENT
.SH API ENDPOINTS
.sp
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
default, API endpoint is disabled. To enable it, add a dedicated
frontend for API using \fI\%\-\-frontend\fP option with "api"
parameter. All requests which come from this frontend address, will
be treated as API request.
.sp
The response is normally JSON dictionary, and at least includes the
following keys:
.INDENT 0.0
.TP
.B status
The status of the request processing. The following values are
defined:
.INDENT 7.0
.TP
.B Success
The request was successful.
.TP
.B Failure
The request was failed. No change has been made.
.UNINDENT
.TP
.B code
HTTP status code
.UNINDENT
.sp
We wrote "normally", since nghttpx may return ordinal HTML response in
some cases where the error has occurred before reaching API endpoint
(e.g., header field is too large).
.sp
The following section describes available API endpoints.
.SS PUT /api/v1beta1/backendconfig
.sp
This API replaces the current backend server settings with the
requested ones. The request method should be PUT, but POST is also
acceptable. The request body must be nghttpx configuration file
format. For configuration file format, see \fI\%FILES\fP section. The
line separator inside the request body must be single LF (0x0A).
Currently, only \fI\%backend\fP option is parsed, the
others are simply ignored. The semantics of this API is replace the
current backend with the backend options in request body. Describe
the desired set of backend severs, and nghttpx makes it happen. If
there is no \fI\%backend\fP option is found in request
body, the current set of backend is replaced with the \fI\%backend\fP option\(aqs default value, which is \fB127.0.0.1,80\fP\&.
.sp
The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is
the case with hot swapping with signals.
.sp
The one limitation is that only numeric IP address is allowd in
\fI\%backend\fP in request body while non numeric
hostname is allowed in command\-line or configuration file is read
using \fI\%\-\-conf\fP\&.
.SH SEE ALSO
.sp
\fInghttp(1)\fP, \fInghttpd(1)\fP, \fIh2load(1)\fP
\fBnghttp(1)\fP, \fBnghttpd(1)\fP, \fBh2load(1)\fP
.SH AUTHOR
Tatsuhiro Tsujikawa
.SH COPYRIGHT

View File

@@ -20,13 +20,13 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.
Set path to server's private key. Required unless
"no-tls" keyword is used in :option:`--frontend` option.
"no-tls" parameter is used in :option:`--frontend` option.
.. describe:: <CERT>
Set path to server's certificate. Required unless
"no-tls" keyword is used in :option:`--frontend` option. To make
OCSP stapling work, this must be an absolute path.
"no-tls" parameter is used in :option:`--frontend` option. To
make OCSP stapling work, this must be an absolute path.
OPTIONS
@@ -37,7 +37,8 @@ The options are categorized into several groups.
Connections
~~~~~~~~~~~
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][;proto=<PROTO>][;tls]]
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;<PARAM>]...]
Set backend host and port. The multiple backend
addresses are accepted by repeating this option. UNIX
@@ -69,7 +70,7 @@ Connections
Host can include "\*" in the left most position to
indicate wildcard match (only suffix match is done).
The "*" must match at least one character. For example,
The "\*" must match at least one character. For example,
host pattern "\*.nghttp2.org" matches against
"www.nghttp2.org" and "git.ngttp2.org", but does not
match against "nghttp2.org". The exact hosts match
@@ -100,17 +101,63 @@ Connections
The backend addresses sharing same <PATTERN> are grouped
together forming load balancing group.
Optionally, backend application protocol can be
specified in <PROTO>. All that share the same <PATTERN>
must have the same <PROTO> value if it is given.
<PROTO> should be one of the following list without
quotes: "h2", "http/1.1". The default value of <PROTO>
is "http/1.1". Note that usually "h2" refers to HTTP/2
over TLS. But in this option, it may mean HTTP/2 over
cleartext TCP unless "tls" keyword is used (see below).
Several parameters <PARAM> are accepted after <PATTERN>.
The parameters are delimited by ";". The available
parameters are: "proto=<PROTO>", "tls",
"sni=<SNI_HOST>", "fall=<N>", "rise=<N>", and
"affinity=<METHOD>". The parameter consists of keyword,
and optionally followed by "=" and value. For example,
the parameter "proto=h2" consists of the keyword "proto"
and value "h2". The parameter "tls" consists of the
keyword "tls" without value. Each parameter is
described as follows.
Optionally, TLS can be enabled by specifying "tls"
keyword. TLS is not enabled by default.
The backend application protocol can be specified using
optional "proto" parameter, and in the form of
"proto=<PROTO>". <PROTO> should be one of the following
list without quotes: "h2", "http/1.1". The default
value of <PROTO> is "http/1.1". Note that usually "h2"
refers to HTTP/2 over TLS. But in this option, it may
mean HTTP/2 over cleartext TCP unless "tls" keyword is
used (see below).
TLS can be enabled by specifying optional "tls"
parameter. TLS is not enabled by default.
With "sni=<SNI_HOST>" parameter, it can override the TLS
SNI field value with given <SNI_HOST>. This will
default to the backend <HOST> name
The feature to detect whether backend is online or
offline can be enabled using optional "fall" and "rise"
parameters. Using "fall=<N>" parameter, if nghttpx
cannot connect to a this backend <N> times in a row,
this backend is assumed to be offline, and it is
excluded from load balancing. If <N> is 0, this backend
never be excluded from load balancing whatever times
nghttpx cannot connect to it, and this is the default.
There is also "rise=<N>" parameter. After backend was
excluded from load balancing group, nghttpx periodically
attempts to make a connection to the failed backend, and
if the connection is made successfully <N> times in a
row, the backend is assumed to be online, and it is now
eligible for load balancing target. If <N> is 0, a
backend is permanently offline, once it goes in that
state, and this is the default behaviour.
The session affinity is enabled using
"affinity=<METHOD>" parameter. If "ip" is given in
<METHOD>, client IP based session affinity is enabled.
If "none" is given in <METHOD>, session affinity is
disabled, and this is the default. The session affinity
is enabled per <PATTERN>. If at least one backend has
"affinity" parameter, and its <METHOD> is not "none",
session affinity is enabled for all backend servers
sharing the same <PATTERN>. It is advised to set
"affinity" parameter to all backend explicitly if
session affinity is desired. The session affinity may
break if one of the backend gets unreachable, or backend
settings are reloaded or replaced by API.
Since ";" and ":" are used as delimiter, <PATTERN> must
not contain these characters. Since ";" has special
@@ -119,7 +166,7 @@ Connections
Default: ``127.0.0.1,80``
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[;no-tls]
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[[;<PARAM>]...]
Set frontend host and port. If <HOST> is '\*', it
assumes all addresses including both IPv4 and IPv6.
@@ -128,8 +175,24 @@ Connections
This option can be used multiple times to listen to
multiple addresses.
This option can take 0 or more parameters, which are
described below. Note that "api" and "healthmon"
parameters are mutually exclusive.
Optionally, TLS can be disabled by specifying "no-tls"
keyword. TLS is enabled by default.
parameter. TLS is enabled by default.
To make this frontend as API endpoint, specify "api"
parameter. This is disabled by default. It is
important to limit the access to the API frontend.
Otherwise, someone may change the backend server, and
break your services, or expose confidential information
to the outside the world.
To make this frontend as health monitor endpoint,
specify "healthmon" parameter. This is disabled by
default. Any requests which come through this address
are replied with 200 HTTP status, without no body.
Default: ``*,3000``
@@ -299,6 +362,13 @@ Performance
Default: ``0``
.. option:: --no-kqueue
Don't use kqueue. This option is only applicable for
the platforms which have kqueue. For other platforms,
this option will be simply ignored.
Timeout
~~~~~~~
@@ -347,6 +417,13 @@ Timeout
Default: ``30s``
.. option:: --backend-connect-timeout=<DURATION>
Specify timeout before establishing TCP connection to
backend.
Default: ``30s``
.. option:: --backend-keep-alive-timeout=<DURATION>
Specify keep-alive timeout for backend connection.
@@ -361,6 +438,33 @@ Timeout
Default: ``30s``
.. option:: --frontend-http2-setting-timeout=<DURATION>
Specify timeout before SETTINGS ACK is received from
client.
Default: ``10s``
.. option:: --backend-http2-settings-timeout=<DURATION>
Specify timeout before SETTINGS ACK is received from
backend server.
Default: ``10s``
.. option:: --backend-max-backoff=<DURATION>
Specify maximum backoff interval. This is used when
doing health check against offline backend (see "fail"
parameter in :option:`--backend` option). It is also used to
limit the maximum interval to temporarily disable
backend when nghttpx failed to connect to it. These
intervals are calculated using exponential backoff, and
consecutive failed attempts increase the interval. This
option caps its maximum value.
Default: ``2m``
SSL/TLS
~~~~~~~
@@ -370,6 +474,16 @@ SSL/TLS
Set allowed cipher list. The format of the string is
described in OpenSSL ciphers(1).
.. option:: --ecdh-curves=<LIST>
Set supported curve list for frontend connections.
<LIST> is a colon separated list of curve NID or names
in the preference order. The supported curves depend on
the linked OpenSSL library. This function requires
OpenSSL >= 1.0.2.
Default: ``P-256:P-384:P-521``
.. option:: -k, --insecure
Don't verify backend server's certificate if TLS is
@@ -389,7 +503,7 @@ SSL/TLS
private key. If none is given and the private key is
password protected it'll be requested interactively.
.. option:: --subcert=<KEYPATH>:<CERTPATH>
.. option:: --subcert=<KEYPATH>:<CERTPATH>[[;<PARAM>]...]
Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname
@@ -397,10 +511,14 @@ SSL/TLS
option can be used multiple times. To make OCSP
stapling work, <CERTPATH> must be absolute path.
.. option:: --backend-tls-sni-field=<HOST>
Additional parameter can be specified in <PARAM>. The
available <PARAM> is "sct-dir=<DIR>".
Explicitly set the content of the TLS SNI extension.
This will default to the backend HOST name.
"sct-dir=<DIR>" specifies the path to directory which
contains \*.sct files for TLS
signed_certificate_timestamp extension (RFC 6962). This
feature requires OpenSSL >= 1.0.2. See also
:option:`--tls-sct-dir` option.
.. option:: --dh-param-file=<PATH>
@@ -490,7 +608,7 @@ SSL/TLS
"TLS SESSION TICKET RESUMPTION" section in manual page
to know the data format in memcached entry. Optionally,
memcached connection can be encrypted with TLS by
specifying "tls" keyword.
specifying "tls" parameter.
.. option:: --tls-ticket-key-memcached-address-family=(auto|IPv4|IPv6)
@@ -565,7 +683,7 @@ SSL/TLS
cache. This enables shared session cache between
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying "tls"
keyword.
parameter.
.. option:: --tls-session-cache-memcached-address-family=(auto|IPv4|IPv6)
@@ -617,6 +735,17 @@ SSL/TLS
See https://tools.ietf.org/html/rfc7540#appendix-A for
the complete HTTP/2 cipher suites black list.
.. option:: --tls-sct-dir=<DIR>
Specifies the directory where \*.sct files exist. All
\*.sct files in <DIR> are read, and sent as
extension_data of TLS signed_certificate_timestamp (RFC
6962) to client. These \*.sct files are for the
certificate specified in positional command-line
argument <CERT>, or certificate option in configuration
file. For additional certificates, use :option:`--subcert`
option. This option requires OpenSSL >= 1.0.2.
HTTP/2 and SPDY
~~~~~~~~~~~~~~~
@@ -637,35 +766,34 @@ HTTP/2 and SPDY
Default: ``100``
.. option:: --frontend-http2-window-bits=<N>
.. option:: --frontend-http2-window-size=<SIZE>
Sets the per-stream initial window size of HTTP/2 SPDY
frontend connection. For HTTP/2, the size is 2\*\*<N>-1.
For SPDY, the size is 2\*\*<N>.
Sets the per-stream initial window size of HTTP/2 and
SPDY frontend connection.
Default: ``16``
Default: ``65535``
.. option:: --frontend-http2-connection-window-bits=<N>
.. option:: --frontend-http2-connection-window-size=<SIZE>
Sets the per-connection window size of HTTP/2 and SPDY
frontend connection. For HTTP/2, the size is
2**<N>-1. For SPDY, the size is 2\*\*<N>.
frontend connection. For SPDY connection, the value
less than 64KiB is rounded up to 64KiB.
Default: ``16``
Default: ``65535``
.. option:: --backend-http2-window-bits=<N>
.. option:: --backend-http2-window-size=<SIZE>
Sets the initial window size of HTTP/2 backend
connection to 2\*\*<N>-1.
connection.
Default: ``16``
Default: ``65535``
.. option:: --backend-http2-connection-window-bits=<N>
.. option:: --backend-http2-connection-window-size=<SIZE>
Sets the per-connection window size of HTTP/2 backend
connection to 2\*\*<N>-1.
connection.
Default: ``30``
Default: ``2147483647``
.. option:: --http2-no-cookie-crumbling
@@ -688,6 +816,65 @@ HTTP/2 and SPDY
via Link header field is also supported. SPDY frontend
does not support server push.
.. option:: --frontend-http2-optimize-write-buffer-size
(Experimental) Enable write buffer size optimization in
frontend HTTP/2 TLS connection. This optimization aims
to reduce write buffer size so that it only contains
bytes which can send immediately. This makes server
more responsive to prioritized HTTP/2 stream because the
buffering of lower priority stream is reduced. This
option is only effective on recent Linux platform.
.. option:: --frontend-http2-optimize-window-size
(Experimental) Automatically tune connection level
window size of frontend HTTP/2 TLS connection. If this
feature is enabled, connection window size starts with
the default window size, 65535 bytes. nghttpx
automatically adjusts connection window size based on
TCP receiving window size. The maximum window size is
capped by the value specified by
:option:`--frontend-http2-connection-window-size`\. Since the
stream is subject to stream level window size, it should
be adjusted using :option:`--frontend-http2-window-size` option as
well. This option is only effective on recent Linux
platform.
.. option:: --frontend-http2-encoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK encoder
in the frontend HTTP/2 connection. The decoder (client)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which client specified.
Default: ``4K``
.. option:: --frontend-http2-decoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK decoder
in the frontend HTTP/2 connection.
Default: ``4K``
.. option:: --backend-http2-encoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK encoder
in the backend HTTP/2 connection. The decoder (backend)
specifies the maximum dynamic table size it accepts.
Then the negotiated dynamic table size is the minimum of
this option value and the value which backend specified.
Default: ``4K``
.. option:: --backend-http2-decoder-dynamic-table-size=<SIZE>
Specify the maximum dynamic table size of HPACK decoder
in the backend HTTP/2 connection.
Default: ``4K``
Mode
~~~~
@@ -696,8 +883,8 @@ Mode
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no-tls"
keyword is used in :option:`--frontend` option, accept HTTP/2 and
HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
parameter is used in :option:`--frontend` option, accept HTTP/2
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
connection can be upgraded to HTTP/2 through HTTP
Upgrade.
@@ -755,6 +942,10 @@ Logging
* $ssl_session_id: session ID for SSL/TLS connection.
* $ssl_session_reused: "r" if SSL/TLS session was
reused. Otherwise, "."
* $backend_host: backend host used to fulfill the
request. "-" if backend host is not available.
* $backend_port: backend port used to fulfill the
request. "-" if backend host is not available.
The variable can be enclosed by "{" and "}" for
disambiguation (e.g., ${remote_addr}).
@@ -919,10 +1110,32 @@ HTTP
Set file path to custom error page served when nghttpx
originally generates HTTP error status code <CODE>.
<CODE> must be greater than or equal to 400, and at most
599. If "*" is used instead of <CODE>, it matches all
599. If "\*" is used instead of <CODE>, it matches all
HTTP status code. If error status code comes from
backend server, the custom error pages are not used.
.. option:: --server-name=<NAME>
Change server response header field value to <NAME>.
Default: ``nghttpx nghttp2/1.16.0``
.. option:: --no-server-rewrite
Don't rewrite server header field in default mode. When
:option:`--http2-proxy` is used, these headers will not be altered
regardless of this option.
API
~~~
.. option:: --api-max-request-body=<SIZE>
Set the maximum size of request body for API request.
Default: ``16K``
Debug
~~~~~
@@ -1061,6 +1274,9 @@ SIGQUIT
accepting connection. After all connections are handled, nghttpx
exits.
SIGHUP
Reload configuration file given in :option:`--conf`.
SIGUSR1
Reopen log files.
@@ -1068,7 +1284,11 @@ SIGUSR2
Fork and execute nghttpx. It will execute the binary in the same
path with same command-line arguments and environment variables.
After new process comes up, sending SIGQUIT to the original process
to perform hot swapping.
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
and SIGHUP is that former is usually used to execute new binary, and
the master process is newly spawned. On the other hand, the latter
just reloads configuration file, and the same master process
continues to exist.
.. note::
@@ -1097,7 +1317,7 @@ backend server and extracts URI-reference with parameter
and pushes those URIs to the frontend client. Here is a sample Link
header field to initiate server push:
.. code-block:: http
.. code-block:: text
Link: </fonts/font.woff>; rel=preload
Link: </css/theme.css>; rel=preload
@@ -1214,6 +1434,24 @@ from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
SIGNALS).
CERTIFICATE TRANSPARENCY
------------------------
nghttpx supports TLS ``signed_certificate_timestamp`` extension (`RFC
6962 <https://tools.ietf.org/html/rfc6962>`_). The relevant options
are :option:`--tls-sct-dir` and ``sct-dir`` parameter in
:option:`--subcert`. They takes a directory, and nghttpx reads all
files whose extension is ``.sct`` under the directory. The ``*.sct``
files are encoded as ``SignedCertificateTimestamp`` struct described
in `section 3.2 of RFC 69662
<https://tools.ietf.org/html/rfc6962#section-3.2>`_. This format is
the same one used by `nginx-ct
<https://github.com/grahamedgecombe/nginx-ct>`_ and `mod_ssl_ct
<https://httpd.apache.org/docs/trunk/mod/mod_ssl_ct.html>`_.
`ct-submit <https://github.com/grahamedgecombe/ct-submit>`_ can be
used to submit certificates to log servers, and obtain the
``SignedCertificateTimestamp`` struct which can be used with nghttpx.
MRUBY SCRIPTING
---------------
@@ -1277,7 +1515,28 @@ respectively.
.. rb:attr_reader:: remote_addr
Return IP address of a remote client.
Return IP address of a remote client. If connection is made
via UNIX domain socket, this returns the string "localhost".
.. rb:attr_reader:: server_addr
Return address of server that accepted the connection. This
is a string which specified in :option:`--frontend` option,
excluding port number, and not a resolved IP address. For
UNIX domain socket, this is a path to UNIX domain socket.
.. rb:attr_reader:: server_port
Return port number of the server frontend which accepted the
connection from client.
.. rb:attr_reader:: tls_used
Return true if TLS is used on the connection.
.. rb:attr_reader:: tls_sni
Return the TLS SNI value which client sent in this connection.
.. rb:class:: Request
@@ -1313,7 +1572,13 @@ respectively.
Request path, including query component (i.e., /index.html).
On assignment, copy of given value is assigned. The path does
not include authority component of URI.
not include authority component of URI. This may include
query component. nghttpx makes certain normalization for
path. It decodes percent-encoding for unreserved characters
(see https://tools.ietf.org/html/rfc3986#section-2.3), and
resolves ".." and ".". But it may leave characters which
should be percent-encoded as is. So be careful when comparing
path against desired string.
.. rb:attr_reader:: headers
@@ -1340,7 +1605,7 @@ respectively.
Clear all existing request header fields.
.. rb:method:: push uri
.. rb:method:: push(uri)
Initiate to push resource identified by *uri*. Only HTTP/2
protocol supports this feature. For the other protocols, this
@@ -1451,6 +1716,62 @@ addresses:
App.new
API ENDPOINTS
-------------
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
default, API endpoint is disabled. To enable it, add a dedicated
frontend for API using :option:`--frontend` option with "api"
parameter. All requests which come from this frontend address, will
be treated as API request.
The response is normally JSON dictionary, and at least includes the
following keys:
status
The status of the request processing. The following values are
defined:
Success
The request was successful.
Failure
The request was failed. No change has been made.
code
HTTP status code
We wrote "normally", since nghttpx may return ordinal HTML response in
some cases where the error has occurred before reaching API endpoint
(e.g., header field is too large).
The following section describes available API endpoints.
PUT /api/v1beta1/backendconfig
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This API replaces the current backend server settings with the
requested ones. The request method should be PUT, but POST is also
acceptable. The request body must be nghttpx configuration file
format. For configuration file format, see `FILES`_ section. The
line separator inside the request body must be single LF (0x0A).
Currently, only :option:`backend <--backend>` option is parsed, the
others are simply ignored. The semantics of this API is replace the
current backend with the backend options in request body. Describe
the desired set of backend severs, and nghttpx makes it happen. If
there is no :option:`backend <--backend>` option is found in request
body, the current set of backend is replaced with the :option:`backend
<--backend>` option's default value, which is ``127.0.0.1,80``.
The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is
the case with hot swapping with signals.
The one limitation is that only numeric IP address is allowd in
:option:`backend <--backend>` in request body while non numeric
hostname is allowed in command-line or configuration file is read
using :option:`--conf`.
SEE ALSO
--------

View File

@@ -49,6 +49,9 @@ SIGQUIT
accepting connection. After all connections are handled, nghttpx
exits.
SIGHUP
Reload configuration file given in :option:`--conf`.
SIGUSR1
Reopen log files.
@@ -56,7 +59,11 @@ SIGUSR2
Fork and execute nghttpx. It will execute the binary in the same
path with same command-line arguments and environment variables.
After new process comes up, sending SIGQUIT to the original process
to perform hot swapping.
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
and SIGHUP is that former is usually used to execute new binary, and
the master process is newly spawned. On the other hand, the latter
just reloads configuration file, and the same master process
continues to exist.
.. note::
@@ -85,7 +92,7 @@ backend server and extracts URI-reference with parameter
and pushes those URIs to the frontend client. Here is a sample Link
header field to initiate server push:
.. code-block:: http
.. code-block:: text
Link: </fonts/font.woff>; rel=preload
Link: </css/theme.css>; rel=preload
@@ -202,6 +209,24 @@ from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
SIGNALS).
CERTIFICATE TRANSPARENCY
------------------------
nghttpx supports TLS ``signed_certificate_timestamp`` extension (`RFC
6962 <https://tools.ietf.org/html/rfc6962>`_). The relevant options
are :option:`--tls-sct-dir` and ``sct-dir`` parameter in
:option:`--subcert`. They takes a directory, and nghttpx reads all
files whose extension is ``.sct`` under the directory. The ``*.sct``
files are encoded as ``SignedCertificateTimestamp`` struct described
in `section 3.2 of RFC 69662
<https://tools.ietf.org/html/rfc6962#section-3.2>`_. This format is
the same one used by `nginx-ct
<https://github.com/grahamedgecombe/nginx-ct>`_ and `mod_ssl_ct
<https://httpd.apache.org/docs/trunk/mod/mod_ssl_ct.html>`_.
`ct-submit <https://github.com/grahamedgecombe/ct-submit>`_ can be
used to submit certificates to log servers, and obtain the
``SignedCertificateTimestamp`` struct which can be used with nghttpx.
MRUBY SCRIPTING
---------------
@@ -265,7 +290,28 @@ respectively.
.. rb:attr_reader:: remote_addr
Return IP address of a remote client.
Return IP address of a remote client. If connection is made
via UNIX domain socket, this returns the string "localhost".
.. rb:attr_reader:: server_addr
Return address of server that accepted the connection. This
is a string which specified in :option:`--frontend` option,
excluding port number, and not a resolved IP address. For
UNIX domain socket, this is a path to UNIX domain socket.
.. rb:attr_reader:: server_port
Return port number of the server frontend which accepted the
connection from client.
.. rb:attr_reader:: tls_used
Return true if TLS is used on the connection.
.. rb:attr_reader:: tls_sni
Return the TLS SNI value which client sent in this connection.
.. rb:class:: Request
@@ -301,7 +347,13 @@ respectively.
Request path, including query component (i.e., /index.html).
On assignment, copy of given value is assigned. The path does
not include authority component of URI.
not include authority component of URI. This may include
query component. nghttpx makes certain normalization for
path. It decodes percent-encoding for unreserved characters
(see https://tools.ietf.org/html/rfc3986#section-2.3), and
resolves ".." and ".". But it may leave characters which
should be percent-encoded as is. So be careful when comparing
path against desired string.
.. rb:attr_reader:: headers
@@ -328,7 +380,7 @@ respectively.
Clear all existing request header fields.
.. rb:method:: push uri
.. rb:method:: push(uri)
Initiate to push resource identified by *uri*. Only HTTP/2
protocol supports this feature. For the other protocols, this
@@ -439,6 +491,62 @@ addresses:
App.new
API ENDPOINTS
-------------
nghttpx exposes API endpoints to manipulate it via HTTP based API. By
default, API endpoint is disabled. To enable it, add a dedicated
frontend for API using :option:`--frontend` option with "api"
parameter. All requests which come from this frontend address, will
be treated as API request.
The response is normally JSON dictionary, and at least includes the
following keys:
status
The status of the request processing. The following values are
defined:
Success
The request was successful.
Failure
The request was failed. No change has been made.
code
HTTP status code
We wrote "normally", since nghttpx may return ordinal HTML response in
some cases where the error has occurred before reaching API endpoint
(e.g., header field is too large).
The following section describes available API endpoints.
PUT /api/v1beta1/backendconfig
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This API replaces the current backend server settings with the
requested ones. The request method should be PUT, but POST is also
acceptable. The request body must be nghttpx configuration file
format. For configuration file format, see `FILES`_ section. The
line separator inside the request body must be single LF (0x0A).
Currently, only :option:`backend <--backend>` option is parsed, the
others are simply ignored. The semantics of this API is replace the
current backend with the backend options in request body. Describe
the desired set of backend severs, and nghttpx makes it happen. If
there is no :option:`backend <--backend>` option is found in request
body, the current set of backend is replaced with the :option:`backend
<--backend>` option's default value, which is ``127.0.0.1,80``.
The replacement is done instantly without breaking existing
connections or requests. It also avoids any process creation as is
the case with hot swapping with signals.
The one limitation is that only numeric IP address is allowd in
:option:`backend <--backend>` in request body while non numeric
hostname is allowed in command-line or configuration file is read
using :option:`--conf`.
SEE ALSO
--------

View File

@@ -36,7 +36,7 @@ functions, and it also interacts with it via many API function calls.
An application can create as many :type:`nghttp2_session` object as it
wants. But single :type:`nghttp2_session` object must be used by a
single thread at the same time. This is not so hard to enforce since
most event-based architecture applicatons use is single thread per
most event-based architecture applications use is single thread per
core, and handling one connection I/O is done by single thread.
To feed input to :type:`nghttp2_session` object, one can use
@@ -177,12 +177,64 @@ Any deviation results in stream error of type PROTOCOL_ERROR. If
error is found in PUSH_PROMISE frame, stream error is raised against
promised stream.
Implement HTTP/2 non-critical extensions
----------------------------------------
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 HTTP/2 non-critical
extension frames.
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
@@ -383,3 +435,41 @@ its creation:
.. code-block:: c
nghttp2_session_client_new2(&session, callbacks, user_data, option);
How to use built-in HTTP/2 extension frame handlers
---------------------------------------------------
In the previous section, we talked about the user defined HTTP/2
extension frames. In this section, we talk about HTTP/2 extension
frame support built into nghttp2 library.
As of this writing, nghttp2 supports ALTSVC extension frame. To send
ALTSVC frame, use `nghttp2_submit_altsvc()` function.
To receive ALTSVC frame through built-in functionality, application
has to use `nghttp2_option_set_builtin_recv_extension_type()` to
indicate the willingness of receiving ALTSVC frame:
.. code-block:: c
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
This is very similar to the case when we used to receive user defined
frames.
If the same frame type is set using
`nghttp2_option_set_builtin_recv_extension_type()` and
`nghttp2_option_set_user_recv_extension_type()`, the latter takes
precedence. Application can implement its own frame handler rather
than using built-in handler.
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
its creation, like so:
.. code-block:: c
nghttp2_session_client_new2(&session, callbacks, user_data, option);
When ALTSVC is received, :type:`nghttp2_on_frame_recv_callback` will
be called as usual.

View File

@@ -17,19 +17,16 @@ installed in the following way. First, let us introduce
under ``$ANDROID_HOME/toolchain``. An user can freely choose the path
for ``ANDROID_HOME``. For example, to install toolchain under
``$ANDROID_HOME/toolchain``, do this in the the directory where NDK is
unpacked::
unpacked:
$ build/tools/make-standalone-toolchain.sh \
--install-dir=$ANDROID_HOME/toolchain \
--toolchain=arm-linux-androideabi-4.9 \
--llvm-version=3.5 \
--platform=android-16
.. code-block:: text
The additional flag ``--system=linux-x86_64`` may be required if you
are using x86_64 system.
$ build/tools/make_standalone_toolchain.py \
--arch arm --api 16 --stl gnustl
--install-dir $ANDROID_HOME/toolchain
The platform level is not important here because we don't use Android
specific C/C++ API.
The API level (``--api``) is not important here because we don't use
Android specific C/C++ API.
The dependent libraries, such as OpenSSL and libev should be built
with the toolchain and installed under ``$ANDROID_HOME/usr/local``.
@@ -45,7 +42,9 @@ spdylay as well.
Before running ``android-config`` and ``android-make``,
``ANDROID_HOME`` environment variable must be set to point to the
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``::
correct path. Also add ``$ANDROID_HOME/toolchain/bin`` to ``PATH``:
.. code-block:: text
$ export PATH=$PATH:$ANDROID_HOME/toolchain/bin
@@ -133,24 +132,24 @@ To configure spdylay, use the following script:
#!/bin/sh -e
if [ -z "$ANDROID_HOME" ]; then
echo 'No $ANDROID_HOME specified.'
exit 1
echo 'No $ANDROID_HOME specified.'
exit 1
fi
PREFIX=$ANDROID_HOME/usr/local
TOOLCHAIN=$ANDROID_HOME/toolchain
PATH=$TOOLCHAIN/bin:$PATH
./configure \
--disable-shared \
--host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
--without-libxml2 \
--disable-src \
--disable-examples \
CPPFLAGS="-I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-L$PREFIX/lib"
--disable-shared \
--host=arm-linux-androideabi \
--build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
--prefix=$PREFIX \
--without-libxml2 \
--disable-src \
--disable-examples \
CPPFLAGS="-I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-L$PREFIX/lib"
And run ``make install`` to build and install.
@@ -159,6 +158,8 @@ then ``android-make`` to compile nghttp2 source files.
If all went well, application binaries, such as nghttpx, are created
under src directory. Strip debugging information from the binary
using the following command::
using the following command:
.. code-block:: text
$ arm-linux-androideabi-strip src/nghttpx

View File

@@ -27,7 +27,7 @@ We use clang-format to format source code consistently. The
clang-format configuration file .clang-format is located at the root
directory. Since clang-format produces slightly different results
between versions, we currently use clang-format which comes with
clang-3.6.
clang-3.9.
To detect any violation to the coding style, we recommend to setup git
pre-commit hook to check coding style of the changes you introduced.
@@ -35,7 +35,7 @@ The pre-commit file is located at the root directory. Copy it under
.git/hooks and make sure that it is executable. The pre-commit script
uses clang-format-diff.py to detect any style errors. If it is not in
your PATH or it exists under different name (e.g.,
clang-format-diff-3.6 in debian), either add it to PATH variable or
clang-format-diff-3.9 in debian), either add it to PATH variable or
add git option ``clangformatdiff.binary`` to point to the script.
For emacs users, integrating clang-format to emacs is very easy.

View File

@@ -51,3 +51,4 @@ Resources
* HTTP/2 https://tools.ietf.org/html/rfc7540
* HPACK https://tools.ietf.org/html/rfc7541
* HTTP Alternative Services https://tools.ietf.org/html/rfc7838

View File

@@ -48,12 +48,16 @@ explicitly.
The backend is supposed to be Web server. For example, to make
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
backend Web server is configured to listen to HTTP request at port
8080 in the same host, run nghttpx command-line like this::
8080 in the same host, run nghttpx command-line like this:
.. code-block:: text
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
Then HTTP/2 enabled client can access to the nghttpx in HTTP/2. For
example, you can send GET request to the server using nghttp::
example, you can send GET request to the server using nghttp:
.. code-block:: text
$ nghttp -nv https://localhost:8443/
@@ -89,7 +93,9 @@ connection, use :option:`--backend` option, and specify ``h2`` in
For example, to make nghttpx listen to encrypted HTTP/2 requests at
port 8443, and a backend HTTP proxy server is configured to listen to
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
like this::
like this:
.. code-block:: text
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
@@ -118,13 +124,17 @@ to proxy.pac file, something like this:
file:///path/to/proxy.pac
For Chromium, use following command-line::
For Chromium, use following command-line:
.. code-block:: text
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
As HTTP/1 proxy server, Squid may work as out-of-box. Traffic server
requires to be configured as forward proxy. Here is the minimum
configuration items to edit::
configuration items to edit:
.. code-block:: text
CONFIG proxy.config.reverse_proxy.enabled INT 0
CONFIG proxy.config.url_remap.remap_required INT 0
@@ -134,6 +144,11 @@ Consult Traffic server `documentation
to know how to configure traffic server as forward proxy and its
security implications.
ALPN support
------------
ALPN support requires OpenSSL >= 1.0.2.
Disable frontend SSL/TLS
------------------------
@@ -152,9 +167,9 @@ Enable SSL/TLS on memcached connection
--------------------------------------
By default, memcached connection is not encrypted. To enable
encryption, use :option:`--tls-ticket-key-memcached-tls` for TLS
ticket key, and use :option:`--tls-session-cache-memcached-tls` for
TLS session cache.
encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
:option:`--tls-session-cache-memcached` for TLS session cache.
Specifying additional server certificates
-----------------------------------------
@@ -196,17 +211,17 @@ Rewriting location header field
nghttpx automatically rewrites location response header field if the
following all conditions satisfy:
* URI in location header field is not absolute URI or is not https URI.
* In the default mode (:option:`--http2-proxy` is not used)
* :option:`--no-location-rewrite` is not used
* URI in location header field is an absolute URI
* URI in location header field includes non empty host component.
* host (without port) in URI in location header field must match the
host appearing in :authority or host header field.
host appearing in ``:authority`` or ``host`` header field.
When rewrite happens, URI scheme and port are replaced with the ones
used in frontend, and host is replaced with which appears in
:authority or host request header field. :authority header field has
precedence. If the above conditions are not met with the host value
in :authority header field, rewrite is retried with the value in host
header field.
When rewrite happens, URI scheme is replaced with the ones used in
frontend, and authority is replaced with which appears in
``:authority``, or ``host`` request header field. ``:authority``
header field has precedence over ``host``.
Hot swapping
------------
@@ -221,6 +236,9 @@ all existing frontend connections are done, the current process will
exit. At this point, only new nghttpx process exists and serves
incoming requests.
If you want to just reload configuration file without executing new
binary, send SIGHUP to nghttpx master process.
Re-opening log files
--------------------
@@ -383,3 +401,12 @@ Use following options instead of ``--client-proxy``:
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.

View File

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

View File

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

View File

@@ -78,15 +78,16 @@ header data. To initialize the object, use
int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr);
To inflate header data, use `nghttp2_hd_inflate_hd()`::
To inflate header data, use `nghttp2_hd_inflate_hd2()`::
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
uint8_t *in, size_t inlen, int in_final);
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen,
int in_final);
`nghttp2_hd_inflate_hd()` reads a stream of bytes and outputs a single
header field at a time. Multiple calls are normally required to read a
full stream of bytes and output all of the header fields.
`nghttp2_hd_inflate_hd2()` reads a stream of bytes and outputs a
single header field at a time. Multiple calls are normally required to
read a full stream of bytes and output all of the header fields.
The *inflater* is the inflater object initialized above. The *nv_out*
is a pointer to a :type:`nghttp2_nv` into which one header field may
@@ -118,11 +119,7 @@ If *in_final* is zero and the :macro:`NGHTTP2_HD_INFLATE_EMIT` flag is
not set, it indicates that all given data was processed. The caller
is required to pass additional data.
It is important to note that the function may produce one or more
header fields even if *inlen* is 0 when *in_final* is nonzero, due to
differential encoding.
Example usage of `nghttp2_hd_inflate_hd()` is shown in the
Example usage of `nghttp2_hd_inflate_hd2()` is shown in the
`inflate_header_block()` function in `deflate.c`_.
Finally, to delete a :type:`nghttp2_hd_inflater` object, use

View File

@@ -10,7 +10,9 @@ archive or repository.
This simple server takes 3 arguments: The port number to listen on,
the path to your SSL/TLS private key file, and the path to your
certificate file. The synopsis is::
certificate file. The synopsis is:
.. code-block:: text
$ libevent-server PORT /path/to/server.key /path/to/server.crt
@@ -25,7 +27,17 @@ application protocols the server supports to a client. In this
example program, when creating the ``SSL_CTX`` object, we store the
application protocol name in the wire format of NPN in a statically
allocated buffer. This is safe because we only create one ``SSL_CTX``
object in the program's entire lifetime::
object in the program's entire lifetime.
If you are following TLS related RFC, you know that NPN is not the
standardized way to negotiate HTTP/2. NPN itself is not even
published as RFC. The standard way to negotiate HTTP/2 is ALPN,
Application-Layer Protocol Negotiation Extension, defined in `RFC 7301
<https://tools.ietf.org/html/rfc7301>`_. The one caveat of ALPN is
that OpenSSL >= 1.0.2 is required. We use macro to enable/disable
ALPN support depending on OpenSSL version. In ALPN, client sends the
list of supported application protocols, and server selects one of
them. We provide the callback for it::
static unsigned char next_proto_list[256];
static size_t next_proto_list_len;
@@ -37,6 +49,22 @@ object in the program's entire lifetime::
return SSL_TLSEXT_ERR_OK;
}
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg _U_) {
int rv;
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
if (rv != 1) {
return SSL_TLSEXT_ERR_NOACK;
}
return SSL_TLSEXT_ERR_OK;
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_CTX *ssl_ctx;
EC_KEY *ecdh;
@@ -51,6 +79,11 @@ object in the program's entire lifetime::
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
@@ -64,6 +97,11 @@ OpenSSL implementation, we just assign the pointer to the NPN buffers
we filled in earlier. The NPN callback function is set to the
``SSL_CTX`` object using ``SSL_CTX_set_next_protos_advertised_cb()``.
In ``alpn_select_proto_cb()``, we use `nghttp2_select_next_protocol()`
to select application protocol. The `nghttp2_select_next_protocol()`
returns 1 only if it selected h2 (ALPN identifier for HTTP/2), and out
parameters were assigned accordingly.
Next, let's take a look at the main structures used by the example
application:
@@ -167,11 +205,31 @@ underlying network socket::
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
http2_session_data *session_data = (http2_session_data *)ptr;
if (events & BEV_EVENT_CONNECTED) {
const unsigned char *alpn = NULL;
unsigned int alpnlen = 0;
SSL *ssl;
fprintf(stderr, "%s connected\n", session_data->client_addr);
ssl = bufferevent_openssl_get_ssl(session_data->bev);
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
delete_http2_session_data(session_data);
return;
}
initialize_nghttp2_session(session_data);
if (send_server_connection_header(session_data) != 0) {
if (send_server_connection_header(session_data) != 0 ||
session_send(session_data) != 0) {
delete_http2_session_data(session_data);
return;
}
@@ -188,6 +246,9 @@ underlying network socket::
delete_http2_session_data(session_data);
}
Here we validate that HTTP/2 is negotiated, and if not, drop
connection.
For the ``BEV_EVENT_EOF``, ``BEV_EVENT_ERROR``, and
``BEV_EVENT_TIMEOUT`` events, we just simply tear down the connection.
The ``delete_http2_session_data()`` function destroys the

View File

@@ -66,13 +66,13 @@ enum { IO_NONE, WANT_READ, WANT_WRITE };
#define MAKE_NV(NAME, VALUE) \
{ \
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
#define MAKE_NV_CS(NAME, VALUE) \
{ \
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, strlen(VALUE), \
NGHTTP2_NV_FLAG_NONE \
}
@@ -219,9 +219,9 @@ static int on_frame_send_callback(nghttp2_session *session,
const nghttp2_nv *nva = frame->headers.nva;
printf("[INFO] C ----------------------------> S (HEADERS)\n");
for (i = 0; i < frame->headers.nvlen; ++i) {
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
printf(": ");
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
printf("\n");
}
}
@@ -249,9 +249,9 @@ static int on_frame_recv_callback(nghttp2_session *session,
if (req) {
printf("[INFO] C <---------------------------- S (HEADERS)\n");
for (i = 0; i < frame->headers.nvlen; ++i) {
fwrite(nva[i].name, nva[i].namelen, 1, stdout);
fwrite(nva[i].name, 1, nva[i].namelen, stdout);
printf(": ");
fwrite(nva[i].value, nva[i].valuelen, 1, stdout);
fwrite(nva[i].value, 1, nva[i].valuelen, stdout);
printf("\n");
}
}
@@ -457,11 +457,12 @@ static void ctl_poll(struct pollfd *pollfd, struct Connection *connection) {
static void submit_request(struct Connection *connection, struct Request *req) {
int32_t stream_id;
/* Make sure that the last item is NULL */
const nghttp2_nv nva[] = {
MAKE_NV(":method", "GET"), MAKE_NV_CS(":path", req->path),
MAKE_NV(":scheme", "https"), MAKE_NV_CS(":authority", req->hostport),
MAKE_NV("accept", "*/*"),
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
const nghttp2_nv nva[] = {MAKE_NV(":method", "GET"),
MAKE_NV_CS(":path", req->path),
MAKE_NV(":scheme", "https"),
MAKE_NV_CS(":authority", req->hostport),
MAKE_NV("accept", "*/*"),
MAKE_NV("user-agent", "nghttp2/" NGHTTP2_VERSION)};
stream_id = nghttp2_submit_request(connection->session, NULL, nva,
sizeof(nva) / sizeof(nva[0]), NULL, req);
@@ -562,7 +563,11 @@ static void fetch_uri(const struct URI *uri) {
diec("nghttp2_session_client_new", rv);
}
nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
rv = nghttp2_submit_settings(connection.session, NGHTTP2_FLAG_NONE, NULL, 0);
if (rv != 0) {
diec("nghttp2_submit_settings", rv);
}
/* Submit the HTTP request to the outbound queue. */
submit_request(&connection, &req);
@@ -691,9 +696,6 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, 0);
#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_config(NULL);
#endif /* OPENSSL_IS_BORINGSSL */
SSL_load_error_strings();
SSL_library_init();

View File

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

View File

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

View File

@@ -79,7 +79,7 @@
#define MAKE_NV(NAME, VALUE) \
{ \
(uint8_t *) NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
(uint8_t *)NAME, (uint8_t *)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
NGHTTP2_NV_FLAG_NONE \
}
@@ -116,6 +116,22 @@ static int next_proto_cb(SSL *s _U_, const unsigned char **data,
return SSL_TLSEXT_ERR_OK;
}
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int alpn_select_proto_cb(SSL *ssl _U_, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg _U_) {
int rv;
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
if (rv != 1) {
return SSL_TLSEXT_ERR_NOACK;
}
return SSL_TLSEXT_ERR_OK;
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
/* Create SSL_CTX. */
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_CTX *ssl_ctx;
@@ -152,6 +168,11 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
return ssl_ctx;
}
@@ -640,11 +661,31 @@ static void writecb(struct bufferevent *bev, void *ptr) {
static void eventcb(struct bufferevent *bev _U_, short events, void *ptr) {
http2_session_data *session_data = (http2_session_data *)ptr;
if (events & BEV_EVENT_CONNECTED) {
const unsigned char *alpn = NULL;
unsigned int alpnlen = 0;
SSL *ssl;
fprintf(stderr, "%s connected\n", session_data->client_addr);
ssl = bufferevent_openssl_get_ssl(session_data->bev);
SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL) {
SSL_get0_alpn_selected(ssl, &alpn, &alpnlen);
}
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) {
fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr);
delete_http2_session_data(session_data);
return;
}
initialize_nghttp2_session(session_data);
if (send_server_connection_header(session_data) != 0) {
if (send_server_connection_header(session_data) != 0 ||
session_send(session_data) != 0) {
delete_http2_session_data(session_data);
return;
}
@@ -740,9 +781,6 @@ int main(int argc, char **argv) {
act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL);
#ifndef OPENSSL_IS_BORINGSSL
OPENSSL_config(NULL);
#endif /* OPENSSL_IS_BORINGSSL */
SSL_load_error_strings();
SSL_library_init();

View File

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

View File

@@ -129,6 +129,26 @@ OPTIONS = [
"backend-tls",
"backend-connections-per-host",
"error-page",
"no-kqueue",
"frontend-http2-settings-timeout",
"backend-http2-settings-timeout",
"api-max-request-body",
"backend-max-backoff",
"server-name",
"no-server-rewrite",
"frontend-http2-optimize-write-buffer-size",
"frontend-http2-optimize-window-size",
"frontend-http2-window-size",
"frontend-http2-connection-window-size",
"backend-http2-window-size",
"backend-http2-connection-window-size",
"frontend-http2-encoder-dynamic-table-size",
"frontend-http2-decoder-dynamic-table-size",
"backend-http2-encoder-dynamic-table-size",
"backend-http2-decoder-dynamic-table-size",
"ecdh-curves",
"tls-sct-dir",
"backend-connect-timeout",
]
LOGVARS = [
@@ -147,6 +167,8 @@ LOGVARS = [
"ssl_protocol",
"ssl_session_id",
"ssl_session_reused",
"backend_host",
"backend_port",
]
if __name__ == '__main__':

View File

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

View File

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

View File

@@ -2,6 +2,7 @@ package nghttp2
import (
"crypto/tls"
"encoding/json"
"fmt"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
@@ -1843,3 +1844,190 @@ func TestH2H2RespPhaseReturn(t *testing.T) {
t.Errorf("body = %v; want %v", got, want)
}
}
// TestH2APIBackendconfig exercise backendconfig API endpoint routine
// for successful case.
func TestH2APIBackendconfig(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APIBackendconfig",
path: "/api/v1beta1/backendconfig",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2APIBackendconfigQuery exercise backendconfig API endpoint
// routine with query.
func TestH2APIBackendconfigQuery(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APIBackendconfigQuery",
path: "/api/v1beta1/backendconfig?foo=bar",
method: "PUT",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Success"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 200; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2APIBackendconfigBadMethod exercise backendconfig API endpoint
// routine with bad method.
func TestH2APIBackendconfigBadMethod(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APIBackendconfigBadMethod",
path: "/api/v1beta1/backendconfig",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 405; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 405; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2APINotFound exercise backendconfig API endpoint routine when
// API endpoint is not found.
func TestH2APINotFound(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3010;api;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3010)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2APINotFound",
path: "/api/notfound",
method: "GET",
body: []byte(`# comment
backend=127.0.0.1,3011
`),
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
var apiResp APIResponse
err = json.Unmarshal(res.body, &apiResp)
if err != nil {
t.Fatalf("Error unmarshaling API response: %v", err)
}
if got, want := apiResp.Status, "Failure"; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
if got, want := apiResp.Code, 404; got != want {
t.Errorf("apiResp.Status: %v; want %v", got, want)
}
}
// TestH2Healthmon tests health monitor endpoint.
func TestH2Healthmon(t *testing.T) {
st := newServerTesterConnectPort([]string{"-f127.0.0.1,3011;healthmon;no-tls"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatalf("request should not be forwarded")
}, 3011)
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2Healthmon",
path: "/alpha/bravo",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 200; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}
// TestH2ResponseBeforeRequestEnd tests the situation where response
// ends before request body finishes.
func TestH2ResponseBeforeRequestEnd(t *testing.T) {
st := newServerTester([]string{"--mruby-file=" + testDir + "/req-return.rb"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Fatal("request should not be forwarded")
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2ResponseBeforeRequestEnd",
noEndStream: true,
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 404; got != want {
t.Errorf("res.status: %v; want %v", got, want)
}
}

View File

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

View File

@@ -66,27 +66,36 @@ type serverTester struct {
// newServerTester creates test context for plain TCP frontend
// connection.
func newServerTester(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
return newServerTesterInternal(args, t, handler, false, nil)
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
}
func newServerTesterConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
return newServerTesterInternal(args, t, handler, false, port, nil)
}
func newServerTesterHandler(args []string, t *testing.T, handler http.Handler) *serverTester {
return newServerTesterInternal(args, t, handler, false, nil)
return newServerTesterInternal(args, t, handler, false, serverPort, nil)
}
// newServerTester creates test context for TLS frontend connection.
func newServerTesterTLS(args []string, t *testing.T, handler http.HandlerFunc) *serverTester {
return newServerTesterInternal(args, t, handler, true, nil)
return newServerTesterInternal(args, t, handler, true, serverPort, nil)
}
func newServerTesterTLSConnectPort(args []string, t *testing.T, handler http.HandlerFunc, port int) *serverTester {
return newServerTesterInternal(args, t, handler, true, port, nil)
}
// newServerTester creates test context for TLS frontend connection
// with given clientConfig
func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerFunc, clientConfig *tls.Config) *serverTester {
return newServerTesterInternal(args, t, handler, true, clientConfig)
return newServerTesterInternal(args, t, handler, true, serverPort, clientConfig)
}
// newServerTesterInternal creates test context. If frontendTLS is
// true, set up TLS frontend connection.
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
// true, set up TLS frontend connection. connectPort is the server
// side port where client connection is made.
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, connectPort int, clientConfig *tls.Config) *serverTester {
ts := httptest.NewUnstartedServer(handler)
args := []string{}
@@ -138,7 +147,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)
authority := fmt.Sprintf("127.0.0.1:%v", connectPort)
st := &serverTester{
cmd: exec.Command(serverBin, args...),
@@ -160,6 +169,8 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
retry := 0
for {
time.Sleep(50 * time.Millisecond)
var conn net.Conn
var err error
if frontendTLS {
@@ -170,7 +181,7 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
tlsConfig = clientConfig
}
tlsConfig.InsecureSkipVerify = true
tlsConfig.NextProtos = []string{"h2-14", "spdy/3.1"}
tlsConfig.NextProtos = []string{"h2", "spdy/3.1"}
conn, err = tls.Dial("tcp", authority, tlsConfig)
} else {
conn, err = net.Dial("tcp", authority)
@@ -181,7 +192,6 @@ func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handl
st.Close()
st.t.Fatalf("Error server is not responding too long; server command-line arguments may be invalid")
}
time.Sleep(150 * time.Millisecond)
continue
}
if frontendTLS {
@@ -287,6 +297,7 @@ type requestParam struct {
body []byte // request body
trailer []hpack.HeaderField // trailer part
httpUpgrade bool // true if upgraded to HTTP/2 through HTTP Upgrade
noEndStream bool // true if END_STREAM should not be sent
}
// wrapper for request body to set trailer part
@@ -370,8 +381,9 @@ func (st *serverTester) http1(rp requestParam) (*serverResponse, error) {
if err != nil {
st.t.Fatalf("Error parsing URL from st.url %v: %v", st.url, err)
}
u.Path = rp.path
reqURL = u.String()
u.Path = ""
u.RawQuery = ""
reqURL = u.String() + rp.path
}
req, err := http.NewRequest(method, reqURL, body)
@@ -460,7 +472,7 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
}
var synStreamFlags spdy.ControlFlags
if len(rp.body) == 0 {
if len(rp.body) == 0 && !rp.noEndStream {
synStreamFlags = spdy.ControlFlagFin
}
if err := st.spdyFr.WriteFrame(&spdy.SynStreamFrame{
@@ -474,9 +486,13 @@ func (st *serverTester) spdy(rp requestParam) (*serverResponse, error) {
}
if len(rp.body) != 0 {
var dataFlags spdy.DataFlags
if !rp.noEndStream {
dataFlags = spdy.DataFlagFin
}
if err := st.spdyFr.WriteFrame(&spdy.DataFrame{
StreamId: id,
Flags: spdy.DataFlagFin,
Flags: dataFlags,
Data: rp.body,
}); err != nil {
return nil, err
@@ -589,7 +605,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
err := st.fr.WriteHeaders(http2.HeadersFrameParam{
StreamID: id,
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0,
EndStream: len(rp.body) == 0 && len(rp.trailer) == 0 && !rp.noEndStream,
EndHeaders: true,
BlockFragment: st.headerBlkBuf.Bytes(),
})
@@ -599,7 +615,7 @@ func (st *serverTester) http2(rp requestParam) (*serverResponse, error) {
if len(rp.body) != 0 {
// TODO we assume rp.body fits in 1 frame
if err := st.fr.WriteData(id, len(rp.trailer) == 0, rp.body); err != nil {
if err := st.fr.WriteData(id, len(rp.trailer) == 0 && !rp.noEndStream, rp.body); err != nil {
return nil, err
}
}
@@ -746,3 +762,8 @@ func cloneHeader(h http.Header) http.Header {
}
func noopHandler(w http.ResponseWriter, r *http.Request) {}
type APIResponse struct {
Status string `json:"status,omitempty"`
Code int `json:"code,omitempty"`
}

View File

@@ -8,4 +8,5 @@ fi
export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
export CGO_LDFLAGS="-L$libdir"
export LD_LIBRARY_PATH="$libdir"
export GODEBUG=cgocheck=0
"$@"

View File

@@ -23,6 +23,7 @@ set(NGHTTP2_SOURCES
nghttp2_mem.c
nghttp2_http.c
nghttp2_rcbuf.c
nghttp2_debug.c
)
# Public shared library

View File

@@ -48,7 +48,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_callbacks.c \
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c
nghttp2_rcbuf.c \
nghttp2_debug.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
@@ -63,7 +64,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_callbacks.h \
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h
nghttp2_rcbuf.h \
nghttp2_debug.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \

View File

@@ -45,6 +45,7 @@ extern "C" {
#include <inttypes.h>
#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
#include <sys/types.h>
#include <stdarg.h>
#include <nghttp2/nghttp2ver.h>
@@ -81,7 +82,7 @@ extern "C" {
/**
* @macro
*
* The seriazlied form of ALPN protocol identifier this library
* The serialized form of ALPN protocol identifier this library
* supports. Notice that first byte is the length of following
* protocol identifier. This is the same wire format of `TLS ALPN
* extension <https://tools.ietf.org/html/rfc7301>`_. This is useful
@@ -422,7 +423,7 @@ typedef enum {
/**
* @struct
*
* The object representing single contagious buffer.
* The object representing single contiguous buffer.
*/
typedef struct {
/**
@@ -591,7 +592,12 @@ typedef enum {
* callbacks because the library processes this frame type and its
* preceding HEADERS/PUSH_PROMISE as a single frame.
*/
NGHTTP2_CONTINUATION = 0x09
NGHTTP2_CONTINUATION = 0x09,
/**
* The ALTSVC frame, which is defined in `RFC 7383
* <https://tools.ietf.org/html/rfc7838#section-4>`_.
*/
NGHTTP2_ALTSVC = 0x0a
} nghttp2_frame_type;
/**
@@ -663,6 +669,10 @@ typedef enum {
/**
* @macro
*
* .. warning::
*
* Deprecated. The initial max concurrent streams is 0xffffffffu.
*
* Default maximum number of incoming concurrent streams. Use
* `nghttp2_submit_settings()` with
* :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the
@@ -851,8 +861,13 @@ typedef enum {
* achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading
* any data in this invocation. The library removes DATA frame from
* the outgoing queue temporarily. To move back deferred DATA frame
* to outgoing queue, call `nghttp2_session_resume_data()`. In case
* of error, there are 2 choices. Returning
* to outgoing queue, call `nghttp2_session_resume_data()`.
*
* If the application just wants to return from
* `nghttp2_session_send()` or `nghttp2_session_mem_send()` without
* sending anything, return :enum:`NGHTTP2_ERR_PAUSE`.
*
* In case of error, there are 2 choices. Returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream
* by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. If a
* different error code is desirable, use
@@ -1449,9 +1464,19 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session,
* `nghttp2_session_server_new()`.
*
* The implementation of this function must return 0 if it succeeds.
* If nonzero is returned, it is treated as fatal error and
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
* It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the
* transmission of the given frame.
*
* If there is a fatal error while executing this callback, the
* implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
* which makes `nghttp2_session_send()` and
* `nghttp2_session_mem_send()` functions immediately return
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*
* If the other value is returned, it is treated as if
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. But the
* implementation should not rely on this since the library may define
* new return value to extend its capability.
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_before_frame_send_callback()`.
@@ -1702,6 +1727,69 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
nghttp2_rcbuf *value, uint8_t flags,
void *user_data);
/**
* @functypedef
*
* Callback function invoked when a invalid header name/value pair is
* received for the |frame|.
*
* The parameter and behaviour are similar to
* :type:`nghttp2_on_header_callback`. The difference is that this
* callback is only invoked when a invalid header name/value pair is
* received which is silently ignored if this callback is not set.
* Only invalid regular header field are passed to this callback. In
* other words, invalid pseudo header field is not passed to this
* callback. Also header fields which includes upper cased latter are
* also treated as error without passing them to this callback.
*
* This callback is only considered if HTTP messaging validation is
* turned on (which is on by default, see
* `nghttp2_option_set_no_http_messaging()`).
*
* With this callback, application inspects the incoming invalid
* field, and it also can reset stream from this callback by returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
* error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
* code, call `nghttp2_submit_rst_stream()` with the error code of
* choice in addition to returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_on_invalid_header_callback)(
nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name,
size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags,
void *user_data);
/**
* @functypedef
*
* Callback function invoked when a invalid header name/value pair is
* received for the |frame|.
*
* The parameter and behaviour are similar to
* :type:`nghttp2_on_header_callback2`. The difference is that this
* callback is only invoked when a invalid header name/value pair is
* received which is silently ignored if this callback is not set.
* Only invalid regular header field are passed to this callback. In
* other words, invalid pseudo header field is not passed to this
* callback. Also header fields which includes upper cased latter are
* also treated as error without passing them to this callback.
*
* This callback is only considered if HTTP messaging validation is
* turned on (which is on by default, see
* `nghttp2_option_set_no_http_messaging()`).
*
* With this callback, application inspects the incoming invalid
* field, and it also can reset stream from this callback by returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the
* error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error
* code, call `nghttp2_submit_rst_stream()` with the error code of
* choice in addition to returning
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_on_invalid_header_callback2)(
nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
nghttp2_rcbuf *value, uint8_t flags, void *user_data);
/**
* @functypedef
*
@@ -2060,6 +2148,29 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback2 on_header_callback2);
/**
* @function
*
* Sets callback function invoked when a invalid header name/value
* pair is received. If both
* `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
* `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
* used to set callbacks, the latter takes the precedence.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback on_invalid_header_callback);
/**
* @function
*
* Sets callback function invoked when a invalid header name/value
* pair is received.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2);
/**
* @function
*
@@ -2373,6 +2484,26 @@ NGHTTP2_EXTERN void
nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
uint8_t type);
/**
* @function
*
* Sets extension frame type the application is willing to receive
* using builtin handler. The |type| is the extension frame type to
* receive, and must be strictly greater than 0x9. Otherwise, this
* function does nothing. The application can call this function
* multiple times to set more than one frame type to receive. The
* application does not have to call this function if it just sends
* extension frames.
*
* If same frame type is passed to both
* `nghttp2_option_set_builtin_recv_extension_type()` and
* `nghttp2_option_set_user_recv_extension_type()`, the latter takes
* precedence.
*/
NGHTTP2_EXTERN void
nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
uint8_t type);
/**
* @function
*
@@ -2387,6 +2518,34 @@ nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
int val);
/**
* @function
*
* This option sets the maximum length of header block (a set of
* header fields per one HEADERS frame) to send. The length of a
* given set of header fields is calculated using
* `nghttp2_hd_deflate_bound()`. The default value is 64KiB. If
* application attempts to send header fields larger than this limit,
* the transmission of the frame fails with error code
* :enum:`NGHTTP2_ERR_FRAME_SIZE_ERROR`.
*/
NGHTTP2_EXTERN void
nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
size_t val);
/**
* @function
*
* This option sets the maximum dynamic table size for deflating
* header fields. The default value is 4KiB. In HTTP/2, receiver of
* deflated header block can specify maximum dynamic table size. The
* actual maximum size is the minimum of the size receiver specified
* and this option value.
*/
NGHTTP2_EXTERN void
nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
size_t val);
/**
* @function
*
@@ -2579,14 +2738,20 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session);
*
* 6. :type:`nghttp2_before_frame_send_callback` is invoked.
*
* 7. :type:`nghttp2_send_callback` is invoked one or more times to
* 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from
* :type:`nghttp2_before_frame_send_callback`, the current frame
* transmission is canceled, and
* :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort
* the following steps.
*
* 8. :type:`nghttp2_send_callback` is invoked one or more times to
* send the frame.
*
* 8. :type:`nghttp2_on_frame_send_callback` is invoked.
* 9. :type:`nghttp2_on_frame_send_callback` is invoked.
*
* 9. If the transmission of the frame triggers closure of the stream,
* the stream is closed and
* :type:`nghttp2_on_stream_close_callback` is invoked.
* 10. If the transmission of the frame triggers closure of the
* stream, the stream is closed and
* :type:`nghttp2_on_stream_close_callback` is invoked.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -2637,8 +2802,8 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
* buffer up small chunks of data as necessary to avoid this
* situation.
*/
NGHTTP2_EXTERN ssize_t
nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr);
NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
const uint8_t **data_ptr);
/**
* @function
@@ -2678,12 +2843,13 @@ nghttp2_session_mem_send(nghttp2_session *session, const uint8_t **data_ptr);
* taken. If the frame is either HEADERS or PUSH_PROMISE,
* :type:`nghttp2_on_begin_headers_callback` is invoked. Then
* :type:`nghttp2_on_header_callback` is invoked for each header
* name/value pair. After all name/value pairs are emitted
* successfully, :type:`nghttp2_on_frame_recv_callback` is
* invoked. For other frames,
* :type:`nghttp2_on_frame_recv_callback` is invoked. If the
* reception of the frame triggers the closure of the stream,
* :type:`nghttp2_on_stream_close_callback` is invoked.
* name/value pair. For invalid header field,
* :type:`nghttp2_on_invalid_header_callback` is called. After
* all name/value pairs are emitted successfully,
* :type:`nghttp2_on_frame_recv_callback` is invoked. For other
* frames, :type:`nghttp2_on_frame_recv_callback` is invoked.
* If the reception of the frame triggers the closure of the
* stream, :type:`nghttp2_on_stream_close_callback` is invoked.
*
* 3. If the received frame is unpacked but is interpreted as
* invalid, :type:`nghttp2_on_invalid_frame_recv_callback` is
@@ -2852,9 +3018,8 @@ nghttp2_session_get_outbound_queue_size(nghttp2_session *session);
*
* This function returns -1 if it fails.
*/
NGHTTP2_EXTERN int32_t
nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session,
int32_t stream_id);
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_recv_data_length(
nghttp2_session *session, int32_t stream_id);
/**
* @function
@@ -2864,11 +3029,32 @@ nghttp2_session_get_stream_effective_recv_data_length(nghttp2_session *session,
* `nghttp2_submit_window_update()`. This function takes into account
* that and returns effective window size.
*
* This function does not take into account the amount of received
* data from the remote endpoint. Use
* `nghttp2_session_get_stream_local_window_size()` to know the amount
* of data the remote endpoint can send without receiving stream level
* WINDOW_UPDATE frame. Note that each stream is still subject to the
* connection level flow control.
*
* This function returns -1 if it fails.
*/
NGHTTP2_EXTERN int32_t
nghttp2_session_get_stream_effective_local_window_size(nghttp2_session *session,
int32_t stream_id);
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_effective_local_window_size(
nghttp2_session *session, int32_t stream_id);
/**
* @function
*
* Returns the amount of flow-controlled payload (e.g., DATA) that the
* remote endpoint can send without receiving stream level
* WINDOW_UPDATE frame. It is also subject to the connection level
* flow control. So the actual amount of data to send is
* min(`nghttp2_session_get_stream_local_window_size()`,
* `nghttp2_session_get_local_window_size()`).
*
* This function returns -1 if it fails.
*/
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_local_window_size(
nghttp2_session *session, int32_t stream_id);
/**
* @function
@@ -2895,11 +3081,32 @@ nghttp2_session_get_effective_recv_data_length(nghttp2_session *session);
* `nghttp2_submit_window_update()`. This function takes into account
* that and returns effective window size.
*
* This function does not take into account the amount of received
* data from the remote endpoint. Use
* `nghttp2_session_get_local_window_size()` to know the amount of
* data the remote endpoint can send without receiving
* connection-level WINDOW_UPDATE frame. Note that each stream is
* still subject to the stream level flow control.
*
* This function returns -1 if it fails.
*/
NGHTTP2_EXTERN int32_t
nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
/**
* @function
*
* Returns the amount of flow-controlled payload (e.g., DATA) that the
* remote endpoint can send without receiving connection level
* WINDOW_UPDATE frame. Note that each stream is still subject to the
* stream level flow control (see
* `nghttp2_session_get_stream_local_window_size()`).
*
* This function returns -1 if it fails.
*/
NGHTTP2_EXTERN int32_t
nghttp2_session_get_local_window_size(nghttp2_session *session);
/**
* @function
*
@@ -2914,9 +3121,8 @@ nghttp2_session_get_effective_local_window_size(nghttp2_session *session);
*
* This function returns -1 if it fails.
*/
NGHTTP2_EXTERN int32_t
nghttp2_session_get_stream_remote_window_size(nghttp2_session *session,
int32_t stream_id);
NGHTTP2_EXTERN int32_t nghttp2_session_get_stream_remote_window_size(
nghttp2_session *session, int32_t stream_id);
/**
* @function
@@ -2948,6 +3154,24 @@ NGHTTP2_EXTERN int
nghttp2_session_get_stream_remote_close(nghttp2_session *session,
int32_t stream_id);
/**
* @function
*
* Returns the current dynamic table size of HPACK inflater, including
* the overhead 32 bytes per entry described in RFC 7541.
*/
NGHTTP2_EXTERN size_t
nghttp2_session_get_hd_inflate_dynamic_table_size(nghttp2_session *session);
/**
* @function
*
* Returns the current dynamic table size of HPACK deflater including
* the overhead 32 bytes per entry described in RFC 7541.
*/
NGHTTP2_EXTERN size_t
nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session);
/**
* @function
*
@@ -3051,9 +3275,18 @@ NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session);
* The |id| must be one of values defined in
* :enum:`nghttp2_settings_id`.
*/
NGHTTP2_EXTERN uint32_t
nghttp2_session_get_remote_settings(nghttp2_session *session,
nghttp2_settings_id id);
NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings(
nghttp2_session *session, nghttp2_settings_id id);
/**
* @function
*
* Returns the value of SETTINGS |id| of local endpoint acknowledged
* by the remote endpoint. The |id| must be one of the values defined
* in :enum:`nghttp2_settings_id`.
*/
NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
nghttp2_session *session, nghttp2_settings_id id);
/**
* @function
@@ -3348,9 +3581,8 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session,
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
* The provided |buflen| size is too small to hold the output.
*/
NGHTTP2_EXTERN ssize_t
nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
const nghttp2_settings_entry *iv, size_t niv);
NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload(
uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
/**
* @function
@@ -3475,12 +3707,10 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec);
* frame.
*
*/
NGHTTP2_EXTERN int32_t
nghttp2_submit_request(nghttp2_session *session,
const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen,
const nghttp2_data_provider *data_prd,
void *stream_user_data);
NGHTTP2_EXTERN int32_t nghttp2_submit_request(
nghttp2_session *session, const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider *data_prd,
void *stream_user_data);
/**
* @function
@@ -3558,8 +3788,8 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
*
* The |nva| is an array of name/value pair :type:`nghttp2_nv` with
* |nvlen| elements. The application is responsible not to include
* required pseudo-header fields (header field whose name starts with
* ":") in |nva|.
* pseudo-header fields (header field whose name starts with ":") in
* |nva|.
*
* This function creates copies of all name/value pairs in |nva|. It
* also lower-cases all names in |nva|. The order of elements in
@@ -3574,20 +3804,20 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
* :type:`nghttp2_on_frame_not_send_callback` is called.
*
* For server, trailer fields must follow response HEADERS or response
* DATA with END_STREAM flag set. The library does not enforce this
* requirement, and applications should do this for themselves. If
* `nghttp2_submit_trailer()` is called before any response HEADERS
* DATA without END_STREAM flat set. The library does not enforce
* this requirement, and applications should do this for themselves.
* If `nghttp2_submit_trailer()` is called before any response HEADERS
* submission (usually by `nghttp2_submit_response()`), the content of
* |nva| will be sent as response headers, which will result in error.
*
* This function has the same effect with `nghttp2_submit_headers()`,
* with flags = :enum:`NGHTTP2_FLAG_END_HEADERS` and both pri_spec and
* with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and
* stream_user_data to NULL.
*
* To submit trailer fields after `nghttp2_submit_response()` is
* called, the application has to specify
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`. In
* side :type:`nghttp2_data_source_read_callback`, when setting
* :type:`nghttp2_data_provider` to `nghttp2_submit_response()`.
* Inside of :type:`nghttp2_data_source_read_callback`, when setting
* :enum:`NGHTTP2_DATA_FLAG_EOF`, also set
* :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`. After that, the
* application can send trailer fields using
@@ -3695,11 +3925,10 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session,
* frame.
*
*/
NGHTTP2_EXTERN int32_t
nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
int32_t stream_id, const nghttp2_priority_spec *pri_spec,
const nghttp2_nv *nva, size_t nvlen,
void *stream_user_data);
NGHTTP2_EXTERN int32_t nghttp2_submit_headers(
nghttp2_session *session, uint8_t flags, int32_t stream_id,
const nghttp2_priority_spec *pri_spec, const nghttp2_nv *nva, size_t nvlen,
void *stream_user_data);
/**
* @function
@@ -3907,10 +4136,9 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session,
* is called for this frame.
*
*/
NGHTTP2_EXTERN int32_t
nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
int32_t stream_id, const nghttp2_nv *nva,
size_t nvlen, void *promised_stream_user_data);
NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise(
nghttp2_session *session, uint8_t flags, int32_t stream_id,
const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data);
/**
* @function
@@ -4046,14 +4274,17 @@ nghttp2_session_check_server_session(nghttp2_session *session);
* that value as window_size_increment is queued. If the
* |window_size_increment| is larger than the received bytes from the
* remote endpoint, the local window size is increased by that
* difference.
* difference. If the sole purpose is to increase the local window
* size, consider to use `nghttp2_session_set_local_window_size()`.
*
* If the |window_size_increment| is negative, the local window size
* is decreased by -|window_size_increment|. If automatic
* WINDOW_UPDATE is enabled
* (`nghttp2_option_set_no_auto_window_update()`), and the library
* decided that the WINDOW_UPDATE should be submitted, then
* WINDOW_UPDATE is queued with the current received bytes count.
* WINDOW_UPDATE is queued with the current received bytes count. If
* the sole purpose is to decrease the local window size, consider to
* use `nghttp2_session_set_local_window_size()`.
*
* If the |window_size_increment| is 0, the function does nothing and
* returns 0.
@@ -4071,6 +4302,44 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
int32_t stream_id,
int32_t window_size_increment);
/**
* @function
*
* Set local window size (local endpoints's window size) to the given
* |window_size| for the given stream denoted by |stream_id|. To
* change connection level window size, specify 0 to |stream_id|. To
* increase window size, this function may submit WINDOW_UPDATE frame
* to transmission queue.
*
* The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`.
*
* This sounds similar to `nghttp2_submit_window_update()`, but there
* are 2 differences. The first difference is that this function
* takes the absolute value of window size to set, rather than the
* delta. To change the window size, this may be easier to use since
* the application just declares the intended window size, rather than
* calculating delta. The second difference is that
* `nghttp2_submit_window_update()` affects the received bytes count
* which has not acked yet. By the specification of
* `nghttp2_submit_window_update()`, to strictly increase the local
* window size, we have to submit delta including all received bytes
* count, which might not be desirable in some cases. On the other
* hand, this function does not affect the received bytes count. It
* just sets the local window size to the given value.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The |stream_id| is negative.
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int
nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags,
int32_t stream_id, int32_t window_size);
/**
* @function
*
@@ -4113,6 +4382,80 @@ NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session,
uint8_t type, uint8_t flags,
int32_t stream_id, void *payload);
/**
* @struct
*
* The payload of ALTSVC frame. ALTSVC frame is a non-critical
* extension to HTTP/2. If this frame is received, and
* `nghttp2_option_set_user_recv_extension_type()` is not set, and
* `nghttp2_option_set_builtin_recv_extension_type()` is set for
* :enum:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to
* this struct.
*
* It has the following members:
*/
typedef struct {
/**
* The pointer to origin which this alternative service is
* associated with. This is not necessarily NULL-terminated.
*/
uint8_t *origin;
/**
* The length of the |origin|.
*/
size_t origin_len;
/**
* The pointer to Alt-Svc field value contained in ALTSVC frame.
* This is not necessarily NULL-terminated.
*/
uint8_t *field_value;
/**
* The length of the |field_value|.
*/
size_t field_value_len;
} nghttp2_ext_altsvc;
/**
* @function
*
* Submits ALTSVC frame.
*
* ALTSVC frame is a non-critical extension to HTTP/2, and defined in
* is defined in `RFC 7383
* <https://tools.ietf.org/html/rfc7838#section-4>`_.
*
* The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`.
*
* The |origin| points to the origin this alternative service is
* associated with. The |origin_len| is the length of the origin. If
* |stream_id| is 0, the origin must be specified. If |stream_id| is
* not zero, the origin must be empty (in other words, |origin_len|
* must be 0).
*
* The ALTSVC frame is only usable from server side. If this function
* is invoked with client side session, this function returns
* :enum:`NGHTTP2_ERR_INVALID_STATE`.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory
* :enum:`NGHTTP2_ERR_INVALID_STATE`
* The function is called from client side session
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* The sum of |origin_len| and |field_value_len| is larger than
* 16382; or |origin_len| is 0 while |stream_id| is 0; or
* |origin_len| is not 0 while |stream_id| is not 0.
*/
NGHTTP2_EXTERN int nghttp2_submit_altsvc(nghttp2_session *session,
uint8_t flags, int32_t stream_id,
const uint8_t *origin,
size_t origin_len,
const uint8_t *field_value,
size_t field_value_len);
/**
* @function
*
@@ -4243,7 +4586,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
*
* Initializes |*deflater_ptr| for deflating name/values pairs.
*
* The |deflate_hd_table_bufsize_max| is the upper bound of header
* The |max_deflate_dynamic_table_size| is the upper bound of header
* table size the deflater will use.
*
* If this function fails, |*deflater_ptr| is left untouched.
@@ -4254,8 +4597,9 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater;
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
*/
NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
size_t deflate_hd_table_bufsize_max);
NGHTTP2_EXTERN int
nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
size_t max_deflate_dynamic_table_size);
/**
* @function
@@ -4272,9 +4616,10 @@ NGHTTP2_EXTERN int nghttp2_hd_deflate_new(nghttp2_hd_deflater **deflater_ptr,
* The library code does not refer to |mem| pointer after this
* function returns, so the application can safely free it.
*/
NGHTTP2_EXTERN int nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
size_t deflate_hd_table_bufsize_max,
nghttp2_mem *mem);
NGHTTP2_EXTERN int
nghttp2_hd_deflate_new2(nghttp2_hd_deflater **deflater_ptr,
size_t max_deflate_dynamic_table_size,
nghttp2_mem *mem);
/**
* @function
@@ -4287,18 +4632,18 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
* @function
*
* Changes header table size of the |deflater| to
* |settings_hd_table_bufsize_max| bytes. This may trigger eviction
* |settings_max_dynamic_table_size| bytes. This may trigger eviction
* in the dynamic table.
*
* The |settings_hd_table_bufsize_max| should be the value received in
* SETTINGS_HEADER_TABLE_SIZE.
* The |settings_max_dynamic_table_size| should be the value received
* in SETTINGS_HEADER_TABLE_SIZE.
*
* The deflater never uses more memory than
* ``deflate_hd_table_bufsize_max`` bytes specified in
* ``max_deflate_dynamic_table_size`` bytes specified in
* `nghttp2_hd_deflate_new()`. Therefore, if
* |settings_hd_table_bufsize_max| > ``deflate_hd_table_bufsize_max``,
* resulting maximum table size becomes
* ``deflate_hd_table_bufsize_max``.
* |settings_max_dynamic_table_size| >
* ``max_deflate_dynamic_table_size``, resulting maximum table size
* becomes ``max_deflate_dynamic_table_size``.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -4308,7 +4653,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater);
*/
NGHTTP2_EXTERN int
nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
size_t settings_hd_table_bufsize_max);
size_t settings_max_dynamic_table_size);
/**
* @function
@@ -4337,9 +4682,43 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
* The provided |buflen| size is too small to hold the output.
*/
NGHTTP2_EXTERN ssize_t
nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
size_t buflen, const nghttp2_nv *nva, size_t nvlen);
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater,
uint8_t *buf, size_t buflen,
const nghttp2_nv *nva,
size_t nvlen);
/**
* @function
*
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
* the |veclen| size of buf vector |vec|. The each size of buffer
* must be set in len field of :type:`nghttp2_vec`. If and only if
* one chunk is filled up completely, next chunk will be used. If
* |vec| is not large enough to store the deflated header block, this
* function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller
* should use `nghttp2_hd_deflate_bound()` to know the upper bound of
* buffer size required to deflate given header name/value pairs.
*
* Once this function fails, subsequent call of this function always
* returns :enum:`NGHTTP2_ERR_HEADER_COMP`.
*
* After this function returns, it is safe to delete the |nva|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`NGHTTP2_ERR_HEADER_COMP`
* Deflation process has failed.
* :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`
* The provided |buflen| size is too small to hold the output.
*/
NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater,
const nghttp2_vec *vec,
size_t veclen,
const nghttp2_nv *nva,
size_t nvlen);
/**
* @function
@@ -4448,13 +4827,13 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
* Changes header table size in the |inflater|. This may trigger
* eviction in the dynamic table.
*
* The |settings_hd_table_bufsize_max| should be the value transmitted
* in SETTINGS_HEADER_TABLE_SIZE.
* The |settings_max_dynamic_table_size| should be the value
* transmitted in SETTINGS_HEADER_TABLE_SIZE.
*
* This function must not be called while header block is being
* inflated. In other words, this function must be called after
* initialization of |inflater|, but before calling
* `nghttp2_hd_inflate_hd()`, or after
* `nghttp2_hd_inflate_hd2()`, or after
* `nghttp2_hd_inflate_end_headers()`. Otherwise,
* `NGHTTP2_ERR_INVALID_STATE` was returned.
*
@@ -4470,7 +4849,7 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
*/
NGHTTP2_EXTERN int
nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
size_t settings_hd_table_bufsize_max);
size_t settings_max_dynamic_table_size);
/**
* @enum
@@ -4495,6 +4874,10 @@ typedef enum {
/**
* @function
*
* .. warning::
*
* Deprecated. Use `nghttp2_hd_inflate_hd2()` instead.
*
* Inflates name/value block stored in |in| with length |inlen|. This
* function performs decompression. For each successful emission of
* header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
@@ -4574,6 +4957,93 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
int *inflate_flags, uint8_t *in,
size_t inlen, int in_final);
/**
* @function
*
* Inflates name/value block stored in |in| with length |inlen|. This
* function performs decompression. For each successful emission of
* header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in
* |*inflate_flags| and name/value pair is assigned to the |nv_out|
* and the function returns. The caller must not free the members of
* |nv_out|.
*
* The |nv_out| may include pointers to the memory region in the |in|.
* The caller must retain the |in| while the |nv_out| is used.
*
* The application should call this function repeatedly until the
* ``(*inflate_flags) & NGHTTP2_HD_INFLATE_FINAL`` is nonzero and
* return value is non-negative. If that happens, all given input
* data (|inlen| bytes) are processed successfully. Then the
* application must call `nghttp2_hd_inflate_end_headers()` to prepare
* for the next header block input.
*
* In other words, if |in_final| is nonzero, and this function returns
* |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is
* set in |*inflate_flags|.
*
* The caller can feed complete compressed header block. It also can
* feed it in several chunks. The caller must set |in_final| to
* nonzero if the given input is the last block of the compressed
* header.
*
* This function returns the number of bytes processed if it succeeds,
* or one of the following negative error codes:
*
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory.
* :enum:`NGHTTP2_ERR_HEADER_COMP`
* Inflation process has failed.
* :enum:`NGHTTP2_ERR_BUFFER_ERROR`
* The header field name or value is too large.
*
* Example follows::
*
* int inflate_header_block(nghttp2_hd_inflater *hd_inflater,
* uint8_t *in, size_t inlen, int final)
* {
* ssize_t rv;
*
* for(;;) {
* nghttp2_nv nv;
* int inflate_flags = 0;
*
* rv = nghttp2_hd_inflate_hd2(hd_inflater, &nv, &inflate_flags,
* in, inlen, final);
*
* if(rv < 0) {
* fprintf(stderr, "inflate failed with error code %zd", rv);
* return -1;
* }
*
* in += rv;
* inlen -= rv;
*
* if(inflate_flags & NGHTTP2_HD_INFLATE_EMIT) {
* fwrite(nv.name, nv.namelen, 1, stderr);
* fprintf(stderr, ": ");
* fwrite(nv.value, nv.valuelen, 1, stderr);
* fprintf(stderr, "\n");
* }
* if(inflate_flags & NGHTTP2_HD_INFLATE_FINAL) {
* nghttp2_hd_inflate_end_headers(hd_inflater);
* break;
* }
* if((inflate_flags & NGHTTP2_HD_INFLATE_EMIT) == 0 &&
* inlen == 0) {
* break;
* }
* }
*
* return 0;
* }
*
*/
NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out,
int *inflate_flags,
const uint8_t *in, size_t inlen,
int in_final);
/**
* @function
*
@@ -4762,6 +5232,42 @@ NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
NGHTTP2_EXTERN int32_t
nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
/**
* @functypedef
*
* Callback function invoked when the library outputs debug logging.
* The function is called with arguments suitable for ``vfprintf(3)``
*
* The debug output is only enabled if the library is built with
* ``DEBUGBUILD`` macro defined.
*/
typedef void (*nghttp2_debug_vprintf_callback)(const char *format,
va_list args);
/**
* @function
*
* Sets a debug output callback called by the library when built with
* ``DEBUGBUILD`` macro defined. If this option is not used, debug
* log is written into standard error output.
*
* For builds without ``DEBUGBUILD`` macro defined, this function is
* noop.
*
* Note that building with ``DEBUGBUILD`` may cause significant
* performance penalty to libnghttp2 because of extra processing. It
* should be used for debugging purpose only.
*
* .. Warning::
*
* Building with ``DEBUGBUILD`` may cause significant performance
* penalty to libnghttp2 because of extra processing. It should be
* used for debugging purpose only. We write this two times because
* this is important.
*/
NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback(
nghttp2_debug_vprintf_callback debug_vprintf_callback);
#ifdef __cplusplus
}
#endif

View File

@@ -27,6 +27,7 @@
#include <stdio.h>
#include "nghttp2_helper.h"
#include "nghttp2_debug.h"
void nghttp2_buf_init(nghttp2_buf *buf) {
buf->begin = NULL;
@@ -223,13 +224,54 @@ int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
return 0;
}
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
size_t veclen, nghttp2_mem *mem) {
size_t i = 0;
nghttp2_buf_chain *cur_chain;
nghttp2_buf_chain *head_chain;
nghttp2_buf_chain **dst_chain = &head_chain;
if (veclen == 0) {
return nghttp2_bufs_wrap_init(bufs, NULL, 0, mem);
}
head_chain = nghttp2_mem_malloc(mem, sizeof(nghttp2_buf_chain) * veclen);
if (head_chain == NULL) {
return NGHTTP2_ERR_NOMEM;
}
for (i = 0; i < veclen; ++i) {
cur_chain = &head_chain[i];
cur_chain->next = NULL;
nghttp2_buf_wrap_init(&cur_chain->buf, vec[i].base, vec[i].len);
*dst_chain = cur_chain;
dst_chain = &cur_chain->next;
}
bufs->mem = mem;
bufs->offset = 0;
bufs->head = head_chain;
bufs->cur = bufs->head;
/* We don't use chunk_length since no allocation is expected. */
bufs->chunk_length = 0;
bufs->chunk_used = veclen;
bufs->max_chunk = veclen;
bufs->chunk_keep = veclen;
return 0;
}
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs) {
if (bufs == NULL) {
return;
}
nghttp2_mem_free(bufs->mem, bufs->head);
bufs->head = NULL;
if (bufs->head) {
nghttp2_mem_free(bufs->mem, bufs->head);
}
}
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs) {
@@ -256,12 +298,6 @@ size_t nghttp2_bufs_len(nghttp2_bufs *bufs) {
return len;
}
static size_t bufs_avail(nghttp2_bufs *bufs) {
return nghttp2_buf_avail(&bufs->cur->buf) +
(bufs->chunk_length - bufs->offset) *
(bufs->max_chunk - bufs->chunk_used);
}
static int bufs_alloc_chain(nghttp2_bufs *bufs) {
int rv;
nghttp2_buf_chain *chain;
@@ -281,9 +317,8 @@ static int bufs_alloc_chain(nghttp2_bufs *bufs) {
return rv;
}
DEBUGF(fprintf(stderr,
"new buffer %zu bytes allocated for bufs %p, used %zu\n",
bufs->chunk_length, bufs, bufs->chunk_used));
DEBUGF("new buffer %zu bytes allocated for bufs %p, used %zu\n",
bufs->chunk_length, bufs, bufs->chunk_used);
++bufs->chunk_used;
@@ -301,10 +336,6 @@ int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) {
nghttp2_buf *buf;
const uint8_t *p;
if (bufs_avail(bufs) < len) {
return NGHTTP2_ERR_BUFFER_ERROR;
}
p = data;
while (len) {

View File

@@ -138,7 +138,9 @@ typedef struct {
nghttp2_buf_chain *cur;
/* Memory allocator */
nghttp2_mem *mem;
/* The buffer capacity of each buf */
/* The buffer capacity of each buf. This field may be 0 if
nghttp2_bufs is initialized by nghttp2_bufs_wrap_init* family
functions. */
size_t chunk_length;
/* The maximum number of nghttp2_buf_chain */
size_t max_chunk;
@@ -197,10 +199,13 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
/*
* Initializes |bufs| using supplied buffer |begin| of length |len|.
* The first buffer bufs->head uses buffer |begin|. The buffer size
* is fixed and no allocate extra chunk buffer is allocated. In other
* is fixed and no extra chunk buffer is allocated. In other
* words, max_chunk = chunk_keep = 1. To free the resource allocated
* for |bufs|, use nghttp2_bufs_wrap_free().
*
* Don't use the function which performs allocation, such as
* nghttp2_bufs_realloc().
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
@@ -210,6 +215,25 @@ void nghttp2_bufs_free(nghttp2_bufs *bufs);
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
nghttp2_mem *mem);
/*
* Initializes |bufs| using supplied |veclen| size of buf vector
* |vec|. The number of buffers is fixed and no extra chunk buffer is
* allocated. In other words, max_chunk = chunk_keep = |in_len|. To
* free the resource allocated for |bufs|, use
* nghttp2_bufs_wrap_free().
*
* Don't use the function which performs allocation, such as
* nghttp2_bufs_realloc().
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_bufs_wrap_init2(nghttp2_bufs *bufs, const nghttp2_vec *vec,
size_t veclen, nghttp2_mem *mem);
/*
* Frees any related resource to the |bufs|. This function does not
* free supplied buffer provided in nghttp2_bufs_wrap_init().
@@ -312,8 +336,8 @@ int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
} while (0)
/*
* Copies all data stored in |bufs| to the contagious buffer. This
* function allocates the contagious memory to store all data in
* Copies all data stored in |bufs| to the contiguous buffer. This
* function allocates the contiguous memory to store all data in
* |bufs| and assigns it to |*out|.
*
* The contents of |bufs| is left unchanged.
@@ -381,7 +405,7 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
/*
* Returns the buffer length of |bufs|.
* Returns the total buffer length of |bufs|.
*/
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);

View File

@@ -110,6 +110,18 @@ void nghttp2_session_callbacks_set_on_header_callback2(
cbs->on_header_callback2 = on_header_callback2;
}
void nghttp2_session_callbacks_set_on_invalid_header_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback on_invalid_header_callback) {
cbs->on_invalid_header_callback = on_invalid_header_callback;
}
void nghttp2_session_callbacks_set_on_invalid_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2) {
cbs->on_invalid_header_callback2 = on_invalid_header_callback2;
}
void nghttp2_session_callbacks_set_select_padding_callback(
nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback select_padding_callback) {

View File

@@ -92,6 +92,13 @@ struct nghttp2_session_callbacks {
*/
nghttp2_on_header_callback on_header_callback;
nghttp2_on_header_callback2 on_header_callback2;
/**
* Callback function invoked when a invalid header name/value pair
* is received which is silently ignored if these callbacks are not
* set.
*/
nghttp2_on_invalid_header_callback on_invalid_header_callback;
nghttp2_on_invalid_header_callback2 on_invalid_header_callback2;
/**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given

58
lib/nghttp2_debug.c Normal file
View 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
View 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 */

View File

@@ -32,6 +32,7 @@
#include "nghttp2_helper.h"
#include "nghttp2_net.h"
#include "nghttp2_priority_spec.h"
#include "nghttp2_debug.h"
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd) {
nghttp2_put_uint32be(&buf[0], (uint32_t)(hd->length << 8));
@@ -193,6 +194,30 @@ void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
void nghttp2_frame_extension_free(nghttp2_extension *frame _U_) {}
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
uint8_t *origin, size_t origin_len,
uint8_t *field_value, size_t field_value_len) {
nghttp2_ext_altsvc *altsvc;
nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
altsvc = frame->payload;
altsvc->origin = origin;
altsvc->origin_len = origin_len;
altsvc->field_value = field_value;
altsvc->field_value_len = field_value_len;
}
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_ext_altsvc *altsvc;
altsvc = frame->payload;
/* We use the same buffer for altsvc->origin and
altsvc->field_value. */
nghttp2_mem_free(mem, altsvc->origin);
}
size_t nghttp2_frame_priority_len(uint8_t flags) {
if (flags & NGHTTP2_FLAG_PRIORITY) {
return NGHTTP2_PRIORITY_SPECLEN;
@@ -228,8 +253,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
hd = *frame_hd;
hd.length = nghttp2_buf_len(buf);
DEBUGF(fprintf(stderr, "send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n",
hd.length));
DEBUGF("send: HEADERS/PUSH_PROMISE, payloadlen=%zu\n", hd.length);
/* We have multiple frame buffers, which means one or more
CONTINUATION frame is involved. Remove END_HEADERS flag from the
@@ -254,8 +278,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
hd.length = nghttp2_buf_len(buf);
DEBUGF(fprintf(stderr, "send: int CONTINUATION, payloadlen=%zu\n",
hd.length));
DEBUGF("send: int CONTINUATION, payloadlen=%zu\n", hd.length);
buf->pos -= NGHTTP2_FRAME_HDLEN;
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
@@ -266,8 +289,7 @@ static int frame_pack_headers_shared(nghttp2_bufs *bufs,
/* Set END_HEADERS flag for last CONTINUATION */
hd.flags = NGHTTP2_FLAG_END_HEADERS;
DEBUGF(fprintf(stderr, "send: last CONTINUATION, payloadlen=%zu\n",
hd.length));
DEBUGF("send: last CONTINUATION, payloadlen=%zu\n", hd.length);
buf->pos -= NGHTTP2_FRAME_HDLEN;
nghttp2_frame_pack_frame_hd(buf->pos, &hd);
@@ -439,25 +461,11 @@ size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
return NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH * niv;
}
int nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem) {
size_t payloadlen = niv * sizeof(nghttp2_settings_entry);
if (niv == 0) {
frame->iv = NULL;
} else {
frame->iv = nghttp2_mem_malloc(mem, payloadlen);
if (frame->iv == NULL) {
return NGHTTP2_ERR_NOMEM;
}
memcpy(frame->iv, iv, payloadlen);
}
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
nghttp2_settings_entry *iv,
size_t niv) {
frame->iv = iv;
frame->niv = niv;
return 0;
}
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
@@ -668,6 +676,79 @@ void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
}
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
int rv;
nghttp2_buf *buf;
nghttp2_ext_altsvc *altsvc;
altsvc = frame->payload;
buf = &bufs->head->buf;
assert(nghttp2_buf_avail(buf) >=
2 + altsvc->origin_len + altsvc->field_value_len);
buf->pos -= NGHTTP2_FRAME_HDLEN;
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
nghttp2_put_uint16be(buf->last, (uint16_t)altsvc->origin_len);
buf->last += 2;
rv = nghttp2_bufs_add(bufs, altsvc->origin, altsvc->origin_len);
assert(rv == 0);
rv = nghttp2_bufs_add(bufs, altsvc->field_value, altsvc->field_value_len);
assert(rv == 0);
return 0;
}
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
size_t origin_len, uint8_t *payload,
size_t payloadlen) {
nghttp2_ext_altsvc *altsvc;
uint8_t *p;
altsvc = frame->payload;
p = payload;
altsvc->origin = p;
p += origin_len;
altsvc->origin_len = origin_len;
altsvc->field_value = p;
altsvc->field_value_len = (size_t)(payload + payloadlen - p);
}
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
const uint8_t *payload,
size_t payloadlen, nghttp2_mem *mem) {
uint8_t *buf;
size_t origin_len;
if (payloadlen < 2) {
return NGHTTP2_FRAME_SIZE_ERROR;
}
origin_len = nghttp2_get_uint16(payload);
buf = nghttp2_mem_malloc(mem, payloadlen - 2);
if (!buf) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_cpymem(buf, payload + 2, payloadlen - 2);
nghttp2_frame_unpack_altsvc_payload(frame, origin_len, buf, payloadlen - 2);
return 0;
}
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
size_t niv, nghttp2_mem *mem) {
nghttp2_settings_entry *iv_copy;
@@ -847,7 +928,7 @@ static void frame_set_pad(nghttp2_buf *buf, size_t padlen, int framehd_only) {
size_t trail_padlen;
size_t newlen;
DEBUGF(fprintf(stderr, "send: padlen=%zu, shift left 1 bytes\n", padlen));
DEBUGF("send: padlen=%zu, shift left 1 bytes\n", padlen);
memmove(buf->pos - 1, buf->pos, NGHTTP2_FRAME_HDLEN);
@@ -877,7 +958,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
nghttp2_buf *buf;
if (padlen == 0) {
DEBUGF(fprintf(stderr, "send: padlen = 0, nothing to do\n"));
DEBUGF("send: padlen = 0, nothing to do\n");
return 0;
}
@@ -911,8 +992,7 @@ int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
hd->length += padlen;
hd->flags |= NGHTTP2_FLAG_PADDED;
DEBUGF(fprintf(stderr, "send: final payloadlen=%zu, padlen=%zu\n", hd->length,
padlen));
DEBUGF("send: final payloadlen=%zu, padlen=%zu\n", hd->length, padlen);
return 0;
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -288,7 +288,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
/*
* Initializes |deflater| for deflating name/values pairs.
*
* The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
* The encoder only uses up to |max_deflate_dynamic_table_size| bytes
* for header table even if the larger value is specified later in
* nghttp2_hd_change_table_size().
*
@@ -299,7 +299,7 @@ int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
* Out of memory.
*/
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
size_t deflate_hd_table_bufsize_max,
size_t max_deflate_dynamic_table_size,
nghttp2_mem *mem);
/*
@@ -353,9 +353,9 @@ void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
* that return values and semantics are the same as
* nghttp2_hd_inflate_hd().
*/
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out, int *inflate_flags,
uint8_t *in, size_t inlen, int in_final);
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen, int in_final);
/* For unittesting purpose */
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
@@ -372,7 +372,7 @@ int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
/* For unittesting purpose */
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *fin,
uint32_t initial, size_t shift, uint8_t *in,
uint8_t *last, size_t prefix);
@@ -410,8 +410,8 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
* will be written to |buf|. This function assumes that |buf| has the
* enough room to store the decoded byte string.
*
* The caller must set the |final| to nonzero if the given input is
* the final block.
* The caller must set the |fin| to nonzero if the given input is the
* final block.
*
* This function returns the number of read bytes from the |in|.
*
@@ -425,6 +425,6 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
*/
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final);
size_t srclen, int fin);
#endif /* NGHTTP2_HD_H */

View File

@@ -64,15 +64,44 @@ static ssize_t huff_encode_sym(nghttp2_bufs *bufs, size_t *avail_ptr,
code <<= 8 - (nbits & 0x7);
}
/* we lose at most 3 bytes, but it is not critical in practice */
if (*avail_ptr < (nbits + 7) / 8) {
rv = nghttp2_bufs_advance(bufs);
/* slow path */
if (nbits > 24) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 24));
if (rv != 0) {
return rv;
}
nbits -= 8;
}
if (nbits > 16) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 16));
if (rv != 0) {
return rv;
}
nbits -= 8;
}
if (nbits > 8) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)(code >> 8));
if (rv != 0) {
return rv;
}
nbits -= 8;
}
if (nbits == 8) {
rv = nghttp2_bufs_addb(bufs, (uint8_t)code);
if (rv != 0) {
return rv;
}
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
return 8;
}
rv = nghttp2_bufs_addb_hold(bufs, (uint8_t)code);
if (rv != 0) {
return rv;
}
*avail_ptr = nghttp2_bufs_cur_avail(bufs);
/* we assume that we at least 3 buffer space available */
assert(*avail_ptr >= 3);
return (ssize_t)(8 - nbits);
}
/* fast path, since most code is less than 8 */

File diff suppressed because it is too large Load Diff

View File

@@ -189,8 +189,8 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
account it in *delta_ptr. */
*recv_window_size_ptr = recv_reduction_delta;
}
/* recv_reduction_delta must be paied from *delta_ptr, since it
was added in window size reduction (see below). */
/* recv_reduction_delta must be paid from *delta_ptr, since it was
added in window size reduction (see below). */
*delta_ptr -= recv_reduction_delta;
return 0;
@@ -213,6 +213,38 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
return 0;
}
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
int32_t *recv_window_size_ptr,
int32_t *recv_reduction_ptr,
int32_t *delta_ptr) {
int32_t recv_reduction_delta;
int32_t delta;
delta = *delta_ptr;
assert(delta >= 0);
/* The delta size is strictly more than received bytes. Increase
local_window_size by that difference |delta|. */
if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
return NGHTTP2_ERR_FLOW_CONTROL;
}
*local_window_size_ptr += delta;
/* If there is recv_reduction due to earlier window_size
reduction, we have to adjust it too. */
recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
*recv_reduction_ptr -= recv_reduction_delta;
*recv_window_size_ptr += recv_reduction_delta;
/* recv_reduction_delta must be paid from *delta_ptr, since it was
added in window size reduction (see below). */
*delta_ptr -= recv_reduction_delta;
return 0;
}
int nghttp2_should_send_window_update(int32_t local_window_size,
int32_t recv_window_size) {
return recv_window_size > 0 && recv_window_size >= local_window_size / 2;
@@ -306,58 +338,70 @@ const char *nghttp2_strerror(int error_code) {
/* Generated by gennmchartbl.py */
static int VALID_HD_NAME_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, 0 /* , */,
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, 0 /* @ */,
0 /* A */, 0 /* B */, 0 /* C */, 0 /* D */, 0 /* E */,
0 /* F */, 0 /* G */, 0 /* H */, 0 /* I */, 0 /* J */,
0 /* K */, 0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */, 0 /* T */,
0 /* U */, 0 /* V */, 0 /* W */, 0 /* X */, 0 /* Y */,
0 /* Z */, 0 /* [ */, 0 /* \ */, 0 /* ] */, 1 /* ^ */,
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 1 /* | */,
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
0 /* 0xff */
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */,
0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */,
0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */,
0 /* @ */, 0 /* A */, 0 /* B */, 0 /* C */,
0 /* D */, 0 /* E */, 0 /* F */, 0 /* G */,
0 /* H */, 0 /* I */, 0 /* J */, 0 /* K */,
0 /* L */, 0 /* M */, 0 /* N */, 0 /* O */,
0 /* P */, 0 /* Q */, 0 /* R */, 0 /* S */,
0 /* T */, 0 /* U */, 0 /* V */, 0 /* W */,
0 /* X */, 0 /* Y */, 0 /* Z */, 0 /* [ */,
0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
};
int nghttp2_check_header_name(const uint8_t *name, size_t len) {
@@ -382,58 +426,70 @@ int nghttp2_check_header_name(const uint8_t *name, size_t len) {
/* Generated by genvchartbl.py */
static int VALID_HD_VALUE_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 1 /* HT */,
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
0 /* RS */, 0 /* US */, 1 /* SPC */, 1 /* ! */, 1 /* " */,
1 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
1 /* - */, 1 /* . */, 1 /* / */, 1 /* 0 */, 1 /* 1 */,
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, 1 /* @ */,
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
1 /* Z */, 1 /* [ */, 1 /* \ */, 1 /* ] */, 1 /* ^ */,
1 /* _ */, 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, 1 /* | */,
1 /* } */, 1 /* ~ */, 0 /* DEL */, 1 /* 0x80 */, 1 /* 0x81 */,
1 /* 0x82 */, 1 /* 0x83 */, 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */,
1 /* 0x87 */, 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, 1 /* 0x90 */,
1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, 1 /* 0x94 */, 1 /* 0x95 */,
1 /* 0x96 */, 1 /* 0x97 */, 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */,
1 /* 0x9b */, 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, 1 /* 0xa4 */,
1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, 1 /* 0xa8 */, 1 /* 0xa9 */,
1 /* 0xaa */, 1 /* 0xab */, 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */,
1 /* 0xaf */, 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, 1 /* 0xb8 */,
1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, 1 /* 0xbc */, 1 /* 0xbd */,
1 /* 0xbe */, 1 /* 0xbf */, 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */,
1 /* 0xc3 */, 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, 1 /* 0xcc */,
1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, 1 /* 0xd0 */, 1 /* 0xd1 */,
1 /* 0xd2 */, 1 /* 0xd3 */, 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */,
1 /* 0xd7 */, 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, 1 /* 0xe0 */,
1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, 1 /* 0xe4 */, 1 /* 0xe5 */,
1 /* 0xe6 */, 1 /* 0xe7 */, 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */,
1 /* 0xeb */, 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, 1 /* 0xf4 */,
1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, 1 /* 0xf8 */, 1 /* 0xf9 */,
1 /* 0xfa */, 1 /* 0xfb */, 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */,
1 /* 0xff */
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 1 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
1 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */,
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */,
1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */,
1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */,
1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */,
1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */,
1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */,
1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */,
1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */,
1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */,
1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */,
1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */,
1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */,
1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */,
1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */,
1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */,
1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */,
1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */,
1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */,
1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */,
1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */,
1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */,
1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */,
1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */,
1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */,
1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */,
1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */,
1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */,
1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */,
1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */,
1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */,
1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */,
1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */,
1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */,
1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */,
1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */
};
int nghttp2_check_header_value(const uint8_t *value, size_t len) {

View File

@@ -89,6 +89,22 @@ int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
int32_t *recv_reduction_ptr,
int32_t *delta_ptr);
/*
* This function works like nghttp2_adjust_local_window_size(). The
* difference is that this function assumes *delta_ptr >= 0, and
* *recv_window_size_ptr is not decreased by *delta_ptr.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_FLOW_CONTROL
* local_window_size overflow or gets negative.
*/
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
int32_t *recv_window_size_ptr,
int32_t *recv_reduction_ptr,
int32_t *delta_ptr);
/*
* Returns non-zero if the function decided that WINDOW_UPDATE should
* be sent.

View File

@@ -286,58 +286,70 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
/* Generated by genauthroitychartbl.py */
static char VALID_AUTHORITY_CHARS[] = {
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */,
0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, 0 /* BS */, 0 /* HT */,
0 /* LF */, 0 /* VT */, 0 /* FF */, 0 /* CR */, 0 /* SO */,
0 /* SI */, 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, 0 /* CAN */,
0 /* EM */, 0 /* SUB */, 0 /* ESC */, 0 /* FS */, 0 /* GS */,
0 /* RS */, 0 /* US */, 0 /* SPC */, 1 /* ! */, 0 /* " */,
0 /* # */, 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, 1 /* , */,
1 /* - */, 1 /* . */, 0 /* / */, 1 /* 0 */, 1 /* 1 */,
1 /* 2 */, 1 /* 3 */, 1 /* 4 */, 1 /* 5 */, 1 /* 6 */,
1 /* 7 */, 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */, 1 /* @ */,
1 /* A */, 1 /* B */, 1 /* C */, 1 /* D */, 1 /* E */,
1 /* F */, 1 /* G */, 1 /* H */, 1 /* I */, 1 /* J */,
1 /* K */, 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, 1 /* T */,
1 /* U */, 1 /* V */, 1 /* W */, 1 /* X */, 1 /* Y */,
1 /* Z */, 1 /* [ */, 0 /* \ */, 1 /* ] */, 0 /* ^ */,
1 /* _ */, 0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, 1 /* h */,
1 /* i */, 1 /* j */, 1 /* k */, 1 /* l */, 1 /* m */,
1 /* n */, 1 /* o */, 1 /* p */, 1 /* q */, 1 /* r */,
1 /* s */, 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, 0 /* | */,
0 /* } */, 1 /* ~ */, 0 /* DEL */, 0 /* 0x80 */, 0 /* 0x81 */,
0 /* 0x82 */, 0 /* 0x83 */, 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */,
0 /* 0x87 */, 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, 0 /* 0x90 */,
0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, 0 /* 0x94 */, 0 /* 0x95 */,
0 /* 0x96 */, 0 /* 0x97 */, 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */,
0 /* 0x9b */, 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, 0 /* 0xa4 */,
0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, 0 /* 0xa8 */, 0 /* 0xa9 */,
0 /* 0xaa */, 0 /* 0xab */, 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */,
0 /* 0xaf */, 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, 0 /* 0xb8 */,
0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, 0 /* 0xbc */, 0 /* 0xbd */,
0 /* 0xbe */, 0 /* 0xbf */, 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */,
0 /* 0xc3 */, 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, 0 /* 0xcc */,
0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, 0 /* 0xd0 */, 0 /* 0xd1 */,
0 /* 0xd2 */, 0 /* 0xd3 */, 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */,
0 /* 0xd7 */, 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, 0 /* 0xe0 */,
0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, 0 /* 0xe4 */, 0 /* 0xe5 */,
0 /* 0xe6 */, 0 /* 0xe7 */, 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */,
0 /* 0xeb */, 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, 0 /* 0xf4 */,
0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, 0 /* 0xf8 */, 0 /* 0xf9 */,
0 /* 0xfa */, 0 /* 0xfb */, 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */,
0 /* 0xff */
0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */,
0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */,
0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */,
0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */,
0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */,
0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */,
0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */,
0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */,
0 /* SPC */, 1 /* ! */, 0 /* " */, 0 /* # */,
1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */,
1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */,
1 /* , */, 1 /* - */, 1 /* . */, 0 /* / */,
1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */,
1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */,
1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */,
0 /* < */, 1 /* = */, 0 /* > */, 0 /* ? */,
1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */,
1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */,
1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */,
1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */,
1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */,
1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */,
1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */,
0 /* \ */, 1 /* ] */, 0 /* ^ */, 1 /* _ */,
0 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */,
1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */,
1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */,
1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */,
1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */,
1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */,
1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */,
0 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */,
0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */,
0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */,
0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */,
0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */,
0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */,
0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */,
0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */,
0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */,
0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */,
0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */,
0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */,
0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */,
0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */,
0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */,
0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */,
0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */,
0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */,
0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */,
0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */,
0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */,
0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */,
0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */,
0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */,
0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */,
0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */,
0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */,
0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */,
0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */,
0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */,
0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */,
0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */,
0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */
};
static int check_authority(const uint8_t *value, size_t len) {

View File

@@ -29,15 +29,9 @@
#include <config.h>
#endif /* HAVE_CONFIG_H */
/* Macros, types and constants for internal use */
#include <nghttp2/nghttp2.h>
#ifdef DEBUGBUILD
#define DEBUGF(x) x
#else
#define DEBUGF(x) \
do { \
} while (0)
#endif
/* Macros, types and constants for internal use */
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);

View File

@@ -170,20 +170,18 @@ nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) {
int nghttp2_map_remove(nghttp2_map *map, key_type key) {
uint32_t h;
nghttp2_map_entry *entry, *prev;
nghttp2_map_entry **dst;
h = hash(key, map->tablelen);
prev = NULL;
for (entry = map->table[h]; entry; entry = entry->next) {
if (entry->key == key) {
if (prev == NULL) {
map->table[h] = entry->next;
} else {
prev->next = entry->next;
}
--map->size;
return 0;
for (dst = &map->table[h]; *dst; dst = &(*dst)->next) {
if ((*dst)->key != key) {
continue;
}
prev = entry;
*dst = (*dst)->next;
--map->size;
return 0;
}
return NGHTTP2_ERR_INVALID_ARGUMENT;
}

View File

@@ -52,8 +52,8 @@ void nghttp2_mem_free(nghttp2_mem *mem, void *ptr) {
mem->free(ptr, mem->mem_user_data);
}
void nghttp2_mem_free2(nghttp2_free free, void *ptr, void *mem_user_data) {
free(ptr, mem_user_data);
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data) {
free_func(ptr, mem_user_data);
}
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) {

View File

@@ -38,7 +38,7 @@ nghttp2_mem *nghttp2_mem_default(void);
|mem|. */
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
void nghttp2_mem_free2(nghttp2_free free, void *ptr, void *mem_user_data);
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);

View File

@@ -30,7 +30,7 @@ static int select_next_protocol(unsigned char **out, unsigned char *outlen,
const unsigned char *in, unsigned int inlen,
const char *key, unsigned int keylen) {
unsigned int i;
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in [i] + 1)) {
for (i = 0; i + keylen <= inlen; i += (unsigned int)(in[i] + 1)) {
if (memcmp(&in[i], key, keylen) == 0) {
*out = (unsigned char *)&in[i + 1];
*outlen = in[i];

View File

@@ -24,6 +24,8 @@
*/
#include "nghttp2_option.h"
#include "nghttp2_session.h"
int nghttp2_option_new(nghttp2_option **option_ptr) {
*option_ptr = calloc(1, sizeof(nghttp2_option));
@@ -63,6 +65,10 @@ void nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option,
option->max_reserved_remote_streams = val;
}
static void set_ext_type(uint8_t *ext_types, uint8_t type) {
ext_types[type / 8] = (uint8_t)(ext_types[type / 8] | (1 << (type & 0x7)));
}
void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
uint8_t type) {
if (type < 10) {
@@ -70,11 +76,34 @@ void nghttp2_option_set_user_recv_extension_type(nghttp2_option *option,
}
option->opt_set_mask |= NGHTTP2_OPT_USER_RECV_EXT_TYPES;
option->user_recv_ext_types[type / 8] =
(uint8_t)(option->user_recv_ext_types[type / 8] | (1 << (type & 0x7)));
set_ext_type(option->user_recv_ext_types, type);
}
void nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option,
uint8_t type) {
switch (type) {
case NGHTTP2_ALTSVC:
option->opt_set_mask |= NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES;
option->builtin_recv_ext_types |= NGHTTP2_TYPEMASK_ALTSVC;
return;
default:
return;
}
}
void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val) {
option->opt_set_mask |= NGHTTP2_OPT_NO_AUTO_PING_ACK;
option->no_auto_ping_ack = val;
}
void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option,
size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH;
option->max_send_header_block_length = val;
}
void nghttp2_option_set_max_deflate_dynamic_table_size(nghttp2_option *option,
size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE;
option->max_deflate_dynamic_table_size = val;
}

View File

@@ -61,13 +61,24 @@ typedef enum {
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
} nghttp2_option_flag;
/**
* Struct to store option values for nghttp2_session.
*/
struct nghttp2_option {
/**
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
*/
size_t max_send_header_block_length;
/**
* NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE
*/
size_t max_deflate_dynamic_table_size;
/**
* Bitwise OR of nghttp2_option_flag to determine that which fields
* are specified.
@@ -81,6 +92,10 @@ struct nghttp2_option {
* NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS
*/
uint32_t max_reserved_remote_streams;
/**
* NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
*/
uint32_t builtin_recv_ext_types;
/**
* NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE
*/

View File

@@ -72,9 +72,25 @@ void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem) {
case NGHTTP2_WINDOW_UPDATE:
nghttp2_frame_window_update_free(&frame->window_update);
break;
default:
nghttp2_frame_extension_free(&frame->ext);
break;
default: {
nghttp2_ext_aux_data *aux_data;
aux_data = &item->aux_data.ext;
if (aux_data->builtin == 0) {
nghttp2_frame_extension_free(&frame->ext);
break;
}
switch (frame->hd.type) {
case NGHTTP2_ALTSVC:
nghttp2_frame_altsvc_free(&frame->ext, mem);
break;
default:
assert(0);
break;
}
}
}
}

View File

@@ -87,11 +87,19 @@ typedef struct {
uint8_t flags;
} nghttp2_goaway_aux_data;
/* struct used for extension frame */
typedef struct {
/* nonzero if this extension frame is serialized by library
function, instead of user-defined callbacks. */
uint8_t builtin;
} nghttp2_ext_aux_data;
/* Additional data which cannot be stored in nghttp2_frame struct */
typedef union {
nghttp2_data_aux_data data;
nghttp2_headers_aux_data headers;
nghttp2_goaway_aux_data goaway;
nghttp2_ext_aux_data ext;
} nghttp2_aux_data;
struct nghttp2_outbound_item;
@@ -99,6 +107,9 @@ typedef struct nghttp2_outbound_item nghttp2_outbound_item;
struct nghttp2_outbound_item {
nghttp2_frame frame;
/* Storage for extension frame payload. frame->ext.payload points
to this structure to avoid frequent memory allocation. */
nghttp2_ext_frame_payload ext_frame_payload;
nghttp2_aux_data aux_data;
/* The priority used in priority comparion. Smaller is served
ealier. For PING, SETTINGS and non-DATA frames (excluding

File diff suppressed because it is too large Load Diff

View File

@@ -54,6 +54,15 @@ typedef enum {
NGHTTP2_OPTMASK_NO_AUTO_PING_ACK = 1 << 3
} nghttp2_optmask;
/*
* bitmask for built-in type to enable the default handling for that
* type of the frame.
*/
typedef enum {
NGHTTP2_TYPEMASK_NONE = 0,
NGHTTP2_TYPEMASK_ALTSVC = 1 << 0
} nghttp2_typemask;
typedef enum {
NGHTTP2_OB_POP_ITEM,
NGHTTP2_OB_SEND_DATA,
@@ -88,6 +97,9 @@ typedef struct {
these frames in this number, it is considered suspicious. */
#define NGHTTP2_MAX_OBQ_FLOOD_ITEM 10000
/* The default value of maximum number of concurrent streams. */
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
/* Internal state when receiving incoming frame */
typedef enum {
/* Receiving frame header */
@@ -107,21 +119,20 @@ typedef enum {
NGHTTP2_IB_READ_DATA,
NGHTTP2_IB_IGN_DATA,
NGHTTP2_IB_IGN_ALL,
NGHTTP2_IB_READ_ALTSVC_PAYLOAD,
NGHTTP2_IB_READ_EXTENSION_PAYLOAD
} nghttp2_inbound_state;
#define NGHTTP2_INBOUND_NUM_IV 7
typedef struct {
nghttp2_frame frame;
/* Storage for extension frame payload. frame->ext.payload points
to this structure to avoid frequent memory allocation. */
nghttp2_ext_frame_payload ext_frame_payload;
/* The received SETTINGS entry. The protocol says that we only cares
about the defined settings ID. If unknown ID is received, it is
ignored. We use last entry to hold minimum header table size if
same settings are multiple times. */
nghttp2_settings_entry iv[NGHTTP2_INBOUND_NUM_IV];
/* The received SETTINGS entry. For the standard settings entries,
we only keep the last seen value. For
SETTINGS_HEADER_TABLE_SIZE, we also keep minimum value in the
last index. */
nghttp2_settings_entry *iv;
/* buffer pointers to small buffer, raw_sbuf */
nghttp2_buf sbuf;
/* buffer pointers to large buffer, raw_lbuf */
@@ -130,6 +141,8 @@ typedef struct {
uint8_t *raw_lbuf;
/* The number of entry filled in |iv| */
size_t niv;
/* The number of entries |iv| can store. */
size_t max_niv;
/* How many bytes we still need to receive for current frame */
size_t payloadleft;
/* padding length for the current frame */
@@ -246,6 +259,9 @@ struct nghttp2_session {
size_t nvbuflen;
/* Counter for detecting flooding in outbound queue */
size_t obq_flood_counter_;
/* The maximum length of header block to send. Calculated by the
same way as nghttp2_hd_deflate_bound() does. */
size_t max_send_header_block_length;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id;
/* The last stream ID this session initiated. For client session,
@@ -294,6 +310,9 @@ struct nghttp2_session {
/* Unacked local SETTINGS_MAX_CONCURRENT_STREAMS value. We use this
to refuse the incoming stream if it exceeds this value. */
uint32_t pending_local_max_concurrent_stream;
/* The bitwose OR of zero or more of nghttp2_typemask to indicate
that the default handling of extension frame is enabled. */
uint32_t builtin_recv_ext_types;
/* Unacked local ENABLE_PUSH value. We use this to refuse
PUSH_PROMISE before SETTINGS ACK is received. */
uint8_t pending_enable_push;
@@ -716,6 +735,19 @@ int nghttp2_session_on_goaway_received(nghttp2_session *session,
int nghttp2_session_on_window_update_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when ALTSVC is recieved, assuming |frame| is properly
* initialized.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_CALLBACK_FAILURE
* The callback function failed.
*/
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
nghttp2_frame *frame);
/*
* Called when DATA is received, assuming |frame| is properly
* initialized.

View File

@@ -29,6 +29,7 @@
#include "nghttp2_session.h"
#include "nghttp2_helper.h"
#include "nghttp2_debug.h"
/* Maximum distance between any two stream's cycle in the same
prirority queue. Imagine stream A's cycle is A, and stream B's
@@ -152,11 +153,11 @@ static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
stream_next_cycle(stream, dep_stream->descendant_last_cycle);
stream->seq = dep_stream->descendant_next_seq++;
DEBUGF(fprintf(stderr, "stream: stream=%d obq push cycle=%d\n",
stream->stream_id, stream->cycle));
DEBUGF("stream: stream=%d obq push cycle=%d\n", stream->stream_id,
stream->cycle);
DEBUGF(fprintf(stderr, "stream: push stream %d to stream %d\n",
stream->stream_id, dep_stream->stream_id));
DEBUGF("stream: push stream %d to stream %d\n", stream->stream_id,
dep_stream->stream_id);
rv = nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
if (rv != 0) {
@@ -183,8 +184,8 @@ static void stream_obq_remove(nghttp2_stream *stream) {
}
for (; dep_stream; stream = dep_stream, dep_stream = dep_stream->dep_prev) {
DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d\n",
stream->stream_id, dep_stream->stream_id));
DEBUGF("stream: remove stream %d from stream %d\n", stream->stream_id,
dep_stream->stream_id);
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
@@ -214,8 +215,8 @@ static int stream_obq_move(nghttp2_stream *dest, nghttp2_stream *src,
return 0;
}
DEBUGF(fprintf(stderr, "stream: remove stream %d from stream %d (move)\n",
stream->stream_id, src->stream_id));
DEBUGF("stream: remove stream %d from stream %d (move)\n", stream->stream_id,
src->stream_id);
nghttp2_pq_remove(&src->obq, &stream->pq_entry);
stream->queued = 0;
@@ -238,8 +239,8 @@ void nghttp2_stream_reschedule(nghttp2_stream *stream) {
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
stream->stream_id, stream->cycle));
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id,
stream->cycle);
dep_stream->last_writelen = stream->last_writelen;
}
@@ -298,8 +299,8 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_pq_push(&dep_stream->obq, &stream->pq_entry);
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
stream->stream_id, stream->cycle));
DEBUGF("stream: stream=%d obq resched cycle=%d\n", stream->stream_id,
stream->cycle);
}
static nghttp2_stream *stream_last_sib(nghttp2_stream *stream) {
@@ -481,8 +482,7 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
assert((stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) == 0);
assert(stream->item == NULL);
DEBUGF(fprintf(stderr, "stream: stream=%d attach item=%p\n",
stream->stream_id, item));
DEBUGF("stream: stream=%d attach item=%p\n", stream->stream_id, item);
stream->item = item;
@@ -500,8 +500,7 @@ int nghttp2_stream_attach_item(nghttp2_stream *stream,
}
int nghttp2_stream_detach_item(nghttp2_stream *stream) {
DEBUGF(fprintf(stderr, "stream: stream=%d detach item=%p\n",
stream->stream_id, stream->item));
DEBUGF("stream: stream=%d detach item=%p\n", stream->stream_id, stream->item);
stream->item = NULL;
stream->flags = (uint8_t)(stream->flags & ~NGHTTP2_STREAM_FLAG_DEFERRED_ALL);
@@ -512,8 +511,8 @@ int nghttp2_stream_detach_item(nghttp2_stream *stream) {
int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
assert(stream->item);
DEBUGF(fprintf(stderr, "stream: stream=%d defer item=%p cause=%02x\n",
stream->stream_id, stream->item, flags));
DEBUGF("stream: stream=%d defer item=%p cause=%02x\n", stream->stream_id,
stream->item, flags);
stream->flags |= flags;
@@ -523,8 +522,8 @@ int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
assert(stream->item);
DEBUGF(fprintf(stderr, "stream: stream=%d resume item=%p flags=%02x\n",
stream->stream_id, stream->item, flags));
DEBUGF("stream: stream=%d resume item=%p flags=%02x\n", stream->stream_id,
stream->item, flags);
stream->flags = (uint8_t)(stream->flags & ~flags);
@@ -593,9 +592,8 @@ int nghttp2_stream_dep_insert(nghttp2_stream *dep_stream,
nghttp2_stream *si;
int rv;
DEBUGF(fprintf(stderr,
"stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
DEBUGF("stream: dep_insert dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
dep_stream->stream_id, stream, stream->stream_id);
stream->sum_dep_weight = dep_stream->sum_dep_weight;
dep_stream->sum_dep_weight = stream->weight;
@@ -740,8 +738,8 @@ static void unlink_dep(nghttp2_stream *stream) {
void nghttp2_stream_dep_add(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
DEBUGF(fprintf(stderr, "stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
DEBUGF("stream: dep_add dep_stream(%p)=%d, stream(%p)=%d\n", dep_stream,
dep_stream->stream_id, stream, stream->stream_id);
dep_stream->sum_dep_weight += stream->weight;
@@ -759,8 +757,7 @@ int nghttp2_stream_dep_remove(nghttp2_stream *stream) {
int32_t sum_dep_weight_delta;
int rv;
DEBUGF(fprintf(stderr, "stream: dep_remove stream(%p)=%d\n", stream,
stream->stream_id));
DEBUGF("stream: dep_remove stream(%p)=%d\n", stream, stream->stream_id);
/* Distribute weight of |stream| to direct descendants */
sum_dep_weight_delta = -stream->weight;
@@ -813,9 +810,8 @@ int nghttp2_stream_dep_insert_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *si;
int rv;
DEBUGF(fprintf(stderr, "stream: dep_insert_subtree dep_stream(%p)=%d "
"stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
DEBUGF("stream: dep_insert_subtree dep_stream(%p)=%d stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
stream->sum_dep_weight += dep_stream->sum_dep_weight;
dep_stream->sum_dep_weight = stream->weight;
@@ -862,9 +858,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
nghttp2_stream *stream) {
int rv;
DEBUGF(fprintf(stderr, "stream: dep_add_subtree dep_stream(%p)=%d "
"stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id));
DEBUGF("stream: dep_add_subtree dep_stream(%p)=%d stream(%p)=%d\n",
dep_stream, dep_stream->stream_id, stream, stream->stream_id);
dep_stream->sum_dep_weight += stream->weight;
@@ -889,8 +884,8 @@ int nghttp2_stream_dep_add_subtree(nghttp2_stream *dep_stream,
void nghttp2_stream_dep_remove_subtree(nghttp2_stream *stream) {
nghttp2_stream *next, *dep_prev;
DEBUGF(fprintf(stderr, "stream: dep_remove_subtree stream(%p)=%d\n", stream,
stream->stream_id));
DEBUGF("stream: dep_remove_subtree stream(%p)=%d\n", stream,
stream->stream_id);
assert(stream->dep_prev);

View File

@@ -214,7 +214,7 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
const uint8_t *opaque_data) {
flags &= NGHTTP2_FLAG_ACK;
return nghttp2_session_add_ping(session, NGHTTP2_FLAG_NONE, opaque_data);
return nghttp2_session_add_ping(session, flags, opaque_data);
}
int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags _U_,
@@ -410,6 +410,159 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
return 0;
}
int nghttp2_session_set_local_window_size(nghttp2_session *session,
uint8_t flags, int32_t stream_id,
int32_t window_size) {
int32_t window_size_increment;
nghttp2_stream *stream;
int rv;
if (window_size < 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
flags = 0;
if (stream_id == 0) {
window_size_increment = window_size - session->local_window_size;
if (window_size_increment == 0) {
return 0;
}
if (window_size_increment < 0) {
return nghttp2_adjust_local_window_size(
&session->local_window_size, &session->recv_window_size,
&session->recv_reduction, &window_size_increment);
}
rv = nghttp2_increase_local_window_size(
&session->local_window_size, &session->recv_window_size,
&session->recv_reduction, &window_size_increment);
if (rv != 0) {
return rv;
}
} else {
stream = nghttp2_session_get_stream(session, stream_id);
if (stream == NULL) {
return 0;
}
window_size_increment = window_size - stream->local_window_size;
if (window_size_increment == 0) {
return 0;
}
if (window_size_increment < 0) {
return nghttp2_adjust_local_window_size(
&stream->local_window_size, &stream->recv_window_size,
&stream->recv_reduction, &window_size_increment);
}
rv = nghttp2_increase_local_window_size(
&stream->local_window_size, &stream->recv_window_size,
&stream->recv_reduction, &window_size_increment);
if (rv != 0) {
return rv;
}
}
if (window_size_increment > 0) {
return nghttp2_session_add_window_update(session, flags, stream_id,
window_size_increment);
}
return 0;
}
int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags _U_,
int32_t stream_id, const uint8_t *origin,
size_t origin_len, const uint8_t *field_value,
size_t field_value_len) {
nghttp2_mem *mem;
uint8_t *buf, *p;
uint8_t *origin_copy;
uint8_t *field_value_copy;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
nghttp2_ext_altsvc *altsvc;
int rv;
mem = &session->mem;
if (!session->server) {
return NGHTTP2_ERR_INVALID_STATE;
}
if (2 + origin_len + field_value_len > NGHTTP2_MAX_PAYLOADLEN) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (stream_id == 0) {
if (origin_len == 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
} else if (origin_len != 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
buf = nghttp2_mem_malloc(mem, origin_len + field_value_len + 2);
if (buf == NULL) {
return NGHTTP2_ERR_NOMEM;
}
p = buf;
origin_copy = p;
if (origin_len) {
p = nghttp2_cpymem(p, origin, origin_len);
}
*p++ = '\0';
field_value_copy = p;
if (field_value_len) {
p = nghttp2_cpymem(p, field_value, field_value_len);
}
*p++ = '\0';
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) {
rv = NGHTTP2_ERR_NOMEM;
goto fail_item_malloc;
}
nghttp2_outbound_item_init(item);
item->aux_data.ext.builtin = 1;
altsvc = &item->ext_frame_payload.altsvc;
frame = &item->frame;
frame->ext.payload = altsvc;
nghttp2_frame_altsvc_init(&frame->ext, stream_id, origin_copy, origin_len,
field_value_copy, field_value_len);
rv = nghttp2_session_add_item(session, item);
if (rv != 0) {
nghttp2_frame_altsvc_free(&frame->ext, mem);
nghttp2_mem_free(mem, item);
return rv;
}
return 0;
fail_item_malloc:
free(buf);
return rv;
}
static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
const nghttp2_data_provider *data_prd) {
uint8_t flags = NGHTTP2_FLAG_NONE;

View File

@@ -12,7 +12,7 @@ if [ -z "$CLANGFORMATDIFF" ]; then
CLANGFORMATDIFF=clang-format-diff.py
fi
errors=`git diff-index --cached --diff-filter=ACMR -p HEAD -- | $CLANGFORMATDIFF -p1`
errors=`git diff-index --cached --diff-filter=ACMR -p HEAD lib src examples tests | $CLANGFORMATDIFF -p1`
if [ -n "$errors" ]; then
echo "$errors"

View File

@@ -314,9 +314,10 @@ cdef extern from 'nghttp2/nghttp2.h':
int nghttp2_hd_inflate_change_table_size(nghttp2_hd_inflater *inflater,
size_t hd_table_bufsize_max)
ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
uint8_t *input, size_t inlen, int in_final)
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
const uint8_t *input, size_t inlen,
int in_final)
int nghttp2_hd_inflate_end_headers(nghttp2_hd_inflater *inflater)

View File

@@ -191,9 +191,9 @@ cdef class HDInflater:
res = []
while True:
inflate_flags = 0
rv = cnghttp2.nghttp2_hd_inflate_hd(self._inflater, &nv,
&inflate_flags,
buf, buflen, 1)
rv = cnghttp2.nghttp2_hd_inflate_hd2(self._inflater, &nv,
&inflate_flags,
buf, buflen, 1)
if rv < 0:
raise Exception(_strerror(rv))
buf += rv
@@ -260,6 +260,7 @@ try:
import email.utils
import datetime
import time
import ssl as tls
from urllib.parse import urlparse
except ImportError:
asyncio = None
@@ -294,6 +295,25 @@ def wrap_body(body):
# string and flag.
return body
def negotiated_protocol(ssl_obj):
protocol = ssl_obj.selected_alpn_protocol()
if protocol:
logging.info('alpn, protocol:%s', protocol)
return protocol
protocol = ssl_obj.selected_npn_protocol()
if protocol:
logging.info('npn, protocol:%s', protocol)
return protocol
return None
def set_application_protocol(ssl_ctx):
app_protos = [cnghttp2.NGHTTP2_PROTO_VERSION_ID.decode('utf-8')]
ssl_ctx.set_npn_protocols(app_protos)
if tls.HAS_ALPN:
ssl_ctx.set_alpn_protocols(app_protos)
cdef _get_stream_user_data(cnghttp2.nghttp2_session *session,
int32_t stream_id):
cdef void *stream_user_data
@@ -902,6 +922,8 @@ cdef class _HTTP2SessionCore(_HTTP2SessionCoreBase):
return promised_handler
def connection_lost(self):
self._stop_settings_timer()
for handler in self.handlers:
handler.on_close(cnghttp2.NGHTTP2_INTERNAL_ERROR)
self.handlers = set()
@@ -1284,8 +1306,8 @@ if asyncio:
logging.info('failed to set tcp-nodelay: %s', str(e))
ssl_ctx = self.transport.get_extra_info('sslcontext')
if ssl_ctx:
protocol = sock.selected_npn_protocol()
logging.info('npn, protocol:%s', protocol)
ssl_obj = self.transport.get_extra_info('ssl_object')
protocol = negotiated_protocol(ssl_obj)
if protocol is None or protocol.encode('utf-8') != \
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
self.transport.abort()
@@ -1346,8 +1368,7 @@ if asyncio:
self.loop = asyncio.get_event_loop()
if ssl:
ssl.set_npn_protocols([cnghttp2.NGHTTP2_PROTO_VERSION_ID\
.decode('utf-8')])
set_application_protocol(ssl)
coro = self.loop.create_server(session_factory,
host=address[0], port=address[1],
@@ -1516,8 +1537,8 @@ if asyncio:
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
ssl_ctx = self.transport.get_extra_info('sslcontext')
if ssl_ctx:
protocol = sock.selected_npn_protocol()
logging.info('npn, protocol:%s', protocol)
ssl_obj = self.transport.get_extra_info('ssl_object')
protocol = negotiated_protocol(ssl_obj)
if protocol is None or protocol.encode('utf-8') != \
cnghttp2.NGHTTP2_PROTO_VERSION_ID:
self.transport.abort()
@@ -1594,8 +1615,7 @@ if asyncio:
return self.session
if ssl:
ssl.set_npn_protocols([cnghttp2.NGHTTP2_PROTO_VERSION_ID\
.decode('utf-8')])
set_application_protocol(ssl)
self.loop = loop
if not self.loop:

View File

@@ -1,5 +1,6 @@
#!/bin/sh -e
autoreconf -i
git submodule update --init
./configure --with-mruby --with-neverbleed --enable-asio-lib
make -j3 distcheck DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-neverbleed --enable-asio-lib --enable-werror"
make -j8 distcheck DISTCHECK_CONFIGURE_FLAGS="--with-mruby --with-neverbleed --enable-asio-lib --enable-werror"

View File

@@ -100,6 +100,7 @@ if(ENABLE_APP)
shrpx_worker.cc
shrpx_log_config.cc
shrpx_connect_blocker.cc
shrpx_live_check.cc
shrpx_downstream_connection_pool.cc
shrpx_rate_limit.cc
shrpx_connection.cc
@@ -108,6 +109,10 @@ if(ENABLE_APP)
shrpx_worker_process.cc
shrpx_signal.cc
shrpx_router.cc
shrpx_api_downstream_connection.cc
shrpx_health_monitor_downstream_connection.cc
shrpx_exec.cc
xsi_strerror.c
)
if(HAVE_SPDYLAY)
list(APPEND NGHTTPX_SRCS
@@ -147,6 +152,7 @@ if(ENABLE_APP)
shrpx_config_test.cc
shrpx_worker_test.cc
shrpx_http_test.cc
shrpx_router_test.cc
http2_test.cc
util_test.cc
nghttp2_gzip_test.c
@@ -162,7 +168,7 @@ if(ENABLE_APP)
)
target_include_directories(nghttpx-unittest PRIVATE ${CUNIT_INCLUDE_DIRS})
target_compile_definitions(nghttpx-unittest
PRIVATE "-DNGHTTP2_TESTS_DIR=\"${CMAKE_SOURCE_DIR}/tests\""
PRIVATE "-DNGHTTP2_SRC_DIR=\"${CMAKE_SOURCE_DIR}/src\""
)
target_link_libraries(nghttpx-unittest nghttpx_static ${CUNIT_LIBRARIES})
if(HAVE_MRUBY)

View File

@@ -96,6 +96,7 @@ Config::Config()
num_worker(1),
max_concurrent_streams(100),
header_table_size(-1),
encoder_header_table_size(-1),
window_bits(-1),
connection_window_bits(-1),
port(0),
@@ -231,6 +232,7 @@ public:
config_(config),
ssl_ctx_(ssl_ctx),
callbacks_(nullptr),
option_(nullptr),
next_session_id_(1),
tstamp_cached_(ev_now(loop)),
cached_date_(util::http_date(tstamp_cached_)) {
@@ -238,6 +240,13 @@ public:
fill_callback(callbacks_, config_);
nghttp2_option_new(&option_);
if (config_->encoder_header_table_size != -1) {
nghttp2_option_set_max_deflate_dynamic_table_size(
option_, config_->encoder_header_table_size);
}
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
release_fd_timer_.data = this;
}
@@ -246,6 +255,7 @@ public:
for (auto handler : handlers_) {
delete handler;
}
nghttp2_option_del(option_);
nghttp2_session_callbacks_del(callbacks_);
}
void add_handler(Http2Handler *handler) { handlers_.insert(handler); }
@@ -283,6 +293,7 @@ public:
return session_id;
}
const nghttp2_session_callbacks *get_callbacks() const { return callbacks_; }
const nghttp2_option *get_option() const { return option_; }
void accept_connection(int fd) {
util::make_socket_nodelay(fd);
SSL *ssl = nullptr;
@@ -408,6 +419,7 @@ private:
const Config *config_;
SSL_CTX *ssl_ctx_;
nghttp2_session_callbacks *callbacks_;
nghttp2_option *option_;
ev_timer release_fd_timer_;
int64_t next_session_id_;
ev_tstamp tstamp_cached_;
@@ -825,7 +837,8 @@ int Http2Handler::on_write() { return write_(*this); }
int Http2Handler::connection_made() {
int r;
r = nghttp2_session_server_new(&session_, sessions_->get_callbacks(), this);
r = nghttp2_session_server_new2(&session_, sessions_->get_callbacks(), this,
sessions_->get_option());
if (r != 0) {
return r;
@@ -856,10 +869,9 @@ int Http2Handler::connection_made() {
}
if (config->connection_window_bits != -1) {
r = nghttp2_submit_window_update(
r = nghttp2_session_set_local_window_size(
session_, NGHTTP2_FLAG_NONE, 0,
(1 << config->connection_window_bits) - 1 -
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE);
(1 << config->connection_window_bits) - 1);
if (r != 0) {
return r;
}
@@ -1121,8 +1133,12 @@ void prepare_status_response(Stream *stream, Http2Handler *hd, int status) {
data_prd.read_callback = file_read_callback;
HeaderRefs headers;
headers.reserve(2);
headers.emplace_back(StringRef::from_lit("content-type"),
StringRef::from_lit("text/html; charset=UTF-8"));
headers.emplace_back(
StringRef::from_lit("content-length"),
util::make_string_ref_uint(stream->balloc, file_ent->length));
hd->submit_response(StringRef{status_page->status}, stream->stream_id,
headers, &data_prd);
}
@@ -1285,7 +1301,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
p = std::copy(std::begin(htdocs), std::end(htdocs), p);
p = std::copy(std::begin(path), std::end(path), p);
if (trailing_slash) {
p = std::copy(std::begin(DEFAULT_HTML), std::end(DEFAULT_HTML), p);
std::copy(std::begin(DEFAULT_HTML), std::end(DEFAULT_HTML), p);
}
}
@@ -1793,6 +1809,16 @@ void run_worker(Worker *worker) {
}
} // namespace
namespace {
int get_ev_loop_flags() {
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
return ev_recommended_backends() | EVBACKEND_KQUEUE;
}
return 0;
}
} // namespace
class AcceptHandler {
public:
AcceptHandler(HttpServer *sv, Sessions *sessions, const Config *config)
@@ -1805,7 +1831,7 @@ public:
std::cerr << "spawning thread #" << i << std::endl;
}
auto worker = make_unique<Worker>();
auto loop = ev_loop_new(0);
auto loop = ev_loop_new(get_ev_loop_flags());
worker->sessions =
make_unique<Sessions>(sv, loop, config_, sessions_->get_ssl_ctx());
ev_async_init(&worker->w, worker_acceptcb);
@@ -2056,7 +2082,7 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
std::cout << "[ALPN] client offers:" << std::endl;
}
if (config->verbose) {
for (unsigned int i = 0; i < inlen; i += in [i] + 1) {
for (unsigned int i = 0; i < inlen; i += in[i] + 1) {
std::cout << " * ";
std::cout.write(reinterpret_cast<const char *>(&in[i + 1]), in[i]);
std::cout << std::endl;

View File

@@ -69,6 +69,7 @@ struct Config {
size_t num_worker;
size_t max_concurrent_streams;
ssize_t header_table_size;
ssize_t encoder_header_table_size;
int window_bits;
int connection_window_bits;
uint16_t port;

View File

@@ -22,7 +22,10 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = includes
EXTRA_DIST = CMakeLists.txt
EXTRA_DIST = \
CMakeLists.txt \
test.example.com.pem \
test.nghttp2.org.pem
bin_PROGRAMS =
check_PROGRAMS =
@@ -120,6 +123,7 @@ NGHTTPX_SRCS = \
shrpx_worker.cc shrpx_worker.h \
shrpx_log_config.cc shrpx_log_config.h \
shrpx_connect_blocker.cc shrpx_connect_blocker.h \
shrpx_live_check.cc shrpx_live_check.h \
shrpx_downstream_connection_pool.cc shrpx_downstream_connection_pool.h \
shrpx_rate_limit.cc shrpx_rate_limit.h \
shrpx_connection.cc shrpx_connection.h \
@@ -131,7 +135,12 @@ NGHTTPX_SRCS = \
shrpx_process.h \
shrpx_signal.cc shrpx_signal.h \
shrpx_router.cc shrpx_router.h \
buffer.h memchunk.h template.h allocator.h
shrpx_api_downstream_connection.cc shrpx_api_downstream_connection.h \
shrpx_health_monitor_downstream_connection.cc \
shrpx_health_monitor_downstream_connection.h \
shrpx_exec.cc shrpx_exec.h \
buffer.h memchunk.h template.h allocator.h \
xsi_strerror.c xsi_strerror.h
if HAVE_SPDYLAY
NGHTTPX_SRCS += shrpx_spdy_upstream.cc shrpx_spdy_upstream.h
@@ -173,6 +182,7 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
shrpx_config_test.cc shrpx_config_test.h \
shrpx_worker_test.cc shrpx_worker_test.h \
shrpx_http_test.cc shrpx_http_test.h \
shrpx_router_test.cc shrpx_router_test.h \
http2_test.cc http2_test.h \
util_test.cc util_test.h \
nghttp2_gzip_test.c nghttp2_gzip_test.h \
@@ -182,7 +192,7 @@ nghttpx_unittest_SOURCES = shrpx-unittest.cc \
template_test.cc template_test.h \
base64_test.cc base64_test.h
nghttpx_unittest_CPPFLAGS = ${AM_CPPFLAGS} \
-DNGHTTP2_TESTS_DIR=\"$(top_srcdir)/tests\"
-DNGHTTP2_SRC_DIR=\"$(top_srcdir)/src\"
nghttpx_unittest_LDADD = libnghttpx.a ${LDADD} @CUNIT_LIBS@ @TESTLDADD@
if HAVE_MRUBY
@@ -225,6 +235,7 @@ lib_LTLIBRARIES = libnghttp2_asio.la
libnghttp2_asio_la_SOURCES = \
util.cc util.h http2.cc http2.h \
ssl.cc ssl.h \
ssl_compat.h \
timegm.c timegm.h \
asio_common.cc asio_common.h \
asio_io_service_pool.cc asio_io_service_pool.h \

View File

@@ -29,6 +29,8 @@
#include <sys/uio.h>
#include <cassert>
#include "template.h"
namespace nghttp2 {
@@ -45,29 +47,58 @@ struct MemBlock {
// BlockAllocator allocates memory block with given size at once, and
// cuts the region from it when allocation is requested. If the
// requested size is larger than given threshold, it will be allocated
// in a distinct buffer on demand.
// requested size is larger than given threshold (plus small internal
// overhead), it will be allocated in a distinct buffer on demand.
// The |isolation_threshold| must be less than or equal to
// |block_size|.
struct BlockAllocator {
BlockAllocator(size_t block_size, size_t isolation_threshold)
: retain(nullptr),
head(nullptr),
block_size(block_size),
isolation_threshold(std::min(block_size, isolation_threshold)) {}
isolation_threshold(std::min(block_size, isolation_threshold)) {
assert(isolation_threshold <= block_size);
}
~BlockAllocator() {
~BlockAllocator() { reset(); }
BlockAllocator(BlockAllocator &&other) noexcept
: retain(other.retain),
head(other.head),
block_size(other.block_size),
isolation_threshold(other.isolation_threshold) {
other.retain = nullptr;
other.head = nullptr;
}
BlockAllocator &operator=(BlockAllocator &&other) noexcept {
reset();
retain = other.retain;
head = other.head;
block_size = other.block_size;
isolation_threshold = other.isolation_threshold;
other.retain = nullptr;
other.head = nullptr;
return *this;
}
BlockAllocator(const BlockAllocator &) = delete;
BlockAllocator &operator=(const BlockAllocator &) = delete;
void reset() {
for (auto mb = retain; mb;) {
auto next = mb->next;
delete[] reinterpret_cast<uint8_t *>(mb);
mb = next;
}
retain = nullptr;
head = nullptr;
}
BlockAllocator(BlockAllocator &&) = default;
BlockAllocator &operator=(BlockAllocator &&) = default;
BlockAllocator(const BlockAllocator &) = delete;
BlockAllocator &operator=(const BlockAllocator &) = delete;
MemBlock *alloc_mem_block(size_t size) {
auto block = new uint8_t[sizeof(MemBlock) + size];
auto mb = reinterpret_cast<MemBlock *>(block);
@@ -80,20 +111,60 @@ struct BlockAllocator {
}
void *alloc(size_t size) {
if (size >= isolation_threshold) {
auto mb = alloc_mem_block(size);
if (size + sizeof(size_t) >= isolation_threshold) {
auto len = std::max(static_cast<size_t>(16), size);
// We will store the allocated size in size_t field.
auto mb = alloc_mem_block(len + sizeof(size_t));
auto sp = reinterpret_cast<size_t *>(mb->begin);
*sp = len;
mb->last = mb->end;
return mb->begin;
return mb->begin + sizeof(size_t);
}
if (!head || head->end - head->last < static_cast<ssize_t>(size)) {
if (!head ||
head->end - head->last < static_cast<ssize_t>(size + sizeof(size_t))) {
head = alloc_mem_block(block_size);
}
auto res = head->last;
// We will store the allocated size in size_t field.
auto res = head->last + sizeof(size_t);
auto sp = reinterpret_cast<size_t *>(head->last);
*sp = size;
head->last = reinterpret_cast<uint8_t *>(
(reinterpret_cast<intptr_t>(head->last + size) + 0xf) & ~0xf);
(reinterpret_cast<intptr_t>(res + size) + 0xf) & ~0xf);
return res;
}
// Returns allocated size for memory pointed by |ptr|. We assume
// that |ptr| was returned from alloc() or realloc().
size_t get_alloc_length(void *ptr) {
return *reinterpret_cast<size_t *>(static_cast<uint8_t *>(ptr) -
sizeof(size_t));
}
// Allocates memory of at least |size| bytes. If |ptr| is nullptr,
// this is equivalent to alloc(size). If |ptr| is not nullptr,
// obtain the allocated size for |ptr|, assuming that |ptr| was
// returned from alloc() or realloc(). If the allocated size is
// greater than or equal to size, |ptr| is returned. Otherwise,
// allocates at least |size| bytes of memory, and the original
// content pointed by |ptr| is copied to the newly allocated memory.
void *realloc(void *ptr, size_t size) {
if (!ptr) {
return alloc(size);
}
auto alloclen = get_alloc_length(ptr);
auto p = reinterpret_cast<uint8_t *>(ptr);
if (size <= alloclen) {
return ptr;
}
auto nalloclen = std::max(size + 1, alloclen * 2);
auto res = alloc(nalloclen);
std::copy_n(p, alloclen, static_cast<uint8_t *>(res));
return res;
}
@@ -161,6 +232,30 @@ StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) {
return StringRef{dst, len};
}
// Returns the string which is the concatenation of |value| and |args|
// in the given order. The resulting string will be NULL-terminated.
// This function assumes that the pointer value value.c_str() was
// obtained from alloc.alloc() or alloc.realloc(), and attempts to use
// unused memory region by using alloc.realloc(). If value is empty,
// then just call concat_string_ref().
template <typename BlockAllocator, typename... Args>
StringRef realloc_concat_string_ref(BlockAllocator &alloc,
const StringRef &value, Args &&... args) {
if (value.empty()) {
return concat_string_ref(alloc, std::forward<Args>(args)...);
}
auto len =
value.size() + concat_string_ref_count(0, std::forward<Args>(args)...);
auto dst = static_cast<uint8_t *>(
alloc.realloc(const_cast<uint8_t *>(value.byte()), len + 1));
auto p = dst + value.size();
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
*p = '\0';
return StringRef{dst, len};
}
struct ByteRef {
// The pointer to the beginning of the buffer.
uint8_t *base;

View File

@@ -104,6 +104,8 @@ std::string strframetype(uint8_t type) {
return "GOAWAY";
case NGHTTP2_WINDOW_UPDATE:
return "WINDOW_UPDATE";
case NGHTTP2_ALTSVC:
return "ALTSVC";
}
std::string s = "extension(0x";
@@ -332,13 +334,22 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
frame->goaway.error_code,
static_cast<unsigned int>(frame->goaway.opaque_data_len),
util::ascii_dump(frame->goaway.opaque_data,
frame->goaway.opaque_data_len).c_str());
frame->goaway.opaque_data_len)
.c_str());
break;
case NGHTTP2_WINDOW_UPDATE:
print_frame_attr_indent();
fprintf(outfile, "(window_size_increment=%d)\n",
frame->window_update.window_size_increment);
break;
case NGHTTP2_ALTSVC: {
auto altsvc = static_cast<nghttp2_ext_altsvc *>(frame->ext.payload);
print_frame_attr_indent();
fprintf(outfile, "(origin=[%.*s], altsvc_field_value=[%.*s])\n",
static_cast<int>(altsvc->origin_len), altsvc->origin,
static_cast<int>(altsvc->field_value_len), altsvc->field_value);
break;
}
default:
break;
}

View File

@@ -373,9 +373,8 @@ bool session_impl::setup_session() {
{NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, window_size}}};
nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, iv.data(), iv.size());
// increase connection window size up to window_size
nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE, 0,
window_size -
NGHTTP2_INITIAL_CONNECTION_WINDOW_SIZE);
nghttp2_session_set_local_window_size(session_, NGHTTP2_FLAG_NONE, 0,
window_size);
return true;
}
@@ -504,7 +503,7 @@ const request *session_impl::submit(boost::system::error_code &ec,
}
auto nva = std::vector<nghttp2_nv>();
nva.reserve(3 + h.size());
nva.reserve(4 + h.size());
nva.push_back(http2::make_nv_ls(":method", method));
nva.push_back(http2::make_nv_ls(":scheme", uref.scheme));
nva.push_back(http2::make_nv_ls(":path", path));
@@ -522,13 +521,13 @@ const request *session_impl::submit(boost::system::error_code &ec,
if (cb) {
strm->request().impl().on_read(std::move(cb));
prd.source.ptr = strm.get();
prd.read_callback =
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
void *user_data) -> ssize_t {
auto strm = static_cast<stream *>(source->ptr);
return strm->request().impl().call_on_read(buf, length, data_flags);
};
prd.read_callback = [](nghttp2_session *session, int32_t stream_id,
uint8_t *buf, size_t length, uint32_t *data_flags,
nghttp2_data_source *source,
void *user_data) -> ssize_t {
auto strm = static_cast<stream *>(source->ptr);
return strm->request().impl().call_on_read(buf, length, data_flags);
};
prdptr = &prd;
}

View File

@@ -74,10 +74,12 @@ public:
virtual void start_connect(tcp::resolver::iterator endpoint_it) = 0;
virtual tcp::socket &socket() = 0;
virtual void read_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
virtual void write_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h) = 0;
virtual void read_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)>
h) = 0;
virtual void write_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)>
h) = 0;
virtual void shutdown_socket() = 0;
void shutdown();

View File

@@ -44,10 +44,12 @@ public:
virtual void start_connect(tcp::resolver::iterator endpoint_it);
virtual tcp::socket &socket();
virtual void read_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void write_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void read_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)>
h);
virtual void write_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)>
h);
virtual void shutdown_socket();
private:

View File

@@ -47,10 +47,12 @@ public:
virtual void start_connect(tcp::resolver::iterator endpoint_it);
virtual tcp::socket &socket();
virtual void read_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void write_socket(std::function<
void(const boost::system::error_code &ec, std::size_t n)> h);
virtual void read_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)>
h);
virtual void write_socket(
std::function<void(const boost::system::error_code &ec, std::size_t n)>
h);
virtual void shutdown_socket();
private:

View File

@@ -113,22 +113,22 @@ generator_cb file_generator(const std::string &path) {
generator_cb file_generator_from_fd(int fd) {
auto d = defer_shared(close, fd);
return [fd, d](uint8_t *buf, size_t len, uint32_t *data_flags)
-> generator_cb::result_type {
ssize_t n;
while ((n = read(fd, buf, len)) == -1 && errno == EINTR)
;
return [fd, d](uint8_t *buf, size_t len,
uint32_t *data_flags) -> generator_cb::result_type {
ssize_t n;
while ((n = read(fd, buf, len)) == -1 && errno == EINTR)
;
if (n == -1) {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
if (n == -1) {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
if (n == 0) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
}
if (n == 0) {
*data_flags |= NGHTTP2_DATA_FLAG_EOF;
}
return n;
};
return n;
};
}
bool check_path(const std::string &path) { return util::check_path(path); }

View File

@@ -58,7 +58,7 @@ void io_service_pool::run(bool asynchronous) {
// Create a pool of threads to run all of the io_services.
for (std::size_t i = 0; i < io_services_.size(); ++i) {
futures_.push_back(std::async(std::launch::async,
(size_t (boost::asio::io_service::*)(void)) &
(size_t(boost::asio::io_service::*)(void)) &
boost::asio::io_service::run,
io_services_[i]));
}

View File

@@ -130,8 +130,8 @@ void server::start_accept(boost::asio::ssl::context &tls_context,
acceptor.async_accept(
new_connection->socket().lowest_layer(),
[this, &tls_context, &acceptor, &mux, new_connection](
const boost::system::error_code &e) {
[this, &tls_context, &acceptor, &mux,
new_connection](const boost::system::error_code &e) {
if (!e) {
new_connection->socket().lowest_layer().set_option(
tcp::no_delay(true));

View File

@@ -245,6 +245,7 @@ http2_handler::http2_handler(boost::asio::io_service &io_service,
buf_(nullptr),
buflen_(0),
inside_callback_(false),
write_signaled_(false),
tstamp_cached_(time(nullptr)),
formatted_date_(util::http_date(tstamp_cached_)) {}
@@ -345,13 +346,13 @@ int http2_handler::start_response(stream &strm) {
auto &req = strm.request().impl();
if (::nghttp2::http2::expect_response_body(req.method(), res.status_code())) {
prd.source.ptr = &strm;
prd.read_callback =
[](nghttp2_session *session, int32_t stream_id, uint8_t *buf,
size_t length, uint32_t *data_flags, nghttp2_data_source *source,
void *user_data) -> ssize_t {
auto &strm = *static_cast<stream *>(source->ptr);
return strm.response().impl().call_read(buf, length, data_flags);
};
prd.read_callback = [](nghttp2_session *session, int32_t stream_id,
uint8_t *buf, size_t length, uint32_t *data_flags,
nghttp2_data_source *source,
void *user_data) -> ssize_t {
auto &strm = *static_cast<stream *>(source->ptr);
return strm.response().impl().call_read(buf, length, data_flags);
};
prd_ptr = &prd;
}
rv = nghttp2_submit_response(session_, strm.get_stream_id(), nva.data(),
@@ -403,12 +404,17 @@ void http2_handler::stream_error(int32_t stream_id, uint32_t error_code) {
}
void http2_handler::signal_write() {
if (!inside_callback_) {
initiate_write();
if (!inside_callback_ && !write_signaled_) {
write_signaled_ = true;
auto self = shared_from_this();
io_service_.post([self]() { self->initiate_write(); });
}
}
void http2_handler::initiate_write() { writefun_(); }
void http2_handler::initiate_write() {
write_signaled_ = false;
writefun_();
}
void http2_handler::resume(stream &strm) {
nghttp2_session_resume_data(session_, strm.get_stream_id());

View File

@@ -160,6 +160,9 @@ private:
const uint8_t *buf_;
std::size_t buflen_;
bool inside_callback_;
// true if we have pending on_write call. This avoids repeated call
// of io_service::post.
bool write_signaled_;
time_t tstamp_cached_;
std::string formatted_date_;
};

View File

@@ -29,6 +29,9 @@
#include <string>
#include "template.h"
#include "allocator.h"
namespace nghttp2 {
namespace base64 {
@@ -87,7 +90,8 @@ InputIt next_decode_input(InputIt first, InputIt last, const int *tbl) {
return first;
}
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
template <typename InputIt, typename OutputIt>
OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
static constexpr int INDEX_TABLE[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
@@ -104,37 +108,29 @@ template <typename InputIt> std::string decode(InputIt first, InputIt last) {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1};
auto len = last - first;
if (len % 4 != 0) {
return "";
}
std::string res;
res.resize(len / 4 * 3);
auto p = std::begin(res);
assert(std::distance(first, last) % 4 == 0);
auto p = d_first;
for (; first != last;) {
uint32_t n = 0;
for (int i = 1; i <= 4; ++i, ++first) {
auto idx = INDEX_TABLE[static_cast<size_t>(*first)];
if (idx == -1) {
if (i <= 2) {
return "";
return d_first;
}
if (i == 3) {
if (*first == '=' && *(first + 1) == '=' && first + 2 == last) {
*p++ = n >> 16;
res.resize(p - std::begin(res));
return res;
return p;
}
return "";
return d_first;
}
if (*first == '=' && first + 1 == last) {
*p++ = n >> 16;
*p++ = n >> 8 & 0xffu;
res.resize(p - std::begin(res));
return res;
return p;
}
return "";
return d_first;
}
n += idx << (24 - i * 6);
@@ -145,9 +141,37 @@ template <typename InputIt> std::string decode(InputIt first, InputIt last) {
*p++ = n & 0xffu;
}
return p;
}
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
auto len = std::distance(first, last);
if (len % 4 != 0) {
return "";
}
std::string res;
res.resize(len / 4 * 3);
res.erase(decode(first, last, std::begin(res)), std::end(res));
return res;
}
template <typename InputIt>
StringRef decode(BlockAllocator &balloc, InputIt first, InputIt last) {
auto len = std::distance(first, last);
if (len % 4 != 0) {
return StringRef::from_lit("");
}
auto iov = make_byte_ref(balloc, len / 4 * 3 + 1);
auto p = iov.base;
p = decode(first, last, p);
*p = '\0';
return StringRef{iov.base, p};
}
} // namespace base64
} // namespace nghttp2

View File

@@ -59,31 +59,40 @@ void test_base64_encode(void) {
}
void test_base64_decode(void) {
BlockAllocator balloc(4096, 4096);
{
std::string in = "/w==";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("\xff" == out);
CU_ASSERT("\xff" == base64::decode(balloc, std::begin(in), std::end(in)));
}
{
std::string in = "//4=";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("\xff\xfe" == out);
CU_ASSERT("\xff\xfe" ==
base64::decode(balloc, std::begin(in), std::end(in)));
}
{
std::string in = "//79";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("\xff\xfe\xfd" == out);
CU_ASSERT("\xff\xfe\xfd" ==
base64::decode(balloc, std::begin(in), std::end(in)));
}
{
std::string in = "//79/A==";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("\xff\xfe\xfd\xfc" == out);
CU_ASSERT("\xff\xfe\xfd\xfc" ==
base64::decode(balloc, std::begin(in), std::end(in)));
}
{
// we check the number of valid input must be multiples of 4
std::string in = "//79=";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("" == out);
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
}
{
// ending invalid character at the boundary of multiples of 4 is
@@ -91,18 +100,21 @@ void test_base64_decode(void) {
std::string in = "bmdodHRw\n";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("" == out);
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
}
{
// after seeing '=', subsequent input must be also '='.
std::string in = "//79/A=A";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("" == out);
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
}
{
// additional '=' at the end is bad
std::string in = "//79/A======";
auto out = base64::decode(std::begin(in), std::end(in));
CU_ASSERT("" == out);
CU_ASSERT("" == base64::decode(balloc, std::begin(in), std::end(in)));
}
}

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