http - net/http 服务器不发送 100 Continue 除非客户端发送 Transfer-Encoding : chunked or nonzero Content-Length

标签 http go

我正在用 Go 编写一个 HTTP 服务器,它将接收来自客户端的请求 Expect: 100-continue标题。但是,net/http 服务器似乎没有发送 HTTP/1.1 100 Continue除非客户端也发送 Transfer-Encoding: Chunked header ,某些客户端(例如,带有 icecast:// 目标的 ffmpeg)没有。
这是一个最小的服务器,它写入 bytes.Buffer (我用更复杂的服务器重现了相同的行为,例如,使用 io.Copy() 写入文件):

func main() {
    http.HandleFunc("/", func(writer http.ResponseWriter, r *http.Request) {
        log.Printf("Expect header: %v\n", r.Header.Get("Expect"))
        log.Printf("Transfer-Encoding header: %v\n", r.Header.Get("Transfer-Encoding"))

        buf := new(bytes.Buffer)
        defer func() {
            log.Printf("Buffer size: %d\n", buf.Len())
        }()
        defer r.Body.Close()

        log.Println("Writing.")
        io.Copy(buf, r.Body)
    })

    log.Fatal(http.ListenAndServe(":3948", nil))
}
这是两个 HTTP 对话(通过 telnet)的抄本,其中服务器在一个中发送 100 而在另一个中不发送:
PUT /telnetlol HTTP/1.1
Host: localhost
Expect: 100-continue

HTTP/1.1 200 OK
Date: Thu, 18 Mar 2021 10:59:09 GMT
Content-Length: 0
PUT /telnetlol HTTP/1.1
Host: localhost
Expect: 100-continue
Transfer-Encoding: chunked

HTTP/1.1 100 Continue

test
HTTP/1.1 200 OK
Date: Thu, 18 Mar 2021 10:59:35 GMT
Content-Length: 0
Connection: close
这是 Go 中的错误,还是我误解了 HTTP 规范?规范写道:

Upon receiving a request which includes an Expect request-header field with the "100-continue" expectation, an origin server MUST respond with 100 (Continue) status and continue to read from the input stream, or respond with a final status code. The origin server MUST NOT wait for the request body before sending the 100 (Continue) response.


编辑:发送非零 Content-Length初始请求中的 header 也使服务器回复 100 Continue . (虽然,如果我正确理解规范,它仍然应该回复继续,不管。)

最佳答案

net/http 服务器正确处理请求:

PUT /telnetlol HTTP/1.1
Host: localhost
Expect: 100-continue
有了这个回应:
HTTP/1.1 200 OK
Date: Thu, 18 Mar 2021 10:59:09 GMT
Content-Length: 0
根据 RFC 7230 3.3,该请求没有消息正文:

The presence of a message body in a request is signaled by a Content-Length or Transfer-Encoding header field.


当每个 RFC 7231 5.1.1 没有消息正文时,服务器可能会忽略发送 100 响应。 :

A server MAY omit sending a 100 (Continue) response if it has already received some or all of the message body for the corresponding request, or if the framing indicates that there is no message body.


此外,根据 RFC 7231 5.1.1,客户端请求是错误的:

A client MUST NOT generate a 100-continue expectation in a request that does not include a message body.

关于http - net/http 服务器不发送 100 Continue 除非客户端发送 Transfer-Encoding : chunked or nonzero Content-Length,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66689843/

相关文章:

php - 如果没有后备数据库,您将如何实现基于 FORM 的身份验证?

Java HTTP 请求偶尔挂起

json - 在 Go 中表示此 JSON 的最佳方式?

json - Go:获取损坏的 JSON 字段名称

Go: "instance"在此 block 中重新声明

http - 在 Dart 中向同一服务器发出多个请求的最佳方法是什么?

java - HTTP 传输编码 "gzip, chunked"未正确解释

html - 使用 meta http-equiv 标签重定向时避免将页面添加到浏览器历史记录

amazon-web-services - 使用 Go SDK 检查 AWS Data Pipeline 的状态

json - 解析大型单行 JSON 而无需将整个文件加载到内存中