664 Commits

Author SHA1 Message Date
Damien Neil
10ac4db832 http2: deflake TestServer_Rejects_Too_Many_Streams
This CL is the x/net counterpart to CL 755320.

This test contains a race condition in the server handler:

	inHandler <- streamID
	<-leaveHandler

We assume that all requests queue reading from leaveHandler in order,
but it is possible for the second request (stream id 3) to arrive at
leaveHandler before the first (stream id 1).

We could fix the race with a judicious synctest.Wait, but rewrite
the test to use serverHandlerCall to manipulate server handlers,
which permits us to precisely pick which request to unblock.

Fixes #69670

Change-Id: I9507d1dba07f7d62bcdc6c9bb67c47466a6a6964
Reviewed-on: https://go-review.googlesource.com/c/net/+/755081
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
2026-03-16 10:43:20 -07:00
Damien Neil
4a812844d8 http2: update docs to disrecommend this package
Every supported feature of the HTTP/2 client and server
is accessible via the net/http package. Recommend that
users use net/http rather than importing this package.

For #67810

Change-Id: I58b9c65af27e2f7172af493f96ee589a6a6a6964
Reviewed-on: https://go-review.googlesource.com/c/net/+/752160
Reviewed-by: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2026-03-09 08:35:37 -07:00
Damien Neil
8afa12f927 http2: deprecate write schedulers
The user-provided write scheduler mechanism provides too
much visibility into implementation internals, is difficult
to use, and limits our ability to improve performance.

Fixes golang/go#67817

Change-Id: Iac02c0902f805b671b4541a5dd7eafe76a6a6964
Reviewed-on: https://go-review.googlesource.com/c/net/+/751640
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2026-03-05 16:11:29 -08:00
Damien Neil
38019a2dbc http2: add missing copyright header to export_test.go
Change-Id: I7add2f2ef54ef6f985154a60399768e76a6a6964
Reviewed-on: https://go-review.googlesource.com/c/net/+/751620
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2026-03-04 14:19:29 -08:00
Damien Neil
8d297f1cac http2: Move most tests from the http2 package to the http2_test package.
This change makes it easier to move x/net/http2 into std.
Moving the http2 package into std and importing it from net/http
(rather than bundling it as net/http/h2_bundle.go) requires
removing the http2->net/http dependency. Moving tests into
the http2_test package allows them to continue importing net/http
without creating a cycle.

Change-Id: If0799a94a6d2c90f02d7f391e352e14e6a6a6964
Reviewed-on: https://go-review.googlesource.com/c/net/+/749280
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2026-03-03 17:16:54 -08:00
Nicholas S. Husin
3eb9327ec1 http2: do not retry RoundTrip after peer sends a stream protocol error
Years back, our HTTP/2 server implementation had a stream accounting bug
that would cause it to improperly report a PROTOCOL_ERROR. In response
to this, we modified our Transport to retry RoundTrip when a RST_STREAM
with PROTOCOL_ERROR was received from a peer.

At this point, this retry logic had outlived its usefulness. Instead, it
might cause issues, e.g. a client that sends a malformed request will
keep retrying repeatedly, despite there being zero chance for the
request to actually succeed.

Fixes golang/go#77843

Change-Id: Ic043723e3535f68f91db33d8f6bcd7fc2dbce856
Reviewed-on: https://go-review.googlesource.com/c/net/+/750720
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2026-03-02 15:02:12 -08:00
Konnyaku
19f580fd68 http2: fix nil panic in typeFrameParser for unassigned frame types
The addition of FramePriorityUpdate (0x10) in RFC 9218 introduced a gap
in the frameParsers array indices (0x0a-0x0f). These indices were
initialized to nil, causing a panic when typeFrameParser accessed them
for unassigned frame types (e.g., ALTSVC 0x0a).

This change adds a nil check in typeFrameParser to safely fallback to
parseUnknownFrame for these unassigned types, preventing the crash.

Fixes golang/go#77652

