Skip to content

net/http: Wrong ContentLength when use http.Request.Body as the third parameter of http.NewRequest() #11493

Closed
@rtxu

Description

@rtxu
func (h *RedirectHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    body, _ := r.Body.(io.Reader)
    rLogger.Infof("%T", body)   // print: *http.body

    req, _ := http.NewRequest(r.Method, h.Dest+r.URL.String(), r.Body)
    rLogger.Infof("%d", req.ContentLength)  // print: 0

    ......
}

Here's the net/http/request.go implementation:

// NewRequest returns a new Request given a method, URL, and optional body.
//
// If the provided body is also an io.Closer, the returned
// Request.Body is set to body and will be closed by the Client
// methods Do, Post, and PostForm, and Transport.RoundTrip.
func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
        u, err := url.Parse(urlStr)
        if err != nil {
                return nil, err
        }
        rc, ok := body.(io.ReadCloser)
        if !ok && body != nil {
                rc = ioutil.NopCloser(body)
        }
        req := &Request{
                Method:     method,
                URL:        u,
                Proto:      "HTTP/1.1",
                ProtoMajor: 1,
                ProtoMinor: 1,
                Header:     make(Header),
                Body:       rc,
                Host:       u.Host,
        }
        if body != nil {
                switch v := body.(type) {
                case *bytes.Buffer:
                        req.ContentLength = int64(v.Len())
                case *bytes.Reader:
                        req.ContentLength = int64(v.Len())
                case *strings.Reader:
                        req.ContentLength = int64(v.Len())
                }
        }

        return req, nil
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions