@@ -33,26 +33,17 @@ func HandleAPISuccessResponse(resp *http.Response, out interface{}, log logger.L
33
33
return handleDeleteRequest (resp , log )
34
34
}
35
35
36
- // Create a buffer to hold a copy of the response body
37
- var bodyBuffer bytes.Buffer
38
-
39
- // Use TeeReader to read the response body and simultaneously write it to the buffer
40
- teeReader := io .TeeReader (resp .Body , & bodyBuffer )
41
-
42
- // log the response body
43
- logResponseDetails (resp , bodyBuffer .Bytes (), log )
36
+ // Log headers and set up deferred body logging.
37
+ deferBodyLog := logResponseDetails (resp , log )
38
+ defer deferBodyLog () // Ensure body logging happens at the end of this function.
44
39
45
40
mimeType , _ := ParseContentTypeHeader (resp .Header .Get ("Content-Type" ))
46
41
contentDisposition := resp .Header .Get ("Content-Disposition" )
47
42
48
43
if handler , ok := responseUnmarshallers [mimeType ]; ok {
49
- // Replace the response body with a new reader that reads from the buffer, allowing it to be read again
50
- resp .Body = io .NopCloser (& bodyBuffer )
51
- return handler (teeReader , out , log , mimeType ) // Use teeReader here to unmarshal from the original response body
44
+ return handler (resp .Body , out , log , mimeType )
52
45
} else if isBinaryData (mimeType , contentDisposition ) {
53
- // Replace the response body with a new reader that reads from the buffer, allowing it to be read again
54
- resp .Body = io .NopCloser (& bodyBuffer )
55
- return handleBinaryData (teeReader , log , out , mimeType , contentDisposition ) // Use teeReader here to handle binary data
46
+ return handleBinaryData (resp .Body , log , out , mimeType , contentDisposition )
56
47
} else {
57
48
errMsg := fmt .Sprintf ("unexpected MIME type: %s" , mimeType )
58
49
log .Error ("Unmarshal error" , zap .String ("content type" , mimeType ), zap .Error (errors .New (errMsg )))
@@ -74,14 +65,22 @@ func handleDeleteRequest(resp *http.Response, log logger.Logger) error {
74
65
return fmt .Errorf ("DELETE request failed, status code: %d" , resp .StatusCode )
75
66
}
76
67
77
- // Adjusted logResponseDetails to handle a potential nil bodyBytes.
78
- func logResponseDetails (resp * http.Response , bodyBytes []byte , log logger.Logger ) {
79
- // Conditional logging if bodyBytes is not nil.
80
- if bodyBytes != nil {
68
+ // logResponseDetails logs the raw response details and returns a deferred function to log the response body.
69
+ func logResponseDetails (resp * http.Response , log logger.Logger ) func () {
70
+ log .Debug ("HTTP Response Headers" , zap .Any ("Headers" , resp .Header ))
71
+
72
+ // Returning a deferred function to log the body.
73
+ return func () {
74
+ bodyBytes , err := io .ReadAll (resp .Body )
75
+ if err != nil {
76
+ log .Error ("Error reading response body for logging" , zap .Error (err ))
77
+ return
78
+ }
81
79
log .Debug ("Raw HTTP Response" , zap .String ("Body" , string (bodyBytes )))
80
+
81
+ // After logging, reset resp.Body so it can be read again.
82
+ resp .Body = io .NopCloser (bytes .NewBuffer (bodyBytes ))
82
83
}
83
- // Logging headers remains unchanged.
84
- log .Debug ("HTTP Response Headers" , zap .Any ("Headers" , resp .Header ))
85
84
}
86
85
87
86
// unmarshalJSON unmarshals JSON content from an io.Reader into the provided output structure.
0 commit comments