Change-Id: I14d7ad85afc1eafabc46417a9fff10f9e0a22446
Reviewed-on: https://go-review.googlesource.com/c/net/+/746180
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
2026-02-17 11:57:01 -08:00
Dmitri Shuralyov
29181b8c03 all: remove go1.25 and older build constraints
Now that the x/net module requires Go 1.25.0,
the go1.25 build constraint is always satisfied.
Simplify the code accordingly.

Change-Id: I3d6fe4a132a26918455489b998730b494f5273c4
Reviewed-on: https://go-review.googlesource.com/c/net/+/744800
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2026-02-12 07:53:52 -08:00
Nicholas S. Husin
4a490d4f53 internal/http3: add Expect: 100-continue support to ClientConn
When sending a request containing the "Expect: 100-continue" header,
ClientConn.RoundTrip will now only send the request body after receiving
an HTTP 100 status response from the server.

For golang/go#70914

Change-Id: Ib3acea68b078486bda96426952897c3f2d51b47b
Reviewed-on: https://go-review.googlesource.com/c/net/+/742540
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2026-02-06 16:20:02 -08:00
Nicholas S. Husin
64b3af9625 http2: prevent transport deadlock due to WINDOW_UPDATE that exceeds limit
Transport currently deadlocks when receiving a WINDOW_UPDATE for a
non-zero stream that increments its window beyond the 2^31-1 bytes
limit.

This is because endStreamError is called to end the non-zero stream,
which tries to lock an already-locked mutex. Therefore, create and use
endStreamErrorLocked instead, which assumes the mutex is already locked.

Fixes golang/go#77331

Change-Id: Iea212f49a1f305d1bddefb8831dbaca00840870c
Reviewed-on: https://go-review.googlesource.com/c/net/+/739700
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
2026-02-02 09:54:04 -08:00
Nicholas S. Husin
f2078620ee http2: allow prioritization to be disabled using DisableClientPriority field
As part of adding support for HTTP/2 stream prioritization, a
DisableClientPriority field will be added to http.Server to allow users
to completely disable client prioritization if desired. When
DisableClientPriority is set to true, HTTP/2 server will revert back to
the old behavior where streams are processed in a round-robin manner.

For golang/go#75500

Change-Id: Ida083b3ac17a953e5ddb3ad7ab8a81f9cde2bfc1
Reviewed-on: https://go-review.googlesource.com/c/net/+/737521
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2026-01-22 14:59:15 -08:00
Nicholas S. Husin
8f003b3712 http2: support SETTINGS_NO_RFC7540_PRIORITIES in SETTINGS frame
To make sure that clients do not unnecessarily send RFC 7540 priority
signals when it would be treated as a no-op, this change makes it so
that our server always sends SETTINGS_NO_RFC7540_PRIORITIES in our
SETTINGS frame when our write scheduler is set to anything other than
the RFC 7540 write scheduler.

For golang/go#75500

Change-Id: I7a54251022087319999deda7efb663f8b251aa95
Reviewed-on: https://go-review.googlesource.com/c/net/+/729141
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2026-01-14 12:33:57 -08:00
Nicholas S. Husin
8a4d9c198f http2: only make streams non-incremental if clients know of RFC 9218
In RFC 9218, streams are non-incremental by default, meaning that they
are processed one-by-one to completion. This behavior is the opposite of
our current default of handling streams in a round-robin manner.

This might cause a surprising behavior change once we make the RFC 9218
priority scheduler the default write scheduler for most users (we assume
that most users will not be sending RFC 9218 priority signals, at least
initially). To avoid surprising users with such a behavior change, this
CL makes it so that the streams are only made non-incremental once there
has been a clear signal that the end-user is aware of RFC 9218.

For golang/go#75500

Change-Id: Ibd22cb279c43de0190962904c3809007447a5fe3
Reviewed-on: https://go-review.googlesource.com/c/net/+/729140
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2026-01-14 12:33:43 -08:00
Nicholas S. Husin
a475fa8141 http2: add support for setting RFC 9218 priority via header field
RFC 9218 allows HTTP/2 stream priority to be set in two ways: via
PRIORITY_UPDATE frame and via header field. This change adds support for
the latter method.

