Skip to content

Commit 85a0192

Browse files
committed
net/http: add Client.CloseIdleConnections
Fixes #26563 Change-Id: I22b0c72d45fab9d3f31fda04da76a8c0b10cd8b6 Reviewed-on: https://go-review.googlesource.com/130115 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Andrew Bonventre <[email protected]>
1 parent d169a42 commit 85a0192

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

src/net/http/client.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,22 @@ func (c *Client) Head(url string) (resp *Response, err error) {
833833
return c.Do(req)
834834
}
835835

836+
// CloseIdleConnections closes any connections on its Transport which
837+
// were previously connected from previous requests but are now
838+
// sitting idle in a "keep-alive" state. It does not interrupt any
839+
// connections currently in use.
840+
//
841+
// If the Client's Transport does not have a CloseIdleConnections method
842+
// then this method does nothing.
843+
func (c *Client) CloseIdleConnections() {
844+
type closeIdler interface {
845+
CloseIdleConnections()
846+
}
847+
if tr, ok := c.transport().(closeIdler); ok {
848+
tr.CloseIdleConnections()
849+
}
850+
}
851+
836852
// cancelTimerBody is an io.ReadCloser that wraps rc with two features:
837853
// 1) on Read error or close, the stop func is called.
838854
// 2) On Read failure, if reqDidTimeout is true, the error is wrapped and

src/net/http/client_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,3 +1888,27 @@ func TestTransportBodyReadError(t *testing.T) {
18881888
t.Errorf("close calls = %d; want 1", closeCalls)
18891889
}
18901890
}
1891+
1892+
type roundTripperWithoutCloseIdle struct{}
1893+
1894+
func (roundTripperWithoutCloseIdle) RoundTrip(*Request) (*Response, error) { panic("unused") }
1895+
1896+
type roundTripperWithCloseIdle func() // underlying func is CloseIdleConnections func
1897+
1898+
func (roundTripperWithCloseIdle) RoundTrip(*Request) (*Response, error) { panic("unused") }
1899+
func (f roundTripperWithCloseIdle) CloseIdleConnections() { f() }
1900+
1901+
func TestClientCloseIdleConnections(t *testing.T) {
1902+
c := &Client{Transport: roundTripperWithoutCloseIdle{}}
1903+
c.CloseIdleConnections() // verify we don't crash at least
1904+
1905+
closed := false
1906+
var tr RoundTripper = roundTripperWithCloseIdle(func() {
1907+
closed = true
1908+
})
1909+
c = &Client{Transport: tr}
1910+
c.CloseIdleConnections()
1911+
if !closed {
1912+
t.Error("not closed")
1913+
}
1914+
}

0 commit comments

Comments
 (0)