Compare commits

..

516 Commits

Author SHA1 Message Date
Tatsuhiro Tsujikawa
0880de4668 src: Rewrite DList
Rewrite DList, and now is named SList because it is Singly Linked
List.
2025-11-11 18:18:00 +09:00
Tatsuhiro Tsujikawa
e4454672f0 Merge pull request #2560 from nghttp2/integration-cope-with-errprocessdone
integration: Cope with os.ErrProcessDone
2025-11-11 18:16:01 +09:00
Tatsuhiro Tsujikawa
e15a5517c7 integration: Cope with os.ErrProcessDone 2025-11-11 17:46:54 +09:00
Tatsuhiro Tsujikawa
9b0044d051 Merge pull request #2557 from nghttp2/src-workaround-ossl3-perf-regression
src: Workaround performance regression since OpenSSL 3.0
2025-11-09 20:49:27 +09:00
Tatsuhiro Tsujikawa
e9e5e15bbf src: Workaround performance regression since OpenSSL 3.0 2025-11-09 19:12:00 +09:00
Tatsuhiro Tsujikawa
2c7ef6442d Merge pull request #2556 from nghttp2/nghttpx-save-quic-tx-buf-allocation
nghttpx: Avoid separate allocation for QUIC tx buffer
2025-11-09 18:16:07 +09:00
Tatsuhiro Tsujikawa
d3ecf78031 nghttpx: Avoid separate allocation for QUIC tx buffer 2025-11-09 17:47:06 +09:00
Tatsuhiro Tsujikawa
d01db47215 Merge pull request #2555 from nghttp2/src-adopt-get0-ec-key
src: Adopt EVP_PKEY_get0_EC_KEY
2025-11-09 17:32:49 +09:00
Tatsuhiro Tsujikawa
8a760d0726 src: Adopt EVP_PKEY_get0_EC_KEY 2025-11-09 17:00:48 +09:00
Tatsuhiro Tsujikawa
73bfe4bf21 Merge pull request #2554 from nghttp2/src-remove-defer-dtor-noexcept
src: Remove noexcept from ~Defer
2025-11-09 17:00:09 +09:00
Tatsuhiro Tsujikawa
6e5e9bceca src: Remove noexcept from ~Defer
Remove noexcept from ~Defer because it is noexcept by default.
2025-11-09 16:33:46 +09:00
Tatsuhiro Tsujikawa
0476f0efbc Merge pull request #2553 from nghttp2/src-remove-lambda-emplty-param-list
src: Remove empty parameter list from lambda
2025-11-09 16:30:15 +09:00
Tatsuhiro Tsujikawa
ca23a490c3 src: Remove empty parameter list from lambda 2025-11-09 14:45:12 +09:00
Tatsuhiro Tsujikawa
ee2a4b625b Merge pull request #2552 from nghttp2/src-rewrite-defer
src: Rewrite defer
2025-11-09 14:07:00 +09:00
Tatsuhiro Tsujikawa
cec4bf08a2 src: Rewrite defer 2025-11-09 13:45:18 +09:00
Tatsuhiro Tsujikawa
ebf4b7eaee Merge pull request #2550 from nghttp2/remove-unused-macros-and-enums
Remove unused macros and enums
2025-11-03 23:46:09 +09:00
Tatsuhiro Tsujikawa
0bf5b764fa Remove unused macros and enums 2025-11-03 22:45:18 +09:00
Tatsuhiro Tsujikawa
081eb29e9f Merge pull request #2549 from nghttp2/update-map
Port ngtcp2_map changes
2025-11-03 22:44:50 +09:00
Tatsuhiro Tsujikawa
ca81d89fe1 Port ngtcp2_map changes 2025-11-03 21:44:05 +09:00
Tatsuhiro Tsujikawa
450ed6afce Merge pull request #2548 from nghttp2/optimize-hpack-huffman
hpack: Optimize huffman decoding a bit
2025-11-03 19:20:20 +09:00
Tatsuhiro Tsujikawa
e72f4af5de hpack: Optimize huffman decoding a bit 2025-11-03 18:32:37 +09:00
Tatsuhiro Tsujikawa
3fa6a6349c Merge pull request #2546 from nghttp2/dependabot/github_actions/actions/upload-artifact-5
build(deps): bump actions/upload-artifact from 4 to 5
2025-10-28 08:33:37 +09:00
dependabot[bot]
6c0fd9400d build(deps): bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 15:21:33 +00:00
Tatsuhiro Tsujikawa
de81da7621 Merge pull request #2545 from nghttp2/simplify-format-hex
src: Simplify format_hex and format_upper_hex
2025-10-27 18:53:39 +09:00
Tatsuhiro Tsujikawa
8593b1f46c src: Simplify format_hex and format_upper_hex
Ignore -Wsign-conversion warning to avoid an issue that is very hard
to workaround.
2025-10-27 18:20:03 +09:00
Tatsuhiro Tsujikawa
0e9d325dee Bump package version 2025-10-25 17:34:56 +09:00
Tatsuhiro Tsujikawa
534b74b725 Update bash_completion 2025-10-25 17:13:35 +09:00
Tatsuhiro Tsujikawa
090c7fe26c Update manual pages 2025-10-25 17:13:19 +09:00
Tatsuhiro Tsujikawa
527cdebfee Bump package and library versions 2025-10-25 17:09:28 +09:00
Tatsuhiro Tsujikawa
a2667a6692 Merge pull request #2544 from nghttp2/bump-ngtcp2
Bump ngtcp2 and its dependencies
2025-10-22 21:25:39 +09:00
Tatsuhiro Tsujikawa
aedc348754 Bump ngtcp2 and its dependencies 2025-10-22 19:28:19 +09:00
Tatsuhiro Tsujikawa
19fbcf5238 Merge pull request #2543 from nghttp2/remove-ticket_keys-from-WorkerEvent
nghttpx: Remove unused ticket_keys from WorkerEvent
2025-10-14 21:06:32 +09:00
Tatsuhiro Tsujikawa
6fe99003df nghttpx: Remove unused ticket_keys from WorkerEvent 2025-10-14 20:33:21 +09:00
Tatsuhiro Tsujikawa
0139746d53 Merge pull request #2542 from nghttp2/optimize-quic-io
Optimize quic io
2025-10-14 19:35:06 +09:00
Tatsuhiro Tsujikawa
8dd0c86bde h2load: Prioritize QUIC UDP read event over the other events 2025-10-14 19:00:31 +09:00
Tatsuhiro Tsujikawa
5d4df477e8 h2load: Defer write to the next event loop for QUIC 2025-10-14 18:54:52 +09:00
Tatsuhiro Tsujikawa
2b355a338c nghttpx: Prioritize QUIC UDP read event over the other events 2025-10-14 18:54:44 +09:00
Tatsuhiro Tsujikawa
cfeec12a52 nghttpx: Defer write to the next event loop for QUIC 2025-10-14 18:48:38 +09:00
Tatsuhiro Tsujikawa
26e2d53536 Merge pull request #2541 from nghttp2/dependabot/go_modules/golang.org/x/net-0.46.0
build(deps): bump golang.org/x/net from 0.44.0 to 0.46.0
2025-10-14 08:35:08 +09:00
dependabot[bot]
d921c54209 build(deps): bump golang.org/x/net from 0.44.0 to 0.46.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.44.0 to 0.46.0.
- [Commits](https://github.com/golang/net/compare/v0.44.0...v0.46.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.46.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 14:36:11 +00:00
Tatsuhiro Tsujikawa
8f729331c1 Merge pull request #2540 from nghttp2/nghttpx-quic-recv-pktcnt
nghttpx: Increase number of UDP packets to read
2025-10-13 19:14:15 +09:00
Tatsuhiro Tsujikawa
a25dd12811 nghttpx: Increase number of UDP packets to read
It turns out that the limit of 10 packets per event loop is too small,
that prevents an endpoint from consuming ACKs and other control frames
(e.g., MAX_STREAM_DATA, MAX_STREAMS), resulting in the loss of
throughput.  This change increases maximum number of packets to read
to 64.
2025-10-13 18:35:42 +09:00
Tatsuhiro Tsujikawa
2f1565b0e2 Merge pull request #2538 from nghttp2/dependabot/go_modules/github.com/quic-go/quic-go-0.55.0
build(deps): bump github.com/quic-go/quic-go from 0.54.1 to 0.55.0
2025-10-07 00:49:31 +09:00
dependabot[bot]
389ae66d12 build(deps): bump github.com/quic-go/quic-go from 0.54.1 to 0.55.0
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.54.1 to 0.55.0.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.54.1...v0.55.0)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-version: 0.55.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 14:33:55 +00:00
Tatsuhiro Tsujikawa
a60e00c628 Merge pull request #2537 from nghttp2/dependabot/go_modules/github.com/quic-go/quic-go-0.54.1
build(deps): bump github.com/quic-go/quic-go from 0.54.0 to 0.54.1
2025-09-30 21:42:28 +09:00
dependabot[bot]
53ce088694 build(deps): bump github.com/quic-go/quic-go from 0.54.0 to 0.54.1
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.54.0 to 0.54.1.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.54.0...v0.54.1)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-version: 0.54.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-29 18:32:02 +00:00
Copilot
e802ccc02a Fix typos in documentation: "or3xx" → "or 3xx" and missing space after period (#2536)
Fix typos in documentation: "or3xx" → "or 3xx" and "itself.To" → "itself. To"

Co-authored-by: tatsuhiro-t <404610+tatsuhiro-t@users.noreply.github.com>
2025-09-29 23:30:52 +09:00
Tatsuhiro Tsujikawa
17428a5d09 Merge pull request #2535 from nghttp2/h2load-quic-window-bits-default
h2load: Set QUIC window-bits to 24 by default
2025-09-29 22:23:26 +09:00
Tatsuhiro Tsujikawa
83683742f1 h2load: Set QUIC window-bits to 24 by default
Reduce the default windows-bits for QUIC to 24 (16MiB).  The previous
default (1 << 30) is too large and causes too many packet losses on
very fast connection with super low RTT.
2025-09-29 21:04:48 +09:00
Tatsuhiro Tsujikawa
fa585e9182 Merge pull request #2534 from nghttp2/remove-redundant-semicolon
Remove redundant semicolon
2025-09-28 17:53:35 +09:00
Tatsuhiro Tsujikawa
7434a37016 Remove redundant semicolon 2025-09-28 12:08:38 +09:00
Tatsuhiro Tsujikawa
a2c47748f0 Merge pull request #2533 from nghttp2/iterators
src: Use std::ranges::begin and std::ranges::end consistently
2025-09-25 22:23:20 +09:00
Tatsuhiro Tsujikawa
1784c1c0d1 src: Use std::ranges::begin and std::ranges::end consistently 2025-09-25 21:39:50 +09:00
Tatsuhiro Tsujikawa
59a9534a2d Merge pull request #2532 from nghttp2/adopt-nghttp3_conn_read_stream2
src: Adopt nghttp3_conn_read_stream2
2025-09-25 20:31:28 +09:00
Tatsuhiro Tsujikawa
7fcbcd786e src: Adopt nghttp3_conn_read_stream2
Adopt nghttp3_conn_read_stream2 which requires nghttp3 v1.12.0.  To
pass the current timestamp, ngtcp2_conn_get_timestamp is used, which
requires ngtcp2 v1.16.0.
2025-09-25 18:56:05 +09:00
Tatsuhiro Tsujikawa
4e0738d24a Merge pull request #2531 from nghttp2/bump-ngtcp2
Bump ngtcp2 and its dependencies
2025-09-25 18:49:18 +09:00
Tatsuhiro Tsujikawa
1e0413f4a6 Bump ngtcp2 and its dependencies 2025-09-25 17:51:17 +09:00
Tatsuhiro Tsujikawa
06e7219d10 Merge pull request #2530 from nghttp2/examples-consistent-cond-macro-comments
examples: Consistent conditional macro comments
2025-09-24 23:35:58 +09:00
Tatsuhiro Tsujikawa
c06c069126 examples: Consistent conditional macro comments 2025-09-24 22:44:11 +09:00
Tatsuhiro Tsujikawa
d8ed2559f6 Merge pull request #2529 from nghttp2/sgi-daemonize
src: Move sgi _daemonize to util::daemonize
2025-09-24 21:52:41 +09:00
Tatsuhiro Tsujikawa
d829be3517 src: Move sgi _daemonize to util::daemonize
Move sgi _daemonize to util::daemonize so that we do not need to
handle sgi case in the multiple places.  Because we have no test
environment for sgi machine, the flags adjustment is omitted.  This is
not a problem now because we only call util::daemonize with zeros.
2025-09-24 21:26:49 +09:00
Tatsuhiro Tsujikawa
6aa9f6c72e Merge pull request #2528 from nghttp2/src-consistent-cond-macro-comments
src: Consistent conditional macro comments
2025-09-24 20:55:10 +09:00
Tatsuhiro Tsujikawa
4181fffc02 src: Consistent conditional macro comments 2025-09-24 20:29:56 +09:00
Tatsuhiro Tsujikawa
8f8eef40e8 Merge pull request #2527 from nghttp2/lib-consistent-cond-macro-comments
lib: Consistent conditional macro comments
2025-09-23 15:01:54 +09:00
Tatsuhiro Tsujikawa
3a95bf47f3 lib: Consistent conditional macro comments
Make conditional macro comments consistent.

- Repeat condition in closing #endif.
- Use #ifdef for a single macro.  Do not use #if defined(...) in this
  case.  Use defined(...) form when repeating condition in #endif.
- Apply De Morgan when negating conditions in #else.
2025-09-23 14:30:52 +09:00
Tatsuhiro Tsujikawa
c218d441ea Merge pull request #2526 from nghttp2/nullptr
src: Use nullptr in C++ code
2025-09-23 00:29:01 +09:00
Tatsuhiro Tsujikawa
1952b166e9 src: Use nullptr in C++ code 2025-09-22 22:47:05 +09:00
Tatsuhiro Tsujikawa
bcfb5d8305 Merge pull request #2525 from nghttp2/nghttpx-cert-type-constexpr
nghttpx: Define NGHTTP2_CERT_TYPE as constexpr
2025-09-22 21:45:04 +09:00
Tatsuhiro Tsujikawa
37fb82621c nghttpx: Define NGHTTP2_CERT_TYPE as constexpr 2025-09-22 20:55:09 +09:00
Tatsuhiro Tsujikawa
00bd05edcc Merge pull request #2524 from nghttp2/nghttpx-drop-tlsv1.1
nghttpx: Drop TLSv1.0 and TLSv1.1 support
2025-09-21 19:14:07 +09:00
Tatsuhiro Tsujikawa
45c67616b9 nghttpx: Drop TLSv1.0 and TLSv1.1 support
Nowadays, people always use TLSv1.3.  TLSv1.2 may be used for a
particular situation where TLSv1.3 is not available due to TLS stack
limitation.  The large companies started to drop TLSv1.1 and earlier
versions.  I do not feel keeping their support without a strong
reason, and I could not find any.
2025-09-21 18:49:15 +09:00
Tatsuhiro Tsujikawa
d94ce2a557 Merge pull request #2523 from nghttp2/nghttpx-consistent-servername-cb-behavior
nghttpx: Make servername_callback behavior consistent
2025-09-21 18:05:33 +09:00
Tatsuhiro Tsujikawa
8a5c731533 nghttpx: Make servername_callback behavior consistent
Make servername_callback behavior consistent across all supported TLS
stacks.  RFC 6066 does not provide any guidance or requirement when a
server must not acknowledge Server Name Indication.
2025-09-21 17:25:22 +09:00
Tatsuhiro Tsujikawa
6dfb3bdb8f Merge pull request #2522 from nghttp2/nghttpx-wolfssl-support-mldsa-cert-select
nghttpx: Support ML-DSA certificate selection with wolfSSL
2025-09-21 17:24:43 +09:00
Tatsuhiro Tsujikawa
43649c8004 nghttpx: Support ML-DSA certificate selection with wolfSSL 2025-09-21 16:45:32 +09:00
Tatsuhiro Tsujikawa
b35fa94ba5 Merge pull request #2521 from nghttp2/nghttpx-refactor-cert-type-detection
nghttpx: Select a certificate in a single pass
2025-09-21 15:08:32 +09:00
Tatsuhiro Tsujikawa
ee6565feb7 nghttpx: Select a certificate in a single pass
Refactored the certificate selection to select the certificate in a
single pass.  Cache the type of certificate to reduce the overhead.
2025-09-21 14:39:09 +09:00
Tatsuhiro Tsujikawa
7caa11f09e Merge pull request #2520 from nghttp2/nghttpx-cert-select-fast-path
nghttpx: Add the fast path when selecting a certificate
2025-09-20 19:38:42 +09:00
Tatsuhiro Tsujikawa
cb73b18a53 nghttpx: Add the fast path when selecting a certificate 2025-09-20 18:59:23 +09:00
Tatsuhiro Tsujikawa
4da70b34d1 Merge pull request #2519 from nghttp2/nghttpx-wolfssl-cert-select
nghttpx: Select certificate with wolfSSL
2025-09-20 18:58:50 +09:00
Tatsuhiro Tsujikawa
cd868f00b9 nghttpx: Select certificate with wolfSSL
This change adds the certificate selection with the supported
signature algorithms for wolfSSL in a way similar to BoringSSL.
wolfSSL does not support ML-DSA certificate as of this writing.
2025-09-20 18:29:50 +09:00
Tatsuhiro Tsujikawa
9fc31cfd16 Merge pull request #2518 from nghttp2/nghttpx-boringssl-cert-select
nghttpx: Select certificate with BoringSSL
2025-09-20 18:23:05 +09:00
Tatsuhiro Tsujikawa
e9f04ae0ad nghttpx: Select certificate with BoringSSL
Previously, the certificate selection in nghttpx depending on the
supported signature algorithm is dedicated to OpenSSL.  This change
brings the same capability to the BoringSSL build.  BoringSSL does not
support ML-DSA certificate as of this writing.
2025-09-20 17:55:25 +09:00
Tatsuhiro Tsujikawa
5e75f0ac81 Merge pull request #2517 from nghttp2/nghttpx-cert-select-pkey-base-id
nghttpx: Select ECDSA cert based on EVP_PKEY_base_id
2025-09-20 11:52:36 +09:00
Tatsuhiro Tsujikawa
8c3f077c5e nghttpx: Select ECDSA cert based on EVP_PKEY_base_id
We once refactored this with the shared curves, but it seems that it
is not entirely correct for this.  Perhaps, the usage of
X509_get_signature_nid was incorrect.
2025-09-20 11:09:55 +09:00
Tatsuhiro Tsujikawa
9cbe936a25 Merge pull request #2516 from nghttp2/nghttpx-ml-dsa-cert-select
nghttpx: Prefer ML-DSA certificate over ECDSA
2025-09-19 23:32:08 +09:00
Tatsuhiro Tsujikawa
b815972b03 nghttpx: Prefer ML-DSA certificate over ECDSA 2025-09-19 23:00:53 +09:00
Tatsuhiro Tsujikawa
59b6d0d1d9 Merge pull request #2515 from nghttp2/nghttpx-supported-groups
nghttpx: Add groups option
2025-09-19 20:59:27 +09:00
Tatsuhiro Tsujikawa
028eeeefeb nghttpx: Add groups option
The groups option takes the list of the supported groups.  This
deprecates ecdh-curves option.  If ecdh-curves option is used, it is
treated as if groups option is specified.
2025-09-19 19:29:04 +09:00
Tatsuhiro Tsujikawa
1feb3679fe Merge pull request #2514 from nghttp2/groups-list
Use SSL_CTX_set1_groups_list
2025-09-19 19:24:03 +09:00
Tatsuhiro Tsujikawa
b00d8da2e2 Use SSL_CTX_set1_groups_list
Replace SSL_CTX_set1_curves_list with SSL_CTX_set1_groups_list.
Remove the workaround for wolfSSL because the bug has been fixed.
2025-09-19 18:45:04 +09:00
Tatsuhiro Tsujikawa
9df3962d08 Merge pull request #2513 from nghttp2/nghttpd-supported-groups
nghttpd: Make the supported groups configurable
2025-09-19 18:43:24 +09:00
Tatsuhiro Tsujikawa
304bfcbb70 nghttpd: Make the supported groups configurable
Use the same default list of groups as h2load.
2025-09-19 18:06:21 +09:00
Tatsuhiro Tsujikawa
280845e52e Merge pull request #2511 from nghttp2/dependabot/go_modules/golang.org/x/net-0.44.0
build(deps): bump golang.org/x/net from 0.43.0 to 0.44.0
2025-09-16 00:05:32 +09:00
dependabot[bot]
bdc5d5a6d1 build(deps): bump golang.org/x/net from 0.43.0 to 0.44.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.43.0 to 0.44.0.
- [Commits](https://github.com/golang/net/compare/v0.43.0...v0.44.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-15 14:39:06 +00:00
Tatsuhiro Tsujikawa
c9ff3599de Bump library version due to the patch release 2025-09-15 20:52:45 +09:00
Tatsuhiro Tsujikawa
15912bf810 Merge pull request #2510 from nghttp2/remove-glitch-from-invalid-stream2
Remove session_update_glitch_ratelim called from deep inside the chain
2025-09-15 20:25:59 +09:00
Tatsuhiro Tsujikawa
9e65104b00 Remove session_update_glitch_ratelim called from deep inside the chain
Calling session_update_glitch_ratelim from
session_handle_invalid_stream2 makes handling error quite difficult
because it might be called in nested function calls.  It seems to me
that adding that is accidental.
2025-09-15 18:58:05 +09:00
Tatsuhiro Tsujikawa
80ecefebb5 Merge pull request #2509 from nghttp2/fix-assertion-failure
Fix assertion failure
2025-09-15 18:24:32 +09:00
Tatsuhiro Tsujikawa
43b4369fba Fix assertion failure
Fix assertion failure due to the missing check for NGHTTP2_IB_IGN_ALL
state.  Add tests.
2025-09-15 17:56:17 +09:00
Tatsuhiro Tsujikawa
89b30903cc Merge pull request #2508 from nghttp2/more-builtin-ext-glitch
Increase glitch counter for unexpected builtin extension frames
2025-09-13 11:44:03 +09:00
Tatsuhiro Tsujikawa
4904c736e1 Increase glitch counter for unexpected builtin extension frames 2025-09-13 11:16:19 +09:00
Tatsuhiro Tsujikawa
3b45a19423 Merge pull request #2507 from nghttp2/dependabot/github_actions/actions/stale-10
build(deps): bump actions/stale from 9 to 10
2025-09-09 19:00:47 +09:00
Tatsuhiro Tsujikawa
fbf4a7b750 Merge pull request #2506 from nghttp2/dependabot/github_actions/actions/setup-go-6
build(deps): bump actions/setup-go from 5 to 6
2025-09-09 17:47:18 +09:00
Tatsuhiro Tsujikawa
2a190bf5ee Merge pull request #2505 from nghttp2/dependabot/github_actions/actions/github-script-8
build(deps): bump actions/github-script from 7 to 8
2025-09-09 08:48:32 +09:00
dependabot[bot]
877a78186c build(deps): bump actions/stale from 9 to 10
Bumps [actions/stale](https://github.com/actions/stale) from 9 to 10.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v9...v10)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: '10'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 14:09:59 +00:00
dependabot[bot]
3d363ae478 build(deps): bump actions/setup-go from 5 to 6
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5 to 6.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 14:09:55 +00:00
dependabot[bot]
73141a7698 build(deps): bump actions/github-script from 7 to 8
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 8.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-08 14:09:51 +00:00
Tatsuhiro Tsujikawa
eacf3484ca Bump package version 2025-09-02 21:03:21 +09:00
Tatsuhiro Tsujikawa
45ac57609b Update manual pages 2025-09-02 19:20:04 +09:00
Tatsuhiro Tsujikawa
3190d030f7 Bump package and library versions 2025-09-02 19:20:04 +09:00
Tatsuhiro Tsujikawa
6979a07da6 Update AUTHORS 2025-09-02 19:20:04 +09:00
Tatsuhiro Tsujikawa
768e383662 Merge pull request #2503 from nghttp2/bump-ngtcp2
Bump ngtcp2 to v1.15.1
2025-09-02 19:19:24 +09:00
Tatsuhiro Tsujikawa
6fd2f9e027 Bump ngtcp2 to v1.15.1 2025-09-02 18:27:22 +09:00
Tatsuhiro Tsujikawa
54359802fa Merge pull request #2500 from bmarques1995/master
Added nghttp3's pattern targets
2025-09-02 18:23:38 +09:00
bmarques1995
bc57689f17 Added nghttp3's pattern targets 2025-09-01 00:15:48 -03:00
Tatsuhiro Tsujikawa
3ae75e840e Merge pull request #2499 from nghttp2/bump-libbpf
Bump libbpf to v1.6.2
2025-08-31 16:52:59 +09:00
Tatsuhiro Tsujikawa
7f79fbfa3e Bump libbpf to v1.6.2 2025-08-31 16:24:02 +09:00
Tatsuhiro Tsujikawa
4c10abe99e Merge pull request #2497 from nghttp2/test-lib-before-app
Test lib before building applications
2025-08-30 20:35:23 +09:00
Tatsuhiro Tsujikawa
2fed8b4945 Test lib before building applications 2025-08-30 19:29:06 +09:00
Tatsuhiro Tsujikawa
f266ee500d Merge pull request #2496 from nghttp2/quic-padding
src: Adopt NGTCP2_WRITE_STREAM_FLAG_PADDING
2025-08-30 19:17:14 +09:00
Tatsuhiro Tsujikawa
708912fe20 Merge pull request #2495 from nghttp2/constexpr-fixup
src: constexpr fixup
2025-08-30 19:11:59 +09:00
Tatsuhiro Tsujikawa
f90a801609 src: Adopt NGTCP2_WRITE_STREAM_FLAG_PADDING
Adopt NGTCP2_WRITE_STREAM_FLAG_PADDING to increase opportunities for
GSO.
2025-08-30 18:42:07 +09:00
Tatsuhiro Tsujikawa
107b7814fa src: constexpr fixup
- Use inline constexpr for constexpr variable with external linkage
- Use static constexpr where they should
- Use consteval for functions to generate a lookup table
2025-08-30 18:37:06 +09:00
Tatsuhiro Tsujikawa
bd70a1546c Merge pull request #2494 from nghttp2/src-designated-initializers
src: Adopt designated initializers
2025-08-26 19:05:25 +09:00
Tatsuhiro Tsujikawa
6e660ddc4b src: Adopt designated initializers 2025-08-26 18:12:09 +09:00
Tatsuhiro Tsujikawa
ea28e672ae Merge pull request #2493 from nghttp2/ngtcp2-callback-designated-init
src: Adopt designated initializers for ngtcp2_callbacks
2025-08-25 21:50:54 +09:00
Tatsuhiro Tsujikawa
fe8685e37f src: Adopt designated initializers for ngtcp2_callbacks 2025-08-25 21:01:08 +09:00
Tatsuhiro Tsujikawa
62c12b673b Merge pull request #2492 from nghttp2/ngtcp2-crypto-libressl
Adopt libngtcp2_crypto_libressl changes
2025-08-25 19:16:15 +09:00
Tatsuhiro Tsujikawa
9ba0b7fde0 Adopt libngtcp2_crypto_libressl changes 2025-08-25 18:26:10 +09:00
Tatsuhiro Tsujikawa
f9f5db5b6a Merge pull request #2491 from nghttp2/adopt-ngtcp2-nghttp3-features
Adopt ngtcp2 nghttp3 features
2025-08-24 21:20:57 +09:00
Tatsuhiro Tsujikawa
7ef3a91d9b src: Adopt ngtcp2_conn_write_aggregate_pkt, require ngtcp2 >= v1.15.0 2025-08-24 20:52:11 +09:00
Tatsuhiro Tsujikawa
e435050378 src: Specify nghttp3_rand callback, require nghttp3 >= v1.11.0 2025-08-24 19:10:49 +09:00
Tatsuhiro Tsujikawa
8f5b450237 Merge pull request #2490 from nghttp2/bump-ngtcp2
Bump ngtcp2 and its dependencies
2025-08-24 12:04:15 +09:00
Tatsuhiro Tsujikawa
5f5fdc780f Bump ngtcp2 and its dependencies 2025-08-24 11:16:06 +09:00
Tatsuhiro Tsujikawa
fd48570e7f Merge pull request #2489 from nghttp2/fix-test-assertions
tests: Swap the positions of expected and actual values
2025-08-24 11:15:35 +09:00
Tatsuhiro Tsujikawa
daa4260f61 tests: Swap the positions of expected and actual values 2025-08-24 10:44:30 +09:00
Tatsuhiro Tsujikawa
451853f39b Merge pull request #2488 from nghttp2/configurable-glitch-counter
Make glitch counter configurable
2025-08-24 10:43:54 +09:00
Tatsuhiro Tsujikawa
dfab53ef65 Make glitch counter configurable 2025-08-23 19:49:14 +09:00
Tatsuhiro Tsujikawa
5d4d517535 Merge pull request #2487 from nghttp2/gha-bump-clang
GHA: Bump clang to 19
2025-08-23 18:59:00 +09:00
Tatsuhiro Tsujikawa
c36b8ee88a GHA: Bump clang to 19 2025-08-23 18:21:56 +09:00
Tatsuhiro Tsujikawa
2e84de0be9 Merge pull request #2486 from nghttp2/bump-clang-format
Bump clang-format to 19
2025-08-23 18:21:03 +09:00
Tatsuhiro Tsujikawa
e18beaa3bd Bump clang-format to 19 2025-08-23 17:41:35 +09:00
Tatsuhiro Tsujikawa
4890cb0fb8 Merge pull request #2485 from nghttp2/glitch-counter
Add "glitch" counter
2025-08-23 17:38:37 +09:00
Tatsuhiro Tsujikawa
06fb688be2 Add "glitch" counter
Any suspicious activity such as DATA frames to a stream which does not
exist are counted to so called "glitch" counter.  If it increases more
than the configured rate, GOAWAY is sent and the connection is closed.
2025-08-23 17:04:27 +09:00
Tatsuhiro Tsujikawa
56d5406bce Merge pull request #2483 from nghttp2/dependabot/go_modules/golang.org/x/net-0.43.0
Bump golang.org/x/net from 0.42.0 to 0.43.0
2025-08-19 18:40:59 +09:00
Tatsuhiro Tsujikawa
0196b2cc03 Merge pull request #2482 from nghttp2/dependabot/github_actions/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-08-19 18:21:13 +09:00
dependabot[bot]
de7da99453 Bump golang.org/x/net from 0.42.0 to 0.43.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.42.0 to 0.43.0.
- [Commits](https://github.com/golang/net/compare/v0.42.0...v0.43.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 21:33:06 +00:00
dependabot[bot]
40124de400 Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 21:08:56 +00:00
Tatsuhiro Tsujikawa
6d7f80ed7f Merge pull request #2481 from nghttp2/fix-doc
Update doc
2025-08-18 00:24:32 +09:00
Tatsuhiro Tsujikawa
7bf98f2729 Update doc 2025-08-17 21:39:52 +09:00
Tatsuhiro Tsujikawa
e434b74e50 Merge pull request #2480 from nghttp2/robust-error-handling
Make error handling robust
2025-08-17 18:12:44 +09:00
Tatsuhiro Tsujikawa
7784fa979d Make error handling robust
Stream errors are now promoted to connection errors.  This means that
an event that previously just resets a single stream now closes a
connection entirely.  The promoted errors are mostly implementation
errors.  Some involve HTTP fields, but they are already treated stream
error.  People who care about that should have already raised any
issues.  We do not have any outstanding related issues now, so it
seems OK to treat it as connection error.

We have some contradictory specifications around
nghttp2_on_invalid_header and nghttp2_on_invalid_header2 callbacks.
nghttp2_on_invalid_header says that if it is omitted, a stream is
reset.  Meanwhile, nghttp2_on_invalid_header2 says that if it is
omitted, invalid field is silently ignored.  In actual implementation,
if both omitted, we treat it as stream error.  In practice, it is
often required not to bail out if invalid header is received.  In this
change, if both callbacks are omitted, invalid field is silently
ignored as the documentation of nghttp2_on_invalid_header2 says.  The
connection error promotion is applied here as well.  So if invalid
field is received, and callback returns
NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE, it is treated as connection
error.
2025-08-17 16:50:49 +09:00
Tatsuhiro Tsujikawa
8391ae7a57 Merge pull request #2478 from nghttp2/fix-gha-android-build
GHA: Run android workflow on branches event
2025-08-09 18:36:27 +09:00
Tatsuhiro Tsujikawa
d63d2568b7 GHA: Run android workflow on branches event 2025-08-09 17:00:29 +09:00
Tatsuhiro Tsujikawa
d8d94e7a69 Merge pull request #2475 from nghttp2/rewrite-is_hex_string
src: Rewrite util::is_hex_string
2025-07-29 18:06:51 +09:00
Tatsuhiro Tsujikawa
ef3b25e152 src: Rewrite util::is_hex_string 2025-07-29 17:36:46 +09:00
Tatsuhiro Tsujikawa
52ae8b7d9f Merge pull request #2474 from nghttp2/mem-free
lib: Use nghttp2_mem_free
2025-07-25 18:59:14 +09:00
Tatsuhiro Tsujikawa
d204cd0880 lib: Use nghttp2_mem_free 2025-07-25 18:30:51 +09:00
Tatsuhiro Tsujikawa
32a5793b02 Merge pull request #2473 from geoffhill/patch-1
Use allocator-aware free in failure path
2025-07-25 18:27:41 +09:00
Tatsuhiro Tsujikawa
b81979f35b Merge pull request #2472 from nghttp2/dependabot/go_modules/github.com/quic-go/quic-go-0.54.0
Bump github.com/quic-go/quic-go from 0.53.0 to 0.54.0
2025-07-24 20:51:16 +09:00
Geoff Hill
808271a5a9 Use allocator-aware free in failure path
This change avoids free(3) from stdlib in favor of nghttp2_mem_free() for freeing a buffer in an error path. The buffer is allocated with nghttp2_mem_malloc().
2025-07-23 10:41:05 -07:00
dependabot[bot]
4bfd528d44 Bump github.com/quic-go/quic-go from 0.53.0 to 0.54.0
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.53.0 to 0.54.0.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.53.0...v0.54.0)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-version: 0.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-21 16:57:05 +00:00
Tatsuhiro Tsujikawa
2fefe482bf Merge pull request #2471 from nghttp2/dependabot/go_modules/golang.org/x/net-0.42.0
Bump golang.org/x/net from 0.41.0 to 0.42.0
2025-07-16 18:39:22 +09:00
dependabot[bot]
1c2ba03f94 Bump golang.org/x/net from 0.41.0 to 0.42.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.41.0 to 0.42.0.
- [Commits](https://github.com/golang/net/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-14 17:26:26 +00:00
Tatsuhiro Tsujikawa
5edfa62c7b Merge pull request #2468 from nghttp2/dependabot/go_modules/github.com/quic-go/quic-go-0.53.0
Bump github.com/quic-go/quic-go from 0.52.0 to 0.53.0
2025-07-01 21:06:26 +09:00
Tatsuhiro Tsujikawa
efad89d9d2 Merge pull request #2469 from nghttp2/map-seed
Map seed
2025-07-01 20:27:22 +09:00
Tatsuhiro Tsujikawa
a8dfe825d0 src: Specify nghttp2_rand_callback 2025-07-01 19:25:33 +09:00
Tatsuhiro Tsujikawa
a9b0230e57 Add nghttp2_rand_callback
Add nghttp2_rand_callback.  Seed nghttp2_map with the unpredictable
value from the callback.
2025-07-01 19:25:33 +09:00
Tatsuhiro Tsujikawa
01b16f64f4 Port ngtcp2_map changes 2025-07-01 18:25:24 +09:00
dependabot[bot]
b41ca012b4 Bump github.com/quic-go/quic-go from 0.52.0 to 0.53.0
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.52.0 to 0.53.0.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.52.0...v0.53.0)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-version: 0.53.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-30 17:49:27 +00:00
Tatsuhiro Tsujikawa
d2b58bd0cd Merge pull request #2467 from nghttp2/pmtudisc-probe
src: Adopt IP_PMTUDISC_PROBE
2025-06-29 18:03:23 +09:00
Tatsuhiro Tsujikawa
fc43fc1805 src: Adopt IP_PMTUDISC_PROBE
It seems that IP_PMTUDISC_PROBE works in some advertent situations.
2025-06-29 17:37:55 +09:00
Tatsuhiro Tsujikawa
1616d9ef05 Merge pull request #2465 from nghttp2/ngtcp2-map-port
Port ngtcp2 map changes
2025-06-21 19:01:20 +09:00
Tatsuhiro Tsujikawa
05b29df6eb Port ngtcp2 map changes 2025-06-21 18:34:09 +09:00
Tatsuhiro Tsujikawa
9f0c59d6dd Merge pull request #2463 from nghttp2/android-docker-avoid-tag-event
Do not trigger android workflow on tag event
2025-06-17 21:58:51 +09:00
Tatsuhiro Tsujikawa
af02195b60 Do not trigger android workflow on tag event 2025-06-17 21:35:43 +09:00
Tatsuhiro Tsujikawa
0f46173c2d Bump package version 2025-06-17 19:18:12 +09:00
Tatsuhiro Tsujikawa
ac22e0efe3 Update manual pages 2025-06-17 18:56:00 +09:00
Tatsuhiro Tsujikawa
031ae82552 Bump package and library versions 2025-06-17 18:52:43 +09:00
Tatsuhiro Tsujikawa
6b3e58127d Update AUTHORS 2025-06-17 18:46:32 +09:00
Tatsuhiro Tsujikawa
5e576bda7d Merge pull request #2462 from nghttp2/nghttpx-preserve-weightgroup-cycle
nghttpx: Preserve WeightGroup cycles between backend replaces
2025-06-16 21:28:02 +09:00
Tatsuhiro Tsujikawa
6039258f01 nghttpx: Preserve WeightGroup cycles between backend replaces
Preserve cycle in WeightGroups if name and weight of WeightGroups
under a single pattern do not change after replacing backends via
backendconfig API call.  It does not matter if backend addresses under
those groups are changed.
2025-06-16 20:59:10 +09:00
Tatsuhiro Tsujikawa
121e401166 Merge pull request #2460 from nghttp2/dependabot/go_modules/golang.org/x/net-0.41.0
Bump golang.org/x/net from 0.40.0 to 0.41.0
2025-06-10 08:25:19 +09:00
dependabot[bot]
67ab8145c7 Bump golang.org/x/net from 0.40.0 to 0.41.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.40.0 to 0.41.0.
- [Commits](https://github.com/golang/net/compare/v0.40.0...v0.41.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 14:45:27 +00:00
Tatsuhiro Tsujikawa
68b663eaba Merge pull request #2459 from nghttp2/conf-file-check-error
nghttpx: Check error when reading the configuration file
2025-06-09 21:17:43 +09:00
Tatsuhiro Tsujikawa
c9f3166c4d nghttpx: Check error when reading the configuration file 2025-06-09 20:33:42 +09:00
Tatsuhiro Tsujikawa
eafb876a5b Merge pull request #2458 from nghttp2/quic-secret-getline
nghttpx: Use std::getline to read QUIC secrets
2025-06-09 20:32:31 +09:00
Tatsuhiro Tsujikawa
c8790efadf nghttpx: Use std::getline to read QUIC secrets 2025-06-09 19:42:02 +09:00
Tatsuhiro Tsujikawa
fbcf341878 Merge pull request #2457 from nghttp2/thread-local
Remove the availability check for thread_local
2025-06-09 19:24:52 +09:00
Tatsuhiro Tsujikawa
1adb1d9bb7 Remove the availability check for thread_local 2025-06-09 18:51:39 +09:00
Tatsuhiro Tsujikawa
c9bf55f125 Merge pull request #2455 from starrify/nghttpd-support-sslkeylogfile
nghttpd: Support SSLKEYLOGFILE
2025-06-09 18:51:02 +09:00
Tatsuhiro Tsujikawa
2b07607cac Merge pull request #2456 from nghttp2/as-string-view
Use as_string_view to simplify the construction
2025-06-09 18:29:23 +09:00
Peng-Yu Chen
556fa9f781 nghttpd: Support SSLKEYLOGFILE 2025-06-09 10:18:05 +01:00
Tatsuhiro Tsujikawa
827da803f6 Use as_string_view to simplify the construction 2025-06-09 18:04:20 +09:00
Tatsuhiro Tsujikawa
b1496253d0 Merge pull request #2454 from nghttp2/replace-stringref-with-stringview
Replace stringref with stringview
2025-06-08 22:27:07 +09:00
Tatsuhiro Tsujikawa
811608bef8 Update script 2025-06-08 21:36:23 +09:00
Tatsuhiro Tsujikawa
db304adf70 Remove unnecessary casts and some adjustments 2025-06-08 21:19:59 +09:00
Tatsuhiro Tsujikawa
ef94a3be9a Replace StringRef with std::string_view 2025-06-08 21:00:56 +09:00
Tatsuhiro Tsujikawa
2f283177f7 Merge pull request #2453 from nghttp2/src-refactor
Src refactor
2025-06-08 18:00:53 +09:00
Tatsuhiro Tsujikawa
b13eb2c13f util::format_duration: Use std::string_view for unit 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
9707f9bfbe util::show_candidates: Use std::string_view for cands 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
53785c2434 tls::get_tls_protocol: Return std::string_view 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
4f450d0f5a Router::add_node: Receive pattern as StringRef 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
86a36fec8a RNode: Store s as std::string_view 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
5ccd54734a Rewrite http::colorize_headers 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
ecf42e76a8 FieldStore: Pass StringRef rather than const char * and its length 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
c72e5f116d Remove unused http2::dump_nv overloads 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
d79fd53b67 http2::get_header: Take std::string_view 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
0bfdc8682d Remove http2::get_header overloads that take HeaderIndex 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
af5f768a52 Remove unused http2::copy_url_component 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
9a51528aab Remove unused http2::lws 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
e403873ac8 Refactor levenshtein to accept std::string_view 2025-06-08 17:38:00 +09:00
Tatsuhiro Tsujikawa
e004f75e77 Merge pull request #2452 from nghttp2/nghttpx-quic-read-rate
nghttpx: Implement rate limiting for incoming QUIC traffic
2025-06-08 12:45:58 +09:00
Tatsuhiro Tsujikawa
55e02bdb70 nghttpx: Implement rate limiting for incoming QUIC traffic 2025-06-08 12:06:58 +09:00
Tatsuhiro Tsujikawa
d28170aaeb Merge pull request #2451 from nghttp2/refactor-siphash-keygen
src: Refactor siphash key generation
2025-06-06 20:37:19 +09:00
Tatsuhiro Tsujikawa
d2e9479da4 src: Refactor siphash key generation 2025-06-06 19:32:19 +09:00
Tatsuhiro Tsujikawa
e0c815249d Merge pull request #2450 from nghttp2/bump-libbpf
Bump libbpf to v1.5.1
2025-06-04 20:39:58 +09:00
Tatsuhiro Tsujikawa
f5053fb2ad Bump libbpf to v1.5.1 2025-06-04 18:57:06 +09:00
Tatsuhiro Tsujikawa
53ca70ae70 Merge pull request #2449 from nghttp2/bump-llhttp
Bump llhttp to v9.3.0
2025-06-04 18:40:44 +09:00
Tatsuhiro Tsujikawa
eea717d21b Bump llhttp to v9.3.0 2025-06-04 18:18:57 +09:00
Tatsuhiro Tsujikawa
2e86b1bd77 Merge pull request #2448 from nghttp2/bump-ngtcp2
Bump ngtcp2 and its dependencies
2025-06-03 22:55:08 +09:00
Tatsuhiro Tsujikawa
8b638f219c Bump ngtcp2 and its dependencies 2025-06-03 21:46:00 +09:00
Tatsuhiro Tsujikawa
91340d59bb Merge pull request #2447 from nghttp2/app-cleanup-part2
App cleanup part2
2025-05-31 17:11:43 +09:00
Tatsuhiro Tsujikawa
3eafe7e630 Remove unnecessary cast 2025-05-31 16:34:30 +09:00
Tatsuhiro Tsujikawa
923014d163 Remove noexcept 2025-05-31 16:34:30 +09:00
Tatsuhiro Tsujikawa
4fe2aab723 Might be easier to read 2025-05-31 16:34:30 +09:00
Tatsuhiro Tsujikawa
65c9142cd1 Use is_digit 2025-05-31 16:34:30 +09:00
Tatsuhiro Tsujikawa
d159ff9baa Merge pull request #2446 from nghttp2/app-cleanup
App cleanup
2025-05-31 10:47:00 +09:00
Tatsuhiro Tsujikawa
4ef64cab52 Use std::unordered_map::contains 2025-05-31 09:56:34 +09:00
Tatsuhiro Tsujikawa
a7ae4f80ab Remove unused bio_method 2025-05-31 09:56:34 +09:00
Tatsuhiro Tsujikawa
075788af7c Remove unnecessary <map> include 2025-05-31 09:56:34 +09:00
Tatsuhiro Tsujikawa
24d4afb967 Use std::chrono::floor 2025-05-31 09:56:34 +09:00
Tatsuhiro Tsujikawa
a4d961eb17 Merge pull request #2445 from nghttp2/unordered_set
Use std::unordered_set if applicable
2025-05-31 09:56:04 +09:00
Tatsuhiro Tsujikawa
1d8abe7d1c Use std::unordered_set if applicable 2025-05-31 09:30:27 +09:00
Tatsuhiro Tsujikawa
6ad6c61af2 Merge pull request #2444 from trofi/gcc-16-include-fix
src/template.h: add missing `cstdint` include
2025-05-31 09:17:40 +09:00
Sergei Trofimovich
1440e88347 src/template.h: add missing cstdint include
Without the change build against upcoming gcc-16 fails as:

    template.h:457:9: error: ISO C++ forbids declaration of 'type name' with no type [-fpermissive]
      457 |   const uint8_t, N == std::dynamic_extent ? std::dynamic_extent : N * sizeof(T)>
          |         ^~~~~~~
2025-05-30 21:20:51 +01:00
Tatsuhiro Tsujikawa
4e34e45be6 Merge pull request #2443 from nghttp2/unordered_map
Unordered map
2025-05-30 23:22:22 +09:00
Tatsuhiro Tsujikawa
3ebd7f9966 Remove std::map::emplace detection 2025-05-30 22:55:45 +09:00
Tatsuhiro Tsujikawa
ef7b349928 Use std::unordered_map if applicable 2025-05-30 22:55:45 +09:00
Tatsuhiro Tsujikawa
abdd0ea313 Merge pull request #2442 from nghttp2/remove-const_cast-sockaddr
Remove unnecessary const_cast<sockaddr *>
2025-05-30 22:54:44 +09:00
Tatsuhiro Tsujikawa
7eb7740e01 Remove unnecessary const_cast<sockaddr *> 2025-05-30 21:57:38 +09:00
Tatsuhiro Tsujikawa
bbc091d762 Merge pull request #2441 from nghttp2/socklen_t
Reduce cast to socklen_t
2025-05-30 21:32:16 +09:00
Tatsuhiro Tsujikawa
4fa4e5fdad Reduce cast to socklen_t 2025-05-30 20:50:48 +09:00
Tatsuhiro Tsujikawa
06b758de98 Merge pull request #2440 from nghttp2/cxx-wconversion
Cxx wconversion
2025-05-30 20:23:58 +09:00
Tatsuhiro Tsujikawa
c98c67ae73 Bump neverbleed 2025-05-30 19:41:35 +09:00
Tatsuhiro Tsujikawa
32e26bcf68 Add -Wconversion flag to C++ compiler 2025-05-30 19:41:35 +09:00
Tatsuhiro Tsujikawa
b420749135 Merge pull request #2439 from nghttp2/remove-NGHTTP2_MAX_UINT64_DIGITS
Remove NGHTTP2_MAX_UINT64_DIGITS
2025-05-28 01:07:03 +09:00
Tatsuhiro Tsujikawa
47e886b5a0 Remove NGHTTP2_MAX_UINT64_DIGITS
Remove NGHTTP2_MAX_UINT64_DIGITS.  Rely on
std::numeric_limits<T>::digits10 instead.
2025-05-27 23:13:42 +09:00
Tatsuhiro Tsujikawa
cf5b34a12e Merge pull request #2438 from nghttp2/nghttpx-log-without-snprintf
nghttpx: Write log without snprintf
2025-05-27 23:13:09 +09:00
Tatsuhiro Tsujikawa
91328046dd nghttpx: Write log without snprintf
Write log without snprintf.  For syslog, printf-like format is
unavoidable.  Construct a message as much as possible, and then pass
the entire log message.
2025-05-27 22:49:53 +09:00
Tatsuhiro Tsujikawa
d34515372a Merge pull request #2437 from nghttp2/nghttpx-fix-integral-logging
nghttpx: Fix integral logging is always done in 64 bits integer
2025-05-27 21:44:34 +09:00
Tatsuhiro Tsujikawa
2a79151248 nghttpx: Fix integral logging is always done in 64 bits integer 2025-05-27 21:22:54 +09:00
Tatsuhiro Tsujikawa
b07227a169 Merge pull request #2436 from nghttp2/bump-quic-go
Bump quic-go to v0.52.0
2025-05-27 20:30:54 +09:00
Tatsuhiro Tsujikawa
1213986096 Bump quic-go to v0.52.0 2025-05-27 19:40:49 +09:00
Tatsuhiro Tsujikawa
fe0f31a85c Merge pull request #2435 from nghttp2/refactor-capitalize
Refactor http2::capitalize
2025-05-27 19:40:15 +09:00
Tatsuhiro Tsujikawa
550000f160 Refactor http2::capitalize 2025-05-27 19:20:19 +09:00
Tatsuhiro Tsujikawa
36a9d3620e Merge pull request #2434 from nghttp2/revert-2409-no-capitalize-http-field-name
Revert "nghttpx: No need to capitalize HTTP/1.1 field name"
2025-05-27 18:48:16 +09:00
Tatsuhiro Tsujikawa
e6463c00f7 Revert "nghttpx: No need to capitalize HTTP/1.1 field name"
This reverts commit e0089070f5.
2025-05-27 18:23:39 +09:00
Tatsuhiro Tsujikawa
c827d07c10 Merge pull request #2432 from nghttp2/fix-logger-format_hex
nghttpx: Fix logger does not show address correctly
2025-05-27 00:00:13 +09:00
Tatsuhiro Tsujikawa
f8e31cf478 nghttpx: Fix logger does not show address correctly 2025-05-26 23:18:00 +09:00
Tatsuhiro Tsujikawa
963cbb4cce Merge pull request #2431 from nghttp2/avoid-int-overflow
Avoid integer overflow in table generation
2025-05-26 19:26:18 +09:00
Tatsuhiro Tsujikawa
a1e557a725 Avoid integer overflow in table generation 2025-05-26 17:48:55 +09:00
Tatsuhiro Tsujikawa
a6c036e719 Merge pull request #2430 from nghttp2/remove-shrpx_exec
Remove unused shrpx_exec
2025-05-25 23:15:48 +09:00
Tatsuhiro Tsujikawa
80627afe00 Remove unused shrpx_exec 2025-05-25 22:46:35 +09:00
Tatsuhiro Tsujikawa
052a3fafa9 Merge pull request #2429 from nghttp2/rewrite-to_token68
Rewrite util::to_token68
2025-05-25 22:33:07 +09:00
Tatsuhiro Tsujikawa
5535d099f6 Rewrite util::to_token68 2025-05-25 19:41:01 +09:00
Tatsuhiro Tsujikawa
23e555662e Merge pull request #2428 from nghttp2/h2load-ranges
h2load: Adopt std::ranges
2025-05-25 19:15:27 +09:00
Tatsuhiro Tsujikawa
bbe10abe2e h2load: Adopt std::ranges 2025-05-25 18:08:01 +09:00
Tatsuhiro Tsujikawa
a86e70d278 Merge pull request #2427 from nghttp2/nghttpd-ranges
nghttpd: Adopt std::ranges
2025-05-25 18:07:18 +09:00
Tatsuhiro Tsujikawa
ba484c41a9 nghttpd: Adopt std::ranges 2025-05-25 17:38:45 +09:00
Tatsuhiro Tsujikawa
413674f3ab Merge pull request #2426 from nghttp2/nghttp-ranges
nghttp: Adopt std::ranges
2025-05-25 17:38:17 +09:00
Tatsuhiro Tsujikawa
e907529aaf nghttp: Adopt std::ranges 2025-05-25 16:53:20 +09:00
Tatsuhiro Tsujikawa
05f517b118 Merge pull request #2425 from nghttp2/remove-memchunks-append-return-value
Remove Memchunks::append return value
2025-05-25 11:51:45 +09:00
Tatsuhiro Tsujikawa
d99de27967 Remove Memchunks::append return value
Make Memchunks::append return nothing because it always stores
everything given.
2025-05-25 11:17:15 +09:00
Tatsuhiro Tsujikawa
ceeb73fbfb Merge pull request #2424 from nghttp2/safer-memchunks-reserve-append
Safer way to write data directly to Memchunks buffer
2025-05-25 11:16:16 +09:00
Tatsuhiro Tsujikawa
f336a3dfde Safer way to write data directly to Memchunks buffer 2025-05-25 10:50:08 +09:00
Tatsuhiro Tsujikawa
196e533430 Merge pull request #2423 from nghttp2/update-android-dockerfile
Update android dockerfile
2025-05-24 22:18:45 +09:00
Tatsuhiro Tsujikawa
eefe3759f1 Use ARG instead of ENV because they are build time variables 2025-05-24 21:36:19 +09:00
Tatsuhiro Tsujikawa
fd18019e84 Fix deprecated warning about ENV syntax 2025-05-24 21:30:20 +09:00
Tatsuhiro Tsujikawa
8dfd1c3f95 Migrate deprecated MAINTAINER instruction to LABEL 2025-05-24 21:02:44 +09:00
Tatsuhiro Tsujikawa
d448ee9fa5 Bump NDK version to r27c 2025-05-24 20:56:00 +09:00
Tatsuhiro Tsujikawa
0f6f47ebc9 Dockerfile.android: Bump ubuntu to 24.04 2025-05-24 20:56:00 +09:00
Tatsuhiro Tsujikawa
03c416a2ca Merge pull request #2422 from nghttp2/bump-mruby
Bump mruby to 3.4.0+
2025-05-24 20:50:42 +09:00
Tatsuhiro Tsujikawa
2ac38479f5 Bump mruby to 3.4.0+
3.4.0 breaks out-of-tree build.  Fast forward to the commit that fixes
it.
2025-05-24 19:09:13 +09:00
Tatsuhiro Tsujikawa
a4e447bd84 Merge pull request #2421 from nghttp2/fix-dockerfile
docker: Fix build failure
2025-05-24 19:08:43 +09:00
Tatsuhiro Tsujikawa
bf292cc752 docker: Fix build failure 2025-05-24 18:41:28 +09:00
Tatsuhiro Tsujikawa
3ed14f2b38 Merge pull request #2420 from nghttp2/nghttpx-ranges-part4
Nghttpx ranges part4
2025-05-24 18:40:33 +09:00
Tatsuhiro Tsujikawa
c3574b711d Adopt std::ranges for tests 2025-05-24 18:14:49 +09:00
Tatsuhiro Tsujikawa
8d9c80a285 nghttpx: Fix std::ranges adoption remnants 2025-05-24 18:14:49 +09:00
Tatsuhiro Tsujikawa
34b18758cb Merge pull request #2418 from nghttp2/utos-require-unsigned
Make util::utos require std::unsigned_integral
2025-05-24 17:58:49 +09:00
Tatsuhiro Tsujikawa
89fb8dd503 Make util::utos require std::unsigned_integral 2025-05-24 17:34:23 +09:00
Tatsuhiro Tsujikawa
7634e06611 Merge pull request #2417 from nghttp2/remove-draft-h2-alpn-support
Remove draft h2 alpn support
2025-05-24 16:58:18 +09:00
Tatsuhiro Tsujikawa
9278383c1a Remove util::get_default_alpn 2025-05-24 16:36:20 +09:00
Tatsuhiro Tsujikawa
86ba78b461 Remove draft h2 ALPN support 2025-05-24 16:36:20 +09:00
Tatsuhiro Tsujikawa
82320337ea Merge pull request #2416 from nghttp2/memchunk-reserve-test
Add test for Memchunks::reserve
2025-05-24 16:26:28 +09:00
Tatsuhiro Tsujikawa
3b7cabf15a Add test for Memchunks::reserve 2025-05-24 15:56:57 +09:00
Tatsuhiro Tsujikawa
63aa83ac42 Merge pull request #2415 from nghttp2/remove-memchunk-append-char-array
Remove Memchunks::append(const char (&)[N])
2025-05-24 15:56:30 +09:00
Tatsuhiro Tsujikawa
9a09d9602b Remove Memchunks::append(const char (&)[N]) 2025-05-24 15:18:37 +09:00
Tatsuhiro Tsujikawa
9ac5a1a773 Merge pull request #2414 from nghttp2/refactor-to_numeric_addr
Refactor util::to_numeric_addr
2025-05-24 15:18:13 +09:00
Tatsuhiro Tsujikawa
1814fc1f2f Refactor util::to_numeric_addr 2025-05-24 14:44:12 +09:00
Tatsuhiro Tsujikawa
23f2cb85fe Merge pull request #2413 from nghttp2/ranges-util
util: Adopt std::ranges
2025-05-24 14:42:25 +09:00
Tatsuhiro Tsujikawa
1c07b88b2a util: Adopt std::ranges 2025-05-24 14:05:07 +09:00
Tatsuhiro Tsujikawa
44484e2ed5 Merge pull request #2412 from nghttp2/memchunk-direct-write
Allow Writing data to Memchunks directly
2025-05-24 14:04:48 +09:00
Tatsuhiro Tsujikawa
78f542d59e Allow Writing data to Memchunks directly 2025-05-24 13:40:15 +09:00
Tatsuhiro Tsujikawa
99f658d600 Merge pull request #2411 from nghttp2/status-write
Write http status string directly
2025-05-24 13:34:07 +09:00
Tatsuhiro Tsujikawa
aa2955c8fb Write http status string directly 2025-05-24 13:11:52 +09:00
Tatsuhiro Tsujikawa
d995c75173 Merge pull request #2410 from nghttp2/rewrite-upcase
Rewrite util::upcase
2025-05-24 12:45:17 +09:00
Tatsuhiro Tsujikawa
bb7a0c78ce Rewrite util::upcase 2025-05-24 12:18:34 +09:00
Tatsuhiro Tsujikawa
4993297326 Merge pull request #2409 from nghttp2/no-capitalize-http-field-name
nghttpx: No need to capitalize HTTP/1.1 field name
2025-05-24 11:54:53 +09:00
Tatsuhiro Tsujikawa
e0089070f5 nghttpx: No need to capitalize HTTP/1.1 field name 2025-05-24 11:16:14 +09:00
Tatsuhiro Tsujikawa
c3c418ce7a Merge pull request #2408 from nghttp2/pred-func-tables
Generate tables for character predicate functions
2025-05-24 11:11:01 +09:00
Tatsuhiro Tsujikawa
2643afa593 Generate tables for character predicate functions 2025-05-24 10:46:30 +09:00
Tatsuhiro Tsujikawa
1a118fc0b2 Merge pull request #2407 from nghttp2/amend-date
Amend date
2025-05-23 23:21:28 +09:00
Tatsuhiro Tsujikawa
1af84eca7b Amend date
- Use std::chrono::system_clock::from_time_t
- Allocate extra byte for terminal NUL just in case
2025-05-23 22:59:34 +09:00
Tatsuhiro Tsujikawa
e3fbf4b0f1 Merge pull request #2406 from nghttp2/rewrite-format_http_date
Rewrite format_http_date with std::chrono
2025-05-23 22:14:12 +09:00
Tatsuhiro Tsujikawa
ac080aeabb Rewrite format_http_date with std::chrono 2025-05-23 21:43:05 +09:00
Tatsuhiro Tsujikawa
f59f7b6ded Merge pull request #2405 from nghttp2/rewrite-format_common_log
Rewrite format_common_log
2025-05-23 21:20:54 +09:00
Tatsuhiro Tsujikawa
d73b5d42e9 Rewrite format_common_log 2025-05-23 20:46:33 +09:00
Tatsuhiro Tsujikawa
8b0c12219a Merge pull request #2404 from nghttp2/rewrite-format_iso8601_basic
Rewrite format_iso8601_basic with std::chrono
2025-05-23 19:45:54 +09:00
Tatsuhiro Tsujikawa
f0fce329b3 Rewrite format_iso8601_basic with std::chrono 2025-05-23 19:11:02 +09:00
Tatsuhiro Tsujikawa
c39db11532 Merge pull request #2403 from nghttp2/hide-iso8601_date
Hide iso8601_date in unnamed namespace
2025-05-23 19:10:33 +09:00
Tatsuhiro Tsujikawa
be06de738c Hide iso8601_date in unnamed namespace 2025-05-23 18:50:09 +09:00
Tatsuhiro Tsujikawa
3b82d4848a Merge pull request #2402 from nghttp2/util-refactor-format-date
Util refactor format date
2025-05-22 22:28:16 +09:00
Tatsuhiro Tsujikawa
5504920feb Make MONTH and DAY_OF_WEEK array of std::string_view 2025-05-22 21:50:48 +09:00
Tatsuhiro Tsujikawa
faa3831d05 Rewrite cpydig 2025-05-22 21:41:17 +09:00
Tatsuhiro Tsujikawa
75d836c21e Merge pull request #2401 from nghttp2/chrono-format_iso8601
Rewrite format_iso8601 with std::chrono
2025-05-22 21:31:09 +09:00
Tatsuhiro Tsujikawa
0b730de705 Rewrite format_iso8601 with std::chrono 2025-05-22 21:11:11 +09:00
Tatsuhiro Tsujikawa
4f2b72dbeb Merge pull request #2400 from nghttp2/hide-xdigits
Hide *_XDIGITS inside table generator functions
2025-05-22 20:43:46 +09:00
Tatsuhiro Tsujikawa
5faf84cf2f Hide *_XDIGITS inside table generator functions 2025-05-22 20:23:30 +09:00
Tatsuhiro Tsujikawa
784c1dbe36 Merge pull request #2399 from nghttp2/range-disallow-array
Disallow array to substitute R &&
2025-05-22 19:43:57 +09:00
Tatsuhiro Tsujikawa
74c6a20d96 Disallow array to substitute R &&
C array is sometimes very dangerous for this purpose, for example, if
it contains NULL terminated string.  In such case, passing entire
array is unacceptable.
2025-05-22 19:13:46 +09:00
Tatsuhiro Tsujikawa
901d8d777c Merge pull request #2398 from nghttp2/faster-utox
Optimize util::utox
2025-05-22 00:45:52 +09:00
Tatsuhiro Tsujikawa
880fa82e65 Optimize util::utox 2025-05-21 23:10:03 +09:00
Tatsuhiro Tsujikawa
855e65b9c8 Merge pull request #2397 from nghttp2/faster-format_hex
Optimize util::format_hex
2025-05-21 21:20:06 +09:00
Tatsuhiro Tsujikawa
a2f37abdbe Optimize util::format_hex 2025-05-21 20:49:44 +09:00
Tatsuhiro Tsujikawa
e9b9de1006 Merge pull request #2396 from nghttp2/faster-utos
Optimize util::utos
2025-05-21 19:44:13 +09:00
Tatsuhiro Tsujikawa
ab32a1bb40 Optimize util::utos 2025-05-21 19:10:05 +09:00
Tatsuhiro Tsujikawa
e81aeb6fe4 Merge pull request #2395 from nghttp2/base64-constexpr
Make base64 encoder/decoder constexpr
2025-05-20 23:19:31 +09:00
Tatsuhiro Tsujikawa
a404ba5c12 Make base64 encoder/decoder constexpr 2025-05-20 22:49:00 +09:00
Tatsuhiro Tsujikawa
7d15a7aa6b Merge pull request #2394 from nghttp2/refine-output-iterator
Refine output iterator requirements
2025-05-20 22:38:37 +09:00
Tatsuhiro Tsujikawa
d41fd15d23 Refine output iterator requirements 2025-05-20 21:53:55 +09:00
Tatsuhiro Tsujikawa
c1f08ca2f6 Merge pull request #2393 from nghttp2/refactor-make_hostport
Refactor util::make_http_hostport and util::make_hostport
2025-05-20 21:53:25 +09:00
Tatsuhiro Tsujikawa
aeb5185a44 Refactor util::make_http_hostport and util::make_hostport 2025-05-20 21:33:54 +09:00
Tatsuhiro Tsujikawa
88171ab2bf Merge pull request #2392 from nghttp2/remove-inp_strlower
Remove util::inp_strlower in favor of util::tolower
2025-05-20 18:30:03 +09:00
Tatsuhiro Tsujikawa
02d1de1d9d Remove util::inp_strlower in favor of util::tolower 2025-05-20 18:01:25 +09:00
Tatsuhiro Tsujikawa
339bc419bf Merge pull request #2391 from nghttp2/constexpr-format_hex
Make util::format_hex constexpr
2025-05-19 23:54:36 +09:00
Tatsuhiro Tsujikawa
81e817f695 Make util::format_hex constexpr 2025-05-19 23:03:05 +09:00
Tatsuhiro Tsujikawa
6659de1cfd Merge pull request #2390 from nghttp2/rewrite-decode_hex
Rewrite util::decode_hex
2025-05-19 22:52:33 +09:00
Tatsuhiro Tsujikawa
9e11a12c72 Rewrite util::decode_hex 2025-05-19 22:28:08 +09:00
Tatsuhiro Tsujikawa
a1e9e5f640 Merge pull request #2389 from nghttp2/rewrite-utos
Rewrite util::utos functions
2025-05-19 21:27:40 +09:00
Tatsuhiro Tsujikawa
2f02abfe7a Rewrite util::utos functions 2025-05-19 21:04:10 +09:00
Tatsuhiro Tsujikawa
3bca3282f1 Merge pull request #2388 from nghttp2/rewrite-quote_string
Rewrite util::quote_string
2025-05-19 19:07:03 +09:00
Tatsuhiro Tsujikawa
646615022d Rewrite util::quote_string 2025-05-19 18:34:25 +09:00
Tatsuhiro Tsujikawa
dd293082fc Merge pull request #2387 from nghttp2/constinit
Declare hex_to_uint_tbl constinit
2025-05-19 18:18:42 +09:00
Tatsuhiro Tsujikawa
9e235fe957 Declare hex_to_uint_tbl constinit 2025-05-19 17:52:59 +09:00
Tatsuhiro Tsujikawa
2b47d4b525 Merge pull request #2386 from nghttp2/rewrite-percent-encoding
Rewrite percent encoding
2025-05-18 22:43:01 +09:00
Tatsuhiro Tsujikawa
fa5ac09ade Remove old implementation 2025-05-18 22:22:41 +09:00
Tatsuhiro Tsujikawa
a993d99977 Make util::is_hex_digit and util::hex_to_uint constexpr 2025-05-18 22:22:41 +09:00
Tatsuhiro Tsujikawa
d400319bcc Remove unused util::percent_encode 2025-05-18 21:51:09 +09:00
Tatsuhiro Tsujikawa
10d00c8a53 Rewrite util::percent_encode_token 2025-05-18 21:51:09 +09:00
Tatsuhiro Tsujikawa
b559f69199 Rewrite util::percent_decode 2025-05-18 21:15:36 +09:00
Tatsuhiro Tsujikawa
4513bfc3fc Merge pull request #2385 from nghttp2/immutablestring-literal
Add ImmutableString string literal
2025-05-18 18:30:38 +09:00
Tatsuhiro Tsujikawa
5e373a3514 Add ImmutableString string literal 2025-05-18 17:51:54 +09:00
Tatsuhiro Tsujikawa
0df91a4b0c Merge pull request #2384 from nghttp2/ranges-template
template: Adopt std::ranges
2025-05-18 17:51:09 +09:00
Tatsuhiro Tsujikawa
c362f9d36c template: Adopt std::ranges 2025-05-18 17:26:54 +09:00
Tatsuhiro Tsujikawa
9b568cf542 Merge pull request #2383 from nghttp2/ranges-memchunk
memchunk: Adopt std::ranges
2025-05-18 09:51:14 +09:00
Tatsuhiro Tsujikawa
6be52029db memchunk: Adopt std::ranges 2025-05-18 09:20:16 +09:00
Tatsuhiro Tsujikawa
fef9e8fb20 Merge pull request #2382 from nghttp2/buffer-ranges
buffer: Adopt std::ranges
2025-05-17 19:39:03 +09:00
Tatsuhiro Tsujikawa
09bb8350e8 buffer: Adopt std::ranges 2025-05-17 19:13:44 +09:00
Tatsuhiro Tsujikawa
10ebb3825a Merge pull request #2381 from nghttp2/nghttpx-ranges-shrpx
shrpx: Adopt std::ranges
2025-05-17 11:47:17 +09:00
Tatsuhiro Tsujikawa
8bdf022465 shrpx: Adopt std::ranges 2025-05-17 10:59:15 +09:00
Tatsuhiro Tsujikawa
14f1169a5a Merge pull request #2380 from nghttp2/nghttpx-remove-memcached-session-cache
Nghttpx remove memcached session cache
2025-05-17 10:49:54 +09:00
Tatsuhiro Tsujikawa
93dd369b0e Update bash_completion 2025-05-17 10:13:16 +09:00
Tatsuhiro Tsujikawa
bb3c2a3664 Update manual pages 2025-05-17 10:12:58 +09:00
Tatsuhiro Tsujikawa
11903f36a9 nghttpx: Remove TLS session cache with memcached
Nowadays, TLS session caching is done via ticket and no server side
storage is required, remove TLS session cache with memcached.
2025-05-17 10:06:58 +09:00
Tatsuhiro Tsujikawa
afedd3aa06 Merge pull request #2379 from nghttp2/rename-stream-root
Rename root to nghttp2_stream_root
2025-05-16 21:29:59 +09:00
Tatsuhiro Tsujikawa
242c0c3988 Rename root to nghttp2_stream_root
Rename root to nghttp2_stream_root to avoid potential name crash.
2025-05-16 21:03:12 +09:00
Tatsuhiro Tsujikawa
ed3b31fa4c Merge pull request #2378 from nghttp2/nghttpx-remove-ocsp
Nghttpx remove ocsp
2025-05-16 21:00:21 +09:00
Tatsuhiro Tsujikawa
b7be212c30 Update bash_completion 2025-05-16 20:33:00 +09:00
Tatsuhiro Tsujikawa
ac92a4daae Update manual pages 2025-05-16 20:33:00 +09:00
Tatsuhiro Tsujikawa
ed1c6ed344 nghttpx: Remove OCSP stapling
This commit removes OCSP stapling features and the following options
are deprecated and have no effect:

- fetch-ocsp-response-file
- no-ocsp
- no-verify-ocsp
- ocsp-update-interval
2025-05-16 20:33:00 +09:00
Tatsuhiro Tsujikawa
f804e92785 Merge pull request #2377 from nghttp2/nghttpx-listeners-per-worker
nghttpx: Listen TCP and UNIX domain sockets on worker thread
2025-05-16 19:14:12 +09:00
Tatsuhiro Tsujikawa
9275353a47 nghttpx: Listen TCP and UNIX domain sockets on worker thread
Previously, nghttpx listens TCP and UNIX domain sockets on a dedicated
thread, and then distributes the accepted connection to the one of
worker threads.  With this commit, nghttpx listens those sockets on
each worker thread.  For TCP sockets, SO_REUSEPORT is used to load
balance the connections.  This removes the need for inheriting file
descriptors via environment variables.  For UNIX domain sockets,
because there is no SO_REUSEPORT equivalent for them, they are created
as before, but they are handled per worker.

The support for legacy deprecated environment variables has been
removed.

ocsp-startup option has been deprecated due to this change.  OCSP will
be remove very soon.
2025-05-16 18:46:02 +09:00
Tatsuhiro Tsujikawa
d1bc03bd57 Merge pull request #2375 from nghttp2/nghttpx-ranges-config
shrpx_config: Adopt std::ranges
2025-05-13 23:14:36 +09:00
Tatsuhiro Tsujikawa
853b9ccd3c shrpx_config: Adopt std::ranges 2025-05-13 22:21:56 +09:00
Tatsuhiro Tsujikawa
dd02d164ba Merge pull request #2374 from nghttp2/nghttpx-ranges-part3
Nghttpx ranges part3
2025-05-13 21:59:22 +09:00
Tatsuhiro Tsujikawa
c36d0cb807 http3: Adopt std::ranges 2025-05-13 21:29:08 +09:00
Tatsuhiro Tsujikawa
68ed952004 shrpx_quic_connection_handler: Adopt std::ranges 2025-05-13 21:29:08 +09:00
Tatsuhiro Tsujikawa
f7f8592d6d shrpx_quic: Adopt std::ranges 2025-05-13 21:29:08 +09:00
Tatsuhiro Tsujikawa
500eb25302 shrpx_dns_tracker: Adopt std::ranges 2025-05-13 21:29:08 +09:00
Tatsuhiro Tsujikawa
d074d20ad4 shrpx_api_downstream_connection: Adopt std::ranges 2025-05-13 21:29:08 +09:00
Tatsuhiro Tsujikawa
66e5d45994 shrpx_router: Adopt std::ranges 2025-05-13 21:29:08 +09:00
Tatsuhiro Tsujikawa
e68fa65166 Merge pull request #2373 from nghttp2/rewrite-format_hex
Rewrite format_hex
2025-05-13 21:09:47 +09:00
Tatsuhiro Tsujikawa
d5b11e6f94 Rewrite format_hex 2025-05-13 20:39:17 +09:00
Tatsuhiro Tsujikawa
51909d8bf8 Merge pull request #2372 from nghttp2/nghttpx-ranges-part2
Nghttpx ranges part2
2025-05-13 20:38:20 +09:00
Tatsuhiro Tsujikawa
299b6a4e31 shrpx_worker_process: Adopt std::ranges 2025-05-13 20:02:22 +09:00
Tatsuhiro Tsujikawa
a7407b28ce shrpx_memcached_connection: Adopt std::ranges 2025-05-13 20:02:22 +09:00
Tatsuhiro Tsujikawa
4397a37b31 shrpx_downstream_connection_pool: Adopt std::ranges 2025-05-13 20:02:22 +09:00
Tatsuhiro Tsujikawa
996b02c2fe Merge pull request #2371 from nghttp2/str-cmp-constexpr
Make string comparison functions constexpr
2025-05-13 20:01:36 +09:00
Tatsuhiro Tsujikawa
f27d667cec Make string comparison functions constexpr 2025-05-13 19:14:00 +09:00
Tatsuhiro Tsujikawa
50c2a0fc99 Merge pull request #2370 from nghttp2/single-pass-header-name-lowecase
Single pass header name lowecase
2025-05-13 18:19:18 +09:00
Tatsuhiro Tsujikawa
9a7dad6a50 Make sure that args are forwarded once 2025-05-13 17:54:36 +09:00
Tatsuhiro Tsujikawa
12e6caadce append_last_header_key: Copy and lowecase name in a single pass 2025-05-13 17:54:36 +09:00
Tatsuhiro Tsujikawa
3cdfcd3819 Merge pull request #2369 from nghttp2/dependabot/go_modules/golang.org/x/net-0.40.0
build(deps): bump golang.org/x/net from 0.39.0 to 0.40.0
2025-05-12 23:45:52 +09:00
Tatsuhiro Tsujikawa
87396313d6 Merge pull request #2368 from nghttp2/tolower
Add template to copy lowercased string
2025-05-12 23:32:52 +09:00
dependabot[bot]
48ee27dcd0 build(deps): bump golang.org/x/net from 0.39.0 to 0.40.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.39.0 to 0.40.0.
- [Commits](https://github.com/golang/net/compare/v0.39.0...v0.40.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.40.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-12 14:13:47 +00:00
Tatsuhiro Tsujikawa
cb94c00a36 Add template to copy lowercased string 2025-05-12 23:01:02 +09:00
Tatsuhiro Tsujikawa
fa00277afe Merge pull request #2367 from nghttp2/nghttpx-ranges-worker
shrpx_worker: Adopt std::ranges
2025-05-12 22:26:15 +09:00
Tatsuhiro Tsujikawa
bf5565ea2c shrpx_worker: Adopt std::ranges 2025-05-12 21:49:48 +09:00
Tatsuhiro Tsujikawa
da6f0dd646 Merge pull request #2364 from nghttp2/as_string_ref
Add helper template for StringRef from contiguous range
2025-05-12 20:56:34 +09:00
Tatsuhiro Tsujikawa
71dd4399fc Add helper template for StringRef from contiguous range 2025-05-12 20:31:39 +09:00
Tatsuhiro Tsujikawa
08c0dad06f Merge pull request #2366 from nghttp2/integration-external-dns-disable-backend-ipv6
integration: Disable IPv6 on backend for external DNS tests
2025-05-12 20:30:36 +09:00
Tatsuhiro Tsujikawa
be9066bd7a GHA: Add backend to /etc/hosts to avoid nip.io 2025-05-12 19:15:22 +09:00
Tatsuhiro Tsujikawa
13aa7e5e78 integration: Disable IPv6 on backend for external DNS tests 2025-05-12 18:43:29 +09:00
Tatsuhiro Tsujikawa
0dbcb08e64 Merge pull request #2363 from nghttp2/bump-munit
Bump munit
2025-05-11 22:23:53 +09:00
Tatsuhiro Tsujikawa
a158d1dbb4 Bump munit 2025-05-11 21:33:51 +09:00
Tatsuhiro Tsujikawa
5742430337 Merge pull request #2362 from nghttp2/nghttpx-ranges-tls
shrpx_tls: Adopt std::ranges
2025-05-11 19:10:10 +09:00
Tatsuhiro Tsujikawa
75453db4ce shrpx_tls: Adopt std::ranges 2025-05-11 18:30:46 +09:00
Tatsuhiro Tsujikawa
458613c923 Merge pull request #2361 from nghttp2/nghttpx-ranges-part1
Nghttpx ranges part1
2025-05-11 11:13:33 +09:00
Tatsuhiro Tsujikawa
f29a47d577 shrpx_downstream_queue: Adopt std::ranges 2025-05-11 10:21:24 +09:00
Tatsuhiro Tsujikawa
4b6e156ddf shrpx_http_downstream_connection: Adopt std::ranges 2025-05-11 10:21:24 +09:00
Tatsuhiro Tsujikawa
5e26011caf shrpx_downstream:: Adopt std::ranges 2025-05-11 10:21:24 +09:00
Tatsuhiro Tsujikawa
4cd3369ed1 shrpx_client_handler: Adopt std::ranges
I was surprised the changes between std::lower_bound and
std::ranges::lower_bound.  It seems using projection is the simplest
workaround for our use.
2025-05-11 10:21:24 +09:00
Tatsuhiro Tsujikawa
90b2fbea66 shrpx_connection_handler: Adopt std::ranges 2025-05-11 10:21:24 +09:00
Tatsuhiro Tsujikawa
5b725c8a83 Merge pull request #2360 from nghttp2/string-ref-hash
StringRef: Piggyback std::hash<std::string_view>
2025-05-11 10:16:57 +09:00
Tatsuhiro Tsujikawa
83e079322e StringRef: Piggyback std::hash<std::string_view> 2025-05-11 09:37:38 +09:00
Tatsuhiro Tsujikawa
cc0207c967 Merge pull request #2359 from nghttp2/ranges-base64
Ranges base64
2025-05-10 18:19:07 +09:00
Tatsuhiro Tsujikawa
1f84d34371 Merge pull request #2358 from nghttp2/nghttpx-ranges-https-upstream
shrpx_https_upstream: Adopt std::ranges
2025-05-10 17:35:56 +09:00
Tatsuhiro Tsujikawa
f1808e1a0f base64::encode: Adopt std::ranges 2025-05-10 17:05:10 +09:00
Tatsuhiro Tsujikawa
07cc22bffa shrpx_https_upstream: Adopt std::ranges 2025-05-10 17:05:10 +09:00
Tatsuhiro Tsujikawa
db0a936158 base64::decode: Adopt std::ranges 2025-05-10 17:05:10 +09:00
Tatsuhiro Tsujikawa
e1c1168db3 Merge pull request #2357 from nghttp2/nghttpx-fix-forwarded-by
nghttpx: Fix Forwarded By
2025-05-10 17:04:43 +09:00
Tatsuhiro Tsujikawa
f5606f9855 nghttpx: Fix Forwarded By
Previously, the value sent with Forward By parameter is the address
assigned to the listening socket.  This does not work expected if the
assigned address is wild card, (e.g., ::, 0.0.0.0).

This commit fixes this issue by using the local address that the
connection is accepted.  For QUIC, it is the local address that
handshake is performed, and it stays the same even after client
address migration occurred.
2025-05-10 16:32:44 +09:00
Tatsuhiro Tsujikawa
d014becee2 Merge pull request #2356 from nghttp2/nghttpx-quic-frontend-address-resolution
nghttpx: Rework frontend address resolution for QUIC packets
2025-05-10 00:28:41 +09:00
Tatsuhiro Tsujikawa
b27c5481ef nghttpx: Rework frontend address resolution for QUIC packets
Instead of getnameinfo every time when forwarding a QUIC packet
internally, cache binary representation of frontend address on
startup, and compare them.
2025-05-09 20:53:54 +09:00
Tatsuhiro Tsujikawa
fe6288421f Merge pull request #2355 from nghttp2/rst-stream-to-closed-stream
Do not submit RST_STREAM more than once
2025-05-09 19:55:46 +09:00
Tatsuhiro Tsujikawa
6e60f76825 Do not submit RST_STREAM more than once
Do not submit RST_STREAM more than once for a same stream with
nghttp2_submit_rst_stream.  Historically, nghttp2_submit_rst_stream
allows this.  nghttp2 also allows receiving multiple RST_STREAM
frames.  To keep compatibility, nghttp2_submit_rst_stream does not
fail if it attempts to submit RST_STREAM to already closed stream.
2025-05-09 18:41:30 +09:00
Tatsuhiro Tsujikawa
5784ff5b46 Merge pull request #2353 from nghttp2/rewrite-starts-with
Rewrite starts_with, ends_with and streq with std::ranges
2025-05-07 23:45:42 +09:00
Tatsuhiro Tsujikawa
d75fddda00 Rewrite starts_with, ends_with and streq with std::ranges 2025-05-07 22:47:35 +09:00
Tatsuhiro Tsujikawa
c17cf5f1f5 Merge pull request #2352 from nghttp2/remove-copy_lit
Remove util::copy_lit
2025-05-07 22:44:29 +09:00
Tatsuhiro Tsujikawa
2fb05c54ad Remove util::copy_lit 2025-05-07 21:25:41 +09:00
Tatsuhiro Tsujikawa
9555260a65 Merge pull request #2351 from nghttp2/nghttpx-ranges-http3-upstream
shrpx_http3_upstream: Adopt std::ranges
2025-05-07 21:25:13 +09:00
Tatsuhiro Tsujikawa
4ce6c8e1dc Merge pull request #2350 from Karthikdasari0423/patch-1
Update README.rst
2025-05-07 20:34:48 +09:00
Tatsuhiro Tsujikawa
6677faed55 shrpx_http3_upstream: Adopt std::ranges 2025-05-07 19:50:46 +09:00
Tatsuhiro Tsujikawa
8a8838de29 Merge pull request #2349 from nghttp2/nghttpx-ranges-http2-upstream
shrpx_http2_upstream: Adopt std::ranges
2025-05-07 19:49:51 +09:00
Karthik Dasari
fa453878c4 Update README.rst
Update clang-15 to clang-18 in README file.
2025-05-07 16:18:23 +05:30
Tatsuhiro Tsujikawa
93072a2828 shrpx_http2_upstream: Adopt std::ranges 2025-05-07 19:02:15 +09:00
Tatsuhiro Tsujikawa
f52d191a69 Merge pull request #2348 from nghttp2/nghttpx-http2-dconn
shrpx_http2_downstream_connection: Adopt std::ranges
2025-05-07 18:48:41 +09:00
Tatsuhiro Tsujikawa
84f36115e5 shrpx_http2_downstream_connection: Adopt std::ranges 2025-05-06 22:51:47 +09:00
Tatsuhiro Tsujikawa
8dd0637645 Merge pull request #2345 from nghttp2/nghttpx-log-ranges
Nghttpx log ranges
2025-05-05 09:58:48 +09:00
Tatsuhiro Tsujikawa
4d6bca22cc Merge pull request #2342 from zjturner/fix_gettickcount64_check
Fix CMake existence check for GetTickCount64
2025-05-03 09:14:12 +09:00
Tatsuhiro Tsujikawa
7bb4146e58 shrpx_log: Make write_seq take std::input_range 2025-05-02 23:35:58 +09:00
Tatsuhiro Tsujikawa
ed5f3df612 shrpx_log: Rewrite with std::span 2025-05-02 23:35:58 +09:00
Tatsuhiro Tsujikawa
f402668a4e shrpx_log: Fix left over for std::ranges migration 2025-05-02 23:35:58 +09:00
Tatsuhiro Tsujikawa
f723380e32 shrpx_log: Do not return d_last which does not change 2025-05-02 23:35:58 +09:00
Tatsuhiro Tsujikawa
1db823f451 shrpx_log: Adopt std::ranges 2025-05-02 23:35:58 +09:00
Tatsuhiro Tsujikawa
fcd710e31d Merge pull request #2344 from nghttp2/nghttpx-dns
nghttpx: Tweak DNS timeout and retry
2025-05-02 23:35:35 +09:00
Tatsuhiro Tsujikawa
6922b336b0 nghttpx: Tweak DNS timeout and retry
Decrease DNS timeout to 250ms, which is the minimum duration allowed
in c-ares.  The number of retries is 3, which is the default value of
c-ares.
2025-05-02 22:59:41 +09:00
Tatsuhiro Tsujikawa
6edf4343b2 Merge pull request #2343 from nghttp2/ranges-http
shrpx_http: Adopt std::ranges
2025-05-02 21:10:05 +09:00
Tatsuhiro Tsujikawa
81864f3c7f shrpx_http: Adopt std::ranges 2025-05-02 17:21:05 +09:00
Zachary Turner
2a0c0a2598 Fix check for GetTickCount64 2025-05-01 11:41:10 -07:00
Tatsuhiro Tsujikawa
3db4000c80 Merge pull request #2341 from nghttp2/ranges-http2
http2: Adopt std::ranges
2025-05-01 18:48:18 +09:00
Tatsuhiro Tsujikawa
c7b33ceea9 http2: Adopt std::ranges 2025-05-01 18:12:32 +09:00
Tatsuhiro Tsujikawa
e47a2cc34a Merge pull request #2340 from nghttp2/refactor-allocator
Refactor allocator
2025-05-01 18:11:56 +09:00
Tatsuhiro Tsujikawa
aa77184ed5 allocator: Use auto 2025-05-01 17:37:51 +09:00
Tatsuhiro Tsujikawa
58ff9e5188 allocator: Adopt std::ranges 2025-05-01 17:37:51 +09:00
Tatsuhiro Tsujikawa
a0bf1d13bb Remove inline from count_string_ref_count 2025-05-01 17:37:51 +09:00
Tatsuhiro Tsujikawa
c47ab92f69 Remove BlockAllocator template parameter 2025-05-01 17:37:51 +09:00
Tatsuhiro Tsujikawa
ad4b9529dc Merge pull request #2339 from nghttp2/adopt-span-first
nghttpx: Adopt std::span::first
2025-05-01 17:36:08 +09:00
Tatsuhiro Tsujikawa
b5819be055 nghttpx: Adopt std::span::first 2025-05-01 17:06:55 +09:00
Tatsuhiro Tsujikawa
21dfefa0c3 Merge pull request #2337 from nghttp2/h2load-refactor-quic-write-path
h2load: Refactor QUIC packet write path
2025-04-28 22:02:11 +09:00
Tatsuhiro Tsujikawa
4c013d1087 h2load: Refactor QUIC packet write path
Refactor QUIC packet write path in h2load.  h2load now falls back to
non-GSO write after GSO failed.
2025-04-28 21:38:55 +09:00
Tatsuhiro Tsujikawa
825b296d12 Merge pull request #2336 from nghttp2/nghttpx-refactor-quic-packet-write
nghttpx: Refactor QUIC packet write
2025-04-27 21:01:18 +09:00
Tatsuhiro Tsujikawa
514b7743d6 nghttpx: Refactor QUIC packet write 2025-04-27 19:33:52 +09:00
Tatsuhiro Tsujikawa
5265110509 Merge pull request #2333 from nghttp2/quic-ossl
h2load, nghttpx: Add libngtcp2_crypto_ossl support
2025-04-22 20:35:51 +09:00
Tatsuhiro Tsujikawa
aa96bfcb27 Merge pull request #2335 from nghttp2/dependabot/go_modules/github.com/quic-go/quic-go-0.51.0
build(deps): bump github.com/quic-go/quic-go from 0.50.1 to 0.51.0
2025-04-22 19:23:09 +09:00
dependabot[bot]
c7f062aeca build(deps): bump github.com/quic-go/quic-go from 0.50.1 to 0.51.0
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.50.1 to 0.51.0.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.50.1...v0.51.0)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-version: 0.51.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-21 15:42:10 +00:00
Tatsuhiro Tsujikawa
32eeffcd11 h2load, nghttpx: Add libngtcp2_crypto_ossl support 2025-04-19 16:49:02 +09:00
Tatsuhiro Tsujikawa
67a93b53a3 Merge pull request #2332 from nghttp2/gha-android-docker
GHA: Add android workflow
2025-04-19 15:52:54 +09:00
Tatsuhiro Tsujikawa
941024f193 GHA: Add android workflow 2025-04-19 15:30:10 +09:00
Tatsuhiro Tsujikawa
127adf6acf Merge pull request #2330 from feicong/master
Fixed android support
2025-04-19 00:34:06 +09:00
feicong
ff3655c7cd Update Dockerfile.android
Co-authored-by: Tatsuhiro Tsujikawa <404610+tatsuhiro-t@users.noreply.github.com>
2025-04-18 19:37:21 +08:00
Tatsuhiro Tsujikawa
b58c6402f9 Merge pull request #2331 from nghttp2/bump-ngtcp2
Bump ngtcp2
2025-04-18 19:42:19 +09:00
Tatsuhiro Tsujikawa
0af7b9bb84 Bump ngtcp2 2025-04-18 19:06:21 +09:00
feicong
188cd1ef6b Fixed android support 2025-04-17 15:13:51 +08:00
Tatsuhiro Tsujikawa
aa82e0132a Merge pull request #2328 from nghttp2/dependabot/go_modules/golang.org/x/net-0.39.0
build(deps): bump golang.org/x/net from 0.38.0 to 0.39.0
2025-04-16 18:55:02 +09:00
dependabot[bot]
dbd027c796 build(deps): bump golang.org/x/net from 0.38.0 to 0.39.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.38.0 to 0.39.0.
- [Commits](https://github.com/golang/net/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-14 14:15:07 +00:00
Tatsuhiro Tsujikawa
999baf9090 Merge pull request #2327 from nghttp2/gha-macos-15
GHA: Replace macos-13 with macos-15
2025-04-13 17:47:23 +09:00
Tatsuhiro Tsujikawa
ce5b1e9235 GHA: Replace macos-13 with macos-15 2025-04-13 17:03:00 +09:00
Tatsuhiro Tsujikawa
ac29d9da5f Merge pull request #2326 from nghttp2/quic-rand-take2
quic: Use secure random generator for ngtcp2_rand
2025-04-10 21:22:50 +09:00
Tatsuhiro Tsujikawa
44495acf4f quic: Use secure random generator for ngtcp2_rand 2025-04-10 20:41:50 +09:00
Tatsuhiro Tsujikawa
29263b1b41 Merge pull request #2325 from nghttp2/revert-2324-quic-rand
Revert "quic: Use secure random generator for ngtcp2_rand"
2025-04-10 20:36:40 +09:00
Tatsuhiro Tsujikawa
3d2e252e2c Revert "quic: Use secure random generator for ngtcp2_rand" 2025-04-10 20:35:39 +09:00
Tatsuhiro Tsujikawa
e1337244d3 Merge pull request #2324 from nghttp2/quic-rand
quic: Use secure random generator for ngtcp2_rand
2025-04-10 20:31:43 +09:00
Tatsuhiro Tsujikawa
885ea764a0 quic: Use secure random generator for ngtcp2_rand 2025-04-10 19:47:56 +09:00
Tatsuhiro Tsujikawa
58a38d00e4 Merge pull request #2322 from nghttp2/update-integration-tests
Update integration tests
2025-04-04 21:11:44 +09:00
Tatsuhiro Tsujikawa
24a1554e3a Merge pull request #2318 from slyon/fix-ftbfs-upstream
doc:rubydomain: Fix build failure with rubydomain namespace
2025-04-04 20:59:22 +09:00
Tatsuhiro Tsujikawa
d167c34753 Merge pull request #2323 from nghttp2/nghttpx-close-conn-on-h1-connect-failure
nghttpx: Close h1 connection on CONNECT failure
2025-04-04 20:40:18 +09:00
Tatsuhiro Tsujikawa
4fd86afb89 nghttpx: Close h1 connection on CONNECT failure 2025-04-04 19:35:34 +09:00
Tatsuhiro Tsujikawa
a2aa9d1fc7 Fix lint errors 2025-04-04 19:32:04 +09:00
Tatsuhiro Tsujikawa
283cbc4df5 Bump go version to 1.24 2025-04-04 18:30:06 +09:00
Tatsuhiro Tsujikawa
18d98dd215 Merge pull request #2320 from nghttp2/dependabot/go_modules/github.com/quic-go/quic-go-0.50.1
build(deps): bump github.com/quic-go/quic-go from 0.50.0 to 0.50.1
2025-04-03 22:51:54 +09:00
Tatsuhiro Tsujikawa
3dee622df6 Merge pull request #2321 from nghttp2/remove-go-toolchain
Remove go toolchain
2025-04-03 21:49:40 +09:00
Tatsuhiro Tsujikawa
6b81eeb106 Remove go toolchain 2025-04-03 19:04:31 +09:00
dependabot[bot]
594bc072ae build(deps): bump github.com/quic-go/quic-go from 0.50.0 to 0.50.1
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.50.0 to 0.50.1.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.50.0...v0.50.1)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 10:03:31 +00:00
Tatsuhiro Tsujikawa
077259c08c Merge pull request #2319 from nghttp2/dependabot/go_modules/golang.org/x/net-0.38.0
build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0
2025-04-03 19:02:24 +09:00
dependabot[bot]
168f210f34 build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.37.0 to 0.38.0.
- [Commits](https://github.com/golang/net/compare/v0.37.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-31 14:20:04 +00:00
Lukas Märdian
a86dbfd723 doc:rubydomain: Fix build failure with rubydomain namespace
This package fails to build from source in Debian and Ubuntu:

* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1095360
* https://bugs.launchpad.net/ubuntu/+source/nghttp2/+bug/2104171

With the following log output:
```
During a rebuild of all packages in unstable, your package failed to build:

--------------------------------------------------------------------------------
[...]
make[3]: Entering directory '/<<PKGBUILDDIR>>/integration-tests'
make[3]: Nothing to be done for 'html'.
make[3]: Leaving directory '/<<PKGBUILDDIR>>/integration-tests'
Making html in doc
make[3]: Entering directory '/<<PKGBUILDDIR>>/doc'
for i in README.rst programmers-guide.rst nghttp.1.rst nghttpd.1.rst nghttpx.1.rst h2load.1.rst; do [ -e ./$i ] || cp ./$i .; done
/usr/bin/python3 ../doc/mkapiref.py \
apiref.rst macros.rst enums.rst types.rst . ../lib/includes/nghttp2/nghttp2ver.h ../lib/includes/nghttp2/nghttp2.h
sphinx-build -b html -d manual/doctrees . manual/html
Running Sphinx v8.1.3
loading translations [en]... done

Extension error:
Could not import extension rubydomain.rubydomain (exception: No module named 'pkg_resources')
make[3]: *** [Makefile:921: html-local] Error 2
make[3]: Leaving directory '/<<PKGBUILDDIR>>/doc'
make[2]: *** [Makefile:583: html-recursive] Error 1
make[2]: Leaving directory '/<<PKGBUILDDIR>>'
make[1]: *** [debian/rules:14: override_dh_auto_build-indep] Error 2
make[1]: Leaving directory '/<<PKGBUILDDIR>>'
make: *** [debian/rules:62: binary] Error 2
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2
```

Adding a Build-Depends-Indep on `python3-pkg-resources` fixes the build, but is deprecated.

According to setuptools:
```
def declare_namespace(packageName: str) -> None:
    """Declare that package 'packageName' is a namespace package"""

    msg = (
        f"Deprecated call to `pkg_resources.declare_namespace({packageName!r})`.\n"
        "Implementing implicit namespace packages (as specified in PEP 420) "
        "is preferred to `pkg_resources.declare_namespace`. "
        "See https://setuptools.pypa.io/en/latest/references/"
        "keywords.html#keyword-namespace-packages"
    )
    warnings.warn(msg, DeprecationWarning, stacklevel=2)
```

Here it looks like the explicit namespacing was only needed when extending the `sphinxcontrib` module, but it was renamed to be an independent module "rubydomain.rubydomain":
a029f6ed2c

So `doc/_extrs/rubydomain/__init__.py` should just be dropped to make it an implicit namespaced package in accordance with https://peps.python.org/pep-0420/.
2025-03-27 12:47:52 +01:00
Tatsuhiro Tsujikawa
daef61594c Merge pull request #2317 from nghttp2/h2load-group-name
h2load: Check the return value from OBJ_nid2sn
2025-03-23 14:12:48 +09:00
Tatsuhiro Tsujikawa
de7b174cec h2load: Check the return value from OBJ_nid2sn 2025-03-23 13:33:04 +09:00
Tatsuhiro Tsujikawa
d6af4a90d5 Merge pull request #2316 from nghttp2/dependabot/go_modules/golang.org/x/net-0.37.0
build(deps): bump golang.org/x/net from 0.35.0 to 0.37.0
2025-03-12 21:39:01 +09:00
dependabot[bot]
ea6079c2ab build(deps): bump golang.org/x/net from 0.35.0 to 0.37.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.35.0 to 0.37.0.
- [Commits](https://github.com/golang/net/compare/v0.35.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 15:13:44 +00:00
Tatsuhiro Tsujikawa
3fbebd97cd Merge pull request #2314 from nghttp2/bump-quic-go
Bump github.com/quic-go/quic-go to v0.50.0
2025-03-04 19:03:08 +09:00
Tatsuhiro Tsujikawa
b3f18d73f5 Bump github.com/quic-go/quic-go to v0.50.0 2025-03-04 18:09:51 +09:00
Tatsuhiro Tsujikawa
cfbe1ff69c Bump package version 2025-03-02 16:51:14 +09:00
266 changed files with 18301 additions and 18252 deletions

View File

@@ -35,7 +35,29 @@ AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
@@ -45,6 +67,7 @@ AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
@@ -53,9 +76,7 @@ AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
@@ -83,6 +104,7 @@ BraceWrapping:
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
@@ -90,8 +112,10 @@ BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: MultiLine
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
@@ -147,12 +171,15 @@ IntegerLiteralSeparator:
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
KeepEmptyLinesAtEOF: false
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
@@ -221,6 +248,7 @@ SpacesInLineCommentPrefix:
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
@@ -235,6 +263,7 @@ StatementMacros:
- munit_void_test_decl
- nghttp2_max_def
- nghttp2_min_def
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true

24
.github/workflows/android.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: android
on:
push:
paths:
- Dockerfile.android
- .github/workflows/android.yml
branches:
- '**'
permissions: read-all
jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build
uses: docker/build-push-action@v6
with:
file: Dockerfile.android

View File

@@ -5,26 +5,26 @@ on: [push, pull_request]
permissions: read-all
env:
LIBBPF_VERSION: v1.5.0
LIBBPF_VERSION: v1.6.2
OPENSSL1_VERSION: 1_1_1w+quic
OPENSSL3_VERSION: 3.1.7+quic
BORINGSSL_VERSION: 294ab9730c570213b496cfc2fc14b3c0bfcd4bcc
AWSLC_VERSION: v1.46.1
NGHTTP3_VERSION: v1.8.0
NGTCP2_VERSION: v1.11.0
WOLFSSL_VERSION: v5.7.6-stable
OPENSSL3_VERSION: 3.6.0
BORINGSSL_VERSION: db1a8456167249f95b854a1cd24c6b553d0f1567
AWSLC_VERSION: v1.62.0
NGHTTP3_VERSION: v1.12.0
NGTCP2_VERSION: v1.17.0
WOLFSSL_VERSION: v5.8.2-stable
jobs:
build-cache:
strategy:
matrix:
os: [ubuntu-24.04, macos-13, macos-14]
os: [ubuntu-24.04, macos-14, macos-15]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Restore libbpf cache
id: cache-libbpf
uses: actions/cache@v4
@@ -49,8 +49,8 @@ jobs:
uses: actions/cache@v4
with:
path: |
boringssl/build/crypto/libcrypto.a
boringssl/build/ssl/libssl.a
boringssl/build/libcrypto.a
boringssl/build/libssl.a
boringssl/include
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
- name: Restore aws-lc cache
@@ -133,12 +133,12 @@ jobs:
./config --prefix=$PWD/build
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install_sw
- name: Build quictls/openssl v3.x
- name: Build openssl/openssl v3.x
if: steps.cache-openssl3.outputs.cache-hit != 'true'
run: |
git clone --recursive --shallow-submodules --depth 1 -b openssl-${{ env.OPENSSL3_VERSION }} https://github.com/quictls/openssl openssl3
git clone --recursive --shallow-submodules --depth 1 -b openssl-${{ env.OPENSSL3_VERSION }} https://github.com/openssl/openssl openssl3
cd openssl3
./config enable-ktls --prefix=$PWD/build --libdir=$PWD/build/lib
./config enable-ktls --prefix=$PWD/build
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make install_sw
- name: Build BoringSSL
@@ -190,7 +190,7 @@ jobs:
./configure --prefix=$PWD/build --enable-lib-only \
PKG_CONFIG_PATH="../openssl1/build/lib/pkgconfig:../wolfssl/build/lib/pkgconfig" \
BORINGSSL_CFLAGS="-I$PWD/../boringssl/include/" \
BORINGSSL_LIBS="-L$PWD/../boringssl/build/ssl -lssl -L$PWD/../boringssl/build/crypto -lcrypto" \
BORINGSSL_LIBS="-L$PWD/../boringssl/build -lssl -lcrypto" \
--disable-dependency-tracking \
--with-boringssl \
--with-wolfssl
@@ -203,7 +203,7 @@ jobs:
cd ngtcp2-openssl3
autoreconf -i
./configure --prefix=$PWD/build --enable-lib-only \
PKG_CONFIG_PATH="../openssl3/build/lib/pkgconfig" \
PKG_CONFIG_PATH="../openssl3/build/lib64/pkgconfig:../openssl3/build/lib/pkgconfig" \
BORINGSSL_CFLAGS="-I$PWD/../aws-lc/include/" \
BORINGSSL_LIBS="-L$PWD/../aws-lc/build/ssl -lssl -L$PWD/../aws-lc/build/crypto -lcrypto" \
--disable-dependency-tracking \
@@ -217,40 +217,36 @@ jobs:
strategy:
matrix:
os: [ubuntu-24.04, macos-13, macos-14]
os: [ubuntu-24.04, macos-14, macos-15]
compiler: [gcc, clang]
buildtool: [autotools, cmake]
http3: [http3, no-http3]
openssl: [openssl1, openssl3, boringssl, awslc, wolfssl]
exclude:
- os: macos-13
openssl: openssl3
- os: macos-14
openssl: openssl3
- http3: no-http3
openssl: openssl3
- os: macos-13
compiler: gcc
- os: macos-14
compiler: gcc
- # disable macos cmake because of include path issue
os: macos-13
buildtool: cmake
- os: macos-15
compiler: gcc
- # disable macos cmake because of include path issue
os: macos-14
buildtool: cmake
- os: macos-13
openssl: boringssl
- # disable macos cmake because of include path issue
os: macos-15
buildtool: cmake
- os: macos-14
openssl: boringssl
- os: macos-15
openssl: boringssl
- openssl: boringssl
buildtool: cmake
- openssl: boringssl
compiler: gcc
- os: macos-13
openssl: awslc
- os: macos-14
openssl: awslc
- os: macos-15
openssl: awslc
- openssl: awslc
buildtool: cmake
- openssl: awslc
@@ -266,7 +262,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- name: Linux setup
@@ -275,7 +271,7 @@ jobs:
sudo apt-get update
sudo apt-get install \
g++-14 \
clang-18 \
clang-19 \
autoconf \
automake \
autotools-dev \
@@ -314,8 +310,8 @@ jobs:
- name: Setup clang (Linux)
if: runner.os == 'Linux' && matrix.compiler == 'clang'
run: |
echo 'CC=clang-18' >> $GITHUB_ENV
echo 'CXX=clang++-18' >> $GITHUB_ENV
echo 'CC=clang-19' >> $GITHUB_ENV
echo 'CXX=clang++-19' >> $GITHUB_ENV
- name: Setup clang (MacOS)
if: runner.os == 'macOS' && matrix.compiler == 'clang'
run: |
@@ -351,7 +347,7 @@ jobs:
echo 'EXTRA_AUTOTOOLS_OPTS='"$EXTRA_AUTOTOOLS_OPTS" >> $GITHUB_ENV
echo 'EXTRA_CMAKE_OPTS='"$EXTRA_CMAKE_OPTS" >> $GITHUB_ENV
- name: Setup libev variables
if: matrix.os == 'macos-14'
if: runner.os == 'macOS'
run: |
LIBEV_CFLAGS="-I/opt/homebrew/Cellar/libev/4.33/include"
LIBEV_LIBS="-L/opt/homebrew/Cellar/libev/4.33/lib -lev"
@@ -365,7 +361,7 @@ jobs:
path: openssl1/build
key: ${{ matrix.os }}-openssl-${{ env.OPENSSL1_VERSION }}
fail-on-cache-miss: true
- name: Restore quictls/openssl v3.x cache
- name: Restore openssl/openssl v3.x cache
uses: actions/cache/restore@v4
if: matrix.openssl == 'openssl3'
with:
@@ -377,8 +373,8 @@ jobs:
if: matrix.openssl == 'boringssl'
with:
path: |
boringssl/build/crypto/libcrypto.a
boringssl/build/ssl/libssl.a
boringssl/build/libcrypto.a
boringssl/build/libssl.a
boringssl/include
key: ${{ matrix.os }}-boringssl-${{ env.BORINGSSL_VERSION }}
fail-on-cache-miss: true
@@ -398,7 +394,7 @@ jobs:
cd boringssl
OPENSSL_CFLAGS="-I$PWD/include/"
OPENSSL_LIBS="-L$PWD/build/ssl -lssl -L$PWD/build/crypto -lcrypto -pthread"
OPENSSL_LIBS="-L$PWD/build -lssl -lcrypto -pthread"
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --without-neverbleed --without-jemalloc --disable-examples"
echo 'OPENSSL_CFLAGS='"$OPENSSL_CFLAGS" >> $GITHUB_ENV
@@ -459,16 +455,16 @@ jobs:
- name: Setup extra environment variables
if: matrix.http3 == 'no-http3'
run: |
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib"
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib64/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib64 -Wl,-rpath,$PWD/openssl3/build/lib"
echo 'PKG_CONFIG_PATH='"$PKG_CONFIG_PATH" >> $GITHUB_ENV
echo 'LDFLAGS='"$LDFLAGS" >> $GITHUB_ENV
- name: Setup extra environment variables for HTTP/3
if: matrix.http3 == 'http3'
run: |
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2-openssl1/build/lib/pkgconfig:$PWD/ngtcp2-openssl3/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
PKG_CONFIG_PATH="$PWD/openssl1/build/lib/pkgconfig:$PWD/openssl3/build/lib64/pkgconfig:$PWD/openssl3/build/lib/pkgconfig:$PWD/wolfssl/build/lib/pkgconfig:$PWD/nghttp3/build/lib/pkgconfig:$PWD/ngtcp2-openssl1/build/lib/pkgconfig:$PWD/ngtcp2-openssl3/build/lib/pkgconfig:$PWD/libbpf/build/lib64/pkgconfig:$PKG_CONFIG_PATH"
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/openssl1/build/lib -Wl,-rpath,$PWD/openssl3/build/lib64 -Wl,-rpath,$PWD/openssl3/build/lib -Wl,-rpath,$PWD/libbpf/build/lib64"
EXTRA_AUTOTOOLS_OPTS="$EXTRA_AUTOTOOLS_OPTS --enable-http3"
EXTRA_CMAKE_OPTS="$EXTRA_CMAKE_OPTS -DENABLE_HTTP3=1"
@@ -528,15 +524,16 @@ jobs:
cd $NGHTTP2_BUILD_DIR
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)"
make -j"$(nproc 2> /dev/null || sysctl -n hw.ncpu)" check
- uses: actions/setup-go@v5
- uses: actions/setup-go@v6
if: matrix.buildtool != 'distcheck'
with:
go-version: "1.22"
go-version: "1.24"
- name: Integration test
# Integration tests for nghttpx; autotools erases build
# artifacts.
if: matrix.buildtool != 'distcheck'
run: |
sudo sh -c 'echo "127.0.0.1 127.0.0.1.nip.io" >> /etc/hosts'
cd $NGHTTP2_BUILD_DIR/integration-tests
make it
@@ -552,7 +549,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- name: Prepare for i386
@@ -600,7 +597,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
submodules: recursive
- uses: microsoft/setup-msbuild@v2
@@ -625,7 +622,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
with:
fetch-depth: 0
submodules: recursive
@@ -642,7 +639,7 @@ jobs:
GPG_KEY: ${{ secrets.GPG_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
- name: Make release
uses: actions/github-script@v7
uses: actions/github-script@v8
with:
script: |
const fs = require('fs')

View File

@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build

View File

@@ -24,7 +24,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
if: failure()
with:
name: artifacts

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- uses: actions/stale@v9
- uses: actions/stale@v10
with:
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
days-before-stale: 30

View File

@@ -80,6 +80,7 @@ Jonas Kvinge
Josh Braegger
José F. Calcerrada
Kamil Dudka
Karthik Dasari
Kazuho Oku
Kenny (kang-yen) Peng
Kenny Peng
@@ -89,6 +90,7 @@ LazyHamster
Leo Neat
Lorenz Nickel
Lucas Pardue
Lukas Märdian
MATSUMOTO Ryosuke
Marc Bachmann
Marcelo Trylesinski
@@ -104,6 +106,7 @@ Nora Shoemaker
Paweł Wegner
Pedro Santos
Peeyush Aggarwal
Peng-Yu Chen
Peter Wu
Piotr Sikora
PufferOverflow
@@ -119,6 +122,7 @@ Ryan Carsten Schmidt
Ryo Ota
Scott Mitchell
Sebastiaan Deckers
Sergei Trofimovich
Sergey Fedorov
Shelley Vohr
Simon Frankenberger
@@ -146,15 +150,18 @@ Ville Vesilehto
Wenfeng Liu
William A Rowe Jr
Xiaoguang Sun
Zachary Turner
Zhuoyun Wei
acesso
ayanamist
bmarques1995
bxshi
clemahieu
dalf
dawg
es
fangdingjun
feicong
hrxi
jwchoi
kumagi

View File

@@ -24,13 +24,13 @@
cmake_minimum_required(VERSION 3.14)
# XXX using 1.8.90 instead of 1.9.0-DEV
project(nghttp2 VERSION 1.65.0 LANGUAGES C)
project(nghttp2 VERSION 1.68.90 LANGUAGES C)
# See versioning rule:
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
set(LT_CURRENT 42)
set(LT_REVISION 4)
set(LT_AGE 28)
set(LT_CURRENT 43)
set(LT_REVISION 2)
set(LT_AGE 29)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
include(Version)
@@ -71,20 +71,8 @@ if(WITH_WOLFSSL)
else()
find_package(OpenSSL 1.1.1)
endif()
find_package(Libngtcp2 1.0.0)
if(OPENSSL_FOUND)
find_package(Libngtcp2_crypto_quictls 1.0.0)
if(LIBNGTCP2_CRYPTO_QUICTLS_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_QUICTLS 1)
endif()
endif()
if(WOLFSSL_FOUND)
find_package(Libngtcp2_crypto_wolfssl 1.0.0)
if(LIBNGTCP2_CRYPTO_WOLFSSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1)
endif()
endif()
find_package(Libnghttp3 1.1.0)
find_package(Libngtcp2 1.15.0)
find_package(Libnghttp3 1.11.0)
if(WITH_LIBBPF)
find_package(Libbpf 0.7.0)
if(NOT LIBBPF_FOUND)
@@ -155,10 +143,10 @@ if(NOT ENABLE_LIB_ONLY)
#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 that std::chrono::time_zone is available.
check_cxx_source_compiles("
#include <map>
int main() { std::map<int, int>().emplace(1, 2); }" HAVE_STD_MAP_EMPLACE)
#include <chrono>
int main() { auto tz = std::chrono::current_zone(); (void)tz; }" HAVE_STD_CHRONO_TIME_ZONE)
cmake_pop_check_state()
endif()
@@ -196,10 +184,14 @@ if(NOT ENABLE_LIB_ONLY AND OPENSSL_FOUND)
if(WIN32)
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}" "ws2_32" "bcrypt")
endif()
check_symbol_exists("LIBRESSL_VERSION_NUMBER" "openssl/opensslv.h" LIBRESSL_FOUND)
if(ENABLE_HTTP3)
check_symbol_exists(SSL_provide_quic_data "openssl/ssl.h" HAVE_SSL_PROVIDE_QUIC_DATA)
if(NOT HAVE_SSL_PROVIDE_QUIC_DATA)
message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} does not have SSL_provide_quic_data. HTTP/3 support cannot be enabled")
check_symbol_exists(SSL_set_quic_tls_cbs "openssl/ssl.h" HAVE_SSL_SET_QUIC_TLS_CBS)
if(NOT HAVE_SSL_SET_QUIC_TLS_CBS)
message(WARNING "OpenSSL in ${OPENSSL_LIBRARIES} has neither SSL_provide_quic_data nor SSL_set_quic_tls_cbs. HTTP/3 support cannot be enabled")
endif()
endif()
endif()
cmake_pop_check_state()
@@ -279,12 +271,41 @@ if(ENABLE_APP AND NOT (ZLIB_FOUND AND (OPENSSL_FOUND OR WOLFSSL_FOUND) AND LIBEV
message(FATAL_ERROR "Applications were requested (ENABLE_APP=1) but dependencies are not met.")
endif()
# HTTP/3 requires libngtcp2 + (quictls/openssl +
# libngtcp2_crypto_quictls or wolfSSL + libngtcp2_crypto_wolfssl) and
# libnghttp3.
if(ENABLE_HTTP3)
if(HAVE_SSL_PROVIDE_QUIC_DATA AND NOT LIBRESSL_FOUND)
find_package(Libngtcp2_crypto_quictls 1.15.0)
if(LIBNGTCP2_CRYPTO_QUICTLS_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_QUICTLS 1)
endif()
elseif(HAVE_SSL_PROVIDE_QUIC_DATA AND LIBRESSL_FOUND)
find_package(Libngtcp2_crypto_libressl 1.15.0)
if(LIBNGTCP2_CRYPTO_LIBRESSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_LIBRESSL 1)
endif()
elseif(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA)
find_package(Libngtcp2_crypto_wolfssl 1.15.0)
if(LIBNGTCP2_CRYPTO_WOLFSSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1)
endif()
elseif(HAVE_SSL_SET_QUIC_TLS_CBS)
find_package(Libngtcp2_crypto_ossl 1.15.0)
if(LIBNGTCP2_CRYPTO_OSSL_FOUND)
set(HAVE_LIBNGTCP2_CRYPTO_OSSL 1)
endif()
endif()
endif()
# HTTP/3 requires libngtcp2 + nghttp3 + one of:
#
# - quictls/openssl + libngtcp2_crypto_quictls
# - libressl + libngtcp2_crypto_libressl
# - wolfSSL + libngtcp2_crypto_wolfssl
# - openssl/openssl + libngtcp2_crypto_ossl
if(ENABLE_HTTP3 AND NOT (LIBNGTCP2_FOUND AND LIBNGHTTP3_FOUND AND
((HAVE_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_QUICTLS_FOUND) OR
(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_WOLFSSL_FOUND))))
((HAVE_SSL_PROVIDE_QUIC_DATA AND NOT LIBRESSL_FOUND AND LIBNGTCP2_CRYPTO_QUICTLS_FOUND) OR
(HAVE_SSL_PROVIDE_QUIC_DATA AND LIBRESSL_FOUND AND LIBNGTCP2_CRYPTO_LIBRESSL_FOUND) OR
(HAVE_WOLFSSL_SSL_PROVIDE_QUIC_DATA AND LIBNGTCP2_CRYPTO_WOLFSSL_FOUND) OR
(HAVE_SSL_SET_QUIC_TLS_CBS AND LIBNGTCP2_CRYPTO_OSSL_FOUND))))
message(FATAL_ERROR "HTTP/3 was requested (ENABLE_HTTP3=1) but dependencies are not met.")
endif()
@@ -361,7 +382,7 @@ check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
check_function_exists(mkostemp HAVE_MKOSTEMP)
check_function_exists(pipe2 HAVE_PIPE2)
check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64)
check_symbol_exists(GetTickCount64 "windows.h;sysinfoapi.h" HAVE_GETTICKCOUNT64)
include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin?
@@ -478,7 +499,6 @@ if(ENABLE_DOC)
add_subdirectory(doc)
endif()
add_subdirectory(contrib)
add_subdirectory(script)
add_subdirectory(bpf)
@@ -512,6 +532,7 @@ message(STATUS "summary of build options:
Libc-ares: ${HAVE_LIBCARES} (LIBS='${LIBCARES_LIBRARIES}')
Libngtcp2: ${HAVE_LIBNGTCP2} (LIBS='${LIBNGTCP2_LIBRARIES}')
Libngtcp2_crypto_quictls: ${HAVE_LIBNGTCP2_CRYPTO_QUICTLS} (LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}')
Libngtcp2_crypto_libressl: ${HAVE_LIBNGTCP2_CRYPTO_LIBRESSL} (LIBS='${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES}')
Libngtcp2_crypto_wolfssl: ${HAVE_LIBNGTCP2_CRYPTO_WOLFSSL} (LIBS='${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}')
Libnghttp3: ${HAVE_LIBNGHTTP3} (LIBS='${LIBNGHTTP3_LIBRARIES}')
Libbpf: ${HAVE_LIBBPF} (LIBS='${LIBBPF_LIBRARIES}')

View File

@@ -12,21 +12,21 @@
# Only use standalone-toolchain for reduce size
FROM ubuntu:22.04
MAINTAINER Tatsuhiro Tsujikawa
FROM ubuntu:24.04
LABEL org.opencontainers.image.authors="Tatsuhiro Tsujikawa"
ENV NDK_VERSION r26d
ENV NDK /root/android-ndk-$NDK_VERSION
ENV TOOLCHAIN $NDK/toolchains/llvm/prebuilt/linux-x86_64
ENV TARGET aarch64-linux-android
ENV API 33
ENV AR $TOOLCHAIN/bin/llvm-ar
ENV CC $TOOLCHAIN/bin/$TARGET$API-clang
ENV CXX $TOOLCHAIN/bin/$TARGET$API-clang++
ENV LD $TOOLCHAIN/bin/ld
ENV RANDLIB $TOOLCHAIN/bin/llvm-ranlib
ENV STRIP $TOOLCHAIN/bin/llvm-strip
ENV PREFIX /root/usr/local
ARG NDK_VERSION=r27c
ARG NDK=/root/android-ndk-$NDK_VERSION
ARG TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
ARG TARGET=aarch64-linux-android
ARG API=33
ARG AR=$TOOLCHAIN/bin/llvm-ar
ARG CC=$TOOLCHAIN/bin/$TARGET$API-clang
ARG CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
ARG LD=$TOOLCHAIN/bin/ld
ARG RANDLIB=$TOOLCHAIN/bin/llvm-ranlib
ARG STRIP=$TOOLCHAIN/bin/llvm-strip
ARG PREFIX=/root/usr/local
WORKDIR /root
RUN apt-get update && \
@@ -42,11 +42,11 @@ RUN curl -L -O https://dl.google.com/android/repository/android-ndk-$NDK_VERSION
rm android-ndk-$NDK_VERSION-linux.zip
# Setup version of libraries
ENV OPENSSL_VERSION 1.1.1w
ENV LIBEV_VERSION 4.33
ENV ZLIB_VERSION 1.3.1
ENV CARES_VERSION 1.18.1
ENV NGHTTP2_VERSION master
ARG OPENSSL_VERSION=1.1.1w
ARG LIBEV_VERSION=4.33
ARG ZLIB_VERSION=1.3.1
ARG CARES_VERSION=1.18.1
ARG NGHTTP2_VERSION=master
WORKDIR /root/build
RUN curl -L -O https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz && \
@@ -105,7 +105,7 @@ RUN ./configure \
make install
WORKDIR /root/build
RUN git clone https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
RUN git clone --recursive --shallow-submodules https://github.com/nghttp2/nghttp2 -b $NGHTTP2_VERSION --depth 1
WORKDIR /root/build/nghttp2
RUN autoreconf -i && \
./configure \
@@ -119,6 +119,6 @@ RUN autoreconf -i && \
--disable-threads \
CPPFLAGS="-fPIE -I$PREFIX/include" \
PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
LDFLAGS="-fPIE -pie -L$PREFIX/lib" && \
LDFLAGS="-static-libstdc++ -static-libgcc -fPIE -pie -L$PREFIX/lib" && \
make && \
$STRIP src/nghttpx src/nghttpd src/nghttp

View File

@@ -20,8 +20,8 @@
# 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.
SUBDIRS = lib third-party src bpf examples tests integration-tests \
doc contrib script
SUBDIRS = lib tests third-party src bpf examples integration-tests \
doc contrib
ACLOCAL_AMFLAGS = -I m4
@@ -47,6 +47,7 @@ EXTRA_DIST = nghttpx.conf.sample proxy.pac.sample android-config android-env \
cmake/FindLibbrotlienc.cmake \
cmake/FindLibbrotlidec.cmake \
cmake/FindLibngtcp2_crypto_wolfssl.cmake \
cmake/FindLibngtcp2_crypto_ossl.cmake \
cmake/FindWolfSSL.cmake \
cmake/PickyWarningsC.cmake \
cmake/PickyWarningsCXX.cmake

View File

@@ -31,9 +31,8 @@ implementation.
* https://nghttp2.org/ (TLS + ALPN and HTTP/3)
This endpoint supports ``h2``, ``h2-16``, ``h2-14``, and
``http/1.1`` via ALPN and requires TLSv1.2 for HTTP/2
connection.
This endpoint supports ``h2`` and ``http/1.1`` via ALPN and requires
TLSv1.2 for HTTP/2 connection.
It also supports HTTP/3.
@@ -123,13 +122,13 @@ exploited. The neverbleed is disabled by default. To enable it, use
To enable the experimental HTTP/3 support for h2load and nghttpx, the
following libraries are required:
* `OpenSSL with QUIC support
* `quictls
<https://github.com/quictls/openssl/tree/OpenSSL_1_1_1w+quic>`_; or
wolfSSL; or LibreSSL (does not support 0RTT); or aws-lc; or
`BoringSSL <https://boringssl.googlesource.com/boringssl/>`_ (commit
294ab9730c570213b496cfc2fc14b3c0bfcd4bcc)
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ >= 1.4.0
* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ >= 1.1.0
db1a8456167249f95b854a1cd24c6b553d0f1567); or OpenSSL >= 3.5.0
* `ngtcp2 <https://github.com/ngtcp2/ngtcp2>`_ >= 1.16.0
* `nghttp3 <https://github.com/ngtcp2/nghttp3>`_ >= 1.12.0
Use ``--enable-http3`` configure option to enable HTTP/3 feature for
h2load and nghttpx.
@@ -151,7 +150,7 @@ executable.
Compiling libnghttp2 C source code requires a C99 compiler. gcc 4.8
is known to be adequate. In order to compile the C++ source code,
C++20 compliant compiler is required. At least g++ >= 12 and
clang++ >= 15 are known to work.
clang++ >= 18 are known to work.
.. note::
@@ -341,7 +340,7 @@ Build aws-lc:
.. code-block:: text
$ git clone --depth 1 -b v1.46.1 https://github.com/aws/aws-lc
$ git clone --depth 1 -b v1.62.0 https://github.com/aws/aws-lc
$ cd aws-lc
$ cmake -B build -DDISABLE_GO=ON --install-prefix=$PWD/opt
$ make -j$(nproc) -C build
@@ -352,7 +351,7 @@ Build nghttp3:
.. code-block:: text
$ git clone --depth 1 -b v1.8.0 https://github.com/ngtcp2/nghttp3
$ git clone --depth 1 -b v1.12.0 https://github.com/ngtcp2/nghttp3
$ cd nghttp3
$ git submodule update --init --depth 1
$ autoreconf -i
@@ -365,7 +364,7 @@ Build ngtcp2:
.. code-block:: text
$ git clone --depth 1 -b v1.11.0 https://github.com/ngtcp2/ngtcp2
$ git clone --depth 1 -b v1.17.0 https://github.com/ngtcp2/ngtcp2
$ cd ngtcp2
$ git submodule update --init --depth 1
$ autoreconf -i
@@ -381,7 +380,7 @@ from source:
.. code-block:: text
$ git clone --depth 1 -b v1.5.0 https://github.com/libbpf/libbpf
$ git clone --depth 1 -b v1.6.2 https://github.com/libbpf/libbpf
$ cd libbpf
$ PREFIX=$PWD/build make -C src install
$ cd ..
@@ -395,7 +394,7 @@ Build nghttp2:
$ git submodule update --init
$ autoreconf -i
$ ./configure --with-mruby --enable-http3 --with-libbpf \
CC=clang-15 CXX=clang++-15 \
CC=clang-19 CXX=clang++-19 \
PKG_CONFIG_PATH="$PWD/../aws-lc/opt/lib/pkgconfig:$PWD/../nghttp3/build/lib/pkgconfig:$PWD/../ngtcp2/build/lib/pkgconfig:$PWD/../libbpf/build/lib64/pkgconfig" \
LDFLAGS="$LDFLAGS -Wl,-rpath,$PWD/../aws-lc/opt/lib -Wl,-rpath,$PWD/../libbpf/build/lib64"
$ make -j$(nproc)
@@ -847,10 +846,10 @@ 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
stapling, dynamic record sizing, ALPN, forward secrecy and HTTP/2.
``nghttpx`` also offers the functionality to share session cache and
ticket keys among multiple ``nghttpx`` instances via memcached.
session IDs, session tickets (with automatic key rotation), dynamic
record sizing, ALPN, forward secrecy and HTTP/2. ``nghttpx`` also
offers the functionality to share ticket keys among multiple
``nghttpx`` instances via memcached.
``nghttpx`` has 2 operation modes:

View File

@@ -0,0 +1,43 @@
# - Try to find libngtcp2_crypto_libressl
# Once done this will define
# LIBNGTCP2_CRYPTO_LIBRESSL_FOUND - System has libngtcp2_crypto_libressl
# LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS - The libngtcp2_crypto_libressl include directories
# LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_libressl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_LIBRESSL QUIET libngtcp2_crypto_libressl)
find_path(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_quictls.h
HINTS ${PC_LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY
NAMES ngtcp2_crypto_libressl
HINTS ${PC_LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_LIBRESSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_LIBRESSL_VERSION "${LIBNGTCP2_CRYPTO_LIBRESSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_LIBRESSL_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_libressl REQUIRED_VARS
LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY
LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_LIBRESSL_VERSION)
if(LIBNGTCP2_CRYPTO_LIBRESSL_FOUND)
set(LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES ${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY})
set(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIR
LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARY)

View File

@@ -0,0 +1,43 @@
# - Try to find libngtcp2_crypto_ossl
# Once done this will define
# LIBNGTCP2_CRYPTO_OSSL_FOUND - System has libngtcp2_crypto_ossl
# LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS - The libngtcp2_crypto_ossl include directories
# LIBNGTCP2_CRYPTO_OSSL_LIBRARIES - The libraries needed to use libngtcp2_crypto_ossl
find_package(PkgConfig QUIET)
pkg_check_modules(PC_LIBNGTCP2_CRYPTO_OSSL QUIET libngtcp2_crypto_ossl)
find_path(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
NAMES ngtcp2/ngtcp2_crypto_ossl.h
HINTS ${PC_LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS}
)
find_library(LIBNGTCP2_CRYPTO_OSSL_LIBRARY
NAMES ngtcp2_crypto_ossl
HINTS ${PC_LIBNGTCP2_CRYPTO_OSSL_LIBRARY_DIRS}
)
if(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR)
set(_version_regex "^#define[ \t]+NGTCP2_VERSION[ \t]+\"([^\"]+)\".*")
file(STRINGS "${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR}/ngtcp2/version.h"
LIBNGTCP2_CRYPTO_OSSL_VERSION REGEX "${_version_regex}")
string(REGEX REPLACE "${_version_regex}" "\\1"
LIBNGTCP2_CRYPTO_OSSL_VERSION "${LIBNGTCP2_CRYPTO_OSSL_VERSION}")
unset(_version_regex)
endif()
include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set
# LIBNGTCP2_CRYPTO_OSSL_FOUND to TRUE if all listed variables are
# TRUE and the requested version matches.
find_package_handle_standard_args(Libngtcp2_crypto_ossl REQUIRED_VARS
LIBNGTCP2_CRYPTO_OSSL_LIBRARY
LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
VERSION_VAR LIBNGTCP2_CRYPTO_OSSL_VERSION)
if(LIBNGTCP2_CRYPTO_OSSL_FOUND)
set(LIBNGTCP2_CRYPTO_OSSL_LIBRARIES ${LIBNGTCP2_CRYPTO_OSSL_LIBRARY})
set(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS ${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR})
endif()
mark_as_advanced(LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIR
LIBNGTCP2_CRYPTO_OSSL_LIBRARY)

View File

@@ -4,8 +4,8 @@
/* 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 the `std::chrono::time_zone`. */
#cmakedefine HAVE_STD_CHRONO_TIME_ZONE 1
/* Define to 1 if you have `libjansson` library. */
#cmakedefine HAVE_JANSSON 1
@@ -100,6 +100,9 @@
/* Define to 1 if you have `libngtcp2_crypto_quictls` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_QUICTLS
/* Define to 1 if you have `libngtcp2_crypto_libressl` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_LIBRESSL
/* Define to 1 if you have `libngtcp2_crypto_wolfssl` library. */
#cmakedefine HAVE_LIBNGTCP2_CRYPTO_WOLFSSL 1

View File

@@ -25,7 +25,7 @@ dnl Do not change user variables!
dnl https://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html
AC_PREREQ(2.61)
AC_INIT([nghttp2], [1.65.0], [t-tujikawa@users.sourceforge.net])
AC_INIT([nghttp2], [1.69.0-DEV], [t-tujikawa@users.sourceforge.net])
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
@@ -44,9 +44,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
dnl See versioning rule:
dnl https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
AC_SUBST(LT_CURRENT, 42)
AC_SUBST(LT_REVISION, 4)
AC_SUBST(LT_AGE, 28)
AC_SUBST(LT_CURRENT, 43)
AC_SUBST(LT_REVISION, 2)
AC_SUBST(LT_AGE, 29)
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"`
@@ -272,22 +272,6 @@ std::vector<std::future<int>> v;
[have_std_future=no
AC_MSG_RESULT([no])])
# Check that std::map::emplace is available for g++-4.7.
AC_MSG_CHECKING([whether std::map::emplace is available])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <map>
]],
[[
std::map<int, int>().emplace(1, 2);
]])],
[AC_DEFINE([HAVE_STD_MAP_EMPLACE], [1],
[Define to 1 if you have the `std::map::emplace`.])
have_std_map_emplace=yes
AC_MSG_RESULT([yes])],
[have_std_map_emplace=no
AC_MSG_RESULT([no])])
# Check that std::atomic<std::shared_ptr<T>> is supported.
AC_MSG_CHECKING([whether std::atomic<std::shared_ptr<T>> is supported])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
@@ -307,19 +291,21 @@ a.store(p);
[have_atomic_std_shared_ptr=no
AC_MSG_RESULT([no])])
# Check that thread_local storage specifier is available
AC_MSG_CHECKING([whether thread_local storage class specifier is available.])
# Check that std::chrono::time_zone is available.
AC_MSG_CHECKING([whether std::chrono::time_zone is available])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
,
[[
thread_local int a = 0;
(void)a;
#include <chrono>
]],
[[
auto tz = std::chrono::current_zone();
(void)tz;
]])],
[AC_DEFINE([HAVE_THREAD_LOCAL], [1],
[Define to 1 if you have thread_local storage specifier.])
have_thread_local=yes
[AC_DEFINE([HAVE_STD_CHRONO_TIME_ZONE], [1],
[Define to 1 if you have the `std::chrono::time_zone`.])
have_std_chrono_time_zone=yes
AC_MSG_RESULT([yes])],
[have_Thread_local=no
[have_std_chrono_time_zone=no
AC_MSG_RESULT([no])])
CXXFLAGS=$save_CXXFLAGS
@@ -450,6 +436,22 @@ if test "x${request_openssl}" != "xno" &&
[AC_MSG_RESULT([yes]); have_ssl_provide_quic_data=yes],
[AC_MSG_RESULT([no]); have_ssl_provide_quic_data=no])
# Check whether this is libressl or not
AC_CHECK_DECLS([LIBRESSL_VERSION_NUMBER],
[have_libressl=yes], [have_libressl=no],
[[
#include <openssl/opensslv.h>
]])
AC_MSG_CHECKING([for SSL_set_quic_tls_cbs])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <openssl/ssl.h>
]], [[
SSL_set_quic_tls_cbs(NULL, NULL, NULL);
]])],
[AC_MSG_RESULT([yes]); have_ossl_quic=yes],
[AC_MSG_RESULT([no]); have_ossl_quic=no])
# boringssl has SSL_set_quic_early_data_context.
AC_MSG_CHECKING([for SSL_set_quic_early_data_context])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
@@ -530,7 +532,7 @@ fi
# ngtcp2 (for src)
have_libngtcp2=no
if test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 1.4.0], [have_libngtcp2=yes],
PKG_CHECK_MODULES([LIBNGTCP2], [libngtcp2 >= 1.16.0], [have_libngtcp2=yes],
[have_libngtcp2=no])
if test "x${have_libngtcp2}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_PKG_ERRORS)
@@ -547,7 +549,7 @@ have_libngtcp2_crypto_wolfssl=no
if test "x${have_wolfssl_quic}" = "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_WOLFSSL],
[libngtcp2_crypto_wolfssl >= 1.0.0],
[libngtcp2_crypto_wolfssl >= 1.16.0],
[have_libngtcp2_crypto_wolfssl=yes],
[have_libngtcp2_crypto_wolfssl=no])
if test "x${have_libngtcp2_crypto_wolfssl}" = "xno"; then
@@ -567,10 +569,11 @@ fi
# ngtcp2_crypto_quictls (for src)
have_libngtcp2_crypto_quictls=no
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" != "xyes" &&
test "x${have_boringssl_quic}" != "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_QUICTLS],
[libngtcp2_crypto_quictls >= 1.0.0],
[libngtcp2_crypto_quictls >= 1.16.0],
[have_libngtcp2_crypto_quictls=yes],
[have_libngtcp2_crypto_quictls=no])
if test "x${have_libngtcp2_crypto_quictls}" = "xno"; then
@@ -582,12 +585,37 @@ if test "x${have_ssl_provide_quic_data}" = "xyes" &&
fi
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" != "xyes" &&
test "x${have_boringssl_quic}" != "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_quictls}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_quictls was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_libressl (for src)
have_libngtcp2_crypto_libressl=no
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" = "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_LIBRESSL],
[libngtcp2_crypto_libressl >= 1.16.0],
[have_libngtcp2_crypto_libressl=yes],
[have_libngtcp2_crypto_libressl=no])
if test "x${have_libngtcp2_crypto_libressl}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_LIBRESSL_PKG_ERRORS)
else
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_LIBRESSL], [1],
[Define to 1 if you have `libngtcp2_crypto_libressl` library.])
fi
fi
if test "x${have_ssl_provide_quic_data}" = "xyes" &&
test "x${have_libressl}" = "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_libressl}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_libressl was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_boringssl (for src)
have_libngtcp2_crypto_boringssl=no
if test "x${have_boringssl_quic}" = "xyes" &&
@@ -610,10 +638,32 @@ if test "x${have_boringssl_quic}" = "xyes" &&
AC_MSG_ERROR([libngtcp2_crypto_boringssl was requested (--with-libngtcp2) but not found])
fi
# ngtcp2_crypto_ossl (for src)
have_libngtcp2_crypto_ossl=no
if test "x${have_ossl_quic}" = "xyes" &&
test "x${request_libngtcp2}" != "xno"; then
PKG_CHECK_MODULES([LIBNGTCP2_CRYPTO_OSSL],
[libngtcp2_crypto_ossl >= 1.16.0],
[have_libngtcp2_crypto_ossl=yes],
[have_libngtcp2_crypto_ossl=no])
if test "x${have_libngtcp2_crypto_ossl}" = "xno"; then
AC_MSG_NOTICE($LIBNGTCP2_CRYPTO_OSSL_PKG_ERRORS)
else
AC_DEFINE([HAVE_LIBNGTCP2_CRYPTO_OSSL], [1],
[Define to 1 if you have `libngtcp2_crypto_ossl` library.])
fi
fi
if test "x${have_ossl_quic}" = "xyes" &&
test "x${request_libngtcp2}" = "xyes" &&
test "x${have_libngtcp2_crypto_ossl}" != "xyes"; then
AC_MSG_ERROR([libngtcp2_crypto_ossl was requested (--with-libngtcp2) but not found])
fi
# nghttp3 (for src)
have_libnghttp3=no
if test "x${request_libnghttp3}" != "xno"; then
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 1.1.0], [have_libnghttp3=yes],
PKG_CHECK_MODULES([LIBNGHTTP3], [libnghttp3 >= 1.12.0], [have_libnghttp3=yes],
[have_libnghttp3=no])
if test "x${have_libnghttp3}" = "xno"; then
AC_MSG_NOTICE($LIBNGHTTP3_PKG_ERRORS)
@@ -842,7 +892,9 @@ if test "x${request_http3}" != "xno" &&
test "x${have_libngtcp2}" = "xyes" &&
(test "x${have_libngtcp2_crypto_wolfssl}" = "xyes" ||
test "x${have_libngtcp2_crypto_quictls}" = "xyes" ||
test "x${have_libngtcp2_crypto_boringssl}" = "xyes") &&
test "x${have_libngtcp2_crypto_libressl}" = "xyes" ||
test "x${have_libngtcp2_crypto_boringssl}" = "xyes" ||
test "x${have_libngtcp2_crypto_ossl}" = "xyes") &&
test "x${have_libnghttp3}" = "xyes"; then
enable_http3=yes
AC_DEFINE([ENABLE_HTTP3], [1], [Define to 1 if HTTP/3 is enabled.])
@@ -1135,6 +1187,7 @@ if test "x$werror" != "xno"; then
AX_CHECK_COMPILE_FLAG([-Wformat-security], [CXXFLAGS="$CXXFLAGS -Wformat-security"])
AX_CHECK_COMPILE_FLAG([-Wsometimes-uninitialized], [CXXFLAGS="$CXXFLAGS -Wsometimes-uninitialized"])
AX_CHECK_COMPILE_FLAG([-Wextra-semi], [CXXFLAGS="$CXXFLAGS -Wextra-semi"])
AX_CHECK_COMPILE_FLAG([-Wconversion], [CXXFLAGS="$CXXFLAGS -Wconversion"])
# Disable noexcept-type warning of g++-7. This is not harmful as
# long as all source files are compiled with the same compiler.
AX_CHECK_COMPILE_FLAG([-Wno-noexcept-type], [CXXFLAGS="$CXXFLAGS -Wno-noexcept-type"])
@@ -1206,7 +1259,6 @@ AC_CONFIG_FILES([
doc/nghttp2ver.h.rst
doc/contribute.rst
contrib/Makefile
script/Makefile
])
AC_OUTPUT
@@ -1255,7 +1307,9 @@ AC_MSG_NOTICE([summary of build options:
Libc-ares: ${have_libcares} (CFLAGS='${LIBCARES_CFLAGS}' LIBS='${LIBCARES_LIBS}')
libngtcp2: ${have_libngtcp2} (CFLAGS='${LIBNGTCP2_CFLAGS}' LIBS='${LIBNGTCP2_LIBS}')
libngtcp2_crypto_quictls: ${have_libngtcp2_crypto_quictls} (CFLAGS='${LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_QUICTLS_LIBS}')
libngtcp2_crypto_libressl: ${have_libngtcp2_crypto_libressl} (CFLAGS='${LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_LIBRESSL_LIBS}')
libngtcp2_crypto_boringssl: ${have_libngtcp2_crypto_boringssl} (CFLAGS='${LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_BORINGSSL_LIBS}')
libngtcp2_crypto_ossl: ${have_libngtcp2_crypto_ossl} (CFLAGS='${LIBNGTCP2_CRYPTO_OSSL_CFLAGS}' LIBS='${LIBNGTCP2_CRYPTO_OSSL_LIBS}')
libnghttp3: ${have_libnghttp3} (CFLAGS='${LIBNGHTTP3_CFLAGS}' LIBS='${LIBNGHTTP3_LIBS}')
libbpf: ${have_libbpf} (CFLAGS='${LIBBPF_CFLAGS}' LIBS='${LIBBPF_LIBS}')
Libevent(SSL): ${have_libevent_openssl} (CFLAGS='${LIBEVENT_OPENSSL_CFLAGS}' LIBS='${LIBEVENT_OPENSSL_LIBS}')

View File

@@ -81,6 +81,7 @@ APIDOCS= \
nghttp2_option_set_max_outbound_ack.rst \
nghttp2_option_set_max_settings.rst \
nghttp2_option_set_stream_reset_rate_limit.rst \
nghttp2_option_set_glitch_rate_limit.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_pack_settings_payload2.rst \
nghttp2_priority_spec_check_default.rst \
@@ -114,6 +115,7 @@ APIDOCS= \
nghttp2_session_callbacks_set_on_stream_close_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback.rst \
nghttp2_session_callbacks_set_pack_extension_callback2.rst \
nghttp2_session_callbacks_set_rand_callback.rst \
nghttp2_session_callbacks_set_recv_callback.rst \
nghttp2_session_callbacks_set_recv_callback2.rst \
nghttp2_session_callbacks_set_select_padding_callback.rst \

View File

@@ -111,7 +111,7 @@ The example follows::
``@struct`` is used to refer to the struct. Currently, only struct
typedefs are supported. The comment block is used for the document for
the struct type itself.To document each member, put comment block
the struct type itself. To document each member, put comment block
starting with the line ``/**`` and ending with the ``*/`` just before
the member. When the line starts with ``}`` is encountered, the
``mkapiref.py`` extracts strings next to ``}`` as the name of struct.