As part of supporting priority adjustment via header field, this CL
also makes sure to look for the existence of an intermediary. If an
intermediary exists, default priority will be used for all streams to
ensure fairness between multiple clients who could be using the same
intermediary.

For golang/go#75500
For golang/go#75936

Change-Id: I6dc409b650fd52fa192d771a16b7a4ac5e51c9aa
Reviewed-on: https://go-review.googlesource.com/c/net/+/729120
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2026-01-14 12:33:32 -08:00
Nicholas S. Husin
f40205b5b5 http2: add initial support for PRIORITY_UPDATE frame defined in RFC 9218
This change adds initial support for the PRIORITY_UPDATE frame
introduced in RFC 9218.

Clients can now use a new exported function to write PRIORITY_UPDATE
frames easily. However, sending PRIORITY_UPDATE frames to the server
does not currently cause any behavior changes: we only use
PRIORITY_UPDATE frames to adjust stream priority when the RFC 9218 write
scheduler is being used for a particular connection. However, this
scheduler is not currently usable yet from any configuration surfaces
exposed to the user.

For golang/go#75500

Change-Id: Ie2c821cb0d2faa6e942e209e11638f190fc98e2b
Reviewed-on: https://go-review.googlesource.com/c/net/+/705917
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
2026-01-14 12:33:16 -08:00
Nicholas S. Husin
7d3dbb06ce http2: buffer the most recently received PRIORITY_UPDATE frame
Per RFC 9218, servers should buffer the most recently received
PRIORITY_UPDATE frame. This CL implements said buffering within the RFC
9218 priority write scheduler.

For golang/go#75500

Change-Id: I259f4f6787053de6388ec513086cfa1b294fa607
Reviewed-on: https://go-review.googlesource.com/c/net/+/728401
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2025-12-08 15:11:37 -08:00
Dmitri Shuralyov
7c360367ab http2, webdav, websocket: fix %q verb uses with wrong type
Caught early by the improved vet check gated behind the 1.26 language
version combined with a tiplang builder that tests with 1.26 language
version.

Fixes golang/go#76574.
Fixes golang/go#76599.
Fixes golang/go#76547.

Change-Id: If8e2266013df0a39fc980a1e9287f8cb75949811
Cq-Include-Trybots: luci.golang.try:x_net-gotip-linux-amd64-tiplang
Reviewed-on: https://go-review.googlesource.com/c/net/+/725220
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Commit-Queue: Alan Donovan <adonovan@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
2025-11-28 14:06:04 -08:00
Damien Neil
bff14c5256 http2: don't PING a responsive server when resetting a stream
When sending a RST_STREAM for a canceled request, we sometimes send
a PING frame along with the reset to confirm that the server is responsive
and has received the reset.

Sending too many PINGs trips denial-of-service detection on some servers,
causing them to close a connection with an ENHANCE_YOUR_CALM error.

Do not send a PING frame along with an RST_STREAM if the connection
has displayed signs of life since the canceled request began.
Specifically, if we've received any stream-related frames since the
request was sent, assume the server is responsive and do not send a PING.

We still send a PING if a request is canceled and no stream-related
frames have been received from the server since the request was first
sent.

For golang/go#76296

Change-Id: I1be3532febf9ac99d65e9cd35346c02306db5f9d
Reviewed-on: https://go-review.googlesource.com/c/net/+/720300
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-11-24 14:35:53 -08:00
Damien Neil
123d099e1b http2: support net/http.Transport.NewClientConn
Permit net/http to create new HTTP/2 client connections.

We do this by adding a NewClientConn method to the type the HTTP/2 client
registers with net/http.Transport.RegisterProtocol, which creates a
persistent connection from a net.Conn.

No tests in this CL. Tests will be in net/http, and will cover
both the HTTP/1 and HTTP/2 paths for NewClientConn.

For golang/go#75772

