在使用 Golang 的 HTTP 客户端请求中,使用 PUT 方法时未设置 Content-Length 头。

huangapple go评论94阅读模式
英文:

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

问题

我正在使用从源代码构建的Golang 1.4.2版本,并且当我尝试通过http.Client.Do()方法进行HTTP PUT请求时,请求中缺少Content-Length头。我发送的所有其他头都正常。我是否做错了什么?当我使用CURL发送相同的请求时,会发送Content-Length头。我的请求是发送到etcd服务器的,该服务器将所有键设置为空值。虽然这有点新奇,但几乎没有用处。 在使用 Golang 的 HTTP 客户端请求中,使用 PUT 方法时未设置 Content-Length 头。

以下是代码的翻译:

package main

import (
	"bytes"
	"fmt"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
)

func main() {
	put := url.Values{}
	put.Set("value", "这是我的内容")
	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))
}

输出结果为:

PUT /v2/keys/somekey HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
X-Content-Length: 33

ttl=&value=这是我的内容
英文:

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. 在使用 Golang 的 HTTP 客户端请求中,使用 PUT 方法时未设置 Content-Length 头。

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

答案1

得分: 4

如果你说头部Content-Length没有设置(实际上它是自动设置的,只是在转储时没有显示出来),这是设计上的工作原理,因为即使你明确设置了以下头部,在httputil.DumpRequest()中也会被排除:

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

请参考go/src/net/http/httputil/dump.goline 317

如果你发送请求而不是转储它,你将看到头部Content-LengthUser-AgentAccept-Encoding一起发送。

英文:

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.

答案2

得分: 4

我对于 Content-Length 没有被发送的观点是错误的,当我使用 httputil.DumpRequest 时,我只是没有看到它。

解决方法是使用 httputil.DumpRequestOut,它可以正确显示 Content-Length 头部(以及其他头部)。这意味着我的程序中还有其他原因导致 etcd 设置为空值。如果我找到了解决方法,我会更新并提供解决方案。

英文:

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.

huangapple
  • 本文由 发表于 2015年8月6日 16:58:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/31851219.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定