You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)

使用方法

  1. 将上述代码保存为full_interaction_logger.py
  2. 启动mitmdump并加载该脚本:
    mitmdump -s full_interaction_logger.py
    
  3. 所有交互日志会自动保存到mitmproxy_full_interactions目录下,每个文件对应一类交互,且同一链路的四个文件会共享相同的flow_id。

补充说明

  • 如果需要保留mitmproxy原生的flow格式(可直接用mitmproxy打开查看),可以将save_interaction函数替换为flow.save()方法,只需复制对应阶段的flow对象并保存即可。
  • 若不需要单独文件,也可以将四类交互合并到同一个JSON文件中,通过flow_id分组存储。

内容的提问来源于stack exchange,提问作者Wiktor Tomczak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 20:20:24