在我的应用程序中,我想注册 HTTP 客户端沿线路传输了多少字节,以控制该指标。
我找不到轻松完成此任务的方法。
http.Request
对象有一个方便的方法Write
,它用将通过网络传输的HTTP数据包填充缓冲区,但如果我调用它,那么主体就会关闭,并且在此请求上调用http.Client.Do
不会发送正确的数据包。克隆请求没有帮助。
所以这是我的问题:如何获取我要发送(或刚刚发送)的请求的大小(以字节为单位)?对于 HTTPS 连接也可以这样做吗?
要监视正在发送或已发送的请求的大小,您可以创建
http.RoundTripper
的自定义实现,以拦截请求和响应并计算大小。请检查示例代码:
import (
"bytes"
"fmt"
"io"
"net/http"
)
type SizeTrackingTransport struct {
Transport http.RoundTripper
}
func (t *SizeTrackingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
// Capture request body
var requestBody bytes.Buffer
if req.Body != nil {
_, err := io.Copy(&requestBody, req.Body)
if err != nil {
return nil, err
}
}
// Create a clone of the request to send it later
clonedReq := req.Clone(req.Context())
clonedReq.Body = io.NopCloser(&requestBody)
// Send the cloned request using the provided Transport
resp, err := t.Transport.RoundTrip(clonedReq)
if err != nil {
return nil, err
}
// Capture response body
var responseBody bytes.Buffer
if resp.Body != nil {
_, err := io.Copy(&responseBody, resp.Body)
if err != nil {
return nil, err
}
}
// Calculate and print request and response sizes
fmt.Printf("Request size: %d bytes\n", requestBody.Len())
fmt.Printf("Response size: %d bytes\n", responseBody.Len())
// Replace the original response body with the captured one
resp.Body = io.NopCloser(&responseBody)
return resp, nil
}
func main() {
// Create a custom HTTP client with the SizeTrackingTransport
client := &http.Client{
Transport: &SizeTrackingTransport{
Transport: http.DefaultTransport,
},
}
// Example request
req, _ := http.NewRequest("GET", "https://example.com", nil)
// Send the request using the custom client
_, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
}
此代码仅提供基本实现。根据您的需求,您可能需要对其进行改进。我希望这会有所帮助