diff --git a/sdk/internal/CHANGELOG.md b/sdk/internal/CHANGELOG.md index 25580ddcf481..dc3c6d7993c3 100644 --- a/sdk/internal/CHANGELOG.md +++ b/sdk/internal/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +* Prevent `exported.Payload` from panicking in the rare event `*http.Response.Body` is `nil`. + ### Other Changes ## 1.5.1 (2023-12-06) diff --git a/sdk/internal/exported/exported.go b/sdk/internal/exported/exported.go index d4ed6ccc8ad4..9948f604b301 100644 --- a/sdk/internal/exported/exported.go +++ b/sdk/internal/exported/exported.go @@ -39,6 +39,11 @@ type PayloadOptions struct { // Subsequent reads will access the cached value. // Exported as runtime.Payload() WITHOUT the opts parameter. func Payload(resp *http.Response, opts *PayloadOptions) ([]byte, error) { + if resp.Body == nil { + // this shouldn't happen in real-world scenarios as a + // response with no body should set it to http.NoBody + return nil, nil + } modifyBytes := func(b []byte) []byte { return b } if opts != nil && opts.BytesModifier != nil { modifyBytes = opts.BytesModifier diff --git a/sdk/internal/exported/exported_test.go b/sdk/internal/exported/exported_test.go index f1de07d4a63e..3f2273c6e5be 100644 --- a/sdk/internal/exported/exported_test.go +++ b/sdk/internal/exported/exported_test.go @@ -61,6 +61,12 @@ func TestPayloadBytesModifier(t *testing.T) { require.EqualValues(t, newPayload, string(b)) } +func TestPayloadNilBody(t *testing.T) { + b, err := Payload(&http.Response{}, nil) + require.NoError(t, err) + require.Nil(t, b) +} + func TestNopClosingBytesReader(t *testing.T) { const val1 = "the data" ncbr := &nopClosingBytesReader{s: []byte(val1)}