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

@rtxu
Copy link

rtxu 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
Copy link
Contributor

bradfitz 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 as completed 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.
Projects
None yet
Development

No branches or pull requests

3 participants