没有为具有空/无负载的 PATCH 请求设置 Content-Length 标头 - GoLang

我观察到 Content-Length 标头没有为具有空/nil 有效负载的 PATCH 请求设置。即使我们手动设置它,req.Header.Set("content-length", "0")它实际上并没有在发出的请求中设置。这种奇怪的行为(Go bug?)仅发生在 PATCH 请求中,并且仅在有效负载为空或 nil(或设置为 http.NoBody)时发生


package main


import (

    "fmt"

    "io/ioutil"

    "net/http"

    "strings"

)


func main() {


    url := "http://localhost:9999"

    method := "PATCH"


    payload := strings.NewReader("")

    client := &http.Client {

    }

    req, err := http.NewRequest(method, url, payload)


    if err != nil {

        fmt.Println(err)

    }

    req.Header.Set("Authorization", "Bearer my-token")

    req.Header.Set("Content-Length", "0") //this is not honoured


    res, err := client.Do(req)

    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)


    fmt.Println(string(body))

}

即使在最新的 go 版本中,这也是可重现的1.15。只需在一个简单的 http 服务器上运行上面的代码,然后自己看看。


是否有任何解决方案/解决方法可以发送 Content-Length 设置为 0 的 PATCH 请求?


沧海一幻觉
浏览 152回答 1
1回答

慕姐8265434

您可以通过将 TransferEncoding 设置为如下方式来告诉 HTTP 客户端包含Content-Length值为 0 的标头:identity  url := "http://localhost:9999"  method := "PATCH"    client := &http.Client{}  req, err := http.NewRequest(method, url, http.NoBody)  if err != nil {    panic(err)  }   req.TransferEncoding = []string{"identity"}   req.Header.Set("Authorization", "Bearer my-token")  //  req.Header.Set("Content-Length", "0")请注意对原始代码的以下更改:重要的是:req.TransferEncoding = []string{"identity"}指定空主体的惯用方式:(http.NoBody对发送长度没有影响)注释掉req.Header.Set("Content-Length", "0"),客户自己填写也更改为出现错误时恐慌,您可能不想继续的传输编码identity没有写入请求,所以除了 header 之外,Content-Length = 0请求看起来和以前一样。不幸的是,这没有记录(请随时向 Go 团队提出问题),但可以在以下代码中看到:繁琐的细节:transferWriter.writeHeader检查以下内容以写入Content-Length标头:    // Write Content-Length and/or Transfer-Encoding whose values are a    // function of the sanitized field triple (Body, ContentLength,    // TransferEncoding)    if t.shouldSendContentLength() {        if _, err := io.WriteString(w, "Content-Length: "); err != nil {            return err        }        if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {            return err        }反过来,shouldCheckContentLength在长度为零的情况下查看传输编码:    if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {        if t.Method == "GET" || t.Method == "HEAD" {            return false        }        return true    }isIdentity验证这TransferEncoding正是:_ []string{"identity"}func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }) 
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go