]> git.feebdaed.xyz Git - 0xmirror/podman.git/commitdiff
fix(deps): update module golang.org/x/net to v0.48.0
authorrenovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Thu, 11 Dec 2025 14:37:08 +0000 (14:37 +0000)
committerGitHub <noreply@github.com>
Thu, 11 Dec 2025 14:37:08 +0000 (14:37 +0000)
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
go.mod
go.sum
vendor/golang.org/x/net/http2/transport.go
vendor/golang.org/x/net/trace/events.go
vendor/modules.txt

diff --git a/go.mod b/go.mod
index e81ceb163bc7a86bbcad15f6ccc011abff2263a2..c42e09921c3a335a8e334905976d4742acc53373 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -68,7 +68,7 @@ require (
        go.podman.io/image/v5 v5.38.1-0.20251209230740-724707234895
        go.podman.io/storage v1.61.1-0.20251209230740-724707234895
        golang.org/x/crypto v0.46.0
-       golang.org/x/net v0.47.0
+       golang.org/x/net v0.48.0
        golang.org/x/sync v0.19.0
        golang.org/x/sys v0.39.0
        golang.org/x/term v0.38.0
diff --git a/go.sum b/go.sum
index b9040935badbdab035df3a99912634ad01481733..92dd4d64f8a8a3333884c2dfcb2e23eb154e985a 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -491,8 +491,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
-golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
-golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
+golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
+golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
 golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
 golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
index 1965913e543b4750020b4f79c2f69f8814ec7b1e..ccb87e6da37ac6bfb5aa4be519a31148d3d0da22 100644 (file)
@@ -376,11 +376,24 @@ type ClientConn struct {
        // completely unresponsive connection.
        pendingResets int
 
+       // readBeforeStreamID is the smallest stream ID that has not been followed by
+       // a frame read from the peer. We use this to determine when a request may
+       // have been sent to a completely unresponsive connection:
+       // If the request ID is less than readBeforeStreamID, then we have had some
+       // indication of life on the connection since sending the request.
+       readBeforeStreamID uint32
+
        // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.
        // Write to reqHeaderMu to lock it, read from it to unlock.
        // Lock reqmu BEFORE mu or wmu.
        reqHeaderMu chan struct{}
 
+       // internalStateHook reports state changes back to the net/http.ClientConn.
+       // Note that this is different from the user state hook registered by
+       // net/http.ClientConn.SetStateHook: The internal hook calls ClientConn,
+       // which calls the user hook.
+       internalStateHook func()
+
        // wmu is held while writing.
        // Acquire BEFORE mu when holding both, to avoid blocking mu on network writes.
        // Only acquire both at the same time when changing peer settings.
@@ -710,7 +723,7 @@ func canRetryError(err error) bool {
 
 func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {
        if t.transportTestHooks != nil {
-               return t.newClientConn(nil, singleUse)
+               return t.newClientConn(nil, singleUse, nil)
        }
        host, _, err := net.SplitHostPort(addr)
        if err != nil {
@@ -720,7 +733,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b
        if err != nil {
                return nil, err
        }
-       return t.newClientConn(tconn, singleUse)
+       return t.newClientConn(tconn, singleUse, nil)
 }
 
 func (t *Transport) newTLSConfig(host string) *tls.Config {
@@ -772,10 +785,10 @@ func (t *Transport) expectContinueTimeout() time.Duration {
 }
 
 func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
-       return t.newClientConn(c, t.disableKeepAlives())
+       return t.newClientConn(c, t.disableKeepAlives(), nil)
 }
 
-func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
+func (t *Transport) newClientConn(c net.Conn, singleUse bool, internalStateHook func()) (*ClientConn, error) {
        conf := configFromTransport(t)
        cc := &ClientConn{
                t:                           t,
@@ -797,6 +810,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
                pings:                       make(map[[8]byte]chan struct{}),
                reqHeaderMu:                 make(chan struct{}, 1),
                lastActive:                  time.Now(),
+               internalStateHook:           internalStateHook,
        }
        if t.transportTestHooks != nil {
                t.transportTestHooks.newclientconn(cc)
@@ -1037,10 +1051,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
                maxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams)
        }
 
-       st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
-               !cc.doNotReuse &&
-               int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&
-               !cc.tooIdleLocked()
+       st.canTakeNewRequest = maxConcurrentOkay && cc.isUsableLocked()
 
        // If this connection has never been used for a request and is closed,
        // then let it take a request (which will fail).
@@ -1056,6 +1067,31 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
        return
 }
 
+func (cc *ClientConn) isUsableLocked() bool {
+       return cc.goAway == nil &&
+               !cc.closed &&
+               !cc.closing &&
+               !cc.doNotReuse &&
+               int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&
+               !cc.tooIdleLocked()
+}
+
+// canReserveLocked reports whether a net/http.ClientConn can reserve a slot on this conn.
+//
+// This follows slightly different rules than clientConnIdleState.canTakeNewRequest.
+// We only permit reservations up to the conn's concurrency limit.
+// This differs from ClientConn.ReserveNewRequest, which permits reservations
+// past the limit when StrictMaxConcurrentStreams is set.
+func (cc *ClientConn) canReserveLocked() bool {
+       if cc.currentRequestCountLocked() >= int(cc.maxConcurrentStreams) {
+               return false
+       }
+       if !cc.isUsableLocked() {
+               return false
+       }
+       return true
+}
+
 // currentRequestCountLocked reports the number of concurrency slots currently in use,
 // including active streams, reserved slots, and reset streams waiting for acknowledgement.
 func (cc *ClientConn) currentRequestCountLocked() int {
@@ -1067,6 +1103,14 @@ func (cc *ClientConn) canTakeNewRequestLocked() bool {
        return st.canTakeNewRequest
 }
 
+// availableLocked reports the number of concurrency slots available.
+func (cc *ClientConn) availableLocked() int {
+       if !cc.canTakeNewRequestLocked() {
+               return 0
+       }
+       return max(0, int(cc.maxConcurrentStreams)-cc.currentRequestCountLocked())
+}
+
 // tooIdleLocked reports whether this connection has been been sitting idle
 // for too much wall time.
 func (cc *ClientConn) tooIdleLocked() bool {
@@ -1091,6 +1135,7 @@ func (cc *ClientConn) closeConn() {
        t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
        defer t.Stop()
        cc.tconn.Close()
+       cc.maybeCallStateHook()
 }
 
 // A tls.Conn.Close can hang for a long time if the peer is unresponsive.
@@ -1616,6 +1661,8 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
        }
        bodyClosed := cs.reqBodyClosed
        closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
+       // Have we read any frames from the connection since sending this request?
+       readSinceStream := cc.readBeforeStreamID > cs.ID
        cc.mu.Unlock()
        if mustCloseBody {
                cs.reqBody.Close()
@@ -1647,8 +1694,10 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
                                //
                                // This could be due to the server becoming unresponsive.
                                // To avoid sending too many requests on a dead connection,
-                               // we let the request continue to consume a concurrency slot
-                               // until we can confirm the server is still responding.
+                               // if we haven't read any frames from the connection since
+                               // sending this request, we let it continue to consume
+                               // a concurrency slot until we can confirm the server is
+                               // still responding.
                                // We do this by sending a PING frame along with the RST_STREAM
                                // (unless a ping is already in flight).
                                //
@@ -1659,7 +1708,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
                                // because it's short lived and will probably be closed before
                                // we get the ping response.
                                ping := false
-                               if !closeOnIdle {
+                               if !closeOnIdle && !readSinceStream {
                                        cc.mu.Lock()
                                        // rstStreamPingsBlocked works around a gRPC behavior:
                                        // see comment on the field for details.
@@ -1693,6 +1742,7 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
        }
 
        close(cs.donec)
+       cc.maybeCallStateHook()
 }
 
 // awaitOpenSlotForStreamLocked waits until len(streams) < maxConcurrentStreams.
@@ -2745,6 +2795,7 @@ func (rl *clientConnReadLoop) streamByID(id uint32, headerOrData bool) *clientSt
                // See comment on ClientConn.rstStreamPingsBlocked for details.
                rl.cc.rstStreamPingsBlocked = false
        }
+       rl.cc.readBeforeStreamID = rl.cc.nextStreamID
        cs := rl.cc.streams[id]
        if cs != nil && !cs.readAborted {
                return cs
@@ -2795,6 +2846,7 @@ func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {
 
 func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error {
        cc := rl.cc
+       defer cc.maybeCallStateHook()
        cc.mu.Lock()
        defer cc.mu.Unlock()
 
@@ -2975,6 +3027,7 @@ func (cc *ClientConn) Ping(ctx context.Context) error {
 func (rl *clientConnReadLoop) processPing(f *PingFrame) error {
        if f.IsAck() {
                cc := rl.cc
+               defer cc.maybeCallStateHook()
                cc.mu.Lock()
                defer cc.mu.Unlock()
                // If ack, notify listener if any
@@ -3198,9 +3251,13 @@ func registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err erro
 }
 
 // noDialH2RoundTripper is a RoundTripper which only tries to complete the request
-// if there's already has a cached connection to the host.
+// if there's already a cached connection to the host.
 // (The field is exported so it can be accessed via reflect from net/http; tested
 // by TestNoDialH2RoundTripperType)
+//
+// A noDialH2RoundTripper is registered with http1.Transport.RegisterProtocol,
+// and the http1.Transport can use type assertions to call non-RoundTrip methods on it.
+// This lets us expose, for example, NewClientConn to net/http.
 type noDialH2RoundTripper struct{ *Transport }
 
 func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
@@ -3211,6 +3268,85 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err
        return res, err
 }
 
+func (rt noDialH2RoundTripper) NewClientConn(conn net.Conn, internalStateHook func()) (http.RoundTripper, error) {
+       tr := rt.Transport
+       cc, err := tr.newClientConn(conn, tr.disableKeepAlives(), internalStateHook)
+       if err != nil {
+               return nil, err
+       }
+
+       // RoundTrip should block when the conn is at its concurrency limit,
+       // not return an error. Setting strictMaxConcurrentStreams enables this.
+       cc.strictMaxConcurrentStreams = true
+
+       return netHTTPClientConn{cc}, nil
+}
+
+// netHTTPClientConn wraps ClientConn and implements the interface net/http expects from
+// the RoundTripper returned by NewClientConn.
+type netHTTPClientConn struct {
+       cc *ClientConn
+}
+
+func (cc netHTTPClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
+       return cc.cc.RoundTrip(req)
+}
+
+func (cc netHTTPClientConn) Close() error {
+       return cc.cc.Close()
+}
+
+func (cc netHTTPClientConn) Err() error {
+       cc.cc.mu.Lock()
+       defer cc.cc.mu.Unlock()
+       if cc.cc.closed {
+               return errors.New("connection closed")
+       }
+       return nil
+}
+
+func (cc netHTTPClientConn) Reserve() error {
+       defer cc.cc.maybeCallStateHook()
+       cc.cc.mu.Lock()
+       defer cc.cc.mu.Unlock()
+       if !cc.cc.canReserveLocked() {
+               return errors.New("connection is unavailable")
+       }
+       cc.cc.streamsReserved++
+       return nil
+}
+
+func (cc netHTTPClientConn) Release() {
+       defer cc.cc.maybeCallStateHook()
+       cc.cc.mu.Lock()
+       defer cc.cc.mu.Unlock()
+       // We don't complain if streamsReserved is 0.
+       //
+       // This is consistent with RoundTrip: both Release and RoundTrip will
+       // consume a reservation iff one exists.
+       if cc.cc.streamsReserved > 0 {
+               cc.cc.streamsReserved--
+       }
+}
+
+func (cc netHTTPClientConn) Available() int {
+       cc.cc.mu.Lock()
+       defer cc.cc.mu.Unlock()
+       return cc.cc.availableLocked()
+}
+
+func (cc netHTTPClientConn) InFlight() int {
+       cc.cc.mu.Lock()
+       defer cc.cc.mu.Unlock()
+       return cc.cc.currentRequestCountLocked()
+}
+
+func (cc *ClientConn) maybeCallStateHook() {
+       if cc.internalStateHook != nil {
+               cc.internalStateHook()
+       }
+}
+
 func (t *Transport) idleConnTimeout() time.Duration {
        // to keep things backwards compatible, we use non-zero values of
        // IdleConnTimeout, followed by using the IdleConnTimeout on the underlying
index 3aaffdd1f7a2deb0235aa9deb329208f8d05410f..c2b3c009801133ebefaf28a6b4cade874ae8251e 100644 (file)
@@ -58,8 +58,8 @@ func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) {
                Buckets: buckets,
        }
 
-       data.Families = make([]string, 0, len(families))
        famMu.RLock()
+       data.Families = make([]string, 0, len(families))
        for name := range families {
                data.Families = append(data.Families, name)
        }
index 9fd32174c1b8837251f80c8b78faa12782556b4e..17b0acb06047224c24a487bb8a85a92ce14216fe 100644 (file)
@@ -1003,7 +1003,7 @@ golang.org/x/crypto/xts
 # golang.org/x/mod v0.30.0
 ## explicit; go 1.24.0
 golang.org/x/mod/semver
-# golang.org/x/net v0.47.0
+# golang.org/x/net v0.48.0
 ## explicit; go 1.24.0
 golang.org/x/net/bpf
 golang.org/x/net/html