赞
踩
流程回放功能数据流转示意图
实现效果
录制:
回放:
流量回放模块主要包含的功能是:
任务信息列表
创建回放任务
修改任务信息
执行任务
回放对比结果
查看任务详情信息
流量用例列表
用例详情、编辑
解决方案:通过对mitmproxy的二次开发,我们增加了根据指定列表id的dump接口。前端在列表选择的流量id,直接调用暴露的api接口,遍历获取到的id,自定义过滤获取指定的流量文件,同时解析流量数据并入库保存。此时的流量文件保存路径也会入库,以便于后续回放任务指定流量文件。
解决方案:通过全量对比返回数据的形式是不可取的,特别是流量数据大时,很容易造成前端界面的卡死。这里我们通过对返回数据建立hash值的方式,直接对比2次的hash值来获得回放的对比结果,大大提高数据对比模块的性能。
解决方案:此种基于mitmproxy自身流量文件的回放方式,回放时的request流量序列id是不变的,由于在生成流量用例时已经将老的流量返回值入库保存,后续回放时通过中间插件解析并根据id也对新的response流量进行保存,通过唯一的id进行了关联。
解决方案:这个功能平台目前没有开发实现,但是前期已经调研尝试过,可以过开发中间件脚本对流量进行自定义的编辑处理。
这里采用的是 react-diff-viewer 库,组件化剥离了数据对比模块。
- // DiffView.js
- import React, { Component } from 'react';
- import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer';
-
- import styles from './index.less';
-
- export default class Page extends Component {
- render() {
- const { leftTitle, rightTitle, srcResponse, dstResponse } = this.props;
- return (
- <div className={styles.diffContainer}>
- <ReactDiffViewer
- leftTitle={leftTitle}
- rightTitle={rightTitle}
- oldValue={JSON.stringify(srcResponse, null, 2)}
- newValue={JSON.stringify(dstResponse, null, 2)}
- splitView
- // showDiffOnly={false}
- compareMethod={DiffMethod.JSON}
- // renderContent={this.highlightSyntax}
- />
- </div>
- )
- }
- }
这个实际是在mitmweb模式下才会提供的一个接口,通过忽略跨域,暴露出来给前端调用。
- # mitmproxy/tools/web/app.py
- class FlowDumpByIdHandler(RequestHandler):
- def get(self):
- self.set_header("Content-Disposition", "attachment; filename=flows")
- self.set_header("Content-Type", "application/octet-stream")
-
- save_ids = self.json
-
- bio = BytesIO()
- fw = io.FlowWriter(bio)
- for f in self.view:
- if save_ids['saveIds']:
- if f.id in save_ids['saveIds']:
- fw.add(f)
-
- self.write(bio.getvalue())
- bio.close()
核心的是返回值解析部分,这里也可以不做解析就用原生的json,但是最后入库的数据量会很大,影响后续的界面展示性能,可以看到目前主要是解析了xml和json数据,应该能覆盖常见的类型了,对于后续遇到的其它形式的返回值可以自定义扩展解析。
- # getReplayResponse.py
- import mitmproxy.http
- from bs4 import BeautifulSoup
- from mitmproxy import ctx
- import logging, json, typing, requests, hashlib
-
- PARSE_ERROR = object()
-
- def parse_json(s: bytes) -> typing.Any:
- try:
- return json.loads(s.decode('utf-8'))
- except ValueError:
- return PARSE_ERROR
-
- class MappingAddonConfig:
- HTML_PARSER = "html.parser"
-
- class GetReplayResponse:
- def __init__(self):
- self.serverDomain = "{appHost}"
- self.taskId = "{taskId}"
- self.logger = logging.getLogger(self.__class__.__name__)
-
- def uploadToServer(self, requestId, responseData, replayRespHash):
- url = self.serverDomain + '/api/replayManage/getResponseFromProxy'
- data = {{
- 'taskId': self.taskId,
- 'requestId': requestId,
- 'responseData': responseData,
- 'replayRespHash': replayRespHash,
- }}
- headers = {{'Content-Type': 'application/json'}}
- res = requests.post(url, data=json.dumps(data), headers=headers)
- resp = res.json()
- if resp['code'] != 0:
- ctx.log.info("upload [ %s ] flow failed " % requestId)
-
- def response(self, flow: mitmproxy.http.HTTPFlow) -> None:
- """If a response is received, check if we should replace some content. """
- try:
- requestId = flow.id
- res = flow.response
- if res is not None:
- encoding = res.headers.get("content-encoding", "utf-8")
- content_type = res.headers.get("content-type", "text/html")
- replayRespHash = hashlib.sha256(res.raw_content).hexdigest()
- responseData = ''
- if "text/html" in content_type and encoding == "utf-8":
- content = BeautifulSoup(res.content, MappingAddonConfig.HTML_PARSER)
- responseData = content.encode(encoding)
- elif "json" in content_type:
- data = parse_json(res.content)
- if data is not PARSE_ERROR:
- responseData = data
- else:
- self.logger.warning(
- f"PARSE_ERROR content type '{{content_type}}'")
- else:
- self.logger.warning(f"Unsupported content type '{{content_type}}' or content encoding '{{encoding}}'")
- self.uploadToServer(requestId, responseData, replayRespHash)
- except KeyError:
- pass
-
-
- addons = [
- GetReplayResponse()
- ]
本系统采用前后端分离架构,本文仅就 流量回放 模块的设计与实现,做分析讲解,其它模块将在后续文章中拆分讲述。
最后:下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。