Skip to content

Commit 24da2b8

Browse files
committed
Drain response bodies for connection re-use
Fixes issue where HTTP response was not always fully read i.e. drained, so it could not be re-used by the connection pool. Whilst not as important in a CLI due to its short-lived nature, some types are exported for external use. Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
1 parent 6e28e11 commit 24da2b8

File tree

21 files changed

+135
-25
lines changed

21 files changed

+135
-25
lines changed

commands/invoke.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,10 @@ func runInvoke(cmd *cobra.Command, args []string) error {
159159
return fmt.Errorf("failed to invoke function: %s", err)
160160
}
161161
if res.Body != nil {
162-
defer res.Body.Close()
162+
defer func() {
163+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
164+
_ = res.Body.Close()
165+
}()
163166
}
164167

165168
if !authenticate && res.StatusCode == http.StatusUnauthorized {
@@ -182,7 +185,10 @@ func runInvoke(cmd *cobra.Command, args []string) error {
182185
return fmt.Errorf("failed to invoke function: %s", err)
183186
}
184187
if res.Body != nil {
185-
defer res.Body.Close()
188+
defer func() {
189+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
190+
_ = res.Body.Close()
191+
}()
186192
}
187193
}
188194
}

commands/login.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,10 @@ func validateLogin(gatewayURL string, user string, pass string, timeout time.Dur
135135
}
136136

137137
if res.Body != nil {
138-
defer res.Body.Close()
138+
defer func() {
139+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
140+
_ = res.Body.Close()
141+
}()
139142
}
140143