Change-Id: Ib1a06b4d13fdd6008e5db9a090c6e9632029a2a4
Reviewed-on: https://go-review.googlesource.com/c/net/+/722200
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-11-24 11:30:53 -08:00
Nicholas S. Husin
fff0469cf5 http2: document that RFC 7540 prioritization does not work with small payloads
This change demonstrates that golang/go#75936 applies to the RFC 7540
write scheduler.

A similar test will be added for RFC 9218 write scheduler after support
for it is incorporated within http2/server.go.

For golang/go#75936

Change-Id: I4e05dbeb0aab71942eb699b67383ef5b52c3ef4d
Reviewed-on: https://go-review.googlesource.com/c/net/+/714741
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
2025-10-24 15:04:41 -07:00
Nicholas S. Husin
f35e3a4dd2 http2: fix weight overflow in RFC 7540 write scheduler
We use uint8 (0-255, inclusive) to represent the RFC 7540 priorities
weight (1-256, inclusive). To account for the difference, we add 1 to
the uint8 weight value within sortPriorityNodeSiblingsRFC7540.

However, the addition was done before converting the uint8 type to
float. As a result, when provided a maximum weight value, overflow will
happen and will cause the scheduler to treat the maximum weight as a
minimum weight instead.

This CL fixes the issue by making sure the addition happens after the
type conversion.

Change-Id: I404e87e5ad85fa06d5fa49cda613c93ac8847bdc
Reviewed-on: https://go-review.googlesource.com/c/net/+/714742
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2025-10-24 15:04:30 -07:00
Nicholas S. Husin
89adc90ac4 http2: fix typo referring to RFC 9218 as RFC 9128 instead
In go.dev/cl/704758, I accidentally typed RFC 9128 rather than 9218.
This changes fixes all such typo.

For go/golang#75500

Change-Id: I61c3008a85ca0ca0e9f58315cb5eb20cd82fb9f9
Reviewed-on: https://go-review.googlesource.com/c/net/+/714740
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-10-24 15:04:23 -07:00
cuishuang
9be1ff2808 all: fix some comments
Change-Id: I4a06e68307ac3deb5b2e1bab9235ebe01dcd4ea6
Reviewed-on: https://go-review.googlesource.com/c/net/+/713380
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Sean Liao <sean@liao.dev>
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: David Chase <drchase@google.com>
2025-10-23 07:34:54 -07:00
Alexander Yastrebov
c296fafc21 net/http2: pool transport gzip readers
This is a copy of the CL 510255 with the difference that
it preserves use of fs.ErrClosed when reading after close.

goos: darwin
goarch: arm64
pkg: golang.org/x/net/http2
cpu: Apple M4
              │   HEAD~1    │             HEAD              │
              │   sec/op    │   sec/op     vs base          │
ClientGzip-10   752.8µ ± 1%   750.7µ ± 2%  ~ (p=0.393 n=10)

              │    HEAD~1    │                 HEAD                 │
              │     B/op     │     B/op      vs base                │
ClientGzip-10   75.49Ki ± 0%   33.98Ki ± 3%  -54.99% (p=0.000 n=10)

              │   HEAD~1   │               HEAD                │
              │ allocs/op  │ allocs/op   vs base               │
ClientGzip-10   705.0 ± 0%   698.5 ± 0%  -0.92% (p=0.000 n=10)

Updates golang/go#61353

Change-Id: I0fdc0c0a5947d27dcc615e5bcf4d4620c2c95d9e
GitHub-Last-Rev: 4d04dc93f3
GitHub-Pull-Request: golang/net#239
Reviewed-on: https://go-review.googlesource.com/c/net/+/710235
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-10-15 17:07:03 -07:00
Arjan Bal
63d1a5100f http2: Allow reading frame header and body separately
This change exports two new methods on the Framer, ReadFrameHeader and
ReadFrameBodyForHeader, which split the functionality of the existing
ReadFrame method.

This provides more granular control, allowing callers to inspect the
frame header before deciding whether or how to read the frame body.
This is useful for applications that may need to make decisions based on frame
type.

Fixes golang/go#73560

