664 Commits

Author SHA1 Message Date
Damien Neil
2378062003 http2: remove pre-go1.24 support
The x/net go.mod requires go1.24. Remove support for older versions
which don't include the Server.HTTP2 and Transport.HTTP2 config fields.

Change-Id: I6498aa89270a2c58635424ff3e763c806666010e
Reviewed-on: https://go-review.googlesource.com/c/net/+/700919
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:15:48 -07:00
Damien Neil
7c51e1fbce http2: use testing/synctest
Replace ad-hoc pre-synctest synchronization with testing/synctest.

Many of the http2 package tests use a custom-built fake time
implementation and a idleness-detection mechanism based on parsing
goroutine stack dumps. Experience with this approach to testing
eventually led to the development of the testing/synctest package.
Switch over to testing/synctest.

The synctest package became available as an experiment in Go 1.24
(only when GOEXPERIMENT=synctest is set), and was fully released
with some API changes in Go 1.25.

- Use the released synctest API on Go 1.25.

- Use the experimental API (synctest.Run) on Go 1.24 when
  GOEXPERIMENT=synctest is set. (Note that we set this on trybots.)

- Skip tests on Go 1.24 when GOEXPERIMENT=synctest is not set.

The x/net module requires go1.24, so older versions
can be disregarded.

