Protocols

In mitmproxy, protocols are implemented as a set of layers, which are composed on top each other. The first layer is usually the proxy mode, e.g. transparent proxy or normal HTTP proxy. Next, various protocol layers are stacked on top of each other - imagine WebSockets on top of an HTTP Upgrade request. An actual mitmproxy connection may look as follows (outermost layer first):

Transparent HTTP proxy, no TLS:
  • TransparentProxy
  • Http1Layer
  • HttpLayer
Regular proxy, CONNECT request with WebSockets over SSL:
  • ReverseProxy
  • Http1Layer
  • HttpLayer
  • TLSLayer
  • WebsocketLayer (or TCPLayer)

Every layer acts as a read-only context for its inner layers (see Layer). To communicate with an outer layer, a layer can use functions provided in the context. The next layer is always determined by a call to .next_layer(), which is provided by the root context.

Another subtle design goal of this architecture is that upstream connections should be established as late as possible; this makes server replay without any outgoing connections possible.

class mitmproxy.protocol.Layer(ctx, **mixin_args)[source]

Base class for all layers. All other protocol layers should inherit from this class.

__init__(ctx, **mixin_args)[source]

Each layer usually passes itself to its child layers as a context. Properties of the context are transparently mapped to the layer, so that the following works:

root_layer = Layer(None)
root_layer.client_conn = 42
sub_layer = Layer(root_layer)
print(sub_layer.client_conn) # 42

The root layer is passed a mitmproxy.proxy.RootContext object, which provides access to .client_conn, .next_layer and other basic attributes.

Parameters:ctx – The (read-only) parent layer / context.
ctx = None

The parent layer.

Type:Layer
__call__()[source]

Logic of the layer.

Returns:Once the protocol has finished without exceptions.
Raises:ProtocolException – if an exception occurs. No other exceptions must be raised.
__getattr__(name)[source]

Attributes not present on the current layer are looked up on the context.

layers

List of all layers, including the current layer ([self, self.ctx, self.ctx.ctx, ...])

class mitmproxy.protocol.ServerConnectionMixin(server_address=None)[source]

Mixin that provides a layer with the capabilities to manage a server connection. The server address can be passed in the constructor or set by calling set_server(). Subclasses are responsible for calling disconnect() before returning.

Recommended Usage:

class MyLayer(Layer, ServerConnectionMixin):
    def __call__(self):
        try:
            # Do something.
        finally:
            if self.server_conn:
                self.disconnect()
set_server(address, server_tls=None, sni=None)[source]

Sets a new server address. If there is an existing connection, it will be closed.

Raises:

ProtocolException

if server_tls is True, but there was no TLS layer on the protocol stack which could have processed this.

disconnect()[source]

Deletes (and closes) an existing server connection. Must not be called if there is no existing connection.

connect()[source]

Establishes a server connection. Must not be called if there is an existing connection.

Raises:ProtocolException – if the connection could not be established.
exception mitmproxy.protocol.Kill[source]

Signal that both client and server connection(s) should be killed immediately.