go - 如何在 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
所以我们不必使用递归。
解决方案
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 响应是没有意义的。
此外,标准标题可能会来来去去,因此过于严格地限制整体标题大小是不明智的。
相反,请检查您关心的任何单个标题。
推荐阅读
- python - 替换在 python 代码中的 R 中长度为零
- php - 如何使用 PHP-FFMpeg 打开远程视频?
- javascript - 使用 mysql2 数据库注册和登录 javascript api 时遇到错误
- javascript - Chrome 扩展:browser.runtime API 导致“浏览器未定义”错误
- asp.net-mvc - 何时在控制器或模型变量上使用 Items 有意义
- authentication - 我可以使用 AWS Cognito 中的 userSub 作为主键吗?
- amazon-cloudformation - AWS Elasticsearch 通过 CloudFormation 启用“所有流量的 HTTPS”
- java - 在 Java 中基于 MS Access 中的日期执行搜索
- python - 如何访问 OpenCV 连接组件标签中的单个标签
- excel - 在单元格中强制使用美国货币(或其他国家/地区)