1 回答
TA贡献1828条经验 获得超4个赞
其实很简单:
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"os"
)
type Connection struct {
Request *http.Request
Response *http.Response
}
func ReadHTTPFromFile(r io.Reader) ([]Connection, error) {
buf := bufio.NewReader(r)
stream := make([]Connection, 0)
for {
req, err := http.ReadRequest(buf)
if err == io.EOF {
break
}
if err != nil {
return stream, err
}
resp, err := http.ReadResponse(buf, req)
if err != nil {
return stream, err
}
//save response body
b := new(bytes.Buffer)
io.Copy(b, resp.Body)
resp.Body.Close()
resp.Body = ioutil.NopCloser(b)
stream = append(stream, Connection{Request: req, Response: resp})
}
return stream, nil
}
func main() {
f, err := os.Open("/tmp/test.http")
if err != nil {
log.Fatal(err)
}
defer f.Close()
stream, err := ReadHTTPFromFile(f)
if err != nil {
log.Fatalln(err)
}
for _, c := range stream {
b, err := httputil.DumpRequest(c.Request, true)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
b, err = httputil.DumpResponse(c.Response, true)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
}
一些注意事项:
http.ReadRequest
并且http.ReadResponse
可以在同一时间一遍又一遍地调用,bufio.Reader
直到EOF
它“正常工作”“正常工作”取决于 Content-Length 标头是否存在且正确,因此读取正文会将 Reader 置于下一个请求/响应的开头
阅读代码以准确了解哪些有效,哪些无效
resp.Body
必须根据Close
文档进行编辑,因此我们必须将其复制到另一个缓冲区以保留它使用您的示例数据(修改 Content-Length 以匹配您的截断),此代码将输出与给定相同的请求和响应
httputil.DumpRequest
并且httputil.DumpResponse
不一定以与输入文件相同的顺序转储 HTTP 标头,所以不要期望 adiff
是完美的
- 1 回答
- 0 关注
- 258 浏览
添加回答
举报