指令

命令允许用户与插件进行积极的交互-查询其状态,命令他们执行操作以及让他们转换数据。像options一样 ,将键入命令,并在运行时检查命令的调用和返回的数据。命令是一个非常强大的结构-例如,mitmproxy控制台中的所有用户交互都是通过将命令绑定到键来构建的。

简单的例子

让我们从一个简单的例子开始。

"""Add a custom command to mitmproxy's command prompt."""
from mitmproxy import command
from mitmproxy import ctx

class MyAddon:
    def __init__(self):
        self.num = 0

    @command.command("myaddon.inc")
    def inc(self) -> None:
        self.num += 1
        ctx.log.info(f"num = {self.num}")

addons = [
    MyAddon()
]

要查看实际的示例,请在加载了加载项的情况下启动mitmproxy控制台:

> mitmproxy -s ./examples/addons/commands-simple.py

现在,确保显示事件日志,然后在提示符下执行命令(从键入“:”开始):

:myaddon.inc

请注意,制表符补全有效-我们的addon命令与内置命令完全相同。关于此示例,需要注意以下几点:

  • 命令通过command.command装饰器声明。每个命令都有一个唯一的名称-按照惯例,我们使用句点分隔的名称,并以插件的名称作为前缀。
  • 必须使用类型注释命令,包括返回类型(在这种情况下为None)。这使mitmproxy可以在其整个工具集中支持附加命令-运行时调用经过类型检查,附加命令包含在内置帮助中,mitmproxy控制台中的命令编辑器可以执行复杂的完成和错误检查,等等。

处理流程

由于键入了命令参数,因此我们可以为使用某些重要数据类型提供特殊的便利。其中最有用的是Flows代表mitmproxy流量的 类。

考虑以下插件:

"""Handle flows as command arguments."""
import typing

from mitmproxy import command
from mitmproxy import ctx
from mitmproxy import flow

class MyAddon:
    @command.command("myaddon.addheader")
    def addheader(self, flows: typing.Sequence[flow.Flow]) -> None:
        for f in flows:
            f.request.headers["myheader"] = "value"
        ctx.log.alert("done")

addons = [
    MyAddon()
]

该myaddon.addheader命令非常简单:它需要一系列流程,并向每个请求添加标头。这个示例真正有趣的方面是用户如何指定流。由于mitmproxy可以检查类型签名,因此可以透明地将文本流选择器扩展为一系列流。这意味着用户可以充分利用流量过滤器的灵活性。让我们尝试一下。

首先将加载项加载到mitmproxy中并通过发送一些流量,以便我们可以使用以下流程:

> mitmproxy -s ./examples/addons/commands-flows.py

现在,我们可以通过多种方式调用我们的玩具命令。让我们从仅在当前集中的流程上运行它开始:

:myaddon.addheader @focus

我们还可以在所有流上调用它:

:myaddon.addheader @all

或仅来自google.com:

:myaddon.addheader ~d google.com

此外,如果计划频繁使用这些命令,则可以将这些命令简单地绑定到mitmproxy内的键盘快捷键上。流选择器与命令相结合,功能强大,可让我们构建和公开可重用的函数,以对流进行操作。

路径

命令可以带有任意数量的参数。让我们以前面的示例为基础进行说明,并演示另一种特殊类型:路径。

"""Handle file paths as command arguments."""
import typing

from mitmproxy import command
from mitmproxy import ctx
from mitmproxy import flow
from mitmproxy import types

class MyAddon:
    @command.command("myaddon.histogram")
    def histogram(
        self,
        flows: typing.Sequence[flow.Flow],
        path: types.Path,
    ) -> None:
        totals = {}
        for f in flows:
            totals[f.request.host] = totals.setdefault(f.request.host, 0) + 1

        with open(path, "w+") as fp:
            for cnt, dom in sorted([(v, k) for (k, v) in totals.items()]):
                fp.write("%s: %s\n" % (cnt, dom))

        ctx.log.alert("done")

addons = [
    MyAddon()
]

我们的命令计算指定流集合中域的直方图,并将其写入指定为命令第二个参数的路径。尝试像这样调用它:

:myaddon.histogram @all /tmp/xxx

请注意,mitmproxy为流规范和路径提供了制表符补全。

支持的类型

选项支持以下类型。如果您需要使用此处未列出的类型,请向我们发送拉取请求。

  • 基本类型:str,int,bool
  • 顺序: typing.Sequence[str]
  • 流和流序列:flow.Flowtyping.Sequence[flow.Flow]
  • 多选字符串: types.Choice
  • 元类型:types.Commandtypes.Arg。这些用于构造调用其他命令的命令。这在键绑定中最通常有用-请参阅内置的mitmproxy控制台键绑定,以获取大量示例。
  • 数据类型:types.CutSpec和types.Data。目前,cuts机制处于alpha状态,并提供了一种便捷的方式来截取流数据。
  • 小路: types.Path