mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 07:37:20 +00:00
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`.
This commit is contained in:
parent
7368b34a4b
commit
d8f9801305
2 changed files with 12 additions and 4 deletions
14
rpc/http.go
14
rpc/http.go
|
|
@ -168,13 +168,21 @@ func newClientTransportHTTP(endpoint string, cfg *clientConfig) reconnectFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cleanlyCloseBody avoids sending unnecessary RST_STREAM and PING frames by
|
||||||
|
// ensuring the whole body is read before being closed.
|
||||||
|
// See https://blog.cloudflare.com/go-and-enhance-your-calm/#reading-bodies-in-go-can-be-unintuitive
|
||||||
|
func cleanlyCloseBody(body io.ReadCloser) error {
|
||||||
|
io.Copy(io.Discard, body)
|
||||||
|
return body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error {
|
func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error {
|
||||||
hc := c.writeConn.(*httpConn)
|
hc := c.writeConn.(*httpConn)
|
||||||
respBody, err := hc.doRequest(ctx, msg)
|
respBody, err := hc.doRequest(ctx, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer respBody.Close()
|
defer cleanlyCloseBody(respBody)
|
||||||
|
|
||||||
var resp jsonrpcMessage
|
var resp jsonrpcMessage
|
||||||
batch := [1]*jsonrpcMessage{&resp}
|
batch := [1]*jsonrpcMessage{&resp}
|
||||||
|
|
@ -191,7 +199,7 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer respBody.Close()
|
defer cleanlyCloseBody(respBody)
|
||||||
|
|
||||||
var respmsgs []*jsonrpcMessage
|
var respmsgs []*jsonrpcMessage
|
||||||
if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil {
|
if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil {
|
||||||
|
|
@ -236,7 +244,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos
|
||||||
if _, err := buf.ReadFrom(resp.Body); err == nil {
|
if _, err := buf.ReadFrom(resp.Body); err == nil {
|
||||||
body = buf.Bytes()
|
body = buf.Bytes()
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
cleanlyCloseBody(resp.Body)
|
||||||
return nil, HTTPError{
|
return nil, HTTPError{
|
||||||
Status: resp.Status,
|
Status: resp.Status,
|
||||||
StatusCode: resp.StatusCode,
|
StatusCode: resp.StatusCode,
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ func confirmHTTPRequestYieldsStatusCode(t *testing.T, method, contentType, body
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("request failed: %v", err)
|
t.Fatalf("request failed: %v", err)
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
cleanlyCloseBody(resp.Body)
|
||||||
confirmStatusCode(t, resp.StatusCode, expectedStatusCode)
|
confirmStatusCode(t, resp.StatusCode, expectedStatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue