@@ -554,6 +554,12 @@ func WithVersion(version string) RequestOption {
554554 }
555555}
556556
557+ var requestBufferPool = sync.Pool {
558+ New : func () any {
559+ return new (bytes.Buffer )
560+ },
561+ }
562+
557563// NewRequest creates an API request. A relative URL can be provided in urlStr,
558564// in which case it is resolved relative to the BaseURL of the Client.
559565// Relative URLs should always be specified without a preceding slash. If
@@ -573,18 +579,27 @@ func (c *Client) NewRequest(ctx context.Context, method, urlStr string, body any
573579 return nil , err
574580 }
575581
576- var buf io.ReadWriter
582+ var reqBody io.Reader
577583 if body != nil {
578- buf = & bytes.Buffer {}
584+ buf := requestBufferPool . Get ().( * bytes.Buffer )
579585 enc := json .NewEncoder (buf )
580586 enc .SetEscapeHTML (false )
581587 err := enc .Encode (body )
582588 if err != nil {
589+ buf .Reset ()
590+ requestBufferPool .Put (buf )
583591 return nil , err
584592 }
593+
594+ b := make ([]byte , buf .Len ())
595+ copy (b , buf .Bytes ())
596+ reqBody = bytes .NewReader (b )
597+
598+ buf .Reset ()
599+ requestBufferPool .Put (buf )
585600 }
586601
587- req , err := http .NewRequestWithContext (ctx , method , u .String (), buf )
602+ req , err := http .NewRequestWithContext (ctx , method , u .String (), reqBody )
588603 if err != nil {
589604 return nil , err
590605 }
@@ -1114,12 +1129,24 @@ func (c *Client) Do(req *http.Request, v any) (*Response, error) {
11141129 case io.Writer :
11151130 _ , err = io .Copy (v , resp .Body )
11161131 default :
1117- decErr := json .NewDecoder (resp .Body ).Decode (v )
1118- if decErr == io .EOF {
1119- decErr = nil // ignore EOF errors caused by empty response body
1120- }
1121- if decErr != nil {
1122- err = decErr
1132+ respBuf := requestBufferPool .Get ().(* bytes.Buffer )
1133+ defer func () {
1134+ respBuf .Reset ()
1135+ requestBufferPool .Put (respBuf )
1136+ }()
1137+
1138+ _ , readErr := respBuf .ReadFrom (resp .Body )
1139+ if readErr != nil {
1140+ err = readErr
1141+ } else if respBuf .Len () > 0 {
1142+ b := respBuf .Bytes ()
1143+ decErr := json .Unmarshal (b , v )
1144+ if decErr != nil && len (bytes .TrimSpace (b )) == 0 {
1145+ decErr = nil // ignore errors caused by empty response body
1146+ }
1147+ if decErr != nil {
1148+ err = decErr
1149+ }
11231150 }
11241151 }
11251152 return resp , err
0 commit comments