req
req copied to clipboard
Dump 请求和响应内容时,怎么分别获取到请求包和相应包?
resp.Dump() 获取到的是请求包+响应包。这个只能自己根据strings.inde去分割数据,然后获取到请求包、响应包?
dump支持只dump指定部分内容,比如只dump request 部分。然后response部分就不在dump中,但可以从resp对象的字段中获取:
client := req.C()
resp, err := client.R().EnableDumpWithoutResponse().Get(url)
if err != nil {
...
}
reqContent := resp.Dump()
respHeader := resp.Header
respBody := resp.String()
也考虑过支持更灵活的dump能力,但这种需求不多,改动较大,就暂时没支持
dump支持只dump指定部分内容,比如只dump request 部分。然后response部分就不在dump中,但可以从resp对象的字段中获取:
client := req.C() resp, err := client.R().EnableDumpWithoutResponse().Get(url) if err != nil { ... } reqContent := resp.Dump() respHeader := resp.Header respBody := resp.String()
3q。 扫描器的话,对dump还是有需求的,需要请求包和响应包
扫描器场景确实需要,今天已经初步支持了, release 到了 v3.25.0,用法参考 : https://req.cool/docs/tutorial/debugging/#dump-the-content
var reqBuf, respBuf bytes.Buffer
resp, err := client.R().
EnableDump().
SetDumpOptions(&req.DumpOptions{
RequestOutput: &reqBuf,
ResponseOutput: &respBuf,
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
}).
SetBody("test body").
Post("https://httpbin.org/post")
if err != nil {
...
}
fmt.Println("request content:")
fmt.Println(reqBuf.String())
fmt.Println("\n======\n")
fmt.Println("response content:")
fmt.Println(respBuf.String())
可以的。 但有个问题,就是如果请求失败,reqBuf.String()获取不到数据
嗯,如果是连接超时之类的网络错误,请求根本没有发出去,也就无法dump出来。
如果希望这种情况也能知道请求内容,可以用 client.OnBeforeRequest(xx) 加个中间件,每次请求前读取 request 上设置的属性(req.RawURL, req.Method, req.Headers, req.Body, req.FormData)
使用respBuf.String() 的话,有什么函数能自动解码(gzip)嘛?
默认就会自动解压的,前提是server正常响应 Content-Encoding: gzip 的 header,并且body内容也完全是gzip算法压缩的,就会自动解压,验证代码:
package main
import (
"bytes"
"fmt"
"github.com/imroc/req/v3"
)
func main() {
var reqBuf, respBuf bytes.Buffer
req.R().
EnableDump().
SetDumpOptions(&req.DumpOptions{
RequestOutput: &reqBuf,
ResponseOutput: &respBuf,
RequestHeader: true,
RequestBody: true,
ResponseHeader: true,
ResponseBody: true,
}).
MustGet("https://httpbin.org/gzip")
fmt.Println("req content:")
fmt.Println(reqBuf.String())
fmt.Println("resp content:")
fmt.Println(respBuf.String())
}
运行:
$ go run .
req content:
:authority: httpbin.org
:method: GET
:path: /gzip
:scheme: https
accept-encoding: gzip
user-agent: req/v3 (https://github.com/imroc/req)
resp content:
:status: 200
date: Mon, 17 Oct 2022 11:32:52 GMT
content-type: application/json
content-length: 224
server: gunicorn/19.9.0
content-encoding: gzip
access-control-allow-origin: *
access-control-allow-credentials: true
{
"gzipped": true,
"headers": {
"Accept-Encoding": "gzip",
"Host": "httpbin.org",
"User-Agent": "req/v3 (https://github.com/imroc/req)",
"X-Amzn-Trace-Id": "Root=1-634d3d64-225bcc6729505d2933dcd5a3"
},
"method": "GET",
"origin": "103.7.29.7"
}
不知道为啥,单独拿代码放到test里运行,是成功解码的。但放到程序里时,没成功解码
看能否提取成公开可复现代码,这样好排查
嗯嗯,我后续尝试弄弄
关键点在这里:
r.Headers = Req.Header.Clone()
Req.Header 是用 http.ReadRequest
从 reqtext
中解析出来的,而 reqtext 里包含了 Accept-Encoding
的 header,也就是说,显式给 Request 设置了 Accept-Encoding
这个 header,而显式设置 Accept-Encoding
意味着需要用户自行去解压缩。只有不显式设置 Accept-Encoding
才会自动解压缩,标准库也是这样的,你可以试下
噢噢,那只要把Accept-Encoding: gzip, deflate
去掉就行了咯?
噢噢,那只要把
Accept-Encoding: gzip, deflate
去掉就行了咯?
是的
好的,谢谢