Skip to content

Request.Marshal() drains the body and drops ProxyURL / ResponseCharacterEncoding #912

Description

@Noethix55555

Summary

Request.Marshal() does not round-trip a request faithfully. Two distinct facets:

Facet A: Marshal() destroys the original body (non-idempotent)

In Marshal(), the body is read with io.ReadAll(r.Body) but never restored:

if r.Body != nil {
    body, err = io.ReadAll(r.Body)
    ...
}

After Marshal() returns, r.Body is fully consumed. As a result:

  • Calling Marshal() a second time produces a request with an empty body.
  • Calling Do() or Retry() after a Marshal() sends an empty body.

Facet B: ProxyURL and ResponseCharacterEncoding are silently dropped

The internal serializableRequest struct omits ProxyURL and ResponseCharacterEncoding, so Marshal() -> UnmarshalRequest() loses them. ResponseCharacterEncoding is a user-set, pre-fetch field consumed by fixCharset; losing it on a queued or persisted request changes behavior (silently falls back to auto-detect).

Reproduction

  • Marshal the same request twice -> the second result has "Body":"".
  • Set ProxyURL / ResponseCharacterEncoding, Marshal then UnmarshalRequest -> both come back empty.

Fix

Restore r.Body after reading, and add ProxyURL + ResponseCharacterEncoding to serializableRequest (populated in Marshal, restored in UnmarshalRequest). PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions