Edit on GitHub

#  Scripting HTTP/1.1 and HTTP/2.0

Sometimes, we would like to write a quick script without going through the trouble of creating a class. The addons mechanism has a shorthand that allows a module as a whole to be treated as an addon object. This lets us place event handler functions in the module scope. For instance, here is a complete script that adds a header to every request.

def request(flow):
    flow.request.headers["myheader"] = "value"
examples/addons/scripting-minimal-example.py

Here’s another example that intercepts requests to a particular URL and sends an arbitrary response instead:

"""Send a reply from the proxy without sending any data to the remote server."""
from mitmproxy import http


def request(flow: http.HTTPFlow) -> None:
    if flow.request.pretty_url == "http://example.com/path":
        flow.response = http.HTTPResponse.make(
            200,  # (optional) status code
            b"Hello World",  # (optional) content
            {"Content-Type": "text/html"}  # (optional) headers
        )
examples/addons/http-reply-from-proxy.py

All events around the HTTP protocol can be found here.

For HTTP-related objects, please look at the [http][] module, or the [Request][], and [Response][] classes for other attributes that you can use when scripting.

#  Scripting WebSocket

The WebSocket protocol initially looks like a regular HTTP request, before the client and server agree to upgrade the connection to WebSocket. All scripting events for initial HTTP handshake, and also the dedicated WebSocket events can be found here.

"""Process individual messages from a WebSocket connection."""
import re
from mitmproxy import ctx


def websocket_message(flow):
    # get the latest message
    message = flow.messages[-1]

    # was the message sent from the client or server?
    if message.from_client:
        ctx.log.info("Client sent a message: {}".format(message.content))
    else:
        ctx.log.info("Server sent a message: {}".format(message.content))

    # manipulate the message content
    message.content = re.sub(r'^Hello', 'HAPPY', message.content)

    if 'FOOBAR' in message.content:
        # kill the message and not send it to the other endpoint
        message.kill()
examples/addons/websocket-simple.py

For WebSocket-related objects please look at the websocket module to find all attributes that you can use when scripting.

#  Scripting TCP

All events around the TCP protocol can be found here.

"""
Process individual messages from a TCP connection.

This script replaces full occurences of "foo" with "bar" and prints various details for each message.
Please note that TCP is stream-based and *not* message-based. mitmproxy splits stream contents into "messages"
as they are received by socket.recv(). This is pretty arbitrary and should not be relied on.
However, it is sometimes good enough as a quick hack.

Example Invocation:

    mitmdump --rawtcp --tcp-hosts ".*" -s examples/tcp-simple.py
"""
from mitmproxy.utils import strutils
from mitmproxy import ctx
from mitmproxy import tcp


def tcp_message(flow: tcp.TCPFlow):
    message = flow.messages[-1]
    message.content = message.content.replace(b"foo", b"bar")

    ctx.log.info(
        f"tcp_message[from_client={message.from_client}), content={strutils.bytes_to_escaped_str(message.content)}]"
    )
examples/addons/tcp-simple.py

For WebSocket-related objects please look at the tcp module to find all attributes that you can use when scripting.