如何在mitmproxy两端记录完整的4类请求响应交互对?
如何在mitmproxy中记录全链路四类请求/响应交互对
要捕获你提到的c->p(客户端原始请求)、p->s(代理转发请求)、s->p(服务端原始响应)、p->c(代理返回客户端的最终响应)这四类交互,mitmproxy默认的-w参数确实无法满足,必须通过自定义Python插件利用mitmproxy的生命周期事件来实现。
核心思路
mitmproxy提供了多个HTTP生命周期钩子,我们可以在不同阶段捕获对应状态的请求/响应:
request事件:捕获客户端发送给代理的原始请求(c->p)request_send事件:捕获代理即将转发给服务端的修改后请求(p->s)response事件:捕获服务端返回给代理的原始响应(s->p)response_send事件:捕获代理即将返回给客户端的修改后响应(p->c)
完整插件脚本示例
下面的脚本会将四类交互分别保存为JSON文件,每个文件包含请求/响应的核心信息,且通过flow_id关联同一链路的所有交互:
from mitmproxy import http import json from datetime import datetime import os # 日志保存目录,自动创建 LOG_DIR = "mitmproxy_full_interactions" os.makedirs(LOG_DIR, exist_ok=True) def get_timestamp(): return datetime.now().strftime("%Y%m%d_%H%M%S_%f") def save_interaction(interaction_type: str, obj: http.Request | http.Response, flow_id: str): """保存交互数据为JSON文件""" timestamp = get_timestamp() data = { "flow_id": flow_id, "type": interaction_type, "timestamp": timestamp } if isinstance(obj, http.Request): data.update({ "method": obj.method, "url": obj.url, "headers": dict(obj.headers), "content": obj.content.decode("utf-8", errors="ignore") }) elif isinstance(obj, http.Response): data.update({ "status_code": obj.status_code, "reason": obj.reason, "headers": dict(obj.headers), "content": obj.content.decode("utf-8", errors="ignore") }) # 生成文件名并保存 filename = f"{LOG_DIR}/{interaction_type}_{flow_id}_{timestamp}.json" with open(filename, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) # 捕获c->p:客户端发送的原始请求 def request(flow: http.HTTPFlow): target_request = flow.request.original if flow.request.original else flow.request save_interaction("c->p", target_request, flow.id) # 捕获p->s:代理转发给服务端的请求 def request_send(flow: http.HTTPFlow): save_interaction("p->s", flow.request, flow.id) # 捕获s->p:服务端返回的原始响应 def response(flow: http.HTTPFlow): target_response = flow.response.original if flow.response.original else flow.response save_interaction("s->p", target_response, flow.id) # 捕获p->c:代理返回给客户端的最终响应 def response_send(flow: http.HTTPFlow): save_interaction("p->c", flow.response, flow.id)
使用方法
- 将上述代码保存为
full_interaction_logger.py - 启动mitmdump并加载该脚本:
mitmdump -s full_interaction_logger.py - 所有交互日志会自动保存到
mitmproxy_full_interactions目录下,每个文件对应一类交互,且同一链路的四个文件会共享相同的flow_id。
补充说明
- 如果需要保留mitmproxy原生的flow格式(可直接用mitmproxy打开查看),可以将
save_interaction函数替换为flow.save()方法,只需复制对应阶段的flow对象并保存即可。 - 若不需要单独文件,也可以将四类交互合并到同一个JSON文件中,通过
flow_id分组存储。
内容的提问来源于stack exchange,提问作者Wiktor Tomczak
相关产品推荐
相关产品推荐

