在 Go 中解析来自文本文件的 HTTP 请求和响应

给定以下文件,其中包含 HTTP 请求和 HTTP 响应的 HTTP 流水线流。


如何将此文件解析为我的stream变量?


type Connection struct{

   Request *http.Request

   Response *http.Response

}

stream := make([]Connection, 0)

原始文件:


GET /ubuntu/dists/trusty/InRelease HTTP/1.1

Host: archive.ubuntu.com

Cache-Control: max-age=0

Accept: text/*

User-Agent: Debian APT-HTTP/1.3 (1.0.1ubuntu2)


HTTP/1.1 404 Not Found

Date: Thu, 26 Nov 2015 18:26:36 GMT

Server: Apache/2.2.22 (Ubuntu)

Vary: Accept-Encoding

Content-Length: 311

Content-Type: text/html; charset=iso-8859-1


<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

<html><head>

<title>404 Not Found</title>

</head><body>

<h1>Not Found</h1>

<p>The requested URL /ubuntu/dists/trusty/InRelease was not found on this server.</p>

<hr>

<address>Apache/2.2.22 (Ubuntu) Server at archive.ubuntu.com Port 80</address>

</body></html>

GET /ubuntu/dists/trusty-updates/InRelease HTTP/1.1

Host: archive.ubuntu.com

Cache-Control: max-age=0

Accept: text/*

User-Agent: Debian APT-HTTP/1.3 (1.0.1ubuntu2)


HTTP/1.1 200 OK

Date: Thu, 26 Nov 2015 18:26:37 GMT

Server: Apache/2.2.22 (Ubuntu)

Last-Modified: Thu, 26 Nov 2015 18:03:00 GMT

ETag: "fbb7-5257562a5fd00"

Accept-Ranges: bytes

Content-Length: 64439

Cache-Control: max-age=382, proxy-revalidate

Expires: Thu, 26 Nov 2015 18:33:00 GMT


-----BEGIN PGP SIGNED MESSAGE-----

Hash: SHA512


Origin: Ubuntu

Label: Ubuntu

Suite: trusty-updates

Version: 14.04

Codename: trusty

[... truncated by author]

我知道有http.ReadRequest。响应呢?任何想法/反馈/想法表示赞赏。


Smart猫小萌
浏览 259回答 1
1回答

明月笑刀无情

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

相关分类

Go