aboutsummaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2023-02-13 10:58:32 -0800
committerGopher Robot <gobot@golang.org>2023-02-13 20:18:56 +0000
commit7f5274a2885b8a3310cd4c3a6af49453d34cceae (patch)
treea3ff37dc31dd3e586623899553a969b75a145167 /src/net/http
parent0b922bfa9c43b0b1b957f3f6d62bb366bb2c9870 (diff)
downloadgo-7f5274a2885b8a3310cd4c3a6af49453d34cceae.tar.xz
all: update vendored golang.org/x/net
Pull in HTTP/2 fix to deflake builders: 547e7edf38 http2: avoid referencing ResponseWrite.Write parameter after returning For #58446 Change-Id: I7f3666bc1f20ee03a7ccf25f0e091033cbc635d7 Reviewed-on: https://go-review.googlesource.com/c/go/+/467657 Auto-Submit: Damien Neil <dneil@google.com> Run-TryBot: Damien Neil <dneil@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/h2_bundle.go29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index eb3fd159f8..b451cee9dc 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -2063,6 +2063,15 @@ func (f *http2Framer) WriteData(streamID uint32, endStream bool, data []byte) er
// It is the caller's responsibility not to violate the maximum frame size
// and to not call other Write methods concurrently.
func (f *http2Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
+ if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {
+ return err
+ }
+ return f.endWrite()
+}
+
+// startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer.
+// The caller should call endWrite to flush the frame to the underlying writer.
+func (f *http2Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
return http2errStreamID
}
@@ -2092,7 +2101,7 @@ func (f *http2Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad
}
f.wbuf = append(f.wbuf, data...)
f.wbuf = append(f.wbuf, pad...)
- return f.endWrite()
+ return nil
}
// A SettingsFrame conveys configuration parameters that affect how
@@ -4653,8 +4662,13 @@ type http2frameWriteResult struct {
// and then reports when it's done.
// At most one goroutine can be running writeFrameAsync at a time per
// serverConn.
-func (sc *http2serverConn) writeFrameAsync(wr http2FrameWriteRequest) {
- err := wr.write.writeFrame(sc)
+func (sc *http2serverConn) writeFrameAsync(wr http2FrameWriteRequest, wd *http2writeData) {
+ var err error
+ if wd == nil {
+ err = wr.write.writeFrame(sc)
+ } else {
+ err = sc.framer.endWrite()
+ }
sc.wroteFrameCh <- http2frameWriteResult{wr: wr, err: err}
}
@@ -5063,9 +5077,16 @@ func (sc *http2serverConn) startFrameWrite(wr http2FrameWriteRequest) {
sc.writingFrameAsync = false
err := wr.write.writeFrame(sc)
sc.wroteFrame(http2frameWriteResult{wr: wr, err: err})
+ } else if wd, ok := wr.write.(*http2writeData); ok {
+ // Encode the frame in the serve goroutine, to ensure we don't have
+ // any lingering asynchronous references to data passed to Write.
+ // See https://go.dev/issue/58446.
+ sc.framer.startWriteDataPadded(wd.streamID, wd.endStream, wd.p, nil)
+ sc.writingFrameAsync = true
+ go sc.writeFrameAsync(wr, wd)
} else {
sc.writingFrameAsync = true
- go sc.writeFrameAsync(wr)
+ go sc.writeFrameAsync(wr, nil)
}
}