Browse code

client: ensureReaderClosed: small optimizations

Skip draining for HEAD requests and empty responses.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2025/11/15 10:00:27
Showing 2 changed files
... ...
@@ -349,15 +349,21 @@ func jsonEncode(data any) (io.Reader, error) {
349 349
 }
350 350
 
351 351
 func ensureReaderClosed(response *http.Response) {
352
-	if response != nil && response.Body != nil {
353
-		// Drain up to 512 bytes and close the body to let the Transport reuse the connection
354
-		// see https://github.com/google/go-github/pull/317/files#r57536827
355
-		//
356
-		// TODO(thaJeztah): see if this optimization is still needed, or already implemented in stdlib,
357
-		//   and check if context-cancellation should handle this as well. If still needed, consider
358
-		//   wrapping response.Body, or returning a "closer()" from [Client.sendRequest] and related
359
-		//   methods.
360
-		_, _ = io.CopyN(io.Discard, response.Body, 512)
361
-		_ = response.Body.Close()
352
+	if response == nil || response.Body == nil {
353
+		return
362 354
 	}
355
+	if response.ContentLength == 0 || (response.Request != nil && response.Request.Method == http.MethodHead) {
356
+		// No need to drain head requests or zero-length responses.
357
+		_ = response.Body.Close()
358
+		return
359
+	}
360
+	// Drain up to 512 bytes and close the body to let the Transport reuse the connection
361
+	// see https://github.com/google/go-github/pull/317/files#r57536827
362
+	//
363
+	// TODO(thaJeztah): see if this optimization is still needed, or already implemented in stdlib,
364
+	//   and check if context-cancellation should handle this as well. If still needed, consider
365
+	//   wrapping response.Body, or returning a "closer()" from [Client.sendRequest] and related
366
+	//   methods.
367
+	_, _ = io.CopyN(io.Discard, response.Body, 512)
368
+	_ = response.Body.Close()
363 369
 }
... ...
@@ -349,15 +349,21 @@ func jsonEncode(data any) (io.Reader, error) {
349 349
 }
350 350
 
351 351
 func ensureReaderClosed(response *http.Response) {
352
-	if response != nil && response.Body != nil {
353
-		// Drain up to 512 bytes and close the body to let the Transport reuse the connection
354
-		// see https://github.com/google/go-github/pull/317/files#r57536827
355
-		//
356
-		// TODO(thaJeztah): see if this optimization is still needed, or already implemented in stdlib,
357
-		//   and check if context-cancellation should handle this as well. If still needed, consider
358
-		//   wrapping response.Body, or returning a "closer()" from [Client.sendRequest] and related
359
-		//   methods.
360
-		_, _ = io.CopyN(io.Discard, response.Body, 512)
361
-		_ = response.Body.Close()
352
+	if response == nil || response.Body == nil {
353
+		return
362 354
 	}
355
+	if response.ContentLength == 0 || (response.Request != nil && response.Request.Method == http.MethodHead) {
356
+		// No need to drain head requests or zero-length responses.
357
+		_ = response.Body.Close()
358
+		return
359
+	}
360
+	// Drain up to 512 bytes and close the body to let the Transport reuse the connection
361
+	// see https://github.com/google/go-github/pull/317/files#r57536827
362
+	//
363
+	// TODO(thaJeztah): see if this optimization is still needed, or already implemented in stdlib,
364
+	//   and check if context-cancellation should handle this as well. If still needed, consider
365
+	//   wrapping response.Body, or returning a "closer()" from [Client.sendRequest] and related
366
+	//   methods.
367
+	_, _ = io.CopyN(io.Discard, response.Body, 512)
368
+	_ = response.Body.Close()
363 369
 }