Change-Id: I60b42d2889095fac8e243022886740bc6dd94012
Reviewed-on: https://go-review.googlesource.com/c/net/+/710515
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-10-13 16:47:38 -07:00
Damien Neil
9f2f0b95b6 http2: avoid data race on DebugGoroutines in TestGoroutineLock
TestGoroutineLock sets DebugGoroutines = true.

When a previous test leaves a server running after exiting,
this write to DebugGoroutines can race with reads from the server.
Obviously tests shouldn't leave goroutines around after they exit,
but it happens and when it does it can show up here as a rare
and hard-to-debug flake.

DebugGoroutines is always true in tests, so there's no need to set
it here. Just leave it alone.

Fixes golang/go#75811

Change-Id: Iebeab2a22642cbd6867b9f4f5a171c91ea697b17
Reviewed-on: https://go-review.googlesource.com/c/net/+/710675
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-10-09 10:59:46 -07:00
Nicholas S. Husin
e7c005de60 http2: implement a more efficient writeQueue that avoids unnecessary copies.
Our previous implementation of writeQueue relies on one
[]FrameWriteRequests, forcing us to copy the rest of the slice's content
whenever we remove an item from the front.

This change remedies this problem by implementing writeQueue using
two-stage queues, similar to Okasaki's purely functional queue.

With 25 frames per stream, we are observing the following performance
improvement:
goos: linux
goarch: amd64
pkg: golang.org/x/net/http2
cpu: AMD EPYC 7B13
              │  /tmp/old   │              /tmp/new               │
              │   sec/op    │   sec/op     vs base                │
WriteQueue-64   508.3n ± 3%   305.7n ± 3%  -39.86% (p=0.000 n=10)

              │  /tmp/old  │            /tmp/new            │
              │    B/op    │    B/op     vs base            │
WriteQueue-64   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

              │  /tmp/old  │            /tmp/new            │
              │ allocs/op  │ allocs/op   vs base            │
WriteQueue-64   0.000 ± 0%   0.000 ± 0%  ~ (p=1.000 n=10) ¹
¹ all samples are equal

As the number of frames increases, the performance difference becomes
more stark as the old implementation does a quadratic amount of copying
in total to be able to fully consume a queue.

Change-Id: Ide816ebdd89a41275b5829683c0f10d48321af50
Reviewed-on: https://go-review.googlesource.com/c/net/+/710635
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2025-10-09 10:55:28 -07:00
cuishuang
b93acc2126 all: use reflect.TypeFor instead of reflect.TypeOf
For golang/go#60088.

Change-Id: Ifc6d5cf0b94b977b2699e4781875bf75b9aa25c8
Reviewed-on: https://go-review.googlesource.com/c/net/+/709195
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-10-08 13:54:30 -07:00
Nicholas S. Husin
539356380d http2: fix RFC 9218 write scheduler not being idempotent
Previously, the RFC 9218 write scheduler had a bug where AdjustStream()
did not update the stream's metadata after adjusting its priority. This
results in the function not being idempotent, where repeated calls to it
for the same stream can instead remove an unrelated stream from our
scheduler, and duplicate the stream whose priority is being updated.

For go/golang#75500

Change-Id: Iaf3dd819d02839bc6cff65027c4916f9f2fa3e5b
Reviewed-on: https://go-review.googlesource.com/c/net/+/709477
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
2025-10-07 09:12:30 -07:00
Damien Neil
47a241fc51 http2: make the error channel pool per-Server
Channels can't be shared across synctest bubbles, so a global pool causes
panics when using an http2.Server in a bubble. Make the pool per-Server.
A Server can't be shared across bubbles anyway (it contains channels)
and outside of tests most programs will have a single Server.

Fixes golang/go#75674

Change-Id: I966f985e1b9644bdf8ae81d9abb142d80320cc82
Reviewed-on: https://go-review.googlesource.com/c/net/+/708135
Auto-Submit: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-10-01 09:50:47 -07:00
Damien Neil
fe9bcbcc92 http2: support HTTP2Config.StrictMaxConcurrentRequests
When HTTP2Config.StrictMaxConcurrentRequests is set
(added in Go 1.26), use it to override the value of
Transport.StrictMaxConcurrentStreams.

