Content-Length header is not set in Golang http client request using PUT method

15,332

Solution 1

I was incorrect about Content-Length not being sent, I just wasn't seeing it when using httputil.DumpRequest.

Solution here was to use httputil.DumpRequestOut which properly shows the Content-Length header (and others). It means there is something else going on with my program that is causing etcd to set empty values. If I figure that out I'll update with that solution as well.

Solution 2

If you are saying header Content-Length is not set (actually it is set automatically just not showed up when dumping it), it works as designed because the following headers are excluded in httputil.DumpRequest() even you set them explicitly:

  • Host
  • Content-Length
  • Transfer-Encoding
  • Trailer

see line 317 of go/src/net/http/httputil/dump.go.

If you do send the request instead dumping it, you will see the header Content-Length sent along with User-Agent and Accept-Encoding.

Share:
15,332
Austen Hoogen
Author by

Austen Hoogen

Updated on June 21, 2022

Comments

  • Austen Hoogen
    Austen Hoogen about 2 years

    I'm using Golang 1.4.2 (built from source) and when I try to make an HTTP PUT request via http.Client.Do() the Content-Length header is missing from the request. All my other headers are sent... Am I doing something wrong? When I make the same request via CURL the content-length header is sent. My requests are being made to etcd server, which is setting all my keys to empty values. While this is somewhat novel, it is hardly useful. :)

    http://play.golang.org/p/pIoB--bXUT

    package main
    
    import (
        "bytes"
        "fmt"
        "net/http"
        "net/http/httputil"
        "net/url"
        "strconv"
    )
    
    func main() {
        put := url.Values{}
        put.Set("value", "WHOAH here is my stuff")
        put.Add("ttl","")
        encode := put.Encode()
        req, _ := http.NewRequest("PUT", "http://localhost:2379/v2/keys/somekey", bytes.NewBufferString(encode))
        req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
        req.Header.Add("Content-Length", strconv.Itoa(len(encode)))
        req.Header.Add("X-Content-Length", strconv.Itoa(len(encode)))
        dump, _ := httputil.DumpRequest(req, true)
        fmt.Println(string(dump))
    }
    

    yields

    PUT /v2/keys/somekey HTTP/1.1
    Host: localhost
    Content-Type: application/x-www-form-urlencoded
    X-Content-Length: 33
    
    ttl=&value=WHOAH+here+is+my+stuff