]> Cypherpunks.ru repositories - gostls13.git/commitdiff
net/http: add Client.CloseIdleConnections
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 20 Aug 2018 21:04:15 +0000 (21:04 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 20 Aug 2018 23:12:01 +0000 (23:12 +0000)
Fixes #26563

Change-Id: I22b0c72d45fab9d3f31fda04da76a8c0b10cd8b6
Reviewed-on: https://go-review.googlesource.com/130115
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Bonventre <andybons@golang.org>
src/net/http/client.go
src/net/http/client_test.go

index 8f69a298e3fcf4951a69a60b6ca3d955f8d1308e..a15b3ba2761ed76c79818f6a56ea870c39403021 100644 (file)
@@ -833,6 +833,22 @@ func (c *Client) Head(url string) (resp *Response, err error) {
        return c.Do(req)
 }
 
+// CloseIdleConnections closes any connections on its Transport which
+// were previously connected from previous requests but are now
+// sitting idle in a "keep-alive" state. It does not interrupt any
+// connections currently in use.
+//
+// If the Client's Transport does not have a CloseIdleConnections method
+// then this method does nothing.
+func (c *Client) CloseIdleConnections() {
+       type closeIdler interface {
+               CloseIdleConnections()
+       }
+       if tr, ok := c.transport().(closeIdler); ok {
+               tr.CloseIdleConnections()
+       }
+}
+
 // cancelTimerBody is an io.ReadCloser that wraps rc with two features:
 // 1) on Read error or close, the stop func is called.
 // 2) On Read failure, if reqDidTimeout is true, the error is wrapped and
index bfc793e638cae218bf3f7730aa13e1e912ef00ad..12764d3bf1e4078cc08b01ecddb8c9089c8ef555 100644 (file)
@@ -1888,3 +1888,27 @@ func TestTransportBodyReadError(t *testing.T) {
                t.Errorf("close calls = %d; want 1", closeCalls)
        }
 }
+
+type roundTripperWithoutCloseIdle struct{}
+
+func (roundTripperWithoutCloseIdle) RoundTrip(*Request) (*Response, error) { panic("unused") }
+
+type roundTripperWithCloseIdle func() // underlying func is CloseIdleConnections func
+
+func (roundTripperWithCloseIdle) RoundTrip(*Request) (*Response, error) { panic("unused") }
+func (f roundTripperWithCloseIdle) CloseIdleConnections()               { f() }
+
+func TestClientCloseIdleConnections(t *testing.T) {
+       c := &Client{Transport: roundTripperWithoutCloseIdle{}}
+       c.CloseIdleConnections() // verify we don't crash at least
+
+       closed := false
+       var tr RoundTripper = roundTripperWithCloseIdle(func() {
+               closed = true
+       })
+       c = &Client{Transport: tr}
+       c.CloseIdleConnections()
+       if !closed {
+               t.Error("not closed")
+       }
+}