Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 如何通过往返跟踪请求大小?_Http_Go - Fatal编程技术网

Http 如何通过往返跟踪请求大小?

Http 如何通过往返跟踪请求大小?,http,go,Http,Go,对于可能出现的新手问题,我深表歉意,但我正在修改其他人的代码,并且不熟悉Go语言 在代理http请求的代码中,我有以下代码段 func handleHTTP(w http.ResponseWriter, req *http.Request) { resp, err := http.DefaultTransport.RoundTrip(req) .. 我知道req包含一个流正文,所以没有立即长度,因为我希望往返读取这样的流。我的问题是,我如何调整这段代码,以便在流被完全消耗后获得请求正文

对于可能出现的新手问题,我深表歉意,但我正在修改其他人的代码,并且不熟悉Go语言

在代理http请求的代码中,我有以下代码段

func handleHTTP(w http.ResponseWriter, req *http.Request) {
    resp, err := http.DefaultTransport.RoundTrip(req)
..
我知道req包含一个流正文,所以没有立即长度,因为我希望往返读取这样的流。我的问题是,我如何调整这段代码,以便在流被完全消耗后获得请求正文的最终大小

谢谢



http.Request.Body
的类型为
io.ReadCloser
。这是一个
接口
,您可以利用它用自己的
io.ReadCloser
实现来包装正文值,该实现计算从中读取的字节数

package main\u测试
进口(
“fmt”
“io”
“io/ioutil”
“日志”
“net/http”
“net/http/httptest”
“字符串”
“测试”
)
func TestRequestLen(t*testing.t){
reqBody:=“你好,世界!”
resBody:=“你好,客户”
ts:=httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
格式打印(w,正文)
}))
延迟ts关闭()
req,err:=http.NewRequest(http.MethodGet,ts.URL,strings.NewReader(reqBody))
如果错误!=零{
log.Fatal(错误)
}
req.Body=&bytesRead{ReadCloser:req.Body}
res,err:=http.DefaultClient.Do(req)
如果错误!=零{
log.Fatal(错误)
}
问候语,err:=ioutil.ReadAll(res.Body)
res.Body.Close()
如果错误!=零{
log.Fatal(错误)
}
如果需要:=resBody;字符串(问候语)!=want{
t、 Fatalf(“无效响应正文%q需要%q”,字符串(问候语),需要)
}
如果需要:=len(reqBody);req.Body.(*bytesRead).total!=want{
t、 Fatalf(“无效的请求长度%v,需要%v”,请求正文。(*bytesRead)。总计,需要)
}
}
类型bytesRead结构{
io.ReadCloser
总整数
}
func(c*字节读取)读取(p[]字节)(n int,err error){
n、 err=c.ReadCloser.Read(p)
c、 总数+=n
返回
}

Request
有一个
ContentLength
作为可用属性,您可能在某些情况下可以使用它。虽然如果请求使用Transfer编码,我认为该值设置为-1(可能为0)

否则,我认为您可以使用自己的io.ReadCloser实现包装req.Body。像这样:

键入RecordLengthReadCloser结构{
io.ReadCloser
长度整数
}
func(rc*RecordLengthReadCloser)读取(p[]字节)(int,错误){
n、 错误:=rc.ReadCloser.Read(p)
rc.length+=n
返回n,错误
}
func handleHTTP(带http.ResponseWriter,req*http.Request){
rc:=&RecordLengthReadCloser{ReadCloser:req.Body}
请求主体=rc
resp,err:=http.DefaultTransport.RoundTrip(请求)
fmt.Println(钢筋混凝土长度)
_,uu=resp,err
}

这可能有我不知道的问题,我不确定您是否可以自由地重新分配请求正文而不出现问题。

在修复一个输入错误(readCloser->readCloser)后,工作非常顺利。感恩节箍,固定:)