Trouble with Transfer-Encoding: chunked on HTTP client requests

1,749 views
Skip to first unread message

achille...@gmail.com

unread,
Sep 8, 2015, 1:49:49 PM9/8/15
to golang-nuts
Hi all,

I've been trying to get "Transfer-Encoding: chunked" to work on HTTP client requests but it looks like the code is not doing what the documentation says, here's a quick example showing the issue:

package main

import (
    "io/ioutil"
    "net/http"
    "net/url"
    "os"
    "strings"
)

func main() {
    (&http.Request{
        Method: "PUT",
        URL: &url.URL{
            Scheme: "http",
            Host:   "localhost:8050",
            Path:   "/",
        },
        Header: http.Header{
            "Content-Type": {"application/json"},
        },
        ContentLength: -1,
        Body:          ioutil.NopCloser(strings.NewReader("[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]")),
    }).Write(os.Stdout)
}

Which outputs:

PUT / HTTP/1.1
Host: localhost:8050
User-Agent: Go-http-client/1.1
Content-Type: application/json

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


As you see, neither "Content-Length: ..." nor "Transfer-Encoding: chunked" is set, so the body being written is not considered part of the request by the server.

The piece of documentation I'm referring to is:

    func (r *Request) Write(w io.Writer) error
    ...

     If Body is present, Content-Length is <= 0 and TransferEncoding hasn't been set to "identity", Write adds "Transfer-Encoding: chunked" to the header. Body is closed after it is sent.


I've tried setting ContentLength to 0 as well but it that case the body is not set at all (which is not what I understand the documentation is saying).

I've tried forcing TransferEncoding to chunked in the request object but the result was the same.

I dug into the net/http package source code and it really looks like this should be working so I'm not sure what's wrong here.


My question would be, am I misusing the net/http package?
If so then could someone point me to some resources that show how to do this properly?


Cheers you all!

Brad Fitzpatrick

unread,
Sep 8, 2015, 1:53:14 PM9/8/15
to achille...@gmail.com, golang-nuts
net/http.Request.Write is a pretty low-level method. Any reason you aren't using the Transport or Client types, which is the normal way to make HTTP requests?


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

achille...@gmail.com

unread,
Sep 8, 2015, 1:58:44 PM9/8/15
to golang-nuts, achille...@gmail.com
Indeed, I am using a http.Client with the default transport and passing this exact same request, and I'm observing the same behavior on what is received server-side. I wanted to give a simple example of the issue so that it can be reproduced. Also by reading the sources it looks like the default transport uses Request.Write as well.
Plus it doesn't change the fact that the documentation is confusing here.

Also I'm using Go 1.5 on OS X.
Message has been deleted

achille...@gmail.com

unread,
Sep 8, 2015, 1:59:01 PM9/8/15
to golang-nuts, achille...@gmail.com
Indeed, I am using a http.Client with the default transport and passing this exact same request, and I'm observing the same behavior on what is received server-side. I wanted to give a simple example of the issue so that it can be reproduced. Also by reading the sources it looks like the default transport uses Request.Write as well.
Plus it doesn't change the fact that the documentation is confusing here.

Also I'm using Go 1.5 on OS X.

On Tuesday, September 8, 2015 at 10:53:14 AM UTC-7, bradfitz wrote:

Piers

unread,
Sep 8, 2015, 2:19:59 PM9/8/15
to golang-nuts, achille...@gmail.com
The chunked behaviour is conditional on atLeastHTTP11 which is false for a default http.Request (minor = 0) for a literally constructed http.Request. http.NewRequest sets it to 1.

Write prints an HTTP/1.1 first line always.

Piers

unread,
Sep 8, 2015, 2:23:43 PM9/8/15
to golang-nuts, achille...@gmail.com
Actually ProtoMajor is probably zero too.

This works:

achille...@gmail.com

unread,
Sep 8, 2015, 2:40:27 PM9/8/15
to golang-nuts, achille...@gmail.com
Setting ProtoMajor and ProtoMinor did the trick, thanks a lot for your help guys!

achille...@gmail.com

unread,
Sep 8, 2015, 2:40:56 PM9/8/15
to golang-nuts, achille...@gmail.com
Setting ProtoMajor and ProtoMinor did the trick, Thanks a lot for your help guys!


On Tuesday, September 8, 2015 at 11:23:43 AM UTC-7, Piers wrote:
Reply all
Reply to author
Forward
0 new messages