如何在 Golang 中获取 request.Header 的大小(以字节为单位)?

我需要找到request.Header请求*http.Request类型的大小:


req, err := http.NewRequest("GET", "/", nil)

cookie := &http.Cookie{Name: "foo", Value: "bar"}

req.AddCookie(cookie)

我试过了


len(request.Header) # returned the number of elements in the map -- essentially the number of headers


for k, v := range req.Header {

  bytesSize += len(k) + len(v)

}

这也不起作用,因为v它是一张地图。


我发现计算地图问题的内存占用(或字节长度),但答案似乎相当复杂(它们的地图值是整数,这里不是这种情况)。


更新:实际上这里是定义,type Header map[string][]string所以我们不必使用递归。


慕桂英546537
浏览 138回答 1
1回答

一只名叫tom的猫

https://pkg.go.dev/net/http#Server.MaxHeaderBytes可以为您处理。此演示在 Playground 中无法可靠运行(拨号或连接超时)。不过,它似乎在本地可靠地工作,这让我猜这是操场行为的产物。我们将启动一个具有较低 MaxHeaderBytes 的 http Server,然后大大超过它。package mainimport (&nbsp; &nbsp; "context"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "io"&nbsp; &nbsp; "net"&nbsp; &nbsp; "net/http"&nbsp; &nbsp; "strings"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; res := make(chan error)&nbsp; &nbsp; mux := http.NewServeMux()&nbsp; &nbsp; mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(w, "%+v", r.Header)&nbsp; &nbsp; })&nbsp; &nbsp; s := &http.Server{&nbsp; &nbsp; &nbsp; &nbsp; Addr:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"127.0.0.1:8103",&nbsp; &nbsp; &nbsp; &nbsp; Handler:&nbsp; &nbsp; &nbsp; &nbsp; mux,&nbsp; &nbsp; &nbsp; &nbsp; ReadTimeout:&nbsp; &nbsp; 1 * time.Second,&nbsp; &nbsp; &nbsp; &nbsp; WriteTimeout:&nbsp; &nbsp;1 * time.Second,&nbsp; &nbsp; &nbsp; &nbsp; MaxHeaderBytes: 2048,&nbsp; &nbsp; }&nbsp; &nbsp; if l, err := net.Listen("tcp", "127.0.0.1:8103"); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(fmt.Errorf("Couldn't listen: %w", err))&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res <- s.Serve(l)&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; }&nbsp; &nbsp; client := &http.Client{&nbsp; &nbsp; &nbsp; &nbsp; Timeout: 3 * time.Second,&nbsp; &nbsp; }&nbsp; &nbsp; req, err := http.NewRequest("GET", "http://127.0.0.1:8103", nil)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; req.Header.Add("X-Long-Header", strings.Repeat("long ", 2048)+"header")&nbsp; &nbsp; resp, err := client.Do(req)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(fmt.Errorf("HTTP Request failed: %w", err))&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println(resp)&nbsp; &nbsp; body, err := io.ReadAll(resp.Body)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(fmt.Errorf("Could not read response body: %w", err))&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("Body:", string(body))&nbsp; &nbsp; s.Shutdown(context.Background())&nbsp; &nbsp; <-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 响应是没有意义的。此外,标准标题可能会来来去去,因此过于严格地限制整体标题大小是不明智的。相反,请检查您关心的任何单个标题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go