Skip to content
This repository was archived by the owner on Feb 21, 2024. It is now read-only.

Commit ff80013

Browse files
committed
ensure internal client closes all response bodies to avoid leaking connections/goroutines
1 parent 4a2ab77 commit ff80013

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

http/client.go

+17-5
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func (c *InternalClient) CreateIndex(ctx context.Context, index string, opt pilo
164164
}
165165
return err
166166
}
167-
return nil
167+
return errors.Wrap(resp.Body.Close(), "closing response body")
168168
}
169169

170170
// FragmentNodes returns a list of nodes that own a shard.
@@ -705,6 +705,9 @@ func (c *InternalClient) exportNodeCSV(ctx context.Context, node *pilosa.Node, i
705705
return nil
706706
}
707707

708+
// RetrieveShardFromURI returns a ReadCloser which contains the data of the
709+
// specified shard from the specified node. Caller *must* close the returned
710+
// ReadCloser or risk leaking goroutines/tcp connections.
708711
func (c *InternalClient) RetrieveShardFromURI(ctx context.Context, index, field, view string, shard uint64, uri pilosa.URI) (io.ReadCloser, error) {
709712
span, ctx := tracing.StartSpanFromContext(ctx, "InternalClient.RetrieveShardFromURI")
710713
defer span.Finish()
@@ -800,7 +803,7 @@ func (c *InternalClient) CreateFieldWithOptions(ctx context.Context, index, fiel
800803
return err
801804
}
802805

803-
return nil
806+
return errors.Wrap(resp.Body.Close(), "closing response body")
804807
}
805808

806809
// FragmentBlocks returns a list of block checksums for a fragment on a host.
@@ -994,15 +997,24 @@ func (c *InternalClient) SendMessage(ctx context.Context, uri *pilosa.URI, msg [
994997
req.Header.Set("Accept", "application/json")
995998

996999
// Execute request.
997-
_, err = c.executeRequest(req.WithContext(ctx))
998-
return err
1000+
resp, err := c.executeRequest(req.WithContext(ctx))
1001+
if err != nil {
1002+
return errors.Wrap(err, "executing request")
1003+
}
1004+
return errors.Wrap(resp.Body.Close(), "closing response body")
9991005
}
10001006

1001-
// executeRequest executes the given request and checks the Response
1007+
// executeRequest executes the given request and checks the Response. For
1008+
// responses with non-2XX status, the body is read and closed, and an error is
1009+
// returned. If the error is nil, the caller must ensure that the response body
1010+
// is closed.
10021011
func (c *InternalClient) executeRequest(req *http.Request) (*http.Response, error) {
10031012
tracing.GlobalTracer.InjectHTTPHeaders(req)
10041013
resp, err := c.httpClient.Do(req)
10051014
if err != nil {
1015+
if resp != nil {
1016+
resp.Body.Close()
1017+
}
10061018
return nil, errors.Wrap(err, "executing request")
10071019
}
10081020
if resp.StatusCode < 200 || resp.StatusCode >= 300 {

0 commit comments

Comments
 (0)