关于mitmproxy截数据导致客户端响应被阻塞的问题

开发者在使用ffmpeg构建Android播放器时遇到400M视频加载延迟9秒的问题,通过排查ffmpeg和nginx代码未找到原因。后来发现是mitmproxy代理服务器缓存整个http数据包导致的延迟,移除mitmproxy后实现秒播。提醒开发者注意mitmproxy可能带来的性能影响。

近期使用ffmpeg做android播放器, 来播放服务器端的mp4文件, 开发过程中习惯性的打开了mitmproxy来监控http数据包.

经过了几天的各种铺垫架设, 一切事情似乎都很顺利, 测试用的小视频文件在自己的播放器上一切正常. 又开始觉得自己牛逼了, 实现个自己的播放器也没有什么大不了啊. 然而, 悲剧总在天晴后:
无意中播放一个400M的视频文件时, 发现卡在loading界面要等待9秒后才开始播放, 看起来好像是ffmpeg在等待数据或是在分析数据, 黑灯瞎火, 束手无策, 只能再度进入暗黑模式啃代码了.

把ffmpeg的http数据接收部分代码看了个大概, 最后定位到poll一直在等待socket事件. 这就奇怪了, 为何要poll 9秒钟呢? 服务器干什么去了?
又把nginx的发送数据部分代码分析了个大概, 数据发送时该发送的马上就丢出去了啊, 到底是哪里没有搞清楚呢? 百思不得姐, 抓狂!!! 只得老牛反刍继续磨nginx的代码…

搞了3天有余, 想着用wireshark抓一下tcp包看看, 到底网络在磨叽什么东西, 如果实在不行是不是该开涮内核socket处理部分代码了. 结果, 万万想不到的是, 一打开播放器马上就秒播视频文件了. 居然就秒播了啊…
重复了好几次, 反复把mitmproxy给加上又断开, 果断的就是被mitmproxy给卡住了. 尼玛, 花了3天多的时间, 居然就是因为视频数据被代理服务器给截住了. 估计mitmproxy是为了分析协议, 它要把整个http数据包缓存下来后才传给接收端.

因为一直喜欢mitmproxy的分析http包的简单界面, 才舍不得使用wireshark, 没想到简单总被简单误, 出来混总是要还的…
写出来, 希望看到我这个提醒的同志, 不要再在这里栽跟头了.

"""from mitmproxy import http def request(flow:http.HTTPFlow): flow.request.headers["User-Agent"] = "DxShell" with open("../config/request.txt", "w", encoding="utf-8") as file: file.write("URL:"+flow.request.url+"\n") file.write("请求方法"+flow.request.method+"/"+flow.request.scheme+"\n") file.write("请求头:\n") for key, value in flow.request.headers.items(): file.write(f"{key}: {value}\n") file.write("请求数据:\n") file.write(flow.request.text) def response(flow: http.HTTPFlow): flow.response.headers["X-Processed-By"] = "DxShell" with open("../config/response.txt", "w", encoding="utf-8") as file: file.write("响应状态:"+flow.response.reason+"\n") file.write("响应头:\n") for key, value in flow.response.headers.items(): file.write(f"{key}: {value}\n") file.write("响应数据:\n") file.write(flow.response.text)""" import asyncio from mitmproxy import http, ctx from mitmproxy.options import Options from mitmproxy.tools.dump import DumpMaster class HTTPOnlyAddon: def __init__(self): self.blocked_flows = [] # 存储被拦的请求 def request(self, flow: http.HTTPFlow): # 确保只处理 HTTP/HTTPS(非 TCP、DNS、QUIC 等) if isinstance(flow, http.HTTPFlow): print(f"[HTTP] {flow.request.method} {flow.request.pretty_url}\n") for key, value in flow.request.headers.items(): print(f"{key}: {value}\n") print(f"请求内容:\n{flow.request.text}") flow.intercept() ui = input(">>") print(ui) if ui == "q": exit() elif ui == "r": u = input("[输入修改内容和替换内容]++>") up = u.split(" ") print(up) flow.request.headers[f"{up[1]}"] = f"{up[2]}" flow.kill() exec() def response(self, flow: http.HTTPFlow): if isinstance(flow, http.HTTPFlow): print(f"[HTTP] {flow.response.status_code} {flow.request.pretty_url}") async def start_proxy(): opts = Options( listen_host='127.0.0.1', listen_port=8080, # 关键:关闭非 HTTP 协议的处理(减少日志) mode=["regular"], # 仅常规 HTTP 代理模式 rawtcp=False, # 禁用 TCP 流处理 http2=True, # 允许 HTTP/2(可选) websocket=True, # 允许 WebSocket(可选) ) m = DumpMaster(opts, with_termlog=False, with_dumper=False) # 关闭默认日志 m.addons.add(HTTPOnlyAddon()) await m.run() if __name__ == '__main__': asyncio.run(start_proxy()) 这一段代码没能动态改包的原因
07-12
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值