亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Golang 中獲取 request.Header 的大小(以字節為單位)?

如何在 Golang 中獲取 request.Header 的大小(以字節為單位)?

Go
慕桂英546537 2022-10-10 16:52:25
我需要找到request.Header請求*http.Request類型的大?。簉eq, 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所以我們不必使用遞歸。
查看完整描述

1 回答

?
一只名叫tom的貓

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 響應是沒有意義的。


此外,標準標題可能會來來去去,因此過于嚴格地限制整體標題大小是不明智的。


相反,請檢查您關心的任何單個標題。


查看完整回答
反對 回復 2022-10-10
  • 1 回答
  • 0 關注
  • 183 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號