1 回答
TA贡献1906条经验 获得超3个赞
https://pkg.go.dev/net/http#Server.MaxHeaderBytes可以为您处理。
此演示在 Playground 中无法可靠运行(拨号或连接超时)。不过,它似乎在本地可靠地工作,这让我猜这是操场行为的产物。
我们将启动一个具有较低 MaxHeaderBytes 的 http Server,然后大大超过它。
package main
import (
"context"
"fmt"
"io"
"net"
"net/http"
"strings"
"time"
)
func main() {
res := make(chan error)
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%+v", r.Header)
})
s := &http.Server{
Addr: "127.0.0.1:8103",
Handler: mux,
ReadTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
MaxHeaderBytes: 2048,
}
if l, err := net.Listen("tcp", "127.0.0.1:8103"); err != nil {
panic(fmt.Errorf("Couldn't listen: %w", err))
} else {
go func() {
res <- s.Serve(l)
}()
}
client := &http.Client{
Timeout: 3 * time.Second,
}
req, err := http.NewRequest("GET", "http://127.0.0.1:8103", nil)
if err != nil {
panic(err)
}
req.Header.Add("X-Long-Header", strings.Repeat("long ", 2048)+"header")
resp, err := client.Do(req)
if err != nil {
panic(fmt.Errorf("HTTP Request failed: %w", err))
}
fmt.Println(resp)
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(fmt.Errorf("Could not read response body: %w", err))
}
fmt.Println("Body:", string(body))
s.Shutdown(context.Background())
<-res
}
在这里,我设置MaxHeaderBytes为一个相当小的值。我传递的价值远远超过我的X-Long-Header: long long long .... header. 如果您可以让 Playground 正常工作(只需运行几次)或在本地运行,您将获得:
&{431 Request Header Fields Too Large 431 HTTP/1.1 1 1 map[Content-Type:[text/plain; charset=utf-8]] 0xc00001a180 -1 [] true false map[] 0xc000176000 <nil>}
Body: 431 Request Header Fields Too Large
如您所见,如果所有标题都太大,将自动生成 431。
如果特定标头太长,您的处理程序本身可能适合以 431 响应,但是当您的处理程序通过http.Request时,标头已被接收。尝试自己计算标头的总长度然后基于此以 431 响应是没有意义的。
此外,标准标题可能会来来去去,因此过于严格地限制整体标题大小是不明智的。
相反,请检查您关心的任何单个标题。
- 1 回答
- 0 关注
- 135 浏览
添加回答
举报