Skip to content

Commit 6aa643a

Browse files
authored
ensure http response body is closed (#1103)
* Ensure http response body is closed - When appropriate, consume all body data before close to allow connection reuse.
1 parent 4eca47c commit 6aa643a

File tree

4 files changed

+12
-10
lines changed

4 files changed

+12
-10
lines changed

bitswap/network/httpnet/httpnet.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ func (ht *Network) connectToURL(ctx context.Context, p peer.ID, u network.Parsed
624624
// FIXME: Storacha returns 410 for our probe.
625625
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNoContent || resp.StatusCode == http.StatusGone {
626626
log.Debugf("connect/ping request to %s %s succeeded: %d", p, req.URL, resp.StatusCode)
627+
io.Copy(io.Discard, resp.Body) // read all body data so that connection can be reused
627628
return resp.StatusCode, nil
628629
}
629630

filestore/fsrefstore.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package filestore
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"io"
78
"net/http"
@@ -249,6 +250,8 @@ func (f *FileManager) readURLDataObj(ctx context.Context, m mh.Multihash, d *pb.
249250
if err != nil {
250251
return nil, &CorruptReferenceError{StatusFileError, err}
251252
}
253+
defer res.Body.Close()
254+
252255
if res.StatusCode != http.StatusOK && res.StatusCode != http.StatusPartialContent {
253256
return nil, &CorruptReferenceError{
254257
StatusFileError,
@@ -258,12 +261,12 @@ func (f *FileManager) readURLDataObj(ctx context.Context, m mh.Multihash, d *pb.
258261

259262
outbuf := make([]byte, d.GetSize())
260263
_, err = io.ReadFull(res.Body, outbuf)
261-
if err == io.EOF || err == io.ErrUnexpectedEOF {
262-
return nil, &CorruptReferenceError{StatusFileChanged, err}
263-
} else if err != nil {
264+
if err != nil {
265+
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
266+
return nil, &CorruptReferenceError{StatusFileChanged, err}
267+
}
264268
return nil, &CorruptReferenceError{StatusFileError, err}
265269
}
266-
res.Body.Close()
267270

268271
// Work with CIDs for this, as they are a nice wrapper and things
269272
// will not break if multihashes underlying types change.

gateway/backend_car_fetcher.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ func (ps *remoteCarFetcher) Fetch(ctx context.Context, path path.ImmutablePath,
6464
if err != nil {
6565
return err
6666
}
67+
defer resp.Body.Close()
68+
defer io.Copy(io.Discard, resp.Body) // read all body data so that connection can be reused
6769

6870
if resp.StatusCode != http.StatusOK {
6971
errData, err := io.ReadAll(resp.Body)
@@ -75,12 +77,7 @@ func (ps *remoteCarFetcher) Fetch(ctx context.Context, path path.ImmutablePath,
7577
return fmt.Errorf("http error from car gateway: %s: %w", resp.Status, err)
7678
}
7779

78-
err = cb(path, resp.Body)
79-
if err != nil {
80-
resp.Body.Close()
81-
return err
82-
}
83-
return resp.Body.Close()
80+
return cb(path, resp.Body)
8481
}
8582

8683
func (ps *remoteCarFetcher) getRandomGatewayURL() string {

routing/http/client/client.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ func (c *Client) GetClosestPeers(ctx context.Context, key cid.Cid) (peers iter.R
667667
var skipBodyClose bool
668668
defer func() {
669669
if !skipBodyClose {
670+
io.Copy(io.Discard, resp.Body) // Drain body for connection reuse
670671
resp.Body.Close()
671672
}
672673
}()

0 commit comments

Comments
 (0)