Change-Id: Ifc13bfdd9bdada6c016730a78bd5972a5193ee30
Reviewed-on: https://go-review.googlesource.com/c/net/+/700996
Reviewed-by: Nicholas Husin <husin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Nicholas Husin <nsh@golang.org>
2025-09-05 11:08:28 -07:00
Alberto Donizetti
af6926ea18 http2: remove references to defunct http2.golang.org test server
The http2 demo server previously served at http2.golang.org has been
stopped (see golang/go#49301). This change removes a link to it from
the top-level package docs (which now just redirects to go.dev), and
switches the default hostname for the TransportExternal test to
go.dev.

It also delete an unused transport_test flag.

Updates golang/go#49301
Fixes golang/go#51540

Change-Id: I375250a8fec087124d42ed5f1086986e73e7bdfc
Reviewed-on: https://go-review.googlesource.com/c/net/+/693895
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
2025-08-07 11:37:49 -07:00
Chressie Himpel
15f7d40345 http2: correctly wrap ErrFrameTooLarge in Framer.ReadFrame
In Framer.ReadFrame's frame-too-large check, the code that checks for
HTTP/1.1 looking frames accidentally wrapped the unrelated err from the
previous readFrameHeader call instead of ErrFrameTooLarge. Fix that.

Change-Id: I2237759eaad8c6e06e7195c50410abb5792e57ea
Reviewed-on: https://go-review.googlesource.com/c/net/+/676218
Reviewed-by: Chressie Himpel <chressie@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-27 23:45:28 -07:00
Evan Jones
919c6bc7ad http2: use an array instead of a map in typeFrameParser
FrameType is a dense integer range, so we can store the frameParsers
in an array instead of a map. This should be a very small performance
win on all Go http2 servers. For high QPS gRPC services, this function
is visible in the Go profiler. For example, it shows up as 0.16% of
all CPU time on one production service at Datadog.

Change FrameType.String() to use the same pattern.

Add a test for testFrameType with unknown FrameTypes.

Fixes golang/go#73613

Change-Id: I5f5b523e011a99d6b428cbdbfd97415e488169d1
Reviewed-on: https://go-review.googlesource.com/c/net/+/670415
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-12 12:37:34 -07:00
Oleg Zaytsev
12150816f7 http2: improve error when server sends HTTP/1
If for some reason the server sends an HTTP/1.1 response
starting with "HTTP/1.1 " (9 bytes), http2 transport interprets that as
a valid frame header for an expected payload of ~4MB, and fails with
non-descriptive messages like "unexpected EOF".

This could happen, for example, if ALPN is misconfigured on the server's
load balancer.

This change attempts to improve that feedback by noting in the error
messages whenever the frame header was exactly the "HTTP/1.1 " bytes.

Change-Id: I7bf9ed2ee7f299b939b9004386f5bfa30a4e9032
GitHub-Last-Rev: d6e410daa3
GitHub-Pull-Request: golang/net#224
Reviewed-on: https://go-review.googlesource.com/c/net/+/623155
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Auto-Submit: Sean Liao <sean@liao.dev>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Sean Liao <sean@liao.dev>
2025-03-13 05:30:06 -07:00
Hubert Grochowski
09731f9bf9 http2: improve handling of lost PING in Server
This addresses inconsistencies in handling lost PINGs
between Server and Transport by:
1. Always logging a message for lost PINGs, regardless of verbose mode.
2. Invoking CountError with the conn_close_lost_ping error key.

Fixes golang/go#69963

Change-Id: I58fee489f7896dbb80ccc50265452cd953f7ca6b
GitHub-Last-Rev: ef74c9577a
GitHub-Pull-Request: golang/net#229
Reviewed-on: https://go-review.googlesource.com/c/net/+/635555
Auto-Submit: Sean Liao <sean@liao.dev>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: David Chase <drchase@google.com>
2025-03-10 14:07:55 -07:00
Sean Liao
55989e24b9 http2/h2c: use ResponseController for hijacking connections
Fixes golang/go#71999

Change-Id: I38b236e47bc5893c5a84ef33abbeab0828125bd2
Reviewed-on: https://go-review.googlesource.com/c/net/+/655615
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-03-08 12:58:08 -08:00
Damien Neil
aad0180cad http2: fix flakiness from t.Log when GOOS=js
The http2 package uses a precursor to the experimental
testing/synctest package, parsing runtime.Stack output
to determine when goroutines are idle.

When GOOS=js, some tests which use t.Log are flaky.
t.Log blocks in the syscall package writing to stdout.
The GOOS=js implementation of the syscall leaves the goroutine
blocked on a channel operation, which synctest interprets
as the goroutine being "durably blocked".

Fix the http2 synctest to treat any goroutine blocked in the
syscall package as not being durably blocked.

Making this fix reveals another bug when GOOS=js: Looping
while calling runtime.Gosched does not appear to permit
syscalls to make progress. Add a few time.Sleep(1) calls
while waiting for idleness to work around the problem.

While changing things in here, change http2's synctest
to not treat goroutines blocked on mutex operations as
durably blocked. This matches the behavior of testing/synctest.

(This would all be simpler if we just used testing/synctest,
but we don't want to make the http2 package depend on an
experimental API.)

Fixes golang/go#67693

Change-Id: I889834e97e4a33f4ef232278b1a78af00d52d261
Reviewed-on: https://go-review.googlesource.com/c/net/+/653696
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-02-28 11:43:04 -08:00
Damien Neil
b73e5746f6 http2: don't log expected errors from writing invalid trailers
Change-Id: I1c8af5a1f7539a25d5602a7bc8e15756d3cafa56
Reviewed-on: https://go-review.googlesource.com/c/net/+/653695
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-02-28 11:31:43 -08:00
Damien Neil
43c2540165 http2, internal/httpcommon: reject userinfo in :authority
RFC 9113, section 8.3.1: The :authority (host) in an HTTP
request must not include a userinfo (e.g., user@host).

Change-Id: I459a3da40b825c9662467778f582050c7358f8bb
Reviewed-on: https://go-review.googlesource.com/c/net/+/652456
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-02-26 14:12:30 -08:00
Damien Neil
1d78a08500 http2, internal/httpcommon: factor out server header logic for h2/h3
Move common elements of constructing a http.Request for
a server handler into internal/httpcommon.

For golang/go#70914

Change-Id: I5dcd902e189a0bb8daf47c0a815045d274346923
Reviewed-on: https://go-review.googlesource.com/c/net/+/652455
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-02-25 11:03:29 -08:00
Damien Neil
b4c86550a5 http2: avoid extended CONNECT hang when connection breaks during startup
Fixes golang/go#70658

Change-Id: Iaac5c7730a10afc8a8bb2e725746fa7387970582
Reviewed-on: https://go-review.googlesource.com/c/net/+/633277
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Antonio Ojea <aojea@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-02-20 09:31:56 -08:00
Damien Neil
884432780b internal/httpcommon: don't depend on net/http
When the http2 package is bundled into net/http, it imports httpcommon,
so httpcommon must not depend on net/http.

Change-Id: I2aa34e913a0df757fa83deb56f650394a924933e
Reviewed-on: https://go-review.googlesource.com/c/net/+/649415
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-02-13 14:27:35 -08:00
Damien Neil
a6c2c7f364 http2, internal/httpcommon: factor out common request header logic for h2/h3
HTTP/2 and HTTP/3 use the same set of pseudo-headers to represent
requests and responses. Move the http2 package's logic for validating
an http.Request and converting it to a set of pseudo-headers into
internal/httpcommon so it can be shared with HTTP/3.

For golang/go#70914

Change-Id: I80561752e821ccd0da2a811034c44f3f71064434
Reviewed-on: https://go-review.googlesource.com/c/net/+/643780
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Commit-Queue: Damien Neil <dneil@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-01-24 11:09:29 -08:00
Damien Neil
445eead606 http2: encode :protocol pseudo-header before regular headers
HTTP/2 requires that pseudo-headers (which start with : and are
used to pass information other than the regular request headers)
be encoded before all regular headers.

The x/net/http2 Transport's extended CONNECT support is enabled by
the user setting a ":protocol" header in the Request. This header
matches the pseudo-header that will be sent on the wire.

Ensure that the :protocol pseudo-header is sent before any regular
headers.

For golang/go#70728

Change-Id: I70de7ad524ab9457d6dfb61cb3fabe3d53c6b39b
Reviewed-on: https://go-review.googlesource.com/c/net/+/641476
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Antonio Ojea <aojea@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-01-09 12:44:42 -08:00
Damien Neil
97dd44e201 http2, internal/gate: move Gate type to an internal package
For reuse in internal/http3.

Change-Id: I186d7219194a07c100aa8bd049e007232de2d3d9
Reviewed-on: https://go-review.googlesource.com/c/net/+/641497
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2025-01-09 11:13:01 -08:00
Damien Neil
0a5dcdd858 http2: disable extended CONNECT by default
Browsers interpret a server advertising extended CONNECT support as
indicating the server supports WebSockets-over-HTTP/2.
However, WebSocket-over-HTTP/2 requires support from both the HTTP
implementation and the WebSocket implementation, and existing
Go WebSocket packages don't support HTTP/2.

Disable extended CONNECT support by default, since advertising it
is a non-backwards-compatible change.

For golang/go#71128
For golang/go#49918

Change-Id: Ie7d3ee2cd48124836a00bad320752e78719ffc46
Reviewed-on: https://go-review.googlesource.com/c/net/+/641475
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-01-08 10:37:36 -08:00
cuishuang
2124140b04 all: make function and struct comments match the names
Change-Id: I1f4a4c8daec5ac7d26f1d4df76726af664adcb36
Reviewed-on: https://go-review.googlesource.com/c/net/+/639576
Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
Auto-Submit: Damien Neil <dneil@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Jorropo <jorropo.pgm@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2025-01-02 13:01:20 -08:00
Damien Neil
e9d95ba163 http2: do not surface errors from a conn's idle timer expiring
CL 625398 surfaces errors occurring on a client conn before it
has been used for any requests.

Don't surface "errors" arising from a conn being closed for
idleness without ever being used.

For golang/go#70515

Change-Id: I2b45215f90f74fee66ee46f3b62d27117147c64a
Reviewed-on: https://go-review.googlesource.com/c/net/+/631815
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2024-12-30 14:15:19 -08:00
Damien Neil
6e414109c2 http2: fix benchmarks using common frame read/write functions
CL 586249 unified frame read/write functions used by client
and server tests, but inadvertently broke some benchmarks.
Fix those benchmarks.

This mostly restores the previous behavior of the affected
benchmarks (for example, testing only to see that a DATA frame
contains an END_STREAM marker, ignoring the number of bytes
in the frame).

Fixes golang/go#70647

Change-Id: I2b0099c3513ac8754d11c4e37b7d63277a0fb0b1
Reviewed-on: https://go-review.googlesource.com/c/net/+/633055
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Antonio Ojea <aojea@google.com>
2024-12-03 16:13:40 +00:00
Damien Neil
bc37675919 http2: limit number of PINGs bundled with RST_STREAMs
gRPC has an unfortunate behavior of stictly rate limiting
the number of PING frames that it will receive. The default is
two PING frames every two hours when no requests are in flight;
two PING frames every five minutes when a request is in flight;
and the limit resets every time the gRPC endpoint sends a
HEADERS or DATA frame.

When sending a RST_STREAM frame, the Transport can bundle a PING
frame with it to confirm the server is responding. When canceling
several requests in succession, this can result in hitting the
gRPC ping limit.

Work around this gRPC behavior by sending at most one bundled
PING per HEADERS or DATA  frame received. We already limit
ourselves to one PING in flight at a time; now, when we receive
a PING response, disable sending additional bundled PINGs
until we read a HEADERS/DATA frame.

This does not affect keep-alive pings.

Fixes golang/go#70575.

Change-Id: I7c4003039bd2dc52106b2806ca31eeeee37b7e09
Reviewed-on: https://go-review.googlesource.com/c/net/+/632995
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-12-02 21:34:57 +00:00
WeidiDeng
9a51899103 http2: add SETTINGS_ENABLE_CONNECT_PROTOCOL support
For golang/go#49918

Change-Id: Ibcd8fb189200c0976cf1bd03a796abae4afa4cfd
GitHub-Last-Rev: cba5ecd7b7
GitHub-Pull-Request: golang/net#221
Reviewed-on: https://go-review.googlesource.com/c/net/+/610977
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
2024-11-22 01:14:11 +00:00
Damien Neil
858db1a8c8 http2: surface errors occurring very early in a client conn's lifetime
When we create a new connection for a request, the request should
fail if the connection attempt fails.

There is a race condition which can cause this to not happen:

- net/http sends a request to a http2.Transport
- the http2.Transport returns ErrNoCachedConn
- net/http creates a new tls.Conn and passes it to the http2.Transport
- the http2.Transport adds the conn to its connection pool
- the connection immediately encounters an error
- the http2.Transport removes the conn from its connection pool
- net/http resends the request to the http2.Transport
- the http2.Transport returns ErrNoCachedConn, and the process repeates

If the request is sent to the http2.Transport before the connection
encounters an error, then the request fails. But otherwise, we get
stuck in an infinite loop of the http2.Transport asking for a new
connection, receiving one, and throwing it away.

To fix this, leave a dead connection in the pool for a short while
if it has never had a request sent to it. If a dead connection is
used for a new request, return an error and remove the connection
from the pool.

Change-Id: I64eb15a8f1512a6bda52db423072b945fab6f4b5
Reviewed-on: https://go-review.googlesource.com/c/net/+/625398
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-11-06 19:35:40 +00:00
Damien Neil
0aa844c2c8 http2: support unencrypted HTTP/2 handoff from net/http
Allow net/http to pass unencrypted net.Conns to Server/Transport.
We don't have an existing way to pass a conn other than a *tls.Conn
into this package, so (ab)use TLSNextProto to pass unencrypted
connections:

The http2 package adds an "unencrypted_http2" entry to the
TLSNextProto maps. The net/http package calls this function
with a *tls.Conn wrapping a net.Conn with an UnencryptedNetConn
method returning the underlying, unencrypted net.Conn.

For golang/go#67816

Change-Id: I31f9c1ba31a17c82c8ed651382bd94193acf09b9
Reviewed-on: https://go-review.googlesource.com/c/net/+/625175
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2024-11-05 19:37:20 +00:00
Damien Neil
f35fec92ec http2: detect hung client connections by confirming stream resets
Consider the case of an unresponsive client connection, where
the server has stopped responding. We send an infinite sequence of
requests to the connection in sequence, each with a timeout.
Each request counts against the concurrency limit for the
connection while active, but when a request times out we send
a RST_STREAM and free up the concurrency slot it was using.

We continue to try to send requests to the connection forever (or
until the kernel closes the underlying TCP connection, or until
ReadIdleTimeout/WriteByteTimeout results in us closing the connection).

Defend against this scenario by counting a canceled request
against the connection concurrency limit until we confirm the
server is responding. Specifically:

Track the number of in-flight request cancellations in cc.pendingResets.
This total counts against the connection concurrency limit.

When sending a RST_STREAM for a canceled request, increment
cc.pendingResets. Send a PING frame to the server, unless a PING
is already in flight.

When receiving a PING response, set cc.pendingResets to 0.

A hung connection will be used for at most
SETTINGS_MAX_CONCURRENT_STREAMS requests.

When StrictMaxConcurrentStreams is false, we will create a
new connection after reaching the concurrency limit for a hung one.

When StrictMaxConcurrentStreams is true, we will continue to
wait for the existing connection until some timeout closes it
or it becomes responsive again.

For golang/go#59690

Change-Id: I0151f9a594af14b32bcb6005a239fa19eb103704
Reviewed-on: https://go-review.googlesource.com/c/net/+/617655
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
2024-11-01 22:10:14 +00:00
Damien Neil
4783315416 http2: limit 1xx based on size, do not limit when delivered
Replace Transport's limit of 5 1xx responses with a limit based
on the maximum header size: The total size of all 1xx response
headers must not exceed the limit we use on the size of the
final response headers.

(This differs slightly from the corresponding HTTP/1 change,
which imposes a limit on all 1xx response headers *plus* the
final response headers. The difference isn't substantial,
and this implementation fits better with the HTTP/2 framer.)

When the user is reading 1xx responses using a Got1xxResponse
client trace hook, disable the limit: Each 1xx response is
individually limited by the header size limit, but there
is no limit on the total number of responses. The user is
responsible for imposing a limit if they want one.

For golang/go#65035

Change-Id: I9c19dbf068e0f580789d952f63113b3d21ad86fc
Reviewed-on: https://go-review.googlesource.com/c/net/+/615295
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2024-10-21 20:13:47 +00:00
Damien Neil
42b1186360 http2: support ResponseController.EnableFullDuplex
The ResponseController.EnableFullDuplex method indicates that an HTTP
handler intends to interleave reads from a request body with writes
to the response body.

Add an EnableFullDuplex method to the ResponseWriter so we don't
return a not-supported error. The HTTP/2 server always supports
full duplex, so this is a no-op.

For golang/go#57786

Change-Id: I6529e6ce01d59b8b48fb67ba7c244255df57c174
Reviewed-on: https://go-review.googlesource.com/c/net/+/472717
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Дарья Бочкар <dasha7vanya@gmail.com>
2024-10-10 22:34:18 +00:00
Damien Neil
7191757bc6 http2: add support for net/http HTTP2 config field
For golang/go#67813

Change-Id: I6b7f857d6ed250ba8b09649730980a91b3e8d7e9
Reviewed-on: https://go-review.googlesource.com/c/net/+/607255
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-09-25 18:02:06 +00:00
Damien Neil
4790dc7047 http2: add support for server-originated pings
Add configurable support for health-checking idle connections
accepted by the HTTP/2 server, following the same configuration
as the Transport.

Fixes golang/go#67812

Change-Id: Ia4014e691546b2c29db8dad3af5f39966d0ceb93
Reviewed-on: https://go-review.googlesource.com/c/net/+/601497
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-09-25 18:00:35 +00:00
Damien Neil
541dbe58b6 http2: add Server.WriteByteTimeout
Transports support a WriteByteTimeout option which sets the maximum
amount of time we can go without being able to write any bytes to
a connection. Add an equivalent option to Server for consistency.

Fixes golang/go#61777

Change-Id: Iaa8a69dfc403906eb224829320f901e5a6a5c429
Reviewed-on: https://go-review.googlesource.com/c/net/+/601496
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2024-09-23 22:06:05 +00:00
Damien Neil
9617c6335b http2: avoid Transport hang with Connection: close and AllowHTTP
CL 111835 changed Transport stream ID numbering to start at
stream 3 when AllowHTTP is set. This was based on a
misunderstanding:

When a connection upgrades an HTTP/1.1 request to HTTP/2,
the initial HTTP/1.1 request occupies stream 1.
However, Transport does not perform HTTP protocol upgrades.
When using a Transport to send unencrypted HTTP/2 requests,
the entire connection uses HTTP/2, the first request is
sent as HTTP/2, and there is no reason not to use stream 1
for this request.

Starting from stream 3 is mostly harmless,
but ClientConn.idleStateLocked assumes that client streams
start from 1. This causes it to misidentify new single-use
connections as having already sent a request (when AllowHTTP
is set), and therefore not suitable for use.

Revert to always starting stream IDs at 1.

Fixes golang/go#67671

Change-Id: I97c89de4ae49623d916f9dbd200f8252d2fd4247
Reviewed-on: https://go-review.googlesource.com/c/net/+/591275
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-06-12 20:39:16 +00:00
Damien Neil
6249541f2a http2: avoid race in server handler SetReadDeadine/SetWriteDeadline
Can't safely access responseWriter.rws from on the server's serve loop.

Change-Id: I477abe58cf9dd23813a0c5507aed2319696fdfaf
Reviewed-on: https://go-review.googlesource.com/c/net/+/589856
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-06-03 20:27:50 +00:00
Damien Neil
67e8d0c95d http2: report an error if goroutines outlive serverTester tests
Change-Id: Icd2152b4bddacf12120be16c32c8c2d52d235fbd
Reviewed-on: https://go-review.googlesource.com/c/net/+/589075
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-05-30 19:56:53 +00:00
Damien Neil
56082791fe http2: avoid corruption in priority write scheduler
When removing a stream containing children in the priority
tree, it was possible for some children to not be correctly
moved to the parent of the removed stream.

Fixes golang/go#66514

Change-Id: Ie8a8743a6213a6b1a2426e023111878afff78f9e
Reviewed-on: https://go-review.googlesource.com/c/net/+/589255
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-05-30 19:26:57 +00:00
Damien Neil
0d515a535e http2: factor out frame read/write test functions
Client and server tests both write frames to a test connection
and read frames back. Frame reads are usually paired with
test expectations.

Unify the API used for frame reads/writes in tests.

Introduce a testConnFramer type that implements a common set
of read/write methods, and embed it in both client and server
test types.

Change-Id: I6927c43459ba24f150a21c058a92797754f82bf1
Reviewed-on: https://go-review.googlesource.com/c/net/+/586249
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-28 22:41:32 +00:00
Damien Neil
9f5b79b000 http2: drop unused retry function
Change-Id: Ibe7e022a4863c8b0e502d7952b870046443acf7e
Reviewed-on: https://go-review.googlesource.com/c/net/+/586248
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2024-05-28 22:41:19 +00:00
Damien Neil
03c24c2d76 http2: use synthetic time in server tests
Change newServerTester to return a server using fake time
and a fake net.Conn.

Change-Id: I9d5db0cbe75696aed6d99ff1cd2369c2dea426c3
Reviewed-on: https://go-review.googlesource.com/c/net/+/586247
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-05-28 22:41:08 +00:00
Damien Neil
022530c415 http2: add a more full-featured test net.Conn
Add a net.Conn implementation that plays nicely with testsyncGroup,
implements read/write timeouts, and gives control over buffering
to let us write tests that cause writes to a Conn to block at
specific points in time.

Change-Id: I9d870b211ac9d938a8c4a221277981cdb821a6e4
Reviewed-on: https://go-review.googlesource.com/c/net/+/586246
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-21 22:48:04 +00:00
Damien Neil
410d19ee56 http2: avoid racy access to clientStream.requestedGzip
clientStream.requestedGzip is set from clientStream.writeRequest,
and examined by clientConn.readLoop. I'm not sure if there's
any possible way for an actual data race to happen here in
practice, since the read loop should only examine the field
after the request is sent by writeRequest, but it's enough
for the race detector to complain.

Set the field in ClientConn.roundTrip instead, before
the clientStream has become accessible to any other goroutines.

No test, but a following CL has race detector failures without
this change.

Change-Id: Id30f1b95bcfcc35c213440e0e47cce3feaaff06d
Reviewed-on: https://go-review.googlesource.com/c/net/+/586245
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-05-21 22:20:24 +00:00
Damien Neil
332fe235e6 http2: remove spec coverage test
When run with -coverspec, tests track which portions of the
specification they cover and the TestSpecCoverage test produces
an error if any sections lack test coverage.

This is a lovely idea, and perhaps we should resurrect it at
some point, but there is currently exactly one coverage
annotation, dating back to the first commit of this package.

Change-Id: I5d2d8a1032b783d113ed0982f7e97a3bd1c07a33
Reviewed-on: https://go-review.googlesource.com/c/net/+/586243
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-05-21 22:20:14 +00:00
Damien Neil
c1f5833288 all: replace deprecated io/ioutil calls
The io/ioutil package's features were moved to
the io and os packages in Go 1.16.

x/net depends on Go 1.18. Drop ioutil calls,
so gopls doesn't warn about them.

Change-Id: Ibdb576d94f250808ae285aa142e2fd41e7e9afc9
Reviewed-on: https://go-review.googlesource.com/c/net/+/586244
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-05-21 19:59:00 +00:00
Damien Neil
9545aeae37 http2: clearer distinction between test server types
newServerTester is used to create an HTTP/2 server for testing.
It returns a *serverTester, which includes a number of methods
for sending frames to and reading frames from a server connection
under test.

Many tests also use newServerTester to simply start an
*httptest.Server. These tests pass an "optOnlyServer" to
indicate that they don't need a client connection to interact with.
They interact with the *httptest.Server, and use no methods or
fields of *serverTester.

Make a clearer distinction between test types.

Add a newTestServer function which starts and returns
an *httptest.Server.

This function replaces use of newServerTester with optOnlyServer.

Change-Id: Ia590c9b4dcc23c17e530b0cc273b9120965da11a
Reviewed-on: https://go-review.googlesource.com/c/net/+/586155
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-20 20:54:17 +00:00
Damien Neil
b1ec120c3e http2: use implicit synchronization in tests
Rewrite the synchronization used in Transport tests.
This replaces the explicit synchronization, which requires
annotating every point where a goroutine in the code under test
may block, with implicit syncronization based on parsing
goroutine stacks to identify when all goroutines of interest are
blocked.

Change-Id: I02646e2752c359ed1b08126370a48f3d3c1fde77
Reviewed-on: https://go-review.googlesource.com/c/net/+/584895
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-20 20:54:10 +00:00
Andy Pan
c87a5b62e2 http2: set up the timer of closing idle connection after the initialization
Fixes golang/go#66763

Change-Id: I046028b6072a6da77e7f1b4d1f2e6b14f8edb042
Reviewed-on: https://go-review.googlesource.com/c/net/+/578115
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2024-05-16 22:34:05 +00:00
Damien Neil
8aa6dbf491 http2: cancel handler context on stream errors
When we reset a stream due to an error, cancel the handler context.

Fixes golang/go#67036

Change-Id: I66941d9bffb35d8b4358ff8d85cc784c1846afa6
Reviewed-on: https://go-review.googlesource.com/c/net/+/585595
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-05-15 22:50:28 +00:00
Damien Neil
2c14f519f3 http2: drop the gate type
Drop a trivial "gate" type used in exactly one location,
replacing it with an equivalent channel operation.

We've been using a "gate" with a different definition in
the quic package; dropping this hapax legomenon type from
the http2 package frees up the name if we want to use the
same gate here.

Change-Id: Id9c7d05daf7ee920c38090df960822fcc1168a4d
Reviewed-on: https://go-review.googlesource.com/c/net/+/584896
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-13 18:16:53 +00:00
Damien Neil
7fa635bd26 http2: avoid panic on h2c upgrade failure
When performing an h2c upgrade, we would panic if an error occurred
reading the client preface. *serverConn.closeStream assumes that
a conn with an IdleTimeout > 0 will have an idleTimer, but in the
h2c upgrade case the stream may have been created before the timer.

Fixes golang/go#67168

Change-Id: I30b5a701c10753ddc344079b9498285f099155cf
Reviewed-on: https://go-review.googlesource.com/c/net/+/584255
Reviewed-by: Jonathan Amsterdam <jba@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-08 17:52:51 +00:00
Tobias Klauser
e0324fcdb5 http2: use net.ErrClosed
Use errors.Is(err, net.ErrClosed) instead of checking for a known
string. net.ErrClosed is available since Go 1.16, the current minimum
version in go.mod is Go 1.18.

For golang/go#4373

Change-Id: Id98771874434bae7d9c6d1d4d36fddb28822eb39
Reviewed-on: https://go-review.googlesource.com/c/net/+/583016
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-06 15:32:06 +00:00
Damien Neil
ec05fdcd71 http2: don't retry the first request on a connection on GOAWAY error
When a server sends a GOAWAY frame, it indicates the ID of the
last stream it processed. We use this to mark any requests after
that stream as being safe to retry on a new connection.

Change this to not retry the first request on a connection if we
get a GOAWAY with an error, even if the GOAWAY has a stream ID
of 0 indicating that it didn't process that request.
If we're getting an error as the first result on a new connection,
then there's either something wrong with the server or something
wrong with our request; either way, retrying isn't likely to be
productive and may be unsafe.

This matches the behavior of the HTTP/1 client, which
also avoids retrying the first request on a new connection.

For golang/go#66668
Fixes golang/go#60636

Change-Id: I90ea7cfce2974dd413f7cd8b78541678850376a5
Reviewed-on: https://go-review.googlesource.com/c/net/+/576895
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
2024-04-05 22:13:09 +00:00