mitmproxy入门二、自定义response响应的生效规则

在mitmproxy代理脚本编写过程中经常遇到一些代码预期之外的结果(明明想要返回我写的内容,结果却直接请求到真实数据并返回了)。我一般都是在入口文件addons里面引入不同的python文件类来以pipline的形式操作请求(比如前面的python脚本文件专门用来处理请求打印,最后一个python脚本专门实现请求的二次加工),之前没有特别关注过每个引入的python文件里面处理request和response的不同情况下的作用结果,今天就抽时间专门测试了几个案例并分享之。

测试文件结构很简单,在每个addons里面用到的类文件里面都处理request、response:

测试的过程就是在action1.py和action2.py里面通过不同的flow.response赋值来测试我们自己的自定义结果在什么情况下生效,以及受到哪些因素影响,这里就直接忽略过程了贴上一些测试结果,如果有不正确的地方还望指正!

一、如果你的代码完全正确,且不会报错,那么自定义的response结果为:反“Z”字倒查第一个

为什么强调代码正确?因为mitproxy有容错机制只要代理脚本启动成功后,即使你代码存在运行时错误,也可以继续执行而不会退出程序,如果中间存在错误那么mitmproxy会跳过你写的某些逻辑……

所有代码运行正确的情况下:

1、请求的最终结果会先从黄色箭头方向开始寻找,最先找到哪里有自定义的response就返回哪个

2、如果action1.py和action2.py的request里面都没有赋值flow.response语句,那么这个请求
会直接请求到实际的url地址,然后在response里面赋值flow.response的语句相当于修改了
给客户端返回值(实际对应url后端的服务器并不知道它的返回已经被“中间人”修改了)

3、如果action1.py和action2.py的request里面都没有赋值flow.response语句,而且请求的url
是个不存在的地址,那么response里面赋值flow.response的语句会失效(因为目标服务器不可达
,也不存在返回结果和修改了)

4、只要action1.py和action2.py的request里面任意存在一个赋值flow.response语句,那么最终
这个请求不会到达实际的url,而是直接按第1条规则进行返回。

二、如果在执行你自定义的flow.response赋值语句前存在运行时错误结果为:先标记失效,再反“Z”字倒查第一个

在入口文件的addons里面,按action1、action2、action3……这种引入顺序生效,上面已经讲过所有代码运行正常情况下的规则,那么如果某个action文件里面的request或response如果出现运行报错,会遵循什么样的规律呢?

如果运行时程序报错(错误发生在flow.response赋值语句前):

1、如果错误是request中的,那么对应报错python文件本身以及addons里排在该报错文件后面所有引入的文件内对应request函数会整体失效。

2、如果错误是在response中的,则失效规则跟第1点类似,后续response里的都会整体失效

3、去掉这些失效的request、response。以“Z”字形倒查有效flow.response的第一个就是最终返回值

4、第3条倒查有效flow.response规则与本文上面的“第一点”规则一样。(本示例中request全部失效相当于没有request中的flow.response赋值,所以请求会到达真实url,但因为url请求不可达,所以本该显示111+111的也因无结果而失效

三、自定义response作用规则的启示?

1、在实际代理脚本书写过程中逻辑会比示例复杂很多,但总体规则应该是一样的,为了确保结果按预期执行,那么需要注意多try……catch……让代码正常执行下去!

2、在引入的多个python文件中,建议按一定规则进行分工处理,尽量避免一个请求过来后每个python模块里面都会操作到相同的请求属性(比如都做了host修改操作,或都做了自定义返回response…… 那么你很可能就不知道到底是哪里该了什么东西以及一些莫名奇妙的非预期结果,尤其是中间还夹杂了程序错误的时候)

3、目前我用到的mitmproxy功能也不多,常用的几个操作就那么几个,但是因为设计的项目及请求api较多,也就大概做了下简单的python脚本分工

1、定义请求过滤函数,每个引入的python操作都要先根据flow.request.url以及flow.request.get_text() 去匹配关键字决定是否过滤处理
2、尽量按业务或请求api域名来拆分python模块,也就是说正常情况下每个api请求只会被处理一次,且只在该文件里面处理响应结果
3、如果涉及到接口签名可以专门引入一个python脚本来处理,放到addons的最后,这样无论前面怎么处理请求都可以确保签名正确
4、如果有很多mock需求 还用了很多根据不同参数生成不同响应结果的逻辑,记得在该用return的地方加上return;比如在同一个文件的request中,如果前面判断条件里面赋值了flow.response没有return,那么程序会在本文件代码中继续往下执行如果执行遇到了新的赋值那么就会被覆盖

基于互联网精神,在注明出处的前提下本站文章可自由转载!

本文链接:https://ranjuan.cn/mitmproxy-response-action/

赞赏

微信赞赏支付宝赞赏

发表评论