Permits configuring this parameter from net/http
without importing x/net/http2.

For golang/go#67813

Change-Id: Ie7fa5a8ac033b1827cf7fef4e23b5110a05dc95f
Reviewed-on: https://go-review.googlesource.com/c/net/+/707315
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-09-29 09:34:56 -07:00
Nicholas S. Husin
10342476f5 http2: introduce a new write scheduler based on RFC 9218 priority scheme
This change introduces a new write scheduler that prioritizes writes
based on RFC 9218. Eventually, this scheduler will be used to replace
the existing priority scheduler based on RFC 7540, which has been
deprecated in RFC 9113.

No behavioral changes has been introduced as this scheduler is not used
anywhere yet.

goos: linux
goarch: amd64
pkg: golang.org/x/net/http2
cpu: AMD EPYC 7B13
BenchmarkWriteSchedulerThroughputRoundRobin-64                            100000            140884 ns/op          139201 B/op       2900 allocs/op
BenchmarkWriteSchedulerLifetimeRoundRobin-64                              100000            149632 ns/op          139202 B/op       2900 allocs/op
BenchmarkWriteSchedulerThroughputRandom-64                                100000            218311 ns/op          139201 B/op       2900 allocs/op
BenchmarkWriteSchedulerLifetimeRandom-64                                  100000            216559 ns/op          139203 B/op       2900 allocs/op
BenchmarkWriteSchedulerThroughputPriorityRFC7540-64                       100000            587625 ns/op          139201 B/op       2900 allocs/op
BenchmarkWriteSchedulerThroughputPriorityRFC9218Incremental-64            100000            149563 ns/op          139200 B/op       2900 allocs/op
BenchmarkWriteSchedulerLifetimePriorityRFC9218Incremental-64              100000            163697 ns/op          139201 B/op       2900 allocs/op
BenchmarkWriteSchedulerThroughputPriorityRFC9218NonIncremental-64         100000            145364 ns/op          139201 B/op       2900 allocs/op
BenchmarkWriteSchedulerLifetimePriorityRFC9218NonIncremental-64           100000            159316 ns/op          139203 B/op       2900 allocs/op

For golang/go#75500

Change-Id: Id5db195f6f75970f9cc3c7b7a292df96a139de8b
Reviewed-on: https://go-review.googlesource.com/c/net/+/704758
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
2025-09-19 14:13:39 -07:00
Nicholas S. Husin
653f4f665b http2: disambiguate the existing priority WriteScheduler.
This change renames the file for the RFC 7540 priority write scheduler
to writesched_priority_rfc7540.go file. Existing symbols have also been
renamed to make it explicit that they are only used for the RFC 7540
priority implementation.

This is done so that when we introduce the new RFC 9218 priority write
scheduler, we will not cause confusion with regards to which symbols are
used for which scheduler.

This CL only renames and moves symbols, no behavior changes have been
introduced.

For golang/go#75500

Change-Id: I5c31bd51bc0d25415ff72909cc0b8f9fef44c052
Reviewed-on: https://go-review.googlesource.com/c/net/+/704757
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-18 13:27:35 -07:00
cuishuang
875d966983 all: fix some comments
Including mismatched function names/struct names, repeated words, typos, etc.

Change-Id: Ia576274bce6e6fbfe4d2fca6dcd6d31bf00936fb
Reviewed-on: https://go-review.googlesource.com/c/net/+/683875
Auto-Submit: Sean Liao <sean@liao.dev>
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Sean Liao <sean@liao.dev>
2025-09-15 17:28:39 -07:00
Damien Neil
3b23d576ea http2: fix race condition when disabling goroutine debugging for one test
Fixes golang/go#66519

Change-Id: I7aecf20db44caaaf49754d62db193b8c42f3c63a
Reviewed-on: https://go-review.googlesource.com/c/net/+/701836
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2025-09-08 20:33:21 -07:00
Damien Neil
87410502ff http2: simplify TestServer_Push_RejectAfterGoAway
Replace bespoke test synchronization with a call to synctest.Wait.

