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 關注
- 183 瀏覽
添加回答
舉報