Compare commits

...

499 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
7a84d51aaf Merge branch 'master' into http-parser-unknown-method 2016-05-28 22:49:30 +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
f90f40e3b5 Merge branch 'master' into http-parser-unknown-method 2016-05-28 19:51:05 +09:00
Tatsuhiro Tsujikawa
43b045e84c nghttpx: Fix compile error with gcc 2016-05-28 19:50:36 +09:00
Tatsuhiro Tsujikawa
f38babe30f nghttpx: Support unknown method 2016-05-28 19:34:15 +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
Tatsuhiro Tsujikawa
0641d314a6 Update man pages 2016-03-27 22:07:50 +09:00
Tatsuhiro Tsujikawa
2928afa51f Bump up version number to 1.9.1 2016-03-27 22:04:26 +09:00
Tatsuhiro Tsujikawa
757bcf1310 nghttpx: Fix bug that backend tls keyword did not work with -s option 2016-03-27 17:11:44 +09:00
Tatsuhiro Tsujikawa
c9aba4ea0c nghttpx: Don't use data_prd.source.ptr 2016-03-27 16:57:43 +09:00
Tatsuhiro Tsujikawa
2cee80acf0 nghttpx: Fix handing stream after connection check was failed 2016-03-27 15:53:26 +09:00
Tatsuhiro Tsujikawa
d9a2ff278c src: Use len instead of n for clarity 2016-03-27 15:52:24 +09:00
Tatsuhiro Tsujikawa
8a539420c2 Bump up version number to 1.10.0-DEV 2016-03-26 23:19:13 +09:00
Tatsuhiro Tsujikawa
371497968b Update bash_completion 2016-03-26 23:03:59 +09:00
Tatsuhiro Tsujikawa
388d7a944a Update man pages 2016-03-26 23:03:48 +09:00
Tatsuhiro Tsujikawa
afe724ecda Bump up version number to 1.9.0, LT revision to 20:0:6 2016-03-26 22:59:09 +09:00
Tatsuhiro Tsujikawa
0d636893f1 Update AUTHORS 2016-03-26 22:08:28 +09:00
Tatsuhiro Tsujikawa
4ac9417d8d Update doc 2016-03-26 21:45:38 +09:00
Tatsuhiro Tsujikawa
75110320ab Update doc 2016-03-26 21:43:34 +09:00
Tatsuhiro Tsujikawa
8691ec4899 Update github links 2016-03-26 00:58:32 +09:00
Tatsuhiro Tsujikawa
b6e2214903 Update doc 2016-03-26 00:09:02 +09:00
Tatsuhiro Tsujikawa
7ec50e55c9 Update doc 2016-03-25 23:53:59 +09:00
Tatsuhiro Tsujikawa
ad8be7d474 src: parse_link_header takes StringRef 2016-03-25 23:51:42 +09:00
Tatsuhiro Tsujikawa
07926cffca src: Remove lookup_method_token(const std::string&) 2016-03-25 23:31:46 +09:00
Tatsuhiro Tsujikawa
00b2d7d513 src: Remove lookup_token(const std::string&) 2016-03-25 23:29:16 +09:00
Tatsuhiro Tsujikawa
f74d7ea119 src: Don't allow const char * in starts_with 2016-03-25 23:20:48 +09:00
Tatsuhiro Tsujikawa
2bca6360b6 src: Don't allow const char * in istarts_with and istarts_with_l 2016-03-25 23:18:31 +09:00
Tatsuhiro Tsujikawa
841b3c87db src: Don't allow const char * in ends_with and ends_with_l 2016-03-25 23:04:44 +09:00
Tatsuhiro Tsujikawa
2ab79f4938 src: Don't allow const char * in iends_with and iends_with_l 2016-03-25 23:00:34 +09:00
Tatsuhiro Tsujikawa
2182a85875 src: Make strifind functin template 2016-03-25 22:56:23 +09:00
Tatsuhiro Tsujikawa
72d8d78d36 src: Don't allow const char * in 2nd argument of streq_l(S[N], T) 2016-03-25 22:53:31 +09:00
Tatsuhiro Tsujikawa
dad61d032e src: Don't allow const char * in 2nd argument of strieq_l(S[N], T) 2016-03-25 22:51:20 +09:00
Tatsuhiro Tsujikawa
1bbb241baa src: Make streq(T, S) function template 2016-03-25 22:48:13 +09:00
Tatsuhiro Tsujikawa
3e6c38e3be src: Made strieq(T, S) template 2016-03-25 22:45:33 +09:00
Tatsuhiro Tsujikawa
9272e80fa6 nghttpx: Fix compile error on travis 2016-03-25 02:28:10 +09:00
Tatsuhiro Tsujikawa
333dd73a18 Update man pages 2016-03-25 02:15:29 +09:00
Tatsuhiro Tsujikawa
8e84bbd781 Update doc 2016-03-25 02:15:02 +09:00
Tatsuhiro Tsujikawa
44af3dab50 nghttpx: Update doc 2016-03-25 02:14:39 +09:00
Tatsuhiro Tsujikawa
22128767e6 nghttpx: Fix formatting issue on manual page 2016-03-25 02:08:25 +09:00
Tatsuhiro Tsujikawa
f6b78a027c Update doc 2016-03-25 01:57:00 +09:00
Tatsuhiro Tsujikawa
a46c815e4e src: StringRef-fy 2016-03-25 01:41:06 +09:00
Tatsuhiro Tsujikawa
186d440168 nghttpx: More StringRef-fy 2016-03-25 01:19:42 +09:00
Tatsuhiro Tsujikawa
a9e365ad7d fixup! nghttpx: More StringRef-fy 2016-03-25 01:10:48 +09:00
Tatsuhiro Tsujikawa
a104d8a80b fixup! nghttpx: Use StringRef for SHRPX_UNIX_PATH_PREFIX 2016-03-25 01:10:25 +09:00
Tatsuhiro Tsujikawa
a5029d1eed nghttpx: More StringRef-fy 2016-03-25 01:07:22 +09:00
Tatsuhiro Tsujikawa
848e45e333 nghttpx: Use StringRef for SHRPX_UNIX_PATH_PREFIX 2016-03-25 01:00:04 +09:00
Tatsuhiro Tsujikawa
7972593586 integration: Fix tests 2016-03-25 00:56:20 +09:00
Tatsuhiro Tsujikawa
79968c6374 src: Rewrite strifind 2016-03-25 00:27:59 +09:00
Tatsuhiro Tsujikawa
1699aef609 src: Remove strcompare 2016-03-25 00:16:25 +09:00
Tatsuhiro Tsujikawa
2d2d6c3cc0 src: Remove istarts_with(const char*) overload 2016-03-25 00:14:12 +09:00
Tatsuhiro Tsujikawa
bfccab9b9f src: Remove starts_with(const char*, const char*) overload 2016-03-25 00:09:53 +09:00
Tatsuhiro Tsujikawa
17ccbae084 src: Don't compare against c-string 2016-03-25 00:07:21 +09:00
Tatsuhiro Tsujikawa
0875e66aab src: Remove streq(const char *) overload 2016-03-25 00:02:07 +09:00
Tatsuhiro Tsujikawa
4dfae3484f nghttpx: Refactor CertLookupTree interface 2016-03-24 23:35:15 +09:00
Tatsuhiro Tsujikawa
372123c178 nghttpx: Remove strieq(const char*, cosnt char*) overload, and fix unittests 2016-03-24 23:34:56 +09:00
Tatsuhiro Tsujikawa
13596bde90 nghttpx: Refactor option handling using StringRef 2016-03-24 22:15:58 +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
Tatsuhiro Tsujikawa
daa1ae3a45 nghttpx: Cosmetic change 2016-03-24 00:38:10 +09:00
Tatsuhiro Tsujikawa
44ee67ff71 nghttpx: Refactor split_host_port 2016-03-24 00:35:13 +09:00
Tatsuhiro Tsujikawa
144ae3af9d nghttpx: Memcached connection encryption with tls keyword
Like frontend and backend options, encryption for memcached
connections is configured using tls keyword in
tls-session-cache-memcached and tls-ticket-key-memcached options.
tls-session-cache-memcached-tls and tls-ticket-key-memcached-tls
options are deprecated.
2016-03-24 00:22:13 +09:00
Tatsuhiro Tsujikawa
eec0b04a33 nghttpx: Enable/disable TLS per frontend address
This change allows user to disable TLS per frontend address using
no-tls keyword in --frontend option.  We removed --frontend-no-tls in
favor of this new feature.
2016-03-23 23:56:09 +09:00
Tatsuhiro Tsujikawa
58b06f32a2 nghttpx: Configure TLS per backend routing pattern
We added "tls" parameter to --backend option to enable TLS on that
backend connection.  --backend-tls options was deprecated, now is
noop.
2016-03-23 22:56:18 +09:00
Tatsuhiro Tsujikawa
5b58db39ff nghttpx: Fix failure case when comparing backend address set 2016-03-23 22:13:53 +09: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
Tatsuhiro Tsujikawa
7c954c1ea7 nghttpx: Workaround for Ubuntu 15.04 which does not value-initialize on std::make_shared. 2016-03-23 01:32:17 +09:00
Tatsuhiro Tsujikawa
e9f4d0eec2 nghttpx: Properly log incoming GOAWAY from backend 2016-03-23 01:16:44 +09:00
Tatsuhiro Tsujikawa
4f9c78799c nghttpd: Fix compile error with Android NDK 2016-03-23 01:16:02 +09:00
Tatsuhiro Tsujikawa
0f9ed40bd9 nghttpx: Share connection among different patterns if address set are same 2016-03-23 00:01:27 +09:00
Tatsuhiro Tsujikawa
4bb88b35ec nghttpx: "*" must match at least one character 2016-03-22 22:40:23 +09:00
Tatsuhiro Tsujikawa
04145e22a2 Revert "nghttpx: Call setsid after executing new binary"
This reverts commit 6680d8b792.
2016-03-22 00:21:32 +09:00
Tatsuhiro Tsujikawa
cca7e398fd Update doc 2016-03-21 16:11:35 +09:00
Tatsuhiro Tsujikawa
3d04fe2a87 Update doc 2016-03-21 13:08:53 +09:00
Tatsuhiro Tsujikawa
c459034ae9 Update doc 2016-03-20 18:28:01 +09:00
Tatsuhiro Tsujikawa
442bd47535 Update bash_completion 2016-03-20 18:15:02 +09:00
Tatsuhiro Tsujikawa
5cea3e227c Update man pages 2016-03-20 18:14:40 +09:00
Tatsuhiro Tsujikawa
db0a22e991 Update doc 2016-03-20 18:13:44 +09:00
Tatsuhiro Tsujikawa
dc3119303a Rewrite concat_string_ref 2016-03-20 17:55:17 +09:00
Tatsuhiro Tsujikawa
d2b55ad1a2 nghttpx: Allow '*' in --error-page to be used as wildcard 2016-03-19 23:49:15 +09:00
Tatsuhiro Tsujikawa
d7051f5207 nghttpx: Add custom error pages 2016-03-19 23:41:21 +09:00
Tatsuhiro Tsujikawa
db1ee3aa88 nghttpd: Use StringRef 2016-03-19 20:57:40 +09:00
Tatsuhiro Tsujikawa
a1e0bd134e nghttpx: Create at least the same number of h2 session as load balancing hosts 2016-03-19 12:00:27 +09:00
Tatsuhiro Tsujikawa
7a1e0eb618 integration: Disable tests that sometimes break randomly on travis 2016-03-19 11:50:01 +09:00
Tatsuhiro Tsujikawa
65b59bd78a Include config.h from tests/*.h 2016-03-19 11:46:49 +09:00
Tatsuhiro Tsujikawa
dcae6efaa2 nghttpx: Rewrite Downstream::assemble_request_cookie using StringRef 2016-03-19 11:38:09 +09:00
Tatsuhiro Tsujikawa
71cc7a96c2 Merge branch 'Lekensteyn-cmake' 2016-03-19 11:35:27 +09:00
Tatsuhiro Tsujikawa
8da0d649e4 Merge branch 'cmake' of https://github.com/Lekensteyn/nghttp2 into Lekensteyn-cmake 2016-03-19 11:20:31 +09:00
Peter Wu
08c7656e47 travis: remove -DCMAKE_BUILD_TYPE=None
It was added because the default RelWithDebInfo type disabled
assertions, but now that -DNDEBUG is removed from its flags, it is not
necessary to change the build type anymore.
2016-03-17 23:34:14 +01:00
Peter Wu
bd253e1bdd cmake: fix Windows build with CUnit
failmalloc and main tests succesfully pass the test now.
2016-03-17 23:32:07 +01:00
Peter Wu
d10f149161 cmake: fix Windows support
Fix Windows build by defining `ssize_t` when missing and adjusting the
install commands.

Add support for ENABLE_WERROR=1 while at it.

Tested with MSVC 2013 on Windows 7 x64.
2016-03-16 17:33:20 +01:00
Peter Wu
3a2a943fe9 cmake: do not fail without libxml2
Avoid adding a LIBXML2_LIBRARIES-NOTFOUND to the libraries list when it
is not found. Likewise for OpenSSL.
2016-03-16 17:33:10 +01:00
Peter Wu
f34971774b cmake: use -std=c++11 instead of -std=gnu+11
Matches autotools behavior. The m4_if logic was misread...
2016-03-16 14:52:42 +01:00
Peter Wu
f8a9a21428 cmake: add _U_ and NGHTTP2_NORETURN to config.h
Do not add _U_ and NGHTTP2_NORETURN definitions to the command line,
instead add it to config.h. This matches what autotools does.
2016-03-16 14:25:58 +01:00
Peter Wu
0c49e5d56e cmake: enable assertions by default
Users can disable this by setting -DCMAKE_C_FLAGS=-DNDEBUG or
-DCMAKE_CXX_FLAGS=-DNDEBUG to disable assertions as desired.
2016-03-16 14:10:42 +01:00
Tatsuhiro Tsujikawa
e84755eb35 Merge pull request #542 from Lekensteyn/build-fixes
src/Makefile.am: fix missing allocator.h
2016-03-15 23:44:20 +09:00
Peter Wu
b348a02b85 cmake: fix printed C/CXX flags
Build type-specific flags are added before other flags, reflect this in
the output.
2016-03-15 13:58:53 +01:00
Peter Wu
439636c579 cmake: set CMAKE_BUILD_TYPE=RelWithDebInfo by default
NOTE: RelWithDebInfo *disables* assertions by default. To keep
assertions, use CMAKE_BUILD_TYPE=Debug or CMAKE_BUILD_TYPE=None.
2016-03-15 13:40:15 +01:00
Peter Wu
162b1c5e03 cmake: only install ASIO headers when requested 2016-03-15 00:02:46 +01:00
Peter Wu
dc56b951df src/Makefile.am: fix missing allocator.h
Fix regression from v1.8.0-38-gbae37e3 breaking distcheck.
2016-03-14 17:49:23 +01:00
Peter Wu
4d801cd696 travis: add cmake to build matrix
Add Nathan's PPA for cmake 3.2.3 (3.0 or newer is required).
2016-03-14 17:26:59 +01:00
Peter Wu
7c55c335cc Merge branches 'master' and 'cmake-updated' into cmake
Update to latest master with appropriate cmake changes at the same time.
2016-03-14 17:26:15 +01:00
Peter Wu
2ddb83206b cmake: sync with v1.8.0-63-g37b09f6
Adds missing source files and configure.ac changes since
v1.7.0-93-g093eb51.
2016-03-14 17:20:37 +01:00
Tatsuhiro Tsujikawa
ab734f09b6 nghttpx: Fix possible crash in rare case 2016-03-15 00:46:15 +09:00
Tatsuhiro Tsujikawa
dd2bdf3e31 nghttpx: Update doc 2016-03-14 23:53:10 +09:00
Tatsuhiro Tsujikawa
a909bb3eca nghttpx: Initialize proto field 2016-03-14 23:47:29 +09:00
Tatsuhiro Tsujikawa
aaebeceded Merge pull request #538 from Jan-E/master
Fixes and improvements for Makefile.MSVC
2016-03-14 23:00:23 +09:00
Tatsuhiro Tsujikawa
3de435d7b8 contrib: Use simple form in prerequisites 2016-03-14 22:57:26 +09:00
Tatsuhiro Tsujikawa
01408209d8 nghttpx: Fix the bug that forwarded query contains duplicated '?'
This change also fixes that bug that the multiple '/' at the start of
request were not coalesced into one.
2016-03-14 22:20:00 +09:00
Jan-E
e8b62c620d Revert change of NGHTTP2_VERSION_NUM, keep the parentheses around VERSION_NUM, not in the sed -e 2016-03-14 14:13:19 +01:00
Tatsuhiro Tsujikawa
2eb7137e04 Merge branch 'Lekensteyn-autotools-it' 2016-03-14 21:15:59 +09:00
Tatsuhiro Tsujikawa
caa12ec587 Merge branch 'autotools-it' of https://github.com/Lekensteyn/nghttp2 into Lekensteyn-autotools-it 2016-03-14 21:12:33 +09:00
Jan-E
0f71fbce8d Generate nghttp2ver.h before compiling 2016-03-13 18:57:58 +01:00
Jan-E
4e2972a5dc Use string for NGHTTP2_VERSION_NUM, e.g 0x010800: do not add parentheses 2016-03-13 18:43:44 +01:00
Jan-E
78e5417ff2 Remove -nologo: not used in VC11/VC14, throws error in VC9 2016-03-13 18:31:14 +01:00
Jan-E
77852cf572 Use string for NGHTTP2_VERSION_NUM, e.g 0x010800 2016-03-13 18:24:32 +01:00
Jan-E
fa36537f82 Detect version for releases en dev versions 2016-03-13 18:18:22 +01:00
Jan-E
4cde76c9c3 Do not use Cython by default 2016-03-13 18:13:46 +01:00
Jan-E
e02512032b Fix missing external symbol nghttp2_rcbuf_new2 2016-03-13 18:12:39 +01:00
Peter Wu
b092166bc6 cmake: clean more files, fix python dependency
Remove generated documentation, python and mruby build artifacts.
Note that this does not work for Ninja, Makefile works fine though.
2016-03-13 17:36:03 +01:00
Tatsuhiro Tsujikawa
e58db4f8b0 Attempt to fix compile error with msvc 2016-03-14 00:54:02 +09:00
Peter Wu
dad222b8f4 cmake: fix jemalloc, libevent include dirs
Caught with cmake --warn-uninitialized.
2016-03-13 16:42:35 +01:00
Peter Wu
e80977c812 integration-tests: do not use recursive target
Older automake (travis, *cough*) do not support the
AM_EXTRA_RECURSIVE_TARGETS option, this results in invoking "it-local"
directly in the travis script which relies on an implementation detail.

Since the "it" target is only used by the integration-tests directory,
just avoid the recursive targets. The README.rst suggests to enter the
integration-tests directory anyway.
2016-03-13 15:40:17 +01:00
Peter Wu
2b3bc710fc cmake: fix version checks for external packages
The name passed to find_package should match the one that is passed to
find_package_handle_standard_args, otherwise the version matching is not
properly done. The names are based on the FindXXX.cmake filename.

This also simplifies components reporting for Libevent (done by
find_package_handle_standard_args) and results in reporting a library
instead of include directory when found.
2016-03-13 15:06:56 +01:00
Peter Wu
a45540fd79 Lower libev version requirement
libev 4.11 seems to build fine as demonstrated by Travis with autotools.
2016-03-13 13:15:50 +01:00
Peter Wu
7f8110601e cmake: fix compatibility with cmake before 3.3
The COMPILE_LANGUAGE generator expression is only supported since CMake
3.3. Moreover, it does not work with all generators (works with Makefile
and Ninja, but not with Visual Studio).

target_compile_options would only work if a target does not mix C and
C++ sources, since the flags are intended to be set for a specific
language, use set_source_files_properties instead. This approach is also
less repetitive.

Drop the idea of using lists and COMPILE_OPTIONS,
set_source_files_properties only understands COMPILE_FLAGS (a single
string, not a list).
2016-03-13 12:30:41 +01:00
Tatsuhiro Tsujikawa
37b09f6785 Use %u for uint8_t for formatting 2016-03-13 18:25:30 +09:00
Tatsuhiro Tsujikawa
2a606bae4c Add nghttp2_error_callback to tell application human readable error message 2016-03-13 18:22:52 +09:00
Tatsuhiro Tsujikawa
3b2811bfc4 nghttpx: Remove AltSvc ctor 2016-03-13 14:01:59 +09:00
Tatsuhiro Tsujikawa
27275a02ac nghttpx: Remove unused EMPTY_STRING 2016-03-13 13:59:06 +09:00
Tatsuhiro Tsujikawa
34d209b30b nghttpx: Add wildcard host routing
This change allows host pattern in --backend to include '*' to
indicate wildcard match.  The wildcard match is made in suffix match
only.
2016-03-13 01:01:34 +09:00
Tatsuhiro Tsujikawa
94f52d49dc BlockAllocator: Delete copy ctor and assignment operator 2016-03-12 21:25:53 +09:00
Tatsuhiro Tsujikawa
0720671e0a Merge branch 'nghttpx-block-allocator' 2016-03-12 21:21:34 +09:00
Tatsuhiro Tsujikawa
0ee09320e0 src: Remove unused value_to_str 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
78fcb2143f Update doc 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
755b14de5d src: Unify path_join implementation 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
3455cb35e4 nghttpx: Rewrite create_forwarded to use BlockAllocator 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
c1571a3209 src: Rewrite xff handling 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
67569486d1 src: Rewrite http:create_via_header_value 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
d64051fedc src: Return StringRef from http2::stringify_status 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
c897d5b294 src: Use StringRef in parse_http_date 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
863a944179 src: Add specialization for char to avoid reinterpret_cast in constexpr 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
3db9c2c796 Remove extra tokenization of header names; they are not effective at best 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
12dad32890 Add nghttp2_on_header_callback2 2016-03-12 21:13:09 +09:00
Tatsuhiro Tsujikawa
689d2a1afb Fix compile error with --enable-debug 2016-03-12 21:12:27 +09:00
Tatsuhiro Tsujikawa
ff0d137fb3 Reference counted HPACK name/value pair 2016-03-12 21:12:27 +09:00
Tatsuhiro Tsujikawa
8da20975f9 Always allocate buffer for name, and value 2016-03-12 21:12:26 +09:00
Tatsuhiro Tsujikawa
eb393985b7 nghttpx: Make a copy before adding header to Downstream 2016-03-12 21:12:26 +09:00
Tatsuhiro Tsujikawa
7a412df9a5 nghttpx: Fix tests 2016-03-12 21:12:26 +09:00
Tatsuhiro Tsujikawa
b1b57cc740 nghttpx: Use StringRef for authority, scheme and path 2016-03-12 21:12:26 +09:00
Peter Wu
bdb6581990 Add CMake-related files to EXTRA_DIST 2016-03-12 01:38:12 +01:00
Peter Wu
618073e2b4 cmake: add "check" target
Add a "check" target that builds tests before running them.
2016-03-12 00:57:30 +01:00
Tatsuhiro Tsujikawa
fa601e5ba3 Add isolation_threshold, use field to store block size rather than template parameter 2016-03-09 21:25:11 +09:00
Tatsuhiro Tsujikawa
bae37e3e4a nghttpx: Add custom memory allocator mainly for header related objects 2016-03-09 21:16:28 +09:00
Tatsuhiro Tsujikawa
907eeeda8a src: Return StringRef from util::get_uri_field 2016-03-08 21:38:15 +09:00
Tatsuhiro Tsujikawa
fe6ccd16da nghttpx: Change read timeout reset timing 2016-03-05 19:11:36 +09:00
Tatsuhiro Tsujikawa
10ec00126c src: Don't process rel=preload again once we found it 2016-03-04 23:00:33 +09:00
Tatsuhiro Tsujikawa
2d6211c455 asio: Fix bug that server event loop breaks with exception
This can happen when we call throwing version of
basic_stream_socket::remote_endpoint() call while client disconnected.
2016-03-04 22:43:36 +09:00
Tatsuhiro Tsujikawa
e302cc9c16 src: Simplify function parameter using StringRef 2016-03-04 00:38:43 +09:00
Tatsuhiro Tsujikawa
3f2b54cfc4 src: Refactor using StringRef 2016-03-04 00:33:35 +09:00
Tatsuhiro Tsujikawa
acbf38fd3c src: Refactor using StringRef, simplify function parameters 2016-03-04 00:26:59 +09:00
Tatsuhiro Tsujikawa
1e8bea15e5 src: Use StringRef inside LinkHeader 2016-03-03 23:31:44 +09:00
Tatsuhiro Tsujikawa
aaf0177318 src: Use str_size 2016-03-03 23:23:51 +09:00
Tatsuhiro Tsujikawa
9afc017532 src: Don't push if Link header field includes nopush 2016-03-03 23:20:32 +09:00
Tatsuhiro Tsujikawa
5da38b22c0 h2load: Fix bug that it did not try to connect to server again 2016-03-02 22:24:14 +09:00
Tatsuhiro Tsujikawa
ce61f62644 h2load: Fix bug that initial max concurrent streams was too large 2016-03-02 21:18:42 +09:00
Peter Wu
2c525f2471 cmake: ignore "make install" artifact 2016-02-29 16:20:31 +01:00
Peter Wu
5bbcb7148c cmake: update .gitignore files 2016-02-29 16:13:19 +01:00
Peter Wu
8bca2d1048 cmake: fix libevent binary names
Match the output produced by autotools (libevent-client instead of
libevent_client).
2016-02-29 16:11:26 +01:00
Peter Wu
d6c3b6e84c cmake: fix mruby dependency
Ensure that the mruby build is triggered when the surrogate "mruby-lib"
target is used. Fixes building nghttpx when mruby is missing.
2016-02-29 16:00:08 +01:00
Tatsuhiro Tsujikawa
e453759637 Add nghttp2_option_set_no_auto_ping_ack() option
This option prevents the nghttp2 library from sending PING frame with
ACK flag set in the reply to incoming PING frame.  To allow the
application to send PING with ACK flag set, nghttp2_submit_ping() now
recognizes NGHTTP2_FLAG_PING in its flags parameter.
2016-02-29 23:39:50 +09:00
Tatsuhiro Tsujikawa
a21c87d11c Add nghttp2_http2_strerror() to return HTTP/2 error code string 2016-02-29 23:10:20 +09:00
Tatsuhiro Tsujikawa
478fde5fef nghttpx: Fix compile error 2016-02-29 01:16:45 +09:00
Tatsuhiro Tsujikawa
bffc0ec87a Update doc 2016-02-29 01:00:03 +09:00
Tatsuhiro Tsujikawa
1b9b03b68f Update man pages 2016-02-29 00:55:16 +09:00
Tatsuhiro Tsujikawa
a59445ccff Merge branch 'nghttpx-rewrite-h2-coalesce' 2016-02-29 00:52:19 +09:00
Tatsuhiro Tsujikawa
c2ec73302d integration: Fix tests + gofmt 2016-02-29 00:37:51 +09:00
Tatsuhiro Tsujikawa
284691253f nghttpx: Use StringRef for http::create_forwarded parameter 2016-02-29 00:05:32 +09:00
Tatsuhiro Tsujikawa
124d4c9fad src: Fix tests 2016-02-29 00:05:32 +09:00
Tatsuhiro Tsujikawa
5fbe4cc225 nghttpx: Clear upgrade_request flag when Downstream is attached to HTTP/2 backend 2016-02-28 23:21:57 +09:00
Tatsuhiro Tsujikawa
df6466cfbd nghttpx: Update doc 2016-02-28 23:15:57 +09:00
Tatsuhiro Tsujikawa
2326337d32 nghttpx: Deprecate backend-http1-connections-per-host in favor of backend-connections-per-host 2016-02-28 22:15:49 +09:00
Tatsuhiro Tsujikawa
06921f35f3 nghttpx: Restructure mode settings
It is very hard to support multiple protocols in backend while
retaining multiple mode settings.  Therefore, we dropped modes except
for default and HTTP/2 proxy mode.  The other removed modes can be
emulated using combinations of options.  Now the backend connection is
not encrypted by default.  To enable encryption on backend connection,
use --backend-tls option.
2016-02-28 21:35:26 +09:00
Tatsuhiro Tsujikawa
44d3801760 nghttpx: Deprecate backend-http1-connections-per-frontend in favor of backend-connections-per-frontend 2016-02-28 17:11:12 +09:00
Tatsuhiro Tsujikawa
1832f78684 nghttpx: Move downstream proto to DownstreamAddrGroup 2016-02-28 16:56:14 +09:00
Tatsuhiro Tsujikawa
e7601cde8a nghttpx: Don't share session which is already in draining state 2016-02-28 12:41:34 +09:00
Tatsuhiro Tsujikawa
36f6a009b8 nghttpx: Effectively disable backend HTTP/2 connection flow control
This is required to avoid session stall because of too slow frontend
connection.
2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
1e1752266f Update doc 2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
aafcc55006 nghttpx: Deprecate --http2-max-concurrent-streams option
We added 2 new option instead: --frontend-http2-max-concurrent-streams
and --backend-http2-max-concurrent-streams.
2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
c731d1fea5 nghttpx: Deprecate --backend-http2-connections-per-worker option 2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
aa892e4d37 nghttpx: Share TLS session cache between HTTP/2 and HTTP/1 backend 2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
8ca3e5f6ba nghttpx: Separate Downstream address group from config to runtime 2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
21007da392 nghttpx: Rewrite backend HTTP/2 connection coalesce strategy
Previously, we use one Http2Session object per DownstreamAddrGroup.
This is not flexible, and we have to provision how many HTTP/2
connection is required in advance.  The new strategy is we add
Http2Session object on demand.  We measure the number of attached
downstream connection object and server advertised concurrency limit.
As long as former is smaller than the latter, we attach new downstream
connection to it.  Once the limit is reached, we create new
Http2Session object.  If the number lowers the limit, we start to
share Http2Session object again.
2016-02-28 00:19:18 +09:00
Tatsuhiro Tsujikawa
9eeac27966 makerelease.sh: Remove duplicate git module update --init 2016-02-26 00:57:34 +09:00
Tatsuhiro Tsujikawa
e6ff7e1e4a Bump up version number to 1.9.0-DEV 2016-02-26 00:53:42 +09:00
Tatsuhiro Tsujikawa
d1f9f9a3aa makerelease.sh: Add autoreconf 2016-02-26 00:00:52 +09:00
Tatsuhiro Tsujikawa
2415a22757 h2load: Fix uninitialized fields 2016-02-26 00:00:24 +09:00
Tatsuhiro Tsujikawa
887d4d2a41 Update bash_completion 2016-02-25 23:35:44 +09:00
Tatsuhiro Tsujikawa
1c8e625045 Update man pages 2016-02-25 23:35:23 +09:00
Tatsuhiro Tsujikawa
36e931e0d7 Bump up version number to 1.8.0, LT revision to 19:0:5 2016-02-25 23:33:16 +09:00
Tatsuhiro Tsujikawa
31d4077638 Remove files copied in the rule for apiref.rst target 2016-02-25 23:18:21 +09:00
Tatsuhiro Tsujikawa
c098b4ac70 nghttpx: Remove --backend-tls-session-cache-per-worker option 2016-02-25 22:46:25 +09:00
Tatsuhiro Tsujikawa
32446a5197 Revert "Update doc"
This reverts commit 8aac5d6af2.
2016-02-25 21:19:38 +09:00
Tatsuhiro Tsujikawa
40c1b29f36 Handle extension frame in session_inbound_frame_reset 2016-02-25 21:18:59 +09:00
Tatsuhiro Tsujikawa
bc933e9981 src: Use lowercase to show it is not the name of frame 2016-02-25 21:18:09 +09:00
Tatsuhiro Tsujikawa
ba34e911e1 Merge branch 'simple-extensions' 2016-02-25 01:00:35 +09:00
Tatsuhiro Tsujikawa
8aac5d6af2 Update doc 2016-02-25 00:58:50 +09:00
Tatsuhiro Tsujikawa
56bdfd1df2 Revert "Handle extension frame in session_inbound_frame_reset"
This reverts commit dbffb8995b.
2016-02-25 00:58:24 +09:00
Tatsuhiro Tsujikawa
dbffb8995b Handle extension frame in session_inbound_frame_reset 2016-02-25 00:45:24 +09:00
Tatsuhiro Tsujikawa
ebfae904ab Fix typo 2016-02-25 00:32:17 +09:00
Tatsuhiro Tsujikawa
827abb57e9 Simplified bitfield calculation of extension frame 2016-02-24 23:59:01 +09:00
Tatsuhiro Tsujikawa
9aee43f7d8 Update doc for extension frames 2016-02-24 23:51:00 +09:00
Tatsuhiro Tsujikawa
34bf153653 Merge branch 'master' into simple-extensions 2016-02-24 23:21:03 +09:00
Tatsuhiro Tsujikawa
2782ef67de nghttpd: Remove unused function 2016-02-23 01:18:52 +09:00
Tatsuhiro Tsujikawa
9d15f9b00d nghttpd: Start SETTINGS timer after it is written to output buffer 2016-02-23 01:18:07 +09:00
Tatsuhiro Tsujikawa
3e72711e23 Cap 100 limit for remembering idle streams 2016-02-23 01:09:45 +09:00
Tatsuhiro Tsujikawa
f4bb8776d0 mruby: Clean up mrbgems as well 2016-02-23 01:06:23 +09:00
Tatsuhiro Tsujikawa
95ffb4565f Update nghttpx documentation 2016-02-21 18:20:53 +09:00
Tatsuhiro Tsujikawa
f3a415f623 Update nghttpx documentation 2016-02-21 17:47:27 +09:00
Tatsuhiro Tsujikawa
936d4aca1a Update h2load documentation 2016-02-21 17:46:48 +09:00
Tatsuhiro Tsujikawa
216ae0a328 Update nghttpx documentation 2016-02-21 17:36:10 +09:00
Tatsuhiro Tsujikawa
9672bc322f src: Remove unused functions 2016-02-21 16:51:46 +09:00
Tatsuhiro Tsujikawa
b68be1e1fb src: Make token of type int32_t; we have no reason to use int16_t 2016-02-21 16:44:00 +09:00
Tatsuhiro Tsujikawa
f2a7275700 nghttpx: Cache TLS session inside DownstreamAddr object 2016-02-21 16:35:43 +09:00
Tatsuhiro Tsujikawa
177d0a513f nghttpx: More logging for backend connection initiation 2016-02-21 16:11:50 +09:00
Tatsuhiro Tsujikawa
dfc02843b6 src: Rename and rewrite numeric_hostport as to_numeric_addr and support AF_UNIX path 2016-02-21 15:28:11 +09:00
Tatsuhiro Tsujikawa
11c8803b92 nghttpx: Worker wide blocker which is used when socket(2) is failed 2016-02-21 15:27:19 +09:00
Tatsuhiro Tsujikawa
c9a4f293a1 nghttpx: ConnectBlocker per backend address 2016-02-21 14:53:06 +09:00
Tatsuhiro Tsujikawa
61579ad20f nghttpx: Use StringRef for shrpx::add_header 2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
9678daa46a nghttpx: Rename index_headers() as parse_content_length() 2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
23ecfd412d nghttpx: Fix mruby compile error, clean up add_header interface 2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
3ff148811b nghttpx: Use StringRef for add_hedeader 2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
6f1347fc8b nghttpx: Tokenize trailer field as well so that we can ditch prohibited headers in HTTP/2 2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
1703201084 nghttpx: Get rid of hdidx 2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
7921029e33 Tokenize extra HTTP header fields
The extra HTTP header fields are compiled from
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers,
https://en.wikipedia.org/wiki/List_of_HTTP_header_fields, and
https://www.owasp.org/index.php/List_of_useful_HTTP_headers.
2016-02-20 23:30:02 +09:00
Tatsuhiro Tsujikawa
b7159f80b2 Eliminate the possibility of nghttp2_stream.cycle overflow 2016-02-18 23:56:29 +09:00
Peter Wu
9c874bf9b5 cmake: rename nghttpx-bin target to nghttpx
`ninja nghttpx` would create the static library, but I expected a binary
`nghttpx` instead. Rename the nghttpx target to nghttpx_static and
nghttpx-bin to nghttpx.
2016-02-18 14:20:35 +01:00
Peter Wu
9ab5ef3b5b cmake: make find_package non-QUIET
Also fix useless MRUBY_LIBRARIES output and add the CMake build type
(e.g. Release, Debug, etc.)
2016-02-16 16:29:39 +01:00
Tatsuhiro Tsujikawa
f0b5a8db8c Add unistd.h to test initgroups() declaration 2016-02-17 00:26:34 +09:00
Peter Wu
4814d14db5 cmake: fix installing nghttp2_asio.pc, manpages, README.rst 2016-02-16 16:25:50 +01:00
Peter Wu
77e8190b6c cmake: fix symbol visibility issues
libnghttp2.so was missing -fvisibility=hidden. libnghttp2_asio.so on the
other hand had hidden visibility which resulted in no exported symbols
and a broken asio client examples.

Just build a static nghttp2 library to solve this issue.
2016-02-16 16:04:01 +01:00
Peter Wu
f4b2a4ab00 cmake: always enable warnings without -Werror
Warnings are useful, let's enable them by default.
2016-02-16 14:57:05 +01:00
Peter Wu
a909eb6b23 cmake: fix linking http-parser into shared libs 2016-02-16 14:09:10 +01:00
Peter Wu
3dd57e1f59 cmake: fix feature availability reporting
Some detected libraries were not reported when a feature is disabled.
This change removes unnecessary second find_package calls and sets
HAVE_xxx immediately based on xxx_FOUND.
2016-02-16 14:01:44 +01:00
Peter Wu
1b67b2d33e cmake: improve Spdylay detection
Auto-detect spdylay availability using CMake, making pkg-config
completely optional.
2016-02-16 12:48:36 +01:00
Peter Wu
9bc6dc7113 cmake: add python support
FindCython.cmake was taken from
https://github.com/thewtex/cython-cmake-example. The UseCython module
works, but since it is lacking an installation target setup.py will be
used instead.
2016-02-16 12:17:49 +01:00
Peter Wu
f407f7f406 cmake: add mruby support, fix tests dir
mruby is always invoked now (mirrors the autotools behavior). It could
be optimized though to only trigger the mruby build when the static
library is missing.

Also fix typo in NGHTTP2_TESTS_DIR macro definition (detected when
invoking the Ninja generator).
2016-02-15 23:14:27 +01:00
Tatsuhiro Tsujikawa
094168a58f Merge branch 'Lekensteyn-tests-fixes' 2016-02-16 00:08:08 +09:00
Peter Wu
474ecc4b47 cmake: add neverbleed support 2016-02-15 10:50:31 +01:00
Peter Wu
0afc21c9d8 cmake: fix compilation in lib
Need to add -fPIC to objects that will be put in a shared library.
2016-02-15 10:49:55 +01:00
Peter Wu
63e43bff99 tests: remove unused macros
Since v0.6.2-7-g1d138ac ("Unify DATA and other frames in
nghttp2_outbound_item and save malloc()"), the macros are unused and the
builds fails on -Werror=unused-macros.
2016-02-15 10:20:13 +01:00
Peter Wu
8c46d9181f cmake: process tests directory
Split the nghttp2 library into objects and a shared library from those
objects. This is needed because of symbol visibility. An advantage over
the autotools build is that there are no worries about static versus
static library builds.

Test:

    cmake $srcdir
    make nghttpx-unittest main failmalloc
    make test
2016-02-15 01:57:13 +01:00
Peter Wu
cc92ebf471 cmake: add auto-detection, improve library search
Add auto-detection to the most important features (app, hpack, etc.).
Move options to a separate file for easier search.

Add cmake-based Libevent, jansson and CUnit search. Move pkg-config
handling for Libev and jemalloc to their cmake files.

Note: duplicates find_package before including CMakeOptions.txt and when
checking for features. Maybe that can be cleaned up later...
2016-02-15 01:12:07 +01:00
Tatsuhiro Tsujikawa
02b7116d42 Merge branch 'nghttpx-replace-unique-ptr-char-with-immutable-string' 2016-02-14 22:36:48 +09:00
Tatsuhiro Tsujikawa
aa3373a107 nghttpx: Use ImmutableString for mruby_file 2016-02-14 22:27:59 +09:00
Tatsuhiro Tsujikawa
7aabc6b125 nghttpx: Use ImmutableString for user 2016-02-14 22:21:55 +09:00
Tatsuhiro Tsujikawa
466e4b7a1e nghttpx: Use ImmutableString for conf_path 2016-02-14 22:20:10 +09:00
Tatsuhiro Tsujikawa
76a425226f nghttpx: Use ImmutableString for pid_file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
2b707bff27 nghttpx: Use ImmutableString for log file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
9055323b67 nghttpx: Use ImmutableString for request_header_file and response_header_file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
67804cfc8c nghttpx: Use ImmutableString for ciphers 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
2344932b45 nghttpx: Use ImmutableString for dh_param_file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
35ebdd35bc nghttpx: Use ImmutableString for private_key_file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
ac81003669 nghttpx: Use ImmutableString for cert_file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
c999987baf nghttpx: Use ImmutableString for private_key_file 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
529a59d309 nghttpx: Use ImmutableString for tls.client_verify.cacert 2016-02-14 22:17:10 +09:00
Tatsuhiro Tsujikawa
52f6417813 nghttpx: Use ImmutableString for tls.cacert 2016-02-14 22:17:00 +09:00
Peter Wu
c96cf1b303 cmake: improve final variable list
Remove build/host/target by a single target system name (CMake is
different for cross-compiling, you are suggested to set
CMAKE_TOOLCHAIN_FILE).

Fix various library variables, remove CFLAGS (INCLUDE_DIRS could be used
instead though, but I consider that minor information that could be
added later if wanted).

Fix various variable names (prefix, boost, etc.).
2016-02-14 13:22:32 +01:00
Tatsuhiro Tsujikawa
660bc389e6 nghttpx: Use ImmutableString for fetch_ocsp_response_file 2016-02-14 21:01:54 +09:00
Tatsuhiro Tsujikawa
bfc26e8299 nghttpx: Use ImmutableString to store memcached server host 2016-02-14 20:59:10 +09:00
Tatsuhiro Tsujikawa
47106c0756 Merge branch 'nghttpx-refactor-downstream-addr-group' 2016-02-14 20:49:30 +09:00
Tatsuhiro Tsujikawa
49fa914db5 nghttpx: Use StringRef for string parameters in match_downstream_addr_group 2016-02-14 20:48:06 +09:00
Tatsuhiro Tsujikawa
93eabc642b nghttpx: Use StringRef for parameter in Router::match 2016-02-14 19:07:22 +09:00
Tatsuhiro Tsujikawa
2d273f8237 nghttpx: Use StringRef for pattern paramter in Router::add_route 2016-02-14 18:55:53 +09:00
Tatsuhiro Tsujikawa
a53f0f0a17 nghttpx: Refactor DownstreamAddrGroup and router API 2016-02-14 18:47:24 +09:00
Tatsuhiro Tsujikawa
1bd98dcf4f nghttpx: Remove user defined ctor/assignment op from DownstreamAddr 2016-02-14 18:31:08 +09:00
Tatsuhiro Tsujikawa
eebed206c9 Add Architecture doc 2016-02-14 18:23:28 +09:00
Tatsuhiro Tsujikawa
fe74600a5f List all contributors in AUTHORS 2016-02-14 17:40:58 +09:00
Tatsuhiro Tsujikawa
08e2d7cdb3 Merge branch 'Lekensteyn-build-fixes' 2016-02-14 16:59:30 +09:00
Peter Wu
503f0a29a7 cmake: add integration-tests 2016-02-13 20:13:43 +01:00
Peter Wu
ee285fa5da cmake: process script/ 2016-02-13 20:13:43 +01:00
Peter Wu
8c562bd38d cmake: process contrib/ 2016-02-13 20:13:43 +01:00
Peter Wu
15adc23277 cmake: working doc (sphinx-build), out-of-tree! 2016-02-13 20:13:43 +01:00
Peter Wu
a2ec695ec9 cmake: add python stub
Might not be the best approach, maybe use thewtex/cython-cmake-example?
2016-02-13 20:13:43 +01:00
Peter Wu
55b270587b cmake: build examples 2016-02-13 20:13:43 +01:00
Peter Wu
5297136bc0 cmake: use PRIVATE instead of PUBLIC
Avoids leaking compile flags to dependents.
2016-02-13 20:13:43 +01:00
Peter Wu
61bb6428fd cmake: add third-party and src
Remaining work:
 - integrate mruby and neverbleed
 - integrate cunit
2016-02-13 20:13:42 +01:00
Peter Wu
ccd2d34160 cmake: Install headers 2016-02-13 20:13:42 +01:00
Peter Wu
ea6eed10c7 cmake: fix version in soname 2016-02-13 20:13:42 +01:00
Peter Wu
7a86758edb cmake: Fix libnghttp2.pc paths
Must be absolute instead of relative
2016-02-13 20:13:42 +01:00
Peter Wu
90d66ea4a9 cmake: fix detection of -Werror flag
Do not use minus sign in macro names.
2016-02-13 20:13:42 +01:00
Peter Wu
5b21c39bb2 cmake: add lib, add versioning info, install lib
Also remove some headers which were not checked anyway and add macros to
cmakeconfig.h.in (based on the headers list in the CMakeLists.txt file).
2016-02-13 20:13:42 +01:00
Peter Wu
744e80d579 cmake: Fill in auto-tools compatible paths 2016-02-13 20:13:42 +01:00
Peter Wu
3842fe175c cmake: attempt to get diagnostic output right 2016-02-13 20:13:42 +01:00
Peter Wu
900667a998 cmake: moar .in file via configure_file 2016-02-13 20:13:42 +01:00
Peter Wu
147e098827 cmake: test for warning flags 2016-02-13 20:13:42 +01:00
Peter Wu
5819d03c68 cmake: more functions
AC_CHECK_TYPES and AC_C_BIGENDIAN were removed because nothing checks
the resulting macros...
2016-02-13 20:13:42 +01:00
Peter Wu
90f5bf796d cmake: check more headers and sizeof 2016-02-13 20:13:42 +01:00
Peter Wu
2b63980758 cmake: more dependency checks 2016-02-13 20:13:42 +01:00
Peter Wu
65d33c553c CMake WIP
Not working:
 - option(... check)
 - not finished everything (see XXX and FIXME)
 - still halway converting
2016-02-13 20:13:42 +01:00
Peter Wu
2593036053 integration-tests: support out-of-tree tests
`go test` requires both config.go and the test files in the same
directory. For out-of-tree builds, config.go is normally not placed next
to the source files, so copy the tests to the build directory as a
workaround.
2016-02-13 20:11:50 +01:00
Peter Wu
a6effb4d23 doc: fix out-of-tree doc builds
Fixes multiple errors while making docs:

    Could not import extension sphinxcontrib.rubydomain (exception: No module named 'sphinxcontrib')

and

    ../../doc/sources/index.rst:15: WARNING: toctree contains reference to nonexisting document 'nghttp.1'
    ../../doc/sources/index.rst:15: WARNING: toctree contains reference to nonexisting document 'nghttpd.1'
    ../../doc/sources/index.rst:15: WARNING: toctree contains reference to nonexisting document 'nghttpx.1'
    ../../doc/sources/index.rst:15: WARNING: toctree contains reference to nonexisting document 'h2load.1'
    ../../doc/sources/index.rst:15: WARNING: toctree contains reference to nonexisting document 'programmers-guide'
2016-02-13 20:11:50 +01:00
Peter Wu
17215002a1 examples: fix compile warnings
Fixes the following two warnings:

    examples/client.c:292:0: error: macro "MAX_OUTLEN" is not used [-Werror=unused-macros]
    examples/tiny-nghttpd.c:298:13: error: function declaration isn’t a prototype [-Werror=strict-prototypes]

Caught using cmake as the autoconf check fails due to unused macros
(HAVE_xxx in conftest.c) and a main function without parameters
respectively.
2016-02-13 20:11:50 +01:00
Peter Wu
0e469ed221 Fix typo in HAVE_CONFIG_H name
Only used by lib/nghttp2_npn.c where the presence of config.h does not
seem to make a difference though.
2016-02-13 20:11:50 +01:00
Tatsuhiro Tsujikawa
093eb51f8c Update default cipher list 2016-02-14 00:44:50 +09:00
Tatsuhiro Tsujikawa
5f1866fd6b Update man pages 2016-02-14 00:29:07 +09:00
Tatsuhiro Tsujikawa
d8c8a4631d nghttpx: Interleave text/html pushed resources with associated resource 2016-02-14 00:28:08 +09:00
Tatsuhiro Tsujikawa
6b12f17f44 Wrap AM_PATH_XML2 by m4_ifdef to handle the case when AM_PATH_XML2 is not found 2016-02-14 00:05:12 +09:00
Tatsuhiro Tsujikawa
eb0c82d91f nghttpx: More log output when resolving addresses for better debugging 2016-02-13 23:21:32 +09:00
Tatsuhiro Tsujikawa
7adfa5dea7 Add note about --enable-app automatic behaviour 2016-02-13 22:39:24 +09:00
Tatsuhiro Tsujikawa
17758126fa nghttpx: Add headers given in add-response-headers for mruby response 2016-02-13 22:31:38 +09:00
Tatsuhiro Tsujikawa
b440f585bc nghttpx: Use Header to store custom request/response header fields 2016-02-13 22:19:05 +09:00
Tatsuhiro Tsujikawa
63a13ccb18 src: Add constexpr to StringRef ctors 2016-02-13 19:15:14 +09:00
Tatsuhiro Tsujikawa
72877379ec nghttpx: Deprecate --backend-ipv4 and --backend-ipv6 in favor of --backend-address-family 2016-02-13 19:09:39 +09:00
Tatsuhiro Tsujikawa
8449958425 doc: Mention encryption for memcached connections 2016-02-13 18:50:15 +09:00
Tatsuhiro Tsujikawa
9037641592 Merge branch 'nghttpx-memcached-tls' 2016-02-13 18:47:06 +09:00
Tatsuhiro Tsujikawa
c0078ab45a nghttpx: Add options to specify address family of memcached connections 2016-02-13 18:46:07 +09:00
Tatsuhiro Tsujikawa
3a41e4dd1a nghttpx: Add encryption support for TLS ticket key retrieval 2016-02-13 18:46:07 +09:00
Tatsuhiro Tsujikawa
3297a303bf nghttpx: Add client auth options for session cache memcached TLS connection 2016-02-13 18:46:07 +09:00
Tatsuhiro Tsujikawa
f1580f95d4 nghttpx: Add TLS support for session cache memcached connection 2016-02-13 18:46:07 +09:00
Tatsuhiro Tsujikawa
1e150bcf61 Merge branch 'jay-refactor-blacklist' 2016-02-13 17:46:11 +09:00
Jay Satiro
ca371e3ba9 nghttpx: Refactor blacklisted cipher suite check 2016-02-12 21:46:29 -05:00
Tatsuhiro Tsujikawa
61dda40b44 Don't pass NULL to memcpy 2016-02-12 22:31:47 +09:00
Tatsuhiro Tsujikawa
5ad753b90c Merge branch 'limit-incoming-headers' 2016-02-11 23:21:02 +09:00
Tatsuhiro Tsujikawa
0a1beea13a asio: client: Limit incoming response header field buffer size 2016-02-11 23:20:31 +09:00
Tatsuhiro Tsujikawa
00e722f02c Add warning 2016-02-11 23:20:31 +09:00
Tatsuhiro Tsujikawa
ff22862b9d nghttp: Limit incoming header field buffer 2016-02-11 23:20:31 +09:00
Tatsuhiro Tsujikawa
b2264ad57e asio: server: Limit incoming request header field buffer size 2016-02-11 23:20:31 +09:00
Tatsuhiro Tsujikawa
b0227d4051 nghttpd: Limit request header buffer 2016-02-11 23:20:31 +09:00
Tatsuhiro Tsujikawa
28b643e531 Fix configure script for non-gcc, clang build 2016-02-11 23:05:16 +09:00
Tatsuhiro Tsujikawa
82f942c3a3 nghttpx: Parameterize configuration values for client side TLS context 2016-02-11 18:34:31 +09:00
Tatsuhiro Tsujikawa
e4a727f86c nghttpx: Cache TLS client session after initial handshake was done 2016-02-11 17:56:20 +09:00
Tatsuhiro Tsujikawa
b624ca6dcd nghttpx: Rename client TLS session cache field 2016-02-11 17:12:57 +09:00
Tatsuhiro Tsujikawa
ba4c268172 nghttpx: Single SSL_SESSION cache entry for each address 2016-02-11 17:07:48 +09:00
Tatsuhiro Tsujikawa
00175eac33 nghttpx: Use Address* as a key for client side session cache 2016-02-11 12:40:15 +09:00
Tatsuhiro Tsujikawa
396dde1347 Mention libspdylay-dev package availability 2016-02-10 21:42:32 +09:00
Tatsuhiro Tsujikawa
042a59117d Merge pull request #504 from davidjb/master
Document compiling apps and include h2load in configure
2016-02-10 21:35:54 +09:00
David Beitey
b8717208c7 Document compiling apps and include h2load in configure 2016-02-10 08:37:43 +10:00
Tatsuhiro Tsujikawa
304ff6a6f9 Don't send extension frame in closing state 2016-02-07 21:12:36 +09:00
Tatsuhiro Tsujikawa
fc39f2d9d2 Merge branch 'master' into simple-extensions 2016-02-07 21:09:08 +09:00
Tatsuhiro Tsujikawa
e14da859b6 Merge branch 'master' into simple-extensions 2016-01-11 16:39:35 +09:00
Tatsuhiro Tsujikawa
0248d979fe Add missing nghttp2_option_set_user_recv_extension_type.rst 2016-01-10 17:08:03 +09:00
Tatsuhiro Tsujikawa
0caefe20ef Merge branch 'master' into simple-extensions 2016-01-09 19:08:28 +09:00
Tatsuhiro Tsujikawa
9c84f60ba0 Merge branch 'master' into simple-extensions 2015-12-04 23:48:40 +09:00
Tatsuhiro Tsujikawa
83cc2511e3 Remove flags parameter from nghttp2_pack_extension_callback
It has no usecase at the moment.  It is most likely that applications
know the flags when it submitted extension frame, no need to modify it
later.  Possibly feature bloat.
2015-11-17 21:29:21 +09:00
Tatsuhiro Tsujikawa
eb4e402aae Merge branch 'master' into simple-extensions 2015-11-14 22:31:52 +09:00
Tatsuhiro Tsujikawa
5d611d2e24 Merge branch 'master' into simple-extensions 2015-10-29 23:24:34 +09:00
Tatsuhiro Tsujikawa
837e716306 Fix compile error with gcc 2015-10-15 00:30:42 +09:00
Tatsuhiro Tsujikawa
061a557839 Add nghttp2_option_set_user_recv_extension_type to opt-in incoming extension type 2015-10-15 00:17:07 +09:00
Tatsuhiro Tsujikawa
d9893d014c Add tests 2015-10-11 17:46:23 +09:00
Tatsuhiro Tsujikawa
3785cf07ba Add simple HTTP/2 extension framework
Application can utilize this framework to send/receive user defined
extension frames.  These frames are expected not to change existing
protocol behaviour.
2015-10-11 17:46:23 +09:00
228 changed files with 16434 additions and 6986 deletions

16
.gitignore vendored
View File

@@ -29,6 +29,22 @@ missing
stamp-h1
test-driver
# cmake
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
install_manifest.txt
CTestTestfile.cmake
build.ninja
rules.ninja
.ninja_deps
.ninja_log
lib*.so
lib*.so.*
lib*.a
# generated by "make test" with cmake
Testing/
# test logs generated by `make check`
*.log
*.trs

View File

@@ -1,3 +1,7 @@
env:
matrix:
- CI_BUILD=cmake
- CI_BUILD=autotools
language: cpp
compiler:
- clang
@@ -7,6 +11,7 @@ addons:
apt:
sources:
- ubuntu-toolchain-r-test
- george-edison55-precise-backports
packages:
- g++-4.9
- libstdc++-4.9-dev
@@ -23,11 +28,14 @@ addons:
- libevent-dev
- libjansson-dev
- libjemalloc-dev
- cmake
- cmake-data
before_install:
- $CC --version
- if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
- $CC --version
- go version
- cmake --version
before_script:
# First build spdylay, since integration tests require it.
# spdylay is going to be built under third-party/spdylay
@@ -40,13 +48,17 @@ before_script:
- export SPDYLAY_HOME=$PWD
- cd ../..
# Now build nghttp2
- autoreconf -i
- if [ "$CI_BUILD" = "autotools" ]; then autoreconf -i; fi
- git submodule update --init
- ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"
- if [ "$CI_BUILD" = "autotools" ]; then ./configure --enable-werror --with-mruby --with-neverbleed LIBSPDYLAY_CFLAGS="-I$SPDYLAY_HOME/lib/includes" LIBSPDYLAY_LIBS="-L$SPDYLAY_HOME/lib/.libs -lspdylay"; fi
- if [ "$CI_BUILD" = "cmake" ]; then cmake -DENABLE_WERROR=1 -DWITH_MRUBY=1 -DWITH_NEVERBLEED=1 -DSPDYLAY_INCLUDE_DIR="$SPDYLAY_HOME/lib/includes" -DSPDYLAY_LIBRARY="$SPDYLAY_HOME/lib/.libs/libspdylay.so"; fi
script:
- make
- make check
- cd integration-tests
- export GOPATH="$PWD/integration-tests/golang"
- make itprep-local
- make it-local
# As of April, 23, 2016, golang http2 build fails, probably because
# the default go version is too old.
# - export GOPATH="$PWD/integration-tests/golang"
# - make itprep
# - make it

86
AUTHORS
View File

@@ -1 +1,85 @@
Tatsuhiro Tsujikawa <t-tujikawa at users dot sourceforge dot net>
nghttp2 project was started as a fork of spdylay project [1]. Both
projects were started by Tatsuhiro Tsujikawa, who is still the main
author of these projects. Meanwhile, we have many contributions, and
we are not here without them. We sincerely thank you to all who made
a contribution. Here is the all individuals/organizations who
contributed to nghttp2 and spdylay project at which we forked. These
names are retrieved from git commit log. If you have made a
contribution, but you are missing in the list, please let us know via
github issues [2].
[1] https://github.com/tatsuhiro-t/spdylay
[2] https://github.com/nghttp2/nghttp2/issues
--------
187j3x1
Alek Storm
Alex Nalivko
Alexis La Goutte
Anders Bakken
Andreas Pohl
Andy Davies
Ant Bryan
Bernard Spil
Brian Card
Brian Suh
Daniel Stenberg
Dave Reisner
David Beitey
David Weekly
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
Kazuho Oku
Kenny (kang-yen) Peng
Kenny Peng
Kit Chan
Kyle Schomp
Lucas Pardue
MATSUMOTO Ryosuke
Mike Conlen
Mike Frysinger
Nicholas Hurley
Nora Shoemaker
Peeyush Aggarwal
Peter Wu
Piotr Sikora
Raul Gutierrez Segales
Remo E
Reza Tavakoli
Ross Smith II
Scott Mitchell
Stefan Eissing
Stephen Ludin
Sunpoet Po-Chuan Hsieh
Svante Signell
Syohei YOSHIDA
Tatsuhiko Kubo
Tatsuhiro Tsujikawa
Tom Harwood
Tomasz Buchert
Vernon Tang
Viacheslav Biriukov
Viktor Szépe
Xiaoguang Sun
Zhuoyun Wei
acesso
ayanamist
bxshi
es
fangdingjun
kumagi
mod-h2-dev
moparisthebest
snnn
yuuki-kodama

524
CMakeLists.txt Normal file
View File

@@ -0,0 +1,524 @@
# nghttp2 - HTTP/2 C Library
#
# Copyright (c) 2012, 2013, 2014, 2015 Tatsuhiro Tsujikawa
# Copyright (c) 2016 Peter Wu <peter@lekensteyn.nl>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cmake_minimum_required(VERSION 3.0)
# XXX using 1.8.90 instead of 1.9.0-DEV
project(nghttp2 VERSION 1.11.90)
# See versioning rule:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
set(LT_CURRENT 22)
set(LT_REVISION 0)
set(LT_AGE 8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(Version)
math(EXPR LT_SOVERSION "${LT_CURRENT} - ${LT_AGE}")
set(LT_VERSION "${LT_SOVERSION}.${LT_AGE}.${LT_REVISION}")
set(PACKAGE_VERSION "${PROJECT_VERSION}")
HexVersion(PACKAGE_VERSION_NUM ${PROJECT_VERSION_MAJOR} ${PROJECT_VERSION_MINOR} ${PROJECT_VERSION_PATCH})
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the build type" FORCE)
# Include "None" as option to disable any additional (optimization) flags,
# relying on just CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (which are empty by
# default). These strings are presented in cmake-gui.
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
include(GNUInstallDirs)
# For Python bindings and documentation
# (Must be called before PythonLibs for matching versions.)
find_package(PythonInterp)
# Auto-detection of features that can be toggled
find_package(OpenSSL 1.0.1)
find_package(Libev 4.11)
find_package(ZLIB 1.2.3)
if(OPENSSL_FOUND AND LIBEV_FOUND AND ZLIB_FOUND)
set(ENABLE_APP_DEFAULT ON)
else()
set(ENABLE_APP_DEFAULT OFF)
endif()
find_package(Jansson 2.5)
set(ENABLE_HPACK_TOOLS_DEFAULT ${JANSSON_FOUND})
# 2.0.8 is required because we use evconnlistener_set_error_cb()
find_package(Libevent 2.0.8 COMPONENTS libevent openssl)
set(ENABLE_EXAMPLES_DEFAULT ${LIBEVENT_OPENSSL_FOUND})
find_package(Cython)
find_package(PythonLibs)
if(CYTHON_FOUND AND PYTHONLIBS_FOUND)
set(ENABLE_PYTHON_BINDINGS_DEFAULT ON)
else()
set(ENABLE_PYTHON_BINDINGS_DEFAULT OFF)
endif()
find_package(LibXml2 2.7.7)
set(WITH_LIBXML2_DEFAULT ${LIBXML2_FOUND})
find_package(Jemalloc)
set(WITH_JEMALLOC_DEFAULT ${JEMALLOC_FOUND})
find_package(Spdylay 1.3.2)
set(WITH_SPDYLAY_DEFAULT ${SPDYLAY_FOUND})
include(CMakeOptions.txt)
if(ENABLE_LIB_ONLY AND (ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_EXAMPLES OR
ENABLE_PYTHON_BINDINGS))
# Remember when disabled options are disabled for later diagnostics.
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 1)
else()
set(ENABLE_LIB_ONLY_DISABLED_OTHERS 0)
endif()
if(ENABLE_LIB_ONLY)
set(ENABLE_APP OFF)
set(ENABLE_HPACK_TOOLS OFF)
set(ENABLE_EXAMPLES OFF)
set(ENABLE_PYTHON_BINDINGS OFF)
endif()
# Do not disable assertions based on CMAKE_BUILD_TYPE.
foreach(_build_type "Release" "MinSizeRel" "RelWithDebInfo")
foreach(_lang C CXX)
string(TOUPPER "CMAKE_${_lang}_FLAGS_${_build_type}" _var)
string(REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" "" ${_var} "${${_var}}")
endforeach()
endforeach()
#
# If we're running GCC or clang define _U_ to be "__attribute__((unused))"
# so we can use _U_ to flag unused function parameters and not get warnings
# about them. Otherwise, define _U_ to be an empty string so that _U_ used
# to flag an unused function parameters will compile with other compilers.
#
# XXX - similar hints for other compilers?
#
if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(HINT_UNUSED_PARAM "__attribute__((unused))")
set(HINT_NORETURN "__attribute__((noreturn))")
else()
set(HINT_UNUSED_PARAM)
set(HINT_NORETURN)
endif()
include(ExtractValidFlags)
foreach(_cxx1x_flag -std=c++11 -std=c++0x)
extract_valid_cxx_flags(_cxx1x_flag_supported ${_cxx1x_flag})
if(_cxx1x_flag_supported)
set(CXX1XCXXFLAGS ${_cxx1x_flag})
break()
endif()
endforeach()
include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
cmake_push_check_state()
set(CMAKE_REQUIRED_DEFINITIONS "${CXX1XCXXFLAGS}")
# Check that std::future is available.
check_cxx_source_compiles("
#include <vector>
#include <future>
int main() { std::vector<std::future<int>> v; }" HAVE_STD_FUTURE)
# Check that std::map::emplace is available for g++-4.7.
check_cxx_source_compiles("
#include <map>
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
cmake_pop_check_state()
# Checks for libraries.
# Additional libraries required for programs under src directory.
set(APP_LIBRARIES)
if(ENABLE_PYTHON_BINDINGS)
if(NOT (CYTHON_FOUND AND PYTHONLIBS_FOUND))
message(FATAL_ERROR "python bindings were requested "
"(ENABLE_PYTHON_BINDINGS=1) but dependencies are not met.")
endif()
if(NOT PYTHON_VERSION_STRING STREQUAL PYTHONLIBS_VERSION_STRING)
message(FATAL_ERROR
"Python executable and library must have the same version!"
" Found Python ${PYTHON_VERSION_STRING} and"
" PythonLibs ${PYTHONLIBS_VERSION_STRING}"
)
endif()
endif()
set(CMAKE_THREAD_PREFER_PTHREAD 1)
find_package(Threads)
if(CMAKE_USE_PTHREADS_INIT)
list(APPEND APP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT})
endif()
# XXX android and C++, is this still needed in cmake?
# case "$host" in
# *android*)
# android_build=yes
# # android does not need -pthread, but needs followng 3 libs for C++
# APPLDFLAGS="$APPLDFLAGS -lstdc++ -latomic -lsupc++"
# dl: openssl requires libdl when it is statically linked.
# XXX shouldn't ${CMAKE_DL_LIBS} be appended to OPENSSL_LIBRARIES instead of
# APP_LIBRARIES if it is really specific to OpenSSL?
find_package(CUnit 2.1)
enable_testing()
set(HAVE_CUNIT ${CUNIT_FOUND})
if(HAVE_CUNIT)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
endif()
# openssl (for src)
set(HAVE_OPENSSL ${OPENSSL_FOUND})
if(OPENSSL_FOUND)
set(OPENSSL_INCLUDE_DIRS ${OPENSSL_INCLUDE_DIR})
else()
set(OPENSSL_INCLUDE_DIRS "")
set(OPENSSL_LIBRARIES "")
endif()
# libev (for src)
set(HAVE_LIBEV ${LIBEV_FOUND})
set(HAVE_ZLIB ${ZLIB_FOUND})
set(HAVE_LIBEVENT_OPENSSL ${LIBEVENT_FOUND})
if(LIBEVENT_FOUND)
# Must both link the core and openssl libraries.
set(LIBEVENT_OPENSSL_LIBRARIES ${LIBEVENT_LIBRARIES})
endif()
# jansson (for src/nghttp, src/deflatehd and src/inflatehd)
set(HAVE_JANSSON ${JANSSON_FOUND})
# libxml2 (for src/nghttp)
set(HAVE_LIBXML2 ${LIBXML2_FOUND})
if(LIBXML2_FOUND)
set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
else()
set(LIBXML2_INCLUDE_DIRS "")
set(LIBXML2_LIBRARIES "")
endif()
# jemalloc
set(HAVE_JEMALLOC ${JEMALLOC_FOUND})
# spdylay (for src/nghttpx and src/h2load)
set(HAVE_SPDYLAY ${SPDYLAY_FOUND})
if(ENABLE_ASIO_LIB)
find_package(Boost 1.54.0 REQUIRED system thread)
endif()
# The nghttp, nghttpd and nghttpx under src depend on zlib, OpenSSL and libev
if(ENABLE_APP AND NOT (ZLIB_FOUND AND OPENSSL_FOUND AND LIBEV_FOUND))
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
endif()
# HPACK tools requires jansson
if(ENABLE_HPACK_TOOLS AND NOT HAVE_JANSSON)
message(FATAL_ERROR "HPACK tools were requested (ENABLE_HPACK_TOOLS=1) but dependencies are not met.")
endif()
# C++ library libnghttp2_asio
if(ENABLE_EXAMPLES AND NOT (OPENSSL_FOUND AND LIBEVENT_OPENSSL_FOUND))
message(FATAL_ERROR "examples were requested (ENABLE_EXAMPLES=1) but dependencies are not met.")
endif()
# third-party http-parser only be built when needed
if(ENABLE_EXAMPLES OR ENABLE_APP OR ENABLE_HPACK_TOOLS OR ENABLE_ASIO_LIB)
set(ENABLE_THIRD_PARTY 1)
# mruby (for src/nghttpx)
set(HAVE_MRUBY ${WITH_MRUBY})
set(HAVE_NEVERBLEED ${WITH_NEVERBLEED})
else()
set(HAVE_MRUBY 0)
set(HAVE_NEVERBLEED 0)
endif()
# Checks for header files.
include(CheckIncludeFile)
check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
check_include_file("inttypes.h" HAVE_INTTYPES_H)
check_include_file("limits.h" HAVE_LIMITS_H)
check_include_file("netdb.h" HAVE_NETDB_H)
check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
check_include_file("pwd.h" HAVE_PWD_H)
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
check_include_file("syslog.h" HAVE_SYSLOG_H)
check_include_file("time.h" HAVE_TIME_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
include(CheckTypeSize)
# Checks for typedefs, structures, and compiler characteristics.
# AC_TYPE_SIZE_T
check_type_size("ssize_t" SIZEOF_SSIZE_T)
if(SIZEOF_SSIZE_T STREQUAL "")
# ssize_t is a signed type in POSIX storing at least -1.
# Set it to "int" to match the behavior of AC_TYPE_SSIZE_T (autotools).
set(ssize_t int)
endif()
# AC_TYPE_UINT8_T
# AC_TYPE_UINT16_T
# AC_TYPE_UINT32_T
# AC_TYPE_UINT64_T
# AC_TYPE_INT8_T
# AC_TYPE_INT16_T
# AC_TYPE_INT32_T
# AC_TYPE_INT64_T
# AC_TYPE_OFF_T
# AC_TYPE_PID_T
# AC_TYPE_UID_T
# XXX To support inline for crappy compilers, see https://cmake.org/Wiki/CMakeTestInline
# AC_C_INLINE
# XXX is AC_SYS_LARGEFILE still needed for modern systems?
# add_definitions(-D_FILE_OFFSET_BITS=64)
include(CheckStructHasMember)
check_struct_has_member("struct tm" tm_gmtoff time.h HAVE_STRUCT_TM_TM_GMTOFF)
# Check size of pointer to decide we need 8 bytes alignment adjustment.
check_type_size("int *" SIZEOF_INT_P)
check_type_size("time_t" SIZEOF_TIME_T)
# Checks for library functions.
include(CheckFunctionExists)
check_function_exists(_Exit HAVE__EXIT)
check_function_exists(accept4 HAVE_ACCEPT4)
# timerfd_create was added in linux kernel 2.6.25
include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin?
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
# FreeBSD declares initgroups() in unistd.h
check_symbol_exists(initgroups unistd.h HAVE_DECL_INITGROUPS2)
if(HAVE_DECL_INITGROUPS2)
set(HAVE_DECL_INITGROUPS 1)
endif()
endif()
check_function_exists(timerfd_create HAVE_TIMERFD_CREATE)
# Checks for epoll availability, primarily for examples/tiny-nghttpd
check_symbol_exists(epoll_create sys/epoll.h HAVE_EPOLL)
if(HAVE_EPOLL AND HAVE_TIMERFD_CREATE)
set(ENABLE_TINY_NGHTTPD 1)
endif()
set(WARNCFLAGS)
set(WARNCXXFLAGS)
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
if(ENABLE_WERROR)
set(WARNCFLAGS /WX)
set(WARNCXXFLAGS /WX)
endif()
else()
if(ENABLE_WERROR)
extract_valid_c_flags(WARNCFLAGS -Werror)
extract_valid_c_flags(WARNCXXFLAGS -Werror)
endif()
# For C compiler
extract_valid_c_flags(WARNCFLAGS
-Wall
-Wextra
-Wmissing-prototypes
-Wstrict-prototypes
-Wmissing-declarations
-Wpointer-arith
-Wdeclaration-after-statement
-Wformat-security
-Wwrite-strings
-Wshadow
-Winline
-Wnested-externs
-Wfloat-equal
-Wundef
-Wendif-labels
-Wempty-body
-Wcast-align
-Wclobbered
-Wvla
-Wpragmas
-Wunreachable-code
-Waddress
-Wattributes
-Wdiv-by-zero
-Wshorten-64-to-32
-Wconversion
-Wextended-offsetof
-Wformat-nonliteral
-Wlanguage-extension-token
-Wmissing-field-initializers
-Wmissing-noreturn
-Wmissing-variable-declarations
# Not used because we cannot change public structs
# -Wpadded
-Wsign-conversion
# Not used because this basically disallows default case
# -Wswitch-enum
-Wunreachable-code-break
-Wunused-macros
-Wunused-parameter
-Wredundant-decls
# Only work with Clang for the moment
-Wheader-guard
# This is required because we pass format string as "const char*.
-Wno-format-nonliteral
)
extract_valid_cxx_flags(WARNCXXFLAGS
# For C++ compiler
-Wall
-Wformat-security
)
endif()
if(ENABLE_DEBUG)
set(DEBUGBUILD 1)
endif()
# Some platform does not have working std::future. We disable
# threading for those platforms.
if(NOT ENABLE_THREADS OR NOT HAVE_STD_FUTURE)
set(NOTHREADS 1)
endif()
add_definitions(-DHAVE_CONFIG_H)
configure_file(cmakeconfig.h.in config.h)
# autotools-compatible names
# Sphinx expects relative paths in the .rst files. Use the fact that the files
# below are all one directory level deep.
file(RELATIVE_PATH top_srcdir "${CMAKE_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}")
# libnghttp2.pc (pkg-config file)
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "${CMAKE_INSTALL_PREFIX}")
set(libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
set(includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
set(VERSION "${PACKAGE_VERSION}")
# For init scripts and systemd service file (in contrib/)
set(bindir "${CMAKE_INSTALL_FULL_BINDIR}")
set(sbindir "${CMAKE_INSTALL_FULL_SBINDIR}")
foreach(name
lib/libnghttp2.pc
lib/includes/nghttp2/nghttp2ver.h
src/libnghttp2_asio.pc
python/setup.py
integration-tests/config.go
integration-tests/setenv
doc/conf.py
doc/index.rst
doc/package_README.rst
doc/tutorial-client.rst
doc/tutorial-server.rst
doc/tutorial-hpack.rst
doc/nghttpx-howto.rst
doc/h2load-howto.rst
doc/libnghttp2_asio.rst
doc/python-apiref.rst
doc/building-android-binary.rst
doc/nghttp2.h.rst
doc/nghttp2ver.h.rst
doc/asio_http2.h.rst
doc/asio_http2_server.h.rst
doc/asio_http2_client.h.rst
doc/contribute.rst
)
configure_file("${name}.in" "${name}" @ONLY)
endforeach()
include_directories(
"${CMAKE_BINARY_DIR}" # for config.h
)
# For use in src/CMakeLists.txt
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}")
install(FILES README.rst DESTINATION "${CMAKE_INSTALL_DOCDIR}")
add_subdirectory(lib)
#add_subdirectory(lib/includes)
add_subdirectory(third-party)
add_subdirectory(src)
#add_subdirectory(src/includes)
add_subdirectory(examples)
add_subdirectory(python)
add_subdirectory(tests)
#add_subdirectory(tests/testdata)
add_subdirectory(integration-tests)
add_subdirectory(doc)
add_subdirectory(contrib)
add_subdirectory(script)
string(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type)
message(STATUS "summary of build options:
Package version: ${VERSION}
Library version: ${LT_CURRENT}:${LT_REVISION}:${LT_AGE}
Install prefix: ${CMAKE_INSTALL_PREFIX}
Target system: ${CMAKE_SYSTEM_NAME}
Compiler:
Build type: ${CMAKE_BUILD_TYPE}
C compiler: ${CMAKE_C_COMPILER}
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
C++ compiler: ${CMAKE_CXX_COMPILER}
CXXFLAGS: ${CMAKE_CXX_FLAGS_${_build_type}} ${CMAKE_CXX_FLAGS}
WARNCFLAGS: ${WARNCFLAGS}
CXX1XCXXFLAGS: ${CXX1XCXXFLAGS}
Python:
Python: ${PYTHON_EXECUTABLE}
PYTHON_VERSION: ${PYTHON_VERSION_STRING}
Library version:${PYTHONLIBS_VERSION_STRING}
Cython: ${CYTHON_EXECUTABLE}
Test:
CUnit: ${HAVE_CUNIT} (LIBS='${CUNIT_LIBRARIES}')
Failmalloc: ${ENABLE_FAILMALLOC}
Libs:
OpenSSL: ${HAVE_OPENSSL} (LIBS='${OPENSSL_LIBRARIES}')
Libxml2: ${HAVE_LIBXML2} (LIBS='${LIBXML2_LIBRARIES}')
Libev: ${HAVE_LIBEV} (LIBS='${LIBEV_LIBRARIES}')
Libevent(SSL): ${HAVE_LIBEVENT_OPENSSL} (LIBS='${LIBEVENT_OPENSSL_LIBRARIES}')
Spdylay: ${HAVE_SPDYLAY} (LIBS='${SPDYLAY_LIBRARIES}')
Jansson: ${HAVE_JANSSON} (LIBS='${JANSSON_LIBRARIES}')
Jemalloc: ${HAVE_JEMALLOC} (LIBS='${JEMALLOC_LIBRARIES}')
Zlib: ${HAVE_ZLIB} (LIBS='${ZLIB_LIBRARIES}')
Boost::System: ${Boost_SYSTEM_LIBRARY}
Boost::Thread: ${Boost_THREAD_LIBRARY}
Third-party:
http-parser: ${ENABLE_THIRD_PARTY}
MRuby: ${HAVE_MRUBY}
Neverbleed: ${HAVE_NEVERBLEED}
Features:
Applications: ${ENABLE_APP}
HPACK tools: ${ENABLE_HPACK_TOOLS}
Libnghttp2_asio:${ENABLE_ASIO_LIB}
Examples: ${ENABLE_EXAMPLES}
Python bindings:${ENABLE_PYTHON_BINDINGS}
Threading: ${ENABLE_THREADS}
")
if(ENABLE_LIB_ONLY_DISABLED_OTHERS)
message("Only the library will be built. To build other components "
"(such as applications and examples), set ENABLE_LIB_ONLY=OFF.")
endif()

27
CMakeOptions.txt Normal file
View File

@@ -0,0 +1,27 @@
# Features that can be enabled for cmake (see CMakeLists.txt)
option(ENABLE_WERROR "Turn on compile time warnings")
option(ENABLE_DEBUG "Turn on debug output")
option(ENABLE_THREADS "Turn on threading in apps" ON)
option(ENABLE_APP "Build applications (nghttp, nghttpd, nghttpx and h2load)"
${ENABLE_APP_DEFAULT})
option(ENABLE_HPACK_TOOLS "Build HPACK tools"
${ENABLE_HPACK_TOOLS_DEFAULT})
option(ENABLE_ASIO_LIB "Build C++ libnghttp2_asio library")
option(ENABLE_EXAMPLES "Build examples"
${ENABLE_EXAMPLES_DEFAULT})
option(ENABLE_PYTHON_BINDINGS "Build Python bindings"
${ENABLE_PYTHON_BINDINGS_DEFAULT})
option(ENABLE_FAILMALLOC "Build failmalloc test program" ON)
option(ENABLE_LIB_ONLY "Build libnghttp2 only. This is a short hand for -DENABLE_APP=0 -DENABLE_EXAMPLES=0 -DENABLE_HPACK_TOOLS=0 -DENABLE_PYTHON_BINDINGS=0")
option(WITH_LIBXML2 "Use libxml2"
${WITH_LIBXML2_DEFAULT})
option(WITH_JEMALLOC "Use jemalloc"
${WITH_JEMALLOC_DEFAULT})
option(WITH_SPDYLAY "Use spdylay"
${WITH_SPDYLAY_DEFAULT})
option(WITH_MRUBY "Use mruby")
option(WITH_NEVERBLEED "Use neverbleed")
# vim: ft=cmake:

View File

@@ -1,6 +1,7 @@
The MIT License
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -106,7 +106,7 @@ RUN HOST=arm-linux-androideabi \
make install
WORKDIR /root/build
RUN git clone https://github.com/tatsuhiro-t/nghttp2
RUN git clone https://github.com/nghttp2/nghttp2
WORKDIR /root/build/nghttp2
RUN autoreconf -i && \
./configure \

View File

@@ -33,7 +33,19 @@ ACLOCAL_AMFLAGS = -I m4
dist_doc_DATA = README.rst
EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-make \
Dockerfile.android
Dockerfile.android \
cmakeconfig.h.in \
CMakeLists.txt \
CMakeOptions.txt \
cmake/FindSpdylay.cmake \
cmake/ExtractValidFlags.cmake \
cmake/FindJemalloc.cmake \
cmake/FindLibev.cmake \
cmake/FindCUnit.cmake \
cmake/Version.cmake \
cmake/FindCython.cmake \
cmake/FindLibevent.cmake \
cmake/FindJansson.cmake
.PHONY: clang-format

View File

@@ -58,12 +58,12 @@ To build the documentation, you need to install:
* sphinx (http://sphinx-doc.org/)
To build and run the application programs (``nghttp``, ``nghttpd`` and
``nghttpx``) in the ``src`` directory, the following packages are
required:
To build and run the application programs (``nghttp``, ``nghttpd``,
``nghttpx`` and ``h2load``) in the ``src`` directory, the following packages
are required:
* OpenSSL >= 1.0.1
* libev >= 4.15
* libev >= 4.11
* zlib >= 1.2.3
ALPN support requires OpenSSL >= 1.0.2 (released 22 January 2015).
@@ -104,14 +104,17 @@ 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 \
libjemalloc-dev cython python3-dev python-setuptools
spdylay is not packaged in Ubuntu, so you need to build it yourself:
http://tatsuhiro-t.github.io/spdylay/
From Ubuntu 15.10, spdylay has been available as a package named
`libspdylay-dev`. For the earlier Ubuntu release, you need to build
it yourself: http://tatsuhiro-t.github.io/spdylay/
To enable mruby support for nghttpx, `mruby
<https://github.com/mruby/mruby>`_ is required. We need to build
@@ -137,7 +140,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
@@ -160,6 +165,17 @@ To compile the source code, gcc >= 4.8.3 or clang >= 3.4 is required.
them from crashing. A patch is welcome to make multi threading work
on Mac OS X platform.
.. note::
To compile the associated applications (nghttp, nghttpd, nghttpx
and h2load), you must use the ``--enable-app`` configure option and
ensure that the specified requirements above are met. Normally,
configure script checks required dependencies to build these
applications, and enable ``--enable-app`` automatically, so you
don't have to use it explicitly. But if you found that
applications were not built, then using ``--enable-app`` may find
that cause, such as the missing dependency.
Notes for building on Windows (Mingw/Cygwin)
--------------------------------------------
@@ -176,7 +192,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
@@ -194,7 +212,9 @@ Building the documentation
Documentation is still incomplete.
To build the documentation, run::
To build the documentation, run:
.. code-block:: text
$ make html
@@ -223,12 +243,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
@@ -349,7 +373,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
@@ -432,7 +458,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
@@ -528,7 +556,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 *****
@@ -572,7 +602,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
@@ -635,6 +667,14 @@ nghttpx - proxy
HTTP/1.1, and powers http://nghttp2.org and supports HTTP/2 server
push.
We reworked ``nghttpx`` command-line interface, and as a result, there
are several incompatibles from 1.8.0 or earlier. This is necessary to
extend its capability, and secure the further feature enhancements in
the future release. Please read `Migration from nghttpx v1.8.0 or
earlier
<https://nghttp2.org/documentation/nghttpx-howto.html#migration-from-nghttpx-v1-8-0-or-earlier>`_
to know how to migrate from earlier releases.
``nghttpx`` implements `important performance-oriented features
<https://istlsfastyet.com/#server-performance>`_ in TLS, such as
session IDs, session tickets (with automatic key rotation), OCSP
@@ -643,46 +683,42 @@ HTTP/2. ``nghttpx`` also offers the functionality to share session
cache and ticket keys among multiple ``nghttpx`` instances via
memcached.
``nghttpx`` has several operational modes:
``nghttpx`` has 2 operation modes:
================== ============================ ============== =============
Mode option Frontend Backend Note
================== ============================ ============== =============
default mode HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 Reverse proxy
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/1.1 SPDY proxy
``--http2-bridge`` HTTP/2, SPDY, HTTP/1.1 (TLS) HTTP/2 (TLS)
``--client`` HTTP/2, HTTP/1.1 HTTP/2 (TLS)
``--client-proxy`` HTTP/2, HTTP/1.1 HTTP/2 (TLS) Forward proxy
================== ============================ ============== =============
================== ====================== ================ =============
Mode option Frontend Backend Note
================== ====================== ================ =============
default mode HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Reverse proxy
``--http2-proxy`` HTTP/2, SPDY, HTTP/1.1 HTTP/1.1, HTTP/2 Forward proxy
================== ====================== ================ =============
The interesting mode at the moment is the default mode. It works like
a reverse proxy and listens for HTTP/2, SPDY and HTTP/1.1 and can be
deployed as a SSL/TLS terminator for existing web server.
The default mode, ``--http2-proxy`` and ``--http2-bridge`` modes use
SSL/TLS in the frontend connection by default. To disable SSL/TLS,
use the ``--frontend-no-tls`` option. If that option is used, SPDY is
disabled in the frontend and incoming HTTP/1.1 connections can be
upgraded to HTTP/2 through HTTP Upgrade. In these modes, HTTP/1
backend connections are cleartext by default. To enable TLS, use
``--backend-http1-tls`` opiton.
The ``--http2-bridge``, ``--client`` and ``--client-proxy`` modes use
SSL/TLS in the backend connection by default. To disable SSL/TLS, use
the ``--backend-no-tls`` option.
In all modes, the frontend connections are encrypted by SSL/TLS by
default. To disable encryption, use the ``no-tls`` keyword in
``--frontend`` option. If encryption is disabled, SPDY is disabled in
the frontend and incoming HTTP/1.1 connections can be upgraded to
HTTP/2 through HTTP Upgrade. On the other hard, backend connections
are not encrypted by default. To encrypt backend connections, use
``tls`` keyword in ``--backend`` option.
``nghttpx`` supports a configuration file. See the ``--conf`` option and
sample configuration file ``nghttpx.conf.sample``.
In the default mode, (without any of ``--http2-proxy``,
``--http2-bridge``, ``--client-proxy`` and ``--client`` options),
``nghttpx`` works as reverse proxy to the backend server::
In the default mode, ``nghttpx`` works as reverse proxy to the backend
server:
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Web Server
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1, HTTP/2) --> Web Server
[reverse proxy]
With the ``--http2-proxy`` option, it works as a so called secure proxy (aka
SPDY proxy)::
With the ``--http2-proxy`` option, it works as forward proxy, and it
is so called secure HTTP/2 proxy (aka SPDY proxy):
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/1.1) --> Proxy
[secure proxy] (e.g., Squid, ATS)
@@ -690,9 +726,9 @@ SPDY proxy)::
The ``Client`` in the above example needs to be configured to use
``nghttpx`` as secure proxy.
At the time of this writing, Chrome is the only browser which supports
secure proxy. One way to configure Chrome to use a secure proxy is
to create a proxy.pac script like this:
At the time of this writing, both Chrome and Firefox support secure
HTTP/2 proxy. One way to configure Chrome to use a secure proxy is to
create a proxy.pac script like this:
.. code-block:: javascript
@@ -704,42 +740,18 @@ to create a proxy.pac script like this:
machine nghttpx is running on. Please note that Chrome requires a valid
certificate for secure proxy.
Then run Chrome with the following arguments::
Then run Chrome with the following arguments:
.. code-block:: text
$ google-chrome --proxy-pac-url=file:///path/to/proxy.pac --use-npn
With ``--http2-bridge``, it accepts HTTP/2, SPDY and HTTP/1.1
connections and communicates with the backend in HTTP/2::
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web or HTTP/2 Proxy etc
(e.g., nghttpx -s)
With ``--client-proxy``, it works as a forward proxy and expects
that the backend is an HTTP/2 proxy::
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> HTTP/2 Proxy
[forward proxy] (e.g., nghttpx -s)
The ``Client`` needs to be configured to use nghttpx as a forward
proxy. The frontend HTTP/1.1 connection can be upgraded to HTTP/2
through HTTP Upgrade. With the above configuration, one can use
HTTP/1.1 client to access and test their HTTP/2 servers.
With ``--client``, it works as a reverse proxy and expects that
the backend is an HTTP/2 Web server::
Client <-- (HTTP/2, HTTP/1.1) --> nghttpx <-- (HTTP/2) --> Web Server
[reverse proxy]
The frontend HTTP/1.1 connection can be upgraded to HTTP/2
through HTTP Upgrade.
For the operation modes which talk to the backend in HTTP/2 over
SSL/TLS, the backend connections can be tunneled through an HTTP proxy.
The backend HTTP/2 connections can be tunneled through an HTTP proxy.
The proxy is specified using ``--backend-http-proxy-uri``. The
following figure illustrates the example of the ``--http2-bridge`` and
``--backend-http-proxy-uri`` options to talk to the outside HTTP/2
proxy through an HTTP proxy::
following figure illustrates how nghttpx talks to the outside HTTP/2
proxy through an HTTP proxy:
.. code-block:: text
Client <-- (HTTP/2, SPDY, HTTP/1.1) --> nghttpx <-- (HTTP/2) --
@@ -753,7 +765,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...
@@ -841,7 +855,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

View File

@@ -0,0 +1,31 @@
# Convenience function that checks the availability of certain
# C or C++ compiler flags and returns valid ones as a string.
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
function(extract_valid_c_flags varname)
set(valid_flags)
foreach(flag IN LISTS ARGN)
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
set(flag_var "C_FLAG_${flag_var}")
check_c_compiler_flag("${flag}" "${flag_var}")
if(${flag_var})
set(valid_flags "${valid_flags} ${flag}")
endif()
endforeach()
set(${varname} "${valid_flags}" PARENT_SCOPE)
endfunction()
function(extract_valid_cxx_flags varname)
set(valid_flags)
foreach(flag IN LISTS ARGN)
string(REGEX REPLACE "[^a-zA-Z0-9_]+" "_" flag_var ${flag})
set(flag_var "CXX_FLAG_${flag_var}")
check_cxx_compiler_flag("${flag}" "${flag_var}")
if(${flag_var})
set(valid_flags "${valid_flags} ${flag}")
endif()
endforeach()
set(${varname} "${valid_flags}" PARENT_SCOPE)
endfunction()

40
cmake/FindCUnit.cmake Normal file
View File

@@ -0,0 +1,40 @@
# - Try to find cunit
# Once done this will define
# CUNIT_FOUND - System has cunit
# CUNIT_INCLUDE_DIRS - The cunit include directories
# CUNIT_LIBRARIES - The libraries needed to use cunit
find_package(PkgConfig QUIET)
pkg_check_modules(PC_CUNIT QUIET cunit)
find_path(CUNIT_INCLUDE_DIR
NAMES CUnit/CUnit.h
HINTS ${PC_CUNIT_INCLUDE_DIRS}
)
find_library(CUNIT_LIBRARY
NAMES cunit
HINTS ${PC_CUNIT_LIBRARY_DIRS}
)
if(CUNIT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+CU_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${CUNIT_INCLUDE_DIR}/CUnit/CUnit.h"
CUNIT_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
CUNIT_VERSION "${CUNIT_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set CUNIT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(CUnit REQUIRED_VARS
CUNIT_LIBRARY CUNIT_INCLUDE_DIR
VERSION_VAR CUNIT_VERSION)
if(CUNIT_FOUND)
set(CUNIT_LIBRARIES ${CUNIT_LIBRARY})
set(CUNIT_INCLUDE_DIRS ${CUNIT_INCLUDE_DIR})
endif()
mark_as_advanced(CUNIT_INCLUDE_DIR CUNIT_LIBRARY)

44
cmake/FindCython.cmake Normal file
View File

@@ -0,0 +1,44 @@
# Find the Cython compiler.
#
# This code sets the following variables:
#
# CYTHON_EXECUTABLE
#
# See also UseCython.cmake
#=============================================================================
# Copyright 2011 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Use the Cython executable that lives next to the Python executable
# if it is a local installation.
find_package( PythonInterp )
if( PYTHONINTERP_FOUND )
get_filename_component( _python_path ${PYTHON_EXECUTABLE} PATH )
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
HINTS ${_python_path}
)
else()
find_program( CYTHON_EXECUTABLE
NAMES cython cython.bat cython3
)
endif()
include( FindPackageHandleStandardArgs )
FIND_PACKAGE_HANDLE_STANDARD_ARGS( Cython REQUIRED_VARS CYTHON_EXECUTABLE )
mark_as_advanced( CYTHON_EXECUTABLE )

40
cmake/FindJansson.cmake Normal file
View File

@@ -0,0 +1,40 @@
# - Try to find jansson
# Once done this will define
# JANSSON_FOUND - System has jansson
# JANSSON_INCLUDE_DIRS - The jansson include directories
# JANSSON_LIBRARIES - The libraries needed to use jansson
find_package(PkgConfig QUIET)
pkg_check_modules(PC_JANSSON QUIET jansson)
find_path(JANSSON_INCLUDE_DIR
NAMES jansson.h
HINTS ${PC_JANSSON_INCLUDE_DIRS}
)
find_library(JANSSON_LIBRARY
NAMES jansson
HINTS ${PC_JANSSON_LIBRARY_DIRS}
)
if(JANSSON_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+JANSSON_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${JANSSON_INCLUDE_DIR}/jansson.h"
JANSSON_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
JANSSON_VERSION "${JANSSON_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JANSSON_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Jansson REQUIRED_VARS
JANSSON_LIBRARY JANSSON_INCLUDE_DIR
VERSION_VAR JANSSON_VERSION)
if(JANSSON_FOUND)
set(JANSSON_LIBRARIES ${JANSSON_LIBRARY})
set(JANSSON_INCLUDE_DIRS ${JANSSON_INCLUDE_DIR})
endif()
mark_as_advanced(JANSSON_INCLUDE_DIR JANSSON_LIBRARY)

40
cmake/FindJemalloc.cmake Normal file
View File

@@ -0,0 +1,40 @@
# - Try to find jemalloc
# Once done this will define
# JEMALLOC_FOUND - System has jemalloc
# JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
# JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
find_package(PkgConfig QUIET)
pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
find_path(JEMALLOC_INCLUDE_DIR
NAMES jemalloc/jemalloc.h
HINTS ${PC_JEMALLOC_INCLUDE_DIRS}
)
find_library(JEMALLOC_LIBRARY
NAMES jemalloc
HINTS ${PC_JEMALLOC_LIBRARY_DIRS}
)
if(JEMALLOC_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+JEMALLOC_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${JEMALLOC_INCLUDE_DIR}/jemalloc/jemalloc.h"
JEMALLOC_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
JEMALLOC_VERSION "${JEMALLOC_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Jemalloc REQUIRED_VARS
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR
VERSION_VAR JEMALLOC_VERSION)
if(JEMALLOC_FOUND)
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
endif()
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)

38
cmake/FindLibev.cmake Normal file
View File

@@ -0,0 +1,38 @@
# - Try to find libev
# Once done this will define
# LIBEV_FOUND - System has libev
# LIBEV_INCLUDE_DIRS - The libev include directories
# LIBEV_LIBRARIES - The libraries needed to use libev
find_path(LIBEV_INCLUDE_DIR
NAMES ev.h
)
find_library(LIBEV_LIBRARY
NAMES ev
)
if(LIBEV_INCLUDE_DIR)
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
LIBEV_VERSION_MAJOR REGEX "^#define[ \t]+EV_VERSION_MAJOR[ \t]+[0-9]+")
file(STRINGS "${LIBEV_INCLUDE_DIR}/ev.h"
LIBEV_VERSION_MINOR REGEX "^#define[ \t]+EV_VERSION_MINOR[ \t]+[0-9]+")
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MAJOR "${LIBEV_VERSION_MAJOR}")
string(REGEX REPLACE "[^0-9]+" "" LIBEV_VERSION_MINOR "${LIBEV_VERSION_MINOR}")
set(LIBEV_VERSION "${LIBEV_VERSION_MAJOR}.${LIBEV_VERSION_MINOR}")
unset(LIBEV_VERSION_MINOR)
unset(LIBEV_VERSION_MAJOR)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEV_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libev REQUIRED_VARS
LIBEV_LIBRARY LIBEV_INCLUDE_DIR
VERSION_VAR LIBEV_VERSION)
if(LIBEV_FOUND)
set(LIBEV_LIBRARIES ${LIBEV_LIBRARY})
set(LIBEV_INCLUDE_DIRS ${LIBEV_INCLUDE_DIR})
endif()
mark_as_advanced(LIBEV_INCLUDE_DIR LIBEV_LIBRARY)

94
cmake/FindLibevent.cmake Normal file
View File

@@ -0,0 +1,94 @@
# - Try to find libevent
#.rst
# FindLibevent
# ------------
#
# Find Libevent include directories and libraries. Invoke as::
#
# find_package(Libevent
# [version] [EXACT] # Minimum or exact version
# [REQUIRED] # Fail if Libevent is not found
# [COMPONENT <C>...]) # Libraries to look for
#
# Valid components are one or more of:: libevent core extra pthreads openssl.
# Note that 'libevent' contains both core and extra. You must specify one of
# them for the other components.
#
# This module will define the following variables::
#
# LIBEVENT_FOUND - True if headers and requested libraries were found
# LIBEVENT_INCLUDE_DIRS - Libevent include directories
# LIBEVENT_LIBRARIES - Libevent libraries to be linked
# LIBEVENT_<C>_FOUND - Component <C> was found (<C> is uppercase)
# LIBEVENT_<C>_LIBRARY - Library to be linked for Libevent component <C>.
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBEVENT QUIET libevent)
# Look for the Libevent 2.0 or 1.4 headers
find_path(LIBEVENT_INCLUDE_DIR
NAMES
event2/event-config.h
event-config.h
HINTS
${PC_LIBEVENT_INCLUDE_DIRS}
)
if(LIBEVENT_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+_EVENT_VERSION[ \t]+\"([^\"]+)\".*")
if(EXISTS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h")
# Libevent 2.0
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event2/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
else()
# Libevent 1.4
file(STRINGS "${LIBEVENT_INCLUDE_DIR}/event-config.h"
LIBEVENT_VERSION REGEX "${_version_regex}")
endif()
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBEVENT_VERSION "${LIBEVENT_VERSION}")
unset(_version_regex)
endif()
set(_LIBEVENT_REQUIRED_VARS)
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
set(_LIBEVENT_LIBNAME libevent)
# Note: compare two variables to avoid a CMP0054 policy warning
if(COMPONENT STREQUAL _LIBEVENT_LIBNAME)
set(_LIBEVENT_LIBNAME event)
else()
set(_LIBEVENT_LIBNAME "event_${COMPONENT}")
endif()
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
find_library(LIBEVENT_${COMPONENT_UPPER}_LIBRARY
NAMES ${_LIBEVENT_LIBNAME}
HINTS ${PC_LIBEVENT_LIBRARY_DIRS}
)
if(LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
set(Libevent_${COMPONENT}_FOUND 1)
endif()
list(APPEND _LIBEVENT_REQUIRED_VARS LIBEVENT_${COMPONENT_UPPER}_LIBRARY)
endforeach()
unset(_LIBEVENT_LIBNAME)
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set LIBEVENT_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Libevent REQUIRED_VARS
${_LIBEVENT_REQUIRED_VARS}
LIBEVENT_INCLUDE_DIR
VERSION_VAR LIBEVENT_VERSION
HANDLE_COMPONENTS)
if(LIBEVENT_FOUND)
set(LIBEVENT_INCLUDE_DIRS ${LIBEVENT_INCLUDE_DIR})
set(LIBEVENT_LIBRARIES)
foreach(COMPONENT ${Libevent_FIND_COMPONENTS})
string(TOUPPER "${COMPONENT}" COMPONENT_UPPER)
list(APPEND LIBEVENT_LIBRARIES ${LIBEVENT_${COMPONENT_UPPER}_LIBRARY})
set(LIBEVENT_${COMPONENT_UPPER}_FOUND ${Libevent_${COMPONENT}_FOUND})
endforeach()
endif()
mark_as_advanced(LIBEVENT_INCLUDE_DIR ${_LIBEVENT_REQUIRED_VARS})
unset(_LIBEVENT_REQUIRED_VARS)

40
cmake/FindSpdylay.cmake Normal file
View File

@@ -0,0 +1,40 @@
# - Try to find spdylay
# Once done this will define
# SPDYLAY_FOUND - System has spdylay
# SPDYLAY_INCLUDE_DIRS - The spdylay include directories
# SPDYLAY_LIBRARIES - The libraries needed to use spdylay
find_package(PkgConfig QUIET)
pkg_check_modules(PC_SPDYLAY QUIET libspdylay)
find_path(SPDYLAY_INCLUDE_DIR
NAMES spdylay/spdylay.h
HINTS ${PC_SPDYLAY_INCLUDE_DIRS}
)
find_library(SPDYLAY_LIBRARY
NAMES spdylay
HINTS ${PC_SPDYLAY_LIBRARY_DIRS}
)
if(SPDYLAY_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+SPDYLAY_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${SPDYLAY_INCLUDE_DIR}/spdylay/spdylayver.h"
SPDYLAY_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
SPDYLAY_VERSION "${SPDYLAY_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set SPDYLAY_FOUND to TRUE
# if all listed variables are TRUE and the requested version matches.
find_package_handle_standard_args(Spdylay REQUIRED_VARS
SPDYLAY_LIBRARY SPDYLAY_INCLUDE_DIR
VERSION_VAR SPDYLAY_VERSION)
if(SPDYLAY_FOUND)
set(SPDYLAY_LIBRARIES ${SPDYLAY_LIBRARY})
set(SPDYLAY_INCLUDE_DIRS ${SPDYLAY_INCLUDE_DIR})
endif()
mark_as_advanced(SPDYLAY_INCLUDE_DIR SPDYLAY_LIBRARY)

11
cmake/Version.cmake Normal file
View File

@@ -0,0 +1,11 @@
# Converts a version such as 1.2.255 to 0x0102ff
function(HexVersion version_hex_var major minor patch)
math(EXPR version_dec "${major} * 256 * 256 + ${minor} * 256 + ${patch}")
set(version_hex "0x")
foreach(i RANGE 5 0 -1)
math(EXPR num "(${version_dec} >> (4 * ${i})) & 15")
string(SUBSTRING "0123456789abcdef" ${num} 1 num_hex)
set(version_hex "${version_hex}${num_hex}")
endforeach()
set(${version_hex_var} "${version_hex}" PARENT_SCOPE)
endfunction()

84
cmakeconfig.h.in Normal file
View File

@@ -0,0 +1,84 @@
/* Hint to the compiler that a function parameter is not used */
#define _U_ @HINT_UNUSED_PARAM@
/* Hint to the compiler that a function never returns */
#define NGHTTP2_NORETURN @HINT_NORETURN@
/* Define to `int' if <sys/types.h> does not define. */
#cmakedefine ssize_t @ssize_t@
/* Define to 1 if you have the `std::map::emplace`. */
#cmakedefine HAVE_STD_MAP_EMPLACE 1
/* Define to 1 if you have `libjansson` library. */
#cmakedefine HAVE_JANSSON 1
/* Define to 1 if you have `libxml2` library. */
#cmakedefine HAVE_LIBXML2 1
/* Define to 1 if you have `spdylay` library. */
#cmakedefine HAVE_SPDYLAY 1
/* Define to 1 if you have `mruby` library. */
#cmakedefine HAVE_MRUBY 1
/* Define to 1 if you have `neverbleed` library. */
#cmakedefine HAVE_NEVERBLEED 1
/* sizeof(int *) */
#cmakedefine SIZEOF_INT_P @SIZEOF_INT_P@
/* sizeof(time_t) */
#cmakedefine SIZEOF_TIME_T @SIZEOF_TIME_T@
/* Define to 1 if you have the `_Exit` function. */
#cmakedefine HAVE__EXIT 1
/* Define to 1 if you have the `accept4` function. */
#cmakedefine HAVE_ACCEPT4 1
/* Define to 1 if you have the `initgroups` function. */
#cmakedefine01 HAVE_DECL_INITGROUPS
/* Define to 1 to enable debug output. */
#cmakedefine DEBUGBUILD 1
/* Define to 1 if you want to disable threads. */
#cmakedefine NOTHREADS 1
/* Define to 1 if you have the <arpa/inet.h> header file. */
#cmakedefine HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <fcntl.h> header file. */
#cmakedefine HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#cmakedefine HAVE_LIMITS_H 1
/* Define to 1 if you have the <netdb.h> header file. */
#cmakedefine HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#cmakedefine HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <pwd.h> header file. */
#cmakedefine HAVE_PWD_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#cmakedefine HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <syslog.h> header file. */
#cmakedefine HAVE_SYSLOG_H 1
/* Define to 1 if you have the <time.h> header file. */
#cmakedefine HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1

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.8.0-DEV], [t-tujikawa@users.sourceforge.net])
AC_INIT([nghttp2], [1.12.0-DEV], [t-tujikawa@users.sourceforge.net])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
@@ -40,15 +40,13 @@ AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE([subdir-objects])
# AM_EXTRA_RECURSIVE_TARGETS requires automake 1.13 or higher
m4_ifdef([AM_EXTRA_RECURSIVE_TARGETS], [AM_EXTRA_RECURSIVE_TARGETS([it itprep])])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl See versioning rule:
dnl http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
AC_SUBST(LT_CURRENT, 18)
AC_SUBST(LT_REVISION, 1)
AC_SUBST(LT_AGE, 4)
AC_SUBST(LT_CURRENT, 22)
AC_SUBST(LT_REVISION, 0)
AC_SUBST(LT_AGE, 8)
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"`
@@ -76,7 +74,7 @@ AC_ARG_ENABLE([threads],
AC_ARG_ENABLE([app],
[AS_HELP_STRING([--enable-app],
[Build applications (nghttp, nghttpd and nghttpx) [default=check]])],
[Build applications (nghttp, nghttpd, nghttpx and h2load) [default=check]])],
[request_app=$enableval], [request_app=check])
AC_ARG_ENABLE([hpack-tools],
@@ -185,8 +183,8 @@ if test "x$GCC" = "xyes" -o "x$CC" = "xclang" ; then
AC_DEFINE([_U_], [__attribute__((unused))], [Hint to the compiler that a function parameters is not used])
AC_DEFINE([NGHTTP2_NORETURN], [__attribute__((noreturn))], [Hint to the compiler that a function never return])
else
AC_DEFINE([_U_], , [Hint to the compiler that a function parameters is not use AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
d])
AC_DEFINE([_U_], , [Hint to the compiler that a function parameter is not used])
AC_DEFINE([NGHTTP2_NORETURN], , [Hint to the compiler that a function never return])
fi
save_CXXFLAGS="$CXXFLAGS"
@@ -352,7 +350,10 @@ fi
# libxml2 (for src/nghttp)
have_libxml2=no
if test "x${request_libxml2}" != "xno"; then
AM_PATH_XML2(2.7.7, [have_libxml2=yes], [have_libxml2=no])
m4_ifdef([AM_PATH_XML2],
[AM_PATH_XML2(2.7.7, [have_libxml2=yes], [have_libxml2=no])],
[AC_MSG_WARN([configure was created without libxml2 detection macro; libxml2 detection is disabled])])
if test "x${have_libxml2}" = "xyes"; then
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have `libxml2` library.])
fi
@@ -651,8 +652,13 @@ AC_CHECK_FUNC([timerfd_create],
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
# cygwin disables initgroups due to feature test macro magic with our
# configuration.
AC_CHECK_DECLS([initgroups], [], [], [[#include <grp.h>]])
# configuration. FreeBSD declares initgroups() in unistd.h.
AC_CHECK_DECLS([initgroups], [], [], [[
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <grp.h>
]])
# Checks for epoll availability, primarily for examples/tiny-nghttpd
AX_HAVE_EPOLL([have_epoll=yes], [have_epoll=no])
@@ -715,6 +721,9 @@ if test "x$werror" != "xno"; then
# Only work with Clang for the moment
AX_CHECK_COMPILE_FLAG([-Wheader-guard], [CFLAGS="$CFLAGS -Wheader-guard"])
# This is required because we pass format string as "const char*.
AX_CHECK_COMPILE_FLAG([-Wno-format-nonliteral], [CFLAGS="$CFLAGS -Wno-format-nonliteral"])
# For C++ compiler
AC_LANG_PUSH(C++)
AX_CHECK_COMPILE_FLAG([-Wall], [CXXFLAGS="$CXXFLAGS -Wall"])

12
contrib/CMakeLists.txt Normal file
View File

@@ -0,0 +1,12 @@
set(CONFIGFILES
nghttpx-init
nghttpx.service
nghttpx-upstart.conf
)
# Note that the execute permissions of nghttpx-init is preserved
foreach(name IN LISTS CONFIGFILES)
configure_file("${name}.in" "${name}" @ONLY)
endforeach()
# set(EXTRA_DIST ${CONFIGFILES} nghttpx-logrotate tlsticketupdate.go)

View File

@@ -23,17 +23,24 @@
configfiles = nghttpx-init nghttpx.service nghttpx-upstart.conf
EXTRA_DIST = $(configfiles:%=%.in) nghttpx-logrotate tlsticketupdate.go
EXTRA_DIST = \
CMakeLists.txt \
$(configfiles:%=%.in) \
nghttpx-logrotate \
tlsticketupdate.go
edit = sed -e 's|@bindir[@]|$(bindir)|g'
nghttpx-init: %: $(srcdir)/%.in
nghttpx-init: $(srcdir)/nghttpx-init.in
rm -f $@ $@.tmp
$(edit) $< > $@.tmp
chmod +x $@.tmp
mv $@.tmp $@
nghttpx.service nghttpx-upstart.conf: %: $(srcdir)/%.in
nghttpx.service: $(srcdir)/nghttpx.service.in
$(edit) $< > $@
nghttpx-upstart.conf: $(srcdir)/nghttpx-upstart.conf.in
$(edit) $< > $@
$(configfiles): Makefile

339
doc/CMakeLists.txt Normal file
View File

@@ -0,0 +1,339 @@
# Generated documents
set(APIDOCS
macros.rst
enums.rst
types.rst
nghttp2_check_header_name.rst
nghttp2_check_header_value.rst
nghttp2_hd_deflate_bound.rst
nghttp2_hd_deflate_change_table_size.rst
nghttp2_hd_deflate_del.rst
nghttp2_hd_deflate_get_dynamic_table_size.rst
nghttp2_hd_deflate_get_max_dynamic_table_size.rst
nghttp2_hd_deflate_get_num_table_entries.rst
nghttp2_hd_deflate_get_table_entry.rst
nghttp2_hd_deflate_hd.rst
nghttp2_hd_deflate_new.rst
nghttp2_hd_deflate_new2.rst
nghttp2_hd_inflate_change_table_size.rst
nghttp2_hd_inflate_del.rst
nghttp2_hd_inflate_end_headers.rst
nghttp2_hd_inflate_get_dynamic_table_size.rst
nghttp2_hd_inflate_get_max_dynamic_table_size.rst
nghttp2_hd_inflate_get_num_table_entries.rst
nghttp2_hd_inflate_get_table_entry.rst
nghttp2_hd_inflate_hd.rst
nghttp2_hd_inflate_new.rst
nghttp2_hd_inflate_new2.rst
nghttp2_http2_strerror.rst
nghttp2_is_fatal.rst
nghttp2_nv_compare_name.rst
nghttp2_option_del.rst
nghttp2_option_new.rst
nghttp2_option_set_builtin_recv_extension_type.rst
nghttp2_option_set_max_reserved_remote_streams.rst
nghttp2_option_set_no_auto_ping_ack.rst
nghttp2_option_set_no_auto_window_update.rst
nghttp2_option_set_no_http_messaging.rst
nghttp2_option_set_no_recv_client_magic.rst
nghttp2_option_set_peer_max_concurrent_streams.rst
nghttp2_option_set_user_recv_extension_type.rst
nghttp2_pack_settings_payload.rst
nghttp2_priority_spec_check_default.rst
nghttp2_priority_spec_default_init.rst
nghttp2_priority_spec_init.rst
nghttp2_rcbuf_decref.rst
nghttp2_rcbuf_get_buf.rst
nghttp2_rcbuf_incref.rst
nghttp2_select_next_protocol.rst
nghttp2_session_callbacks_del.rst
nghttp2_session_callbacks_new.rst
nghttp2_session_callbacks_set_before_frame_send_callback.rst
nghttp2_session_callbacks_set_data_source_read_length_callback.rst
nghttp2_session_callbacks_set_error_callback.rst
nghttp2_session_callbacks_set_on_begin_frame_callback.rst
nghttp2_session_callbacks_set_on_begin_headers_callback.rst
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst
nghttp2_session_callbacks_set_on_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_stream_close_callback.rst
nghttp2_session_callbacks_set_pack_extension_callback.rst
nghttp2_session_callbacks_set_recv_callback.rst
nghttp2_session_callbacks_set_select_padding_callback.rst
nghttp2_session_callbacks_set_send_callback.rst
nghttp2_session_callbacks_set_send_data_callback.rst
nghttp2_session_callbacks_set_unpack_extension_callback.rst
nghttp2_session_client_new.rst
nghttp2_session_client_new2.rst
nghttp2_session_client_new3.rst
nghttp2_session_consume.rst
nghttp2_session_consume_connection.rst
nghttp2_session_consume_stream.rst
nghttp2_session_create_idle_stream.rst
nghttp2_session_del.rst
nghttp2_session_find_stream.rst
nghttp2_session_get_effective_local_window_size.rst
nghttp2_session_get_effective_recv_data_length.rst
nghttp2_session_get_last_proc_stream_id.rst
nghttp2_session_get_next_stream_id.rst
nghttp2_session_get_outbound_queue_size.rst
nghttp2_session_get_remote_settings.rst
nghttp2_session_get_remote_window_size.rst
nghttp2_session_get_root_stream.rst
nghttp2_session_get_stream_effective_local_window_size.rst
nghttp2_session_get_stream_effective_recv_data_length.rst
nghttp2_session_get_stream_local_close.rst
nghttp2_session_get_stream_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_next_stream_id.rst
nghttp2_session_set_stream_user_data.rst
nghttp2_session_terminate_session.rst
nghttp2_session_terminate_session2.rst
nghttp2_session_upgrade.rst
nghttp2_session_upgrade2.rst
nghttp2_session_want_read.rst
nghttp2_session_want_write.rst
nghttp2_stream_get_first_child.rst
nghttp2_stream_get_next_sibling.rst
nghttp2_stream_get_parent.rst
nghttp2_stream_get_previous_sibling.rst
nghttp2_stream_get_state.rst
nghttp2_stream_get_sum_dependency_weight.rst
nghttp2_stream_get_weight.rst
nghttp2_strerror.rst
nghttp2_submit_altsvc.rst
nghttp2_submit_data.rst
nghttp2_submit_extension.rst
nghttp2_submit_goaway.rst
nghttp2_submit_headers.rst
nghttp2_submit_ping.rst
nghttp2_submit_priority.rst
nghttp2_submit_push_promise.rst
nghttp2_submit_request.rst
nghttp2_submit_response.rst
nghttp2_submit_rst_stream.rst
nghttp2_submit_settings.rst
nghttp2_submit_shutdown_notice.rst
nghttp2_submit_trailer.rst
nghttp2_submit_window_update.rst
nghttp2_version.rst
)
set(MAN_PAGES
nghttp.1
nghttpd.1
nghttpx.1
h2load.1
)
# Other .rst files from the source tree that need to be copied
# XXX move them to sources/ and create .in files?
set(RST_FILES
README.rst
programmers-guide.rst
nghttp.1.rst
nghttpd.1.rst
nghttpx.1.rst
h2load.1.rst
)
# XXX unused for now
set(EXTRA_DIST
mkapiref.py
${RST_FILES}
${APIDOCS}
sources/index.rst
sources/tutorial-client.rst
sources/tutorial-server.rst
sources/tutorial-hpack.rst
sources/nghttpx-howto.rst
sources/h2load-howto.rst
sources/libnghttp2_asio.rst
sources/python-apiref.rst
sources/building-android-binary.rst
sources/contribute.rst
_exts/sphinxcontrib/LICENSE.rubydomain
_exts/sphinxcontrib/__init__.py
_exts/sphinxcontrib/rubydomain.py
_themes/sphinx_rtd_theme/__init__.py
_themes/sphinx_rtd_theme/breadcrumbs.html
_themes/sphinx_rtd_theme/footer.html
_themes/sphinx_rtd_theme/layout.html
_themes/sphinx_rtd_theme/layout_old.html
_themes/sphinx_rtd_theme/search.html
_themes/sphinx_rtd_theme/searchbox.html
_themes/sphinx_rtd_theme/static/css/badge_only.css
_themes/sphinx_rtd_theme/static/css/theme.css
_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
_themes/sphinx_rtd_theme/static/js/theme.js
_themes/sphinx_rtd_theme/theme.conf
_themes/sphinx_rtd_theme/versions.html
${MAN_PAGES}
bash_completion/nghttp
bash_completion/nghttpd
bash_completion/nghttpx
bash_completion/h2load
)
# Based on Makefile for Sphinx documentation
# You can set these variables from the command line.
set(SPHINXOPTS)
set(SPHINXBUILD sphinx-build)
set(PAPER)
set(BUILDDIR manual)
# Internal variables.
set(PAPEROPT_a4 -D latex_paper_size=a4)
set(PAPEROPT_letter -D latex_paper_size=letter)
set(ALLSPHINXOPTS -d ${BUILDDIR}/doctrees ${PAPEROPT_${PAPER}} ${SPHINXOPTS} .)
# "Please use `make <target>' where <target> is one of"
# " html to make standalone HTML files"
# " dirhtml to make HTML files named index.html in directories"
# " singlehtml to make a single large HTML file"
# " pickle to make pickle files"
# " json to make JSON files"
# " htmlhelp to make HTML files and a HTML help project"
# " qthelp to make HTML files and a qthelp project"
# " devhelp to make HTML files and a Devhelp project"
# " epub to make an epub"
# " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
# " latexpdf to make LaTeX files and run them through pdflatex"
# " text to make text files"
# " man to make manual pages"
# " changes to make an overview of all changed/added/deprecated items"
# " linkcheck to check all external links for integrity"
# " doctest to run all doctests embedded in the documentation (if enabled)"
# Copy files for out-of-tree builds
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
set(RST_BUILD_FILES)
foreach(rstfile IN LISTS RST_FILES)
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${rstfile}")
add_custom_command(OUTPUT "${outfile}"
COMMAND ${CMAKE_COMMAND} -E copy
"${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}" "${outfile}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${rstfile}"
)
list(APPEND RST_BUILD_FILES "${outfile}")
endforeach()
else()
set(RST_BUILD_FILES "${RST_FILES}")
endif()
set(apiref_SOURCES
${CMAKE_BINARY_DIR}/lib/includes/nghttp2/nghttp2ver.h
${CMAKE_SOURCE_DIR}/lib/includes/nghttp2/nghttp2.h
)
# Generates apiref.rst and other files
add_custom_command(
OUTPUT
apiref.rst
${APIDOCS}
COMMAND
"${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/mkapiref.py"
apiref.rst macros.rst enums.rst types.rst .
${apiref_SOURCES}
DEPENDS
${RST_BUILD_FILES}
${apiref_SOURCES}
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${BUILDDIR}")
# Invokes sphinx-build and prints the given messages when completed
function(sphinxbuild builder)
set(echo_commands)
foreach(message IN LISTS ARGN)
list(APPEND echo_commands COMMAND ${CMAKE_COMMAND} -E echo "${message}")
endforeach()
add_custom_target(${builder}
COMMAND "${SPHINXBUILD}" -b ${builder} ${ALLSPHINXOPTS} "${BUILDDIR}/${builder}"
COMMAND ${CMAKE_COMMAND} -E echo
${echo_commands}
VERBATIM
DEPENDS apiref.rst
)
endfunction()
foreach(builder html dirhtml singlehtml)
sphinxbuild(${builder}
"Build finished. The HTML pages are in ${BUILDDIR}/${builder}.")
endforeach()
sphinxbuild(pickle "Build finished; now you can process the pickle files.")
sphinxbuild(json "Build finished; now you can process the JSON files.")
sphinxbuild(htmlhelp
"Build finished; now you can run HTML Help Workshop with the"
".hhp project file in ${BUILDDIR}/htmlhelp."
)
sphinxbuild(qthelp
"Build finished; now you can run \"qcollectiongenerator\" with the"
".qhcp project file in ${BUILDDIR}/qthelp, like this:"
"# qcollectiongenerator ${BUILDDIR}/qthelp/nghttp2.qhcp"
"To view the help file:"
"# assistant -collectionFile ${BUILDDIR}/qthelp/nghttp2.qhc"
)
sphinxbuild(devhelp
"Build finished."
"To view the help file:"
"# mkdir -p ~/.local/share/devhelp/nghttp2"
"# ln -s ${BUILDDIR}/devhelp ~/.local/share/devhelp/nghttp2"
"# devhelp"
)
sphinxbuild(epub "Build finished. The epub file is in ${BUILDDIR}/epub.")
sphinxbuild(latex
"Build finished; the LaTeX files are in ${BUILDDIR}/latex."
"Run `make' in that directory to run these through (pdf)latex"
"(use `make latexpdf' here to do that automatically)."
)
# Invoke the Makefile generated by sphinx
add_custom_target(latexpdf
COMMAND ${CMAKE_COMMAND} -E echo "Running LaTeX files through pdflatex..."
COMMAND make -C "${BUILDDIR}/latex" all-pdf
COMMAND ${CMAKE_COMMAND} -E echo "pdflatex finished; the PDF files are in ${BUILDDIR}/latex."
DEPENDS latex
)
sphinxbuild(text "Build finished. The text files are in ${BUILDDIR}/text.")
sphinxbuild(man "Build finished. The manual pages are in ${BUILDDIR}/man.")
sphinxbuild(changes "The overview file is in ${BUILDDIR}/changes.")
sphinxbuild(linkcheck
"Link check complete; look for any errors in the above output"
"or in ${BUILDDIR}/linkcheck/output.txt."
)
sphinxbuild(doctest
"Testing of doctests in the sources finished, look at the"
"results in ${BUILDDIR}/doctest/output.txt."
)
foreach(_man_page IN LISTS MAN_PAGES)
install(FILES ${_man_page}
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
)
endforeach()

View File

@@ -47,39 +47,52 @@ APIDOCS= \
nghttp2_hd_inflate_get_num_table_entries.rst \
nghttp2_hd_inflate_get_table_entry.rst \
nghttp2_hd_inflate_hd.rst \
nghttp2_hd_inflate_hd2.rst \
nghttp2_hd_inflate_new.rst \
nghttp2_hd_inflate_new2.rst \
nghttp2_http2_strerror.rst \
nghttp2_is_fatal.rst \
nghttp2_nv_compare_name.rst \
nghttp2_option_del.rst \
nghttp2_option_new.rst \
nghttp2_option_set_builtin_recv_extension_type.rst \
nghttp2_option_set_max_reserved_remote_streams.rst \
nghttp2_option_set_no_auto_ping_ack.rst \
nghttp2_option_set_no_auto_window_update.rst \
nghttp2_option_set_no_http_messaging.rst \
nghttp2_option_set_no_recv_client_magic.rst \
nghttp2_option_set_peer_max_concurrent_streams.rst \
nghttp2_option_set_user_recv_extension_type.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
nghttp2_priority_spec_init.rst \
nghttp2_rcbuf_decref.rst \
nghttp2_rcbuf_get_buf.rst \
nghttp2_rcbuf_incref.rst \
nghttp2_select_next_protocol.rst \
nghttp2_session_callbacks_del.rst \
nghttp2_session_callbacks_new.rst \
nghttp2_session_callbacks_set_before_frame_send_callback.rst \
nghttp2_session_callbacks_set_data_source_read_length_callback.rst \
nghttp2_session_callbacks_set_error_callback.rst \
nghttp2_session_callbacks_set_on_begin_frame_callback.rst \
nghttp2_session_callbacks_set_on_begin_headers_callback.rst \
nghttp2_session_callbacks_set_on_data_chunk_recv_callback.rst \
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback.rst \
nghttp2_session_callbacks_set_on_frame_not_send_callback.rst \
nghttp2_session_callbacks_set_on_frame_recv_callback.rst \
nghttp2_session_callbacks_set_on_frame_send_callback.rst \
nghttp2_session_callbacks_set_on_header_callback.rst \
nghttp2_session_callbacks_set_on_header_callback2.rst \
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback.rst \
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback.rst \
nghttp2_session_callbacks_set_recv_callback.rst \
nghttp2_session_callbacks_set_select_padding_callback.rst \
nghttp2_session_callbacks_set_send_callback.rst \
nghttp2_session_callbacks_set_send_data_callback.rst \
nghttp2_session_callbacks_set_unpack_extension_callback.rst \
nghttp2_session_client_new.rst \
nghttp2_session_client_new2.rst \
nghttp2_session_client_new3.rst \
@@ -130,7 +143,9 @@ 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 \
nghttp2_submit_headers.rst \
nghttp2_submit_ping.rst \
@@ -145,15 +160,19 @@ APIDOCS= \
nghttp2_submit_window_update.rst \
nghttp2_version.rst
EXTRA_DIST = \
mkapiref.py \
RST_FILES = \
README.rst \
programmers-guide.rst \
$(APIDOCS) \
nghttp.1.rst \
nghttpd.1.rst \
nghttpx.1.rst \
h2load.1.rst \
h2load.1.rst
EXTRA_DIST = \
CMakeLists.txt \
mkapiref.py \
$(RST_FILES) \
$(APIDOCS) \
sources/index.rst \
sources/tutorial-client.rst \
sources/tutorial-server.rst \
@@ -227,13 +246,15 @@ help:
apiref.rst: \
$(top_builddir)/lib/includes/nghttp2/nghttp2ver.h \
$(top_builddir)/lib/includes/nghttp2/nghttp2.h
$(top_srcdir)/lib/includes/nghttp2/nghttp2.h
for i in $(RST_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
$(PYTHON) $(top_srcdir)/doc/mkapiref.py \
apiref.rst macros.rst enums.rst types.rst . $^
$(APIDOCS): apiref.rst
clean-local:
[ $(srcdir) = $(builddir) ] || for i in $(RST_FILES); do [ -e $(builddir)/$$i ] && rm $(builddir)/$$i; done
-rm -f apiref.rst
-rm -f $(APIDOCS)
-rm -rf $(BUILDDIR)/*

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

View File

@@ -41,7 +41,7 @@ import sys, os
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.append(os.path.abspath('_exts'))
sys.path.append(os.path.abspath('@top_srcdir@/doc/_exts'))
# -- General configuration -----------------------------------------------------

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "H2LOAD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.TH "H2LOAD" "1" "May 26, 2016" "1.11.0" "nghttp2"
.SH NAME
h2load \- HTTP/2 benchmarking tool
.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTP" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.TH "NGHTTP" "1" "May 26, 2016" "1.11.0" "nghttp2"
.SH NAME
nghttp \- HTTP/2 client
.
@@ -217,6 +217,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

View File

@@ -169,6 +169,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.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPD" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.TH "NGHTTPD" "1" "May 26, 2016" "1.11.0" "nghttp2"
.SH NAME
nghttpd \- HTTP/2 server
.

View File

@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
.TH "NGHTTPX" "1" "February 07, 2016" "1.8.0-DEV" "nghttp2"
.TH "NGHTTPX" "1" "May 26, 2016" "1.11.0" "nghttp2"
.SH NAME
nghttpx \- HTTP/2 proxy
.
@@ -39,15 +39,15 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.
.INDENT 0.0
.TP
.B <PRIVATE_KEY>
Set path to server\(aqs private key. Required unless \fI\%\-p\fP,
\fI\%\-\-client\fP or \fI\%\-\-frontend\-no\-tls\fP are given.
Set path to server\(aqs private key. Required unless
"no\-tls" parameter is used in \fI\%\-\-frontend\fP option.
.UNINDENT
.INDENT 0.0
.TP
.B <CERT>
Set path to server\(aqs certificate. Required unless \fI\%\-p\fP,
\fI\%\-\-client\fP or \fI\%\-\-frontend\-no\-tls\fP are given. To make OCSP
stapling work, this must be absolute path.
Set path to server\(aqs certificate. Required unless
"no\-tls" parameter is used in \fI\%\-\-frontend\fP option. To
make OCSP stapling work, this must be an absolute path.
.UNINDENT
.SH OPTIONS
.sp
@@ -55,38 +55,46 @@ The options are categorized into several groups.
.SS Connections
.INDENT 0.0
.TP
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;<PATTERN>[:...]]
.B \-b, \-\-backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;PARAM]...]
Set backend host and port. The multiple backend
addresses are accepted by repeating this option. UNIX
domain socket can be specified by prefixing path name
with "unix:" (e.g., unix:/var/run/backend.sock).
.sp
Optionally, if <PATTERN>s are given, the backend address
is only used if request matches the pattern. If \fI\%\-s\fP or
\fI\%\-p\fP is used, <PATTERN>s are ignored. The pattern
matching is closely designed to ServeMux in net/http
package of Go programming language. <PATTERN> consists
of path, host + path or just host. The path must start
with "\fI/\fP". If it ends with "\fI/\fP", it matches all request
path in its subtree. To deal with the request to the
directory without trailing slash, the path which ends
with "\fI/\fP" also matches the request path which only lacks
trailing \(aq\fI/\fP\(aq (e.g., path "\fI/foo/\fP" matches request path
"\fI/foo\fP"). If it does not end with "\fI/\fP", it performs exact
match against the request path. If host is given, it
performs exact match against the request host. If host
alone is given, "\fI/\fP" is appended to it, so that it
matches all request paths under the host (e.g.,
specifying "nghttp2.org" equals to "nghttp2.org/").
is only used if request matches the pattern. If
\fI\%\-\-http2\-proxy\fP is used, <PATTERN>s are ignored. The
pattern matching is closely designed to ServeMux in
net/http package of Go programming language. <PATTERN>
consists of path, host + path or just host. The path
must start with "\fI/\fP". If it ends with "\fI/\fP", it matches
all request path in its subtree. To deal with the
request to the directory without trailing slash, the
path which ends with "\fI/\fP" also matches the request path
which only lacks trailing \(aq\fI/\fP\(aq (e.g., path "\fI/foo/\fP"
matches request path "\fI/foo\fP"). If it does not end with
"\fI/\fP", it performs exact match against the request path.
If host is given, it performs exact match against the
request host. If host alone is given, "\fI/\fP" is appended
to it, so that it matches all request paths under the
host (e.g., specifying "nghttp2.org" equals to
"nghttp2.org/").
.sp
Patterns with host take precedence over patterns with
just path. Then, longer patterns take precedence over
shorter ones, breaking a tie by the order of the
appearance in the configuration.
shorter ones.
.sp
If <PATTERN> is omitted, "\fI/\fP" is used as pattern, which
matches all request paths (catch\-all pattern). The
catch\-all backend must be given.
Host can include "*" in the left most position to
indicate wildcard match (only suffix match is done).
The "*" must match at least one character. For example,
host pattern "*.nghttp2.org" matches against
"www.nghttp2.org" and "git.ngttp2.org", but does not
match against "nghttp2.org". The exact hosts match
takes precedence over the wildcard hosts match.
.sp
If <PATTERN> is omitted or empty string, "\fI/\fP" is used as
pattern, which matches all request paths (catch\-all
pattern). The catch\-all backend must be given.
.sp
When doing a match, nghttpx made some normalization to
pattern, request host and path. For host part, they are
@@ -109,6 +117,49 @@ and \fI\%\-b\fP\(aq127.0.0.1,8080;www.nghttp2.org\(aq.
The backend addresses sharing same <PATTERN> are grouped
together forming load balancing group.
.sp
Several parameters <PARAM> are accepted after <PATTERN>.
The parameters are delimited by ";". The available
parameters are: "proto=<PROTO>", "tls",
"sni=<SNI_HOST>", "fall=<N>", and "rise=<N>". The
parameter consists of keyword, and optionally followed
by "=" and value. For example, the parameter "proto=h2"
consists of the keyword "proto" and value "h2". The
parameter "tls" consists of the keyword "tls" without
value. Each parameter is described as follows.
.sp
The backend application protocol can be specified using
optional "proto" parameter, and in the form of
"proto=<PROTO>". <PROTO> should be one of the following
list without quotes: "h2", "http/1.1". The default
value of <PROTO> is "http/1.1". Note that usually "h2"
refers to HTTP/2 over TLS. But in this option, it may
mean HTTP/2 over cleartext TCP unless "tls" keyword is
used (see below).
.sp
TLS can be enabled by specifying optional "tls"
parameter. TLS is not enabled by default.
.sp
With "sni=<SNI_HOST>" parameter, it can override the TLS
SNI field value with given <SNI_HOST>. This will
default to the backend <HOST> name
.sp
The feature to detect whether backend is online or
offline can be enabled using optional "fall" and "rise"
parameters. Using "fall=<N>" parameter, if nghttpx
cannot connect to a this backend <N> times in a row,
this backend is assumed to be offline, and it is
excluded from load balancing. If <N> is 0, this backend
never be excluded from load balancing whatever times
nghttpx cannot connect to it, and this is the default.
There is also "rise=<N>" parameter. After backend was
excluded from load balancing group, nghttpx periodically
attempts to make a connection to the failed backend, and
if the connection is made successfully <N> times in a
row, the backend is assumed to be online, and it is now
eligible for load balancing target. If <N> is 0, a
backend is permanently offline, once it goes in that
state, and this is the default behaviour.
.sp
Since ";" and ":" are used as delimiter, <PATTERN> must
not contain these characters. Since ";" has special
meaning in shell, the option value must be quoted.
@@ -117,7 +168,7 @@ Default: \fB127.0.0.1,80\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)
.B \-f, \-\-frontend=(<HOST>,<PORT>|unix:<PATH>)[;no\-tls]
Set frontend host and port. If <HOST> is \(aq*\(aq, it
assumes all addresses including both IPv4 and IPv6.
UNIX domain socket can be specified by prefixing path
@@ -125,6 +176,9 @@ name with "unix:" (e.g., unix:/var/run/nghttpx.sock).
This option can be used multiple times to listen to
multiple addresses.
.sp
Optionally, TLS can be disabled by specifying "no\-tls"
parameter. TLS is enabled by default.
.sp
Default: \fB*,3000\fP
.UNINDENT
.INDENT 0.0
@@ -136,13 +190,13 @@ Default: \fB512\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-ipv4
Resolve backend hostname to IPv4 address only.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-ipv6
Resolve backend hostname to IPv6 address only.
.B \-\-backend\-address\-family=(auto|IPv4|IPv6)
Specify address family of backend connections. If
"auto" is given, both IPv4 and IPv6 are considered. If
"IPv4" is given, only IPv4 address is considered. If
"IPv6" is given, only IPv6 address is considered.
.sp
Default: \fBauto\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -165,22 +219,6 @@ be specified by \fI\%\-\-backend\-read\-timeout\fP and
.B \-\-accept\-proxy\-protocol
Accept PROXY protocol version 1 on frontend connection.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-no\-tls
Disable SSL/TLS on backend connections. For HTTP/2
backend connections, TLS is enabled by default. For
HTTP/1 backend connections, TLS is disabled by default,
and can be enabled by \fI\%\-\-backend\-http1\-tls\fP option. If
both \fI\%\-\-backend\-no\-tls\fP and \fI\%\-\-backend\-http1\-tls\fP options
are used, \fI\%\-\-backend\-no\-tls\fP has the precedence.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http1\-tls
Enable SSL/TLS on backend HTTP/1 connections. See also
\fI\%\-\-backend\-no\-tls\fP option.
.UNINDENT
.SS Performance
.INDENT 0.0
.TP
@@ -269,37 +307,27 @@ Default: \fB0\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-connections\-per\-worker=<N>
Set maximum number of backend HTTP/2 physical
connections per worker. If pattern is used in \fI\%\-b\fP
option, this limit is applied to each pattern group (in
other words, each pattern group can have maximum <N>
HTTP/2 connections). The default value is 0, which
means that the value is adjusted to the number of
backend addresses. If pattern is used, this adjustment
is done for each pattern group.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http1\-connections\-per\-host=<N>
Set maximum number of backend concurrent HTTP/1
connections per origin host. This option is meaningful
when \fI\%\-s\fP option is used. The origin host is determined
by authority portion of request URI (or :authority
header field for HTTP/2). To limit the number of
connections per frontend for default mode, use
\fI\%\-\-backend\-http1\-connections\-per\-frontend\fP\&.
.B \-\-backend\-connections\-per\-host=<N>
Set maximum number of backend concurrent connections
(and/or streams in case of HTTP/2) per origin host.
This option is meaningful when \fI\%\-\-http2\-proxy\fP option is
used. The origin host is determined by authority
portion of request URI (or :authority header field for
HTTP/2). To limit the number of connections per
frontend for default mode, use
\fI\%\-\-backend\-connections\-per\-frontend\fP\&.
.sp
Default: \fB8\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http1\-connections\-per\-frontend=<N>
Set maximum number of backend concurrent HTTP/1
connections per frontend. This option is only used for
default mode. 0 means unlimited. To limit the number
of connections per host for HTTP/2 or SPDY proxy mode
(\-s option), use \fI\%\-\-backend\-http1\-connections\-per\-host\fP\&.
.B \-\-backend\-connections\-per\-frontend=<N>
Set maximum number of backend concurrent connections
(and/or streams in case of HTTP/2) per frontend. This
option is only used for default mode. 0 means
unlimited. To limit the number of connections per host
with \fI\%\-\-http2\-proxy\fP option, use
\fI\%\-\-backend\-connections\-per\-host\fP\&.
.sp
Default: \fB0\fP
.UNINDENT
@@ -335,6 +363,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
@@ -404,6 +439,22 @@ 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
.SS SSL/TLS
.INDENT 0.0
.TP
@@ -444,12 +495,6 @@ 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.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-dh\-param\-file=<PATH>
Path to file that contains DH parameters in PEM format.
Without this option, DHE cipher suites are not
@@ -533,17 +578,30 @@ required.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-ticket\-key\-memcached=<HOST>,<PORT>
Specify address of memcached server to store session
cache. This enables shared TLS ticket key between
multiple nghttpx instances. nghttpx does not set TLS
ticket key to memcached. The external ticket key
generator is required. nghttpx just gets TLS ticket
keys from memcached, and use them, possibly replacing
current set of keys. It is up to extern TLS ticket key
generator to rotate keys frequently. See "TLS SESSION
TICKET RESUMPTION" section in manual page to know the
data format in memcached entry.
.B \-\-tls\-ticket\-key\-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to get TLS ticket
keys for session resumption. This enables shared TLS
ticket key between multiple nghttpx instances. nghttpx
does not set TLS ticket key to memcached. The external
ticket key generator is required. nghttpx just gets TLS
ticket keys from memcached, and use them, possibly
replacing current set of keys. It is up to extern TLS
ticket key generator to rotate keys frequently. See
"TLS SESSION TICKET RESUMPTION" section in manual page
to know the data format in memcached entry. Optionally,
memcached connection can be encrypted with TLS by
specifying "tls" parameter.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-ticket\-key\-memcached\-address\-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to get
TLS ticket keys. If "auto" is given, both IPv4 and IPv6
are considered. If "IPv4" is given, only IPv4 address
is considered. If "IPv6" is given, only IPv6 address is
considered.
.sp
Default: \fBauto\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -581,6 +639,18 @@ aes\-128\-cbc is used.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-ticket\-key\-memcached\-cert\-file=<PATH>
Path to client certificate for memcached connections to
get TLS ticket keys.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-ticket\-key\-memcached\-private\-key\-file=<PATH>
Path to client private key for memcached connections to
get TLS ticket keys.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-fetch\-ocsp\-response\-file=<PATH>
Path to fetch\-ocsp\-response script file. It should be
absolute path.
@@ -601,10 +671,35 @@ Disable OCSP stapling.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached=<HOST>,<PORT>
.B \-\-tls\-session\-cache\-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session
cache. This enables shared session cache between
multiple nghttpx instances.
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying "tls"
parameter.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached\-address\-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to store
session cache. If "auto" is given, both IPv4 and IPv6
are considered. If "IPv4" is given, only IPv4 address
is considered. If "IPv6" is given, only IPv6 address is
considered.
.sp
Default: \fBauto\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached\-cert\-file=<PATH>
Path to client certificate for memcached connections to
store session cache.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached\-private\-key\-file=<PATH>
Path to client private key for memcached connections to
store session cache.
.UNINDENT
.INDENT 0.0
.TP
@@ -639,20 +734,22 @@ 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 \-\-backend\-tls\-session\-cache\-per\-worker=<N>
Set the maximum number of backend TLS session cache
stored per worker.
.sp
Default: \fB10000\fP
.UNINDENT
.SS HTTP/2 and SPDY
.INDENT 0.0
.TP
.B \-c, \-\-http2\-max\-concurrent\-streams=<N>
.B \-c, \-\-frontend\-http2\-max\-concurrent\-streams=<N>
Set the maximum number of the concurrent streams in one
HTTP/2 and SPDY session.
frontend HTTP/2 and SPDY session.
.sp
Default: \(ga\(ga 100\(ga\(ga
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-max\-concurrent\-streams=<N>
Set the maximum number of the concurrent streams in one
backend HTTP/2 session. This sets maximum number of
concurrent opened pushed streams. The maximum number of
concurrent requests are set by a remote server.
.sp
Default: \fB100\fP
.UNINDENT
@@ -676,11 +773,6 @@ Default: \fB16\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-frontend\-no\-tls
Disable SSL/TLS on frontend connections.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-backend\-http2\-window\-bits=<N>
Sets the initial window size of HTTP/2 backend
connection to 2**<N>\-1.
@@ -693,7 +785,7 @@ Default: \fB16\fP
Sets the per\-connection window size of HTTP/2 backend
connection to 2**<N>\-1.
.sp
Default: \fB16\fP
Default: \fB30\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -714,52 +806,26 @@ protocol security.
Disable HTTP/2 server push. Server push is supported by
default mode and HTTP/2 frontend via Link header field.
It is also supported if both frontend and backend are
HTTP/2 (which implies \fI\%\-\-http2\-bridge\fP or \fI\%\-\-client\fP mode).
In this case, server push from backend session is
relayed to frontend, and server push via Link header
field is also supported. HTTP SPDY frontend does not
support server push.
HTTP/2 in default mode. In this case, server push from
backend session is relayed to frontend, and server push
via Link header field is also supported. SPDY frontend
does not support server push.
.UNINDENT
.SS Mode
.INDENT 0.0
.TP
.B (default mode)
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. If
\fI\%\-\-frontend\-no\-tls\fP is used, accept HTTP/2 and HTTP/1.1.
The incoming HTTP/1.1 connection can be upgraded to
HTTP/2 through HTTP Upgrade. The protocol to the
backend is HTTP/1.1.
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no\-tls"
parameter is used in \fI\%\-\-frontend\fP option, accept HTTP/2
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
connection can be upgraded to HTTP/2 through HTTP
Upgrade.
.UNINDENT
.INDENT 0.0
.TP
.B \-s, \-\-http2\-proxy
Like default mode, but enable secure proxy mode.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-http2\-bridge
Like default mode, but communicate with the backend in
HTTP/2 over SSL/TLS. Thus the incoming all connections
are converted to HTTP/2 connection and relayed to the
backend. See \fI\%\-\-backend\-http\-proxy\-uri\fP option if you are
behind the proxy and want to connect to the outside
HTTP/2 proxy.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-client
Accept HTTP/2 and HTTP/1.1 without SSL/TLS. The
incoming HTTP/1.1 connection can be upgraded to HTTP/2
connection through HTTP Upgrade. The protocol to the
backend is HTTP/2. To use nghttpx as a forward proxy,
use \fI\%\-p\fP option instead.
.UNINDENT
.INDENT 0.0
.TP
.B \-p, \-\-client\-proxy
Like \fI\%\-\-client\fP option, but it also requires the request
path from frontend must be an absolute URI, suitable for
use as a forward proxy.
Like default mode, but enable forward proxy. This is so
called HTTP/2 proxy mode.
.UNINDENT
.SS Logging
.INDENT 0.0
@@ -925,18 +991,16 @@ is received, it is left unaltered.
.INDENT 0.0
.TP
.B \-\-no\-location\-rewrite
Don\(aqt rewrite location header field on \fI\%\-\-http2\-bridge\fP,
\fI\%\-\-client\fP and default mode. For \fI\%\-\-http2\-proxy\fP and
\fI\%\-\-client\-proxy\fP mode, location header field will not be
altered regardless of this option.
Don\(aqt rewrite location header field in default mode.
When \fI\%\-\-http2\-proxy\fP is used, location header field will
not be altered regardless of this option.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-host\-rewrite
Rewrite host and :authority header fields on
\fI\%\-\-http2\-bridge\fP, \fI\%\-\-client\fP and default mode. For
\fI\%\-\-http2\-proxy\fP and \fI\%\-\-client\-proxy\fP mode, these headers
will not be altered regardless of this option.
Rewrite host and :authority header fields in default
mode. When \fI\%\-\-http2\-proxy\fP is used, these headers will
not be altered regardless of this option.
.UNINDENT
.INDENT 0.0
.TP
@@ -1004,6 +1068,16 @@ towards this number.
.sp
Default: \fB500\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-error\-page=(<CODE>|*)=<PATH>
Set file path to custom error page served when nghttpx
originally generates HTTP error status code <CODE>.
<CODE> must be greater than or equal to 400, and at most
599. If "*" is used instead of <CODE>, it matches all
HTTP status code. If error status code comes from
backend server, the custom error pages are not used.
.UNINDENT
.SS Debug
.INDENT 0.0
.TP
@@ -1208,12 +1282,12 @@ associated stream\(aqs status code must be 200.
This limitation may be loosened in the future release.
.sp
nghttpx also supports server push if both frontend and backend are
HTTP/2 (which implies \fI\%\-\-http2\-bridge\fP or \fI\%\-\-client\fP).
In this case, in addition to server push via Link header field, server
push from backend is relayed to frontend HTTP/2 session.
HTTP/2 in default mode. In this case, in addition to server push via
Link header field, server push from backend is forwarded to frontend
HTTP/2 session.
.sp
HTTP/2 server push will be disabled if \fI\%\-\-http2\-proxy\fP or
\fI\%\-\-client\-proxy\fP is used.
HTTP/2 server push will be disabled if \fI\%\-\-http2\-proxy\fP is
used.
.SH UNIX DOMAIN SOCKET
.sp
nghttpx supports UNIX domain socket with a filename for both frontend
@@ -1251,6 +1325,10 @@ insert serialized session data to memcached with
\fBnghttpx:tls\-session\-cache:\fP + lowercased hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
.sp
By default, connections to memcached server are not encrypted. To
enable encryption, use \fBtls\fP keyword in
\fI\%\-\-tls\-session\-cache\-memcached\fP option.
.SS TLS SESSION TICKET RESUMPTION
.sp
By default, session ticket is shared by all worker threads. The
@@ -1295,6 +1373,10 @@ used, LEN must be 48. If
keys. The key appeared first is used as encryption key. All the
remaining keys are used as decryption only.
.sp
By default, connections to memcached server are not encrypted. To
enable encryption, use \fBtls\fP keyword in
\fI\%\-\-tls\-ticket\-key\-memcached\fP option.
.sp
If \fI\%\-\-tls\-ticket\-key\-file\fP is given, encryption key is read
from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
@@ -1368,7 +1450,27 @@ 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
.UNINDENT
.INDENT 0.0
@@ -1411,7 +1513,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
@@ -1444,7 +1552,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

View File

@@ -19,14 +19,14 @@ A reverse proxy for HTTP/2, HTTP/1 and SPDY.
.. describe:: <PRIVATE_KEY>
Set path to server's private key. Required unless :option:`-p`\,
:option:`--client` or :option:`\--frontend-no-tls` are given.
Set path to server's private key. Required unless
"no-tls" parameter is used in :option:`--frontend` option.
.. describe:: <CERT>
Set path to server's certificate. Required unless :option:`-p`\,
:option:`--client` or :option:`\--frontend-no-tls` are given. To make OCSP
stapling work, this must be absolute path.
Set path to server's certificate. Required unless
"no-tls" parameter is used in :option:`--frontend` option. To
make OCSP stapling work, this must be an absolute path.
OPTIONS
@@ -37,7 +37,8 @@ The options are categorized into several groups.
Connections
~~~~~~~~~~~
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;<PATTERN>[:...]]
.. option:: -b, --backend=(<HOST>,<PORT>|unix:<PATH>)[;[<PATTERN>[:...]][[;PARAM]...]
Set backend host and port. The multiple backend
addresses are accepted by repeating this option. UNIX
@@ -45,31 +46,39 @@ Connections
with "unix:" (e.g., unix:/var/run/backend.sock).
Optionally, if <PATTERN>s are given, the backend address
is only used if request matches the pattern. If :option:`-s` or
:option:`-p` is used, <PATTERN>s are ignored. The pattern
matching is closely designed to ServeMux in net/http
package of Go programming language. <PATTERN> consists
of path, host + path or just host. The path must start
with "*/*". If it ends with "*/*", it matches all request
path in its subtree. To deal with the request to the
directory without trailing slash, the path which ends
with "*/*" also matches the request path which only lacks
trailing '*/*' (e.g., path "*/foo/*" matches request path
"*/foo*"). If it does not end with "*/*", it performs exact
match against the request path. If host is given, it
performs exact match against the request host. If host
alone is given, "*/*" is appended to it, so that it
matches all request paths under the host (e.g.,
specifying "nghttp2.org" equals to "nghttp2.org/").
is only used if request matches the pattern. If
:option:`--http2-proxy` is used, <PATTERN>s are ignored. The
pattern matching is closely designed to ServeMux in
net/http package of Go programming language. <PATTERN>
consists of path, host + path or just host. The path
must start with "*/*". If it ends with "*/*", it matches
all request path in its subtree. To deal with the
request to the directory without trailing slash, the
path which ends with "*/*" also matches the request path
which only lacks trailing '*/*' (e.g., path "*/foo/*"
matches request path "*/foo*"). If it does not end with
"*/*", it performs exact match against the request path.
If host is given, it performs exact match against the
request host. If host alone is given, "*/*" is appended
to it, so that it matches all request paths under the
host (e.g., specifying "nghttp2.org" equals to
"nghttp2.org/").
Patterns with host take precedence over patterns with
just path. Then, longer patterns take precedence over
shorter ones, breaking a tie by the order of the
appearance in the configuration.
shorter ones.
If <PATTERN> is omitted, "*/*" is used as pattern, which
matches all request paths (catch-all pattern). The
catch-all backend must be given.
Host can include "\*" in the left most position to
indicate wildcard match (only suffix match is done).
The "*" must match at least one character. For example,
host pattern "\*.nghttp2.org" matches against
"www.nghttp2.org" and "git.ngttp2.org", but does not
match against "nghttp2.org". The exact hosts match
takes precedence over the wildcard hosts match.
If <PATTERN> is omitted or empty string, "*/*" is used as
pattern, which matches all request paths (catch-all
pattern). The catch-all backend must be given.
When doing a match, nghttpx made some normalization to
pattern, request host and path. For host part, they are
@@ -92,6 +101,49 @@ Connections
The backend addresses sharing same <PATTERN> are grouped
together forming load balancing group.
Several parameters <PARAM> are accepted after <PATTERN>.
The parameters are delimited by ";". The available
parameters are: "proto=<PROTO>", "tls",
"sni=<SNI_HOST>", "fall=<N>", and "rise=<N>". The
parameter consists of keyword, and optionally followed
by "=" and value. For example, the parameter "proto=h2"
consists of the keyword "proto" and value "h2". The
parameter "tls" consists of the keyword "tls" without
value. Each parameter is described as follows.
The backend application protocol can be specified using
optional "proto" parameter, and in the form of
"proto=<PROTO>". <PROTO> should be one of the following
list without quotes: "h2", "http/1.1". The default
value of <PROTO> is "http/1.1". Note that usually "h2"
refers to HTTP/2 over TLS. But in this option, it may
mean HTTP/2 over cleartext TCP unless "tls" keyword is
used (see below).
TLS can be enabled by specifying optional "tls"
parameter. TLS is not enabled by default.
With "sni=<SNI_HOST>" parameter, it can override the TLS
SNI field value with given <SNI_HOST>. This will
default to the backend <HOST> name
The feature to detect whether backend is online or
offline can be enabled using optional "fall" and "rise"
parameters. Using "fall=<N>" parameter, if nghttpx
cannot connect to a this backend <N> times in a row,
this backend is assumed to be offline, and it is
excluded from load balancing. If <N> is 0, this backend
never be excluded from load balancing whatever times
nghttpx cannot connect to it, and this is the default.
There is also "rise=<N>" parameter. After backend was
excluded from load balancing group, nghttpx periodically
attempts to make a connection to the failed backend, and
if the connection is made successfully <N> times in a
row, the backend is assumed to be online, and it is now
eligible for load balancing target. If <N> is 0, a
backend is permanently offline, once it goes in that
state, and this is the default behaviour.
Since ";" and ":" are used as delimiter, <PATTERN> must
not contain these characters. Since ";" has special
meaning in shell, the option value must be quoted.
@@ -99,7 +151,7 @@ Connections
Default: ``127.0.0.1,80``
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)
.. option:: -f, --frontend=(<HOST>,<PORT>|unix:<PATH>)[;no-tls]
Set frontend host and port. If <HOST> is '\*', it
assumes all addresses including both IPv4 and IPv6.
@@ -108,6 +160,10 @@ Connections
This option can be used multiple times to listen to
multiple addresses.
Optionally, TLS can be disabled by specifying "no-tls"
parameter. TLS is enabled by default.
Default: ``*,3000``
.. option:: --backlog=<N>
@@ -116,13 +172,14 @@ Connections
Default: ``512``
.. option:: --backend-ipv4
.. option:: --backend-address-family=(auto|IPv4|IPv6)
Resolve backend hostname to IPv4 address only.
Specify address family of backend connections. If
"auto" is given, both IPv4 and IPv6 are considered. If
"IPv4" is given, only IPv4 address is considered. If
"IPv6" is given, only IPv6 address is considered.
.. option:: --backend-ipv6
Resolve backend hostname to IPv6 address only.
Default: ``auto``
.. option:: --backend-http-proxy-uri=<URI>
@@ -143,20 +200,6 @@ Connections
Accept PROXY protocol version 1 on frontend connection.
.. option:: --backend-no-tls
Disable SSL/TLS on backend connections. For HTTP/2
backend connections, TLS is enabled by default. For
HTTP/1 backend connections, TLS is disabled by default,
and can be enabled by :option:`--backend-http1-tls` option. If
both :option:`--backend-no-tls` and :option:`\--backend-http1-tls` options
are used, :option:`--backend-no-tls` has the precedence.
.. option:: --backend-http1-tls
Enable SSL/TLS on backend HTTP/1 connections. See also
:option:`--backend-no-tls` option.
Performance
~~~~~~~~~~~
@@ -236,36 +279,27 @@ Performance
Default: ``0``
.. option:: --backend-http2-connections-per-worker=<N>
.. option:: --backend-connections-per-host=<N>
Set maximum number of backend HTTP/2 physical
connections per worker. If pattern is used in :option:`-b`
option, this limit is applied to each pattern group (in
other words, each pattern group can have maximum <N>
HTTP/2 connections). The default value is 0, which
means that the value is adjusted to the number of
backend addresses. If pattern is used, this adjustment
is done for each pattern group.
.. option:: --backend-http1-connections-per-host=<N>
Set maximum number of backend concurrent HTTP/1
connections per origin host. This option is meaningful
when :option:`-s` option is used. The origin host is determined
by authority portion of request URI (or :authority
header field for HTTP/2). To limit the number of
connections per frontend for default mode, use
:option:`--backend-http1-connections-per-frontend`\.
Set maximum number of backend concurrent connections
(and/or streams in case of HTTP/2) per origin host.
This option is meaningful when :option:`--http2-proxy` option is
used. The origin host is determined by authority
portion of request URI (or :authority header field for
HTTP/2). To limit the number of connections per
frontend for default mode, use
:option:`--backend-connections-per-frontend`\.
Default: ``8``
.. option:: --backend-http1-connections-per-frontend=<N>
.. option:: --backend-connections-per-frontend=<N>
Set maximum number of backend concurrent HTTP/1
connections per frontend. This option is only used for
default mode. 0 means unlimited. To limit the number
of connections per host for HTTP/2 or SPDY proxy mode
(-s option), use :option:`--backend-http1-connections-per-host`\.
Set maximum number of backend concurrent connections
(and/or streams in case of HTTP/2) per frontend. This
option is only used for default mode. 0 means
unlimited. To limit the number of connections per host
with :option:`--http2-proxy` option, use
:option:`--backend-connections-per-host`\.
Default: ``0``
@@ -297,6 +331,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
~~~~~~~
@@ -359,6 +400,20 @@ 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``
SSL/TLS
~~~~~~~
@@ -395,11 +450,6 @@ SSL/TLS
option can be used multiple times. To make OCSP
stapling work, <CERTPATH> must be absolute path.
.. option:: --backend-tls-sni-field=<HOST>
Explicitly set the content of the TLS SNI extension.
This will default to the backend HOST name.
.. option:: --dh-param-file=<PATH>
Path to file that contains DH parameters in PEM format.
@@ -475,18 +525,30 @@ SSL/TLS
ticket key sharing between nghttpx instances is not
required.
.. option:: --tls-ticket-key-memcached=<HOST>,<PORT>
.. option:: --tls-ticket-key-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session
cache. This enables shared TLS ticket key between
multiple nghttpx instances. nghttpx does not set TLS
ticket key to memcached. The external ticket key
generator is required. nghttpx just gets TLS ticket
keys from memcached, and use them, possibly replacing
current set of keys. It is up to extern TLS ticket key
generator to rotate keys frequently. See "TLS SESSION
TICKET RESUMPTION" section in manual page to know the
data format in memcached entry.
Specify address of memcached server to get TLS ticket
keys for session resumption. This enables shared TLS
ticket key between multiple nghttpx instances. nghttpx
does not set TLS ticket key to memcached. The external
ticket key generator is required. nghttpx just gets TLS
ticket keys from memcached, and use them, possibly
replacing current set of keys. It is up to extern TLS
ticket key generator to rotate keys frequently. See
"TLS SESSION TICKET RESUMPTION" section in manual page
to know the data format in memcached entry. Optionally,
memcached connection can be encrypted with TLS by
specifying "tls" parameter.
.. option:: --tls-ticket-key-memcached-address-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to get
TLS ticket keys. If "auto" is given, both IPv4 and IPv6
are considered. If "IPv4" is given, only IPv4 address
is considered. If "IPv6" is given, only IPv6 address is
considered.
Default: ``auto``
.. option:: --tls-ticket-key-memcached-interval=<DURATION>
@@ -518,6 +580,16 @@ SSL/TLS
either aes-128-cbc or aes-256-cbc. By default,
aes-128-cbc is used.
.. option:: --tls-ticket-key-memcached-cert-file=<PATH>
Path to client certificate for memcached connections to
get TLS ticket keys.
.. option:: --tls-ticket-key-memcached-private-key-file=<PATH>
Path to client private key for memcached connections to
get TLS ticket keys.
.. option:: --fetch-ocsp-response-file=<PATH>
Path to fetch-ocsp-response script file. It should be
@@ -535,11 +607,33 @@ SSL/TLS
Disable OCSP stapling.
.. option:: --tls-session-cache-memcached=<HOST>,<PORT>
.. option:: --tls-session-cache-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session
cache. This enables shared session cache between
multiple nghttpx instances.
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying "tls"
parameter.
.. option:: --tls-session-cache-memcached-address-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to store
session cache. If "auto" is given, both IPv4 and IPv6
are considered. If "IPv4" is given, only IPv4 address
is considered. If "IPv6" is given, only IPv6 address is
considered.
Default: ``auto``
.. option:: --tls-session-cache-memcached-cert-file=<PATH>
Path to client certificate for memcached connections to
store session cache.
.. option:: --tls-session-cache-memcached-private-key-file=<PATH>
Path to client private key for memcached connections to
store session cache.
.. option:: --tls-dyn-rec-warmup-threshold=<SIZE>
@@ -571,21 +665,23 @@ SSL/TLS
See https://tools.ietf.org/html/rfc7540#appendix-A for
the complete HTTP/2 cipher suites black list.
.. option:: --backend-tls-session-cache-per-worker=<N>
Set the maximum number of backend TLS session cache
stored per worker.
Default: ``10000``
HTTP/2 and SPDY
~~~~~~~~~~~~~~~
.. option:: -c, --http2-max-concurrent-streams=<N>
.. option:: -c, --frontend-http2-max-concurrent-streams=<N>
Set the maximum number of the concurrent streams in one
HTTP/2 and SPDY session.
frontend HTTP/2 and SPDY session.
Default: `` 100``
.. option:: --backend-http2-max-concurrent-streams=<N>
Set the maximum number of the concurrent streams in one
backend HTTP/2 session. This sets maximum number of
concurrent opened pushed streams. The maximum number of
concurrent requests are set by a remote server.
Default: ``100``
@@ -605,10 +701,6 @@ HTTP/2 and SPDY
Default: ``16``
.. option:: --frontend-no-tls
Disable SSL/TLS on frontend connections.
.. option:: --backend-http2-window-bits=<N>
Sets the initial window size of HTTP/2 backend
@@ -621,7 +713,7 @@ HTTP/2 and SPDY
Sets the per-connection window size of HTTP/2 backend
connection to 2\*\*<N>-1.
Default: ``16``
Default: ``30``
.. option:: --http2-no-cookie-crumbling
@@ -639,11 +731,10 @@ HTTP/2 and SPDY
Disable HTTP/2 server push. Server push is supported by
default mode and HTTP/2 frontend via Link header field.
It is also supported if both frontend and backend are
HTTP/2 (which implies :option:`--http2-bridge` or :option:`\--client` mode).
In this case, server push from backend session is
relayed to frontend, and server push via Link header
field is also supported. HTTP SPDY frontend does not
support server push.
HTTP/2 in default mode. In this case, server push from
backend session is relayed to frontend, and server push
via Link header field is also supported. SPDY frontend
does not support server push.
Mode
@@ -652,38 +743,16 @@ Mode
.. describe:: (default mode)
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. If
:option:`--frontend-no-tls` is used, accept HTTP/2 and HTTP/1.1.
The incoming HTTP/1.1 connection can be upgraded to
HTTP/2 through HTTP Upgrade. The protocol to the
backend is HTTP/1.1.
Accept HTTP/2, SPDY and HTTP/1.1 over SSL/TLS. "no-tls"
parameter is used in :option:`--frontend` option, accept HTTP/2
and HTTP/1.1 over cleartext TCP. The incoming HTTP/1.1
connection can be upgraded to HTTP/2 through HTTP
Upgrade.
.. option:: -s, --http2-proxy
Like default mode, but enable secure proxy mode.
.. option:: --http2-bridge
Like default mode, but communicate with the backend in
HTTP/2 over SSL/TLS. Thus the incoming all connections
are converted to HTTP/2 connection and relayed to the
backend. See :option:`--backend-http-proxy-uri` option if you are
behind the proxy and want to connect to the outside
HTTP/2 proxy.
.. option:: --client
Accept HTTP/2 and HTTP/1.1 without SSL/TLS. The
incoming HTTP/1.1 connection can be upgraded to HTTP/2
connection through HTTP Upgrade. The protocol to the
backend is HTTP/2. To use nghttpx as a forward proxy,
use :option:`-p` option instead.
.. option:: -p, --client-proxy
Like :option:`--client` option, but it also requires the request
path from frontend must be an absolute URI, suitable for
use as a forward proxy.
Like default mode, but enable forward proxy. This is so
called HTTP/2 proxy mode.
Logging
@@ -824,17 +893,15 @@ HTTP
.. option:: --no-location-rewrite
Don't rewrite location header field on :option:`--http2-bridge`\,
:option:`--client` and default mode. For :option:`\--http2-proxy` and
:option:`--client-proxy` mode, location header field will not be
altered regardless of this option.
Don't rewrite location header field in default mode.
When :option:`--http2-proxy` is used, location header field will
not be altered regardless of this option.
.. option:: --host-rewrite
Rewrite host and :authority header fields on
:option:`--http2-bridge`\, :option:`--client` and default mode. For
:option:`--http2-proxy` and :option:`\--client-proxy` mode, these headers
will not be altered regardless of this option.
Rewrite host and :authority header fields in default
mode. When :option:`--http2-proxy` is used, these headers will
not be altered regardless of this option.
.. option:: --altsvc=<PROTOID,PORT[,HOST,[ORIGIN]]>
@@ -895,6 +962,15 @@ HTTP
Default: ``500``
.. option:: --error-page=(<CODE>|*)=<PATH>
Set file path to custom error page served when nghttpx
originally generates HTTP error status code <CODE>.
<CODE> must be greater than or equal to 400, and at most
599. If "*" is used instead of <CODE>, it matches all
HTTP status code. If error status code comes from
backend server, the custom error pages are not used.
Debug
~~~~~
@@ -1082,12 +1158,12 @@ Currently, the following restriction is applied for server push:
This limitation may be loosened in the future release.
nghttpx also supports server push if both frontend and backend are
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
In this case, in addition to server push via Link header field, server
push from backend is relayed to frontend HTTP/2 session.
HTTP/2 in default mode. In this case, in addition to server push via
Link header field, server push from backend is forwarded to frontend
HTTP/2 session.
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
:option:`--client-proxy` is used.
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
used.
UNIX DOMAIN SOCKET
------------------
@@ -1134,6 +1210,10 @@ insert serialized session data to memcached with
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1173,6 +1253,10 @@ used, LEN must be 48. If
keys. The key appeared first is used as encryption key. All the
remaining keys are used as decryption only.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached` option.
If :option:`--tls-ticket-key-file` is given, encryption key is read
from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
@@ -1241,7 +1325,24 @@ 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:class:: Request
@@ -1277,7 +1378,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
@@ -1304,7 +1411,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

View File

@@ -98,12 +98,12 @@ Currently, the following restriction is applied for server push:
This limitation may be loosened in the future release.
nghttpx also supports server push if both frontend and backend are
HTTP/2 (which implies :option:`--http2-bridge` or :option:`--client`).
In this case, in addition to server push via Link header field, server
push from backend is relayed to frontend HTTP/2 session.
HTTP/2 in default mode. In this case, in addition to server push via
Link header field, server push from backend is forwarded to frontend
HTTP/2 session.
HTTP/2 server push will be disabled if :option:`--http2-proxy` or
:option:`--client-proxy` is used.
HTTP/2 server push will be disabled if :option:`--http2-proxy` is
used.
UNIX DOMAIN SOCKET
------------------
@@ -150,6 +150,10 @@ insert serialized session data to memcached with
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -189,6 +193,10 @@ used, LEN must be 48. If
keys. The key appeared first is used as encryption key. All the
remaining keys are used as decryption only.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached` option.
If :option:`--tls-ticket-key-file` is given, encryption key is read
from the given file. In this case, nghttpx does not rotate key
automatically. To rotate key, one has to restart nghttpx (see
@@ -257,7 +265,24 @@ 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:class:: Request
@@ -293,7 +318,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
@@ -320,7 +351,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

View File

@@ -1,6 +1,79 @@
Programmers' Guide
==================
Architecture
------------
The most notable point in nghttp2 library architecture is it does not
perform any I/O. nghttp2 only performs HTTP/2 protocol stuff based on
input byte strings. It will calls callback functions set by
applications while processing input. The output of nghttp2 is just
byte string. An application is responsible to send these output to
the remote peer. The callback functions may be called while producing
output.
Not doing I/O makes embedding nghttp2 library in the existing code
base very easy. Usually, the existing applications have its own I/O
event loops. It is very hard to use nghttp2 in that situation if
nghttp2 does its own I/O. It also makes light weight language wrapper
for nghttp2 easy with the same reason. The down side is that an
application author has to write more code to write complete
application using nghttp2. This is especially true for simple "toy"
application. For the real applications, however, this is not the
case. This is because you probably want to support HTTP/1 which
nghttp2 does not provide, and to do that, you will need to write your
own HTTP/1 stack or use existing third-party library, and bind them
together with nghttp2 and I/O event loop. In this point, not
performing I/O in nghttp2 has more point than doing it.
The primary object that an application uses is :type:`nghttp2_session`
object, which is opaque struct and its details are hidden in order to
ensure the upgrading its internal architecture without breaking the
backward compatibility. An application can set callbacks to
:type:`nghttp2_session` object through the dedicated object and
functions, and it also interacts with it via many API function calls.
An application can create as many :type:`nghttp2_session` object as it
wants. But single :type:`nghttp2_session` object must be used by a
single thread at the same time. This is not so hard to enforce since
most event-based architecture applicatons use is single thread per
core, and handling one connection I/O is done by single thread.
To feed input to :type:`nghttp2_session` object, one can use
`nghttp2_session_recv()` or `nghttp2_session_mem_recv()` functions.
They behave similarly, and the difference is that
`nghttp2_session_recv()` will use :type:`nghttp2_read_callback` to get
input. On the other hand, `nghttp2_session_mem_recv()` will take
input as its parameter. If in doubt, use `nghttp2_session_mem_recv()`
since it is simpler, and could be faster since it avoids calling
callback function.
To get output from :type:`nghttp2_session` object, one can use
`nghttp2_session_send()` or `nghttp2_session_mem_send()`. The
difference between them is that the former uses
:type:`nghttp2_send_callback` to pass output to an application. On
the other hand, the latter returns the output to the caller. If in
doubt, use `nghttp2_session_mem_send()` since it is simpler. But
`nghttp2_session_send()` might be easier to use if the output buffer
an application has is fixed sized.
In general, an application should call `nghttp2_session_mem_send()`
when it gets input from underlying connection. Since there is great
chance to get something pushed into transmission queue while the call
of `nghttp2_session_mem_send()`, it is recommended to call
`nghttp2_session_mem_recv()` after `nghttp2_session_mem_send()`.
There is a question when we are safe to close HTTP/2 session without
waiting for the closure of underlying connection. We offer 2 API
calls for this: `nghttp2_session_want_read()` and
`nghttp2_session_want_write()`. If they both return 0, application
can destroy :type:`nghttp2_session`, and then close the underlying
connection. But make sure that the buffered output has been
transmitted to the peer before closing the connection when
`nghttp2_session_mem_send()` is used, since
`nghttp2_session_want_write()` does not take into account the
transmission of the buffered data outside of :type:`nghttp2_session`.
Includes
--------
@@ -103,3 +176,251 @@ header field if it is present (this does not include padding bytes).
Any deviation results in stream error of type PROTOCOL_ERROR. If
error is found in PUSH_PROMISE frame, stream error is raised against
promised stream.
Implement user defined HTTP/2 non-critical extensions
-----------------------------------------------------
As of nghttp2 v1.8.0, we have added HTTP/2 non-critical extension
framework, which lets application send and receive user defined custom
HTTP/2 non-critical extension frames. nghttp2 also offers built-in
functionality to send and receive official HTTP/2 extension frames
(e.g., ALTSVC frame). For these built-in handler, refer to the next
section.
To send extension frame, use `nghttp2_submit_extension()`, and
implement :type:`nghttp2_pack_extension_callback`. The callback
implements how to encode data into wire format. The callback must be
set to :type:`nghttp2_session_callbacks` using
`nghttp2_session_callbacks_set_pack_extension_callback()`.
For example, we will illustrate how to send `ALTSVC
<https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-14>`_ frame.
.. code-block:: c
typedef struct {
const char *origin;
const char *field;
} alt_svc;
ssize_t pack_extension_callback(nghttp2_session *session, uint8_t *buf,
size_t len, const nghttp2_frame *frame,
void *user_data) {
const alt_svc *altsvc = (const alt_svc *)frame->ext.payload;
size_t originlen = strlen(altsvc->origin);
size_t fieldlen = strlen(altsvc->field);
uint8_t *p;
if (len < 2 + originlen + fieldlen || originlen > 0xffff) {
return NGHTTP2_ERR_CANCEL;
}
p = buf;
*p++ = originlen >> 8;
*p++ = originlen & 0xff;
memcpy(p, altsvc->origin, originlen);
p += originlen;
memcpy(p, altsvc->field, fieldlen);
p += fieldlen;
return p - buf;
}
This implements :type:`nghttp2_pack_extension_callback`. We have to
set this callback to :type:`nghttp2_session_callbacks`:
.. code-block:: c
nghttp2_session_callbacks_set_pack_extension_callback(
callbacks, pack_extension_callback);
To send ALTSVC frame, call `nghttp2_submit_extension()`:
.. code-block:: c
static const alt_svc altsvc = {"example.com", "h2=\":8000\""};
nghttp2_submit_extension(session, 0xa, NGHTTP2_FLAG_NONE, 0,
(void *)&altsvc);
Notice that ALTSVC is use frame type ``0xa``.
To receive extension frames, implement 2 callbacks:
:type:`nghttp2_unpack_extension_callback` and
:type:`nghttp2_on_extension_chunk_recv_callback`.
:type:`nghttp2_unpack_extension_callback` implements the way how to
decode wire format. :type:`nghttp2_on_extension_chunk_recv_callback`
implements how to buffer the incoming extension payload. These
callbacks must be set using
`nghttp2_session_callbacks_set_unpack_extension_callback()` and
`nghttp2_session_callbacks_set_on_extension_chunk_recv_callback()`
respectively. The application also must tell the library which
extension frame type it is willing to receive using
`nghttp2_option_set_user_recv_extension_type()`. Note that the
application has to create :type:`nghttp2_option` object for that
purpose, and initialize session with it.
We use ALTSVC again to illustrate how to receive extension frames. We
use different ``alt_svc`` struct than the previous one.
First implement 2 callbacks. We store incoming ALTSVC payload to
global variable ``altsvc_buffer``. Don't do this in production code
since this is not thread safe:
.. code-block:: c
typedef struct {
const uint8_t *origin;
size_t originlen;
const uint8_t *field;
size_t fieldlen;
} alt_svc;
/* buffers incoming ALTSVC payload */
uint8_t altsvc_buffer[4096];
/* The length of byte written to altsvc_buffer */
size_t altsvc_bufferlen = 0;
int on_extension_chunk_recv_callback(nghttp2_session *session,
const nghttp2_frame_hd *hd,
const uint8_t *data, size_t len,
void *user_data) {
if (sizeof(altsvc_buffer) < altsvc_bufferlen + len) {
altsvc_bufferlen = 0;
return NGHTTP2_ERR_CANCEL;
}
memcpy(altsvc_buffer + altsvc_bufferlen, data, len);
altsvc_bufferlen += len;
return 0;
}
int unpack_extension_callback(nghttp2_session *session, void **payload,
const nghttp2_frame_hd *hd, void *user_data) {
uint8_t *origin, *field;
size_t originlen, fieldlen;
uint8_t *p, *end;
alt_svc *altsvc;
if (altsvc_bufferlen < 2) {
altsvc_bufferlen = 0;
return NGHTTP2_ERR_CANCEL;
}
p = altsvc_buffer;
end = altsvc_buffer + altsvc_bufferlen;
originlen = ((*p) << 8) + *(p + 1);
p += 2;
if (p + originlen > end) {
altsvc_bufferlen = 0;
return NGHTTP2_ERR_CANCEL;
}
origin = p;
field = p + originlen;
fieldlen = end - field;
altsvc = (alt_svc *)malloc(sizeof(alt_svc));
altsvc->origin = origin;
altsvc->originlen = originlen;
altsvc->field = field;
altsvc->fieldlen = fieldlen;
*payload = altsvc;
altsvc_bufferlen = 0;
return 0;
}
Set these callbacks to :type:`nghttp2_session_callbacks`:
.. code-block:: c
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
callbacks, on_extension_chunk_recv_callback);
nghttp2_session_callbacks_set_unpack_extension_callback(
callbacks, unpack_extension_callback);
In ``unpack_extension_callback`` above, we set unpacked ``alt_svc``
object to ``*payload``. nghttp2 library then, calls
:type:`nghttp2_on_frame_recv_callback`, and ``*payload`` will be
available as ``frame->ext.payload``:
.. code-block:: c
int on_frame_recv_callback(nghttp2_session *session,
const nghttp2_frame *frame, void *user_data) {
switch (frame->hd.type) {
...
case 0xa: {
alt_svc *altsvc = (alt_svc *)frame->ext.payload;
fprintf(stderr, "ALTSVC frame received\n");
fprintf(stderr, " origin: %.*s\n", (int)altsvc->originlen, altsvc->origin);
fprintf(stderr, " field : %.*s\n", (int)altsvc->fieldlen, altsvc->field);
free(altsvc);
break;
}
}
return 0;
}
Finally, application should set the extension frame types it is
willing to receive:
.. code-block:: c
nghttp2_option_set_user_recv_extension_type(option, 0xa);
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
its creation:
.. code-block:: c
nghttp2_session_client_new2(&session, callbacks, user_data, option);
How to use built-in HTTP/2 extension frame handlers
---------------------------------------------------
In the previous section, we talked about the user defined HTTP/2
extension frames. In this section, we talk about HTTP/2 extension
frame support built into nghttp2 library.
As of this writing, nghttp2 supports ALTSVC extension frame. To send
ALTSVC frame, use `nghttp2_submit_altsvc()` function.
To receive ALTSVC frame through built-in functionality, application
has to use `nghttp2_option_set_builtin_recv_extension_type()` to
indicate the willingness of receiving ALTSVC frame:
.. code-block:: c
nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC);
This is very similar to the case when we used to receive user defined
frames.
If the same frame type is set using
`nghttp2_option_set_builtin_recv_extension_type()` and
`nghttp2_option_set_user_recv_extension_type()`, the latter takes
precedence. Application can implement its own frame handler rather
than using built-in handler.
The :type:`nghttp2_option` must be set to :type:`nghttp2_session` on
its creation, like so:
.. code-block:: c
nghttp2_session_client_new2(&session, callbacks, user_data, option);
When ALTSVC is received, :type:`nghttp2_on_frame_recv_callback` will
be called as usual.

View File

@@ -1,33 +1,43 @@
.. program:: h2load
h2load - HTTP/2 benchmarking tool - HOW-TO
==========================================
h2load is benchmarking tool for HTTP/2 and HTTP/1.1. If built with
spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it also
supports SPDY protocol. It supports SSL/TLS and clear text for all
supported protocols.
:doc:`h2load.1` is benchmarking tool for HTTP/2 and HTTP/1.1. If
built with spdylay (http://tatsuhiro-t.github.io/spdylay/) library, it
also supports SPDY protocol. It supports SSL/TLS and clear text for
all supported protocols.
Compiling from source
---------------------
h2load is compiled alongside nghttp2 and requires that the
``--enable-apps`` flag is passed to ``./configure`` and `required
dependencies <https://github.com/nghttp2/nghttp2#requirements>`_ are
available during compilation. For details on compiling, see `nghttp2:
Building from Git
<https://github.com/nghttp2/nghttp2#building-from-git>`_.
Basic Usage
-----------
In order to set benchmark settings, specify following 3 options.
``-n``
:option:`-n`
The number of total requests. Default: 1
``-c``
:option:`-c`
The number of concurrent clients. Default: 1
``-m``
The max concurrent streams to issue per client.
If ``auto`` is given, the number of given URIs is used.
Default: ``auto``
:option:`-m`
The max concurrent streams to issue per client. Default: 1
For SSL/TLS connection, the protocol will be negotiated via ALPN/NPN.
You can set specific protocols in ``--npn-list`` option. For
You can set specific protocols in :option:`--npn-list` option. For
cleartext connection, the default protocol is HTTP/2. To change the
protocol in cleartext connection, use ``--no-tls-proto`` option. For
convenience, ``--h1`` option forces HTTP/1.1 for both cleartext and
SSL/TLS connections.
protocol in cleartext connection, use :option:`--no-tls-proto` option.
For convenience, :option:`--h1` option forces HTTP/1.1 for both
cleartext and SSL/TLS connections.
Here is a command-line to perform benchmark to URI \https://localhost
using total 100000 requests, 100 concurrent clients and 10 max
@@ -62,11 +72,11 @@ benchmarking results. By default, h2load uses large enough flow
control window, which effectively disables flow control. To adjust
receiver flow control window size, there are following options:
``-w``
:option:`-w`
Sets the stream level initial window size to
(2**<N>)-1. For SPDY, 2**<N> is used instead.
``-W``
:option:`-W`
Sets the connection level initial window size to
(2**<N>)-1. For SPDY, if <N> is strictly less
than 16, this option is ignored. Otherwise
@@ -76,17 +86,17 @@ Multi-Threading
---------------
Sometimes benchmarking client itself becomes a bottleneck. To remedy
this situation, use ``-t`` option to specify the number of native
this situation, use :option:`-t` option to specify the number of native
thread to use.
``-t``
:option:`-t`
The number of native threads. Default: 1
Selecting protocol for clear text
---------------------------------
By default, if \http:// URI is given, HTTP/2 protocol is used. To
change the protocol to use for clear text, use ``-p`` option.
change the protocol to use for clear text, use :option:`-p` option.
Multiple URIs
-------------
@@ -97,3 +107,12 @@ If multiple URIs are specified, they are used in round robin manner.
Please note that h2load uses scheme, host and port in the first URI
and ignores those parts in the rest of the URIs.
UNIX domain socket
------------------
To request against UNIX domain socket, use :option:`--base-uri`, and
specify ``unix:`` followed by the path to UNIX domain socket. For
example, if UNIX domain socket is ``/tmp/nghttpx.sock``, use
``--base-uri=unix:/tmp/nghttpx.sock``. h2load uses scheme, host and
port in the first URI in command-line or input file.

View File

@@ -8,7 +8,8 @@ nghttp2 - HTTP/2 C Library
This is an implementation of Hypertext Transfer Protocol version 2.
The project is hosted at `github.com/tatsuhiro-t/nghttp2 <https://github.com/tatsuhiro-t/nghttp2>`_.
The project is hosted at `github.com/nghttp2/nghttp2
<https://github.com/nghttp2/nghttp2>`_.
Contents:
@@ -36,17 +37,18 @@ Contents:
asio_http2_server.h
asio_http2_client.h
asio_http2.h
Source <https://github.com/tatsuhiro-t/nghttp2>
Issues <https://github.com/tatsuhiro-t/nghttp2/issues>
Source <https://github.com/nghttp2/nghttp2>
Issues <https://github.com/nghttp2/nghttp2/issues>
nghttp2.org <https://nghttp2.org/>
Released Versions
=================
https://github.com/tatsuhiro-t/nghttp2/releases
https://github.com/nghttp2/nghttp2/releases
Resources
---------
* HTTP/2 https://tools.ietf.org/html/rfc7540
* HPACK https://tools.ietf.org/html/rfc7541
* HTTP Alternative Services https://tools.ietf.org/html/rfc7838

View File

@@ -1,44 +1,54 @@
.. program:: nghttpx
nghttpx - HTTP/2 proxy - HOW-TO
===============================
nghttpx is a proxy translating protocols between HTTP/2 and other
protocols (e.g., HTTP/1, SPDY). It operates in several modes and each
mode may require additional programs to work with. This article
describes each operation mode and explains the intended use-cases. It
also covers some useful options later.
:doc:`nghttpx.1` is a proxy translating protocols between HTTP/2 and
other protocols (e.g., HTTP/1, SPDY). It operates in several modes
and each mode may require additional programs to work with. This
article describes each operation mode and explains the intended
use-cases. It also covers some useful options later.
Default mode
------------
If nghttpx is invoked without any ``-s``, ``-p`` and ``--client``, it
operates in default mode. In this mode, nghttpx frontend listens for
HTTP/2 requests and translates them to HTTP/1 requests. Thus it works
as reverse proxy (gateway) for HTTP/2 clients to HTTP/1 web server.
This is also known as "HTTP/2 router". HTTP/1 requests are also
supported in frontend as a fallback. If nghttpx is linked with
spdylay library and frontend connection is SSL/TLS, the frontend also
supports SPDY protocol.
If nghttpx is invoked without :option:`--http2-proxy`, it operates in
default mode. In this mode, it works as reverse proxy (gateway) for
both HTTP/2 and HTTP/1 clients to backend servers. This is also known
as "HTTP/2 router". If nghttpx is linked with spdylay library and
frontend connection is SSL/TLS, the frontend also supports SPDY
protocol.
By default, this mode's frontend connection is encrypted using
SSL/TLS. So server's private key and certificate must be supplied to
the command line (or through configuration file). In this case, the
frontend protocol selection will be done via ALPN or NPN.
By default, frontend connection is encrypted using SSL/TLS. So
server's private key and certificate must be supplied to the command
line (or through configuration file). In this case, the frontend
protocol selection will be done via ALPN or NPN.
With ``--frontend-no-tls`` option, user can turn off SSL/TLS in
frontend connection. In this case, SPDY protocol is not available
even if spdylay library is liked to nghttpx. HTTP/2 and HTTP/1 are
available on the frontend and a HTTP/1 connection can be upgraded to
HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by sending
HTTP/2 connection preface is also supported.
To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option. In this case, SPDY protocol is not
available even if spdylay library is liked to nghttpx. HTTP/2 and
HTTP/1 are available on the frontend, and an HTTP/1 connection can be
upgraded to HTTP/2 using HTTP Upgrade. Starting HTTP/2 connection by
sending HTTP/2 connection preface is also supported.
By default, backend HTTP/1 connections are not encrypted. To enable
TLS on HTTP/1 backend connections, use ``--backend-http1-tls`` option.
This applies to all mode whose backend connections are HTTP/1.
nghttpx can listen on multiple frontend addresses. This is achieved
by using multiple :option:`--frontend` options. For each frontend
address, TLS can be enabled or disabled.
The backend is supposed to be HTTP/1 Web server. For example, to make
By default, backend connections are not encrypted. To enable TLS
encryption on backend connections, use ``tls`` keyword in
:option:`--backend` option. Using patterns and ``proto`` keyword in
:option:`--backend` option, backend application protocol can be
specified per host/request path pattern. It means that you can use
both HTTP/2 and HTTP/1 in backend connections at the same time. Note
that default backend protocol is HTTP/1.1. To use HTTP/2 in backend,
you have to specify ``h2`` in ``proto`` keyword in :option:`--backend`
explicitly.
The backend is supposed to be Web server. For example, to make
nghttpx listen to encrypted HTTP/2 requests at port 8443, and a
backend HTTP/1 web server is configured to listen to HTTP/1 request at
port 8080 in the same host, run nghttpx command-line like this::
backend Web server is configured to listen to HTTP request at port
8080 in the same host, run nghttpx command-line like this::
$ nghttpx -f0.0.0.0,8443 -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
@@ -50,30 +60,36 @@ example, you can send GET request to the server using nghttp::
HTTP/2 proxy mode
-----------------
If nghttpx is invoked with ``-s`` option, it operates in HTTP/2 proxy
mode. The supported protocols in frontend and backend connections are
the same in `default mode`_. The difference is that this mode acts
like forward proxy and assumes the backend is HTTP/1 proxy server
(e.g., squid, traffic server). So HTTP/1 request must include
absolute URI in request line.
If nghttpx is invoked with :option:`--http2-proxy` (or its shorthand
:option:`-s`) option, it operates in HTTP/2 proxy mode. The supported
protocols in frontend and backend connections are the same in `default
mode`_. The difference is that this mode acts like forward proxy and
assumes the backend is HTTP proxy server (e.g., Squid, Apache Traffic
Server). HTTP/1 request must include absolute URI in request line.
By default, frontend connection is encrypted. So this mode is also
called secure proxy. If nghttpx is linked with spdylay, it supports
SPDY protocols and it works as so called SPDY proxy.
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
connection, so the connection gets insecure.
To turn off encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` option.
The backend must be HTTP/1 proxy server. nghttpx supports multiple
backend server addresses. It translates incoming requests to HTTP/1
The backend must be HTTP proxy server. nghttpx supports multiple
backend server addresses. It translates incoming requests to HTTP
request to backend server. The backend server performs real proxy
work for each request, for example, dispatching requests to the origin
server and caching contents.
The backend connection is not encrypted by default. To enable
encryption, use ``tls`` keyword in :option:`--backend` option. The
default backend protocol is HTTP/1.1. To use HTTP/2 in backend
connection, use :option:`--backend` option, and specify ``h2`` in
``proto`` keyword explicitly.
For example, to make nghttpx listen to encrypted HTTP/2 requests at
port 8443, and a backend HTTP/1 proxy server is configured to listen
to HTTP/1 request at port 8080 in the same host, run nghttpx
command-line like this::
port 8443, and a backend HTTP proxy server is configured to listen to
HTTP/1 request at port 8080 in the same host, run nghttpx command-line
like this::
$ nghttpx -s -f'*,8443' -b127.0.0.1,8080 /path/to/server.key /path/to/server.crt
@@ -96,7 +112,9 @@ Chromium require valid certificate for secure proxy.
For Firefox, open Preference window and select Advanced then click
Network tab. Clicking Connection Settings button will show the
dialog. Select "Automatic proxy configuration URL" and enter the path
to proxy.pac file, something like this::
to proxy.pac file, something like this:
.. code-block:: text
file:///path/to/proxy.pac
@@ -112,136 +130,51 @@ configuration items to edit::
CONFIG proxy.config.url_remap.remap_required INT 0
Consult Traffic server `documentation
<https://docs.trafficserver.apache.org/en/latest/admin/forward-proxy.en.html>`_
<http://trafficserver.readthedocs.org/en/latest/admin-guide/configuration/transparent-forward-proxying.en.html>`_
to know how to configure traffic server as forward proxy and its
security implications.
Client mode
-----------
Disable frontend SSL/TLS
------------------------
If nghttpx is invoked with ``--client`` option, it operates in client
mode. In this mode, nghttpx listens for plain, unencrypted HTTP/2 and
HTTP/1 requests and translates them to encrypted HTTP/2 requests to
the backend. User cannot enable SSL/TLS in frontend connection.
The frontend connections are encrypted with SSL/TLS by default. To
turn off SSL/TLS, use ``no-tls`` keyword in :option:`--frontend`
option. If this option is used, the private key and certificate are
not required to run nghttpx.
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
Upgrade. To disable SSL/TLS in backend connection, use
``--backend-no-tls`` option.
Enable backend SSL/TLS
----------------------
By default, the number of backend HTTP/2 connections per worker
(thread) is determined by number of ``-b`` option. To adjust this
value, use ``--backend-http2-connections-per-worker`` option.
The backend connections are not encrypted by default. To enable
SSL/TLS encryption, use ``tls`` keyword in :option:`--backend` option.
The backend server is supporsed to be a HTTP/2 web server (e.g.,
nghttpd). The one use-case of this mode is utilize existing HTTP/1
clients to test HTTP/2 deployment. Suppose that HTTP/2 web server
listens to port 80 without encryption. Then run nghttpx as client
mode to access to that web server::
Enable SSL/TLS on memcached connection
--------------------------------------
$ nghttpx --client -f127.0.0.1,8080 -b127.0.0.1,80 --backend-no-tls
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.
.. note::
Specifying additional server certificates
-----------------------------------------
You may need ``-k`` option if HTTP/2 server enables SSL/TLS and
its certificate is self-signed. But please note that it is
insecure.
Then you can use curl to access HTTP/2 server via nghttpx::
$ curl http://localhost:8080/
Client proxy mode
-----------------
If nghttpx is invoked with ``-p`` option, it operates in client proxy
mode. This mode behaves like `client mode`_, but it works like
forward proxy. So HTTP/1 request must include absolute URI in request
line.
HTTP/1 frontend connection can be upgraded to HTTP/2 using HTTP
Upgrade. To disable SSL/TLS in backend connection, use
``--backend-no-tls`` option.
By default, the number of backend HTTP/2 connections per worker
(thread) is determined by number of ``-b`` option. To adjust this
value, use ``--backend-http2-connections-per-worker`` option.
The backend server must be a HTTP/2 proxy. You can use nghttpx in
`HTTP/2 proxy mode`_ as backend server. The one use-case of this mode
is utilize existing HTTP/1 clients to test HTTP/2 connections between
2 proxies. The another use-case is use this mode to aggregate local
HTTP/1 connections to one HTTP/2 backend encrypted connection. This
makes HTTP/1 clients which does not support secure proxy can use
secure HTTP/2 proxy via nghttpx client mode.
Suppose that HTTP/2 proxy listens to port 8443, just like we saw in
`HTTP/2 proxy mode`_. To run nghttpx in client proxy mode to access
that server, invoke nghttpx like this::
$ nghttpx -p -f127.0.0.1,8080 -b127.0.0.1,8443
.. note::
You may need ``-k`` option if HTTP/2 server's certificate is
self-signed. But please note that it is insecure.
Then you can use curl to issue HTTP request via HTTP/2 proxy::
$ curl --http-proxy=http://localhost:8080 http://www.google.com/
You can configure web browser to use localhost:8080 as forward
proxy.
HTTP/2 bridge mode
------------------
If nghttpx is invoked with ``--http2-bridge`` option, it operates in
HTTP/2 bridge mode. The supported protocols in frontend connections
are the same in `default mode`_. The protocol in backend is HTTP/2
only.
With ``--frontend-no-tls`` option, SSL/TLS is turned off in frontend
connection, so the connection gets insecure. To disable SSL/TLS in
backend connection, use ``--backend-no-tls`` option.
By default, the number of backend HTTP/2 connections per worker
(thread) is determined by number of ``-b`` option. To adjust this
value, use ``--backend-http2-connections-per-worker`` option.
The backend server is supporsed to be a HTTP/2 web server or HTTP/2
proxy. If backend server is HTTP/2 proxy, use
``--no-location-rewrite`` and ``--no-host-rewrite`` options to disable
rewriting location, host and :authority header field.
The use-case of this mode is aggregate the incoming connections to one
HTTP/2 connection. One backend HTTP/2 connection is created per
worker (thread).
Disable SSL/TLS
---------------
In `default mode`_, `HTTP/2 proxy mode`_ and `HTTP/2 bridge mode`_,
frontend connections are encrypted with SSL/TLS by default. To turn
off SSL/TLS, use ``--frontend-no-tls`` option. If this option is
used, the private key and certificate are not required to run nghttpx.
In `client mode`_, `client proxy mode`_ and `HTTP/2 bridge mode`_,
backend connections are encrypted with SSL/TLS by default. To turn
off SSL/TLS, use ``--backend-no-tls`` option.
nghttpx accepts additional server private key and certificate pairs
using :option:`--subcert` option. It can be used multiple times.
Specifying additional CA certificate
------------------------------------
By default, nghttpx tries to read CA certificate from system. But
depending on the system you use, this may fail or is not supported.
To specify CA certificate manually, use ``--cacert`` option. The
specified file must be PEM format and can contain multiple
To specify CA certificate manually, use :option:`--cacert` option.
The specified file must be PEM format and can contain multiple
certificates.
By default, nghttpx validates server's certificate. If you want to
turn off this validation, knowing this is really insecure and what you
are doing, you can use ``-k`` option to disable certificate
validation.
are doing, you can use :option:`--insecure` option to disable
certificate validation.
Read/write rate limit
---------------------
@@ -250,9 +183,9 @@ nghttpx supports transfer rate limiting on frontend connections. You
can do rate limit per frontend connection for reading and writing
individually.
To perform rate limit for reading, use ``--read-rate`` and
``--read-burst`` options. For writing, use ``--write-rate`` and
``--write-burst``.
To perform rate limit for reading, use :option:`--read-rate` and
:option:`--read-burst` options. For writing, use
:option:`--write-rate` and :option:`--write-burst`.
Please note that rate limit is performed on top of TCP and nothing to
do with HTTP/2 flow control.
@@ -294,14 +227,168 @@ Re-opening log files
When rotating log files, it is desirable to re-open log files after
log rotation daemon renamed existing log files. To tell nghttpx to
re-open log files, send USR1 signal to nghttpx process. It will
re-open files specified by ``--accesslog-file`` and
``--errorlog-file`` options.
re-open files specified by :option:`--accesslog-file` and
:option:`--errorlog-file` options.
Multiple frontend addresses
---------------------------
nghttpx can listen on multiple frontend addresses. To specify them,
just use :option:`--frontend` (or its shorthand :option:`-f`) option
repeatedly. TLS can be enabled or disabled per frontend address
basis. For example, to listen on port 443 with TLS enabled, and on
port 80 without TLS:
.. code-block:: text
frontend=*,443
frontend=*,80;no-tls
Multiple backend addresses
--------------------------
nghttpx supports multiple backend addresses. To specify them, just
use ``-b`` option repeatedly. For example, to use backend1:8080 and
backend2:8080, use command-line like this: ``-bbackend1,8080
-bbackend2,8080``. For HTTP/2 backend, see also
``--backend-http2-connections-per-worker`` option.
use :option:`--backend` (or its shorthand :option:`-b`) option
repeatedly. For example, to use ``192.168.0.10:8080`` and
``192.168.0.11:8080``, use command-line like this:
``-b192.168.0.10,8080 -b192.168.0.11,8080``. In configuration file,
this looks like:
.. code-block:: text
backend=192.168.0.10,8080
backend=192.168.0.11,8008
nghttpx can route request to different backend according to request
host and path. For example, to route request destined to host
``doc.example.com`` to backend server ``docserv:3000``, you can write
like so:
.. code-block:: text
backend=docserv,3000;doc.example.com/
When you write this option in command-line, you should enclose
argument with single or double quotes, since the character ``;`` has a
special meaning in shell.
To route, request to request path whose prefix is ``/foo`` to backend
server ``[::1]:8080``, you can write like so:
.. code-block:: text
backend=::1,8080;/foo
Of course, you can specify both host and request path at the same
time:
.. code-block:: text
backend=192.168.0.10,8080;example.com/foo
We can use ``*`` in the left most position of host to achieve wildcard
suffix match. If ``*`` is the left most character, then the remaining
string should match the request host suffix. ``*`` must match at
least one character. For example, ``*.example.com`` matches
``www.example.com`` and ``dev.example.com``, and does not match
``example.com`` and ``nghttp2.org``. The exact match (without ``*``)
always takes precedence over wildcard match.
One important thing you have to remember is that we have to specify
default routing pattern for so called "catch all" pattern. To write
"catch all" pattern, just specify backend server address, without
pattern.
Usually, host is the value of ``Host`` header field. In HTTP/2, the
value of ``:authority`` pseudo header field is used.
When you write multiple backend addresses sharing the same routing
pattern, they are used as load balancing. For example, to use 2
servers ``serv1:3000`` and ``serv2:3000`` for request host
``example.com`` and path ``/myservice``, you can write like so:
.. code-block:: text
backend=serv1,3000;example.com/myservice
backend=serv2,3000;example.com/myservice
You can also specify backend application protocol in
:option:`--backend` option using ``proto`` keyword after pattern.
Utilizing this allows ngttpx to route certain request to HTTP/2, other
requests to HTTP/1. For example, to route requests to ``/ws/`` in
backend HTTP/1.1 connection, and use backend HTTP/2 for other
requests, do this:
.. code-block:: text
backend=serv1,3000;/;proto=h2
backend=serv1,3000;/ws/;proto=http/1.1
Note that the backends share the same pattern must have the same
backend protocol. The default backend protocol is HTTP/1.1.
TLS can be enabed per pattern basis:
.. code-block:: text
backend=serv1,8443;/;proto=h2;tls
backend=serv2,8080;/ws/;proto=http/1.1
In the above case, connection to serv1 will be encrypted by TLS. On
the other hand, connection to serv2 will not be encrypted by TLS.
Migration from nghttpx v1.8.0 or earlier
----------------------------------------
As of nghttpx 1.9.0, ``--frontend-no-tls`` and ``--backend-no-tls``
have been removed.
To disable encryption on frontend connection, use ``no-tls`` keyword
in :option:`--frontend` potion:
.. code-block:: text
frontend=*,3000;no-tls
The TLS encryption is now disabled on backend connection in all modes
by default. To enable encryption on backend connection, use ``tls``
keyword in :option:`--backend` option:
.. code-block:: text
backend=127.0.0.1,8080;tls
As of nghttpx 1.9.0, ``--http2-bridge``, ``--client`` and
``--client-proxy`` options have been removed. These functionality can
be used using combinations of options.
Use following option instead of ``--http2-bridge``:
.. code-block:: text
backend=<ADDR>,<PORT>;;proto=h2;tls
Use following options instead of ``--client``:
.. code-block:: text
frontend=<ADDR>,<PORT>;no-tls
backend=<ADDR>,<PORT>;;proto=h2;tls
Use following options instead of ``--client-proxy``:
.. code-block:: text
http2-proxy=yes
frontend=<ADDR>,<PORT>;no-tls
backend=<ADDR>,<PORT>;;proto=h2;tls
We also removed ``--backend-http2-connections-per-worker`` option. It
was present because previously the number of backend h2 connection was
statically configured, and defaulted to 1. Now the number of backend
h2 connection is increased on demand. We know the maximum number of
concurrent streams per connection. When we push as many request as
the maximum concurrency to the one connection, we create another new
connection so that we can distribute load and avoid delay the request
processing. This is done automatically without any configuration.

53
examples/CMakeLists.txt Normal file
View File

@@ -0,0 +1,53 @@
if(ENABLE_EXAMPLES)
file(GLOB c_sources *.c)
set_source_files_properties(${c_sources} PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}")
file(GLOB cxx_sources *.cc)
set_source_files_properties(${cxx_sources} PROPERTIES
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
include_directories(
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/lib/includes
${CMAKE_BINARY_DIR}/lib/includes
${CMAKE_SOURCE_DIR}/src/includes
${CMAKE_SOURCE_DIR}/third-party
${LIBEVENT_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
)
link_libraries(
nghttp2
${LIBEVENT_OPENSSL_LIBRARIES}
${OPENSSL_LIBRARIES}
${APP_LIBRARIES}
)
add_executable(client client.c $<TARGET_OBJECTS:http-parser>)
add_executable(libevent-client libevent-client.c $<TARGET_OBJECTS:http-parser>)
add_executable(libevent-server libevent-server.c $<TARGET_OBJECTS:http-parser>)
add_executable(deflate deflate.c $<TARGET_OBJECTS:http-parser>)
if(ENABLE_TINY_NGHTTPD)
add_executable(tiny-nghttpd tiny-nghttpd.c $<TARGET_OBJECTS:http-parser>)
endif()
if(ENABLE_ASIO_LIB)
foreach(name asio-sv asio-sv2 asio-cl asio-cl2)
add_executable(${name} ${name}.cc $<TARGET_OBJECTS:http-parser>)
target_include_directories(${name} PRIVATE
${OPENSSL_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
target_link_libraries(${name}
nghttp2
nghttp2_asio
${JEMALLOC_LIBRARIES}
${OPENSSL_LIBRARIES}
${Boost_LIBRARIES}
${APP_LIBRARIES}
)
endforeach()
endif()
endif()

View File

@@ -21,6 +21,8 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTRA_DIST = CMakeLists.txt
if ENABLE_EXAMPLES
AM_CFLAGS = $(WARNCFLAGS)

View File

@@ -289,8 +289,6 @@ static int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
return 0;
}
#define MAX_OUTLEN 4096
/*
* The implementation of nghttp2_on_data_chunk_recv_callback type. We
* use this function to print the received response body.

View File

@@ -295,7 +295,7 @@ static size_t http_date(char *buf, time_t t) {
static char date[29];
static size_t datelen;
static void update_date() { datelen = http_date(date, time(NULL)); }
static void update_date(void) { datelen = http_date(date, time(NULL)); }
static size_t utos(char *buf, size_t len, uint64_t n) {
size_t nwrite = 0;

View File

@@ -106,7 +106,7 @@ def gen_enum():
def gen_index_header():
print '''\
static inline int lookup_token(const uint8_t *name, size_t namelen) {
static inline int32_t lookup_token(const uint8_t *name, size_t namelen) {
switch (namelen) {'''
b = build_header(HEADERS)
for size in sorted(b.keys()):

View File

@@ -92,6 +92,7 @@ OPTIONS = [
"tls-ticket-key-cipher",
"host-rewrite",
"tls-session-cache-memcached",
"tls-session-cache-memcached-tls",
"tls-ticket-key-memcached",
"tls-ticket-key-memcached-interval",
"tls-ticket-key-memcached-max-retry",
@@ -114,7 +115,23 @@ OPTIONS = [
"max-header-fields",
"no-http2-cipher-black-list",
"backend-http1-tls",
"backend-tls-session-cache-per-worker"
"tls-session-cache-memcached-cert-file",
"tls-session-cache-memcached-private-key-file",
"tls-session-cache-memcached-address-family",
"tls-ticket-key-memcached-tls",
"tls-ticket-key-memcached-cert-file",
"tls-ticket-key-memcached-private-key-file",
"tls-ticket-key-memcached-address-family",
"backend-address-family",
"frontend-http2-max-concurrent-streams",
"backend-http2-max-concurrent-streams",
"backend-connections-per-frontend",
"backend-tls",
"backend-connections-per-host",
"error-page",
"no-kqueue",
"frontend-http2-settings-timeout",
"backend-http2-settings-timeout",
]
LOGVARS = [

View File

@@ -1,2 +1,3 @@
# generated files
config.go
setenv

View File

@@ -0,0 +1,48 @@
set(GO_FILES
nghttpx_http1_test.go
nghttpx_http2_test.go
nghttpx_spdy_test.go
server_tester.go
)
# XXX unused
set(EXTRA_DIST
${GO_FILES}
server.key
server.crt
alt-server.key
alt-server.crt
setenv
req-set-header.rb
resp-set-header.rb
req-return.rb
resp-return.rb
)
add_custom_target(itprep
COMMAND go get -d -v golang.org/x/net/http2
COMMAND go get -d -v github.com/tatsuhiro-t/go-nghttp2
COMMAND go get -d -v github.com/tatsuhiro-t/spdy
COMMAND go get -d -v golang.org/x/net/websocket
)
# 'go test' requires both config.go and the test files in the same directory.
# For out-of-tree builds, config.go is normally not placed next to the source
# files, so copy the tests to the build directory as a workaround.
set(GO_BUILD_FILES)
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
foreach(gofile IN LISTS GO_FILES)
set(outfile "${CMAKE_CURRENT_BINARY_DIR}/${gofile}")
add_custom_command(OUTPUT "${outfile}"
COMMAND ${CMAKE_COMMAND} -E copy
"${CMAKE_CURRENT_SOURCE_DIR}/${gofile}" "${outfile}"
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${gofile}"
)
list(APPEND GO_BUILD_FILES "${outfile}")
endforeach()
endif()
add_custom_target(it
COMMAND sh setenv go test -v
DEPENDS ${GO_BUILD_FILES}
)

View File

@@ -21,11 +21,15 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTRA_DIST = \
GO_FILES = \
nghttpx_http1_test.go \
nghttpx_http2_test.go \
nghttpx_spdy_test.go \
server_tester.go \
server_tester.go
EXTRA_DIST = \
CMakeLists.txt \
$(GO_FILES) \
server.key \
server.crt \
alt-server.key \
@@ -36,11 +40,12 @@ EXTRA_DIST = \
req-return.rb \
resp-return.rb
itprep-local:
itprep:
go get -d -v golang.org/x/net/http2
go get -d -v github.com/tatsuhiro-t/go-nghttp2
go get -d -v github.com/tatsuhiro-t/spdy
go get -d -v golang.org/x/net/websocket
it-local:
it:
for i in $(GO_FILES); do [ -e $(builddir)/$$i ] || cp $(srcdir)/$$i $(builddir); done
sh setenv go test -v

View File

@@ -2,4 +2,5 @@ package nghttp2
const (
buildDir = "@top_builddir@"
sourceDir = "@top_srcdir@"
)

View File

@@ -53,23 +53,20 @@ func TestH1H1PlainGETClose(t *testing.T) {
}
}
// TestH1H1InvalidMethod tests that server rejects invalid method with
// 501 status code
func TestH1H1InvalidMethod(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward this request")
})
// TestH1H1UnknownMethod tests that server can forward unknown method
func TestH1H1UnknownMethod(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
defer st.Close()
res, err := st.http1(requestParam{
name: "TestH1H1InvalidMethod",
name: "TestH1H1UnknownMethod",
method: "get",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
if got, want := res.status, 501; got != want {
if got, want := res.status, 200; got != want {
t.Errorf("status = %v; want %v", got, want)
}
}
@@ -103,26 +100,26 @@ Content-Length: 0
}
}
// TestH1H1ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/1 backend failed.
func TestH1H1ConnectFailure(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
defer st.Close()
// // TestH1H1ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/1 backend failed.
// func TestH1H1ConnectFailure(t *testing.T) {
// st := newServerTester(nil, t, noopHandler)
// defer st.Close()
// shutdown backend server to simulate backend connect failure
st.ts.Close()
// // shutdown backend server to simulate backend connect failure
// st.ts.Close()
res, err := st.http1(requestParam{
name: "TestH1H1ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// res, err := st.http1(requestParam{
// name: "TestH1H1ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http1() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
// TestH1H1GracefulShutdown tests graceful shutdown.
func TestH1H1GracefulShutdown(t *testing.T) {
@@ -531,26 +528,26 @@ func TestH1H1RespPhaseReturn(t *testing.T) {
}
}
// TestH1H2ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/2 backend failed.
func TestH1H2ConnectFailure(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
defer st.Close()
// // TestH1H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestH1H2ConnectFailure(t *testing.T) {
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
// defer st.Close()
// simulate backend connect attempt failure
st.ts.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
res, err := st.http1(requestParam{
name: "TestH1H2ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// res, err := st.http1(requestParam{
// name: "TestH1H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http1() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
// TestH1H2NoHost tests that server rejects request without Host
// header field for HTTP/2 backend.

View File

@@ -568,43 +568,40 @@ func TestH2H1InvalidRequestCL(t *testing.T) {
}
}
// TestH2H1ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/1 backend failed.
func TestH2H1ConnectFailure(t *testing.T) {
// // TestH2H1ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/1 backend failed.
// func TestH2H1ConnectFailure(t *testing.T) {
// st := newServerTester(nil, t, noopHandler)
// defer st.Close()
// // shutdown backend server to simulate backend connect failure
// st.ts.Close()
// res, err := st.http2(requestParam{
// name: "TestH2H1ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http2() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
// TestH2H1UnknownMethod tests that server can forward unknown method.
func TestH2H1UnknownMethod(t *testing.T) {
st := newServerTester(nil, t, noopHandler)
defer st.Close()
// shutdown backend server to simulate backend connect failure
st.ts.Close()
res, err := st.http2(requestParam{
name: "TestH2H1ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// TestH2H1InvalidMethod tests that server rejects invalid method with
// 501.
func TestH2H1InvalidMethod(t *testing.T) {
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward this request")
})
defer st.Close()
res, err := st.http2(requestParam{
name: "TestH2H1InvalidMethod",
name: "TestH2H1UnknownMethod",
method: "get",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
if got, want := res.status, 501; got != want {
if got, want := res.status, 200; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
@@ -1486,26 +1483,26 @@ func TestH2H2InvalidResponseCL(t *testing.T) {
}
}
// TestH2H2ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/2 backend failed.
func TestH2H2ConnectFailure(t *testing.T) {
st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
defer st.Close()
// // TestH2H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestH2H2ConnectFailure(t *testing.T) {
// st := newServerTester([]string{"--http2-bridge"}, t, noopHandler)
// defer st.Close()
// simulate backend connect attempt failure
st.ts.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
res, err := st.http2(requestParam{
name: "TestH2H2ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.http2() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// res, err := st.http2(requestParam{
// name: "TestH2H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.http2() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
// TestH2H2HostRewrite tests that server rewrites host header field
func TestH2H2HostRewrite(t *testing.T) {

View File

@@ -210,22 +210,19 @@ func TestS3H1HeaderFields(t *testing.T) {
}
}
// TestS3H1InvalidMethod tests that server rejects invalid method with
// 501.
func TestS3H1InvalidMethod(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, func(w http.ResponseWriter, r *http.Request) {
t.Errorf("server should not forward this request")
})
// TestS3H1UnknownMethod tests that server can forward unknown method.
func TestS3H1UnknownMethod(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1"}, t, noopHandler)
defer st.Close()
res, err := st.spdy(requestParam{
name: "TestS3H1InvalidMethod",
name: "TestS3H1UnknownMethod",
method: "get",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
if got, want := res.status, 501; got != want {
if got, want := res.status, 200; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
@@ -384,26 +381,26 @@ func TestS3H1RespPhaseReturn(t *testing.T) {
}
}
// TestS3H2ConnectFailure tests that server handles the situation that
// connection attempt to HTTP/2 backend failed.
func TestS3H2ConnectFailure(t *testing.T) {
st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
defer st.Close()
// // TestS3H2ConnectFailure tests that server handles the situation that
// // connection attempt to HTTP/2 backend failed.
// func TestS3H2ConnectFailure(t *testing.T) {
// st := newServerTesterTLS([]string{"--npn-list=spdy/3.1", "--http2-bridge"}, t, noopHandler)
// defer st.Close()
// simulate backend connect attempt failure
st.ts.Close()
// // simulate backend connect attempt failure
// st.ts.Close()
res, err := st.spdy(requestParam{
name: "TestS3H2ConnectFailure",
})
if err != nil {
t.Fatalf("Error st.spdy() = %v", err)
}
want := 503
if got := res.status; got != want {
t.Errorf("status: %v; want %v", got, want)
}
}
// res, err := st.spdy(requestParam{
// name: "TestS3H2ConnectFailure",
// })
// if err != nil {
// t.Fatalf("Error st.spdy() = %v", err)
// }
// want := 503
// if got := res.status; got != want {
// t.Errorf("status: %v; want %v", got, want)
// }
// }
// TestS3H2ReqPhaseReturn tests mruby request phase hook returns
// custom response.

View File

@@ -6,10 +6,10 @@ import (
"crypto/tls"
"errors"
"fmt"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
"github.com/tatsuhiro-t/go-nghttp2"
"github.com/tatsuhiro-t/spdy"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
"golang.org/x/net/websocket"
"io"
"io/ioutil"
@@ -29,7 +29,8 @@ import (
const (
serverBin = buildDir + "/src/nghttpx"
serverPort = 3009
testDir = buildDir + "/integration-tests"
testDir = sourceDir + "/integration-tests"
logDir = buildDir + "/integration-tests"
)
func pair(name, value string) hpack.HeaderField {
@@ -85,14 +86,18 @@ func newServerTesterTLSConfig(args []string, t *testing.T, handler http.HandlerF
// newServerTesterInternal creates test context. If frontendTLS is
// true, set up TLS frontend connection.
func newServerTesterInternal(args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
func newServerTesterInternal(src_args []string, t *testing.T, handler http.Handler, frontendTLS bool, clientConfig *tls.Config) *serverTester {
ts := httptest.NewUnstartedServer(handler)
args := []string{}
backendTLS := false
for _, k := range args {
for _, k := range src_args {
switch k {
case "--http2-bridge":
backendTLS = true
default:
args = append(args, k)
}
}
if backendTLS {
@@ -101,9 +106,9 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
// NextProtos separately for ts.TLS. NextProtos set
// in nghttp2.ConfigureServer is effectively ignored.
ts.TLS = new(tls.Config)
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2-14")
ts.TLS.NextProtos = append(ts.TLS.NextProtos, "h2")
ts.StartTLS()
args = append(args, "-k")
args = append(args, "-k", "--backend-tls")
} else {
ts.Start()
}
@@ -111,8 +116,6 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
if frontendTLS {
scheme = "https"
args = append(args, testDir+"/server.key", testDir+"/server.crt")
} else {
args = append(args, "--frontend-no-tls")
}
backendURL, err := url.Parse(ts.URL)
@@ -123,8 +126,17 @@ func newServerTesterInternal(args []string, t *testing.T, handler http.Handler,
// URL.Host looks like "127.0.0.1:8080", but we want
// "127.0.0.1,8080"
b := "-b" + strings.Replace(backendURL.Host, ":", ",", -1)
args = append(args, fmt.Sprintf("-f127.0.0.1,%v", serverPort), b,
"--errorlog-file="+testDir+"/log.txt", "-LINFO")
if backendTLS {
b += ";;proto=h2;tls"
}
noTLS := "no-tls"
if frontendTLS {
noTLS = ""
}
args = append(args, fmt.Sprintf("-f127.0.0.1,%v;%v", serverPort, noTLS), b,
"--errorlog-file="+logDir+"/log.txt", "-LINFO")
authority := fmt.Sprintf("127.0.0.1:%v", serverPort)

View File

@@ -1,6 +1,12 @@
#!/bin/sh -e
libdir="@abs_top_builddir@/lib"
if [ -d "$libdir/.libs" ]; then
libdir="$libdir/.libs"
fi
export CGO_CFLAGS="-I@abs_top_srcdir@/lib/includes -I@abs_top_builddir@/lib/includes"
export CGO_LDFLAGS="-L@abs_top_builddir@/lib/.libs"
export LD_LIBRARY_PATH="@abs_top_builddir@/lib/.libs"
export CGO_LDFLAGS="-L$libdir"
export LD_LIBRARY_PATH="$libdir"
export GODEBUG=cgocheck=0
"$@"

51
lib/CMakeLists.txt Normal file
View File

@@ -0,0 +1,51 @@
add_subdirectory(includes)
include_directories(
"${CMAKE_CURRENT_SOURCE_DIR}/includes"
"${CMAKE_CURRENT_BINARY_DIR}/includes"
)
add_definitions(-DBUILDING_NGHTTP2)
set(NGHTTP2_SOURCES
nghttp2_pq.c nghttp2_map.c nghttp2_queue.c
nghttp2_frame.c
nghttp2_buf.c
nghttp2_stream.c nghttp2_outbound_item.c
nghttp2_session.c nghttp2_submit.c
nghttp2_helper.c
nghttp2_npn.c
nghttp2_hd.c nghttp2_hd_huffman.c nghttp2_hd_huffman_data.c
nghttp2_version.c
nghttp2_priority_spec.c
nghttp2_option.c
nghttp2_callbacks.c
nghttp2_mem.c
nghttp2_http.c
nghttp2_rcbuf.c
)
# Public shared library
add_library(nghttp2 SHARED ${NGHTTP2_SOURCES})
set_target_properties(nghttp2 PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
C_VISIBILITY_PRESET hidden
)
if(HAVE_CUNIT)
# Static library (for unittests because of symbol visibility)
add_library(nghttp2_static STATIC ${NGHTTP2_SOURCES})
set_target_properties(nghttp2_static PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}"
VERSION ${LT_VERSION} SOVERSION ${LT_SOVERSION}
ARCHIVE_OUTPUT_NAME nghttp2
)
target_compile_definitions(nghttp2_static PUBLIC "-DNGHTTP2_STATICLIB")
endif()
install(TARGETS nghttp2
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")

View File

@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = includes
EXTRA_DIST = Makefile.msvc
EXTRA_DIST = Makefile.msvc CMakeLists.txt
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \
@@ -47,7 +47,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \
nghttp2_option.c \
nghttp2_callbacks.c \
nghttp2_mem.c \
nghttp2_http.c
nghttp2_http.c \
nghttp2_rcbuf.c
HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_frame.h \
@@ -61,7 +62,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \
nghttp2_option.h \
nghttp2_callbacks.h \
nghttp2_mem.h \
nghttp2_http.h
nghttp2_http.h \
nghttp2_rcbuf.h
libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS)
libnghttp2_la_LDFLAGS = -no-undefined \

View File

@@ -12,16 +12,16 @@
#
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
USE_CYTHON := 1
#USE_CYTHON := 0
USE_CYTHON := 0
#USE_CYTHON := 1
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -r -e 's/(-DEV)?], //g')
_VERSION := $(shell grep AC_INIT ../configure.ac | cut -d'[' -f3 | sed -e 's/-DEV//g' -e 's/], //g')
_VERSION := $(subst ., ,$(_VERSION))
VER_MAJOR := $(word 1,$(_VERSION))
VER_MINOR := $(word 2,$(_VERSION))
VER_MICRO := $(word 3,$(_VERSION))
VERSION := $(VER_MAJOR).$(VER_MINOR).$(VER_MICRO)
VERSION_NUM := ($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO)
VERSION_NUM := (($(VER_MAJOR) << 16) + ($(VER_MINOR) << 8) + $(VER_MICRO))
GENERATED := 'Generated by $(realpath Makefile.MSVC)'
@@ -90,7 +90,8 @@ NGHTTP2_SRC := nghttp2_pq.c \
nghttp2_option.c \
nghttp2_callbacks.c \
nghttp2_mem.c \
nghttp2_http.c
nghttp2_http.c \
nghttp2_rcbuf.c
NGHTTP2_OBJ_R := $(addprefix $(OBJ_DIR)/r_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
@@ -101,7 +102,7 @@ NGHTTP2_OBJ_D := $(addprefix $(OBJ_DIR)/d_, $(notdir $(NGHTTP2_SRC:.c=.obj)))
clean_nghttp2_pyd_0 clean_nghttp2_pyd_1
all: intro $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
all: intro includes/nghttp2/nghttp2ver.h $(OBJ_DIR) $(TARGETS) build_nghttp2_pyd_$(USE_CYTHON)
@echo 'Welcome to NgHTTP2 (release + debug).'
@echo 'Do a "make -f Makefile.MSVC install" at own risk!'
@@ -193,17 +194,17 @@ $(OBJ_DIR)/d_%.obj: %.c $(THIS_MAKEFILE)
@echo
$(OBJ_DIR)/r_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
$(RC) -nologo -D_RELEASE -Fo $@ $<
$(RC) -D_RELEASE -Fo $@ $<
@echo
$(OBJ_DIR)/d_nghttp2.res: $(OBJ_DIR)/nghttp2.rc $(THIS_MAKEFILE)
$(RC) -nologo -D_DEBUG -Fo $@ $<
$(RC) -D_DEBUG -Fo $@ $<
@echo
includes/nghttp2/nghttp2ver.h: includes/nghttp2/nghttp2ver.h.in $(THIS_MAKEFILE)
sed < includes/nghttp2/nghttp2ver.h.in \
-e 's/@PACKAGE_VERSION@/$(VERSION)/g' \
-e 's/@PACKAGE_VERSION_NUM@/($(VERSION_NUM))/g' > $@
-e 's/@PACKAGE_VERSION_NUM@/$(VERSION_NUM)/g' > $@
touch --reference=includes/nghttp2/nghttp2ver.h.in $@

View File

@@ -0,0 +1,4 @@
install(FILES
nghttp2/nghttp2.h
"${CMAKE_CURRENT_BINARY_DIR}/nghttp2/nghttp2ver.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nghttp2")

View File

@@ -20,4 +20,7 @@
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTRA_DIST = CMakeLists.txt
nobase_include_HEADERS = nghttp2/nghttp2.h nghttp2/nghttp2ver.h

View File

@@ -382,6 +382,10 @@ typedef enum {
* Unexpected internal error, but recovered.
*/
NGHTTP2_ERR_INTERNAL = -534,
/**
* Indicates that a processing was canceled.
*/
NGHTTP2_ERR_CANCEL = -535,
/**
* The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
* under unexpected condition and processing was terminated (e.g.,
@@ -415,6 +419,55 @@ typedef enum {
NGHTTP2_ERR_FLOODED = -904
} nghttp2_error;
/**
* @struct
*
* The object representing single contiguous buffer.
*/
typedef struct {
/**
* The pointer to the buffer.
*/
uint8_t *base;
/**
* The length of the buffer.
*/
size_t len;
} nghttp2_vec;
struct nghttp2_rcbuf;
/**
* @struct
*
* The object representing reference counted buffer. The details of
* this structure are intentionally hidden from the public API.
*/
typedef struct nghttp2_rcbuf nghttp2_rcbuf;
/**
* @function
*
* Increments the reference count of |rcbuf| by 1.
*/
NGHTTP2_EXTERN void nghttp2_rcbuf_incref(nghttp2_rcbuf *rcbuf);
/**
* @function
*
* Decrements the reference count of |rcbuf| by 1. If the reference
* count becomes zero, the object pointed by |rcbuf| will be freed.
* In this case, application must not use |rcbuf| again.
*/
NGHTTP2_EXTERN void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf);
/**
* @function
*
* Returns the underlying buffer managed by |rcbuf|.
*/
NGHTTP2_EXTERN nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf);
/**
* @enum
*
@@ -538,7 +591,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;
/**
@@ -1608,6 +1666,14 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session,
*
* To set this callback to :type:`nghttp2_session_callbacks`, use
* `nghttp2_session_callbacks_set_on_header_callback()`.
*
* .. warning::
*
* Application should properly limit the total buffer size to store
* incoming header fields. Without it, peer may send large number
* of header fields or large header fields to cause out of memory in
* local endpoint. Due to how HPACK works, peer can do this
* effectively without using much memory on their own.
*/
typedef int (*nghttp2_on_header_callback)(nghttp2_session *session,
const nghttp2_frame *frame,
@@ -1615,6 +1681,32 @@ typedef int (*nghttp2_on_header_callback)(nghttp2_session *session,
const uint8_t *value, size_t valuelen,
uint8_t flags, void *user_data);
/**
* @functypedef
*
* Callback function invoked when a header name/value pair is received
* for the |frame|. The |name| is header name. The |value| is header
* value. The |flags| is bitwise OR of one or more of
* :type:`nghttp2_nv_flag`.
*
* This callback behaves like :type:`nghttp2_on_header_callback`,
* except that |name| and |value| are stored in reference counted
* buffer. If application wishes to keep these references without
* copying them, use `nghttp2_rcbuf_incref()` to increment their
* reference count. It is the application's responsibility to call
* `nghttp2_rcbuf_decref()` if they called `nghttp2_rcbuf_incref()` so
* as not to leak memory. If the |session| is created by
* `nghttp2_session_server_new3()` or `nghttp2_session_client_new3()`,
* the function to free memory is the one belongs to the mem
* parameter. As long as this free function alives, |name| and
* |value| can live after |session| was destroyed.
*/
typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
const nghttp2_frame *frame,
nghttp2_rcbuf *name,
nghttp2_rcbuf *value, uint8_t flags,
void *user_data);
/**
* @functypedef
*
@@ -1692,6 +1784,124 @@ typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session,
const nghttp2_frame_hd *hd,
void *user_data);
/**
* @functypedef
*
* Callback function invoked when chunk of extension frame payload is
* received. The |hd| points to frame header. The received
* chunk is |data| of length |len|.
*
* The implementation of this function must return 0 if it succeeds.
*
* To abort processing this extension frame, return
* :enum:`NGHTTP2_ERR_CANCEL`.
*
* If fatal error occurred, application should return
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the
* other values are returned, currently they are treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_on_extension_chunk_recv_callback)(
nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data,
size_t len, void *user_data);
/**
* @functypedef
*
* Callback function invoked when library asks the application to
* unpack extension payload from its wire format. The extension
* payload has been passed to the application using
* :type:`nghttp2_on_extension_chunk_recv_callback`. The frame header
* is already unpacked by the library and provided as |hd|.
*
* To receive extension frames, the application must tell desired
* extension frame type to the library using
* `nghttp2_option_set_user_recv_extension_type()`.
*
* The implementation of this function may store the pointer to the
* created object as a result of unpacking in |*payload|, and returns
* 0. The pointer stored in |*payload| is opaque to the library, and
* the library does not own its pointer. |*payload| is initialized as
* ``NULL``. The |*payload| is available as ``frame->ext.payload`` in
* :type:`nghttp2_on_frame_recv_callback`. Therefore if application
* can free that memory inside :type:`nghttp2_on_frame_recv_callback`
* callback. Of course, application has a liberty not ot use
* |*payload|, and do its own mechanism to process extension frames.
*
* To abort processing this extension frame, return
* :enum:`NGHTTP2_ERR_CANCEL`.
*
* If fatal error occurred, application should return
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the
* other values are returned, currently they are treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*/
typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session,
void **payload,
const nghttp2_frame_hd *hd,
void *user_data);
/**
* @functypedef
*
* Callback function invoked when library asks the application to pack
* extension payload in its wire format. The frame header will be
* packed by library. Application must pack payload only.
* ``frame->ext.payload`` is the object passed to
* `nghttp2_submit_extension()` as payload parameter. Application
* must pack extension payload to the |buf| of its capacity |len|
* bytes. The |len| is at least 16KiB.
*
* The implementation of this function should return the number of
* bytes written into |buf| when it succeeds.
*
* To abort processing this extension frame, return
* :enum:`NGHTTP2_ERR_CANCEL`, and
* :type:`nghttp2_on_frame_not_send_callback` will be invoked.
*
* If fatal error occurred, application should return
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
* immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the
* other values are returned, currently they are treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the return value is
* strictly larger than |len|, it is treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`.
*/
typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session,
uint8_t *buf, size_t len,
const nghttp2_frame *frame,
void *user_data);
/**
* @functypedef
*
* Callback function invoked when library provides the error message
* intended for human consumption. This callback is solely for
* debugging purpose. The |msg| is typically NULL-terminated string
* of length |len|. |len| does not include the sentinel NULL
* character.
*
* The format of error message may change between nghttp2 library
* versions. The application should not depend on the particular
* format.
*
* Normally, application should return 0 from this callback. If fatal
* error occurred while doing something in this callback, application
* should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case,
* library will return immediately with return value
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value
* is returned from this callback, they are treated as
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not
* rely on this details.
*/
typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg,
size_t len, void *user_data);
struct nghttp2_session_callbacks;
/**
@@ -1836,12 +2046,25 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_headers_callback(
* @function
*
* Sets callback function invoked when a header name/value pair is
* received.
* received. If both
* `nghttp2_session_callbacks_set_on_header_callback()` and
* `nghttp2_session_callbacks_set_on_header_callback2()` are used to
* set callbacks, the latter has the precedence.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback on_header_callback);
/**
* @function
*
* Sets callback function invoked when a header name/value pair is
* received.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback2 on_header_callback2);
/**
* @function
*
@@ -1884,6 +2107,46 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback(
nghttp2_session_callbacks *cbs,
nghttp2_send_data_callback send_data_callback);
/**
* @function
*
* Sets callback function invoked when the library asks the
* application to pack extension frame payload in wire format.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_pack_extension_callback pack_extension_callback);
/**
* @function
*
* Sets callback function invoked when the library asks the
* application to unpack extension frame payload from wire format.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_unpack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_unpack_extension_callback unpack_extension_callback);
/**
* @function
*
* Sets callback function invoked when chunk of extension frame
* payload is received.
*/
NGHTTP2_EXTERN void
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback);
/**
* @function
*
* Sets callback function invoked when library tells error message to
* the application.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback);
/**
* @functypedef
*
@@ -2098,6 +2361,57 @@ NGHTTP2_EXTERN void
nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option,
uint32_t val);
/**
* @function
*
* Sets extension frame type the application is willing to handle with
* user defined callbacks (see
* :type:`nghttp2_on_extension_chunk_recv_callback` and
* :type:`nghttp2_unpack_extension_callback`). The |type| is
* extension frame type, 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.
*/
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
*
* This option prevents the library from sending PING frame with ACK
* flag set automatically when PING frame without ACK flag set is
* received. If this option is set to nonzero, the library won't send
* PING frame with ACK flag set in the response for incoming PING
* frame. The application can send PING frame with ACK flag set using
* `nghttp2_submit_ping()` with :enum:`NGHTTP2_FLAG_ACK` as flags
* parameter.
*/
NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option,
int val);
/**
* @function
*
@@ -3071,6 +3385,16 @@ nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
*/
NGHTTP2_EXTERN const char *nghttp2_strerror(int lib_error_code);
/**
* @function
*
* Returns string representation of HTTP/2 error code |error_code|
* (e.g., ``PROTOCOL_ERROR`` is returned if ``error_code ==
* NGHTTP2_PROTOCOL_ERROR``). If string representation is unknown for
* given |error_code|, this function returns string ``unknown``.
*/
NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code);
/**
* @function
*
@@ -3620,8 +3944,12 @@ nghttp2_submit_push_promise(nghttp2_session *session, uint8_t flags,
* received PING frame. The library automatically submits PING frame
* in this case.
*
* The |flags| is currently ignored and should be
* :enum:`NGHTTP2_FLAG_NONE`.
* The |flags| is bitwise OR of 0 or more of the following value.
*
* * :enum:`NGHTTP2_FLAG_ACK`
*
* Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags|
* should be :enum:`NGHTTP2_FLAG_NONE`.
*
* If the |opaque_data| is non ``NULL``, then it should point to the 8
* bytes array of memory to specify opaque data to send with PING
@@ -3768,6 +4096,122 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session,
int32_t stream_id,
int32_t window_size_increment);
/**
* @function
*
* Submits extension frame.
*
* Application can pass arbitrary frame flags and stream ID in |flags|
* and |stream_id| respectively. The |payload| is opaque pointer, and
* it can be accessible though ``frame->ext.payload`` in
* :type:`nghttp2_pack_extension_callback`. The library will not own
* passed |payload| pointer.
*
* The application must set :type:`nghttp2_pack_extension_callback`
* using `nghttp2_session_callbacks_set_pack_extension_callback()`.
*
* The application should retain the memory pointed by |payload| until
* the transmission of extension frame is done (which is indicated by
* :type:`nghttp2_on_frame_send_callback`), or transmission fails
* (which is indicated by :type:`nghttp2_on_frame_not_send_callback`).
* If application does not touch this memory region after packing it
* into a wire format, application can free it inside
* :type:`nghttp2_pack_extension_callback`.
*
* The standard HTTP/2 frame cannot be sent with this function, so
* |type| must be strictly grater than 0x9. Otherwise, this function
* will fail with error code :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :enum:`NGHTTP2_ERR_INVALID_STATE`
* If :type:`nghttp2_pack_extension_callback` is not set.
* :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`
* If |type| specifies standard HTTP/2 frame type. The frame
* types in the rage [0x0, 0x9], both inclusive, are standard
* HTTP/2 frame type, and cannot be sent using this function.
* :enum:`NGHTTP2_ERR_NOMEM`
* Out of memory
*/
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
*
@@ -4109,7 +4553,7 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater);
* 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.
*
@@ -4150,6 +4594,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
@@ -4229,6 +4677,88 @@ 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. This means the all input values are
* processed successfully. Then the application must call
* `nghttp2_hd_inflate_end_headers()` to prepare for the next header
* block input.
*
* 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
*

View File

@@ -73,7 +73,7 @@ typedef struct {
/*
* Initializes the |buf|. No memory is allocated in this function. Use
* nghttp2_buf_reserve() or nghttp2_buf_reserve2() to allocate memory.
* nghttp2_buf_reserve() to allocate memory.
*/
void nghttp2_buf_init(nghttp2_buf *buf);
@@ -312,8 +312,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.

View File

@@ -104,6 +104,12 @@ void nghttp2_session_callbacks_set_on_header_callback(
cbs->on_header_callback = on_header_callback;
}
void nghttp2_session_callbacks_set_on_header_callback2(
nghttp2_session_callbacks *cbs,
nghttp2_on_header_callback2 on_header_callback2) {
cbs->on_header_callback2 = on_header_callback2;
}
void nghttp2_session_callbacks_set_select_padding_callback(
nghttp2_session_callbacks *cbs,
nghttp2_select_padding_callback select_padding_callback) {
@@ -127,3 +133,26 @@ void nghttp2_session_callbacks_set_send_data_callback(
nghttp2_send_data_callback send_data_callback) {
cbs->send_data_callback = send_data_callback;
}
void nghttp2_session_callbacks_set_pack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_pack_extension_callback pack_extension_callback) {
cbs->pack_extension_callback = pack_extension_callback;
}
void nghttp2_session_callbacks_set_unpack_extension_callback(
nghttp2_session_callbacks *cbs,
nghttp2_unpack_extension_callback unpack_extension_callback) {
cbs->unpack_extension_callback = unpack_extension_callback;
}
void nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(
nghttp2_session_callbacks *cbs,
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback) {
cbs->on_extension_chunk_recv_callback = on_extension_chunk_recv_callback;
}
void nghttp2_session_callbacks_set_error_callback(
nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback) {
cbs->error_callback = error_callback;
}

View File

@@ -91,6 +91,7 @@ struct nghttp2_session_callbacks {
* received.
*/
nghttp2_on_header_callback on_header_callback;
nghttp2_on_header_callback2 on_header_callback2;
/**
* Callback function invoked when the library asks application how
* many padding bytes are required for the transmission of the given
@@ -107,6 +108,10 @@ struct nghttp2_session_callbacks {
*/
nghttp2_on_begin_frame_callback on_begin_frame_callback;
nghttp2_send_data_callback send_data_callback;
nghttp2_pack_extension_callback pack_extension_callback;
nghttp2_unpack_extension_callback unpack_extension_callback;
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback;
};
#endif /* NGHTTP2_CALLBACKS_H */

View File

@@ -184,6 +184,39 @@ void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
void nghttp2_frame_data_free(nghttp2_data *frame _U_) {}
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
uint8_t flags, int32_t stream_id,
void *payload) {
nghttp2_frame_hd_init(&frame->hd, 0, type, flags, stream_id);
frame->payload = payload;
}
void nghttp2_frame_extension_free(nghttp2_extension *frame _U_) {}
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
uint8_t *origin, size_t origin_len,
uint8_t *field_value, size_t field_value_len) {
nghttp2_ext_altsvc *altsvc;
nghttp2_frame_hd_init(&frame->hd, 2 + origin_len + field_value_len,
NGHTTP2_ALTSVC, NGHTTP2_FLAG_NONE, stream_id);
altsvc = frame->payload;
altsvc->origin = origin;
altsvc->origin_len = origin_len;
altsvc->field_value = field_value;
altsvc->field_value_len = field_value_len;
}
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem) {
nghttp2_ext_altsvc *altsvc;
altsvc = frame->payload;
/* We use the same buffer for altsvc->origin and
altsvc->field_value. */
nghttp2_mem_free(mem, altsvc->origin);
}
size_t nghttp2_frame_priority_len(uint8_t flags) {
if (flags & NGHTTP2_FLAG_PRIORITY) {
return NGHTTP2_PRIORITY_SPECLEN;
@@ -430,25 +463,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,
@@ -659,6 +678,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;

View File

@@ -72,7 +72,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 +215,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 +361,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
@@ -439,6 +472,31 @@ void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
uint8_t flags, int32_t stream_id,
void *payload);
void nghttp2_frame_extension_free(nghttp2_extension *frame);
/*
* Initializes ALTSVC frame |frame| with given values. This function
* assumes that frame->payload points to nghttp2_ext_altsvc object.
* Also |origin| and |field_value| are allocated in single buffer,
* starting |origin|. On success, this function takes ownership of
* |origin|, so caller must not free it.
*/
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
uint8_t *origin, size_t origin_len,
uint8_t *field_value, size_t field_value_len);
/*
* Frees up resources under |frame|. This function does not free
* nghttp2_ext_altsvc object pointed by frame->payload. This function
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
* other fields must be allocated in the same buffer with origin.
*/
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
/*
* Returns the number of padding bytes after payload. The total
* padding length is given in the |padlen|. The returned value does

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,7 @@
#include "nghttp2_hd_huffman.h"
#include "nghttp2_buf.h"
#include "nghttp2_mem.h"
#include "nghttp2_rcbuf.h"
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
@@ -109,28 +110,32 @@ typedef enum {
NGHTTP2_TOKEN_CONNECTION,
NGHTTP2_TOKEN_KEEP_ALIVE,
NGHTTP2_TOKEN_PROXY_CONNECTION,
NGHTTP2_TOKEN_UPGRADE
NGHTTP2_TOKEN_UPGRADE,
} nghttp2_token;
typedef enum {
NGHTTP2_HD_FLAG_NONE = 0,
/* Indicates name was dynamically allocated and must be freed */
NGHTTP2_HD_FLAG_NAME_ALLOC = 1,
/* Indicates value was dynamically allocated and must be freed */
NGHTTP2_HD_FLAG_VALUE_ALLOC = 1 << 1,
/* Indicates that the name was gifted to the entry and no copying
necessary. */
NGHTTP2_HD_FLAG_NAME_GIFT = 1 << 2,
/* Indicates that the value was gifted to the entry and no copying
necessary. */
NGHTTP2_HD_FLAG_VALUE_GIFT = 1 << 3
} nghttp2_hd_flags;
struct nghttp2_hd_entry;
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
typedef struct {
/* The buffer containing header field name. NULL-termination is
guaranteed. */
nghttp2_rcbuf *name;
/* The buffer containing header field value. NULL-termination is
guaranteed. */
nghttp2_rcbuf *value;
/* nghttp2_token value for name. It could be -1 if we have no token
for that header field name. */
int32_t token;
/* Bitwise OR of one or more of nghttp2_nv_flag. */
uint8_t flags;
} nghttp2_hd_nv;
struct nghttp2_hd_entry {
nghttp2_nv nv;
/* The header field name/value pair */
nghttp2_hd_nv nv;
/* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
APIs to keep backward compatibility. */
nghttp2_nv cnv;
/* The next entry which shares same bucket in hash table. */
nghttp2_hd_entry *next;
/* The sequence number. We will increment it by one whenever we
@@ -138,14 +143,17 @@ struct nghttp2_hd_entry {
uint32_t seq;
/* The hash value for header name (nv.name). */
uint32_t hash;
/* nghttp2_token value for nv.name. It could be -1 if we have no
token for that header field name. */
int token;
/* Reference count */
uint8_t ref;
uint8_t flags;
};
/* The entry used for static header table. */
typedef struct {
nghttp2_rcbuf name;
nghttp2_rcbuf value;
nghttp2_nv cnv;
int32_t token;
uint32_t hash;
} nghttp2_hd_static_entry;
typedef struct {
nghttp2_hd_entry **buffer;
size_t mask;
@@ -219,24 +227,18 @@ struct nghttp2_hd_deflater {
struct nghttp2_hd_inflater {
nghttp2_hd_context ctx;
/* header buffer */
nghttp2_bufs nvbufs;
/* Stores current state of huffman decoding */
nghttp2_hd_huff_decode_context huff_decode_ctx;
/* Pointer to the nghttp2_hd_entry which is used current header
emission. This is required because in some cases the
ent_keep->ref == 0 and we have to keep track of it. */
nghttp2_hd_entry *ent_keep;
/* Pointer to the name/value pair buffer which is used in the
current header emission. */
uint8_t *nv_keep;
/* header buffer */
nghttp2_buf namebuf, valuebuf;
nghttp2_rcbuf *namercbuf, *valuercbuf;
/* Pointer to the name/value pair which are used in the current
header emission. */
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
/* The number of bytes to read */
size_t left;
/* The index in indexed repr or indexed name */
size_t index;
/* The length of new name encoded in literal. For huffman encoded
string, this is the length after it is decoded. */
size_t newnamelen;
/* The maximum header table size the inflater supports. This is the
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
size_t settings_hd_table_bufsize_max;
@@ -256,24 +258,16 @@ struct nghttp2_hd_inflater {
};
/*
* Initializes the |ent| members. If NGHTTP2_HD_FLAG_NAME_ALLOC bit
* set in the |flags|, the content pointed by the |name| with length
* |namelen| is copied. Likewise, if NGHTTP2_HD_FLAG_VALUE_ALLOC bit
* set in the |flags|, the content pointed by the |value| with length
* |valuelen| is copied. The |token| is enum number looked up by
* |name|. It could be -1 if we don't have that enum value.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* Initializes the |ent| members. The reference counts of nv->name
* and nv->value are increased by one for each.
*/
int nghttp2_hd_entry_init(nghttp2_hd_entry *ent, uint8_t flags, uint8_t *name,
size_t namelen, uint8_t *value, size_t valuelen,
int token, nghttp2_mem *mem);
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent, nghttp2_mem *mem);
/*
* This function decreases the reference counts of nv->name and
* nv->value.
*/
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
/*
* Initializes |deflater| for deflating name/values pairs.
@@ -354,16 +348,14 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
/*
* Similar to nghttp2_hd_inflate_hd(), but this takes additional
* output parameter |token|. On successful header emission, it
* contains nghttp2_token value for nv_out->name. It could be -1 if
* we don't have enum value for the name. Other than that return
* values and semantics are the same as nghttp2_hd_inflate_hd().
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
* instead of nghttp2_nv as output parameter |nv_out|. Other than
* that return values and semantics are the same as
* nghttp2_hd_inflate_hd().
*/
ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_nv *nv_out, int *inflate_flags,
int *token, uint8_t *in, size_t inlen,
int in_final);
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
nghttp2_hd_nv *nv_out, int *inflate_flags,
const uint8_t *in, size_t inlen, int in_final);
/* For unittesting purpose */
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
@@ -377,8 +369,7 @@ int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
/* For unittesting purpose */
nghttp2_hd_entry *nghttp2_hd_table_get(nghttp2_hd_context *context,
size_t index);
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
/* For unittesting purpose */
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
@@ -414,11 +405,10 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
/*
* Decodes the given data |src| with length |srclen|. The |ctx| must
* Decodes the given data |src| with length |srclen|. The |ctx| must
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
* will be added to |dest|. This function may expand |dest| as
* needed. The caller is responsible to release the memory of |dest|
* by calling nghttp2_bufs_free().
* will be written to |buf|. This function assumes that |buf| has the
* enough room to store the decoded byte string.
*
* The caller must set the |final| to nonzero if the given input is
* the final block.
@@ -430,13 +420,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_BUFFER_ERROR
* Maximum buffer capacity size exceeded.
* NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed.
*/
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_bufs *bufs, const uint8_t *src,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final);
#endif /* NGHTTP2_HD_H */

View File

@@ -166,31 +166,10 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->accept = 1;
}
/* Use macro to make the code simpler..., but error case is tricky.
We spent most of the CPU in decoding, so we are doing this
thing. */
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
do { \
if ((avail)) { \
nghttp2_bufs_fast_addb((bufs), (sym)); \
--(avail); \
} else { \
rv = nghttp2_bufs_addb((bufs), (sym)); \
if (rv != 0) { \
return rv; \
} \
(avail) = nghttp2_bufs_cur_avail((bufs)); \
} \
} while (0)
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_bufs *bufs, const uint8_t *src,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final) {
size_t i;
int rv;
size_t avail;
avail = nghttp2_bufs_cur_avail(bufs);
/* We use the decoding algorithm described in
http://graphics.ics.uci.edu/pub/Prefix.pdf */
@@ -202,8 +181,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return NGHTTP2_ERR_HEADER_COMP;
}
if (t->flags & NGHTTP2_HUFF_SYM) {
/* this is macro, and may return from this function on error */
hd_huff_decode_sym_emit(bufs, t->sym, avail);
*buf->last++ = t->sym;
}
t = &huff_decode_table[t->state][src[i] & 0xf];
@@ -211,8 +189,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return NGHTTP2_ERR_HEADER_COMP;
}
if (t->flags & NGHTTP2_HUFF_SYM) {
/* this is macro, and may return from this function on error */
hd_huff_decode_sym_emit(bufs, t->sym, avail);
*buf->last++ = t->sym;
}
ctx->state = t->state;

View File

@@ -288,6 +288,8 @@ const char *nghttp2_strerror(int error_code) {
return "Stream was refused";
case NGHTTP2_ERR_INTERNAL:
return "Internal error";
case NGHTTP2_ERR_CANCEL:
return "Cancel";
case NGHTTP2_ERR_NOMEM:
return "Out of memory";
case NGHTTP2_ERR_CALLBACK_FAILURE:
@@ -449,3 +451,38 @@ uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len) {
return dest + len;
}
const char *nghttp2_http2_strerror(uint32_t error_code) {
switch (error_code) {
case NGHTTP2_NO_ERROR:
return "NO_ERROR";
case NGHTTP2_PROTOCOL_ERROR:
return "PROTOCOL_ERROR";
case NGHTTP2_INTERNAL_ERROR:
return "INTERNAL_ERROR";
case NGHTTP2_FLOW_CONTROL_ERROR:
return "FLOW_CONTROL_ERROR";
case NGHTTP2_SETTINGS_TIMEOUT:
return "SETTINGS_TIMEOUT";
case NGHTTP2_STREAM_CLOSED:
return "STREAM_CLOSED";
case NGHTTP2_FRAME_SIZE_ERROR:
return "FRAME_SIZE_ERROR";
case NGHTTP2_REFUSED_STREAM:
return "REFUSED_STREAM";
case NGHTTP2_CANCEL:
return "CANCEL";
case NGHTTP2_COMPRESSION_ERROR:
return "COMPRESSION_ERROR";
case NGHTTP2_CONNECT_ERROR:
return "CONNECT_ERROR";
case NGHTTP2_ENHANCE_YOUR_CALM:
return "ENHANCE_YOUR_CALM";
case NGHTTP2_INADEQUATE_SECURITY:
return "INADEQUATE_SECURITY";
case NGHTTP2_HTTP_1_1_REQUIRED:
return "HTTP_1_1_REQUIRED";
default:
return "unknown";
}
}

View File

@@ -82,12 +82,12 @@ static int lws(const uint8_t *s, size_t n) {
return 1;
}
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_nv *nv,
static int check_pseudo_header(nghttp2_stream *stream, const nghttp2_hd_nv *nv,
int flag) {
if (stream->http_flags & flag) {
return 0;
}
if (lws(nv->value, nv->valuelen)) {
if (lws(nv->value->base, nv->value->len)) {
return 0;
}
stream->http_flags = (uint16_t)(stream->http_flags | flag);
@@ -112,16 +112,16 @@ static int check_path(nghttp2_stream *stream) {
(stream->http_flags & NGHTTP2_HTTP_FLAG_PATH_ASTERISK)));
}
static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
int token, int trailer) {
if (nv->name[0] == ':') {
static int http_request_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
int trailer) {
if (nv->name->base[0] == ':') {
if (trailer ||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
switch (token) {
switch (nv->token) {
case NGHTTP2_TOKEN__AUTHORITY:
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__AUTHORITY)) {
return NGHTTP2_ERR_HTTP_HEADER;
@@ -131,16 +131,16 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__METHOD)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
switch (nv->valuelen) {
switch (nv->value->len) {
case 4:
if (lstreq("HEAD", nv->value, nv->valuelen)) {
if (lstreq("HEAD", nv->value->base, nv->value->len)) {
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_HEAD;
}
break;
case 7:
switch (nv->value[6]) {
switch (nv->value->base[6]) {
case 'T':
if (lstreq("CONNECT", nv->value, nv->valuelen)) {
if (lstreq("CONNECT", nv->value->base, nv->value->len)) {
if (stream->stream_id % 2 == 0) {
/* we won't allow CONNECT for push */
return NGHTTP2_ERR_HTTP_HEADER;
@@ -153,7 +153,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
}
break;
case 'S':
if (lstreq("OPTIONS", nv->value, nv->valuelen)) {
if (lstreq("OPTIONS", nv->value->base, nv->value->len)) {
stream->http_flags |= NGHTTP2_HTTP_FLAG_METH_OPTIONS;
}
break;
@@ -168,9 +168,9 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__PATH)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (nv->value[0] == '/') {
if (nv->value->base[0] == '/') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_REGULAR;
} else if (nv->valuelen == 1 && nv->value[0] == '*') {
} else if (nv->value->len == 1 && nv->value->base[0] == '*') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PATH_ASTERISK;
}
break;
@@ -181,8 +181,8 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__SCHEME)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if ((nv->valuelen == 4 && memieq("http", nv->value, 4)) ||
(nv->valuelen == 5 && memieq("https", nv->value, 5))) {
if ((nv->value->len == 4 && memieq("http", nv->value->base, 4)) ||
(nv->value->len == 5 && memieq("https", nv->value->base, 5))) {
stream->http_flags |= NGHTTP2_HTTP_FLAG_SCHEME_HTTP;
}
break;
@@ -195,7 +195,7 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
if (stream->content_length != -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->content_length = parse_uint(nv->value, nv->valuelen);
stream->content_length = parse_uint(nv->value->base, nv->value->len);
if (stream->content_length == -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -209,41 +209,41 @@ static int http_request_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
case NGHTTP2_TOKEN_UPGRADE:
return NGHTTP2_ERR_HTTP_HEADER;
case NGHTTP2_TOKEN_TE:
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
default:
if (nv->name[0] == ':') {
if (nv->name->base[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
if (nv->name[0] != ':') {
if (nv->name->base[0] != ':') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
}
return 0;
}
static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
int token, int trailer) {
if (nv->name[0] == ':') {
static int http_response_on_header(nghttp2_stream *stream, nghttp2_hd_nv *nv,
int trailer) {
if (nv->name->base[0] == ':') {
if (trailer ||
(stream->http_flags & NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
switch (token) {
switch (nv->token) {
case NGHTTP2_TOKEN__STATUS: {
if (!check_pseudo_header(stream, nv, NGHTTP2_HTTP_FLAG__STATUS)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
if (nv->valuelen != 3) {
if (nv->value->len != 3) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->status_code = (int16_t)parse_uint(nv->value, nv->valuelen);
stream->status_code = (int16_t)parse_uint(nv->value->base, nv->value->len);
if (stream->status_code == -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -253,7 +253,7 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
if (stream->content_length != -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
stream->content_length = parse_uint(nv->value, nv->valuelen);
stream->content_length = parse_uint(nv->value->base, nv->value->len);
if (stream->content_length == -1) {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -267,17 +267,17 @@ static int http_response_on_header(nghttp2_stream *stream, nghttp2_nv *nv,
case NGHTTP2_TOKEN_UPGRADE:
return NGHTTP2_ERR_HTTP_HEADER;
case NGHTTP2_TOKEN_TE:
if (!lstrieq("trailers", nv->value, nv->valuelen)) {
if (!lstrieq("trailers", nv->value->base, nv->value->len)) {
return NGHTTP2_ERR_HTTP_HEADER;
}
break;
default:
if (nv->name[0] == ':') {
if (nv->name->base[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
}
if (nv->name[0] != ':') {
if (nv->name->base[0] != ':') {
stream->http_flags |= NGHTTP2_HTTP_FLAG_PSEUDO_HEADER_DISALLOWED;
}
@@ -375,7 +375,7 @@ static int check_scheme(const uint8_t *value, size_t len) {
}
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
nghttp2_frame *frame, nghttp2_nv *nv, int token,
nghttp2_frame *frame, nghttp2_hd_nv *nv,
int trailer) {
int rv;
@@ -386,14 +386,14 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
this, we may disrupt many web sites and/or libraries. So we
become conservative here, and just ignore those illegal regular
headers. */
if (!nghttp2_check_header_name(nv->name, nv->namelen)) {
if (!nghttp2_check_header_name(nv->name->base, nv->name->len)) {
size_t i;
if (nv->namelen > 0 && nv->name[0] == ':') {
if (nv->name->len > 0 && nv->name->base[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
/* header field name must be lower-cased without exception */
for (i = 0; i < nv->namelen; ++i) {
uint8_t c = nv->name[i];
for (i = 0; i < nv->name->len; ++i) {
uint8_t c = nv->name->base[i];
if ('A' <= c && c <= 'Z') {
return NGHTTP2_ERR_HTTP_HEADER;
}
@@ -405,17 +405,18 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
return NGHTTP2_ERR_IGN_HTTP_HEADER;
}
if (token == NGHTTP2_TOKEN__AUTHORITY || token == NGHTTP2_TOKEN_HOST) {
rv = check_authority(nv->value, nv->valuelen);
} else if (token == NGHTTP2_TOKEN__SCHEME) {
rv = check_scheme(nv->value, nv->valuelen);
if (nv->token == NGHTTP2_TOKEN__AUTHORITY ||
nv->token == NGHTTP2_TOKEN_HOST) {
rv = check_authority(nv->value->base, nv->value->len);
} else if (nv->token == NGHTTP2_TOKEN__SCHEME) {
rv = check_scheme(nv->value->base, nv->value->len);
} else {
rv = nghttp2_check_header_value(nv->value, nv->valuelen);
rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
}
if (rv == 0) {
assert(nv->namelen > 0);
if (nv->name[0] == ':') {
assert(nv->name->len > 0);
if (nv->name->base[0] == ':') {
return NGHTTP2_ERR_HTTP_HEADER;
}
/* When ignoring regular headers, we set this flag so that we
@@ -426,10 +427,10 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
}
if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
return http_request_on_header(stream, nv, token, trailer);
return http_request_on_header(stream, nv, trailer);
}
return http_response_on_header(stream, nv, token, trailer);
return http_response_on_header(stream, nv, trailer);
}
int nghttp2_http_on_request_headers(nghttp2_stream *stream,

View File

@@ -36,8 +36,7 @@
/*
* This function is called when HTTP header field |nv| in |frame| is
* received for |stream|. This function will validate |nv| against
* the current state of stream. The |token| is nghttp2_token value
* for nv->name, or -1 if we don't have enum value for the name.
* the current state of stream.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -49,7 +48,7 @@
* if it was not received because of compatibility reasons.
*/
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
nghttp2_frame *frame, nghttp2_nv *nv, int token,
nghttp2_frame *frame, nghttp2_hd_nv *nv,
int trailer);
/*

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,6 +52,10 @@ void nghttp2_mem_free(nghttp2_mem *mem, void *ptr) {
mem->free(ptr, mem->mem_user_data);
}
void nghttp2_mem_free2(nghttp2_free free, void *ptr, void *mem_user_data) {
free(ptr, mem_user_data);
}
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size) {
return mem->calloc(nmemb, size, mem->mem_user_data);
}

View File

@@ -38,6 +38,7 @@ nghttp2_mem *nghttp2_mem_default(void);
|mem|. */
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
void nghttp2_mem_free2(nghttp2_free free, 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

@@ -25,9 +25,9 @@
#ifndef NGHTTP2_NPN_H
#define NGHTTP2_NPN_H
#ifdef HAVE_CONFIG
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG */
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>

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));
@@ -62,3 +64,34 @@ void nghttp2_option_set_max_reserved_remote_streams(nghttp2_option *option,
option->opt_set_mask |= NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS;
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) {
return;
}
option->opt_set_mask |= NGHTTP2_OPT_USER_RECV_EXT_TYPES;
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;
}

View File

@@ -59,7 +59,10 @@ typedef enum {
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7
} nghttp2_option_flag;
/**
@@ -79,6 +82,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
*/
@@ -91,6 +98,14 @@ struct nghttp2_option {
* NGHTTP2_OPT_NO_HTTP_MESSAGING
*/
int no_http_messaging;
/**
* NGHTTP2_OPT_NO_AUTO_PING_ACK
*/
int no_auto_ping_ack;
/**
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
*/
uint8_t user_recv_ext_types[32];
};
#endif /* NGHTTP2_OPTION_H */

View File

@@ -72,6 +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_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

99
lib/nghttp2_rcbuf.c Normal file
View File

@@ -0,0 +1,99 @@
/*
* 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_rcbuf.h"
#include <string.h>
#include <assert.h>
#include "nghttp2_mem.h"
int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size,
nghttp2_mem *mem) {
uint8_t *p;
p = nghttp2_mem_malloc(mem, sizeof(nghttp2_rcbuf) + size);
if (p == NULL) {
return NGHTTP2_ERR_NOMEM;
}
*rcbuf_ptr = (void *)p;
(*rcbuf_ptr)->mem_user_data = mem->mem_user_data;
(*rcbuf_ptr)->free = mem->free;
(*rcbuf_ptr)->base = p + sizeof(nghttp2_rcbuf);
(*rcbuf_ptr)->len = size;
(*rcbuf_ptr)->ref = 1;
return 0;
}
int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
size_t srclen, nghttp2_mem *mem) {
int rv;
rv = nghttp2_rcbuf_new(rcbuf_ptr, srclen + 1, mem);
if (rv != 0) {
return rv;
}
memcpy((*rcbuf_ptr)->base, src, srclen);
(*rcbuf_ptr)->len = srclen;
(*rcbuf_ptr)->base[srclen] = '\0';
return 0;
}
/*
* Frees |rcbuf| itself, regardless of its reference cout.
*/
void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf) {
nghttp2_mem_free2(rcbuf->free, rcbuf, rcbuf->mem_user_data);
}
void nghttp2_rcbuf_incref(nghttp2_rcbuf *rcbuf) {
if (rcbuf->ref == -1) {
return;
}
++rcbuf->ref;
}
void nghttp2_rcbuf_decref(nghttp2_rcbuf *rcbuf) {
if (rcbuf == NULL || rcbuf->ref == -1) {
return;
}
assert(rcbuf->ref > 0);
if (--rcbuf->ref == 0) {
nghttp2_rcbuf_del(rcbuf);
}
}
nghttp2_vec nghttp2_rcbuf_get_buf(nghttp2_rcbuf *rcbuf) {
nghttp2_vec res = {rcbuf->base, rcbuf->len};
return res;
}

80
lib/nghttp2_rcbuf.h Normal file
View File

@@ -0,0 +1,80 @@
/*
* 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_RCBUF_H
#define NGHTTP2_RCBUF_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <nghttp2/nghttp2.h>
struct nghttp2_rcbuf {
/* custom memory allocator belongs to the mem parameter when
creating this object. */
void *mem_user_data;
nghttp2_free free;
/* The pointer to the underlying buffer */
uint8_t *base;
/* Size of buffer pointed by |base|. */
size_t len;
/* Reference count */
int32_t ref;
};
/*
* Allocates nghttp2_rcbuf object with |size| as initial buffer size.
* When the function succeeds, the reference count becomes 1.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM:
* Out of memory.
*/
int nghttp2_rcbuf_new(nghttp2_rcbuf **rcbuf_ptr, size_t size, nghttp2_mem *mem);
/*
* Like nghttp2_rcbuf_new(), but initializes the buffer with |src| of
* length |srclen|. This function allocates additional byte at the
* end and puts '\0' into it, so that the resulting buffer could be
* used as NULL-terminated string. Still (*rcbuf_ptr)->len equals to
* |srclen|.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* NGHTTP2_ERR_NOMEM:
* Out of memory.
*/
int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
size_t srclen, nghttp2_mem *mem);
/*
* Frees |rcbuf| itself, regardless of its reference cout.
*/
void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
#endif /* NGHTTP2_RCBUF_H */

View File

@@ -28,6 +28,7 @@
#include <stddef.h>
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include "nghttp2_helper.h"
#include "nghttp2_net.h"
@@ -141,6 +142,66 @@ static int session_detect_idle_stream(nghttp2_session *session,
return 0;
}
static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) {
return (ext_types[type / 8] & (1 << (type & 0x7))) > 0;
}
static int session_call_error_callback(nghttp2_session *session,
const char *fmt, ...) {
size_t bufsize;
va_list ap;
char *buf;
int rv;
nghttp2_mem *mem;
if (!session->callbacks.error_callback) {
return 0;
}
mem = &session->mem;
va_start(ap, fmt);
rv = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
if (rv < 0) {
return NGHTTP2_ERR_NOMEM;
}
bufsize = (size_t)(rv + 1);
buf = nghttp2_mem_malloc(mem, bufsize);
if (buf == NULL) {
return NGHTTP2_ERR_NOMEM;
}
va_start(ap, fmt);
rv = vsnprintf(buf, bufsize, fmt, ap);
va_end(ap);
if (rv < 0) {
nghttp2_mem_free(mem, buf);
/* vsnprintf may return error because of various things we can
imagine, but typically we don't want to drop session just for
debug callback. */
DEBUGF(fprintf(stderr,
"error_callback: vsnprintf failed. The template was %s\n",
fmt));
return 0;
}
rv = session->callbacks.error_callback(session, buf, (size_t)rv,
session->user_data);
nghttp2_mem_free(mem, buf);
if (rv != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return 0;
}
static int session_terminate_session(nghttp2_session *session,
int32_t last_stream_id,
uint32_t error_code, const char *reason) {
@@ -231,6 +292,8 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
nghttp2_session_new(), we rely on the fact that
iframe->frame.hd.type is 0, so that no free is performed. */
switch (iframe->frame.hd.type) {
case NGHTTP2_DATA:
break;
case NGHTTP2_HEADERS:
nghttp2_frame_headers_free(&iframe->frame.headers, mem);
break;
@@ -242,6 +305,13 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
break;
case NGHTTP2_SETTINGS:
nghttp2_frame_settings_free(&iframe->frame.settings, mem);
nghttp2_mem_free(mem, iframe->iv);
iframe->iv = NULL;
iframe->niv = 0;
iframe->max_niv = 0;
break;
case NGHTTP2_PUSH_PROMISE:
nghttp2_frame_push_promise_free(&iframe->frame.push_promise, mem);
@@ -254,6 +324,23 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
break;
case NGHTTP2_WINDOW_UPDATE:
nghttp2_frame_window_update_free(&iframe->frame.window_update);
break;
default:
/* extension frame */
if (check_ext_type_set(session->user_recv_ext_types,
iframe->frame.hd.type)) {
nghttp2_frame_extension_free(&iframe->frame.ext);
} else {
switch (iframe->frame.hd.type) {
case NGHTTP2_ALTSVC:
if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) == 0) {
break;
}
nghttp2_frame_altsvc_free(&iframe->frame.ext, mem);
break;
}
}
break;
}
@@ -269,12 +356,10 @@ static void session_inbound_frame_reset(nghttp2_session *session) {
nghttp2_buf_free(&iframe->lbuf, mem);
nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
iframe->niv = 0;
iframe->raw_lbuf = NULL;
iframe->payloadleft = 0;
iframe->padlen = 0;
iframe->iv[NGHTTP2_INBOUND_NUM_IV - 1].settings_id =
NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
iframe->iv[NGHTTP2_INBOUND_NUM_IV - 1].value = UINT32_MAX;
}
static void init_settings(nghttp2_settings_storage *settings) {
@@ -405,6 +490,20 @@ static int session_new(nghttp2_session **session_ptr,
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_HTTP_MESSAGING;
}
if (option->opt_set_mask & NGHTTP2_OPT_USER_RECV_EXT_TYPES) {
memcpy((*session_ptr)->user_recv_ext_types, option->user_recv_ext_types,
sizeof((*session_ptr)->user_recv_ext_types));
}
if (option->opt_set_mask & NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES) {
(*session_ptr)->builtin_recv_ext_types = option->builtin_recv_ext_types;
}
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_PING_ACK) &&
option->no_auto_ping_ack) {
(*session_ptr)->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_PING_ACK;
}
}
(*session_ptr)->callbacks = *callbacks;
@@ -1216,11 +1315,12 @@ int nghttp2_session_adjust_idle_stream(nghttp2_session *session) {
size_t max;
int rv;
/* Make minimum number of idle streams 16, which is arbitrary chosen
number. */
max = nghttp2_max(16,
nghttp2_min(session->local_settings.max_concurrent_streams,
session->pending_local_max_concurrent_stream));
/* Make minimum number of idle streams 16, and maximum 100, which
are arbitrary chosen numbers. */
max = nghttp2_min(
100, nghttp2_max(
16, nghttp2_min(session->local_settings.max_concurrent_streams,
session->pending_local_max_concurrent_stream)));
DEBUGF(fprintf(stderr, "stream: adjusting kept idle streams "
"num_idle_streams=%zu, max=%zu\n",
@@ -1568,6 +1668,11 @@ static int session_predicate_push_promise_send(nghttp2_session *session,
static int session_predicate_window_update_send(nghttp2_session *session,
int32_t stream_id) {
nghttp2_stream *stream;
if (session_is_closing(session)) {
return NGHTTP2_ERR_SESSION_CLOSING;
}
if (stream_id == 0) {
/* Connection-level window update */
return 0;
@@ -1576,9 +1681,6 @@ static int session_predicate_window_update_send(nghttp2_session *session,
if (stream == NULL) {
return NGHTTP2_ERR_STREAM_CLOSED;
}
if (session_is_closing(session)) {
return NGHTTP2_ERR_SESSION_CLOSING;
}
if (stream->state == NGHTTP2_STREAM_CLOSING) {
return NGHTTP2_ERR_STREAM_CLOSING;
}
@@ -1588,6 +1690,29 @@ static int session_predicate_window_update_send(nghttp2_session *session,
return 0;
}
static int session_predicate_altsvc_send(nghttp2_session *session,
int32_t stream_id) {
nghttp2_stream *stream;
if (session_is_closing(session)) {
return NGHTTP2_ERR_SESSION_CLOSING;
}
if (stream_id == 0) {
return 0;
}
stream = nghttp2_session_get_stream(session, stream_id);
if (stream == NULL) {
return NGHTTP2_ERR_STREAM_CLOSED;
}
if (stream->state == NGHTTP2_STREAM_CLOSING) {
return NGHTTP2_ERR_STREAM_CLOSING;
}
return 0;
}
/* Take into account settings max frame size and both connection-level
flow control here */
static ssize_t
@@ -1748,6 +1873,41 @@ static size_t session_estimate_headers_payload(nghttp2_session *session,
additional;
}
static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs,
nghttp2_frame *frame) {
ssize_t rv;
nghttp2_buf *buf;
size_t buflen;
size_t framelen;
assert(session->callbacks.pack_extension_callback);
buf = &bufs->head->buf;
buflen = nghttp2_min(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN);
rv = session->callbacks.pack_extension_callback(session, buf->last, buflen,
frame, session->user_data);
if (rv == NGHTTP2_ERR_CANCEL) {
return (int)rv;
}
if (rv < 0 || (size_t)rv > buflen) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
framelen = (size_t)rv;
frame->hd.length = framelen;
assert(buf->pos == buf->last);
buf->last += framelen;
buf->pos -= NGHTTP2_FRAME_HDLEN;
nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
return 0;
}
/*
* This function serializes frame for transmission.
*
@@ -1988,8 +2148,48 @@ static int session_prep_frame(nghttp2_session *session,
nghttp2_frame_pack_window_update(&session->aob.framebufs,
&frame->window_update);
break;
default:
return NGHTTP2_ERR_INVALID_ARGUMENT;
case NGHTTP2_CONTINUATION:
/* We never handle CONTINUATION here. */
assert(0);
break;
default: {
nghttp2_ext_aux_data *aux_data;
/* extension frame */
aux_data = &item->aux_data.ext;
if (aux_data->builtin == 0) {
if (session_is_closing(session)) {
return NGHTTP2_ERR_SESSION_CLOSING;
}
rv = session_pack_extension(session, &session->aob.framebufs, frame);
if (rv != 0) {
return rv;
}
break;
}
switch (frame->hd.type) {
case NGHTTP2_ALTSVC:
rv = session_predicate_altsvc_send(session, frame->hd.stream_id);
if (rv != 0) {
return rv;
}
nghttp2_frame_pack_altsvc(&session->aob.framebufs, &frame->ext);
break;
default:
/* Unreachable here */
assert(0);
break;
}
break;
}
}
return 0;
} else {
@@ -2685,7 +2885,6 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
return rv;
}
*data_ptr = NULL;
for (;;) {
switch (aob->state) {
case NGHTTP2_OB_POP_ITEM: {
@@ -2942,6 +3141,8 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session,
int rv;
ssize_t len;
*data_ptr = NULL;
len = nghttp2_session_mem_send_internal(session, data_ptr, 1);
if (len <= 0) {
return len;
@@ -2963,7 +3164,7 @@ ssize_t nghttp2_session_mem_send(nghttp2_session *session,
}
int nghttp2_session_send(nghttp2_session *session) {
const uint8_t *data;
const uint8_t *data = NULL;
ssize_t datalen;
ssize_t sentlen;
nghttp2_bufs *framebufs;
@@ -3056,20 +3257,65 @@ static int session_call_on_begin_headers(nghttp2_session *session,
static int session_call_on_header(nghttp2_session *session,
const nghttp2_frame *frame,
const nghttp2_nv *nv) {
int rv;
if (session->callbacks.on_header_callback) {
const nghttp2_hd_nv *nv) {
int rv = 0;
if (session->callbacks.on_header_callback2) {
rv = session->callbacks.on_header_callback2(
session, frame, nv->name, nv->value, nv->flags, session->user_data);
} else if (session->callbacks.on_header_callback) {
rv = session->callbacks.on_header_callback(
session, frame, nv->name, nv->namelen, nv->value, nv->valuelen,
nv->flags, session->user_data);
if (rv == NGHTTP2_ERR_PAUSE ||
rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
session, frame, nv->name->base, nv->name->len, nv->value->base,
nv->value->len, nv->flags, session->user_data);
}
if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
return rv;
}
if (rv != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return 0;
}
static int
session_call_on_extension_chunk_recv_callback(nghttp2_session *session,
const uint8_t *data, size_t len) {
int rv;
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
if (session->callbacks.on_extension_chunk_recv_callback) {
rv = session->callbacks.on_extension_chunk_recv_callback(
session, &frame->hd, data, len, session->user_data);
if (rv == NGHTTP2_ERR_CANCEL) {
return rv;
}
if (rv != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
}
return 0;
}
static int session_call_unpack_extension_callback(nghttp2_session *session) {
int rv;
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
void *payload = NULL;
rv = session->callbacks.unpack_extension_callback(
session, &payload, &frame->hd, session->user_data);
if (rv == NGHTTP2_ERR_CANCEL) {
return rv;
}
if (rv != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
frame->ext.payload = payload;
return 0;
}
@@ -3210,11 +3456,10 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
ssize_t proclen;
int rv;
int inflate_flags;
nghttp2_nv nv;
nghttp2_hd_nv nv;
nghttp2_stream *stream;
nghttp2_stream *subject_stream;
int trailer = 0;
int token;
*readlen_ptr = 0;
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
@@ -3230,8 +3475,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
DEBUGF(fprintf(stderr, "recv: decoding header block %zu bytes\n", inlen));
for (;;) {
inflate_flags = 0;
proclen = nghttp2_hd_inflate_hd2(&session->hd_inflater, &nv, &inflate_flags,
&token, in, inlen, final);
proclen = nghttp2_hd_inflate_hd_nv(&session->hd_inflater, &nv,
&inflate_flags, in, inlen, final);
if (nghttp2_is_fatal((int)proclen)) {
return (int)proclen;
}
@@ -3266,13 +3511,23 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
if (call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) {
rv = 0;
if (subject_stream && session_enforce_http_messaging(session)) {
rv = nghttp2_http_on_header(session, subject_stream, frame, &nv, token,
rv = nghttp2_http_on_header(session, subject_stream, frame, &nv,
trailer);
if (rv == NGHTTP2_ERR_HTTP_HEADER) {
DEBUGF(fprintf(
stderr, "recv: HTTP error: type=%d, id=%d, header %.*s: %.*s\n",
frame->hd.type, subject_stream->stream_id, (int)nv.namelen,
nv.name, (int)nv.valuelen, nv.value));
stderr, "recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n",
frame->hd.type, subject_stream->stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base));
rv = session_call_error_callback(
session, "Invalid HTTP header field was received: frame type: "
"%u, stream: %d, name: [%.*s], value: [%.*s]",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv =
session_handle_invalid_stream2(session, subject_stream->stream_id,
@@ -3286,9 +3541,9 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
if (rv == NGHTTP2_ERR_IGN_HTTP_HEADER) {
/* header is ignored */
DEBUGF(fprintf(
stderr, "recv: HTTP ignored: type=%d, id=%d, header %.*s: %.*s\n",
frame->hd.type, subject_stream->stream_id, (int)nv.namelen,
nv.name, (int)nv.valuelen, nv.value));
stderr, "recv: HTTP ignored: type=%u, id=%d, header %.*s: %.*s\n",
frame->hd.type, subject_stream->stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base));
}
}
if (rv == 0) {
@@ -4117,39 +4372,39 @@ int nghttp2_session_on_settings_received(nghttp2_session *session,
}
static int session_process_settings_frame(nghttp2_session *session) {
int rv;
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
size_t i;
nghttp2_settings_entry min_header_size_entry;
nghttp2_mem *mem;
mem = &session->mem;
min_header_size_entry = iframe->iv[NGHTTP2_INBOUND_NUM_IV - 1];
if (iframe->max_niv) {
min_header_size_entry = iframe->iv[iframe->max_niv - 1];
if (min_header_size_entry.value < UINT32_MAX) {
/* If we have less value, then we must have
SETTINGS_HEADER_TABLE_SIZE in i < iframe->niv */
for (i = 0; i < iframe->niv; ++i) {
if (iframe->iv[i].settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) {
break;
if (min_header_size_entry.value < UINT32_MAX) {
/* If we have less value, then we must have
SETTINGS_HEADER_TABLE_SIZE in i < iframe->niv */
for (i = 0; i < iframe->niv; ++i) {
if (iframe->iv[i].settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) {
break;
}
}
assert(i < iframe->niv);
if (min_header_size_entry.value != iframe->iv[i].value) {
iframe->iv[iframe->niv++] = iframe->iv[i];
iframe->iv[i] = min_header_size_entry;
}
}
assert(i < iframe->niv);
if (min_header_size_entry.value != iframe->iv[i].value) {
iframe->iv[iframe->niv++] = iframe->iv[i];
iframe->iv[i] = min_header_size_entry;
}
}
rv = nghttp2_frame_unpack_settings_payload(&frame->settings, iframe->iv,
iframe->niv, mem);
if (rv != 0) {
assert(nghttp2_is_fatal(rv));
return rv;
}
nghttp2_frame_unpack_settings_payload(&frame->settings, iframe->iv,
iframe->niv);
iframe->iv = NULL;
iframe->niv = 0;
iframe->max_niv = 0;
return nghttp2_session_on_settings_received(session, frame, 0 /* ACK */);
}
@@ -4262,7 +4517,8 @@ int nghttp2_session_on_ping_received(nghttp2_session *session,
return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
"PING: stream_id != 0");
}
if ((frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 &&
if ((session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_PING_ACK) == 0 &&
(frame->hd.flags & NGHTTP2_FLAG_ACK) == 0 &&
!session_is_closing(session)) {
/* Peer sent ping, so ping it back */
rv = nghttp2_session_add_ping(session, NGHTTP2_FLAG_ACK,
@@ -4411,6 +4667,70 @@ static int session_process_window_update_frame(nghttp2_session *session) {
return nghttp2_session_on_window_update_received(session, frame);
}
int nghttp2_session_on_altsvc_received(nghttp2_session *session,
nghttp2_frame *frame) {
nghttp2_ext_altsvc *altsvc;
nghttp2_stream *stream;
altsvc = frame->ext.payload;
/* session->server case has been excluded */
if (frame->hd.stream_id == 0) {
if (altsvc->origin_len == 0) {
return 0;
}
} else {
if (altsvc->origin_len > 0) {
return 0;
}
stream = nghttp2_session_get_stream(session, frame->hd.stream_id);
if (!stream) {
return 0;
}
if (stream->state == NGHTTP2_STREAM_CLOSING) {
return 0;
}
}
return session_call_on_frame_received(session, frame);
}
static int session_process_altsvc_frame(nghttp2_session *session) {
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
nghttp2_frame_unpack_altsvc_payload(
&frame->ext, nghttp2_get_uint16(iframe->sbuf.pos), iframe->lbuf.pos,
nghttp2_buf_len(&iframe->lbuf));
/* nghttp2_frame_unpack_altsvc_payload steals buffer from
iframe->lbuf */
nghttp2_buf_wrap_init(&iframe->lbuf, NULL, 0);
return nghttp2_session_on_altsvc_received(session, frame);
}
static int session_process_extension_frame(nghttp2_session *session) {
int rv;
nghttp2_inbound_frame *iframe = &session->iframe;
nghttp2_frame *frame = &iframe->frame;
rv = session_call_unpack_extension_callback(session);
if (nghttp2_is_fatal(rv)) {
return rv;
}
/* This handles the case where rv == NGHTTP2_ERR_CANCEL as well */
if (rv != 0) {
return 0;
}
return session_call_on_frame_received(session, frame);
}
int nghttp2_session_on_data_received(nghttp2_session *session,
nghttp2_frame *frame) {
int rv = 0;
@@ -4740,6 +5060,7 @@ static size_t inbound_frame_buf_read(nghttp2_inbound_frame *iframe,
*/
static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
nghttp2_settings_entry iv;
nghttp2_settings_entry *min_header_table_size_entry;
size_t i;
nghttp2_frame_unpack_settings_entry(&iv, iframe->sbuf.pos);
@@ -4753,8 +5074,11 @@ static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
case NGHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE:
break;
default:
DEBUGF(fprintf(stderr, "recv: ignore unknown settings id=0x%02x\n",
iv.settings_id));
DEBUGF(
fprintf(stderr, "recv: unknown settings id=0x%02x\n", iv.settings_id));
iframe->iv[iframe->niv++] = iv;
return;
}
@@ -4769,10 +5093,13 @@ static void inbound_frame_set_settings_entry(nghttp2_inbound_frame *iframe) {
iframe->iv[iframe->niv++] = iv;
}
if (iv.settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE &&
iv.value < iframe->iv[NGHTTP2_INBOUND_NUM_IV - 1].value) {
if (iv.settings_id == NGHTTP2_SETTINGS_HEADER_TABLE_SIZE) {
/* Keep track of minimum value of SETTINGS_HEADER_TABLE_SIZE */
min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1];
iframe->iv[NGHTTP2_INBOUND_NUM_IV - 1] = iv;
if (iv.value < min_header_table_size_entry->value) {
min_header_table_size_entry->value = iv.value;
}
}
}
@@ -4901,6 +5228,15 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->state = NGHTTP2_IB_IGN_ALL;
rv = session_call_error_callback(
session, "Remote peer returned unexpected data while we expected "
"SETTINGS frame. Perhaps, peer does not support HTTP/2 "
"properly.");
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = nghttp2_session_terminate_session_with_reason(
session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected");
@@ -5136,6 +5472,25 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
iframe->state = NGHTTP2_IB_READ_SETTINGS;
if (iframe->payloadleft) {
nghttp2_settings_entry *min_header_table_size_entry;
/* We allocate iv with addtional one entry, to store the
minimum header table size. */
iframe->max_niv =
iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
iframe->max_niv);
if (!iframe->iv) {
return NGHTTP2_ERR_NOMEM;
}
min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1];
min_header_table_size_entry->settings_id =
NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
min_header_table_size_entry->value = UINT32_MAX;
inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH);
break;
}
@@ -5227,15 +5582,66 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
default:
DEBUGF(fprintf(stderr, "recv: unknown frame\n"));
DEBUGF(fprintf(stderr, "recv: extension frame\n"));
/* Silently ignore unknown frame type. */
if (check_ext_type_set(session->user_recv_ext_types,
iframe->frame.hd.type)) {
if (!session->callbacks.unpack_extension_callback) {
/* Silently ignore unknown frame type. */
busy = 1;
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
break;
}
busy = 1;
iframe->state = NGHTTP2_IB_READ_EXTENSION_PAYLOAD;
break;
} else {
switch (iframe->frame.hd.type) {
case NGHTTP2_ALTSVC:
if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
0) {
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
}
DEBUGF(fprintf(stderr, "recv: ALTSVC\n"));
iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
if (session->server) {
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
}
if (iframe->payloadleft < 2) {
busy = 1;
iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
break;
}
busy = 1;
iframe->state = NGHTTP2_IB_READ_NBYTE;
inbound_frame_set_mark(iframe, 2);
break;
default:
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
}
}
}
if (!on_begin_frame_called) {
@@ -5445,6 +5851,37 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
session_inbound_frame_reset(session);
break;
case NGHTTP2_ALTSVC: {
size_t origin_len;
origin_len = nghttp2_get_uint16(iframe->sbuf.pos);
DEBUGF(fprintf(stderr, "recv: origin_len=%zu\n", origin_len));
if (2 + origin_len > iframe->payloadleft) {
busy = 1;
iframe->state = NGHTTP2_IB_FRAME_SIZE_ERROR;
break;
}
if (iframe->frame.hd.length > 2) {
iframe->raw_lbuf =
nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2);
if (iframe->raw_lbuf == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_buf_wrap_init(&iframe->lbuf, iframe->raw_lbuf,
iframe->frame.hd.length);
}
busy = 1;
iframe->state = NGHTTP2_IB_READ_ALTSVC_PAYLOAD;
break;
}
default:
/* This is unknown frame */
session_inbound_frame_reset(session);
@@ -5640,10 +6077,12 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
readlen = inbound_frame_payload_readlen(iframe, in, last);
iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
if (readlen > 0) {
iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
iframe->payloadleft -= readlen;
in += readlen;
iframe->payloadleft -= readlen;
in += readlen;
}
DEBUGF(fprintf(stderr, "recv: readlen=%zu, payloadleft=%zu\n", readlen,
iframe->payloadleft));
@@ -5691,7 +6130,7 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
if (cont_hd.type != NGHTTP2_CONTINUATION ||
cont_hd.stream_id != iframe->frame.hd.stream_id) {
DEBUGF(fprintf(stderr, "recv: expected stream_id=%d, type=%d, but "
"got stream_id=%d, type=%d\n",
"got stream_id=%d, type=%u\n",
iframe->frame.hd.stream_id, NGHTTP2_CONTINUATION,
cont_hd.stream_id, cont_hd.type));
rv = nghttp2_session_terminate_session_with_reason(
@@ -5931,6 +6370,74 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
break;
case NGHTTP2_IB_IGN_ALL:
return (ssize_t)inlen;
case NGHTTP2_IB_READ_EXTENSION_PAYLOAD:
DEBUGF(fprintf(stderr, "recv: [IB_READ_EXTENSION_PAYLOAD]\n"));
readlen = inbound_frame_payload_readlen(iframe, in, last);
iframe->payloadleft -= readlen;
in += readlen;
DEBUGF(fprintf(stderr, "recv: readlen=%zu, payloadleft=%zu\n", readlen,
iframe->payloadleft));
if (readlen > 0) {
rv = session_call_on_extension_chunk_recv_callback(
session, in - readlen, readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (rv != 0) {
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
}
}
if (iframe->payloadleft > 0) {
break;
}
rv = session_process_extension_frame(session);
if (nghttp2_is_fatal(rv)) {
return rv;
}
session_inbound_frame_reset(session);
break;
case NGHTTP2_IB_READ_ALTSVC_PAYLOAD:
DEBUGF(fprintf(stderr, "recv: [IB_READ_ALTSVC_PAYLOAD]\n"));
readlen = inbound_frame_payload_readlen(iframe, in, last);
if (readlen > 0) {
iframe->lbuf.last = nghttp2_cpymem(iframe->lbuf.last, in, readlen);
iframe->payloadleft -= readlen;
in += readlen;
}
DEBUGF(fprintf(stderr, "recv: readlen=%zu, payloadleft=%zu\n", readlen,
iframe->payloadleft));
if (iframe->payloadleft) {
assert(nghttp2_buf_avail(&iframe->lbuf) > 0);
break;
}
rv = session_process_altsvc_frame(session);
if (nghttp2_is_fatal(rv)) {
return rv;
}
session_inbound_frame_reset(session);
break;
}
if (!busy && in == last) {
@@ -6399,6 +6906,14 @@ int nghttp2_session_pack_data(nghttp2_session *session, nghttp2_bufs *bufs,
reschedule_stream(stream);
if (frame->hd.length == 0 && (data_flags & NGHTTP2_DATA_FLAG_EOF) &&
(data_flags & NGHTTP2_DATA_FLAG_NO_END_STREAM)) {
/* DATA payload length is 0, and DATA frame does not bear
END_STREAM. In this case, there is no point to send 0 length
DATA frame. */
return NGHTTP2_ERR_CANCEL;
}
return 0;
}

View File

@@ -50,9 +50,19 @@ extern int nghttp2_enable_strict_preface;
typedef enum {
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0,
NGHTTP2_OPTMASK_NO_RECV_CLIENT_MAGIC = 1 << 1,
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2
NGHTTP2_OPTMASK_NO_HTTP_MESSAGING = 1 << 2,
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,
@@ -105,21 +115,21 @@ typedef enum {
NGHTTP2_IB_READ_PAD_DATA,
NGHTTP2_IB_READ_DATA,
NGHTTP2_IB_IGN_DATA,
NGHTTP2_IB_IGN_ALL
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 */
@@ -128,6 +138,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 */
@@ -292,6 +304,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;
@@ -304,6 +319,13 @@ struct nghttp2_session {
this session. The nonzero does not necessarily mean
WINDOW_UPDATE is not queued. */
uint8_t window_update_queued;
/* Bitfield of extension frame types that application is willing to
receive. To designate the bit of given frame type i, use
user_recv_ext_types[i / 8] & (1 << (i & 0x7)). First 10 frame
types are standard frame types and not used in this bitfield. If
bit is set, it indicates that incoming frame with that type is
passed to user defined callbacks, otherwise they are ignored. */
uint8_t user_recv_ext_types[32];
};
/* Struct used when updating initial window size of each active
@@ -707,6 +729,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

@@ -30,14 +30,32 @@
#include "nghttp2_session.h"
#include "nghttp2_helper.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
cycle is B, and A < B. The cycle is unsigned 32 bit integer, it
may get overflow. Because of how we calculate the next cycle
value, if B - A is less than or equals to
NGHTTP2_MAX_CYCLE_DISTANCE, A and B are in the same scale, in other
words, B is really greater than or equal to A. Otherwise, A is a
result of overflow, and it is actually A > B if we consider that
fact. */
#define NGHTTP2_MAX_CYCLE_DISTANCE (16384 * 256 + 255)
static int stream_less(const void *lhsx, const void *rhsx) {
const nghttp2_stream *lhs, *rhs;
lhs = nghttp2_struct_of(lhsx, nghttp2_stream, pq_entry);
rhs = nghttp2_struct_of(rhsx, nghttp2_stream, pq_entry);
return lhs->cycle < rhs->cycle ||
(lhs->cycle == rhs->cycle && lhs->seq < rhs->seq);
if (lhs->cycle == rhs->cycle) {
return lhs->seq < rhs->seq;
}
if (lhs->cycle < rhs->cycle) {
return rhs->cycle - lhs->cycle <= NGHTTP2_MAX_CYCLE_DISTANCE;
}
return lhs->cycle - rhs->cycle > NGHTTP2_MAX_CYCLE_DISTANCE;
}
void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id,
@@ -116,14 +134,14 @@ static int stream_subtree_active(nghttp2_stream *stream) {
/*
* Returns next cycle for |stream|.
*/
static void stream_next_cycle(nghttp2_stream *stream, uint64_t last_cycle) {
size_t penalty;
static void stream_next_cycle(nghttp2_stream *stream, uint32_t last_cycle) {
uint32_t penalty;
penalty =
stream->last_writelen * NGHTTP2_MAX_WEIGHT + stream->pending_penalty;
penalty = (uint32_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT +
stream->pending_penalty;
stream->cycle = last_cycle + penalty / (uint32_t)stream->weight;
stream->pending_penalty = (uint32_t)(penalty % (uint32_t)stream->weight);
stream->pending_penalty = penalty % (uint32_t)stream->weight;
}
static int stream_obq_push(nghttp2_stream *dep_stream, nghttp2_stream *stream) {
@@ -134,7 +152,7 @@ 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=%ld\n",
DEBUGF(fprintf(stderr, "stream: stream=%d obq push cycle=%d\n",
stream->stream_id, stream->cycle));
DEBUGF(fprintf(stderr, "stream: push stream %d to stream %d\n",
@@ -220,7 +238,7 @@ 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=%ld\n",
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
stream->stream_id, stream->cycle));
dep_stream->last_writelen = stream->last_writelen;
@@ -229,9 +247,9 @@ void nghttp2_stream_reschedule(nghttp2_stream *stream) {
void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_stream *dep_stream;
uint64_t last_cycle;
uint32_t last_cycle;
int32_t old_weight;
size_t wlen_penalty;
uint32_t wlen_penalty;
if (stream->weight == weight) {
return;
@@ -254,7 +272,7 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
nghttp2_pq_remove(&dep_stream->obq, &stream->pq_entry);
wlen_penalty = stream->last_writelen * NGHTTP2_MAX_WEIGHT;
wlen_penalty = (uint32_t)stream->last_writelen * NGHTTP2_MAX_WEIGHT;
/* Compute old stream->pending_penalty we used to calculate
stream->cycle */
@@ -270,7 +288,9 @@ void nghttp2_stream_change_weight(nghttp2_stream *stream, int32_t weight) {
place */
stream_next_cycle(stream, last_cycle);
if (stream->cycle < dep_stream->descendant_last_cycle) {
if (stream->cycle < dep_stream->descendant_last_cycle &&
(dep_stream->descendant_last_cycle - stream->cycle) <=
NGHTTP2_MAX_CYCLE_DISTANCE) {
stream->cycle = dep_stream->descendant_last_cycle;
}
@@ -278,7 +298,7 @@ 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=%ld\n",
DEBUGF(fprintf(stderr, "stream: stream=%d obq resched cycle=%d\n",
stream->stream_id, stream->cycle));
}

View File

@@ -147,9 +147,9 @@ struct nghttp2_stream {
/* Received body so far */
int64_t recv_content_length;
/* Base last_cycle for direct descendent streams. */
uint64_t descendant_last_cycle;
uint32_t descendant_last_cycle;
/* Next scheduled time to sent item */
uint64_t cycle;
uint32_t cycle;
/* Next seq used for direct descendant streams */
uint64_t descendant_next_seq;
/* Secondary key for prioritization to break a tie for cycle. This

View File

@@ -211,9 +211,10 @@ int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
nvlen, NULL, stream_user_data);
}
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags _U_,
int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
const uint8_t *opaque_data) {
return nghttp2_session_add_ping(session, NGHTTP2_FLAG_NONE, opaque_data);
flags &= NGHTTP2_FLAG_ACK;
return nghttp2_session_add_ping(session, flags, opaque_data);
}
int nghttp2_submit_priority(nghttp2_session *session, uint8_t flags _U_,
@@ -409,6 +410,90 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
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;
@@ -530,3 +615,40 @@ ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
return (ssize_t)nghttp2_frame_pack_settings_payload(buf, iv, niv);
}
int nghttp2_submit_extension(nghttp2_session *session, uint8_t type,
uint8_t flags, int32_t stream_id, void *payload) {
int rv;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
nghttp2_mem *mem;
mem = &session->mem;
if (type <= NGHTTP2_CONTINUATION) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (!session->callbacks.pack_extension_callback) {
return NGHTTP2_ERR_INVALID_STATE;
}
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) {
return NGHTTP2_ERR_NOMEM;
}
nghttp2_outbound_item_init(item);
frame = &item->frame;
nghttp2_frame_extension_init(&frame->ext, type, flags, stream_id, payload);
rv = nghttp2_session_add_item(session, item);
if (rv != 0) {
nghttp2_frame_extension_free(&frame->ext);
nghttp2_mem_free(mem, item);
return rv;
}
return 0;
}

View File

@@ -3,12 +3,12 @@
TAG=$1
PREV_TAG=$2
git submodule update --init
git checkout refs/tags/$TAG
git log --pretty=fuller --date=short refs/tags/$PREV_TAG..HEAD > ChangeLog
git submodule update --init
autoreconf -i
./configure --with-mruby && \
make dist-bzip2 && make dist-gzip && make dist-xz || echo "error"
make distclean

39
python/CMakeLists.txt Normal file
View File

@@ -0,0 +1,39 @@
# EXTRA_DIST = cnghttp2.pxd nghttp2.pyx
if(ENABLE_PYTHON_BINDINGS)
add_custom_target(python ALL
COMMAND "${PYTHON_EXECUTABLE}" setup.py build
VERBATIM
DEPENDS nghttp2.c nghttp2
)
configure_file(install-python.cmake.in install-python.cmake ESCAPE_QUOTES @ONLY)
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/install-python.cmake")
add_custom_command(OUTPUT nghttp2.c
COMMAND "${CYTHON_EXECUTABLE}" -o nghttp2.c
"${CMAKE_CURRENT_SOURCE_DIR}/nghttp2.pyx"
VERBATIM
DEPENDS nghttp2.pyx
)
# Instead of calling "setup.py clean --all", this should do...
set_directory_properties(PROPERTIES
ADDITIONAL_MAKE_CLEAN_FILES "build;python_nghttp2.egg-info"
)
## This works also, except that the installation target is missing...
# include(UseCython)
# cython_add_module(python_nghttp2 nghttp2.pyx)
# set_target_properties(python_nghttp2 PROPERTIES
# OUTPUT_NAME nghttp2
# )
# target_include_directories(python_nghttp2 PRIVATE
# "${CMAKE_SOURCE_DIR}/lib"
# "${CMAKE_SOURCE_DIR}/lib/includes"
# "${CMAKE_BINARY_DIR}/lib/includes"
# )
# target_link_libraries(python_nghttp2
# nghttp2
# )
endif()

View File

@@ -25,7 +25,7 @@
# clean-local in parallel build.
.NOTPARALLEL:
EXTRA_DIST = cnghttp2.pxd nghttp2.pyx
EXTRA_DIST = cnghttp2.pxd nghttp2.pyx CMakeLists.txt install-python.cmake.in
if ENABLE_PYTHON_BINDINGS

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

@@ -0,0 +1,10 @@
get_filename_component(rootdir "$ENV{DESTDIR}" ABSOLUTE)
if(rootdir STREQUAL "")
set(rootdir /)
endif()
execute_process(
COMMAND "@PYTHON_EXECUTABLE@" setup.py install
--skip-build
--root=${rootdir} --prefix=${CMAKE_INSTALL_PREFIX}
WORKING_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
)

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

View File

@@ -39,6 +39,7 @@ setup(
'@top_srcdir@/lib/includes',
'@top_builddir@/lib/includes'],
library_dirs=['@top_builddir@/lib/.libs',
'@top_builddir@/lib',
'@top_builddir@'],
libraries=LIBS)],
long_description='TBD'

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"

5
script/CMakeLists.txt Normal file
View File

@@ -0,0 +1,5 @@
# EXTRA_DIST = README.rst
install(
PROGRAMS fetch-ocsp-response
DESTINATION "${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}"
)

View File

@@ -21,5 +21,5 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTRA_DIST = README.rst
EXTRA_DIST = README.rst CMakeLists.txt
dist_pkgdata_SCRIPTS = fetch-ocsp-response

258
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,258 @@
add_subdirectory(includes)
file(GLOB c_sources *.c)
set_source_files_properties(${c_sources} PROPERTIES
COMPILE_FLAGS "${WARNCFLAGS}")
file(GLOB cxx_sources *.cc)
set_source_files_properties(${cxx_sources} PROPERTIES
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}")
include_directories(
"${CMAKE_SOURCE_DIR}/lib/includes"
"${CMAKE_BINARY_DIR}/lib/includes"
"${CMAKE_SOURCE_DIR}/lib"
"${CMAKE_SOURCE_DIR}/src/includes"
"${CMAKE_SOURCE_DIR}/third-party"
${JEMALLOC_INCLUDE_DIRS}
${SPDYLAY_INCLUDE_DIRS}
${LIBXML2_INCLUDE_DIRS}
${LIBEV_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${JANSSON_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
)
# XXX per-target?
link_libraries(
nghttp2
${JEMALLOC_LIBRARIES}
${SPDYLAY_LIBRARIES}
${LIBXML2_LIBRARIES}
${LIBEV_LIBRARIES}
${OPENSSL_LIBRARIES}
${JANSSON_LIBRARIES}
${ZLIB_LIBRARIES}
${APP_LIBRARIES}
)
if(ENABLE_APP)
set(HELPER_OBJECTS
util.cc
http2.cc timegm.c app_helper.cc nghttp2_gzip.c
)
# nghttp client
set(NGHTTP_SOURCES
${HELPER_OBJECTS}
nghttp.cc
ssl.cc
)
if(HAVE_LIBXML2)
list(APPEND NGHTTP_SOURCES HtmlParser.cc)
endif()
# nghttpd
set(NGHTTPD_SOURCES
${HELPER_OBJECTS}
nghttpd.cc
ssl.cc
HttpServer.cc
)
# h2load
set(H2LOAD_SOURCES
util.cc
http2.cc h2load.cc
timegm.c
ssl.cc
h2load_http2_session.cc
h2load_http1_session.cc
)
if(HAVE_SPDYLAY)
list(APPEND H2LOAD_SOURCES
h2load_spdy_session.cc
)
endif()
# Common libnhttpx sources (used for nghttpx and unit tests)
set(NGHTTPX_SRCS
util.cc http2.cc timegm.c
app_helper.cc
ssl.cc
shrpx_config.cc
shrpx_accept_handler.cc
shrpx_connection_handler.cc
shrpx_client_handler.cc
shrpx_http2_upstream.cc
shrpx_https_upstream.cc
shrpx_downstream.cc
shrpx_downstream_connection.cc
shrpx_http_downstream_connection.cc
shrpx_http2_downstream_connection.cc
shrpx_http2_session.cc
shrpx_downstream_queue.cc
shrpx_log.cc
shrpx_http.cc
shrpx_io_control.cc
shrpx_ssl.cc
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
shrpx_memcached_dispatcher.cc
shrpx_memcached_connection.cc
shrpx_worker_process.cc
shrpx_signal.cc
shrpx_router.cc
)
if(HAVE_SPDYLAY)
list(APPEND NGHTTPX_SRCS
shrpx_spdy_upstream.cc
)
endif()
if(HAVE_MRUBY)
list(APPEND NGHTTPX_SRCS
shrpx_mruby.cc
shrpx_mruby_module.cc
shrpx_mruby_module_env.cc
shrpx_mruby_module_request.cc
shrpx_mruby_module_response.cc
)
endif()
add_library(nghttpx_static STATIC ${NGHTTPX_SRCS})
set_target_properties(nghttpx_static PROPERTIES ARCHIVE_OUTPUT_NAME nghttpx)
set(NGHTTPX-bin_SOURCES
shrpx.cc
)
if(HAVE_MRUBY)
target_link_libraries(nghttpx_static mruby-lib)
endif()
if(HAVE_NEVERBLEED)
target_link_libraries(nghttpx_static neverbleed)
endif()
if(HAVE_CUNIT)
set(NGHTTPX_UNITTEST_SOURCES
shrpx-unittest.cc
shrpx_ssl_test.cc
shrpx_downstream_test.cc
shrpx_config_test.cc
shrpx_worker_test.cc
shrpx_http_test.cc
http2_test.cc
util_test.cc
nghttp2_gzip_test.c
nghttp2_gzip.c
buffer_test.cc
memchunk_test.cc
template_test.cc
base64_test.cc
)
add_executable(nghttpx-unittest EXCLUDE_FROM_ALL
${NGHTTPX_UNITTEST_SOURCES}
$<TARGET_OBJECTS:http-parser>
)
target_include_directories(nghttpx-unittest PRIVATE ${CUNIT_INCLUDE_DIRS})
target_compile_definitions(nghttpx-unittest
PRIVATE "-DNGHTTP2_TESTS_DIR=\"${CMAKE_SOURCE_DIR}/tests\""
)
target_link_libraries(nghttpx-unittest nghttpx_static ${CUNIT_LIBRARIES})
if(HAVE_MRUBY)
target_link_libraries(nghttpx-unittest mruby-lib)
endif()
if(HAVE_NEVERBLEED)
target_link_libraries(nghttpx-unittest neverbleed)
endif()
add_test(nghttpx-unittest nghttpx-unittest)
add_dependencies(check nghttpx-unittest)
endif()
add_executable(nghttp ${NGHTTP_SOURCES} $<TARGET_OBJECTS:http-parser>)
add_executable(nghttpd ${NGHTTPD_SOURCES} $<TARGET_OBJECTS:http-parser>)
add_executable(nghttpx ${NGHTTPX-bin_SOURCES} $<TARGET_OBJECTS:http-parser>)
target_compile_definitions(nghttpx PRIVATE "-DPKGDATADIR=\"${PKGDATADIR}\"")
target_link_libraries(nghttpx nghttpx_static)
add_executable(h2load ${H2LOAD_SOURCES} $<TARGET_OBJECTS:http-parser>)
install(TARGETS nghttp nghttpd nghttpx h2load
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(ENABLE_HPACK_TOOLS)
set(inflatehd_SOURCES
inflatehd.cc
comp_helper.c
)
set(deflatehd_SOURCES
deflatehd.cc
comp_helper.c
)
add_executable(inflatehd ${inflatehd_SOURCES})
add_executable(deflatehd ${deflatehd_SOURCES})
install(TARGETS inflatehd deflatehd
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(ENABLE_ASIO_LIB)
set(NGHTTP2_ASIO_SOURCES
util.cc http2.cc
ssl.cc
timegm.c
asio_common.cc
asio_io_service_pool.cc
asio_server_http2.cc
asio_server_http2_impl.cc
asio_server.cc
asio_server_http2_handler.cc
asio_server_request.cc
asio_server_request_impl.cc
asio_server_response.cc
asio_server_response_impl.cc
asio_server_stream.cc
asio_server_serve_mux.cc
asio_server_request_handler.cc
asio_server_tls_context.cc
asio_client_session.cc
asio_client_session_impl.cc
asio_client_session_tcp_impl.cc
asio_client_session_tls_impl.cc
asio_client_response.cc
asio_client_response_impl.cc
asio_client_request.cc
asio_client_request_impl.cc
asio_client_stream.cc
asio_client_tls_context.cc
)
add_library(nghttp2_asio SHARED
${NGHTTP2_ASIO_SOURCES}
$<TARGET_OBJECTS:http-parser>
)
target_include_directories(nghttp2_asio PRIVATE
${OPENSSL_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
target_link_libraries(nghttp2_asio
nghttp2
${OPENSSL_LIBRARIES}
${Boost_LIBRARIES}
)
set_target_properties(nghttp2_asio PROPERTIES
VERSION 1.0.0 SOVERSION 1)
install(TARGETS nghttp2_asio
DESTINATION "${CMAKE_INSTALL_LIBDIR}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2_asio.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif()

View File

@@ -39,23 +39,27 @@ HtmlParser::HtmlParser(const std::string &base_uri)
HtmlParser::~HtmlParser() { htmlFreeParserCtxt(parser_ctx_); }
namespace {
const char *get_attr(const xmlChar **attrs, const char *name) {
StringRef get_attr(const xmlChar **attrs, const StringRef &name) {
if (attrs == nullptr) {
return nullptr;
return StringRef{};
}
for (; *attrs; attrs += 2) {
if (util::strieq(reinterpret_cast<const char *>(attrs[0]), name)) {
return reinterpret_cast<const char *>(attrs[1]);
if (util::strieq(StringRef{attrs[0], strlen(reinterpret_cast<const char *>(
attrs[0]))},
name)) {
return StringRef{attrs[1],
strlen(reinterpret_cast<const char *>(attrs[1]))};
}
}
return nullptr;
return StringRef{};
}
} // namespace
namespace {
void add_link(ParserData *parser_data, const char *uri, ResourceType res_type) {
void add_link(ParserData *parser_data, const StringRef &uri,
ResourceType res_type) {
auto u = xmlBuildURI(
reinterpret_cast<const xmlChar *>(uri),
reinterpret_cast<const xmlChar *>(uri.c_str()),
reinterpret_cast<const xmlChar *>(parser_data->base_uri.c_str()));
if (u) {
parser_data->links.push_back(
@@ -66,32 +70,34 @@ void add_link(ParserData *parser_data, const char *uri, ResourceType res_type) {
} // namespace
namespace {
void start_element_func(void *user_data, const xmlChar *name,
void start_element_func(void *user_data, const xmlChar *src_name,
const xmlChar **attrs) {
auto parser_data = static_cast<ParserData *>(user_data);
if (util::strieq(reinterpret_cast<const char *>(name), "head")) {
auto name =
StringRef{src_name, strlen(reinterpret_cast<const char *>(src_name))};
if (util::strieq_l("head", name)) {
++parser_data->inside_head;
}
if (util::strieq(reinterpret_cast<const char *>(name), "link")) {
auto rel_attr = get_attr(attrs, "rel");
auto href_attr = get_attr(attrs, "href");
if (!href_attr) {
if (util::strieq_l("link", name)) {
auto rel_attr = get_attr(attrs, StringRef::from_lit("rel"));
auto href_attr = get_attr(attrs, StringRef::from_lit("href"));
if (rel_attr.empty() || href_attr.empty()) {
return;
}
if (util::strieq(rel_attr, "shortcut icon")) {
if (util::strieq_l("shortcut icon", rel_attr)) {
add_link(parser_data, href_attr, REQ_OTHERS);
} else if (util::strieq(rel_attr, "stylesheet")) {
} else if (util::strieq_l("stylesheet", rel_attr)) {
add_link(parser_data, href_attr, REQ_CSS);
}
} else if (util::strieq(reinterpret_cast<const char *>(name), "img")) {
auto src_attr = get_attr(attrs, "src");
if (!src_attr) {
} else if (util::strieq_l("img", name)) {
auto src_attr = get_attr(attrs, StringRef::from_lit("src"));
if (src_attr.empty()) {
return;
}
add_link(parser_data, src_attr, REQ_IMG);
} else if (util::strieq(reinterpret_cast<const char *>(name), "script")) {
auto src_attr = get_attr(attrs, "src");
if (!src_attr) {
} else if (util::strieq_l("script", name)) {
auto src_attr = get_attr(attrs, StringRef::from_lit("src"));
if (src_attr.empty()) {
return;
}
if (parser_data->inside_head) {
@@ -106,7 +112,9 @@ void start_element_func(void *user_data, const xmlChar *name,
namespace {
void end_element_func(void *user_data, const xmlChar *name) {
auto parser_data = static_cast<ParserData *>(user_data);
if (util::strieq(reinterpret_cast<const char *>(name), "head")) {
if (util::strieq_l(
"head",
StringRef{name, strlen(reinterpret_cast<const char *>(name))})) {
--parser_data->inside_head;
}
}

View File

@@ -71,8 +71,9 @@ namespace nghttp2 {
namespace {
// TODO could be constexpr
constexpr char DEFAULT_HTML[] = "index.html";
constexpr char NGHTTPD_SERVER[] = "nghttpd nghttp2/" NGHTTP2_VERSION;
constexpr auto DEFAULT_HTML = StringRef::from_lit("index.html");
constexpr auto NGHTTPD_SERVER =
StringRef::from_lit("nghttpd nghttp2/" NGHTTP2_VERSION);
} // namespace
namespace {
@@ -86,20 +87,6 @@ namespace {
void print_session_id(int64_t id) { std::cout << "[id=" << id << "] "; }
} // namespace
namespace {
template <typename Array> void append_nv(Stream *stream, const Array &nva) {
for (size_t i = 0; i < nva.size(); ++i) {
auto &nv = nva[i];
auto token = http2::lookup_token(nv.name, nv.namelen);
if (token != -1) {
http2::index_header(stream->hdidx, token, i);
}
http2::add_header(stream->headers, nv.name, nv.namelen, nv.value,
nv.valuelen, nv.flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
}
}
} // namespace
Config::Config()
: mime_types_file("/etc/mime.types"),
stream_read_timeout(1_min),
@@ -308,7 +295,6 @@ public:
}
auto handler =
make_unique<Http2Handler>(this, fd, ssl, get_next_session_id());
handler->setup_bev();
if (!ssl) {
if (handler->connection_made() != 0) {
return;
@@ -443,10 +429,13 @@ void release_fd_cb(struct ev_loop *loop, ev_timer *w, int revents) {
} // namespace
Stream::Stream(Http2Handler *handler, int32_t stream_id)
: handler(handler),
: balloc(1024, 1024),
header{},
handler(handler),
file_ent(nullptr),
body_length(0),
body_offset(0),
header_buffer_size(0),
stream_id(stream_id),
echo_upload(false) {
auto config = handler->get_config();
@@ -454,10 +443,6 @@ Stream::Stream(Http2Handler *handler, int32_t stream_id)
ev_timer_init(&wtimer, stream_timeout_cb, 0., config->stream_write_timeout);
rtimer.data = this;
wtimer.data = this;
headers.reserve(10);
http2::init_hdidx(hdidx);
}
Stream::~Stream() {
@@ -466,6 +451,15 @@ Stream::~Stream() {
sessions->release_fd(file_ent);
}
auto &rcbuf = header.rcbuf;
nghttp2_rcbuf_decref(rcbuf.method);
nghttp2_rcbuf_decref(rcbuf.scheme);
nghttp2_rcbuf_decref(rcbuf.authority);
nghttp2_rcbuf_decref(rcbuf.host);
nghttp2_rcbuf_decref(rcbuf.path);
nghttp2_rcbuf_decref(rcbuf.ims);
nghttp2_rcbuf_decref(rcbuf.expect);
auto loop = handler->get_loop();
ev_timer_stop(loop, &rtimer);
ev_timer_stop(loop, &wtimer);
@@ -574,7 +568,9 @@ struct ev_loop *Http2Handler::get_loop() const {
Http2Handler::WriteBuf *Http2Handler::get_wb() { return &wb_; }
int Http2Handler::setup_bev() { return 0; }
void Http2Handler::start_settings_timer() {
ev_timer_start(sessions_->get_loop(), &settings_timerev_);
}
int Http2Handler::fill_wb() {
if (data_pending_) {
@@ -869,8 +865,6 @@ int Http2Handler::connection_made() {
}
}
ev_timer_start(sessions_->get_loop(), &settings_timerev_);
if (ssl_ && !nghttp2::ssl::check_http2_requirement(ssl_)) {
terminate_session(NGHTTP2_INADEQUATE_SECURITY);
}
@@ -885,11 +879,11 @@ int Http2Handler::verify_npn_result() {
SSL_get0_next_proto_negotiated(ssl_, &next_proto, &next_proto_len);
for (int i = 0; i < 2; ++i) {
if (next_proto) {
auto proto = StringRef{next_proto, next_proto_len};
if (sessions_->get_config()->verbose) {
std::string proto(next_proto, next_proto + next_proto_len);
std::cout << "The negotiated protocol: " << proto << std::endl;
}
if (util::check_h2_is_selected(next_proto, next_proto_len)) {
if (util::check_h2_is_selected(proto)) {
return 0;
}
break;
@@ -909,37 +903,22 @@ int Http2Handler::verify_npn_result() {
return -1;
}
namespace {
std::string make_trailer_header_value(const Headers &trailer) {
if (trailer.empty()) {
return "";
}
auto trailer_names = trailer[0].name;
for (size_t i = 1; i < trailer.size(); ++i) {
trailer_names += ", ";
trailer_names += trailer[i].name;
}
return trailer_names;
}
} // namespace
int Http2Handler::submit_file_response(const std::string &status,
Stream *stream, time_t last_modified,
off_t file_length,
int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
time_t last_modified, off_t file_length,
const std::string *content_type,
nghttp2_data_provider *data_prd) {
std::string content_length = util::utos(file_length);
std::string last_modified_str;
auto nva = make_array(http2::make_nv_ls(":status", status),
http2::make_nv_ll("server", NGHTTPD_SERVER),
auto nva = make_array(http2::make_nv_ls_nocopy(":status", status),
http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER),
http2::make_nv_ll("cache-control", "max-age=3600"),
http2::make_nv_ls("date", sessions_->get_cached_date()),
http2::make_nv_ll("", ""), http2::make_nv_ll("", ""),
http2::make_nv_ll("", ""), http2::make_nv_ll("", ""));
size_t nvlen = 4;
if (!get_config()->no_content_length) {
nva[nvlen++] = http2::make_nv_ls("content-length", content_length);
nva[nvlen++] = http2::make_nv_ls_nocopy(
"content-length",
util::make_string_ref_uint(stream->balloc, file_length));
}
if (last_modified != 0) {
last_modified_str = util::http_date(last_modified);
@@ -948,52 +927,50 @@ int Http2Handler::submit_file_response(const std::string &status,
if (content_type) {
nva[nvlen++] = http2::make_nv_ls("content-type", *content_type);
}
auto trailer_names = make_trailer_header_value(get_config()->trailer);
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_nv_ls("trailer", trailer_names);
nva[nvlen++] = http2::make_nv_ls_nocopy("trailer", trailer_names);
}
return nghttp2_submit_response(session_, stream->stream_id, nva.data(), nvlen,
data_prd);
}
int Http2Handler::submit_response(const std::string &status, int32_t stream_id,
const Headers &headers,
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
const HeaderRefs &headers,
nghttp2_data_provider *data_prd) {
auto nva = std::vector<nghttp2_nv>();
nva.reserve(4 + headers.size());
nva.push_back(http2::make_nv_ls(":status", status));
nva.push_back(http2::make_nv_ll("server", NGHTTPD_SERVER));
nva.push_back(http2::make_nv_ls_nocopy(":status", status));
nva.push_back(http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER));
nva.push_back(http2::make_nv_ls("date", sessions_->get_cached_date()));
std::string trailer_names;
if (data_prd) {
trailer_names = make_trailer_header_value(get_config()->trailer);
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva.push_back(http2::make_nv_ls("trailer", trailer_names));
nva.push_back(http2::make_nv_ls_nocopy("trailer", trailer_names));
}
}
for (auto &nv : headers) {
nva.push_back(http2::make_nv(nv.name, nv.value, nv.no_index));
nva.push_back(http2::make_nv_nocopy(nv.name, nv.value, nv.no_index));
}
int r = nghttp2_submit_response(session_, stream_id, nva.data(), nva.size(),
data_prd);
return r;
}
int Http2Handler::submit_response(const std::string &status, int32_t stream_id,
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
nghttp2_data_provider *data_prd) {
auto nva = make_array(http2::make_nv_ls(":status", status),
http2::make_nv_ll("server", NGHTTPD_SERVER),
auto nva = make_array(http2::make_nv_ls_nocopy(":status", status),
http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER),
http2::make_nv_ls("date", sessions_->get_cached_date()),
http2::make_nv_ll("", ""));
size_t nvlen = 3;
std::string trailer_names;
if (data_prd) {
trailer_names = make_trailer_header_value(get_config()->trailer);
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_nv_ls("trailer", trailer_names);
nva[nvlen++] = http2::make_nv_ls_nocopy("trailer", trailer_names);
}
}
@@ -1009,21 +986,20 @@ int Http2Handler::submit_non_final_response(const std::string &status,
}
int Http2Handler::submit_push_promise(Stream *stream,
const std::string &push_path) {
auto authority =
http2::get_header(stream->hdidx, http2::HD__AUTHORITY, stream->headers);
const StringRef &push_path) {
auto authority = stream->header.authority;
if (!authority) {
authority =
http2::get_header(stream->hdidx, http2::HD_HOST, stream->headers);
if (authority.empty()) {
authority = stream->header.host;
}
auto nva =
make_array(http2::make_nv_ll(":method", "GET"),
http2::make_nv_ls(":path", push_path),
get_config()->no_tls ? http2::make_nv_ll(":scheme", "http")
: http2::make_nv_ll(":scheme", "https"),
http2::make_nv_ls(":authority", authority->value));
auto scheme = get_config()->no_tls ? StringRef::from_lit("http")
: StringRef::from_lit("https");
auto nva = make_array(http2::make_nv_ll(":method", "GET"),
http2::make_nv_ls_nocopy(":path", push_path),
http2::make_nv_ls_nocopy(":scheme", scheme),
http2::make_nv_ls_nocopy(":authority", authority));
auto promised_stream_id = nghttp2_submit_push_promise(
session_, NGHTTP2_FLAG_END_HEADERS, stream->stream_id, nva.data(),
@@ -1035,7 +1011,13 @@ int Http2Handler::submit_push_promise(Stream *stream,
auto promised_stream = make_unique<Stream>(this, promised_stream_id);
append_nv(promised_stream.get(), nva);
auto &promised_header = promised_stream->header;
promised_header.method = StringRef::from_lit("GET");
promised_header.path = push_path;
promised_header.scheme = scheme;
promised_header.authority =
make_string_ref(promised_stream->balloc, authority);
add_stream(promised_stream_id, std::move(promised_stream));
return 0;
@@ -1138,10 +1120,15 @@ void prepare_status_response(Stream *stream, Http2Handler *hd, int status) {
data_prd.source.fd = file_ent->fd;
data_prd.read_callback = file_read_callback;
Headers headers;
headers.emplace_back("content-type", "text/html; charset=UTF-8");
hd->submit_response(status_page->status, stream->stream_id, headers,
&data_prd);
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);
}
} // namespace
@@ -1161,13 +1148,16 @@ void prepare_echo_response(Stream *stream, Http2Handler *hd) {
data_prd.source.fd = stream->file_ent->fd;
data_prd.read_callback = file_read_callback;
Headers headers;
headers.emplace_back("nghttpd-response", "echo");
HeaderRefs headers;
headers.emplace_back(StringRef::from_lit("nghttpd-response"),
StringRef::from_lit("echo"));
if (!hd->get_config()->no_content_length) {
headers.emplace_back("content-length", util::utos(length));
headers.emplace_back(StringRef::from_lit("content-length"),
util::make_string_ref_uint(stream->balloc, length));
}
hd->submit_response("200", stream->stream_id, headers, &data_prd);
hd->submit_response(StringRef::from_lit("200"), stream->stream_id, headers,
&data_prd);
}
} // namespace
@@ -1193,27 +1183,24 @@ bool prepare_upload_temp_store(Stream *stream, Http2Handler *hd) {
namespace {
void prepare_redirect_response(Stream *stream, Http2Handler *hd,
const std::string &path, int status) {
auto scheme =
http2::get_header(stream->hdidx, http2::HD__SCHEME, stream->headers);
auto authority =
http2::get_header(stream->hdidx, http2::HD__AUTHORITY, stream->headers);
if (!authority) {
authority =
http2::get_header(stream->hdidx, http2::HD_HOST, stream->headers);
const StringRef &path, int status) {
auto scheme = stream->header.scheme;
auto authority = stream->header.authority;
if (authority.empty()) {
authority = stream->header.host;
}
auto redirect_url = scheme->value;
redirect_url += "://";
redirect_url += authority->value;
redirect_url += path;
auto location = concat_string_ref(
stream->balloc, scheme, StringRef::from_lit("://"), authority, path);
auto headers = Headers{{"location", redirect_url}};
auto headers = HeaderRefs{{StringRef::from_lit("location"), location}};
auto sessions = hd->get_sessions();
auto status_page = sessions->get_server()->get_status_page(status);
hd->submit_response(status_page->status, stream->stream_id, headers, nullptr);
hd->submit_response(StringRef{status_page->status}, stream->stream_id,
headers, nullptr);
}
} // namespace
@@ -1221,39 +1208,49 @@ namespace {
void prepare_response(Stream *stream, Http2Handler *hd,
bool allow_push = true) {
int rv;
auto pathhdr =
http2::get_header(stream->hdidx, http2::HD__PATH, stream->headers);
if (!pathhdr) {
auto reqpath = stream->header.path;
if (reqpath.empty()) {
prepare_status_response(stream, hd, 405);
return;
}
auto reqpath = pathhdr->value;
auto ims =
get_header(stream->hdidx, http2::HD_IF_MODIFIED_SINCE, stream->headers);
auto ims = stream->header.ims;
time_t last_mod = 0;
bool last_mod_found = false;
if (ims) {
if (!ims.empty()) {
last_mod_found = true;
last_mod = util::parse_http_date(ims->value);
last_mod = util::parse_http_date(ims);
}
auto query_pos = reqpath.find("?");
std::string url;
if (query_pos != std::string::npos) {
StringRef raw_path, raw_query;
auto query_pos = std::find(std::begin(reqpath), std::end(reqpath), '?');
if (query_pos != std::end(reqpath)) {
// Do not response to this request to allow clients to test timeouts.
if (reqpath.find("nghttpd_do_not_respond_to_req=yes", query_pos) !=
std::string::npos) {
if (util::streq_l("nghttpd_do_not_respond_to_req=yes",
StringRef{query_pos, std::end(reqpath)})) {
return;
}
url = reqpath.substr(0, query_pos);
raw_path = StringRef{std::begin(reqpath), query_pos};
raw_query = StringRef{query_pos, std::end(reqpath)};
} else {
url = reqpath;
raw_path = reqpath;
}
auto sessions = hd->get_sessions();
url = util::percent_decode(std::begin(url), std::end(url));
if (!util::check_path(url)) {
StringRef path;
if (std::find(std::begin(raw_path), std::end(raw_path), '%') ==
std::end(raw_path)) {
path = raw_path;
} else {
path = util::percent_decode(stream->balloc, raw_path);
}
path = http2::path_join(stream->balloc, StringRef{}, StringRef{}, path,
StringRef{});
if (std::find(std::begin(path), std::end(path), '\\') != std::end(path)) {
if (stream->file_ent) {
sessions->release_fd(stream->file_ent);
stream->file_ent = nullptr;
@@ -1261,20 +1258,39 @@ void prepare_response(Stream *stream, Http2Handler *hd,
prepare_status_response(stream, hd, 404);
return;
}
auto push_itr = hd->get_config()->push.find(url);
if (allow_push && push_itr != std::end(hd->get_config()->push)) {
for (auto &push_path : (*push_itr).second) {
rv = hd->submit_push_promise(stream, push_path);
if (rv != 0) {
std::cerr << "nghttp2_submit_push_promise() returned error: "
<< nghttp2_strerror(rv) << std::endl;
if (!hd->get_config()->push.empty()) {
auto push_itr = hd->get_config()->push.find(path.str());
if (allow_push && push_itr != std::end(hd->get_config()->push)) {
for (auto &push_path : (*push_itr).second) {
rv = hd->submit_push_promise(stream, StringRef{push_path});
if (rv != 0) {
std::cerr << "nghttp2_submit_push_promise() returned error: "
<< nghttp2_strerror(rv) << std::endl;
}
}
}
}
std::string path = hd->get_config()->htdocs + url;
if (path[path.size() - 1] == '/') {
path += DEFAULT_HTML;
std::string file_path;
{
auto len = hd->get_config()->htdocs.size() + path.size();
auto trailing_slash = path[path.size() - 1] == '/';
if (trailing_slash) {
len += DEFAULT_HTML.size();
}
file_path.resize(len);
auto p = &file_path[0];
auto &htdocs = hd->get_config()->htdocs;
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);
}
}
if (stream->echo_upload) {
@@ -1283,10 +1299,10 @@ void prepare_response(Stream *stream, Http2Handler *hd,
return;
}
auto file_ent = sessions->get_cached_fd(path);
auto file_ent = sessions->get_cached_fd(file_path);
if (file_ent == nullptr) {
int file = open(path.c_str(), O_RDONLY | O_BINARY);
int file = open(file_path.c_str(), O_RDONLY | O_BINARY);
if (file == -1) {
prepare_status_response(stream, hd, 404);
@@ -1305,11 +1321,8 @@ void prepare_response(Stream *stream, Http2Handler *hd,
if (buf.st_mode & S_IFDIR) {
close(file);
if (query_pos == std::string::npos) {
reqpath += '/';
} else {
reqpath.insert(query_pos, "/");
}
auto reqpath = concat_string_ref(stream->balloc, raw_path,
StringRef::from_lit("/"), raw_query);
prepare_redirect_response(stream, hd, reqpath, 301);
@@ -1318,41 +1331,36 @@ void prepare_response(Stream *stream, Http2Handler *hd,
const std::string *content_type = nullptr;
if (path[path.size() - 1] == '/') {
static const std::string TEXT_HTML = "text/html";
content_type = &TEXT_HTML;
} else {
auto ext = path.c_str() + path.size() - 1;
for (; path.c_str() < ext && *ext != '.' && *ext != '/'; --ext)
;
if (*ext == '.') {
++ext;
auto ext = file_path.c_str() + file_path.size() - 1;
for (; file_path.c_str() < ext && *ext != '.' && *ext != '/'; --ext)
;
if (*ext == '.') {
++ext;
const auto &mime_types = hd->get_config()->mime_types;
auto content_type_itr = mime_types.find(ext);
if (content_type_itr != std::end(mime_types)) {
content_type = &(*content_type_itr).second;
}
const auto &mime_types = hd->get_config()->mime_types;
auto content_type_itr = mime_types.find(ext);
if (content_type_itr != std::end(mime_types)) {
content_type = &(*content_type_itr).second;
}
}
file_ent = sessions->cache_fd(
path, FileEntry(path, buf.st_size, buf.st_mtime, file, content_type,
ev_now(sessions->get_loop())));
file_path, FileEntry(file_path, buf.st_size, buf.st_mtime, file,
content_type, ev_now(sessions->get_loop())));
}
stream->file_ent = file_ent;
if (last_mod_found && file_ent->mtime <= last_mod) {
hd->submit_response("304", stream->stream_id, nullptr);
hd->submit_response(StringRef::from_lit("304"), stream->stream_id, nullptr);
return;
}
auto &method = http2::get_header(stream->hdidx, http2::HD__METHOD,
stream->headers)->value;
if (method == "HEAD") {
hd->submit_file_response("200", stream, file_ent->mtime, file_ent->length,
auto method = stream->header.method;
if (method == StringRef::from_lit("HEAD")) {
hd->submit_file_response(StringRef::from_lit("200"), stream,
file_ent->mtime, file_ent->length,
file_ent->content_type, nullptr);
return;
}
@@ -1364,21 +1372,24 @@ void prepare_response(Stream *stream, Http2Handler *hd,
data_prd.source.fd = file_ent->fd;
data_prd.read_callback = file_read_callback;
hd->submit_file_response("200", stream, file_ent->mtime, file_ent->length,
file_ent->content_type, &data_prd);
hd->submit_file_response(StringRef::from_lit("200"), stream, file_ent->mtime,
file_ent->length, file_ent->content_type, &data_prd);
}
} // namespace
namespace {
int on_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) {
int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
nghttp2_rcbuf *name, nghttp2_rcbuf *value,
uint8_t flags, void *user_data) {
auto hd = static_cast<Http2Handler *>(user_data);
auto namebuf = nghttp2_rcbuf_get_buf(name);
auto valuebuf = nghttp2_rcbuf_get_buf(value);
if (hd->get_config()->verbose) {
print_session_id(hd->session_id());
verbose_on_header_callback(session, frame, name, namelen, value, valuelen,
flags, user_data);
verbose_on_header_callback(session, frame, namebuf.base, namebuf.len,
valuebuf.base, valuebuf.len, flags, user_data);
}
if (frame->hd.type != NGHTTP2_HEADERS ||
frame->headers.cat != NGHTTP2_HCAT_REQUEST) {
@@ -1389,11 +1400,55 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
return 0;
}
auto token = http2::lookup_token(name, namelen);
if (stream->header_buffer_size + namebuf.len + valuebuf.len > 64_k) {
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
return 0;
}
stream->header_buffer_size += namebuf.len + valuebuf.len;
auto token = http2::lookup_token(namebuf.base, namebuf.len);
auto &header = stream->header;
switch (token) {
case http2::HD__METHOD:
header.method = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.method = value;
nghttp2_rcbuf_incref(value);
break;
case http2::HD__SCHEME:
header.scheme = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.scheme = value;
nghttp2_rcbuf_incref(value);
break;
case http2::HD__AUTHORITY:
header.authority = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.authority = value;
nghttp2_rcbuf_incref(value);
break;
case http2::HD_HOST:
header.host = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.host = value;
nghttp2_rcbuf_incref(value);
break;
case http2::HD__PATH:
header.path = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.path = value;
nghttp2_rcbuf_incref(value);
break;
case http2::HD_IF_MODIFIED_SINCE:
header.ims = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.ims = value;
nghttp2_rcbuf_incref(value);
break;
case http2::HD_EXPECT:
header.expect = StringRef{valuebuf.base, valuebuf.len};
header.rcbuf.expect = value;
nghttp2_rcbuf_incref(value);
break;
}
http2::index_header(stream->hdidx, token, stream->headers.size());
http2::add_header(stream->headers, name, namelen, value, valuelen,
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
return 0;
}
} // namespace
@@ -1453,17 +1508,16 @@ int hd_on_frame_recv_callback(nghttp2_session *session,
if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
auto expect100 =
http2::get_header(stream->hdidx, http2::HD_EXPECT, stream->headers);
auto expect100 = stream->header.expect;
if (expect100 && util::strieq_l("100-continue", expect100->value)) {
if (util::strieq_l("100-continue", expect100)) {
hd->submit_non_final_response("100", frame->hd.stream_id);
}
auto &method = http2::get_header(stream->hdidx, http2::HD__METHOD,
stream->headers)->value;
auto method = stream->header.method;
if (hd->get_config()->echo_upload &&
(method == "POST" || method == "PUT")) {
(method == StringRef::from_lit("POST") ||
method == StringRef::from_lit("PUT"))) {
if (!prepare_upload_temp_store(stream, hd)) {
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
return 0;
@@ -1530,6 +1584,15 @@ int hd_on_frame_send_callback(nghttp2_session *session,
break;
}
case NGHTTP2_SETTINGS: {
if (frame->hd.flags & NGHTTP2_FLAG_ACK) {
return 0;
}
hd->start_settings_timer();
break;
}
case NGHTTP2_PUSH_PROMISE: {
auto promised_stream_id = frame->push_promise.promised_stream_id;
auto promised_stream = hd->get_stream(promised_stream_id);
@@ -1673,13 +1736,16 @@ void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
if (config->verbose) {
nghttp2_session_callbacks_set_on_invalid_frame_recv_callback(
callbacks, verbose_on_invalid_frame_recv_callback);
nghttp2_session_callbacks_set_error_callback(callbacks,
verbose_error_callback);
}
nghttp2_session_callbacks_set_on_data_chunk_recv_callback(
callbacks, on_data_chunk_recv_callback);
nghttp2_session_callbacks_set_on_header_callback(callbacks,
on_header_callback);
nghttp2_session_callbacks_set_on_header_callback2(callbacks,
on_header_callback2);
nghttp2_session_callbacks_set_on_begin_headers_callback(
callbacks, on_begin_headers_callback);
@@ -1731,6 +1797,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)
@@ -1743,7 +1819,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);
@@ -1831,11 +1907,15 @@ void acceptcb(struct ev_loop *loop, ev_io *w, int revents) {
namespace {
FileEntry make_status_body(int status, uint16_t port) {
BlockAllocator balloc(1024, 1024);
auto status_string = http2::get_status_string(balloc, status);
std::string body;
body = "<html><head><title>";
body += http2::get_status_string(status);
body += status_string;
body += "</title></head><body><h1>";
body += http2::get_status_string(status);
body += status_string;
body += "</h1><hr><address>";
body += NGHTTPD_SERVER;
body += " at port ";

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