Change-Id: Id082fbd3696b5b4a1839b2804ee61bb02e86a929
Reviewed-on: https://go-review.googlesource.com/c/net/+/701835
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-08 13:55:56 -07:00
Damien Neil
96e405cac1 http2: modernize TestTransportRoundtripCloseOnWriteError
Rewrite this test to use a testClientConn and fake network,
allowing us to inject its network error into the fake net
rather than by twiddling the client connection internals.

Change-Id: Idcd96498ceaee701ad0c053dc0c6ce74701cc182
Reviewed-on: https://go-review.googlesource.com/c/net/+/701006
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-08 13:55:53 -07:00
Damien Neil
6dc6880bcd http2: simplify ClientConn Close and Shutdown tests
Split testClientConnClose into four separate tests,
rather than having one big function which performs
different tests depending on its parameter.

Use the more modern testClientConn in these tests,
for simplicity.

Drop the activeStreams function, which pokes a bit too
far into implementation internals and isn't necessary
for the new tests. (It had one use outside of
testClientConnClose, which provides little useful
signal and can also be dropped.)

Change-Id: Id8d1c7feab59c1f041bc2d1cf0398e8b1e230c69
Reviewed-on: https://go-review.googlesource.com/c/net/+/701005
Reviewed-by: Nicholas Husin <nsh@golang.org>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-08 13:53:19 -07:00
Damien Neil
4e2915b652 http2: modernize TestTransportAllocationsAfterResponseBodyClose
This is a transport test. Use a testClientConn rather than a
Transport attached to a test server, for better control over
the frames sent to the test transport.

Drop one section of the test which pokes into the response
body's transportResponseBody type, as being too coupled to the
implementation internals.

Change-Id: I7bc7c7c756fd0c596424fab9a892dda8d9e89d1c
Reviewed-on: https://go-review.googlesource.com/c/net/+/701004
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-08 13:53:16 -07:00
Damien Neil
30b0e78859 http2: modernize TestRoundTripDoesntConsumeRequestBodyEarly
Use a testClientConn with its fake network connection
configured to encounter an error, rather than an http2.Client
with its internals tweaked into a closed state.

Change-Id: I0e9415ca3fdf50b9d6cdaccb24d7c4939b3b6ebd
Reviewed-on: https://go-review.googlesource.com/c/net/+/701003
Reviewed-by: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-09-08 13:42:40 -07:00
Damien Neil
b9acd777f1 http2: speed up TestTransportFlowControl
Rewrite the slowest test in the http2 package.

This test was added in CL 23812 to verify that a Transport does not
provide flow control window updates until the user consumes data
from a stream.

Rewrite the test to use the more modern testClientConn, which permits
precise examination of when the transport sends WINDOW_UPDATE frames.

Change-Id: Ibcde492549cad6363ce0e1a5ba169da7a4427d85
Reviewed-on: https://go-review.googlesource.com/c/net/+/700923
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-09-08 13:42:37 -07:00
Damien Neil
9338bdd9ee http2: speed up TestTransportHandlerBodyClose
Rewrite the slowest test in the http2 package.

This test was added in CL 23287 to verify two changes:
  - A server handler calling req.Body.Close does not
    kill the request stream.
  - A Transport does not leak a goroutine if a request body is
    still being written when the request stream is closed.

Split the test into two individual tests, one for the
server behavior and one for the transport.

Change-Id: I211f458e1001df435d00c2e1ebd7f3072e053c89
Reviewed-on: https://go-review.googlesource.com/c/net/+/700922
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-09-08 11:02:39 -07:00
Damien Neil
6b200364a6 http2: add synchronous handler support to serverTester
It is often useful in server tests to orchestrate a sequence
of actions that involve both a server connection and request handler.
For example, we might want to have the request handler read from
the request body at a precise point in the test.

Add support for this to serverTester (used for most server tests).
Pass a nil handler to serverTester, and it will provide synchronous
access to the handler:

    call := st.nextHandlerCall()
    call.do(func(w http.ResponseWriter, r *http.Request) {
        // this executes in the handler goroutine
    })

