【问题标题】:Using mitmproxy inside python script在 python 脚本中使用 mitmproxy
【发布时间】:2023-04-03 00:44:01
【问题描述】:

我是 mitmproxy 的新手。但我不知道如何在 python 脚本中使用它。

我想将 mitmproxy 放入我的 python 脚本中,就像一个库一样,并且还指定端口或主机等所有内容,并在我的 python 脚本中使用 Request 或 Response 进行一些修改。 所以当我像这样开始我的脚本时

python sample.py

一切都将自动运行,无需像这样从命令行运行 mitmproxy

mitmproxy -s sample.py

感谢阅读。

【问题讨论】:

    标签: python mitmproxy


    【解决方案1】:

    你可以使用这样的东西。此代码取自发布在 mithproxy github 上的问题,发现 here

    from mitmproxy import proxy, options
    from mitmproxy.tools.dump import DumpMaster
    from mitmproxy.addons import core
    
    
    class AddHeader:
        def __init__(self):
            self.num = 0
    
        def response(self, flow):
            self.num = self.num + 1
            print(self.num)
            flow.response.headers["count"] = str(self.num)
    
    
    addons = [
        AddHeader()
    ]
    
    opts = options.Options(listen_host='127.0.0.1', listen_port=8080)
    pconf = proxy.config.ProxyConfig(opts)
    
    m = DumpMaster(None)
    m.server = proxy.server.ProxyServer(pconf)
    # print(m.addons)
    m.addons.add(addons)
    print(m.addons)
    # m.addons.add(core.Core())
    
    try:
        m.run()
    except KeyboardInterrupt:
        m.shutdown()
    

    【讨论】:

    • 感谢您的示例!只有对我来说,AddHeader 插件从未被触发,因为如果你 .add() 数组,你实际上是在向当前的“插件”数组添加另一个数组,这将导致 AddHeader() 插件不被读取。不管怎样,对于遇到同样问题的其他人来说;只需这样做: m.addons.add(AddHeader()) 而不是 m.addons.add(addons)
    • 我觉得可以用list.extendpython方法。
    【解决方案2】:

    以编程方式在后台启动 mitmproxy 以将其集成到现有应用中:

    from mitmproxy.options import Options
    from mitmproxy.proxy.config import ProxyConfig
    from mitmproxy.proxy.server import ProxyServer
    from mitmproxy.tools.dump import DumpMaster
    
    import threading
    import asyncio
    import time
    
    class Addon(object):
        def __init__(self):
            self.num = 1
    
        def request(self, flow):
            flow.request.headers["count"] = str(self.num)
    
        def response(self, flow):
            self.num = self.num + 1
            flow.response.headers["count"] = str(self.num)
            print(self.num)
    
    
    # see source mitmproxy/master.py for details
    def loop_in_thread(loop, m):
        asyncio.set_event_loop(loop)  # This is the key.
        m.run_loop(loop.run_forever)
    
    
    if __name__ == "__main__":
        options = Options(listen_host='0.0.0.0', listen_port=8080, http2=True)
        m = DumpMaster(options, with_termlog=False, with_dumper=False)
        config = ProxyConfig(options)
        m.server = ProxyServer(config)
        m.addons.add(Addon())
    
        # run mitmproxy in backgroud, especially integrated with other server
        loop = asyncio.get_event_loop()
        t = threading.Thread( target=loop_in_thread, args=(loop,m) )
        t.start()
    
        # Other servers, such as a web server, might be started then.
        time.sleep(20)
        print('going to shutdown mitmproxy')
        m.shutdown()
    

    来自my gist

    【讨论】:

    • 一般来说,我会删除包装事件循环的额外线程 + sleep(20),因为大多数情况下不需要这样做,这很令人困惑?
    • 这种情况下如何实现流请求拦截呢?例如def request(flow: http.HTTPFlow) -> None: print(flow.request.headers)
    • 如何向插件发送选项?我已经在我的对象的 load() 方法中定义了选项,并且可以用 --set 命令行参数填充它们,但不确定如何在 python 脚本中执行此操作。
    • @Sully,谢谢,但实际上仍在从脚本运行。我正在尝试在 python 脚本中运行。我只是将我的变量传递给 init 并将它们设置为对象级 var 并且它起作用了。不过谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多