用 Python 的 mitmproxy 库做请求拦截、修改时遇到'NoneType' object has no attribute 'text'

2020-09-25 10:37:13 +08:00
 ikamu

期望:在本地程序发起的请求到达本地代理时做出修改,直接返回给目标程序,不再到达服务器。 mitmproxy==5.0.1,python==3.6.1, 程序结构:

class MyAdd:
    def request(self, flow):
        # do something in request
        if "pan.baidu.com" in flow.request.pretty_url:            
            flow.kill()
            
        if "test_kkk.cn" = flow.request.host:
            with open('./init') as f_init:
                flow.response.text = f_init.read()
                flow.response.status_code = 200
                
    def response(self, flow):
        if "baidu.com" not in flow.request.pretty_url:
            print(flow.response.text)

报错

    flow.response.text = f_init.read()
AttributeError: 'NoneType' object has no attribute 'text'

而如果把 if "test_kkk.cn" = flow.request.host 放到 response 函数下则能正确修改,但不能满足“直接返回给目标程序,不再到达服务器”的要求。 该怎么实现呢

2405 次点击
所在节点    Python
6 条回复
ljhaoboy
2020-09-25 11:24:14 +08:00
xiaolinjia
2020-09-25 11:27:08 +08:00
虽然没用过这个库,不过看报错就是因为 flow.response=None 。
于是推测原因是,在 request 方法里,这库还没有给 flow.response 对象实例化。
然后问题又来了,不到达服务器,又怎么有 response 响应呢?
xiaolinjia
2020-09-25 11:31:48 +08:00
@xiaolinjia 看了下楼上,自己在 request 方法里实例化个 flow.Response 对象应该是可行的。
ikamu
2020-09-25 12:44:45 +08:00
@ljhaoboy 看了下这个库,有点老以至于很多类的位置不再与目录文件对应。

@xiaolinjia 出现问题的原因明白了,得在某处实例个 flow.Response 对象,这个依旧有点不知该在哪添。
ikamu
2020-09-25 12:46:48 +08:00
结局:顺着一楼的链接中找到了新版的,https 。。。github 。com/mitmproxy/mitmproxy/blob/v5.x/examples/addons/http-reply-from-proxy.py 。虽然和实例个 flow.Response 对象,然后用 flow.response.text 进行赋值的预期目标有区别,但还算是符合。
```
def start():
Addon = MyAdd()
options = Options(listen_host='127.0.0.1', listen_port=8080)
config = ProxyConfig(options)
m = DumpMaster (options)
m.server = ProxyServer(config)
m.addons.add(Addon)
m.run()
```
调用方式,期待其他答案。
ikamu
2020-09-25 13:24:17 +08:00
方法找到了:添加 flow.response = http.HTTPResponse.make()
```
from mitmproxy import http

flow.response = http.HTTPResponse.make()
if "test_kkk.cn" = flow.request.host:
with open('./init') as f_init:
flow.response.text = f_init.read()
flow.response.status_code = 200
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/710326

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX