当前位置: 首页 > 面试题库 >

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

孙钱青
2023-03-14
问题内容

给定以下文件,该文件包含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。那回应呢?任何想法/反馈/想法表示赞赏。


问题答案:

实际上非常简单:

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.ReadRequesthttp.ReadResponse
  • http.ReadRequesthttp.ReadResponse可以在相同的位置上反复调用,bufio.Reader直到EOF它“正常工作”
    • “正常工作”取决于Content-Length标头的存在和正确性,因此读取正文会将Reader置于下一个请求/响应的开始
    • 阅读代码以确切了解哪些将起作用,哪些将不起作用
  • resp.Body必须根据Close文档进行编辑,因此我们必须将其复制到另一个缓冲区以保留它
  • 使用您的示例数据(修改Content-Length以匹配您的截断),此代码将输出与给定相同的请求和响应
  • httputil.DumpRequest并且httputil.DumpResponse不一定会以与输入文件相同的顺序转储HTTP标头,因此不要指望a diff是完美的


 类似资料:
  • 我正试图通过JMeter发送HTTP请求。我创建了一个循环计数为25的线程组。我有一个120的加速期,线程数设置为30。在线程组中,我有20个HTTP请求。对于JMeter如何运行这些请求,我有点困惑。一个线程组内的20个请求是否都在一个线程中运行,而线程组上的每个循环是否在不同的线程上并发运行?或者,20个请求中的每一个都在可用时在不同的线程中运行。 我的另一个问题是,在每个循环中,我想改变通过

  • 问题内容: 我一直试图找出如何从Angularjs前端的一个HTTP请求表单中解析PDF文档和JSON数据。请求有效负载为 HTTP请求 内容处置:表单数据;name =“文件”; filename =“ Parent Handbook.pdf”内容类型:application / pdf 内容处置:表单数据;name =“ doc” {“ title”:“ test”,“ cat”:“ test

  • 我想通过AJAX请求检索我的本地JSON文件数据。当我在Chrome中启动html时,它产生了错误: XMLHttpRequest无法加载。跨源请求仅支持以下协议方案:超文本传输协议、数据、chrome、chrome-扩展、https、chrome-扩展-资源。 以下是我的代码: 如果我添加<code>数据类型:“jsonp”,则 它返回我错误函数。

  • 问题内容: 我想通过Google Directions API动态查询Google Maps。例如,此请求计算通过伊利诺伊州芝加哥市到密苏里州乔普林市和俄克拉荷马州俄克拉荷马市的两个航路点的路线: http://maps.googleapis.com/maps/api/directions/json?origin = Chicago,IL&destination = Los + Angeles,C

  • 所以我做了一个简单的。html文件和一个简单的。js脚本。它非常简单,只是一个按钮,可以生成http。按下后获取请求。一旦我按下按钮,get请求就会被创建,我也会从请求中得到响应(代码200,可以在调试器中看到数据),但我也会得到一个304阻塞代码(被CORS阻塞)。我正在使用jquery ajax创建请求。 我的问题是-我可以从本地文件创建get请求,但我不能使用我得到的数据。。。为什么会这样?

  • 问题内容: 我正在尝试对Android上的程序使用Flurry Analytics,但无法从服务器获取xml文件本身。 我正在接近,因为在Log Cat System.out标记中由于某种原因我可以得到一半,它说“ XML传递异常= java.net.MalformedURLException:找不到协议:?xml版本= 1.0编码=“ UTF -8“等…直到大约完成我的xml代码的一半。不确定我