Skip to content

Commit d8f9801

Browse files
rpc: avoid unnecessary RST_STREAM, PING frames sent by client (#33122)
Context from Cloudflare blog: https://blog.cloudflare.com/go-and-enhance-your-calm/#reading-bodies-in-go-can-be-unintuitive We were able to reproduce the same issue discussed by Cloudflare in their recent blog post above using the `ethclient`.
1 parent 7368b34 commit d8f9801

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

rpc/http.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,21 @@ func newClientTransportHTTP(endpoint string, cfg *clientConfig) reconnectFunc {
168168
}
169169
}
170170

171+
// cleanlyCloseBody avoids sending unnecessary RST_STREAM and PING frames by
172+
// ensuring the whole body is read before being closed.
173+
// See https://blog.cloudflare.com/go-and-enhance-your-calm/#reading-bodies-in-go-can-be-unintuitive
174+
func cleanlyCloseBody(body io.ReadCloser) error {
175+
io.Copy(io.Discard, body)
176+
return body.Close()
177+
}
178+
171179
func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error {
172180
hc := c.writeConn.(*httpConn)
173181
respBody, err := hc.doRequest(ctx, msg)
174182
if err != nil {
175183
return err
176184
}
177-
defer respBody.Close()
185+
defer cleanlyCloseBody(respBody)
178186

179187
var resp jsonrpcMessage
180188
batch := [1]*jsonrpcMessage{&resp}
@@ -191,7 +199,7 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr
191199
if err != nil {
192200
return err
193201
}
194-
defer respBody.Close()
202+
defer cleanlyCloseBody(respBody)
195203

196204
var respmsgs []*jsonrpcMessage
197205
if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil {
@@ -236,7 +244,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos
236244
if _, err := buf.ReadFrom(resp.Body); err == nil {
237245
body = buf.Bytes()
238246
}
239-
resp.Body.Close()
247+
cleanlyCloseBody(resp.Body)
240248
return nil, HTTPError{
241249
Status: resp.Status,
242250
StatusCode: resp.StatusCode,

rpc/http_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func confirmHTTPRequestYieldsStatusCode(t *testing.T, method, contentType, body
106106
if err != nil {
107107
t.Fatalf("request failed: %v", err)
108108
}
109-
resp.Body.Close()
109+
cleanlyCloseBody(resp.Body)
110110
confirmStatusCode(t, resp.StatusCode, expectedStatusCode)
111111
}
112112

0 commit comments

Comments
 (0)