Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
rtxu opened this issue Jul 1, 2015 · 1 comment

Comments

Projects
None yet
3 participants
@rtxu
Copy link

commented Jul 1, 2015

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
}
@bradfitz

This comment has been minimized.

Copy link
Member

commented Jul 1, 2015

NewRequest has a few special cases for common types in the standard library with known lengths, but it doesn't do everything. You'll have to set your own lengths when it matters. Usually chunked encoding should be good enough.

@bradfitz bradfitz closed this Jul 1, 2015

@mikioh mikioh changed the title Wrong ContentLength when use http.Request.Body as the third parameter of http.NewRequest() net/http: Wrong ContentLength when use http.Request.Body as the third parameter of http.NewRequest() Jul 2, 2015

@golang golang locked and limited conversation to collaborators Jul 1, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.