zoukankan      html  css  js  c++  java
  • MitmProxy使用:流量劫持与入库,流量回放

    流量截取与入库

    我们需要先定义和初始化流量截取后存储的表结构,这里我们采用 peewee 这个 ORM 库,进行操作。
    更多操作可参考:
    http://docs.peewee-orm.com/en/latest/peewee/quickstart.html

    from peewee import *
    import datetime
    //可以考虑通过 docker 快速搭建 Mysql 服务
    db = MySQLDatabase("mitmproxy", host="172.17.0.2", port=3306, user="root", passwd="xxxx")
    db.connect()
    
    class HttpRecords(Model):
        //定义了三个字段,id, http 请求记录,时间戳
        id = BigAutoField(primary_key=True)
        httprecord = TextField()
        timestamps = DateTimeField(default=datetime.datetime.utcnow)
    
        class Meta:
            database = db

    接下来编写我们的插件脚本,用于拦截请求,并且写入到我们定义好的数据库表中,如下:

    //关注接口(get 请求)
    get_url = "https://frodo.douban.com/api/v2/user/91807076/following"
    
    //发表说说的接口(post 请求)
    post_url = "https://frodo.douban.com/api/v2/status/create_status?loc_id=118282"
    httprecord = {}
    url_list = [get_url, post_url]
    
    def parser_data(query):
        data = {}
        for key, value in query.items():
            data[key] = value
        return data
    
    class HttpRecord:
        @concurrent
        def request(self, flow: http.HTTPFlow):
            //这里可以根据自身业务需求,拦截特定域名下的请求(这里为了方便演示,特地指定了两个接口地址)
            if flow.request.pretty_url.startswith(get_url):
                httprecord['method'] = flow.request.method
                httprecord['scheme'] = flow.request.scheme
                httprecord['url'] = flow.request.pretty_url
                httprecord['request_headers'] = {}
                for item in flow.request.headers:
                    httprecord['request_headers'][item] = flow.request.headers[item]
                httprecord['get_data'] = parser_data(flow.request.query)
                httprecord['post_data'] = parser_data(flow.request.urlencoded_form)
    
        @concurrent
        def response(self, flow: http.HTTPFlow):
            if flow.request.pretty_url.startswith(get_url):
                httprecord['status_code'] = flow.response.status_code
                httprecord['response_headers'] = {}
                for item in flow.response.headers:
                    httprecord['response_headers'][item] = flow.response.headers[item]
                httprecord['response_content'] = flow.response.get_text()
    
                # 插入数据库
                record = HttpRecords(httprecord=httprecord)
                record.save()
    
    addons = [
        HttpRecord()
    ]

    检查数据库表,看是否插入成功,如下:

    流量回放进行接口测试

    从数据库中查询请求记录,并按不同请求方法,e.g. get/post 进行分类;
    通过 request 网络请求库,进行重新回放请求接口;
    引入 Pytest 测试框架,加入断言,进行组织测试用例的执行,具体代码可参考如下:

    import demjson
    import requests
    from replay.httpmodel import HttpRecords
    import pytest
    
    class TestInterface:
        get_http = []
        post_http = []
        def setup_class(self):
            # 从数据库获取流量记录(前置处理操作)
            self.httprecords = HttpRecords.select()
            for item in self.httprecords:
                data = demjson.decode(item.httprecord)
                if data['method'] == "GET":
                    self.get_http.append(data)
                elif data['method'] == "POST":
                    self.post_http.append(data)
                else:
                    ...
            # 初始化请求 session
            self.session = requests.session()
    
        def testReplayGet(self):
            """
             测试回放 Get 请求
            """
            for i in range(len(self.get_http)):
                res = self.session.get(url=self.get_http[i]['url'], headers=self.get_http[i]['request_headers'], data=self.get_http[i]['get_data'])
                //这里主要是断言了响应状态码,在实际业务中,我们还需要断言返回格式及校验核心字段。
                assert res.status_code == 200
    
        def testRelayPost(self):
            """
            测试回放 Post 请求
            """
            for i in range(len(self.post_http)):
                res = self.session.post(url=self.post_http[i]['url'], headers=self.post_http[i]['request_headers'], data=self.post_http[i]['post_data'])
                assert res.status_code == 200
    
    if __name__ == '__main__':
        pytest.main(["--html=report.html --self-contained-html", "interfacereplay.py"])

    查看测试报告
    get 和 post 请求分别回放测试成功:

  • 相关阅读:
    订单号生成规则
    mysql启动错误:mysql.sock丢失
    【转】Nginx服务并发过10万的Linux内核优化配置
    代理(正向代理)跟反向代理的区别
    php socket编程入门
    CentOS更改yum源与更新系统
    查看github.com上代码star排行
    html-3,table 表格标签 tr th td caption thead tbody tfoot 的简单使用
    html-2, a img ul li ol dl dt dd 标签与列表标签的简单使用
    html基本标签介绍及应用
  • 原文地址:https://www.cnblogs.com/-wenli/p/13940934.html
Copyright © 2011-2022 走看看