为这个潜在的新手问题道歉,但我正在修改别人的代码,而且不熟悉Go语言。
在代理http请求的代码中,我有以下段
func handleHTTP(w http.ResponseWriter, req *http.Request) {
resp, err := http.DefaultTransport.RoundTrip(req)
..我知道req包含一个流体,所以没有即时长度,因为我期望RoundTrip读取这样的流。我的问题是如何调整这样的代码,以便在流被完全消耗之后,我可以拥有请求主体的最终大小.
谢谢
发布于 2020-12-04 23:11:38
Request有一个ContentLength作为可用属性,在某些情况下您可能就可以使用它了。虽然如果请求使用Tranfer Encoding,我认为这个值被设置为-1 (也许是0)。
否则,我认为您可以用自己的req.Body实现包装io.ReadCloser。就像这样:
type RecordLengthReadCloser struct {
io.ReadCloser
length int
}
func (rc *RecordLengthReadCloser) Read(p []byte) (int, error) {
n, err := rc.ReadCloser.Read(p)
rc.length += n
return n, err
}
func handleHTTP(w http.ResponseWriter, req *http.Request) {
rc := &RecordLengthReadCloser{ReadCloser: req.Body}
req.Body = rc
resp, err := http.DefaultTransport.RoundTrip(req)
fmt.Println(rc.length)
_, _ = resp, err
}这可能有一些我不知道的问题,我不确定您是否可以自由地重新分配req.Body而没有问题。
发布于 2020-12-04 23:10:48
http.Request.Body是io.ReadCloser型的。它是一个interface,您可以利用这一点用自己的io.ReadCloser实现包装正文值,以计数从中读取的字节。
package main_test
import (
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestRequestLen(t *testing.T) {
reqBody := "Hello world!"
resBody := "Hello, client"
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, resBody)
}))
defer ts.Close()
req, err := http.NewRequest(http.MethodGet, ts.URL, strings.NewReader(reqBody))
if err != nil {
log.Fatal(err)
}
req.Body = &bytesRead{ReadCloser: req.Body}
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
greeting, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
log.Fatal(err)
}
if want := resBody; string(greeting) != want {
t.Fatalf("invalid response body %q want %q", string(greeting), want)
}
if want := len(reqBody); req.Body.(*bytesRead).total != want {
t.Fatalf("invalid request length %v want %v", req.Body.(*bytesRead).total, want)
}
}
type bytesRead struct {
io.ReadCloser
total int
}
func (c *bytesRead) Read(p []byte) (n int, err error) {
n, err = c.ReadCloser.Read(p)
c.total += n
return
}https://stackoverflow.com/questions/65151727
复制相似问题