141144
switch res.StatusCode {

commands/store.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ func storeList(store string) ([]storeV2.StoreFunction, error) {
6868
}
6969

7070
if res.Body != nil {
71-
defer res.Body.Close()
71+
defer func() {
72+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
73+
_ = res.Body.Close()
74+
}()
7275
}
7376

7477
switch res.StatusCode {

commands/template_store_list.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,10 @@ func getTemplateInfo(repository string) ([]TemplateInfo, error) {
125125
if res.Body == nil {
126126
return nil, fmt.Errorf("error empty response body from: %s", templateStoreURL)
127127
}
128-
defer res.Body.Close()
128+
defer func() {
129+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
130+
_ = res.Body.Close()
131+
}()
129132

130133
if res.StatusCode != http.StatusOK {
131134
return nil, fmt.Errorf("unexpected status code wanted: %d got: %d", http.StatusOK, res.StatusCode)

go.mod

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ require (
1616
github.com/mitchellh/go-wordwrap v1.0.1
1717
github.com/moby/term v0.5.2
1818
github.com/morikuni/aec v1.0.0
19-
github.com/openfaas/faas-provider v0.25.8
19+
github.com/openfaas/faas-provider v0.25.10
2020
github.com/openfaas/faas/gateway v0.0.0-20250422101858-7803ea1861f2
2121
github.com/openfaas/go-sdk v0.2.19
2222
github.com/pkg/errors v0.9.1
@@ -29,6 +29,8 @@ require (
2929
require (
3030
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
3131
github.com/VividCortex/ewma v1.2.0 // indirect
32+
github.com/beorn7/perks v1.0.1 // indirect
33+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
3234
github.com/cheggaaa/pb/v3 v3.1.7 // indirect
3335
github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
3436
github.com/docker/cli v28.3.3+incompatible // indirect
@@ -38,23 +40,30 @@ require (
3840
github.com/fatih/color v1.18.0 // indirect
3941
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
4042
github.com/go-git/go-billy/v5 v5.6.2 // indirect
43+
github.com/gorilla/mux v1.8.1 // indirect
4144
github.com/inconshreveable/mousetrap v1.1.0 // indirect
4245
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
4346
github.com/klauspost/compress v1.18.0 // indirect
4447
github.com/mattn/go-colorable v0.1.14 // indirect
4548
github.com/mattn/go-isatty v0.0.20 // indirect
4649
github.com/mattn/go-runewidth v0.0.16 // indirect
50+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
4751
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 // indirect
4852
github.com/olekukonko/errors v1.1.0 // indirect
4953
github.com/olekukonko/ll v0.1.0 // indirect
5054
github.com/olekukonko/tablewriter v1.0.9 // indirect
5155
github.com/opencontainers/go-digest v1.0.0 // indirect
5256
github.com/opencontainers/image-spec v1.1.1 // indirect
57+
github.com/prometheus/client_golang v1.20.5 // indirect
58+
github.com/prometheus/client_model v0.6.1 // indirect
59+
github.com/prometheus/common v0.62.0 // indirect
60+
github.com/prometheus/procfs v0.15.1 // indirect
5361
github.com/rivo/uniseg v0.4.7 // indirect
5462
github.com/ryanuber/go-glob v1.0.0 // indirect
5563
github.com/sirupsen/logrus v1.9.3 // indirect
5664
github.com/vbatts/tar-split v0.12.1 // indirect
5765
golang.org/x/net v0.43.0 // indirect
5866
golang.org/x/sys v0.35.0 // indirect
67+
google.golang.org/protobuf v1.36.4 // indirect
5968
gopkg.in/warnings.v0 v0.1.2 // indirect
6069
)

go.sum

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ github.com/alexellis/go-execute/v2 v2.2.1 h1:4Ye3jiCKQarstODOEmqDSRCqxMHLkC92Bhs
1010
github.com/alexellis/go-execute/v2 v2.2.1/go.mod h1:FMdRnUTiFAmYXcv23txrp3VYZfLo24nMpiIneWgKHTQ=
1111
github.com/alexellis/hmac/v2 v2.0.0 h1:/sH/UJxDXPpJorUeg2DudeKSeUrWPF32Yamw2TiDoOQ=
1212
github.com/alexellis/hmac/v2 v2.0.0/go.mod h1:O7hZZgTfh5fp5+vAamzodZPlbw+aQK+nnrrJNHsEvL0=
13+
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
14+
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
1315
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
1416
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
17+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
18+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
1519
github.com/cheggaaa/pb/v3 v3.1.7 h1:2FsIW307kt7A/rz/ZI2lvPO+v3wKazzE4K/0LtTWsOI=
1620
github.com/cheggaaa/pb/v3 v3.1.7/go.mod h1:/Ji89zfVPeC/u5j8ukD0MBPHt2bzTYp74lQ7KlgFWTQ=
1721
github.com/containerd/stargz-snapshotter/estargz v0.17.0 h1:+TyQIsR/zSFI1Rm31EQBwpAA1ovYgIKHy7kctL3sLcE=
@@ -45,6 +49,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
4549
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
4650
github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
4751
github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
52+
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
53+
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
4854
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
4955
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
5056
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
@@ -69,6 +75,8 @@ github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
6975
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
7076
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
7177
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
78+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
79+
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
7280
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00 h1:ZCnkxe9GgWqqBxAk3cIKlQJuaqgOUF/nUtQs8flVTHM=
7381
github.com/olekukonko/cat v0.0.0-20250817074551-3280053e4e00/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
7482
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
@@ -83,6 +91,8 @@ github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJw
8391
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
8492
github.com/openfaas/faas-provider v0.25.8 h1:3W1ZyhUvpqTOiNQoV7jzdZhDJeJJlJelosAtjFzMNyw=
8593
github.com/openfaas/faas-provider v0.25.8/go.mod h1:rMXbj+AYVpn82UoHIOgWHiDeV118t0bSxyoC9d00jpc=
94+
github.com/openfaas/faas-provider v0.25.10 h1:fCf2i1vCx3UL8o9gjYPt7CcX8Kko2dc6xme7ITIa8uY=
95+
github.com/openfaas/faas-provider v0.25.10/go.mod h1:rMXbj+AYVpn82UoHIOgWHiDeV118t0bSxyoC9d00jpc=
8696
github.com/openfaas/faas/gateway v0.0.0-20250422101858-7803ea1861f2 h1:Reu1wD3BZ/+t+cCnWGYUuFREa8cC7/01tirlkc5rUmk=
8797
github.com/openfaas/faas/gateway v0.0.0-20250422101858-7803ea1861f2/go.mod h1:j5eUH36/clgztwBYFoXZ/s1UFQ9Alzt8rb50gh7L5Ns=
8898
github.com/openfaas/go-sdk v0.2.19 h1:L31+TzyKGMaRx56gDZQNE9mhAwWHq1WUsMY3ApjIOTo=
@@ -91,6 +101,14 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
91101
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
92102
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
93103
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
104+
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
105+
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
106+
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
107+
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
108+
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
109+
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
110+
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
111+
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
94112
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
95113
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
96114
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -123,6 +141,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
123141
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
124142
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
125143
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
144+
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
145+
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
126146
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
127147
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
128148
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

proxy/delete.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ func (c *Client) DeleteFunction(ctx context.Context, functionName string, namesp
4747
}
4848

4949
if res.Body != nil {
50-
defer res.Body.Close()
50+
defer func() {
51+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
52+
_ = res.Body.Close()
53+
}()
5154
}
5255

5356
switch res.StatusCode {

proxy/deploy.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ func (c *Client) deploy(context context.Context, spec *DeployFunctionSpec, updat
162162
}
163163

164164
if res.Body != nil {
165-
defer res.Body.Close()
165+
defer func() {
166+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
167+
_ = res.Body.Close()
168+
}()
166169
}
167170

168171
switch res.StatusCode {

proxy/describe.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ func (c *Client) GetFunctionInfo(ctx context.Context, functionName string, names
4343
}
4444

4545
if res.Body != nil {
46-
defer res.Body.Close()
46+
defer func() {
47+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
48+
_ = res.Body.Close()
49+
}()
4750
}
4851

4952
switch res.StatusCode {

proxy/function_store.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ func FunctionStoreList(store string) ([]v2.StoreFunction, error) {
3434
}
3535

3636
if res.Body != nil {
37-
defer res.Body.Close()
37+
defer func() {
38+
_, _ = io.Copy(io.Discard, res.Body) // drain to EOF
39+
_ = res.Body.Close()
40+
}()
3841
}
3942

4043
switch res.StatusCode {

0 commit comments

Comments
 (0)