Replace the existing handlerPuppet type, which provided a
similar mechanism but only worked on a single call at a time.

Change-Id: I023e032084f911ab4f9b803c393e4a55b12af87f
Reviewed-on: https://go-review.googlesource.com/c/net/+/701002
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-09-08 09:35:58 -07:00
Damien Neil
b0013c645b http2: modernize TestTransportChecksRequestHeaderListSize
Rewrite this test to use testClientConn, which simplifies tests
of client-only functionality.

Change-Id: I9ff86ef1267323caf6e085fe140f6d4641740328
Reviewed-on: https://go-review.googlesource.com/c/net/+/700921
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
2025-09-08 07:15:58 -07:00
Damien Neil
162ad308ad http2: simplify TestServerWindowUpdateOnBodyClose
This test closes a handler's request mid-test by poking into
the server internals. There's no reason I can see to do this,
when the handler can just call req.Body.Close to achieve the
same effect.

Change the test to use the public API.

Change-Id: I4f14939e951c4d8f07abd9d3c2f30c2004f87dad
Reviewed-on: https://go-review.googlesource.com/c/net/+/701001
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Auto-Submit: Nicholas Husin <nsh@golang.org>
2025-09-08 07:14:56 -07:00
Damien Neil
22a8c02e92 http2: remove test-only path in requestBody.Read
requestBody.Read avoids panicking when requestBody.conn is unset
and we are in tests. This seems like an excellent way to hide a
non-test panic. Drop the exceptional path.

This path was introduced in golang.org/cl/31636 to support a
test verifying that concurrently closing and reading from a
Request.Body does not race. Rewrite this test to use a real
server handler.

Change-Id: I778e78ff9ab45e248769557fff94d17940eb7a18
Reviewed-on: https://go-review.googlesource.com/c/net/+/701000
Auto-Submit: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-09-08 07:14:52 -07:00
Damien Neil
1ff92d3eb0 http2: don't panic when ServeConn is passed a nil options
Fixes golang/go#75286

Change-Id: I91e6a0a61234c81f809b74151946dddde9099078
Reviewed-on: https://go-review.googlesource.com/c/net/+/700999
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
2025-09-05 13:18:06 -07:00
Damien Neil
a2a62f206b http2: use synctest.Wait rather than poking into server internals in test
Reduce test's dependence on unrelated internal implementation details.

Change-Id: Iaf38df44c1c8898cd8ab24587e410d45a48ef322
Reviewed-on: https://go-review.googlesource.com/c/net/+/700998
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
2025-09-05 13:18:03 -07:00
Damien Neil
7da929c666 http2: avoid examining ResponseWriter internals in test
TestServer_Rejects_Too_Many_Streams digs inside a ResponseWriter
to find the stream ID for a request. Just pass the stream ID as
part of the request path to reduce coupling between the test
and package internals.

Change-Id: I4276a6c4497aa0f311f9227e3a26717eeecf95cb
Reviewed-on: https://go-review.googlesource.com/c/net/+/700997
Reviewed-by: Nicholas Husin <nsh@golang.org>
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Nicholas Husin <nsh@golang.org>
2025-09-05 13:17:59 -07:00
Damien Neil
a99f4fee59 http2: remove unused stream-level flow control check
The test-only function serverTester.wantFlowControlConsumed
purports to check for the amount of connection or stream level
flow control consumed. Calling it with a streamID of 0
checks the connection-level flow control tokens.

However, the stream-level flow control path is unimplemented and unused.
Calling this function with a non-zero streamID doesn't work,
and (fortunately) all tests that use it only check connection-level
flow control.

Rename the function to wantConnFlowControlConsumed.

Change-Id: I1d934e8b46b4c43d393d102f1b2621329a7472aa
Reviewed-on: https://go-review.googlesource.com/c/net/+/700920
Auto-Submit: Nicholas Husin <nsh@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Nicholas Husin <husin@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-09-05 11:17:01 -07:00