View File

@@ -1,14 +0,0 @@
# -*- coding: utf-8 -*-
"""
sphinxcontrib
~~~~~~~~~~~~~
This package is a namespace package that contains all extensions
distributed in the ``sphinx-contrib`` distribution.
:copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
__import__('pkg_resources').declare_namespace(__name__)

View File

@@ -8,7 +8,7 @@ _nghttpd()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --ktls --version --help ' -- "$cur" ) )
COMPREPLY=( $( compgen -W '--address --daemon --verify-client --htdocs --verbose --no-tls --header-table-size --encoder-header-table-size --color --push --padding --max-concurrent-streams --workers --error-gzip --window-bits --connection-window-bits --dh-param-file --early-response --trailer --hexdump --echo-upload --mime-types-file --no-content-length --groups --ktls --version --help ' -- "$cur" ) )
;;
*)
_filedir

View File

@@ -8,7 +8,7 @@ _nghttpx()
_get_comp_words_by_ref cur prev
case $cur in
-*)
COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-idle-timeout --frontend-http3-idle-timeout --frontend-write-timeout --frontend-keep-alive-timeout --frontend-header-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --ecdh-curves --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --alpn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --fetch-ocsp-response-file --ocsp-update-interval --ocsp-startup --no-verify-ocsp --no-ocsp --tls-session-cache-memcached --tls-session-cache-memcached-address-family --tls-session-cache-memcached-cert-file --tls-session-cache-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --tls-ktls --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-window-size --frontend-http2-encoder-dynamic-table-size --frontend-http2-decoder-dynamic-table-size --backend-http2-encoder-dynamic-table-size --backend-http2-decoder-dynamic-table-size --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --require-http-scheme --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
COMPREPLY=( $( compgen -W '--backend --frontend --backlog --backend-address-family --backend-http-proxy-uri --workers --single-thread --read-rate --read-burst --write-rate --write-burst --worker-read-rate --worker-read-burst --worker-write-rate --worker-write-burst --worker-frontend-connections --backend-connections-per-host --backend-connections-per-frontend --rlimit-nofile --rlimit-memlock --backend-request-buffer --backend-response-buffer --fastopen --no-kqueue --frontend-http2-idle-timeout --frontend-http3-idle-timeout --frontend-write-timeout --frontend-keep-alive-timeout --frontend-header-timeout --stream-read-timeout --stream-write-timeout --backend-read-timeout --backend-write-timeout --backend-connect-timeout --backend-keep-alive-timeout --listener-disable-timeout --frontend-http2-setting-timeout --backend-http2-settings-timeout --backend-max-backoff --ciphers --tls13-ciphers --client-ciphers --tls13-client-ciphers --groups --insecure --cacert --private-key-passwd-file --subcert --dh-param-file --alpn-list --verify-client --verify-client-cacert --verify-client-tolerate-expired --client-private-key-file --client-cert-file --tls-min-proto-version --tls-max-proto-version --tls-ticket-key-file --tls-ticket-key-memcached --tls-ticket-key-memcached-address-family --tls-ticket-key-memcached-interval --tls-ticket-key-memcached-max-retry --tls-ticket-key-memcached-max-fail --tls-ticket-key-cipher --tls-ticket-key-memcached-cert-file --tls-ticket-key-memcached-private-key-file --tls-dyn-rec-warmup-threshold --tls-dyn-rec-idle-timeout --no-http2-cipher-block-list --client-no-http2-cipher-block-list --tls-sct-dir --psk-secrets --client-psk-secrets --tls-no-postpone-early-data --tls-max-early-data --tls-ktls --frontend-http2-max-concurrent-streams --backend-http2-max-concurrent-streams --frontend-http2-window-size --frontend-http2-connection-window-size --backend-http2-window-size --backend-http2-connection-window-size --http2-no-cookie-crumbling --padding --no-server-push --frontend-http2-optimize-write-buffer-size --frontend-http2-optimize-window-size --frontend-http2-encoder-dynamic-table-size --frontend-http2-decoder-dynamic-table-size --backend-http2-encoder-dynamic-table-size --backend-http2-decoder-dynamic-table-size --http2-proxy --log-level --accesslog-file --accesslog-syslog --accesslog-format --accesslog-write-early --errorlog-file --errorlog-syslog --syslog-facility --add-x-forwarded-for --strip-incoming-x-forwarded-for --no-add-x-forwarded-proto --no-strip-incoming-x-forwarded-proto --add-forwarded --strip-incoming-forwarded --forwarded-by --forwarded-for --no-via --no-strip-incoming-early-data --no-location-rewrite --host-rewrite --altsvc --http2-altsvc --add-request-header --add-response-header --request-header-field-buffer --max-request-header-fields --response-header-field-buffer --max-response-header-fields --error-page --server-name --no-server-rewrite --redirect-https-port --require-http-scheme --api-max-request-body --dns-cache-timeout --dns-lookup-timeout --dns-max-try --frontend-max-requests --frontend-http2-dump-request-header --frontend-http2-dump-response-header --frontend-frame-debug --daemon --pid-file --user --single-process --max-worker-processes --worker-process-grace-shutdown-period --mruby-file --ignore-per-pattern-mruby-error --frontend-quic-idle-timeout --frontend-quic-debug-log --quic-bpf-program-file --frontend-quic-early-data --frontend-quic-qlog-dir --frontend-quic-require-token --frontend-quic-congestion-controller --frontend-quic-secret-file --quic-server-id --frontend-quic-initial-rtt --no-quic-bpf --frontend-http3-window-size --frontend-http3-connection-window-size --frontend-http3-max-window-size --frontend-http3-max-connection-window-size --frontend-http3-max-concurrent-streams --conf --include --version --help ' -- "$cur" ) )
;;
*)
_filedir

View File

@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "H2LOAD" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
.TH "H2LOAD" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
.SH NAME
h2load \- HTTP/2 benchmarking tool
.SH SYNOPSIS
@@ -109,9 +109,9 @@ Default: \fB16K\fP
.TP
.B \-w, \-\-window\-bits=<N>
Sets the stream level initial window size to (2**<N>)\-1.
For QUIC, <N> is capped to 26 (roughly 64MiB).
.sp
Default: \fB30\fP
For QUIC, <N> is capped to 26 (roughly 64MiB). It
defaults to 24 (16MiB) for QUIC, and 30 for other
protocols.
.UNINDENT
.INDENT 0.0
.TP
@@ -262,7 +262,7 @@ protocol comes first. The parameter must be delimited
by a single comma only and any white spaces are treated
as a part of protocol string.
.sp
Default: \fBh2,h2\-16,h2\-14,http/1.1\fP
Default: \fBh2,http/1.1\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -388,7 +388,7 @@ The number of requests completed.
.TP
.B succeeded
The number of requests completed successfully. Only HTTP status
code 2xx or3xx are considered as success.
code 2xx or 3xx are considered as success.
.TP
.B failed
The number of requests failed, including HTTP level failures

View File

@@ -83,9 +83,9 @@ OPTIONS
.. option:: -w, --window-bits=<N>
Sets the stream level initial window size to (2\*\*<N>)-1.
For QUIC, <N> is capped to 26 (roughly 64MiB).
Default: ``30``
For QUIC, <N> is capped to 26 (roughly 64MiB). It
defaults to 24 (16MiB) for QUIC, and 30 for other
protocols.
.. option:: -W, --connection-window-bits=<N>
@@ -221,7 +221,7 @@ OPTIONS
by a single comma only and any white spaces are treated
as a part of protocol string.
Default: ``h2,h2-16,h2-14,http/1.1``
Default: ``h2,http/1.1``
.. option:: --h1
@@ -331,7 +331,7 @@ requests
The number of requests completed.
succeeded
The number of requests completed successfully. Only HTTP status
code 2xx or3xx are considered as success.
code 2xx or 3xx are considered as success.
failed
The number of requests failed, including HTTP level failures
(non-successful HTTP status code).

View File

@@ -12,7 +12,7 @@ requests
The number of requests completed.
succeeded
The number of requests completed successfully. Only HTTP status
code 2xx or3xx are considered as success.
code 2xx or 3xx are considered as success.
failed
The number of requests failed, including HTTP level failures
(non-successful HTTP status code).

View File

@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "NGHTTP" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
.TH "NGHTTP" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
.SH NAME
nghttp \- HTTP/2 client
.SH SYNOPSIS
@@ -243,11 +243,6 @@ Enable ktls.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-rfc7540\-pri
Disable RFC7540 priorities.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-version
Display version information and exit.
.UNINDENT

View File

@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "NGHTTPD" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
.TH "NGHTTPD" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
.SH NAME
nghttpd \- HTTP/2 server
.SH SYNOPSIS
@@ -204,6 +204,13 @@ Don\(aqt send content\-length header field.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-groups=<GROUPS>
Specify the supported groups.
.sp
Default: \fBX25519:P\-256:P\-384:P\-521\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ktls
Enable ktls.
.UNINDENT

View File

@@ -159,6 +159,12 @@ OPTIONS
Don't send content-length header field.
.. option:: --groups=<GROUPS>
Specify the supported groups.
Default: ``X25519:P-256:P-384:P-521``
.. option:: --ktls
Enable ktls.

View File

@@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "NGHTTPX" "1" "Jan 12, 2025" "1.65.0-DEV" "nghttp2"
.TH "NGHTTPX" "1" "Oct 25, 2025" "1.68.0" "nghttp2"
.SH NAME
nghttpx \- HTTP/2 proxy
.SH SYNOPSIS
@@ -46,8 +46,7 @@ Set path to server\(aqs private key. Required unless
.TP
.B <CERT>
Set path to server\(aqs certificate. Required unless
\(dqno\-tls\(dq parameter is used in \fI\%\-\-frontend\fP option. To
make OCSP stapling work, this must be an absolute path.
\(dqno\-tls\(dq parameter is used in \fI\%\-\-frontend\fP option.
.UNINDENT
.SH OPTIONS
.sp
@@ -688,8 +687,8 @@ Default: \fB2m\fP
.B \-\-ciphers=<SUITE>
Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use \fI\%\-\-tls13\-ciphers\fP for TLSv1.3.
This option sets cipher suites for TLSv1.2. Use
\fI\%\-\-tls13\-ciphers\fP for TLSv1.3.
.sp
Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384\fP
.UNINDENT
@@ -699,7 +698,7 @@ Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:EC
Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.3. Use
\fI\%\-\-ciphers\fP for TLSv1.2 or earlier.
\fI\%\-\-ciphers\fP for TLSv1.2.
.sp
Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\fP
.UNINDENT
@@ -708,8 +707,8 @@ Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_
.B \-\-client\-ciphers=<SUITE>
Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use \fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.3.
This option sets cipher suites for TLSv1.2. Use
\fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.3.
.sp
Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:ECDHE\-ECDSA\-AES256\-GCM\-SHA384:ECDHE\-RSA\-AES256\-GCM\-SHA384:ECDHE\-ECDSA\-CHACHA20\-POLY1305:ECDHE\-RSA\-CHACHA20\-POLY1305:DHE\-RSA\-AES128\-GCM\-SHA256:DHE\-RSA\-AES256\-GCM\-SHA384\fP
.UNINDENT
@@ -719,15 +718,15 @@ Default: \fBECDHE\-ECDSA\-AES128\-GCM\-SHA256:ECDHE\-RSA\-AES128\-GCM\-SHA256:EC
Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.3. Use
\fI\%\-\-tls13\-client\-ciphers\fP for TLSv1.2 or earlier.
\fI\%\-\-client\-ciphers\fP for TLSv1.2.
.sp
Default: \fBTLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ecdh\-curves=<LIST>
Set supported curve list for frontend connections.
<LIST> is a colon separated list of curve NID or names
.B \-\-groups=<LIST>
Set the supported group list for frontend connections.
<LIST> is a colon separated list of group NID or names
in the preference order. The supported curves depend on
the linked OpenSSL library. This function requires
OpenSSL >= 1.0.2.
@@ -745,12 +744,10 @@ enabled for backend connections.
.B \-\-cacert=<PATH>
Set path to trusted CA certificate file. It is used in
backend TLS connections to verify peer\(aqs certificate.
It is also used to verify OCSP response from the script
set by \fI\%\-\-fetch\-ocsp\-response\-file\fP\&. The file must be in
PEM format. It can contain multiple certificates. If
the linked OpenSSL is configured to load system wide
certificates, they are loaded at startup regardless of
this option.
The file must be in PEM format. It can contain multiple
certificates. If the linked OpenSSL is configured to
load system wide certificates, they are loaded at
startup regardless of this option.
.UNINDENT
.INDENT 0.0
.TP
@@ -765,13 +762,12 @@ password protected it\(aqll be requested interactively.
Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. If nghttpx
is built with OpenSSL >= 1.0.2, the shared elliptic
curves (e.g., P\-256) between client and server are also
taken into consideration. This allows nghttpx to send
ECDSA certificate to modern clients, while sending RSA
based certificate to older clients. This option can be
used multiple times. To make OCSP stapling work,
<CERTPATH> must be absolute path.
is built with OpenSSL >= 1.0.2, the signature algorithms
(e.g., ECDSA+SHA256) presented by client are also taken
into consideration. This allows nghttpx to send ML\-DSA
or ECDSA certificate to modern clients, while sending
RSA based certificate to older clients. This option can
be used multiple times.
.sp
Additional parameter can be specified in <PARAM>. The
available <PARAM> is \(dqsct\-dir=<DIR>\(dq.
@@ -798,7 +794,7 @@ protocol comes first. The parameter must be delimited
by a single comma only and any white spaces are treated
as a part of protocol string.
.sp
Default: \fBh2,h2\-16,h2\-14,http/1.1\fP
Default: \fBh2,http/1.1\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -840,12 +836,8 @@ done in case\-insensitive manner. The versions between
\fI\%\-\-tls\-min\-proto\-version\fP and \fI\%\-\-tls\-max\-proto\-version\fP are
enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error
message \(dqunknown protocol\(dq. If a protocol version lower
than TLSv1.2 is specified, make sure that the compatible
ciphers are included in \fI\%\-\-ciphers\fP option. The default
cipher list only includes ciphers compatible with
TLSv1.2 or above. The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
message \(dqunknown protocol\(dq. The available versions are:
TLSv1.3 and TLSv1.2
.sp
Default: \fBTLSv1.2\fP
.UNINDENT
@@ -858,7 +850,7 @@ done in case\-insensitive manner. The versions between
enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error
message \(dqunknown protocol\(dq. The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
TLSv1.3 and TLSv1.2
.sp
Default: \fBTLSv1.3\fP
.UNINDENT
@@ -962,72 +954,6 @@ 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.
.sp
Default: \fB/usr/local/share/nghttp2/fetch\-ocsp\-response\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ocsp\-update\-interval=<DURATION>
Set interval to update OCSP response cache.
.sp
Default: \fB4h\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-ocsp\-startup
Start accepting connections after initial attempts to
get OCSP responses finish. It does not matter some of
the attempts fail. This feature is useful if OCSP
responses must be available before accepting
connections.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-verify\-ocsp
nghttpx does not verify OCSP response.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-no\-ocsp
Disable OCSP stapling.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session
cache. This enables shared session cache between
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying \(dqtls\(dq
parameter.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached\-address\-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to store
session cache. If \(dqauto\(dq is given, both IPv4 and IPv6
are considered. If \(dqIPv4\(dq is given, only IPv4 address
is considered. If \(dqIPv6\(dq is given, only IPv6 address is
considered.
.sp
Default: \fBauto\fP
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached\-cert\-file=<PATH>
Path to client certificate for memcached connections to
store session cache.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-session\-cache\-memcached\-private\-key\-file=<PATH>
Path to client private key for memcached connections to
store session cache.
.UNINDENT
.INDENT 0.0
.TP
.B \-\-tls\-dyn\-rec\-warmup\-threshold=<SIZE>
Specify the threshold size for TLS dynamic record size
behaviour. During a TLS session, after the threshold
@@ -1135,8 +1061,7 @@ Default: \fB16K\fP
.INDENT 0.0
.TP
.B \-\-tls\-ktls
Enable ktls. For server, ktls is enable if
\fI\%\-\-tls\-session\-cache\-memcached\fP is not configured.
Enable ktls.
.UNINDENT
.SS HTTP/2
.INDENT 0.0
@@ -1675,7 +1600,7 @@ initial DNS query. For the 2nd and later queries,
server is given time based on this timeout, and it is
scaled linearly.
.sp
Default: \fB5s\fP
Default: \fB250ms\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -1683,7 +1608,7 @@ Default: \fB5s\fP
Set the number of DNS query before nghttpx gives up name
lookup.
.sp
Default: \fB2\fP
Default: \fB3\fP
.UNINDENT
.INDENT 0.0
.TP
@@ -2154,35 +2079,6 @@ specified socket already exists in the file system, nghttpx first
deletes it. However, if SIGUSR2 is used to execute new binary and
both old and new configurations use same filename, new binary does not
delete the socket and continues to use it.
.SH OCSP STAPLING
.sp
OCSP query is done using external Python script
\fBfetch\-ocsp\-response\fP, which has been originally developed in Perl
as part of h2o project (\X'tty: link https://github.com/h2o/h2o'\fI\%https://github.com/h2o/h2o\fP\X'tty: link'), and was
translated into Python.
.sp
The script file is usually installed under
\fB$(prefix)/share/nghttp2/\fP directory. The actual path to script can
be customized using \fI\%\-\-fetch\-ocsp\-response\-file\fP option.
.sp
If OCSP query is failed, previous OCSP response, if any, is continued
to be used.
.sp
\fI\%\-\-fetch\-ocsp\-response\-file\fP option provides wide range of
possibility to manage OCSP response. It can take an arbitrary script
or executable. The requirement is that it supports the command\-line
interface of \fBfetch\-ocsp\-response\fP script, and it must return a
valid DER encoded OCSP response on success. It must return exit code
0 on success, and 75 for temporary error, and the other error code for
generic failure. For large cluster of servers, it is not efficient
for each server to perform OCSP query using \fBfetch\-ocsp\-response\fP\&.
Instead, you can retrieve OCSP response in some way, and store it in a
disk or a shared database. Then specify a program in
\fI\%\-\-fetch\-ocsp\-response\-file\fP to fetch it from those stores.
This could provide a way to share the OCSP response between fleet of
servers, and also any OCSP query strategy can be applied which may be
beyond the ability of nghttpx itself or \fBfetch\-ocsp\-response\fP
script.
.SH TLS SESSION RESUMPTION
.sp
nghttpx supports TLS session resumption through both session ID and
@@ -2190,16 +2086,6 @@ session ticket.
.SS SESSION ID RESUMPTION
.sp
By default, session ID is shared by all worker threads.
.sp
If \fI\%\-\-tls\-session\-cache\-memcached\fP is given, nghttpx will
insert serialized session data to memcached with
\fBnghttpx:tls\-session\-cache:\fP + lowercase hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
.sp
By default, connections to memcached server are not encrypted. To
enable encryption, use \fBtls\fP keyword in
\fI\%\-\-tls\-session\-cache\-memcached\fP option.
.SS TLS SESSION TICKET RESUMPTION
.sp
By default, session ticket is shared by all worker threads. The

View File

@@ -25,8 +25,7 @@ A reverse proxy for HTTP/3, HTTP/2, and HTTP/1.
.. describe:: <CERT>
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.
"no-tls" parameter is used in :option:`--frontend` option.
OPTIONS
@@ -644,8 +643,8 @@ SSL/TLS
Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use :option:`--tls13-ciphers` for TLSv1.3.
This option sets cipher suites for TLSv1.2. Use
:option:`--tls13-ciphers` for TLSv1.3.
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
@@ -654,7 +653,7 @@ SSL/TLS
Set allowed cipher list for frontend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.3. Use
:option:`--ciphers` for TLSv1.2 or earlier.
:option:`--ciphers` for TLSv1.2.
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
@@ -662,8 +661,8 @@ SSL/TLS
Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.2 or earlier.
Use :option:`--tls13-client-ciphers` for TLSv1.3.
This option sets cipher suites for TLSv1.2. Use
:option:`--tls13-client-ciphers` for TLSv1.3.
Default: ``ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384``
@@ -672,14 +671,14 @@ SSL/TLS
Set allowed cipher list for backend connection. The
format of the string is described in OpenSSL ciphers(1).
This option sets cipher suites for TLSv1.3. Use
:option:`--tls13-client-ciphers` for TLSv1.2 or earlier.
:option:`--client-ciphers` for TLSv1.2.
Default: ``TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256``
.. option:: --ecdh-curves=<LIST>
.. option:: --groups=<LIST>
Set supported curve list for frontend connections.
<LIST> is a colon separated list of curve NID or names
Set the supported group list for frontend connections.
<LIST> is a colon separated list of group NID or names
in the preference order. The supported curves depend on
the linked OpenSSL library. This function requires
OpenSSL >= 1.0.2.
@@ -695,12 +694,10 @@ SSL/TLS
Set path to trusted CA certificate file. It is used in
backend TLS connections to verify peer's certificate.
It is also used to verify OCSP response from the script
set by :option:`--fetch-ocsp-response-file`\. The file must be in
PEM format. It can contain multiple certificates. If
the linked OpenSSL is configured to load system wide
certificates, they are loaded at startup regardless of
this option.
The file must be in PEM format. It can contain multiple
certificates. If the linked OpenSSL is configured to
load system wide certificates, they are loaded at
startup regardless of this option.
.. option:: --private-key-passwd-file=<PATH>
@@ -713,13 +710,12 @@ SSL/TLS
Specify additional certificate and private key file.
nghttpx will choose certificates based on the hostname
indicated by client using TLS SNI extension. If nghttpx
is built with OpenSSL >= 1.0.2, the shared elliptic
curves (e.g., P-256) between client and server are also
taken into consideration. This allows nghttpx to send
ECDSA certificate to modern clients, while sending RSA
based certificate to older clients. This option can be
used multiple times. To make OCSP stapling work,
<CERTPATH> must be absolute path.
is built with OpenSSL >= 1.0.2, the signature algorithms
(e.g., ECDSA+SHA256) presented by client are also taken
into consideration. This allows nghttpx to send ML-DSA
or ECDSA certificate to modern clients, while sending
RSA based certificate to older clients. This option can
be used multiple times.
Additional parameter can be specified in <PARAM>. The
available <PARAM> is "sct-dir=<DIR>".
@@ -744,7 +740,7 @@ SSL/TLS
by a single comma only and any white spaces are treated
as a part of protocol string.
Default: ``h2,h2-16,h2-14,http/1.1``
Default: ``h2,http/1.1``
.. option:: --verify-client
@@ -780,12 +776,8 @@ SSL/TLS
:option:`--tls-min-proto-version` and :option:`\--tls-max-proto-version` are
enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error
message "unknown protocol". If a protocol version lower
than TLSv1.2 is specified, make sure that the compatible
ciphers are included in :option:`--ciphers` option. The default
cipher list only includes ciphers compatible with
TLSv1.2 or above. The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
message "unknown protocol". The available versions are:
TLSv1.3 and TLSv1.2
Default: ``TLSv1.2``
@@ -797,7 +789,7 @@ SSL/TLS
enabled. If the protocol list advertised by client does
not overlap this range, you will receive the error
message "unknown protocol". The available versions are:
TLSv1.3, TLSv1.2, TLSv1.1, and TLSv1.0
TLSv1.3 and TLSv1.2
Default: ``TLSv1.3``
@@ -890,63 +882,6 @@ SSL/TLS
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
absolute path.
Default: ``/usr/local/share/nghttp2/fetch-ocsp-response``
.. option:: --ocsp-update-interval=<DURATION>
Set interval to update OCSP response cache.
Default: ``4h``
.. option:: --ocsp-startup
Start accepting connections after initial attempts to
get OCSP responses finish. It does not matter some of
the attempts fail. This feature is useful if OCSP
responses must be available before accepting
connections.
.. option:: --no-verify-ocsp
nghttpx does not verify OCSP response.
.. option:: --no-ocsp
Disable OCSP stapling.
.. option:: --tls-session-cache-memcached=<HOST>,<PORT>[;tls]
Specify address of memcached server to store session
cache. This enables shared session cache between
multiple nghttpx instances. Optionally, memcached
connection can be encrypted with TLS by specifying "tls"
parameter.
.. option:: --tls-session-cache-memcached-address-family=(auto|IPv4|IPv6)
Specify address family of memcached connections to store
session cache. If "auto" is given, both IPv4 and IPv6
are considered. If "IPv4" is given, only IPv4 address
is considered. If "IPv6" is given, only IPv6 address is
considered.
Default: ``auto``
.. option:: --tls-session-cache-memcached-cert-file=<PATH>
Path to client certificate for memcached connections to
store session cache.
.. option:: --tls-session-cache-memcached-private-key-file=<PATH>
Path to client private key for memcached connections to
store session cache.
.. option:: --tls-dyn-rec-warmup-threshold=<SIZE>
Specify the threshold size for TLS dynamic record size
@@ -1046,8 +981,7 @@ SSL/TLS
.. option:: --tls-ktls
Enable ktls. For server, ktls is enable if
:option:`--tls-session-cache-memcached` is not configured.
Enable ktls.
HTTP/2
@@ -1524,14 +1458,14 @@ DNS
server is given time based on this timeout, and it is
scaled linearly.
Default: ``5s``
Default: ``250ms``
.. option:: --dns-max-try=<N>
Set the number of DNS query before nghttpx gives up name
lookup.
Default: ``2``
Default: ``3``
.. option:: --frontend-max-requests=<N>
@@ -1971,37 +1905,6 @@ deletes it. However, if SIGUSR2 is used to execute new binary and
both old and new configurations use same filename, new binary does not
delete the socket and continues to use it.
OCSP STAPLING
-------------
OCSP query is done using external Python script
``fetch-ocsp-response``, which has been originally developed in Perl
as part of h2o project (https://github.com/h2o/h2o), and was
translated into Python.
The script file is usually installed under
``$(prefix)/share/nghttp2/`` directory. The actual path to script can
be customized using :option:`--fetch-ocsp-response-file` option.
If OCSP query is failed, previous OCSP response, if any, is continued
to be used.
:option:`--fetch-ocsp-response-file` option provides wide range of
possibility to manage OCSP response. It can take an arbitrary script
or executable. The requirement is that it supports the command-line
interface of ``fetch-ocsp-response`` script, and it must return a
valid DER encoded OCSP response on success. It must return exit code
0 on success, and 75 for temporary error, and the other error code for
generic failure. For large cluster of servers, it is not efficient
for each server to perform OCSP query using ``fetch-ocsp-response``.
Instead, you can retrieve OCSP response in some way, and store it in a
disk or a shared database. Then specify a program in
:option:`--fetch-ocsp-response-file` to fetch it from those stores.
This could provide a way to share the OCSP response between fleet of
servers, and also any OCSP query strategy can be applied which may be
beyond the ability of nghttpx itself or ``fetch-ocsp-response``
script.
TLS SESSION RESUMPTION
----------------------
@@ -2013,16 +1916,6 @@ SESSION ID RESUMPTION
By default, session ID is shared by all worker threads.
If :option:`--tls-session-cache-memcached` is given, nghttpx will
insert serialized session data to memcached with
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -156,37 +156,6 @@ deletes it. However, if SIGUSR2 is used to execute new binary and
both old and new configurations use same filename, new binary does not
delete the socket and continues to use it.
OCSP STAPLING
-------------
OCSP query is done using external Python script
``fetch-ocsp-response``, which has been originally developed in Perl
as part of h2o project (https://github.com/h2o/h2o), and was
translated into Python.
The script file is usually installed under
``$(prefix)/share/nghttp2/`` directory. The actual path to script can
be customized using :option:`--fetch-ocsp-response-file` option.
If OCSP query is failed, previous OCSP response, if any, is continued
to be used.
:option:`--fetch-ocsp-response-file` option provides wide range of
possibility to manage OCSP response. It can take an arbitrary script
or executable. The requirement is that it supports the command-line
interface of ``fetch-ocsp-response`` script, and it must return a
valid DER encoded OCSP response on success. It must return exit code
0 on success, and 75 for temporary error, and the other error code for
generic failure. For large cluster of servers, it is not efficient
for each server to perform OCSP query using ``fetch-ocsp-response``.
Instead, you can retrieve OCSP response in some way, and store it in a
disk or a shared database. Then specify a program in
:option:`--fetch-ocsp-response-file` to fetch it from those stores.
This could provide a way to share the OCSP response between fleet of
servers, and also any OCSP query strategy can be applied which may be
beyond the ability of nghttpx itself or ``fetch-ocsp-response``
script.
TLS SESSION RESUMPTION
----------------------
@@ -198,16 +167,6 @@ SESSION ID RESUMPTION
By default, session ID is shared by all worker threads.
If :option:`--tls-session-cache-memcached` is given, nghttpx will
insert serialized session data to memcached with
``nghttpx:tls-session-cache:`` + lowercase hex string of session ID
as a memcached entry key, with expiry time 12 hours. Session timeout
is set to 12 hours.
By default, connections to memcached server are not encrypted. To
enable encryption, use ``tls`` keyword in
:option:`--tls-session-cache-memcached` option.
TLS SESSION TICKET RESUMPTION
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -26,7 +26,7 @@ Coding style
We use clang-format to format source code consistently. The
clang-format configuration file .clang-format is located at the root
directory. Since clang-format produces slightly different results
between versions, we currently use clang-format-18.
between versions, we currently use clang-format-19.
To detect any violation to the coding style, we recommend to setup git
pre-commit hook to check coding style of the changes you introduced.

View File

@@ -167,8 +167,7 @@ Enable SSL/TLS on memcached connection
By default, memcached connection is not encrypted. To enable
encryption, use ``tls`` keyword in
:option:`--tls-ticket-key-memcached` for TLS ticket key, and
:option:`--tls-session-cache-memcached` for TLS session cache.
:option:`--tls-ticket-key-memcached`.
Specifying additional server certificates
-----------------------------------------

View File

@@ -4,33 +4,36 @@ ARG NGHTTP2_BRANCH=master
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git clang make binutils autoconf automake autotools-dev libtool \
git clang-19 make binutils autoconf automake autotools-dev libtool \
pkg-config cmake cmake-data \
zlib1g-dev libev-dev libjemalloc-dev ruby-dev libc-ares-dev bison \
libelf-dev libbrotli-dev
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.46.1 https://github.com/aws/aws-lc && \
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.62.0 https://github.com/aws/aws-lc && \
cd aws-lc && \
export CC=clang-19 CXX=clang++-19 && \
cmake -B build -DDISABLE_GO=ON && \
make -j$(nproc) -C build && \
cmake --install build && \
cd .. && \
rm -rf aws-lc
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.8.0 https://github.com/ngtcp2/nghttp3 && \
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.12.0 https://github.com/ngtcp2/nghttp3 && \
cd nghttp3 && \
autoreconf -i && \
./configure --disable-dependency-tracking --enable-lib-only && \
./configure --disable-dependency-tracking --enable-lib-only \
CC=clang-19 CXX=clang++-19 && \
make -j$(nproc) && \
make install-strip && \
cd .. && \
rm -rf nghttp3
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.11.0 https://github.com/ngtcp2/ngtcp2 && \
RUN git clone --recursive --shallow-submodules --depth 1 -b v1.17.0 https://github.com/ngtcp2/ngtcp2 && \
cd ngtcp2 && \
autoreconf -i && \
./configure --disable-dependency-tracking --enable-lib-only \
--with-boringssl \
CC=clang-19 CXX=clang++-19 \
LIBTOOL_LDFLAGS="-static-libtool-libs" \
BORINGSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
PKG_CONFIG_PATH="/usr/local/lib64/pkgconfig" && \
@@ -39,9 +42,9 @@ RUN git clone --recursive --shallow-submodules --depth 1 -b v1.11.0 https://gith
cd .. && \
rm -rf ngtcp2
RUN git clone --depth 1 -b v1.5.0 https://github.com/libbpf/libbpf && \
RUN git clone --depth 1 -b v1.6.2 https://github.com/libbpf/libbpf && \
cd libbpf && \
PREFIX=/usr/local make -C src install && \
CC=clang-19 PREFIX=/usr/local make -C src install && \
cd .. && \
rm -rf libbpf
@@ -53,7 +56,7 @@ RUN git clone --recursive --shallow-submodules --depth 1 -b $NGHTTP2_BRANCH http
--with-mruby \
--enable-http3 --with-libbpf \
--with-libbrotlienc --with-libbrotlidec \
CC=clang CXX=clang++ \
CC=clang-19 CXX=clang++-19 \
LIBTOOL_LDFLAGS="-static-libtool-libs" \
OPENSSL_LIBS="-l:libssl.a -l:libcrypto.a" \
LIBEV_LIBS="-l:libev.a" \
@@ -71,9 +74,6 @@ RUN git clone --recursive --shallow-submodules --depth 1 -b $NGHTTP2_BRANCH http
FROM gcr.io/distroless/base-nossl-debian12
COPY --from=build --link \
/usr/local/share/nghttp2/ \
/usr/local/share/nghttp2/
COPY --from=build --link \
/usr/local/bin/h2load \
/usr/local/bin/nghttpx \

View File

@@ -28,26 +28,26 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <inttypes.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* defined(HAVE_UNISTD_H) */
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#endif /* defined(HAVE_FCNTL_H) */
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#endif /* defined(HAVE_SYS_SOCKET_H) */
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif /* HAVE_NETDB_H */
#endif /* defined(HAVE_NETDB_H) */
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#endif /* defined(HAVE_NETINET_IN_H) */
#include <netinet/tcp.h>
#include <poll.h>
#include <signal.h>

View File

@@ -24,7 +24,7 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* !HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <stdio.h>
#include <string.h>

View File

@@ -31,26 +31,26 @@
}
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
char *strndup(const char *s, size_t size);
#endif
#endif /* defined(__sgi) */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* defined(HAVE_UNISTD_H) */
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#endif /* defined(HAVE_SYS_SOCKET_H) */
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#endif /* defined(HAVE_NETINET_IN_H) */
#include <netinet/tcp.h>
#ifndef __sgi
# include <err.h>
#endif
#endif /* !defined(__sgi) */
#include <signal.h>
#include <string.h>

View File

@@ -30,35 +30,35 @@
}
# define warn(format, args...) warnx(format ": %s", ##args, strerror(errno))
# define warnx(format, args...) fprintf(stderr, format "\n", ##args)
#endif
#endif /* defined(__sgi) */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif /* HAVE_SYS_SOCKET_H */
#endif /* defined(HAVE_SYS_SOCKET_H) */
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif /* HAVE_NETDB_H */
#endif /* defined(HAVE_NETDB_H) */
#include <signal.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* defined(HAVE_UNISTD_H) */
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#endif /* defined(HAVE_FCNTL_H) */
#include <ctype.h>
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#endif /* defined(HAVE_NETINET_IN_H) */
#include <netinet/tcp.h>
#ifndef __sgi
# include <err.h>
#endif
#endif /* !defined(__sgi) */
#include <string.h>
#include <errno.h>
@@ -136,11 +136,11 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
errx(1, "SSL_CTX_set1_curves_list failed: %s",
if (SSL_CTX_set1_groups_list(ssl_ctx, "P-256") != 1) {
errx(1, "SSL_CTX_set1_groups_list failed: %s",
ERR_error_string(ERR_get_error(), NULL));
}
#else /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
{
EC_KEY *ecdh;
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
@@ -151,7 +151,7 @@ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh);
EC_KEY_free(ecdh);
}
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
errx(1, "Could not read private key file %s", key_file);
@@ -727,7 +727,7 @@ static void start_listen(struct event_base *evbase, const char *service,
hints.ai_flags = AI_PASSIVE;
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif /* AI_ADDRCONFIG */
#endif /* defined(AI_ADDRCONFIG) */
rv = getaddrinfo(NULL, service, &hints, &res);
if (rv != 0) {

View File

@@ -204,6 +204,7 @@ OPTIONS = [
"frontend-header-timeout",
"frontend-http2-idle-timeout",
"frontend-http3-idle-timeout",
"groups",
]
LOGVARS = [

View File

@@ -35,7 +35,7 @@ enum {''')
def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
print('''\
{} lookup_token(const StringRef &name) {{
{} lookup_token(const std::string_view &name) {{
switch (name.size()) {{'''.format(return_type))
b = build_header(tokens)
for size in sorted(b.keys()):
@@ -50,7 +50,7 @@ def gen_index_header(tokens, prefix, comp_fun, return_type, fail_value):
case '{}':'''.format(c))
for k in headers:
print('''\
if ({}("{}"_sr, name, {})) {{
if ({}("{}"sv, name.substr(0, {}))) {{
return {};
}}'''.format(comp_fun, k[:-1], size - 1, to_enum_hd(k, prefix)))
print('''\

23
go.mod
View File

@@ -1,25 +1,20 @@
module github.com/nghttp2/nghttp2
go 1.22.0
go 1.24.0
require (
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874
github.com/quic-go/quic-go v0.49.0
github.com/quic-go/quic-go v0.55.0
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8
golang.org/x/net v0.35.0
golang.org/x/net v0.46.0
)
require (
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
go.uber.org/mock v0.5.0 // indirect
golang.org/x/crypto v0.33.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/sys v0.30.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.37.0 // indirect
)

64
go.sum
View File

@@ -1,62 +1,34 @@
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.49.0 h1:w5iJHXwHxs1QxyBv1EHKuC50GX5to8mJAxvtnttJp94=
github.com/quic-go/quic-go v0.49.0/go.mod h1:s2wDnmCdooUQBmQfpUSTCYBl1/D4FcqbULMMkASvR6s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/quic-go/quic-go v0.55.0 h1:zccPQIqYCXDt5NmcEabyYvOnomjs8Tlwl7tISjJh9Mk=
github.com/quic-go/quic-go v0.55.0/go.mod h1:DR51ilwU1uE164KuWXhinFcKWGlEjzys2l8zUl5Ss1U=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8 h1:zKJxuRe+a0O34V81GAZWOrotuU6mveT30QLjJ7OPMMg=
github.com/tatsuhiro-t/go-nghttp2 v0.0.0-20240121064059-46ccb0a462a8/go.mod h1:gTqc3Q4boc+cKRlSFywTYdX9t6VGRcsThlNIWwaL3Dc=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko=
go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -882,12 +882,39 @@ func TestH1H1CONNECTMethodFailure(t *testing.T) {
if _, err := io.ReadAll(resp.Body); err != nil {
t.Fatalf("Error io.ReadAll() = %v", err)
}
}
if _, err := io.WriteString(st.conn, "CONNECT 127.0.0.1:443 HTTP/1.1\r\nTest-Case: TestH1H1CONNECTMethodFailure\r\nHost: 127.0.0.1:443\r\nrequired-header: foo\r\n\r\n"); err != nil {
// TestH1H1CONNECTMethod tests that CONNECT request succeeds.
func TestH1H1CONNECTMethod(t *testing.T) {
opts := options{
handler: func(w http.ResponseWriter, r *http.Request) {
hj, ok := w.(http.Hijacker)
if !ok {
http.Error(w, "Could not hijack the connection", http.StatusInternalServerError)
return
}
_, bufrw, err := hj.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if _, err := bufrw.WriteString("HTTP/1.1 200\r\n\r\n"); err != nil {
t.Fatalf("Error bufrw.WriteString() = %v", err)
}
bufrw.Flush()
},
}
st := newServerTester(t, opts)
defer st.Close()
if _, err := io.WriteString(st.conn, "CONNECT 127.0.0.1:443 HTTP/1.1\r\nTest-Case: TestH1H1CONNECTMethod\r\nHost: 127.0.0.1:443\r\n\r\n"); err != nil {
t.Fatalf("Error io.WriteString() = %v", err)
}
resp, err = http.ReadResponse(bufio.NewReader(st.conn), nil)
resp, err := http.ReadResponse(bufio.NewReader(st.conn), nil)
if err != nil {
t.Fatalf("Error http.ReadResponse() = %v", err)
}

View File

@@ -1334,7 +1334,6 @@ func TestH2H1Upgrade(t *testing.T) {
pair("HTTP2-Settings", "AAMAAABkAAQAAP__"),
},
})
if err != nil {
t.Fatalf("Error st.http1() = %v", err)
}

View File

@@ -161,7 +161,7 @@ func newServerTester(t *testing.T, opts options) *serverTester {
b := "-b"
if !externalDNS {
b += fmt.Sprintf("%v;", strings.Replace(backendURL.Host, ":", ",", -1))
b += fmt.Sprintf("%v;", strings.ReplaceAll(backendURL.Host, ":", ","))
} else {
sep := strings.LastIndex(backendURL.Host, ":")
if sep == -1 {
@@ -170,6 +170,8 @@ func newServerTester(t *testing.T, opts options) *serverTester {
// We use awesome service nip.io.
b += fmt.Sprintf("%v.nip.io,%v;", backendURL.Host[:sep], backendURL.Host[sep+1:])
// Make external DNS tests less flaky.
args = append(args, "--backend-address-family=IPv4")
}
if backendTLS {
@@ -206,7 +208,19 @@ func newServerTester(t *testing.T, opts options) *serverTester {
if opts.quic {
args = append(args,
fmt.Sprintf("-f127.0.0.1,%v;quic", serverPort),
"--no-quic-bpf")
"--no-quic-bpf",
// quic-go client just closes connection after
// receiving the first GOAWAY without any
// indication like sending CONNECTION_CLOSE if
// there is no active stream. If that
// happens, server keeps resending 2nd GOAWAY
// until idle timeout passes. If that happens
// during Close(), the process will be killed
// because the default idle timeout is longer
// than the close timeout. Shorten the idle
// timeout to prevent it from happening.
"--frontend-quic-idle-timeout=5",
)
}
authority := fmt.Sprintf("127.0.0.1:%v", opts.connectPort)
@@ -309,14 +323,14 @@ func (st *serverTester) Close() {
close(done)
}()
if err := st.cmd.Process.Signal(syscall.SIGQUIT); err != nil {
if err := st.cmd.Process.Signal(syscall.SIGQUIT); err != nil && !errors.Is(err, os.ErrProcessDone) {
st.t.Errorf("Error st.cmd.Process.Signal() = %v", err)
}
select {
case <-done:
case <-time.After(10 * time.Second):
if err := st.cmd.Process.Kill(); err != nil {
if err := st.cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) {
st.t.Errorf("Error st.cmd.Process.Kill() = %v", err)
}
@@ -631,7 +645,7 @@ loop:
return res, err
}
sr, ok := streams[f.FrameHeader.StreamID]
sr, ok := streams[f.StreamID]
if !ok {
st.header = make(http.Header)
break
@@ -643,7 +657,7 @@ loop:
status, err = strconv.Atoi(sr.header.Get(":status"))
if err != nil {
return res, fmt.Errorf("Error parsing status code: %w", err)
return res, fmt.Errorf("could not parse :status: %w", err)
}
sr.status = status
@@ -664,7 +678,7 @@ loop:
streams[sr.streamID] = sr
case *http2.DataFrame:
sr, ok := streams[f.FrameHeader.StreamID]
sr, ok := streams[f.StreamID]
if !ok {
break
}
@@ -675,7 +689,7 @@ loop:
break loop
}
case *http2.RSTStreamFrame:
sr, ok := streams[f.FrameHeader.StreamID]
sr, ok := streams[f.StreamID]
if !ok {
break
}

View File

@@ -15,7 +15,7 @@ import (
)
func (st *serverTester) http3(rp requestParam) (*serverResponse, error) {
rt := &http3.RoundTripper{
rt := &http3.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},

View File

@@ -47,7 +47,29 @@ if(WIN32)
set(NGHTTP2_RES ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
endif()
set(EXPORT_SET "${PROJECT_NAME}-targets")
set(NGHTTP2_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(NGHTTP2_VERSION_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(NGHTTP2_PROJECT_CONFIG "${NGHTTP2_GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
set(NGHTTP2_TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(NGHTTP2_CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(NGHTTP2_NAMESPACE "${PROJECT_NAME}::")
set(NGHTTP2_VERSION ${PROJECT_VERSION})
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${NGHTTP2_VERSION_CONFIG}" VERSION ${NGHTTP2_VERSION} COMPATIBILITY SameMajorVersion
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.cmake.in" "${NGHTTP2_PROJECT_CONFIG}" @ONLY)
# Install cmake config files
install(
FILES "${NGHTTP2_PROJECT_CONFIG}" "${NGHTTP2_VERSION_CONFIG}"
DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
install(
EXPORT "${NGHTTP2_TARGETS_EXPORT_NAME}"
NAMESPACE "${NGHTTP2_NAMESPACE}"
DESTINATION "${NGHTTP2_CONFIG_INSTALL_DIR}")
# Public shared library
if(BUILD_SHARED_LIBS)
@@ -65,7 +87,11 @@ if(BUILD_SHARED_LIBS)
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
install(TARGETS ${SHARED_LIB} EXPORT ${EXPORT_SET})
install(TARGETS ${SHARED_LIB}
EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
list(APPEND nghttp2_exports ${SHARED_LIB})
endif()
@@ -87,7 +113,9 @@ if(BUILD_STATIC_LIBS)
target_compile_definitions(${STATIC_LIB} PUBLIC "-DNGHTTP2_STATICLIB")
install(TARGETS ${STATIC_LIB} EXPORT ${EXPORT_SET})
install(TARGETS ${STATIC_LIB}
EXPORT ${NGHTTP2_TARGETS_EXPORT_NAME}
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}")
list(APPEND nghttp2_exports ${STATIC_LIB})
endif()
@@ -97,11 +125,7 @@ else()
set(LIB_SELECTED ${STATIC_LIB})
endif()
add_library(${PROJECT_NAME}::nghttp2 ALIAS ${LIB_SELECTED})
add_library(nghttp2 ALIAS ${LIB_SELECTED})
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libnghttp2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
install(EXPORT ${EXPORT_SET}
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
NAMESPACE ${PROJECT_NAME}::)

View File

@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = includes
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in
EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in config.cmake.in
AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG)
AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \

3
lib/config.cmake.in Normal file
View File

@@ -0,0 +1,3 @@
include(CMakeFindDependencyMacro)
include("${CMAKE_CURRENT_LIST_DIR}/@NGHTTP2_TARGETS_EXPORT_NAME@.cmake")

View File

@@ -2039,18 +2039,19 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session,
/**
* @functypedef
*
* Callback function invoked when a invalid header name/value pair is
* Callback function invoked when an invalid header name/value pair is
* received for the |frame|.
*
* The parameter and behaviour are similar to
* :type:`nghttp2_on_header_callback`. The difference is that this
* callback is only invoked when a invalid header name/value pair is
* received which is treated as stream error if this callback is not
* set. Only invalid regular header field are passed to this
* callback. In other words, invalid pseudo header field is not
* passed to this callback. Also header fields which includes upper
* cased latter are also treated as error without passing them to this
* callback.
* callback is only invoked when an invalid header name/value pair is
* received which is treated as stream error if this callback returns
* :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and
* :type:`nghttp2_on_invalid_header_callback2` is not set. Only
* invalid regular header field are passed to this callback. In other
* words, invalid pseudo header field is not passed to this callback.
* Also header fields which includes upper cased latter are also
* treated as error without passing them to this callback.
*
* This callback is only considered if HTTP messaging validation is
* turned on (which is on by default, see
@@ -2076,17 +2077,18 @@ typedef int (*nghttp2_on_invalid_header_callback)(
/**
* @functypedef
*
* Callback function invoked when a invalid header name/value pair is
* Callback function invoked when an invalid header name/value pair is
* received for the |frame|.
*
* The parameter and behaviour are similar to
* :type:`nghttp2_on_header_callback2`. The difference is that this
* callback is only invoked when a invalid header name/value pair is
* received which is silently ignored if this callback is not set.
* Only invalid regular header field are passed to this callback. In
* other words, invalid pseudo header field is not passed to this
* callback. Also header fields which includes upper cased latter are
* also treated as error without passing them to this callback.
* callback is only invoked when an invalid header name/value pair is
* received which is silently ignored if neither this callback nor
* :type:`nghttp2_on_invalid_header_callback` is set. Only invalid
* regular header field are passed to this callback. In other words,
* invalid pseudo header field is not passed to this callback. Also
* header fields which includes upper cased latter are also treated as
* error without passing them to this callback.
*
* This callback is only considered if HTTP messaging validation is
* turned on (which is on by default, see
@@ -2445,6 +2447,15 @@ typedef int (*nghttp2_error_callback2)(nghttp2_session *session,
int lib_error_code, const char *msg,
size_t len, void *user_data);
/**
* @functypedef
*
* Callback function invoked when unpredictable data of |destlen|
* bytes are needed. The implementation must write unpredictable data
* of |destlen| bytes into the buffer pointed by |dest|.
*/
typedef void (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen);
struct nghttp2_session_callbacks;
/**
@@ -2649,7 +2660,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
/**
* @function
*
* Sets callback function invoked when a invalid header name/value
* Sets callback function invoked when an invalid header name/value
* pair is received. If both
* `nghttp2_session_callbacks_set_on_invalid_header_callback()` and
* `nghttp2_session_callbacks_set_on_invalid_header_callback2()` are
@@ -2662,7 +2673,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback(
/**
* @function
*
* Sets callback function invoked when a invalid header name/value
* Sets callback function invoked when an invalid header name/value
* pair is received.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_invalid_header_callback2(
@@ -2833,6 +2844,18 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback(
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
/**
* @function
*
* Sets callback function invoked when unpredictable data is needed.
* Although this callback is optional due to the backward
* compatibility, it is recommended to specify it to harden the
* runtime behavior against suspicious activities of a remote
* endpoint.
*/
NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback(
nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback);
/**
* @functypedef
*
@@ -3218,6 +3241,23 @@ nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
size_t val);
/**
* @function
*
* This function sets the rate limit for the "glitches", the
* suspicious activities from a remote endpoint. It is a token-bucket
* based rate limiter. |burst| specifies the number of tokens that is
* initially available. The maximum number of tokens is capped to
* this value. |rate| specifies the number of tokens that are
* regenerated per second. When a suspicious activity is detected,
* some amount of tokens are consumed. If there is no token
* available, GOAWAY is sent to tear down the connection. |burst| and
* |rate| default to 1000 and 33 respectively.
*/
NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
uint64_t burst,
uint64_t rate);
/**
* @function
*

View File

@@ -27,8 +27,8 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#endif /* NGHTTP2_ALPN_H */
#endif /* !defined(NGHTTP2_ALPN_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -409,4 +409,4 @@ int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
*/
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
#endif /* NGHTTP2_BUF_H */
#endif /* !defined(NGHTTP2_BUF_H) */

View File

@@ -201,3 +201,8 @@ void nghttp2_session_callbacks_set_error_callback2(
nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
cbs->error_callback2 = error_callback2;
}
void nghttp2_session_callbacks_set_rand_callback(
nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) {
cbs->rand_callback = rand_callback;
}

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -151,6 +151,7 @@ struct nghttp2_session_callbacks {
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
nghttp2_error_callback error_callback;
nghttp2_error_callback2 error_callback2;
nghttp2_rand_callback rand_callback;
};
#endif /* NGHTTP2_CALLBACKS_H */
#endif /* !defined(NGHTTP2_CALLBACKS_H) */

View File

@@ -50,11 +50,11 @@ void nghttp2_set_debug_vprintf_callback(
static_debug_vprintf_callback = debug_vprintf_callback;
}
#else /* !DEBUGBUILD */
#else /* !defined(DEBUGBUILD) */
void nghttp2_set_debug_vprintf_callback(
nghttp2_debug_vprintf_callback debug_vprintf_callback) {
(void)debug_vprintf_callback;
}
#endif /* !DEBUGBUILD */
#endif /* !defined(DEBUGBUILD) */

View File

@@ -27,17 +27,17 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#ifdef DEBUGBUILD
# define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
void nghttp2_debug_vprintf(const char *format, ...);
#else
#else /* !defined(DEBUGBUILD) */
# define DEBUGF(...) \
do { \
} while (0)
#endif
#endif /* !defined(DEBUGBUILD) */
#endif /* NGHTTP2_DEBUG_H */
#endif /* !defined(NGHTTP2_DEBUG_H) */

View File

@@ -28,7 +28,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -62,4 +62,4 @@ void nghttp2_extpri_from_uint8(nghttp2_extpri *extpri, uint8_t u8extpri);
*/
#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0)
#endif /* NGHTTP2_EXTPRI_H */
#endif /* !defined(NGHTTP2_EXTPRI_H) */

View File

@@ -27,17 +27,14 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#include "nghttp2_hd.h"
#include "nghttp2_buf.h"
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
/* The number of bytes of frame header. */
#define NGHTTP2_FRAME_HDLEN 9
@@ -634,4 +631,4 @@ int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
size_t padlen, int framehd_only);
#endif /* NGHTTP2_FRAME_H */
#endif /* !defined(NGHTTP2_FRAME_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -439,4 +439,4 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
*/
int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
#endif /* NGHTTP2_HD_H */
#endif /* !defined(NGHTTP2_HD_H) */

View File

@@ -104,15 +104,15 @@ int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
}
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx->fstate = NGHTTP2_HUFF_ACCEPTED;
ctx->fstate = 0;
ctx->flags = NGHTTP2_HUFF_ACCEPTED;
}
nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
nghttp2_buf *buf, const uint8_t *src,
size_t srclen, int final) {
const uint8_t *end = src + srclen;
nghttp2_huff_decode node = {ctx->fstate, 0};
const nghttp2_huff_decode *t = &node;
nghttp2_huff_decode t = {ctx->fstate, ctx->flags, 0};
uint8_t c;
/* We use the decoding algorithm described in
@@ -121,20 +121,21 @@ nghttp2_ssize nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
- https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
for (; src != end;) {
c = *src++;
t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
t = huff_decode_table[t.fstate][c >> 4];
if (t.flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t.sym;
}
t = &huff_decode_table[t->fstate & 0x1ff][c & 0xf];
if (t->fstate & NGHTTP2_HUFF_SYM) {
*buf->last++ = t->sym;
t = huff_decode_table[t.fstate][c & 0xf];
if (t.flags & NGHTTP2_HUFF_SYM) {
*buf->last++ = t.sym;
}
}
ctx->fstate = t->fstate;
ctx->fstate = t.fstate;
ctx->flags = t.flags;
if (final && !(ctx->fstate & NGHTTP2_HUFF_ACCEPTED)) {
if (final && !(ctx->flags & NGHTTP2_HUFF_ACCEPTED)) {
return NGHTTP2_ERR_HEADER_COMP;
}

View File

@@ -27,16 +27,16 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
typedef enum {
/* FSA accepts this state as the end of huffman encoding
sequence. */
NGHTTP2_HUFF_ACCEPTED = 1 << 14,
NGHTTP2_HUFF_ACCEPTED = 1,
/* This state emits symbol */
NGHTTP2_HUFF_SYM = 1 << 15,
NGHTTP2_HUFF_SYM = 1 << 1,
} nghttp2_huff_decode_flag;
typedef struct {
@@ -48,6 +48,7 @@ typedef struct {
a special node and it is a terminal state that means decoding
failed. */
uint16_t fstate;
uint8_t flags;
/* symbol if NGHTTP2_HUFF_SYM flag set */
uint8_t sym;
} nghttp2_huff_decode;
@@ -57,6 +58,7 @@ typedef nghttp2_huff_decode huff_decode_table_type[16];
typedef struct {
/* fstate is the current huffman decoding state. */
uint16_t fstate;
uint8_t flags;
} nghttp2_hd_huff_decode_context;
typedef struct {
@@ -69,4 +71,4 @@ typedef struct {
extern const nghttp2_huff_sym huff_sym_table[];
extern const nghttp2_huff_decode huff_decode_table[][16];
#endif /* NGHTTP2_HD_HUFFMAN_H */
#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <string.h>
#include <stddef.h>
@@ -142,4 +142,4 @@ int nghttp2_should_send_window_update(int32_t local_window_size,
*/
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
#endif /* NGHTTP2_HELPER_H */
#endif /* !defined(NGHTTP2_HELPER_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#include "nghttp2_session.h"
@@ -97,4 +97,4 @@ void nghttp2_http_record_request_method(nghttp2_stream *stream,
int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
size_t valuelen);
#endif /* NGHTTP2_HTTP_H */
#endif /* !defined(NGHTTP2_HTTP_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -39,7 +39,6 @@ typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
/* Internal error code. They must be in the range [-499, -100],
inclusive. */
typedef enum {
NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
NGHTTP2_ERR_IGN_PAYLOAD = -104,
/*
@@ -52,7 +51,11 @@ typedef enum {
* Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
* nghttp2_on_invalid_header_callback.
*/
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106,
/*
* Cancel pushed stream.
*/
NGHTTP2_ERR_PUSH_CANCEL = -107,
} nghttp2_internal_error;
#endif /* NGHTTP2_INT_H */
#endif /* !defined(NGHTTP2_INT_H) */

View File

@@ -31,13 +31,13 @@
#include "nghttp2_helper.h"
#define NGHTTP2_INITIAL_TABLE_LENBITS 4
#define NGHTTP2_INITIAL_HASHBITS 4
void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
map->mem = mem;
map->hashbits = 0;
map->table = NULL;
map->size = 0;
void nghttp2_map_init(nghttp2_map *map, uint64_t seed, nghttp2_mem *mem) {
*map = (nghttp2_map){
.mem = mem,
.seed = seed,
};
}
void nghttp2_map_free(nghttp2_map *map) {
@@ -45,30 +45,27 @@ void nghttp2_map_free(nghttp2_map *map) {
return;
}
nghttp2_mem_free(map->mem, map->table);
nghttp2_mem_free(map->mem, map->keys);
}
int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
void *ptr) {
int rv;
size_t i;
nghttp2_map_bucket *bkt;
size_t tablelen;
if (map->size == 0) {
return 0;
}
tablelen = 1u << map->hashbits;
tablelen = (size_t)1 << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
if (map->psl[i] == 0) {
continue;
}
rv = func(bkt->data, ptr);
rv = func(map->data[i], ptr);
if (rv != 0) {
return rv;
}
@@ -77,164 +74,230 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
return 0;
}
static size_t hash(nghttp2_map_key_type key, size_t bits) {
return (size_t)(((uint32_t)key * 2654435769u) >> (32 - bits));
}
/* Hasher from
https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
to maximize the output's sensitivity to all input bits. */
#define NGHTTP2_MAP_HASHER 0xf1357aea2e62a9c5ull
/* 64-bit Fibonacci hashing constant, Golden Ratio constant, to get
the high bits with the good distribution. */
#define NGHTTP2_MAP_FIBO 0x9e3779b97f4a7c15ull
static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) {
nghttp2_map_bucket c = *a;
static size_t map_index(const nghttp2_map *map, nghttp2_map_key_type key32) {
uint64_t key = (uint64_t)key32;
*a = *b;
*b = c;
key += map->seed;
key *= NGHTTP2_MAP_HASHER;
return (size_t)((key * NGHTTP2_MAP_FIBO) >> (64 - map->hashbits));
}
#ifndef WIN32
void nghttp2_map_print_distance(const nghttp2_map *map) {
size_t i;
size_t idx;
nghttp2_map_bucket *bkt;
size_t tablelen;
if (map->size == 0) {
return;
}
tablelen = 1u << map->hashbits;
tablelen = (size_t)1 << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
if (map->psl[i] == 0) {
fprintf(stderr, "@%zu <EMPTY>\n", i);
continue;
}
idx = hash(bkt->key, map->hashbits);
fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i,
hash(bkt->key, map->hashbits), bkt->key, idx, bkt->psl);
idx = map_index(map, map->keys[i]);
fprintf(stderr, "@%zu key=%d base=%zu distance=%u\n", i, map->keys[i], idx,
map->psl[i] - 1);
}
}
#endif /* !WIN32 */
#endif /* !defined(WIN32) */
static int insert(nghttp2_map_bucket *table, size_t hashbits,
nghttp2_map_key_type key, void *data) {
size_t idx = hash(key, hashbits);
nghttp2_map_bucket b = {0, key, data}, *bkt;
size_t mask = (1u << hashbits) - 1;
static void map_set_entry(nghttp2_map *map, size_t idx,
nghttp2_map_key_type key, void *data, size_t psl) {
map->keys[idx] = key;
map->data[idx] = data;
map->psl[idx] = (uint8_t)psl;
}
#define NGHTTP2_SWAP(TYPE, A, B) \
do { \
TYPE t = (TYPE) * (A); \
\
*(A) = *(B); \
*(B) = t; \
} while (0)
/*
* map_insert inserts |key| and |data| to |map|, and returns the index
* where the pair is stored if it succeeds. Otherwise, it returns one
* of the following negative error codes:
*
* NGHTTP2_ERR_INVALID_ARGUMENT
* The another data associated to |key| is already present.
*/
static nghttp2_ssize map_insert(nghttp2_map *map, nghttp2_map_key_type key,
void *data) {
size_t idx = map_index(map, key);
size_t mask = ((size_t)1 << map->hashbits) - 1;
size_t psl = 1;
size_t kpsl;
for (;;) {
bkt = &table[idx];
kpsl = map->psl[idx];
if (bkt->data == NULL) {
*bkt = b;
return 0;
if (kpsl == 0) {
map_set_entry(map, idx, key, data, psl);
++map->size;
return (nghttp2_ssize)idx;
}
if (b.psl > bkt->psl) {
map_bucket_swap(bkt, &b);
} else if (bkt->key == key) {
/* TODO This check is just a waste after first swap or if this
function is called from map_resize. That said, there is no
difference with or without this conditional in performance
wise. */
if (psl > kpsl) {
NGHTTP2_SWAP(nghttp2_map_key_type, &key, &map->keys[idx]);
NGHTTP2_SWAP(void *, &data, &map->data[idx]);
NGHTTP2_SWAP(uint8_t, &psl, &map->psl[idx]);
} else if (map->keys[idx] == key) {
/* This check ensures that no duplicate keys are inserted. But
it is just a waste after first swap or if this function is
called from map_resize. That said, there is no difference
with or without this conditional in performance wise. */
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
++b.psl;
++psl;
idx = (idx + 1) & mask;
}
}
/* NGHTTP2_MAP_MAX_HASHBITS is the maximum number of bits used for
hash table. The theoretical limit of the maximum number of keys
that can be stored is 1 << NGHTTP2_MAP_MAX_HASHBITS. */
#define NGHTTP2_MAP_MAX_HASHBITS (sizeof(size_t) * 8 - 1)
static int map_resize(nghttp2_map *map, size_t new_hashbits) {
size_t i;
nghttp2_map_bucket *new_table;
nghttp2_map_bucket *bkt;
size_t tablelen;
int rv;
(void)rv;
nghttp2_ssize idx;
nghttp2_map new_map = {
.mem = map->mem,
.seed = map->seed,
.hashbits = new_hashbits,
};
void *buf;
(void)idx;
new_table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
sizeof(nghttp2_map_bucket));
if (new_table == NULL) {
if (new_hashbits > NGHTTP2_MAP_MAX_HASHBITS) {
return NGHTTP2_ERR_NOMEM;
}
tablelen = (size_t)1 << new_hashbits;
buf = nghttp2_mem_calloc(map->mem, tablelen,
sizeof(nghttp2_map_key_type) + sizeof(void *) +
sizeof(uint8_t));
if (buf == NULL) {
return NGHTTP2_ERR_NOMEM;
}
new_map.keys = buf;
new_map.data =
(void *)((uint8_t *)new_map.keys + tablelen * sizeof(nghttp2_map_key_type));
new_map.psl = (uint8_t *)new_map.data + tablelen * sizeof(void *);
if (map->size) {
tablelen = 1u << map->hashbits;
tablelen = (size_t)1 << map->hashbits;
for (i = 0; i < tablelen; ++i) {
bkt = &map->table[i];
if (bkt->data == NULL) {
if (map->psl[i] == 0) {
continue;
}
rv = insert(new_table, new_hashbits, bkt->key, bkt->data);
idx = map_insert(&new_map, map->keys[i], map->data[i]);
assert(0 == rv);
/* map_insert must not fail because all keys are unique during
resize. */
assert(idx >= 0);
}
}
nghttp2_mem_free(map->mem, map->table);
nghttp2_mem_free(map->mem, map->keys);
map->keys = new_map.keys;
map->data = new_map.data;
map->psl = new_map.psl;
map->hashbits = new_hashbits;
map->table = new_table;
return 0;
}
/* NGHTTP2_MAX_PSL_RESIZE_THRESH is the maximum psl threshold. If
reached, resize the table. */
#define NGHTTP2_MAX_PSL_RESIZE_THRESH 128
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
int rv;
size_t tablelen;
nghttp2_ssize idx;
assert(data);
/* Load factor is 0.75 */
/* Under the very initial condition, that is map->size == 0 and
map->hashbits == 0, 4 > 3 still holds nicely. */
if ((map->size + 1) * 4 > (1u << map->hashbits) * 3) {
if (map->hashbits) {
rv = map_resize(map, map->hashbits + 1);
if (rv != 0) {
return rv;
}
} else {
rv = map_resize(map, NGHTTP2_INITIAL_TABLE_LENBITS);
if (rv != 0) {
return rv;
}
/* tablelen is incorrect if map->hashbits == 0 which leads to
tablelen = 1, but it is only used to check the load factor, and
it works in this special case. */
tablelen = (size_t)1 << map->hashbits;
/* Load factor is 7 / 8. Because tablelen is power of 2, (tablelen
- (tablelen >> 3)) computes tablelen * 7 / 8. */
if (map->size + 1 >= (tablelen - (tablelen >> 3))) {
rv = map_resize(map, map->hashbits ? map->hashbits + 1
: NGHTTP2_INITIAL_HASHBITS);
if (rv != 0) {
return rv;
}
idx = map_insert(map, key, data);
if (idx < 0) {
return (int)idx;
}
return 0;
}
rv = insert(map->table, map->hashbits, key, data);
if (rv != 0) {
return rv;
idx = map_insert(map, key, data);
if (idx < 0) {
return (int)idx;
}
++map->size;
/* Resize if psl reaches really large value which is almost
improbable, but just in case. */
if (map->psl[idx] - 1 < NGHTTP2_MAX_PSL_RESIZE_THRESH) {
return 0;
}
return 0;
return map_resize(map, map->hashbits + 1);
}
void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
size_t idx;
nghttp2_map_bucket *bkt;
size_t psl = 0;
size_t psl = 1;
size_t mask;
if (map->size == 0) {
return NULL;
}
idx = hash(key, map->hashbits);
mask = (1u << map->hashbits) - 1;
idx = map_index(map, key);
mask = ((size_t)1 << map->hashbits) - 1;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL || psl > bkt->psl) {
if (psl > map->psl[idx]) {
return NULL;
}
if (bkt->key == key) {
return bkt->data;
if (map->keys[idx] == key) {
return map->data[idx];
}
++psl;
@@ -244,38 +307,36 @@ void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
size_t idx;
nghttp2_map_bucket *b, *bkt;
size_t psl = 0;
size_t dest;
size_t psl = 1, kpsl;
size_t mask;
if (map->size == 0) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
idx = hash(key, map->hashbits);
mask = (1u << map->hashbits) - 1;
idx = map_index(map, key);
mask = ((size_t)1 << map->hashbits) - 1;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL || psl > bkt->psl) {
if (psl > map->psl[idx]) {
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
if (bkt->key == key) {
b = bkt;
if (map->keys[idx] == key) {
dest = idx;
idx = (idx + 1) & mask;
for (;;) {
bkt = &map->table[idx];
if (bkt->data == NULL || bkt->psl == 0) {
b->data = NULL;
kpsl = map->psl[idx];
if (kpsl <= 1) {
map->psl[dest] = 0;
break;
}
--bkt->psl;
*b = *bkt;
b = bkt;
map_set_entry(map, dest, map->keys[idx], map->data[idx], kpsl - 1);
dest = idx;
idx = (idx + 1) & mask;
}
@@ -295,7 +356,7 @@ void nghttp2_map_clear(nghttp2_map *map) {
return;
}
memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits));
memset(map->psl, 0, sizeof(*map->psl) * ((size_t)1 << map->hashbits));
map->size = 0;
}

View File

@@ -28,7 +28,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -38,15 +38,15 @@
typedef int32_t nghttp2_map_key_type;
typedef struct nghttp2_map_bucket {
uint32_t psl;
nghttp2_map_key_type key;
void *data;
} nghttp2_map_bucket;
typedef struct nghttp2_map {
nghttp2_map_bucket *table;
nghttp2_map_key_type *keys;
void **data;
/* psl is the Probe Sequence Length. 0 has special meaning that the
element is not stored at i-th position if psl[i] == 0. Because
of this, the actual psl value is psl[i] - 1 if psl[i] > 0. */
uint8_t *psl;
nghttp2_mem *mem;
uint64_t seed;
size_t size;
size_t hashbits;
} nghttp2_map;
@@ -54,7 +54,7 @@ typedef struct nghttp2_map {
/*
* nghttp2_map_init initializes the map |map|.
*/
void nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
void nghttp2_map_init(nghttp2_map *map, uint64_t seed, nghttp2_mem *mem);
/*
* nghttp2_map_free deallocates any resources allocated for |map|.
@@ -123,6 +123,6 @@ int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
#ifndef WIN32
void nghttp2_map_print_distance(const nghttp2_map *map);
#endif /* !WIN32 */
#endif /* !defined(WIN32) */
#endif /* NGHTTP2_MAP_H */
#endif /* !defined(NGHTTP2_MAP_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -42,4 +42,4 @@ void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
#endif /* NGHTTP2_MEM_H */
#endif /* !defined(NGHTTP2_MEM_H) */

View File

@@ -27,28 +27,28 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */
#endif /* defined(HAVE_ARPA_INET_H) */
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
#endif /* defined(HAVE_NETINET_IN_H) */
#include <nghttp2/nghttp2.h>
#if defined(WIN32)
#ifdef WIN32
/* Windows requires ws2_32 library for ntonl family functions. We
define inline functions for those function so that we don't have
dependency on that lib. */
# ifdef _MSC_VER
# define STIN static __inline
# else
# else /* !defined(_MSC_VER) */
# define STIN static inline
# endif
# endif /* !defined(_MSC_VER) */
STIN uint32_t htonl(uint32_t hostlong) {
uint32_t res;
@@ -86,6 +86,6 @@ STIN uint16_t ntohs(uint16_t netshort) {
return res;
}
#endif /* WIN32 */
#endif /* defined(WIN32) */
#endif /* NGHTTP2_NET_H */
#endif /* !defined(NGHTTP2_NET_H) */

View File

@@ -155,3 +155,10 @@ void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) {
option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
option->max_continuations = val;
}
void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
uint64_t burst, uint64_t rate) {
option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT;
option->glitch_burst = burst;
option->glitch_rate = rate;
}

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -72,6 +72,7 @@ typedef enum {
NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17,
} nghttp2_option_flag;
/**
@@ -83,6 +84,11 @@ struct nghttp2_option {
*/
uint64_t stream_reset_burst;
uint64_t stream_reset_rate;
/**
* NGHTTP2_OPT_GLITCH_RATE_LIMIT
*/
uint64_t glitch_burst;
uint64_t glitch_rate;
/**
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
*/
@@ -154,4 +160,4 @@ struct nghttp2_option {
uint8_t user_recv_ext_types[32];
};
#endif /* NGHTTP2_OPTION_H */
#endif /* !defined(NGHTTP2_OPTION_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#include "nghttp2_frame.h"
@@ -186,4 +186,4 @@ void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q);
/* Returns the size of the queue */
#define nghttp2_outbound_queue_size(Q) ((Q)->n)
#endif /* NGHTTP2_OUTBOUND_ITEM_H */
#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#include "nghttp2_int.h"
@@ -121,4 +121,4 @@ int nghttp2_pq_each(nghttp2_pq *pq, nghttp2_pq_item_cb fun, void *arg);
*/
void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
#endif /* NGHTTP2_PQ_H */
#endif /* !defined(NGHTTP2_PQ_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -39,4 +39,4 @@
*/
void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
#endif /* NGHTTP2_PRIORITY_SPEC_H */
#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -48,4 +48,4 @@ void *nghttp2_queue_front(nghttp2_queue *queue);
void *nghttp2_queue_back(nghttp2_queue *queue);
int nghttp2_queue_empty(nghttp2_queue *queue);
#endif /* NGHTTP2_QUEUE_H */
#endif /* !defined(NGHTTP2_QUEUE_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -54,4 +54,4 @@ void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
succeeds, or -1. */
int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
#endif /* NGHTTP2_RATELIM_H */
#endif /* !defined(NGHTTP2_RATELIM_H) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -77,4 +77,4 @@ int nghttp2_rcbuf_new2(nghttp2_rcbuf **rcbuf_ptr, const uint8_t *src,
*/
void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
#endif /* NGHTTP2_RCBUF_H */
#endif /* !defined(NGHTTP2_RCBUF_H) */

View File

@@ -41,7 +41,7 @@
#include "nghttp2_debug.h"
#include "nghttp2_submit.h"
nghttp2_stream root;
nghttp2_stream nghttp2_stream_root;
/*
* Returns non-zero if the number of outgoing opened streams is larger
@@ -438,6 +438,7 @@ static int session_new(nghttp2_session **session_ptr,
size_t max_deflate_dynamic_table_size =
NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
size_t i;
uint64_t map_seed;
if (mem == NULL) {
mem = nghttp2_mem_default();
@@ -474,6 +475,10 @@ static int session_new(nghttp2_session **session_ptr,
NGHTTP2_DEFAULT_STREAM_RESET_BURST,
NGHTTP2_DEFAULT_STREAM_RESET_RATE);
nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
NGHTTP2_DEFAULT_GLITCH_BURST,
NGHTTP2_DEFAULT_GLITCH_RATE);
if (server) {
(*session_ptr)->server = 1;
}
@@ -566,6 +571,11 @@ static int session_new(nghttp2_session **session_ptr,
if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
(*session_ptr)->max_continuations = option->max_continuations;
}
if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) {
nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
option->glitch_burst, option->glitch_rate);
}
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -594,7 +604,13 @@ static int session_new(nghttp2_session **session_ptr,
goto fail_aob_framebuf;
}
nghttp2_map_init(&(*session_ptr)->streams, mem);
if (callbacks->rand_callback) {
callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed));
} else {
map_seed = 0;
}
nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem);
active_outbound_item_reset(&(*session_ptr)->aob, mem);
@@ -1092,6 +1108,15 @@ int nghttp2_session_add_item(nghttp2_session *session,
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
uint32_t error_code) {
return nghttp2_session_add_rst_stream_continue(
session, stream_id, error_code,
/* continue_without_stream = */ 1);
}
int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
int32_t stream_id,
uint32_t error_code,
int continue_without_stream) {
int rv;
nghttp2_outbound_item *item;
nghttp2_frame *frame;
@@ -1148,6 +1173,12 @@ int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
}
}
/* To keep the old behaviour, do not fail if stream was not
found. */
if (!continue_without_stream && !stream) {
return 0;
}
item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
if (item == NULL) {
return NGHTTP2_ERR_NOMEM;
@@ -3241,7 +3272,9 @@ static int session_call_on_invalid_header(nghttp2_session *session,
session, frame, nv->name->base, nv->name->len, nv->value->base,
nv->value->len, nv->flags, session->user_data);
} else {
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
/* If both callbacks are not set, the invalid field nv is
ignored. */
return 0;
}
if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -3326,6 +3359,10 @@ static uint32_t get_error_code_from_lib_error_code(int lib_error_code) {
case NGHTTP2_ERR_HTTP_HEADER:
case NGHTTP2_ERR_HTTP_MESSAGING:
return NGHTTP2_PROTOCOL_ERROR;
case NGHTTP2_ERR_INTERNAL:
return NGHTTP2_INTERNAL_ERROR;
case NGHTTP2_ERR_PUSH_CANCEL:
return NGHTTP2_CANCEL;
default:
return NGHTTP2_INTERNAL_ERROR;
}
@@ -3352,17 +3389,32 @@ static int session_call_on_invalid_frame_recv_callback(nghttp2_session *session,
return 0;
}
static int session_update_glitch_ratelim(nghttp2_session *session) {
if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
return 0;
}
nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec());
if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) {
return 0;
}
return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM);
}
static int session_handle_invalid_stream2(nghttp2_session *session,
int32_t stream_id,
nghttp2_frame *frame,
int lib_error_code) {
int rv;
rv = nghttp2_session_add_rst_stream(
session, stream_id, get_error_code_from_lib_error_code(lib_error_code));
if (rv != 0) {
return rv;
}
if (session->callbacks.on_invalid_frame_recv_callback) {
if (frame && session->callbacks.on_invalid_frame_recv_callback) {
if (session->callbacks.on_invalid_frame_recv_callback(
session, frame, lib_error_code, session->user_data) != 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -3517,7 +3569,29 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
rv2 = session_call_on_invalid_header(session, frame, &nv);
if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = NGHTTP2_ERR_HTTP_HEADER;
DEBUGF("recv: HTTP error: type=%u, id=%d, header %.*s: %.*s\n",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base);
rv = session_call_error_callback(
session, NGHTTP2_ERR_HTTP_HEADER,
"Invalid HTTP header field was received: frame type: "
"%u, stream: %d, name: [%.*s], value: [%.*s]",
frame->hd.type, frame->hd.stream_id, (int)nv.name->len,
nv.name->base, (int)nv.value->len, nv.value->base);
if (nghttp2_is_fatal(rv)) {
return rv;
}
rv = session_handle_invalid_stream2(
session, subject_stream->stream_id, frame,
NGHTTP2_ERR_HTTP_HEADER);
if (nghttp2_is_fatal(rv)) {
return rv;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
} else {
if (rv2 != 0) {
return rv2;
@@ -3557,13 +3631,8 @@ static int inflate_header_block(nghttp2_session *session, nghttp2_frame *frame,
return rv;
}
rv =
session_handle_invalid_stream2(session, subject_stream->stream_id,
frame, NGHTTP2_ERR_HTTP_HEADER);
if (nghttp2_is_fatal(rv)) {
return rv;
}
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
return nghttp2_session_terminate_session(session,
NGHTTP2_PROTOCOL_ERROR);
}
}
if (rv == 0) {
@@ -3676,27 +3745,7 @@ static int session_after_header_block_received(nghttp2_session *session) {
}
}
if (rv != 0) {
int32_t stream_id;
if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
stream_id = frame->push_promise.promised_stream_id;
} else {
stream_id = frame->hd.stream_id;
}
rv = session_handle_invalid_stream2(session, stream_id, frame,
NGHTTP2_ERR_HTTP_MESSAGING);
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (frame->hd.type == NGHTTP2_HEADERS &&
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
/* Don't call nghttp2_session_close_stream_if_shut_rdwr
because RST_STREAM has been submitted. */
}
return 0;
return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
}
}
@@ -4032,8 +4081,7 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
rv = nghttp2_stream_update_remote_initial_window_size(
stream, arg->new_window_size, arg->old_window_size);
if (rv != 0) {
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
return NGHTTP2_ERR_FLOW_CONTROL;
}
/* If window size gets positive, push deferred DATA frame to
@@ -4059,6 +4107,8 @@ static int update_remote_initial_window_size_func(void *entry, void *ptr) {
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FLOW_CONTROL
* Window size gets out of range.
*/
static int
session_update_remote_initial_window_size(nghttp2_session *session,
@@ -4082,8 +4132,7 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
rv = nghttp2_stream_update_local_initial_window_size(
stream, arg->new_window_size, arg->old_window_size);
if (rv != 0) {
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
return NGHTTP2_ERR_FLOW_CONTROL;
}
if (stream->window_update_queued) {
@@ -4117,6 +4166,8 @@ static int update_local_initial_window_size_func(void *entry, void *ptr) {
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_FLOW_CONTROL
* Window size gets out of range.
*/
static int
session_update_local_initial_window_size(nghttp2_session *session,
@@ -4503,9 +4554,9 @@ int nghttp2_session_on_push_promise_received(nghttp2_session *session,
session->max_incoming_reserved_streams) {
/* Currently, client does not retain closed stream, so we don't
check NGHTTP2_SHUT_RD condition here. */
rv = nghttp2_session_add_rst_stream(
session, frame->push_promise.promised_stream_id, NGHTTP2_CANCEL);
rv = session_handle_invalid_stream2(session,
frame->push_promise.promised_stream_id,
NULL, NGHTTP2_ERR_PUSH_CANCEL);
if (rv != 0) {
return rv;
}
@@ -4662,8 +4713,9 @@ static int session_on_stream_window_update_received(nghttp2_session *session,
}
if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
stream->remote_window_size) {
return session_handle_invalid_stream(session, frame,
NGHTTP2_ERR_FLOW_CONTROL);
return session_handle_invalid_connection(
session, frame, NGHTTP2_ERR_FLOW_CONTROL,
"WINDOW_UPDATE: window size overflow");
}
stream->remote_window_size += frame->window_update.window_size_increment;
@@ -4893,16 +4945,7 @@ int nghttp2_session_on_data_received(nghttp2_session *session,
if (session_enforce_http_messaging(session) &&
(frame->hd.flags & NGHTTP2_FLAG_END_STREAM)) {
if (nghttp2_http_on_remote_end_stream(stream) != 0) {
rv = nghttp2_session_add_rst_stream(session, stream->stream_id,
NGHTTP2_PROTOCOL_ERROR);
if (nghttp2_is_fatal(rv)) {
return rv;
}
nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_RD);
/* Don't call nghttp2_session_close_stream_if_shut_rdwr because
RST_STREAM has been submitted. */
return 0;
return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
}
}
@@ -4960,8 +5003,8 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
rv = adjust_recv_window_size(&stream->recv_window_size, delta_size,
stream->local_window_size);
if (rv != 0) {
return nghttp2_session_add_rst_stream(session, stream->stream_id,
NGHTTP2_FLOW_CONTROL_ERROR);
return nghttp2_session_terminate_session(session,
NGHTTP2_FLOW_CONTROL_ERROR);
}
/* We don't have to send WINDOW_UPDATE if the data received is the
last chunk in the incoming stream. */
@@ -5429,6 +5472,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
DEBUGF("recv: DATA not allowed stream_id=%d\n",
iframe->frame.hd.stream_id);
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
iframe->state = NGHTTP2_IB_IGN_DATA;
break;
}
@@ -5454,6 +5507,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
break;
}
/* Empty DATA frame without END_STREAM flag set is
suspicious. */
if (iframe->payloadleft == 0 &&
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
iframe->state = NGHTTP2_IB_READ_DATA;
break;
}
@@ -5520,8 +5587,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -5530,6 +5597,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
break;
}
@@ -5550,6 +5626,18 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
break;
}
/* This is deprecated RFC 7540 priorities mechanism which is
very unpopular. We do not expect it is received so
frequently. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
iframe->state = NGHTTP2_IB_READ_NBYTE;
inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN);
@@ -5566,7 +5654,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
DEBUGF("recv: WINDOW_UPDATE\n");
break;
}
#endif /* DEBUGBUILD */
#endif /* defined(DEBUGBUILD) */
iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
@@ -5722,8 +5810,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (check_ext_type_set(session->user_recv_ext_types,
iframe->frame.hd.type)) {
if (!session->callbacks.unpack_extension_callback) {
/* Silently ignore unknown frame type. */
/* Receiving too frequent unknown frames is suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
/* Silently ignore unknown frame type. */
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
@@ -5741,6 +5838,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
case NGHTTP2_ALTSVC:
if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
0) {
/* Receiving too frequent unknown frames is suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
@@ -5752,6 +5859,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
if (session->server) {
/* Receiving too frequent ALTSVC from client is
suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
@@ -5771,6 +5889,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
break;
case NGHTTP2_ORIGIN:
if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) {
/* Receiving too frequent unknown frames is suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
@@ -5782,6 +5910,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (session->server || iframe->frame.hd.stream_id ||
(iframe->frame.hd.flags & 0xf0)) {
/* Receiving too frequent invalid frames is
suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
@@ -5808,6 +5947,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
case NGHTTP2_PRIORITY_UPDATE:
if ((session->builtin_recv_ext_types &
NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
/* Receiving too frequent unknown frames is suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
break;
@@ -5835,6 +5984,17 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
break;
}
/* Receiving too frequent PRIORITY_UPDATE is
suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
@@ -5848,6 +6008,16 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
break;
default:
/* Receiving too frequent unknown frames is suspicious. */
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
@@ -5934,8 +6104,8 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -5944,6 +6114,15 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
break;
}
@@ -6009,9 +6188,9 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
}
if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.push_promise.promised_stream_id,
NGHTTP2_INTERNAL_ERROR);
rv = session_handle_invalid_stream2(
session, iframe->frame.push_promise.promised_stream_id, NULL,
NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6136,7 +6315,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
} else {
DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n");
}
#endif /* DEBUGBUILD */
#endif /* defined(DEBUGBUILD) */
readlen = inbound_frame_payload_readlen(iframe, in, last);
@@ -6189,12 +6368,12 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
iframe->payloadleft -= hd_proclen;
/* Use promised stream ID for PUSH_PROMISE */
rv = nghttp2_session_add_rst_stream(
rv = session_handle_invalid_stream2(
session,
iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
? iframe->frame.push_promise.promised_stream_id
: iframe->frame.hd.stream_id,
NGHTTP2_INTERNAL_ERROR);
NULL, NGHTTP2_ERR_INTERNAL);
if (nghttp2_is_fatal(rv)) {
return rv;
}
@@ -6241,6 +6420,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
session_inbound_frame_reset(session);
@@ -6364,7 +6547,7 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
} else {
fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
}
#endif /* DEBUGBUILD */
#endif /* defined(DEBUGBUILD) */
if (++session->num_continuations > session->max_continuations) {
return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
@@ -6466,6 +6649,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
busy = 1;
@@ -6482,6 +6669,20 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
iframe->frame.data.padlen = (size_t)padlen;
/* Empty DATA frame without END_STREAM flag set is
suspicious. */
if (iframe->payloadleft == 0 &&
(iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
rv = session_update_glitch_ratelim(session);
if (rv != 0) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
}
iframe->state = NGHTTP2_IB_READ_DATA;
break;
@@ -6524,6 +6725,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
data_readlen =
inbound_frame_effective_readlen(iframe, iframe->payloadleft, readlen);
@@ -6553,28 +6758,13 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
if (data_readlen > 0) {
if (session_enforce_http_messaging(session)) {
if (nghttp2_http_on_data_chunk(stream, (size_t)data_readlen) != 0) {
if (session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) {
/* Consume all data for connection immediately here */
rv = session_update_connection_consumed_size(
session, (size_t)data_readlen);
if (nghttp2_is_fatal(rv)) {
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_DATA) {
return (nghttp2_ssize)inlen;
}
}
rv = nghttp2_session_add_rst_stream(
session, iframe->frame.hd.stream_id, NGHTTP2_PROTOCOL_ERROR);
rv = nghttp2_session_terminate_session(session,
NGHTTP2_PROTOCOL_ERROR);
if (nghttp2_is_fatal(rv)) {
return rv;
}
busy = 1;
iframe->state = NGHTTP2_IB_IGN_DATA;
break;
return (nghttp2_ssize)inlen;
}
}
if (session->callbacks.on_data_chunk_recv_callback) {
@@ -6601,6 +6791,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
return rv;
}
if (iframe->state == NGHTTP2_IB_IGN_ALL) {
return (nghttp2_ssize)inlen;
}
session_inbound_frame_reset(session);
break;
@@ -7715,7 +7909,7 @@ int32_t nghttp2_session_get_last_proc_stream_id(nghttp2_session *session) {
nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
int32_t stream_id) {
if (stream_id == 0) {
return &root;
return &nghttp2_stream_root;
}
return nghttp2_session_get_stream_raw(session, stream_id);
@@ -7724,7 +7918,7 @@ nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
(void)session;
return &root;
return &nghttp2_stream_root;
}
int nghttp2_session_check_server_session(nghttp2_session *session) {

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#include "nghttp2_map.h"
@@ -45,7 +45,7 @@
preface handling. */
extern int nghttp2_enable_strict_preface;
extern nghttp2_stream root;
extern nghttp2_stream nghttp2_stream_root;
/*
* Option flags.
@@ -106,6 +106,10 @@ typedef struct {
#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
/* The default values for glitch rate limiter. */
#define NGHTTP2_DEFAULT_GLITCH_BURST 1000
#define NGHTTP2_DEFAULT_GLITCH_RATE 33
/* The default max number of CONTINUATION frames following an incoming
HEADER frame. */
#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
@@ -229,6 +233,8 @@ struct nghttp2_session {
/* Stream reset rate limiter. If receiving excessive amount of
stream resets, GOAWAY will be sent. */
nghttp2_ratelim stream_reset_ratelim;
/* Rate limiter for all kinds of glitches. */
nghttp2_ratelim glitch_ratelim;
/* Sequential number across all streams to process streams in
FIFO. */
uint64_t stream_seq;
@@ -402,6 +408,13 @@ int nghttp2_session_is_my_stream_id(nghttp2_session *session,
int nghttp2_session_add_item(nghttp2_session *session,
nghttp2_outbound_item *item);
/*
* This function wraps around nghttp2_session_add_rst_stream_continue
* with continue_without_stream = 1.
*/
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
uint32_t error_code);
/*
* Adds RST_STREAM frame for the stream |stream_id| with the error
* code |error_code|. This is a convenient function built on top of
@@ -409,7 +422,9 @@ int nghttp2_session_add_item(nghttp2_session *session,
*
* This function simply returns 0 without adding RST_STREAM frame if
* given stream is in NGHTTP2_STREAM_CLOSING state, because multiple
* RST_STREAM for a stream is redundant.
* RST_STREAM for a stream is redundant. It also returns 0 without
* adding the frame if |continue_without_stream| is nonzero, and
* stream was already gone.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
@@ -417,8 +432,10 @@ int nghttp2_session_add_item(nghttp2_session *session,
* NGHTTP2_ERR_NOMEM
* Out of memory.
*/
int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
uint32_t error_code);
int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
int32_t stream_id,
uint32_t error_code,
int continue_without_stream);
/*
* Adds PING frame. This is a convenient function built on top of
@@ -875,4 +892,4 @@ int nghttp2_session_update_recv_stream_window_size(nghttp2_session *session,
size_t delta_size,
int send_window_update);
#endif /* NGHTTP2_SESSION_H */
#endif /* !defined(NGHTTP2_SESSION_H) */

View File

@@ -151,7 +151,7 @@ void nghttp2_stream_promise_fulfilled(nghttp2_stream *stream) {
}
nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream) {
if (stream == &root) {
if (stream == &nghttp2_stream_root) {
return NGHTTP2_STREAM_STATE_IDLE;
}

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
#include "nghttp2_outbound_item.h"
@@ -294,4 +294,4 @@ void nghttp2_stream_attach_item(nghttp2_stream *stream,
*/
void nghttp2_stream_detach_item(nghttp2_stream *stream);
#endif /* NGHTTP2_STREAM */
#endif /* !defined(NGHTTP2_STREAM_H) */

View File

@@ -185,7 +185,8 @@ int nghttp2_submit_rst_stream(nghttp2_session *session, uint8_t flags,
return NGHTTP2_ERR_INVALID_ARGUMENT;
}
return nghttp2_session_add_rst_stream(session, stream_id, error_code);
return nghttp2_session_add_rst_stream_continue(
session, stream_id, error_code, /* continue_without_stream = */ 0);
}
int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
@@ -486,7 +487,7 @@ int nghttp2_submit_altsvc(nghttp2_session *session, uint8_t flags,
return 0;
fail_item_malloc:
free(buf);
nghttp2_mem_free(mem, buf);
return rv;
}
@@ -569,7 +570,7 @@ int nghttp2_submit_origin(nghttp2_session *session, uint8_t flags,
return 0;
fail_item_malloc:
free(ov_copy);
nghttp2_mem_free(mem, ov_copy);
return rv;
}
@@ -641,7 +642,7 @@ int nghttp2_submit_priority_update(nghttp2_session *session, uint8_t flags,
return 0;
fail_item_malloc:
free(buf);
nghttp2_mem_free(mem, buf);
return rv;
}

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -37,4 +37,4 @@ int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
int32_t stream_id,
const nghttp2_data_provider_wrap *dpw);
#endif /* NGHTTP2_SUBMIT_H */
#endif /* !defined(NGHTTP2_SUBMIT_H) */

View File

@@ -26,7 +26,7 @@
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif /* HAVE_WINDOWS_H */
#endif /* defined(HAVE_WINDOWS_H) */
#include <time.h>
@@ -40,12 +40,11 @@ static uint64_t time_now_sec(void) {
return (uint64_t)t;
}
#endif /* !HAVE_GETTICKCOUNT64 || __CYGWIN__ */
#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */
#if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__)
uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
#elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_DECL_CLOCK_MONOTONIC) && \
HAVE_DECL_CLOCK_MONOTONIC
#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
uint64_t nghttp2_time_now_sec(void) {
struct timespec tp;
int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
@@ -56,8 +55,8 @@ uint64_t nghttp2_time_now_sec(void) {
return (uint64_t)tp.tv_sec;
}
#else /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \
(!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */
#else /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \
(!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
#endif /* (!HAVE_CLOCK_GETTIME || !HAVE_DECL_CLOCK_MONOTONIC) && \
(!HAVE_GETTICKCOUNT64 || __CYGWIN__)) */
#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) && \
(!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */

View File

@@ -27,7 +27,7 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>
@@ -35,4 +35,4 @@
timepoint. If it is unable to get seconds, it returns 0. */
uint64_t nghttp2_time_now_sec(void);
#endif /* NGHTTP2_TIME_H */
#endif /* !defined(NGHTTP2_TIME_H) */

View File

@@ -24,7 +24,7 @@
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#endif /* defined(HAVE_CONFIG_H) */
#include <nghttp2/nghttp2.h>

View File

@@ -356,8 +356,8 @@ def _build_transition_table(ctx, node):
def huffman_tree_build_transition_table(ctx):
_build_transition_table(ctx, ctx.root)
NGHTTP2_HUFF_ACCEPTED = 1 << 14
NGHTTP2_HUFF_SYM = 1 << 15
NGHTTP2_HUFF_ACCEPTED = 1
NGHTTP2_HUFF_SYM = 1 << 1
def _print_transition_table(node):
if node.term is not None:
@@ -381,7 +381,7 @@ def _print_transition_table(node):
flags |= NGHTTP2_HUFF_ACCEPTED
elif nd.accept:
flags |= NGHTTP2_HUFF_ACCEPTED
print(' {{0x{:02x}, {}}},'.format(id | flags, out))
print(' {{0x{:02x}, {}, {}}},'.format(id, flags, out))
print('},')
_print_transition_table(node.left)
_print_transition_table(node.right)
@@ -390,22 +390,10 @@ def huffman_tree_print_transition_table(ctx):
_print_transition_table(ctx.root)
print('/* 256 */')
print('{')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
print(' {0x100, 0},')
for _ in range(16):
print(' {0x100, 0, 0},')
print('},')
if __name__ == '__main__':
@@ -458,6 +446,7 @@ enum {{
print('''\
typedef struct {
uint16_t fstate;
uint8_t flags;
uint8_t sym;
} nghttp2_huff_decode;
''')

View File

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

View File

@@ -1,25 +0,0 @@
# nghttp2 - HTTP/2 C Library
# Copyright (c) 2015 Tatsuhiro Tsujikawa
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
EXTRA_DIST = README.rst CMakeLists.txt
dist_pkgdata_SCRIPTS = fetch-ocsp-response

View File

@@ -1,10 +0,0 @@
fetch-ocsp-response is a Python script which performs OCSP query and
get response. It uses openssl command under the hood. nghttpx uses
it to enable OCSP stapling feature.
fetch-ocsp-response is a translation from original fetch-ocsp-response
written in Perl and which has been developed as part of h2o project
(https://github.com/h2o/h2o).
fetch-ocsp-response is usually installed under $(pkgdatadir), which is
$(prefix)/share/nghttp2.

View File

@@ -1,253 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# nghttp2 - HTTP/2 C Library
# Copyright (c) 2015 Tatsuhiro Tsujikawa
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# This program was translated from the program originally developed by
# h2o project (https://github.com/h2o/h2o), written in Perl. It had
# the following copyright notice:
# Copyright (c) 2015 DeNA Co., Ltd.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
from __future__ import unicode_literals
import argparse
import io
import os
import os.path
import re
import shutil
import subprocess
import sys
import tempfile
# make this program work for both Python 3 and Python 2.
try:
from urllib.parse import urlparse
stdout_bwrite = sys.stdout.buffer.write
except ImportError:
from urlparse import urlparse
stdout_bwrite = sys.stdout.write
def die(msg):
sys.stderr.write(msg)
sys.stderr.write('\n')
sys.exit(255)
def tempfail(msg):
sys.stderr.write(msg)
sys.stderr.write('\n')
sys.exit(os.EX_TEMPFAIL)
def run_openssl(args, allow_tempfail=False):
buf = io.BytesIO()
try:
p = subprocess.Popen(args, stdout=subprocess.PIPE)
except Exception as e:
die('failed to invoke {}:{}'.format(args, e))
try:
while True:
data = p.stdout.read()
if len(data) == 0:
break
buf.write(data)
if p.wait() != 0:
raise Exception('nonzero return code {}'.format(p.returncode))
return buf.getvalue()
except Exception as e:
msg = 'OpenSSL exited abnormally: {}:{}'.format(args, e)
tempfail(msg) if allow_tempfail else die(msg)
def read_file(path):
with open(path, 'rb') as f:
return f.read()
def write_file(path, data):
with open(path, 'wb') as f:
f.write(data)
def detect_openssl_version(cmd):
return run_openssl([cmd, 'version']).decode('utf-8').strip()
def extract_ocsp_uri(cmd, cert_fn):
# obtain ocsp uri
ocsp_uri = run_openssl(
[cmd, 'x509', '-in', cert_fn, '-noout',
'-ocsp_uri']).decode('utf-8').strip()
if not re.match(r'^https?://', ocsp_uri):
die('failed to extract ocsp URI from {}'.format(cert_fn))
return ocsp_uri
def save_issuer_certificate(issuer_fn, cert_fn):
# save issuer certificate
chain = read_file(cert_fn).decode('utf-8')
m = re.match(
r'.*?-----END CERTIFICATE-----.*?(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)',
chain, re.DOTALL)
if not m:
die('--issuer option was not used, and failed to extract issuer certificate from the certificate')
write_file(issuer_fn, (m.group(1) + '\n').encode('utf-8'))
def send_and_receive_ocsp(respder_fn, cmd, cert_fn, issuer_fn, ocsp_uri,
ocsp_host, openssl_version):
# obtain response (without verification)
sys.stderr.write('sending OCSP request to {}\n'.format(ocsp_uri))
args = [
cmd, 'ocsp', '-issuer', issuer_fn, '-cert', cert_fn, '-url', ocsp_uri,
'-noverify', '-respout', respder_fn
]
ver = openssl_version.lower()
if ver.startswith('openssl 1.0.') or ver.startswith('libressl '):
args.extend(['-header', 'Host', ocsp_host])
resp = run_openssl(args, allow_tempfail=True)
return resp.decode('utf-8')
def verify_response(cmd, tempdir, issuer_fn, respder_fn):
# verify the response
sys.stderr.write('verifying the response signature\n')
verify_fn = os.path.join(tempdir, 'verify.out')
# try from exotic options
allextra = [
# for comodo
['-VAfile', issuer_fn],
# these options are only available in OpenSSL >= 1.0.2
['-partial_chain', '-trusted_first', '-CAfile', issuer_fn],
# for OpenSSL <= 1.0.1
['-CAfile', issuer_fn],
]
for extra in allextra:
with open(verify_fn, 'w+b') as f:
args = [cmd, 'ocsp', '-respin', respder_fn]
args.extend(extra)
p = subprocess.Popen(args, stdout=f, stderr=f)
if p.wait() == 0:
# OpenSSL <= 1.0.1, openssl ocsp still returns exit
# code 0 even if verification was failed. So check
# the error message in stderr output.
f.seek(0)
if f.read().decode('utf-8').find(
'Response Verify Failure') != -1:
continue
sys.stderr.write('verify OK (used: {})\n'.format(extra))
return True
sys.stderr.write(read_file(verify_fn).decode('utf-8'))
return False
def fetch_ocsp_response(cmd, cert_fn, tempdir, issuer_fn=None):
openssl_version = detect_openssl_version(cmd)
sys.stderr.write(
'fetch-ocsp-response (using {})\n'.format(openssl_version))
ocsp_uri = extract_ocsp_uri(cmd, cert_fn)
ocsp_host = urlparse(ocsp_uri).netloc
if not issuer_fn:
issuer_fn = os.path.join(tempdir, 'issuer.crt')
save_issuer_certificate(issuer_fn, cert_fn)
respder_fn = os.path.join(tempdir, 'resp.der')
resp = send_and_receive_ocsp(
respder_fn, cmd, cert_fn, issuer_fn, ocsp_uri, ocsp_host,
openssl_version)
sys.stderr.write('{}\n'.format(resp))
# OpenSSL 1.0.2 still returns exit code 0 even if ocsp responder
# returned error status (e.g., trylater(3))
if resp.find('Responder Error:') != -1:
raise Exception('responder returned error')
if not verify_response(cmd, tempdir, issuer_fn, respder_fn):
tempfail('failed to verify the response')
# success
res = read_file(respder_fn)
stdout_bwrite(res)
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description=
'''The command issues an OCSP request for given server certificate, verifies the response and prints the resulting DER.''',
epilog=
'''The command exits 0 if successful, or 75 (EX_TEMPFAIL) on temporary error. Other exit codes may be returned in case of hard errors.''')
parser.add_argument(
'--issuer',
metavar='FILE',
help=
'issuer certificate (if omitted, is extracted from the certificate chain)')
parser.add_argument('--openssl',
metavar='CMD',
help='openssl command to use (default: "openssl")',
default='openssl')
parser.add_argument('certificate',
help='path to certificate file to validate')
args = parser.parse_args()
tempdir = None
try:
# Python3.2 has tempfile.TemporaryDirectory, which has nice
# feature to delete its tree by cleanup() function. We have
# to support Python2.7, so we have to do this manually.
tempdir = tempfile.mkdtemp()
fetch_ocsp_response(args.openssl, args.certificate, tempdir,
args.issuer)
finally:
if tempdir:
shutil.rmtree(tempdir)

View File

@@ -16,7 +16,9 @@ include_directories(
${LIBNGHTTP3_INCLUDE_DIRS}
${LIBNGTCP2_INCLUDE_DIRS}
${LIBNGTCP2_CRYPTO_QUICTLS_INCLUDE_DIRS}
${LIBNGTCP2_CRYPTO_LIBRESSL_INCLUDE_DIRS}
${LIBNGTCP2_CRYPTO_WOLFSSL_INCLUDE_DIRS}
${LIBNGTCP2_CRYPTO_OSSL_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${WOLFSSL_INCLUDE_DIRS}
${LIBCARES_INCLUDE_DIRS}
@@ -36,7 +38,9 @@ link_libraries(
${LIBNGHTTP3_LIBRARIES}
${LIBNGTCP2_LIBRARIES}
${LIBNGTCP2_CRYPTO_QUICTLS_LIBRARIES}
${LIBNGTCP2_CRYPTO_LIBRESSL_LIBRARIES}
${LIBNGTCP2_CRYPTO_WOLFSSL_LIBRARIES}
${LIBNGTCP2_CRYPTO_OSSL_LIBRARIES}
${OPENSSL_LIBRARIES}
${WOLFSSL_LIBRARIES}
${LIBCARES_LIBRARIES}
@@ -85,7 +89,6 @@ if(ENABLE_APP)
list(APPEND H2LOAD_SOURCES
h2load_http3_session.cc
h2load_quic.cc
quic.cc
)
endif()
@@ -125,7 +128,6 @@ if(ENABLE_APP)
shrpx_api_downstream_connection.cc
shrpx_health_monitor_downstream_connection.cc
shrpx_null_downstream_connection.cc
shrpx_exec.cc
shrpx_dns_resolver.cc
shrpx_dual_dns_resolver.cc
shrpx_dns_tracker.cc
@@ -147,7 +149,6 @@ if(ENABLE_APP)
shrpx_quic_connection_handler.cc
shrpx_http3_upstream.cc
http3.cc
quic.cc
siphash.cc
)
endif()
@@ -248,6 +249,7 @@ if(ENABLE_HPACK_TOOLS)
comp_helper.c
util.cc
timegm.c
tls.cc
)
add_executable(inflatehd ${inflatehd_SOURCES})
add_executable(deflatehd ${deflatehd_SOURCES})

View File

@@ -39,30 +39,28 @@ HtmlParser::HtmlParser(const std::string &base_uri)
HtmlParser::~HtmlParser() { htmlFreeParserCtxt(parser_ctx_); }
namespace {
StringRef get_attr(const xmlChar **attrs, const StringRef &name) {
std::string_view get_attr(const xmlChar **attrs, const std::string_view &name) {
if (attrs == nullptr) {
return StringRef{};
return ""sv;
}
for (; *attrs; attrs += 2) {
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]))};
if (util::strieq(std::string_view{reinterpret_cast<const char *>(attrs[0])},
name)) {
return std::string_view{reinterpret_cast<const char *>(attrs[1])};
}
}
return StringRef{};
return ""sv;
}
} // namespace
namespace {
ResourceType
get_resource_type_for_preload_as(const StringRef &attribute_value) {
if (util::strieq("image"_sr, attribute_value)) {
get_resource_type_for_preload_as(const std::string_view &attribute_value) {
if (util::strieq("image"sv, attribute_value)) {
return REQ_IMG;
} else if (util::strieq("style"_sr, attribute_value)) {
} else if (util::strieq("style"sv, attribute_value)) {
return REQ_CSS;
} else if (util::strieq("script"_sr, attribute_value)) {
} else if (util::strieq("script"sv, attribute_value)) {
return REQ_UNBLOCK_JS;
} else {
return REQ_OTHERS;
@@ -71,7 +69,7 @@ get_resource_type_for_preload_as(const StringRef &attribute_value) {
} // namespace
namespace {
void add_link(ParserData *parser_data, const StringRef &uri,
void add_link(ParserData *parser_data, const std::string_view &uri,
ResourceType res_type) {
auto u = xmlBuildURI(
reinterpret_cast<const xmlChar *>(uri.data()),
@@ -88,37 +86,36 @@ namespace {
void start_element_func(void *user_data, const xmlChar *src_name,
const xmlChar **attrs) {
auto parser_data = static_cast<ParserData *>(user_data);
auto name =
StringRef{src_name, strlen(reinterpret_cast<const char *>(src_name))};
if (util::strieq("head"_sr, name)) {
auto name = std::string_view{reinterpret_cast<const char *>(src_name)};
if (util::strieq("head"sv, name)) {
++parser_data->inside_head;
}
if (util::strieq("link"_sr, name)) {
auto rel_attr = get_attr(attrs, "rel"_sr);
auto href_attr = get_attr(attrs, "href"_sr);
if (util::strieq("link"sv, name)) {
auto rel_attr = get_attr(attrs, "rel"sv);
auto href_attr = get_attr(attrs, "href"sv);
if (rel_attr.empty() || href_attr.empty()) {
return;
}
if (util::strieq("shortcut icon"_sr, rel_attr)) {
if (util::strieq("shortcut icon"sv, rel_attr)) {
add_link(parser_data, href_attr, REQ_OTHERS);
} else if (util::strieq("stylesheet"_sr, rel_attr)) {
} else if (util::strieq("stylesheet"sv, rel_attr)) {
add_link(parser_data, href_attr, REQ_CSS);
} else if (util::strieq("preload"_sr, rel_attr)) {
auto as_attr = get_attr(attrs, "as"_sr);
} else if (util::strieq("preload"sv, rel_attr)) {
auto as_attr = get_attr(attrs, "as"sv);
if (as_attr.empty()) {
return;
}
add_link(parser_data, href_attr,
get_resource_type_for_preload_as(as_attr));
}
} else if (util::strieq("img"_sr, name)) {
auto src_attr = get_attr(attrs, "src"_sr);
} else if (util::strieq("img"sv, name)) {
auto src_attr = get_attr(attrs, "src"sv);
if (src_attr.empty()) {
return;
}
add_link(parser_data, src_attr, REQ_IMG);
} else if (util::strieq("script"_sr, name)) {
auto src_attr = get_attr(attrs, "src"_sr);
} else if (util::strieq("script"sv, name)) {
auto src_attr = get_attr(attrs, "src"sv);
if (src_attr.empty()) {
return;
}
@@ -134,9 +131,8 @@ void start_element_func(void *user_data, const xmlChar *src_name,
namespace {
void end_element_func(void *user_data, const xmlChar *name) {
auto parser_data = static_cast<ParserData *>(user_data);
if (util::strieq(
"head"_sr,
StringRef{name, strlen(reinterpret_cast<const char *>(name))})) {
if (util::strieq("head"sv,
std::string_view{reinterpret_cast<const char *>(name)})) {
--parser_data->inside_head;
}
}
@@ -181,9 +177,9 @@ xmlSAXHandler saxHandler = {
int HtmlParser::parse_chunk(const char *chunk, size_t size, int fin) {
if (!parser_ctx_) {
parser_ctx_ =
htmlCreatePushParserCtxt(&saxHandler, &parser_data_, chunk, size,
base_uri_.c_str(), XML_CHAR_ENCODING_NONE);
parser_ctx_ = htmlCreatePushParserCtxt(
&saxHandler, &parser_data_, chunk, static_cast<int>(size),
base_uri_.c_str(), XML_CHAR_ENCODING_NONE);
if (!parser_ctx_) {
return -1;
} else {
@@ -199,7 +195,7 @@ int HtmlParser::parse_chunk(const char *chunk, size_t size, int fin) {
}
int HtmlParser::parse_chunk_internal(const char *chunk, size_t size, int fin) {
int rv = htmlParseChunk(parser_ctx_, chunk, size, fin);
int rv = htmlParseChunk(parser_ctx_, chunk, static_cast<int>(size), fin);
if (rv == 0) {
return 0;
} else {

View File

@@ -31,10 +31,8 @@
#include <string>
#ifdef HAVE_LIBXML2
# include <libxml/HTMLparser.h>
#endif // HAVE_LIBXML2
#endif // defined(HAVE_LIBXML2)
namespace nghttp2 {
@@ -72,7 +70,7 @@ private:
ParserData parser_data_;
};
#else // !HAVE_LIBXML2
#else // !defined(HAVE_LIBXML2)
class HtmlParser {
public:
@@ -87,8 +85,8 @@ private:
std::vector<std::pair<std::string, ResourceType>> links_;
};
#endif // !HAVE_LIBXML2
#endif // !defined(HAVE_LIBXML2)
} // namespace nghttp2
#endif // HTML_PARSER_H
#endif // !defined(HTML_PARSER_H)

View File

@@ -27,26 +27,26 @@
#include <sys/stat.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#endif // defined(HAVE_SYS_SOCKET_H)
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif // HAVE_NETDB_H
#endif // defined(HAVE_NETDB_H)
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif // HAVE_UNISTD_H
#endif // defined(HAVE_UNISTD_H)
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif // HAVE_FCNTL_H
#endif // defined(HAVE_FCNTL_H)
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#endif // defined(HAVE_NETINET_IN_H)
#include <netinet/tcp.h>
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif // HAVE_ARPA_INET_H
#endif // defined(HAVE_ARPA_INET_H)
#include <cassert>
#include <set>
#include <unordered_set>
#include <iostream>
#include <thread>
#include <mutex>
@@ -58,13 +58,13 @@
# include <wolfssl/options.h>
# include <wolfssl/openssl/err.h>
# include <wolfssl/openssl/dh.h>
#else // !NGHTTP2_OPENSSL_IS_WOLFSSL
#else // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
# include <openssl/err.h>
# include <openssl/dh.h>
# if OPENSSL_3_0_0_API
# include <openssl/decoder.h>
# endif // OPENSSL_3_0_0_API
#endif // !NGHTTP2_OPENSSL_IS_WOLFSSL
#endif // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
#include <zlib.h>
@@ -76,16 +76,17 @@
#ifndef O_BINARY
# define O_BINARY (0)
#endif // O_BINARY
#endif // !defined(O_BINARY)
using namespace std::chrono_literals;
using namespace std::string_literals;
namespace nghttp2 {
namespace {
// TODO could be constexpr
constexpr auto DEFAULT_HTML = "index.html"_sr;
constexpr auto NGHTTPD_SERVER = "nghttpd nghttp2/" NGHTTP2_VERSION ""_sr;
constexpr auto DEFAULT_HTML = "index.html"sv;
constexpr auto NGHTTPD_SERVER = "nghttpd nghttp2/" NGHTTP2_VERSION ""sv;
} // namespace
namespace {
@@ -101,6 +102,7 @@ void print_session_id(int64_t id) { std::cout << "[id=" << id << "] "; }
Config::Config()
: mime_types_file("/etc/mime.types"),
groups("X25519:P-256:P-384:P-521"sv),
stream_read_timeout(1_min),
stream_write_timeout(1_min),
data_ptr(nullptr),
@@ -250,7 +252,9 @@ public:
option_(nullptr),
next_session_id_(1),
tstamp_cached_(ev_now(loop)),
cached_date_(util::http_date(tstamp_cached_)) {
cached_date_(
util::format_http_date(std::chrono::system_clock::from_time_t(
static_cast<time_t>(tstamp_cached_)))) {
nghttp2_session_callbacks_new(&callbacks_);
fill_callback(callbacks_, config_);
@@ -259,7 +263,7 @@ public:
if (config_->encoder_header_table_size != -1) {
nghttp2_option_set_max_deflate_dynamic_table_size(
option_, config_->encoder_header_table_size);
option_, as_unsigned(config_->encoder_header_table_size));
}
ev_timer_init(&release_fd_timer_, release_fd_cb, 0., RELEASE_FD_TIMEOUT);
@@ -326,7 +330,11 @@ public:
}
add_handler(handler.release());
}
void update_cached_date() { cached_date_ = util::http_date(tstamp_cached_); }
void update_cached_date() {
cached_date_ =
util::format_http_date(std::chrono::system_clock::from_time_t(
static_cast<time_t>(tstamp_cached_)));
}
const std::string &get_cached_date() {
auto t = ev_now(loop_);
if (t != tstamp_cached_) {
@@ -370,19 +378,13 @@ public:
return nullptr;
}
FileEntry *cache_fd(const std::string &path, const FileEntry &ent) {
#ifdef HAVE_STD_MAP_EMPLACE
auto rv = fd_cache_.emplace(path, std::make_unique<FileEntry>(ent));
#else // !HAVE_STD_MAP_EMPLACE
// for gcc-4.7
auto rv =
fd_cache_.insert(std::make_pair(path, std::make_unique<FileEntry>(ent)));
#endif // !HAVE_STD_MAP_EMPLACE
auto &res = (*rv).second;
res->it = rv;
fd_cache_lru_.append(res.get());
while (fd_cache_.size() > FILE_ENTRY_EVICT_THRES) {
auto ent = fd_cache_lru_.head;
auto ent = fd_cache_lru_.front();
if (ent->usecount) {
break;
}
@@ -407,7 +409,8 @@ public:
// cache. The timer will be started when there is no handler.
}
void release_unused_fd() {
for (auto i = std::begin(fd_cache_); i != std::end(fd_cache_);) {
for (auto i = std::ranges::begin(fd_cache_);
i != std::ranges::end(fd_cache_);) {
auto &ent = (*i).second;
if (ent->usecount != 0) {
++i;
@@ -423,10 +426,10 @@ public:
bool handlers_empty() const { return handlers_.empty(); }
private:
std::set<Http2Handler *> handlers_;
std::unordered_set<Http2Handler *> handlers_;
// cache for file descriptors to read file.
std::multimap<std::string, std::unique_ptr<FileEntry>> fd_cache_;
DList<FileEntry> fd_cache_lru_;
std::unordered_multimap<std::string, std::unique_ptr<FileEntry>> fd_cache_;
SList<FileEntry, &FileEntry::slent> fd_cache_lru_;
HttpServer *sv_;
struct ev_loop *loop_;
const Config *config_;
@@ -615,16 +618,16 @@ int Http2Handler::fill_wb() {
if (datalen < 0) {
std::cerr << "nghttp2_session_mem_send2() returned error: "
<< nghttp2_strerror(datalen) << std::endl;
<< nghttp2_strerror(static_cast<int>(datalen)) << std::endl;
return -1;
}
if (datalen == 0) {
break;
}
auto n = wb_.write(data, datalen);
auto n = wb_.write(data, as_unsigned(datalen));
if (n < static_cast<decltype(n)>(datalen)) {
data_pending_ = data + n;
data_pendinglen_ = datalen - n;
data_pendinglen_ = as_unsigned(datalen) - n;
break;
}
}
@@ -632,7 +635,6 @@ int Http2Handler::fill_wb() {
}
int Http2Handler::read_clear() {
int rv;
std::array<uint8_t, 8_k> buf;
ssize_t nread;
@@ -649,14 +651,15 @@ int Http2Handler::read_clear() {
}
if (get_config()->hexdump) {
util::hexdump(stdout, buf.data(), nread);
util::hexdump(stdout, buf.data(), as_unsigned(nread));
}
rv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
if (rv < 0) {
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
auto nrecv =
nghttp2_session_mem_recv2(session_, buf.data(), as_unsigned(nread));
if (nrecv < 0) {
if (nrecv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
std::cerr << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv) << std::endl;
<< nghttp2_strerror(static_cast<int>(nrecv)) << std::endl;
}
return -1;
}
@@ -679,7 +682,7 @@ int Http2Handler::write_clear() {
}
return -1;
}
wb_.drain(nwrite);
wb_.drain(as_unsigned(nwrite));
continue;
}
wb_.reset();
@@ -770,17 +773,17 @@ int Http2Handler::read_tls() {
}
}
auto nread = rv;
auto nread = static_cast<size_t>(rv);
if (get_config()->hexdump) {
util::hexdump(stdout, buf.data(), nread);
}
rv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
if (rv < 0) {
if (rv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
auto nrecv = nghttp2_session_mem_recv2(session_, buf.data(), nread);
if (nrecv < 0) {
if (nrecv != NGHTTP2_ERR_BAD_CLIENT_MAGIC) {
std::cerr << "nghttp2_session_mem_recv2() returned error: "
<< nghttp2_strerror(rv) << std::endl;
<< nghttp2_strerror(static_cast<int>(nrecv)) << std::endl;
}
return -1;
}
@@ -800,7 +803,7 @@ int Http2Handler::write_tls() {
for (;;) {
if (wb_.rleft() > 0) {
auto rv = SSL_write(ssl_, wb_.pos, wb_.rleft());
auto rv = SSL_write(ssl_, wb_.pos, static_cast<int>(wb_.rleft()));
if (rv <= 0) {
auto err = SSL_get_error(ssl_, rv);
@@ -816,7 +819,7 @@ int Http2Handler::write_tls() {
}
}
wb_.drain(rv);
wb_.drain(static_cast<size_t>(rv));
continue;
}
wb_.reset();
@@ -861,14 +864,14 @@ int Http2Handler::connection_made() {
size_t niv = 2;
entry[0].settings_id = NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS;
entry[0].value = config->max_concurrent_streams;
entry[0].value = static_cast<uint32_t>(config->max_concurrent_streams);
entry[1].settings_id = NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES;
entry[1].value = 1;
if (config->header_table_size >= 0) {
entry[niv].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
entry[niv].value = config->header_table_size;
entry[niv].value = static_cast<uint32_t>(config->header_table_size);
++niv;
}
@@ -905,7 +908,7 @@ int Http2Handler::verify_alpn_result() {
// Check the negotiated protocol in ALPN
SSL_get0_alpn_selected(ssl_, &next_proto, &next_proto_len);
if (next_proto) {
auto proto = StringRef{next_proto, next_proto_len};
auto proto = as_string_view(next_proto, next_proto_len);
if (sessions_->get_config()->verbose) {
std::cout << "The negotiated protocol: " << proto << std::endl;
}
@@ -921,16 +924,17 @@ int Http2Handler::verify_alpn_result() {
return -1;
}
int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
time_t last_modified, off_t file_length,
int Http2Handler::submit_file_response(const std::string_view &status,
Stream *stream, time_t last_modified,
off_t file_length,
const std::string *content_type,
nghttp2_data_provider2 *data_prd) {
std::string last_modified_str;
auto nva = std::to_array({
http2::make_field(":status"_sr, status),
http2::make_field("server"_sr, NGHTTPD_SERVER),
http2::make_field("cache-control"_sr, "max-age=3600"_sr),
http2::make_field_v("date"_sr, sessions_->get_cached_date()),
http2::make_field(":status"sv, status),
http2::make_field("server"sv, NGHTTPD_SERVER),
http2::make_field("cache-control"sv, "max-age=3600"sv),
http2::make_field_v("date"sv, sessions_->get_cached_date()),
{},
{},
{},
@@ -939,37 +943,38 @@ int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
size_t nvlen = 4;
if (!get_config()->no_content_length) {
nva[nvlen++] = http2::make_field(
"content-length"_sr,
util::make_string_ref_uint(stream->balloc, file_length));
"content-length"sv,
util::make_string_ref_uint(stream->balloc, as_unsigned(file_length)));
}
if (last_modified != 0) {
last_modified_str = util::http_date(last_modified);
nva[nvlen++] = http2::make_field_v("last-modified"_sr, last_modified_str);
last_modified_str = util::format_http_date(
std::chrono::system_clock::from_time_t(last_modified));
nva[nvlen++] = http2::make_field_v("last-modified"sv, last_modified_str);
}
if (content_type) {
nva[nvlen++] = http2::make_field_v("content-type"_sr, *content_type);
nva[nvlen++] = http2::make_field_v("content-type"sv, *content_type);
}
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_field("trailer"_sr, trailer_names);
nva[nvlen++] = http2::make_field("trailer"sv, trailer_names);
}
return nghttp2_submit_response2(session_, stream->stream_id, nva.data(),
nvlen, data_prd);
}
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
const HeaderRefs &headers,
int Http2Handler::submit_response(const std::string_view &status,
int32_t stream_id, const HeaderRefs &headers,
nghttp2_data_provider2 *data_prd) {
auto nva = std::vector<nghttp2_nv>();
nva.reserve(4 + headers.size());
nva.push_back(http2::make_field(":status"_sr, status));
nva.push_back(http2::make_field("server"_sr, NGHTTPD_SERVER));
nva.push_back(http2::make_field_v("date"_sr, sessions_->get_cached_date()));
nva.push_back(http2::make_field(":status"sv, status));
nva.push_back(http2::make_field("server"sv, NGHTTPD_SERVER));
nva.push_back(http2::make_field_v("date"sv, sessions_->get_cached_date()));
if (data_prd) {
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva.push_back(http2::make_field("trailer"_sr, trailer_names));
nva.push_back(http2::make_field("trailer"sv, trailer_names));
}
}
@@ -982,12 +987,13 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
return r;
}
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
int Http2Handler::submit_response(const std::string_view &status,
int32_t stream_id,
nghttp2_data_provider2 *data_prd) {
auto nva = std::to_array({
http2::make_field(":status"_sr, status),
http2::make_field("server"_sr, NGHTTPD_SERVER),
http2::make_field_v("date"_sr, sessions_->get_cached_date()),
http2::make_field(":status"sv, status),
http2::make_field("server"sv, NGHTTPD_SERVER),
http2::make_field_v("date"sv, sessions_->get_cached_date()),
{},
});
size_t nvlen = 3;
@@ -995,7 +1001,7 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
if (data_prd) {
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_field("trailer"_sr, trailer_names);
nva[nvlen++] = http2::make_field("trailer"sv, trailer_names);
}
}
@@ -1005,25 +1011,25 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
int Http2Handler::submit_non_final_response(const std::string &status,
int32_t stream_id) {
auto nva = std::to_array({http2::make_field_v(":status"_sr, status)});
auto nva = std::to_array({http2::make_field_v(":status"sv, status)});
return nghttp2_submit_headers(session_, NGHTTP2_FLAG_NONE, stream_id, nullptr,
nva.data(), nva.size(), nullptr);
}
int Http2Handler::submit_push_promise(Stream *stream,
const StringRef &push_path) {
const std::string_view &push_path) {
auto authority = stream->header.authority;
if (authority.empty()) {
authority = stream->header.host;
}
auto scheme = get_config()->no_tls ? "http"_sr : "https"_sr;
auto scheme = get_config()->no_tls ? "http"sv : "https"sv;
auto nva = std::to_array({http2::make_field(":method"_sr, "GET"_sr),
http2::make_field(":path"_sr, push_path),
http2::make_field(":scheme"_sr, scheme),
http2::make_field(":authority"_sr, authority)});
auto nva = std::to_array({http2::make_field(":method"sv, "GET"sv),
http2::make_field(":path"sv, push_path),
http2::make_field(":scheme"sv, scheme),
http2::make_field(":authority"sv, authority)});
auto promised_stream_id = nghttp2_submit_push_promise(
session_, NGHTTP2_FLAG_END_HEADERS, stream->stream_id, nva.data(),
@@ -1036,7 +1042,7 @@ int Http2Handler::submit_push_promise(Stream *stream,
auto promised_stream = std::make_unique<Stream>(this, promised_stream_id);
auto &promised_header = promised_stream->header;
promised_header.method = "GET"_sr;
promised_header.method = "GET"sv;
promised_header.path = push_path;
promised_header.scheme = scheme;
promised_header.authority =
@@ -1066,7 +1072,7 @@ void Http2Handler::remove_stream(int32_t stream_id) {
Stream *Http2Handler::get_stream(int32_t stream_id) {
auto itr = id2stream_.find(stream_id);
if (itr == std::end(id2stream_)) {
if (itr == std::ranges::end(id2stream_)) {
return nullptr;
} else {
return (*itr).second.get();
@@ -1148,12 +1154,12 @@ void prepare_status_response(Stream *stream, Http2Handler *hd, int status) {
HeaderRefs headers;
headers.reserve(2);
headers.emplace_back("content-type"_sr, "text/html; charset=UTF-8"_sr);
headers.emplace_back("content-type"sv, "text/html; charset=UTF-8"sv);
headers.emplace_back(
"content-length"_sr,
util::make_string_ref_uint(stream->balloc, file_ent->length));
hd->submit_response(StringRef{status_page->status}, stream->stream_id,
headers, &data_prd);
"content-length"sv,
util::make_string_ref_uint(stream->balloc, as_unsigned(file_ent->length)));
hd->submit_response(status_page->status, stream->stream_id, headers,
&data_prd);
}
} // namespace
@@ -1174,13 +1180,14 @@ void prepare_echo_response(Stream *stream, Http2Handler *hd) {
data_prd.read_callback = file_read_callback;
HeaderRefs headers;
headers.emplace_back("nghttpd-response"_sr, "echo"_sr);
headers.emplace_back("nghttpd-response"sv, "echo"sv);
if (!hd->get_config()->no_content_length) {
headers.emplace_back("content-length"_sr,
util::make_string_ref_uint(stream->balloc, length));
headers.emplace_back(
"content-length"sv,
util::make_string_ref_uint(stream->balloc, as_unsigned(length)));
}
hd->submit_response("200"_sr, stream->stream_id, headers, &data_prd);
hd->submit_response("200"sv, stream->stream_id, headers, &data_prd);
}
} // namespace
@@ -1206,7 +1213,7 @@ bool prepare_upload_temp_store(Stream *stream, Http2Handler *hd) {
namespace {
void prepare_redirect_response(Stream *stream, Http2Handler *hd,
const StringRef &path, int status) {
const std::string_view &path, int status) {
auto scheme = stream->header.scheme;
auto authority = stream->header.authority;
@@ -1215,15 +1222,14 @@ void prepare_redirect_response(Stream *stream, Http2Handler *hd,
}
auto location =
concat_string_ref(stream->balloc, scheme, "://"_sr, authority, path);
concat_string_ref(stream->balloc, scheme, "://"sv, authority, path);
auto headers = HeaderRefs{{"location"_sr, location}};
auto headers = HeaderRefs{{"location"sv, location}};
auto sessions = hd->get_sessions();
auto status_page = sessions->get_server()->get_status_page(status);
hd->submit_response(StringRef{status_page->status}, stream->stream_id,
headers, nullptr);
hd->submit_response(status_page->status, stream->stream_id, headers, nullptr);
}
} // namespace
@@ -1246,34 +1252,32 @@ void prepare_response(Stream *stream, Http2Handler *hd,
last_mod = util::parse_http_date(ims);
}
StringRef raw_path, raw_query;
auto query_pos = std::find(std::begin(reqpath), std::end(reqpath), '?');
if (query_pos != std::end(reqpath)) {
std::string_view raw_path, raw_query;
auto query_pos = std::ranges::find(reqpath, '?');
if (query_pos != std::ranges::end(reqpath)) {
// Do not response to this request to allow clients to test timeouts.
if ("nghttpd_do_not_respond_to_req=yes"_sr ==
StringRef{query_pos, std::end(reqpath)}) {
if ("nghttpd_do_not_respond_to_req=yes"sv ==
std::string_view{query_pos, std::ranges::end(reqpath)}) {
return;
}
raw_path = StringRef{std::begin(reqpath), query_pos};
raw_query = StringRef{query_pos, std::end(reqpath)};
raw_path = std::string_view{std::ranges::begin(reqpath), query_pos};
raw_query = std::string_view{query_pos, std::ranges::end(reqpath)};
} else {
raw_path = reqpath;
}
auto sessions = hd->get_sessions();
StringRef path;
if (std::find(std::begin(raw_path), std::end(raw_path), '%') ==
std::end(raw_path)) {
path = raw_path;
} else {
std::string_view path;
if (util::contains(raw_path, '%')) {
path = util::percent_decode(stream->balloc, raw_path);
} else {
path = raw_path;
}
path = http2::path_join(stream->balloc, StringRef{}, StringRef{}, path,
StringRef{});
path = http2::path_join(stream->balloc, ""sv, ""sv, path, ""sv);
if (std::find(std::begin(path), std::end(path), '\\') != std::end(path)) {
if (util::contains(path, '\\')) {
if (stream->file_ent) {
sessions->release_fd(stream->file_ent);
stream->file_ent = nullptr;
@@ -1284,9 +1288,9 @@ void prepare_response(Stream *stream, Http2Handler *hd,
if (!hd->get_config()->push.empty()) {
auto push_itr = hd->get_config()->push.find(std::string{path});
if (allow_push && push_itr != std::end(hd->get_config()->push)) {
if (allow_push && push_itr != std::ranges::end(hd->get_config()->push)) {
for (auto &push_path : (*push_itr).second) {
rv = hd->submit_push_promise(stream, StringRef{push_path});
rv = hd->submit_push_promise(stream, push_path);
if (rv != 0) {
std::cerr << "nghttp2_submit_push_promise() returned error: "
<< nghttp2_strerror(rv) << std::endl;
@@ -1309,10 +1313,10 @@ void prepare_response(Stream *stream, Http2Handler *hd,
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);
p = std::ranges::copy(htdocs, p).out;
p = std::ranges::copy(path, p).out;
if (trailing_slash) {
std::copy(std::begin(DEFAULT_HTML), std::end(DEFAULT_HTML), p);
std::ranges::copy(DEFAULT_HTML, p);
}
}
@@ -1345,7 +1349,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
close(file);
auto reqpath =
concat_string_ref(stream->balloc, raw_path, "/"_sr, raw_query);
concat_string_ref(stream->balloc, raw_path, "/"sv, raw_query);
prepare_redirect_response(stream, hd, reqpath, 301);
@@ -1362,7 +1366,7 @@ void prepare_response(Stream *stream, Http2Handler *hd,
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)) {
if (content_type_itr != std::ranges::end(mime_types)) {
content_type = &(*content_type_itr).second;
}
}
@@ -1375,15 +1379,15 @@ void prepare_response(Stream *stream, Http2Handler *hd,
stream->file_ent = file_ent;
if (last_mod_found && file_ent->mtime <= last_mod) {
hd->submit_response("304"_sr, stream->stream_id, nullptr);
hd->submit_response("304"sv, stream->stream_id, nullptr);
return;
}
auto method = stream->header.method;
if (method == "HEAD"_sr) {
hd->submit_file_response("200"_sr, stream, file_ent->mtime,
file_ent->length, file_ent->content_type, nullptr);
if (method == "HEAD"sv) {
hd->submit_file_response("200"sv, stream, file_ent->mtime, file_ent->length,
file_ent->content_type, nullptr);
return;
}
@@ -1394,7 +1398,7 @@ 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"_sr, stream, file_ent->mtime, file_ent->length,
hd->submit_file_response("200"sv, stream, file_ent->mtime, file_ent->length,
file_ent->content_type, &data_prd);
}
} // namespace
@@ -1429,43 +1433,43 @@ int on_header_callback2(nghttp2_session *session, const nghttp2_frame *frame,
stream->header_buffer_size += namebuf.len + valuebuf.len;
auto token = http2::lookup_token(StringRef{namebuf.base, namebuf.len});
auto token = http2::lookup_token(as_string_view(namebuf.base, namebuf.len));
auto &header = stream->header;
switch (token) {
case http2::HD__METHOD:
header.method = StringRef{valuebuf.base, valuebuf.len};
header.method = as_string_view(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.scheme = as_string_view(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.authority = as_string_view(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.host = as_string_view(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.path = as_string_view(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.ims = as_string_view(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.expect = as_string_view(valuebuf.base, valuebuf.len);
header.rcbuf.expect = value;
nghttp2_rcbuf_incref(value);
break;
@@ -1531,13 +1535,13 @@ int hd_on_frame_recv_callback(nghttp2_session *session,
if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
auto expect100 = stream->header.expect;
if (util::strieq("100-continue"_sr, expect100)) {
if (util::strieq("100-continue"sv, expect100)) {
hd->submit_non_final_response("100", frame->hd.stream_id);
}
auto method = stream->header.method;
if (hd->get_config()->echo_upload &&
(method == "POST"_sr || method == "PUT"_sr)) {
(method == "POST"sv || method == "PUT"sv)) {
if (!prepare_upload_temp_store(stream, hd)) {
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
return 0;
@@ -1649,10 +1653,10 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
auto p = wb->last;
p = std::copy_n(framehd, 9, p);
p = std::ranges::copy_n(framehd, 9, p).out;
if (padlen) {
*p++ = padlen - 1;
*p++ = static_cast<uint8_t>(padlen - 1);
}
while (length) {
@@ -1669,12 +1673,12 @@ int send_data_callback(nghttp2_session *session, nghttp2_frame *frame,
}
stream->body_offset += nread;
length -= nread;
length -= as_unsigned(nread);
p += nread;
}
if (padlen) {
std::fill(p, p + padlen - 1, 0);
std::ranges::fill(p, p + padlen - 1, 0);
p += padlen - 1;
}
@@ -1689,7 +1693,8 @@ nghttp2_ssize select_padding_callback(nghttp2_session *session,
const nghttp2_frame *frame,
size_t max_payload, void *user_data) {
auto hd = static_cast<Http2Handler *>(user_data);
return std::min(max_payload, frame->hd.length + hd->get_config()->padding);
return as_signed(
std::min(max_payload, frame->hd.length + hd->get_config()->padding));
}
} // namespace
@@ -1715,7 +1720,7 @@ int on_data_chunk_recv_callback(nghttp2_session *session, uint8_t flags,
hd->submit_rst_stream(stream, NGHTTP2_INTERNAL_ERROR);
return 0;
}
len -= n;
len -= as_unsigned(n);
data += n;
}
}
@@ -1777,6 +1782,8 @@ void fill_callback(nghttp2_session_callbacks *callbacks, const Config *config) {
nghttp2_session_callbacks_set_select_padding_callback2(
callbacks, select_padding_callback);
}
nghttp2_session_callbacks_set_rand_callback(callbacks, util::secure_random);
}
} // namespace
@@ -1817,12 +1824,12 @@ void run_worker(Worker *worker) {
#ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
wc_ecc_fp_free();
#endif // NGHTTP2_OPENSSL_IS_WOLFSSL
#endif // defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
}
} // namespace
namespace {
int get_ev_loop_flags() {
unsigned int get_ev_loop_flags() {
if (ev_supported_backends() & ~ev_recommended_backends() & EVBACKEND_KQUEUE) {
return ev_recommended_backends() | EVBACKEND_KQUEUE;
}
@@ -1902,15 +1909,15 @@ public:
for (;;) {
#ifdef HAVE_ACCEPT4
auto fd = accept4(fd_, nullptr, nullptr, SOCK_NONBLOCK);
#else // !HAVE_ACCEPT4
#else // !defined(HAVE_ACCEPT4)
auto fd = accept(fd_, nullptr, nullptr);
#endif // !HAVE_ACCEPT4
#endif // !defined(HAVE_ACCEPT4)
if (fd == -1) {
break;
}
#ifndef HAVE_ACCEPT4
util::make_socket_nonblocking(fd);
#endif // !HAVE_ACCEPT4
#endif // !defined(HAVE_ACCEPT4)
acceptor_->accept_connection(fd);
}
}
@@ -1930,7 +1937,7 @@ void acceptcb(struct ev_loop *loop, ev_io *w, int revents) {
} // namespace
namespace {
FileEntry make_status_body(int status, uint16_t port) {
FileEntry make_status_body(uint32_t status, uint16_t port) {
BlockAllocator balloc(1024, 1024);
auto status_string = http2::stringify_status(balloc, status);
@@ -2012,13 +2019,15 @@ int start_listen(HttpServer *sv, struct ev_loop *loop, Sessions *sessions,
std::shared_ptr<AcceptHandler> acceptor;
auto service = util::utos(config->port);
addrinfo hints{};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
addrinfo hints{
.ai_flags = AI_PASSIVE
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif // AI_ADDRCONFIG
| AI_ADDRCONFIG
#endif // defined(AI_ADDRCONFIG)
,
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
};
if (!config->address.empty()) {
addr = config->address.c_str();
@@ -2051,7 +2060,7 @@ int start_listen(HttpServer *sv, struct ev_loop *loop, Sessions *sessions,
continue;
}
}
#endif // IPV6_V6ONLY
#endif // defined(IPV6_V6ONLY)
if (bind(fd, rp->ai_addr, rp->ai_addrlen) == 0 && listen(fd, 1000) == 0) {
if (!acceptor) {
acceptor = std::make_shared<AcceptHandler>(sv, sessions, config);
@@ -2103,7 +2112,6 @@ int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
int HttpServer::run() {
SSL_CTX *ssl_ctx = nullptr;
std::vector<unsigned char> next_proto;
if (!config_->no_tls) {
ssl_ctx = SSL_CTX_new(TLS_server_method());
@@ -2112,17 +2120,17 @@ int HttpServer::run() {
return -1;
}
auto ssl_opts = (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) |
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_TICKET |
SSL_OP_CIPHER_SERVER_PREFERENCE;
auto ssl_opts = static_cast<nghttp2_ssl_op_type>(
(SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) | SSL_OP_NO_SSLv2 |
SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE |
SSL_OP_NO_TICKET | SSL_OP_CIPHER_SERVER_PREFERENCE);
#ifdef SSL_OP_ENABLE_KTLS
if (config_->ktls) {
ssl_opts |= SSL_OP_ENABLE_KTLS;
}
#endif // SSL_OP_ENABLE_KTLS
#endif // defined(SSL_OP_ENABLE_KTLS)
SSL_CTX_set_options(ssl_ctx, ssl_opts);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
@@ -2147,19 +2155,17 @@ int HttpServer::run() {
std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
return -1;
}
#endif // NGHTTP2_OPENSSL_IS_WOLFSSL
#endif // defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
const unsigned char sid_ctx[] = "nghttpd";
SSL_CTX_set_session_id_context(ssl_ctx, sid_ctx, sizeof(sid_ctx) - 1);
SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER);
#ifndef OPENSSL_NO_EC
if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
std::cerr << "SSL_CTX_set1_curves_list failed: "
if (SSL_CTX_set1_groups_list(ssl_ctx, config_->groups.data()) != 1) {
std::cerr << "SSL_CTX_set1_groups_list failed: "
<< ERR_error_string(ERR_get_error(), nullptr);
return -1;
}
#endif // OPENSSL_NO_EC
if (!config_->dh_param_file.empty()) {
// Read DH parameters from file
@@ -2223,8 +2229,6 @@ int HttpServer::run() {
verify_callback);
}
next_proto = util::get_default_alpn();
// ALPN selection callback
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, this);
@@ -2235,7 +2239,13 @@ int HttpServer::run() {
std::cerr << "SSL_CTX_add_cert_compression_alg failed." << std::endl;
return -1;
}
#endif // NGHTTP2_OPENSSL_IS_BORINGSSL && HAVE_LIBBROTLI
#endif // defined(NGHTTP2_OPENSSL_IS_BORINGSSL) &&
// defined(HAVE_LIBBROTLI)
if (tls::setup_keylog_callback(ssl_ctx) != 0) {
std::cerr << "Failed to setup keylog" << std::endl;
return -1;
}
}
auto loop = EV_DEFAULT;

View File

@@ -34,17 +34,18 @@
#include <string>
#include <vector>
#include <map>
#include <unordered_map>
#include <memory>
#include <string_view>
#include "ssl_compat.h"
#ifdef NGHTTP2_OPENSSL_IS_WOLFSSL
# include <wolfssl/options.h>
# include <wolfssl/openssl/ssl.h>
#else // !NGHTTP2_OPENSSL_IS_WOLFSSL
#else // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
# include <openssl/ssl.h>
#endif // !NGHTTP2_OPENSSL_IS_WOLFSSL
#endif // !defined(NGHTTP2_OPENSSL_IS_WOLFSSL)
#include <ev.h>
@@ -59,8 +60,8 @@
namespace nghttp2 {
struct Config {
std::map<std::string, std::vector<std::string>> push;
std::map<std::string, std::string> mime_types;
std::unordered_map<std::string, std::vector<std::string>> push;
std::unordered_map<std::string, std::string> mime_types;
Headers trailer;
std::string trailer_names;
std::string htdocs;
@@ -70,6 +71,7 @@ struct Config {
std::string dh_param_file;
std::string address;
std::string mime_types_file;
std::string_view groups;
ev_tstamp stream_read_timeout;
ev_tstamp stream_write_timeout;
void *data_ptr;
@@ -107,31 +109,29 @@ struct FileEntry {
mtime(mtime),
last_valid(last_valid),
content_type(content_type),
dlnext(nullptr),
dlprev(nullptr),
fd(fd),
usecount(1),
stale(stale) {}
std::string path;
std::multimap<std::string, std::unique_ptr<FileEntry>>::iterator it;
std::unordered_multimap<std::string, std::unique_ptr<FileEntry>>::iterator it;
int64_t length;
int64_t mtime;
std::chrono::steady_clock::time_point last_valid;
const std::string *content_type;
FileEntry *dlnext, *dlprev;
SListEntry<FileEntry> slent;
int fd;
int usecount;
bool stale;
};
struct RequestHeader {
StringRef method;
StringRef scheme;
StringRef authority;
StringRef host;
StringRef path;
StringRef ims;
StringRef expect;
std::string_view method;
std::string_view scheme;
std::string_view authority;
std::string_view host;
std::string_view path;
std::string_view ims;
std::string_view expect;
struct {
nghttp2_rcbuf *method;
@@ -176,21 +176,21 @@ public:
int connection_made();
int verify_alpn_result();
int submit_file_response(const StringRef &status, Stream *stream,
int submit_file_response(const std::string_view &status, Stream *stream,
time_t last_modified, off_t file_length,
const std::string *content_type,
nghttp2_data_provider2 *data_prd);
int submit_response(const StringRef &status, int32_t stream_id,
int submit_response(const std::string_view &status, int32_t stream_id,
nghttp2_data_provider2 *data_prd);
int submit_response(const StringRef &status, int32_t stream_id,
int submit_response(const std::string_view &status, int32_t stream_id,
const HeaderRefs &headers,
nghttp2_data_provider2 *data_prd);
int submit_non_final_response(const std::string &status, int32_t stream_id);
int submit_push_promise(Stream *stream, const StringRef &push_path);
int submit_push_promise(Stream *stream, const std::string_view &push_path);
int submit_rst_stream(Stream *stream, uint32_t error_code);
@@ -221,7 +221,7 @@ private:
ev_io wev_;
ev_io rev_;
ev_timer settings_timerev_;
std::map<int32_t, std::unique_ptr<Stream>> id2stream_;
std::unordered_map<int32_t, std::unique_ptr<Stream>> id2stream_;
WriteBuf wb_;
std::function<int(Http2Handler &)> read_, write_;
int64_t session_id_;
@@ -258,4 +258,4 @@ nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
} // namespace nghttp2
#endif // HTTP_SERVER_H
#endif // !defined(HTTP_SERVER_H)

View File

@@ -47,7 +47,9 @@ AM_CPPFLAGS = \
@LIBNGHTTP3_CFLAGS@ \
@LIBNGTCP2_CRYPTO_WOLFSSL_CFLAGS@ \
@LIBNGTCP2_CRYPTO_QUICTLS_CFLAGS@ \
@LIBNGTCP2_CRYPTO_LIBRESSL_CFLAGS@ \
@LIBNGTCP2_CRYPTO_BORINGSSL_CFLAGS@ \
@LIBNGTCP2_CRYPTO_OSSL_CFLAGS@ \
@LIBNGTCP2_CFLAGS@ \
@WOLFSSL_CFLAGS@ \
@OPENSSL_CFLAGS@ \
@@ -70,7 +72,9 @@ LDADD = $(top_builddir)/lib/libnghttp2.la \
@LIBNGHTTP3_LIBS@ \
@LIBNGTCP2_CRYPTO_WOLFSSL_LIBS@ \
@LIBNGTCP2_CRYPTO_QUICTLS_LIBS@ \
@LIBNGTCP2_CRYPTO_LIBRESSL_LIBS@ \
@LIBNGTCP2_CRYPTO_BORINGSSL_LIBS@ \
@LIBNGTCP2_CRYPTO_OSSL_LIBS@ \
@LIBNGTCP2_LIBS@ \
@WOLFSSL_LIBS@ \
@OPENSSL_LIBS@ \
@@ -121,8 +125,7 @@ h2load_SOURCES = util.cc util.h \
if ENABLE_HTTP3
h2load_SOURCES += \
h2load_http3_session.cc h2load_http3_session.h \
h2load_quic.cc h2load_quic.h \
quic.cc quic.h
h2load_quic.cc h2load_quic.h
endif # ENABLE_HTTP3
NGHTTPX_SRCS = \
@@ -166,7 +169,6 @@ NGHTTPX_SRCS = \
shrpx_health_monitor_downstream_connection.cc \
shrpx_health_monitor_downstream_connection.h \
shrpx_null_downstream_connection.cc shrpx_null_downstream_connection.h \
shrpx_exec.cc shrpx_exec.h \
shrpx_dns_resolver.cc shrpx_dns_resolver.h \
shrpx_dual_dns_resolver.cc shrpx_dual_dns_resolver.h \
shrpx_dns_tracker.cc shrpx_dns_tracker.h \
@@ -189,7 +191,6 @@ NGHTTPX_SRCS += \
shrpx_quic_connection_handler.cc shrpx_quic_connection_handler.h \
shrpx_http3_upstream.cc shrpx_http3_upstream.h \
http3.cc http3.h \
quic.cc quic.h \
siphash.cc siphash.h
endif # ENABLE_HTTP3
@@ -261,7 +262,8 @@ bin_PROGRAMS += inflatehd deflatehd
HPACK_TOOLS_COMMON_SRCS = \
comp_helper.c comp_helper.h \
util.cc util.h \
timegm.c timegm.h
timegm.c timegm.h \
tls.cc tls.h
inflatehd_SOURCES = inflatehd.cc $(HPACK_TOOLS_COMMON_SRCS)

View File

@@ -29,11 +29,12 @@
#ifndef _WIN32
# include <sys/uio.h>
#endif // !_WIN32
#endif // !defined(_WIN32)
#include <cassert>
#include <utility>
#include <span>
#include <algorithm>
#include "template.h"
@@ -179,7 +180,7 @@ struct BlockAllocator {
auto nalloclen = std::max(size + 1, alloclen * 2);
auto res = alloc(nalloclen);
std::copy_n(p, alloclen, static_cast<uint8_t *>(res));
std::ranges::copy_n(p, as_signed(alloclen), static_cast<uint8_t *>(res));
return res;
}
@@ -195,29 +196,37 @@ struct BlockAllocator {
size_t isolation_threshold;
};
// Makes a copy of |src|. The resulting string will be
// NULL-terminated.
template <typename BlockAllocator>
StringRef make_string_ref(BlockAllocator &alloc, const StringRef &src) {
auto dst = static_cast<uint8_t *>(alloc.alloc(src.size() + 1));
auto p = dst;
p = std::copy(std::begin(src), std::end(src), p);
// Makes a copy of a range [|first|, |last|). The resulting string
// will be NULL-terminated.
template <std::input_iterator I>
std::string_view make_string_ref(BlockAllocator &alloc, I first, I last) {
auto dst = static_cast<char *>(
alloc.alloc(static_cast<size_t>(std::ranges::distance(first, last) + 1)));
auto p = std::ranges::copy(first, last, dst).out;
*p = '\0';
return StringRef{dst, src.size()};
return std::string_view{dst, p};
}
// Makes a copy of |r| as std::string_view. The resulting string will be
// NULL-terminated.
template <std::ranges::input_range R>
requires(!std::is_array_v<std::remove_cvref_t<R>>)
std::string_view make_string_ref(BlockAllocator &alloc, R &&r) {
return make_string_ref(alloc, std::ranges::begin(r), std::ranges::end(r));
}
// private function used in concat_string_ref. this is the base
// function of concat_string_ref_count().
inline constexpr size_t concat_string_ref_count(size_t acc) { return acc; }
constexpr size_t concat_string_ref_count(size_t acc) { return acc; }
// private function used in concat_string_ref. This function counts
// the sum of length of given arguments. The calculated length is
// accumulated, and passed to the next function.
template <typename... Args>
constexpr size_t concat_string_ref_count(size_t acc, const StringRef &value,
Args &&...args) {
return concat_string_ref_count(acc + value.size(),
std::forward<Args>(args)...);
template <std::ranges::input_range R, std::ranges::input_range... Args>
requires(!std::is_array_v<std::remove_cvref_t<R>>)
constexpr size_t concat_string_ref_count(size_t acc, R &&r, Args &&...args) {
return concat_string_ref_count(acc + std::ranges::size(r), args...);
}
// private function used in concat_string_ref. this is the base
@@ -228,23 +237,23 @@ inline uint8_t *concat_string_ref_copy(uint8_t *p) { return p; }
// given strings into |p|. |p| is incremented by the copied length,
// and returned. In the end, return value points to the location one
// beyond the last byte written.
template <typename... Args>
uint8_t *concat_string_ref_copy(uint8_t *p, const StringRef &value,
Args &&...args) {
p = std::copy(std::begin(value), std::end(value), p);
return concat_string_ref_copy(p, std::forward<Args>(args)...);
template <std::ranges::input_range R, std::ranges::input_range... Args>
requires(!std::is_array_v<std::remove_cvref_t<R>>)
uint8_t *concat_string_ref_copy(uint8_t *p, R &&r, Args &&...args) {
return concat_string_ref_copy(std::ranges::copy(std::forward<R>(r), p).out,
std::forward<Args>(args)...);
}
// Returns the string which is the concatenation of |args| in the
// given order. The resulting string will be NULL-terminated.
template <typename BlockAllocator, typename... Args>
StringRef concat_string_ref(BlockAllocator &alloc, Args &&...args) {
size_t len = concat_string_ref_count(0, std::forward<Args>(args)...);
template <std::ranges::input_range... Args>
std::string_view concat_string_ref(BlockAllocator &alloc, Args &&...args) {
auto len = concat_string_ref_count(0, args...);
auto dst = static_cast<uint8_t *>(alloc.alloc(len + 1));
auto p = dst;
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
*p = '\0';
return StringRef{dst, len};
return as_string_view(dst, p);
}
// Returns the string which is the concatenation of |value| and |args|
@@ -253,30 +262,30 @@ StringRef concat_string_ref(BlockAllocator &alloc, Args &&...args) {
// obtained from alloc.alloc() or alloc.realloc(), and attempts to use
// unused memory region by using alloc.realloc(). If value is empty,
// then just call concat_string_ref().
template <typename BlockAllocator, typename... Args>
StringRef realloc_concat_string_ref(BlockAllocator &alloc,
const StringRef &value, Args &&...args) {
template <std::ranges::input_range... Args>
std::string_view realloc_concat_string_ref(BlockAllocator &alloc,
const std::string_view &value,
Args &&...args) {
if (value.empty()) {
return concat_string_ref(alloc, std::forward<Args>(args)...);
}
auto len =
value.size() + concat_string_ref_count(0, std::forward<Args>(args)...);
auto dst = static_cast<uint8_t *>(
alloc.realloc(const_cast<uint8_t *>(value.byte()), len + 1));
auto len = value.size() + concat_string_ref_count(0, args...);
auto dst = static_cast<uint8_t *>(alloc.realloc(
const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(value.data())),
len + 1));
auto p = dst + value.size();
p = concat_string_ref_copy(p, std::forward<Args>(args)...);
*p = '\0';
return StringRef{dst, len};
return as_string_view(dst, p);
}
// Makes an uninitialized buffer with given size.
template <typename BlockAllocator>
std::span<uint8_t> make_byte_ref(BlockAllocator &alloc, size_t size) {
inline std::span<uint8_t> make_byte_ref(BlockAllocator &alloc, size_t size) {
return {static_cast<uint8_t *>(alloc.alloc(size)), size};
}
} // namespace nghttp2
#endif // ALLOCATOR_H
#endif // !defined(ALLOCATOR_H)

View File

@@ -25,19 +25,19 @@
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif // HAVE_SYS_SOCKET_H
#endif // defined(HAVE_SYS_SOCKET_H)
#ifdef HAVE_NETDB_H
# include <netdb.h>
#endif // HAVE_NETDB_H
#endif // defined(HAVE_NETDB_H)
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif // HAVE_UNISTD_H
#endif // defined(HAVE_UNISTD_H)
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif // HAVE_FCNTL_H
#endif // defined(HAVE_FCNTL_H)
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif // HAVE_NETINET_IN_H
#endif // defined(HAVE_NETINET_IN_H)
#include <netinet/tcp.h>
#include <poll.h>
@@ -49,7 +49,6 @@
#include <string>
#include <iostream>
#include <string>
#include <set>
#include <iomanip>
#include <fstream>
@@ -329,7 +328,7 @@ void print_frame(print_type ptype, const nghttp2_frame *frame) {
case NGHTTP2_PING:
print_frame_attr_indent();
fprintf(outfile, "(opaque_data=%s)\n",
util::format_hex(frame->ping.opaque_data).c_str());
util::format_hex(std::span{frame->ping.opaque_data}).c_str());
break;
case NGHTTP2_GOAWAY:
print_frame_attr_indent();

View File

@@ -31,10 +31,9 @@
#include <cstdlib>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif // HAVE_SYS_TIME_H
#endif // defined(HAVE_SYS_TIME_H)
#include <poll.h>
#include <map>
#include <chrono>
#include <nghttp2/nghttp2.h>
@@ -92,4 +91,4 @@ void set_output(FILE *file);
} // namespace nghttp2
#endif // APP_HELPER_H
#endif // !defined(APP_HELPER_H)

View File

@@ -36,152 +36,140 @@ namespace nghttp2 {
namespace base64 {
namespace {
constexpr char B64_CHARS[] = {
inline constexpr char B64_CHARS[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
};
} // namespace
template <typename InputIt> std::string encode(InputIt first, InputIt last) {
std::string res;
size_t len = last - first;
if (len == 0) {
return res;
}
size_t r = len % 3;
res.resize((len + 2) / 3 * 4);
auto j = last - r;
auto p = std::begin(res);
while (first != j) {
uint32_t n = static_cast<uint8_t>(*first++) << 16;
n += static_cast<uint8_t>(*first++) << 8;
n += static_cast<uint8_t>(*first++);
*p++ = B64_CHARS[n >> 18];
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
*p++ = B64_CHARS[n & 0x3fu];
}
if (r == 2) {
uint32_t n = static_cast<uint8_t>(*first++) << 16;
n += static_cast<uint8_t>(*first++) << 8;
*p++ = B64_CHARS[n >> 18];
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
*p++ = '=';
} else if (r == 1) {
uint32_t n = static_cast<uint8_t>(*first++) << 16;
*p++ = B64_CHARS[n >> 18];
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
*p++ = '=';
*p++ = '=';
}
return res;
}
constexpr size_t encode_length(size_t n) { return (n + 2) / 3 * 4; }
template <typename InputIt, typename OutputIt>
OutputIt encode(InputIt first, InputIt last, OutputIt d_first) {
size_t len = last - first;
template <std::input_iterator I, std::weakly_incrementable O>
requires(std::indirectly_writable<O, char>)
constexpr O encode(I first, I last, O result) {
using result_type = std::iter_value_t<O>;
auto len = std::ranges::distance(first, last);
if (len == 0) {
return d_first;
}
auto r = len % 3;
auto j = last - r;
auto p = d_first;
while (first != j) {
uint32_t n = static_cast<uint8_t>(*first++) << 16;
n += static_cast<uint8_t>(*first++) << 8;
n += static_cast<uint8_t>(*first++);
*p++ = B64_CHARS[n >> 18];
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
*p++ = B64_CHARS[n & 0x3fu];
return result;
}
switch (r) {
auto p = result;
for (;;) {
len = std::ranges::distance(first, last);
if (len < 3) {
break;
}
auto n = static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 16);
n += static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 8);
n += static_cast<uint8_t>(*first++);
*p++ = static_cast<result_type>(B64_CHARS[n >> 18]);
*p++ = static_cast<result_type>(B64_CHARS[(n >> 12) & 0x3fu]);
*p++ = static_cast<result_type>(B64_CHARS[(n >> 6) & 0x3fu]);
*p++ = static_cast<result_type>(B64_CHARS[n & 0x3fu]);
}
switch (len) {
case 2: {
uint32_t n = static_cast<uint8_t>(*first++) << 16;
n += static_cast<uint8_t>(*first++) << 8;
*p++ = B64_CHARS[n >> 18];
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
*p++ = B64_CHARS[(n >> 6) & 0x3fu];
auto n = static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 16);
n += static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 8);
*p++ = static_cast<result_type>(B64_CHARS[n >> 18]);
*p++ = static_cast<result_type>(B64_CHARS[(n >> 12) & 0x3fu]);
*p++ = static_cast<result_type>(B64_CHARS[(n >> 6) & 0x3fu]);
*p++ = '=';
break;
}
case 1: {
uint32_t n = static_cast<uint8_t>(*first++) << 16;
*p++ = B64_CHARS[n >> 18];
*p++ = B64_CHARS[(n >> 12) & 0x3fu];
auto n = static_cast<uint32_t>(static_cast<uint8_t>(*first++) << 16);
*p++ = static_cast<result_type>(B64_CHARS[n >> 18]);
*p++ = static_cast<result_type>(B64_CHARS[(n >> 12) & 0x3fu]);
*p++ = '=';
*p++ = '=';
break;
}
}
return p;
}
template <typename InputIt>
InputIt next_decode_input(InputIt first, InputIt last, const int *tbl) {
for (; first != last; ++first) {
if (tbl[static_cast<size_t>(*first)] != -1 || *first == '=') {
break;
}
}
return first;
template <std::ranges::input_range R, std::weakly_incrementable O>
requires(std::indirectly_writable<O, char> &&
!std::is_array_v<std::remove_cvref_t<R>>)
constexpr O encode(R &&r, O result) {
return encode(std::ranges::begin(r), std::ranges::end(r), std::move(result));
}
template <typename InputIt, typename OutputIt>
OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
static constexpr int INDEX_TABLE[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1,
-1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1};
assert(std::distance(first, last) % 4 == 0);
auto p = d_first;
template <std::ranges::input_range R>
requires(!std::is_array_v<std::remove_cvref_t<R>>)
constexpr std::string encode(R &&r) {
std::string res;
auto len = std::ranges::size(r);
if (len == 0) {
return res;
}
res.resize((len + 2) / 3 * 4);
encode(std::forward<R>(r), std::ranges::begin(res));
return res;
}
inline constexpr int B64_INDEX_TABLE[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1,
-1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1};
template <std::input_iterator I, std::weakly_incrementable O>
requires(std::indirectly_writable<O, uint8_t>)
constexpr O decode(I first, I last, O result) {
using result_type = std::iter_value_t<O>;
assert(std::ranges::distance(first, last) % 4 == 0);
auto p = result;
for (; first != last;) {
uint32_t n = 0;
for (int i = 1; i <= 4; ++i, ++first) {
auto idx = INDEX_TABLE[static_cast<size_t>(*first)];
auto idx = B64_INDEX_TABLE[static_cast<size_t>(*first)];
if (idx == -1) {
if (i <= 2) {
return d_first;
return result;
}
if (i == 3) {
if (*first == '=' && *(first + 1) == '=' && first + 2 == last) {
*p++ = n >> 16;
if (*first == '=' && *std::ranges::next(first, 1) == '=' &&
std::ranges::next(first, 2) == last) {
*p++ = static_cast<result_type>(n >> 16);
return p;
}
return d_first;
return result;
}
if (*first == '=' && first + 1 == last) {
*p++ = n >> 16;
if (*first == '=' && std::ranges::next(first, 1) == last) {
*p++ = static_cast<result_type>(n >> 16);
*p++ = n >> 8 & 0xffu;
return p;
}
return d_first;
return result;
}
n += idx << (24 - i * 6);
n += static_cast<uint32_t>(idx) << (24 - i * 6);
}
*p++ = n >> 16;
*p++ = static_cast<result_type>(n >> 16);
*p++ = n >> 8 & 0xffu;
*p++ = n & 0xffu;
}
@@ -189,37 +177,24 @@ OutputIt decode(InputIt first, InputIt last, OutputIt d_first) {
return p;
}
template <typename InputIt> std::string decode(InputIt first, InputIt last) {
auto len = std::distance(first, last);
if (len % 4 != 0) {
return "";
}
std::string res;
res.resize(len / 4 * 3);
res.erase(decode(first, last, std::begin(res)), std::end(res));
return res;
}
template <typename InputIt>
std::span<const uint8_t> decode(BlockAllocator &balloc, InputIt first,
InputIt last) {
auto len = std::distance(first, last);
template <std::ranges::input_range R>
requires(!std::is_array_v<std::remove_cvref_t<R>>)
std::span<const uint8_t> decode(BlockAllocator &balloc, R &&r) {
auto len = std::ranges::size(r);
if (len % 4 != 0) {
return {};
}
auto iov = make_byte_ref(balloc, len / 4 * 3 + 1);
auto p = std::begin(iov);
auto p = std::ranges::begin(iov);
p = decode(first, last, p);
p = decode(std::ranges::begin(r), std::ranges::end(r), p);
*p = '\0';
return {std::begin(iov), p};
return {std::ranges::begin(iov), p};
}
} // namespace base64
} // namespace nghttp2
#endif // BASE64_H
#endif // !defined(BASE64_H)

View File

@@ -52,22 +52,22 @@ const MunitSuite base64_suite{
void test_base64_encode(void) {
{
std::string in = "\xff";
auto out = base64::encode(std::begin(in), std::end(in));
auto out = base64::encode(in);
assert_stdstring_equal("/w==", out);
}
{
std::string in = "\xff\xfe";
auto out = base64::encode(std::begin(in), std::end(in));
auto out = base64::encode(in);
assert_stdstring_equal("//4=", out);
}
{
std::string in = "\xff\xfe\xfd";
auto out = base64::encode(std::begin(in), std::end(in));
auto out = base64::encode(in);
assert_stdstring_equal("//79", out);
}
{
std::string in = "\xff\xfe\xfd\xfc";
auto out = base64::encode(std::begin(in), std::end(in));
auto out = base64::encode(in);
assert_stdstring_equal("//79/A==", out);
}
}
@@ -76,66 +76,43 @@ void test_base64_decode(void) {
BlockAllocator balloc(4096, 4096);
{
auto in = "/w=="sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal("\xff"sv, out);
assert_stdsv_equal("\xff"sv, StringRef{base64::decode(
balloc, std::begin(in), std::end(in))});
assert_stdsv_equal("\xff"sv, as_string_view(base64::decode(balloc, in)));
}
{
auto in = "//4="sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal("\xff\xfe"sv, out);
assert_stdsv_equal("\xff\xfe"sv, StringRef{base64::decode(
balloc, std::begin(in), std::end(in))});
assert_stdsv_equal("\xff\xfe"sv,
as_string_view(base64::decode(balloc, in)));
}
{
auto in = "//79"sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal("\xff\xfe\xfd"sv, out);
assert_stdsv_equal(
"\xff\xfe\xfd"sv,
StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
assert_stdsv_equal("\xff\xfe\xfd"sv,
as_string_view(base64::decode(balloc, in)));
}
{
auto in = "//79/A=="sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal("\xff\xfe\xfd\xfc"sv, out);
assert_stdsv_equal(
"\xff\xfe\xfd\xfc"sv,
StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
assert_stdsv_equal("\xff\xfe\xfd\xfc"sv,
as_string_view(base64::decode(balloc, in)));
}
{
// we check the number of valid input must be multiples of 4
auto in = "//79="sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal(""sv, out);
assert_stdsv_equal(
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
}
{
// ending invalid character at the boundary of multiples of 4 is
// bad
auto in = "bmdodHRw\n"sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal("", out);
assert_stdsv_equal(
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
}
{
// after seeing '=', subsequent input must be also '='.
auto in = "//79/A=A"sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal(""sv, out);
assert_stdsv_equal(
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
}
{
// additional '=' at the end is bad
auto in = "//79/A======"sv;
auto out = base64::decode(std::begin(in), std::end(in));
assert_stdsv_equal(""sv, out);
assert_stdsv_equal(
""sv, StringRef{base64::decode(balloc, std::begin(in), std::end(in))});
assert_stdsv_equal(""sv, as_string_view(base64::decode(balloc, in)));
}
}

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