Edit on GitHub

mitmproxy.proxy.mode_specs

This module is responsible for parsing proxy mode specifications such as "regular", "reverse:https://example.com", or "socks5@1234". The general syntax is

mode [: mode_configuration] [@ [listen_addr:]listen_port]

For a full example, consider reverse:https://[email protected]:443. This would spawn a reverse proxy on port 443 bound to localhost. The mode is reverse, and the mode data is https://example.com. Examples:

mode = ProxyMode.parse("regular@1234")
assert mode.listen_port == 1234
assert isinstance(mode, RegularMode)

ProxyMode.parse("reverse:example.com@invalid-port")  # ValueError

RegularMode.parse("regular")  # ok
RegularMode.parse("socks5")  # ValueError
  1"""
  2This module is responsible for parsing proxy mode specifications such as
  3`"regular"`, `"reverse:https://example.com"`, or `"socks5@1234"`. The general syntax is
  4
  5    mode [: mode_configuration] [@ [listen_addr:]listen_port]
  6
  7For a full example, consider `reverse:https://[email protected]:443`.
  8This would spawn a reverse proxy on port 443 bound to localhost.
  9The mode is `reverse`, and the mode data is `https://example.com`.
 10Examples:
 11
 12    mode = ProxyMode.parse("regular@1234")
 13    assert mode.listen_port == 1234
 14    assert isinstance(mode, RegularMode)
 15
 16    ProxyMode.parse("reverse:example.com@invalid-port")  # ValueError
 17
 18    RegularMode.parse("regular")  # ok
 19    RegularMode.parse("socks5")  # ValueError
 20
 21"""
 22
 23from __future__ import annotations
 24
 25import dataclasses
 26import platform
 27import re
 28import sys
 29from abc import ABCMeta
 30from abc import abstractmethod
 31from dataclasses import dataclass
 32from functools import cache
 33from typing import ClassVar
 34from typing import Literal
 35
 36import mitmproxy_rs
 37from mitmproxy.coretypes.serializable import Serializable
 38from mitmproxy.net import server_spec
 39
 40if sys.version_info < (3, 11):
 41    from typing_extensions import Self  # pragma: no cover
 42else:
 43    from typing import Self
 44
 45
 46@dataclass(frozen=True)  # type: ignore
 47class ProxyMode(Serializable, metaclass=ABCMeta):
 48    """
 49    Parsed representation of a proxy mode spec. Subclassed for each specific mode,
 50    which then does its own data validation.
 51    """
 52
 53    full_spec: str
 54    """The full proxy mode spec as entered by the user."""
 55    data: str
 56    """The (raw) mode data, i.e. the part after the mode name."""
 57    custom_listen_host: str | None
 58    """A custom listen host, if specified in the spec."""
 59    custom_listen_port: int | None
 60    """A custom listen port, if specified in the spec."""
 61
 62    type_name: ClassVar[
 63        str
 64    ]  # automatically derived from the class name in __init_subclass__
 65    """The unique name for this proxy mode, e.g. "regular" or "reverse"."""
 66    __types: ClassVar[dict[str, type[ProxyMode]]] = {}
 67
 68    def __init_subclass__(cls, **kwargs):
 69        cls.type_name = cls.__name__.removesuffix("Mode").lower()
 70        assert cls.type_name not in ProxyMode.__types
 71        ProxyMode.__types[cls.type_name] = cls
 72
 73    def __repr__(self):
 74        return f"ProxyMode.parse({self.full_spec!r})"
 75
 76    @abstractmethod
 77    def __post_init__(self) -> None:
 78        """Validation of data happens here."""
 79
 80    @property
 81    @abstractmethod
 82    def description(self) -> str:
 83        """The mode description that will be used in server logs and UI."""
 84
 85    @property
 86    def default_port(self) -> int | None:
 87        """
 88        Default listen port of servers for this mode, see `ProxyMode.listen_port()`.
 89        """
 90        return 8080
 91
 92    @property
 93    @abstractmethod
 94    def transport_protocol(self) -> Literal["tcp", "udp", "both"]:
 95        """The transport protocol used by this mode's server."""
 96
 97    @classmethod
 98    @cache
 99    def parse(cls, spec: str) -> Self:
100        """
101        Parse a proxy mode specification and return the corresponding `ProxyMode` instance.
102        """
103        head, _, listen_at = spec.rpartition("@")
104        if not head:
105            head = listen_at
106            listen_at = ""
107
108        mode, _, data = head.partition(":")
109
110        if listen_at:
111            if ":" in listen_at:
112                host, _, port_str = listen_at.rpartition(":")
113            else:
114                host = None
115                port_str = listen_at
116            try:
117                port = int(port_str)
118                if port < 0 or 65535 < port:
119                    raise ValueError
120            except ValueError:
121                raise ValueError(f"invalid port: {port_str}")
122        else:
123            host = None
124            port = None
125
126        try:
127            mode_cls = ProxyMode.__types[mode.lower()]
128        except KeyError:
129            raise ValueError(f"unknown mode")
130
131        if not issubclass(mode_cls, cls):
132            raise ValueError(f"{mode!r} is not a spec for a {cls.type_name} mode")
133
134        return mode_cls(
135            full_spec=spec, data=data, custom_listen_host=host, custom_listen_port=port
136        )
137
138    def listen_host(self, default: str | None = None) -> str:
139        """
140        Return the address a server for this mode should listen on. This can be either directly
141        specified in the spec or taken from a user-configured global default (`options.listen_host`).
142        By default, return an empty string to listen on all hosts.
143        """
144        if self.custom_listen_host is not None:
145            return self.custom_listen_host
146        elif default is not None:
147            return default
148        else:
149            return ""
150
151    def listen_port(self, default: int | None = None) -> int | None:
152        """
153        Return the port a server for this mode should listen on. This can be either directly
154        specified in the spec, taken from a user-configured global default (`options.listen_port`),
155        or from `ProxyMode.default_port`.
156        May be `None` for modes that don't bind to a specific address, e.g. local redirect mode.
157        """
158        if self.custom_listen_port is not None:
159            return self.custom_listen_port
160        elif self.default_port is None:
161            return None
162        elif default is not None:
163            return default
164        else:
165            return self.default_port
166
167    @classmethod
168    def from_state(cls, state):
169        return ProxyMode.parse(state)
170
171    def get_state(self):
172        return self.full_spec
173
174    def set_state(self, state):
175        if state != self.full_spec:
176            raise dataclasses.FrozenInstanceError("Proxy modes are immutable.")
177
178
179TCP: Literal["tcp", "udp", "both"] = "tcp"
180UDP: Literal["tcp", "udp", "both"] = "udp"
181BOTH: Literal["tcp", "udp", "both"] = "both"
182
183
184def _check_empty(data):
185    if data:
186        raise ValueError("mode takes no arguments")
187
188
189class RegularMode(ProxyMode):
190    """A regular HTTP(S) proxy that is interfaced with `HTTP CONNECT` calls (or absolute-form HTTP requests)."""
191
192    description = "HTTP(S) proxy"
193    transport_protocol = TCP
194
195    def __post_init__(self) -> None:
196        _check_empty(self.data)
197
198
199class TransparentMode(ProxyMode):
200    """A transparent proxy, see https://docs.mitmproxy.org/dev/howto-transparent/"""
201
202    description = "Transparent Proxy"
203    transport_protocol = TCP
204
205    def __post_init__(self) -> None:
206        _check_empty(self.data)
207
208
209class UpstreamMode(ProxyMode):
210    """A regular HTTP(S) proxy, but all connections are forwarded to a second upstream HTTP(S) proxy."""
211
212    description = "HTTP(S) proxy (upstream mode)"
213    transport_protocol = TCP
214    scheme: Literal["http", "https"]
215    address: tuple[str, int]
216
217    # noinspection PyDataclass
218    def __post_init__(self) -> None:
219        scheme, self.address = server_spec.parse(self.data, default_scheme="http")
220        if scheme != "http" and scheme != "https":
221            raise ValueError("invalid upstream proxy scheme")
222        self.scheme = scheme
223
224
225class ReverseMode(ProxyMode):
226    """A reverse proxy. This acts like a normal server, but redirects all requests to a fixed target."""
227
228    description = "reverse proxy"
229    transport_protocol = TCP
230    scheme: Literal[
231        "http", "https", "http3", "tls", "dtls", "tcp", "udp", "dns", "quic"
232    ]
233    address: tuple[str, int]
234
235    # noinspection PyDataclass
236    def __post_init__(self) -> None:
237        self.scheme, self.address = server_spec.parse(self.data, default_scheme="https")
238        if self.scheme in ("http3", "dtls", "udp", "quic"):
239            self.transport_protocol = UDP
240        elif self.scheme in ("dns", "https"):
241            self.transport_protocol = BOTH
242        self.description = f"{self.description} to {self.data}"
243
244    @property
245    def default_port(self) -> int | None:
246        if self.scheme == "dns":
247            return 53
248        return super().default_port
249
250
251class Socks5Mode(ProxyMode):
252    """A SOCKSv5 proxy."""
253
254    description = "SOCKS v5 proxy"
255    default_port = 1080
256    transport_protocol = TCP
257
258    def __post_init__(self) -> None:
259        _check_empty(self.data)
260
261
262class DnsMode(ProxyMode):
263    """A DNS server."""
264
265    description = "DNS server"
266    default_port = 53
267    transport_protocol = BOTH
268
269    def __post_init__(self) -> None:
270        _check_empty(self.data)
271
272
273# class Http3Mode(ProxyMode):
274#     """
275#     A regular HTTP3 proxy that is interfaced with absolute-form HTTP requests.
276#     (This class will be merged into `RegularMode` once the UDP implementation is deemed stable enough.)
277#     """
278#
279#     description = "HTTP3 proxy"
280#     transport_protocol = UDP
281#
282#     def __post_init__(self) -> None:
283#         _check_empty(self.data)
284
285
286class WireGuardMode(ProxyMode):
287    """Proxy Server based on WireGuard"""
288
289    description = "WireGuard server"
290    default_port = 51820
291    transport_protocol = UDP
292
293    def __post_init__(self) -> None:
294        pass
295
296
297class LocalMode(ProxyMode):
298    """OS-level transparent proxy."""
299
300    description = "Local redirector"
301    transport_protocol = BOTH
302    default_port = None
303
304    def __post_init__(self) -> None:
305        # should not raise
306        mitmproxy_rs.local.LocalRedirector.describe_spec(self.data)
307
308
309class TunMode(ProxyMode):
310    """A Tun interface."""
311
312    description = "TUN interface"
313    default_port = None
314    transport_protocol = BOTH
315
316    def __post_init__(self) -> None:
317        invalid_tun_name = self.data and (
318            # The Rust side is Linux only for the moment, but eventually we may need this.
319            platform.system() == "Darwin" and not re.match(r"^utun\d+$", self.data)
320        )
321        if invalid_tun_name:  # pragma: no cover
322            raise ValueError(
323                f"Invalid tun name: {self.data}. "
324                f"On macOS, the tun name must be the form utunx where x is a number, such as utun3."
325            )
326
327
328class OsProxyMode(ProxyMode):  # pragma: no cover
329    """Deprecated alias for LocalMode"""
330
331    description = "Deprecated alias for LocalMode"
332    transport_protocol = BOTH
333    default_port = None
334
335    def __post_init__(self) -> None:
336        raise ValueError(
337            "osproxy mode has been renamed to local mode. Thanks for trying our experimental features!"
338        )
@dataclass(frozen=True)
class ProxyMode(mitmproxy.coretypes.serializable.Serializable):
 47@dataclass(frozen=True)  # type: ignore
 48class ProxyMode(Serializable, metaclass=ABCMeta):
 49    """
 50    Parsed representation of a proxy mode spec. Subclassed for each specific mode,
 51    which then does its own data validation.
 52    """
 53
 54    full_spec: str
 55    """The full proxy mode spec as entered by the user."""
 56    data: str
 57    """The (raw) mode data, i.e. the part after the mode name."""
 58    custom_listen_host: str | None
 59    """A custom listen host, if specified in the spec."""
 60    custom_listen_port: int | None
 61    """A custom listen port, if specified in the spec."""
 62
 63    type_name: ClassVar[
 64        str
 65    ]  # automatically derived from the class name in __init_subclass__
 66    """The unique name for this proxy mode, e.g. "regular" or "reverse"."""
 67    __types: ClassVar[dict[str, type[ProxyMode]]] = {}
 68
 69    def __init_subclass__(cls, **kwargs):
 70        cls.type_name = cls.__name__.removesuffix("Mode").lower()
 71        assert cls.type_name not in ProxyMode.__types
 72        ProxyMode.__types[cls.type_name] = cls
 73
 74    def __repr__(self):
 75        return f"ProxyMode.parse({self.full_spec!r})"
 76
 77    @abstractmethod
 78    def __post_init__(self) -> None:
 79        """Validation of data happens here."""
 80
 81    @property
 82    @abstractmethod
 83    def description(self) -> str:
 84        """The mode description that will be used in server logs and UI."""
 85
 86    @property
 87    def default_port(self) -> int | None:
 88        """
 89        Default listen port of servers for this mode, see `ProxyMode.listen_port()`.
 90        """
 91        return 8080
 92
 93    @property
 94    @abstractmethod
 95    def transport_protocol(self) -> Literal["tcp", "udp", "both"]:
 96        """The transport protocol used by this mode's server."""
 97
 98    @classmethod
 99    @cache
100    def parse(cls, spec: str) -> Self:
101        """
102        Parse a proxy mode specification and return the corresponding `ProxyMode` instance.
103        """
104        head, _, listen_at = spec.rpartition("@")
105        if not head:
106            head = listen_at
107            listen_at = ""
108
109        mode, _, data = head.partition(":")
110
111        if listen_at:
112            if ":" in listen_at:
113                host, _, port_str = listen_at.rpartition(":")
114            else:
115                host = None
116                port_str = listen_at
117            try:
118                port = int(port_str)
119                if port < 0 or 65535 < port:
120                    raise ValueError
121            except ValueError:
122                raise ValueError(f"invalid port: {port_str}")
123        else:
124            host = None
125            port = None
126
127        try:
128            mode_cls = ProxyMode.__types[mode.lower()]
129        except KeyError:
130            raise ValueError(f"unknown mode")
131
132        if not issubclass(mode_cls, cls):
133            raise ValueError(f"{mode!r} is not a spec for a {cls.type_name} mode")
134
135        return mode_cls(
136            full_spec=spec, data=data, custom_listen_host=host, custom_listen_port=port
137        )
138
139    def listen_host(self, default: str | None = None) -> str:
140        """
141        Return the address a server for this mode should listen on. This can be either directly
142        specified in the spec or taken from a user-configured global default (`options.listen_host`).
143        By default, return an empty string to listen on all hosts.
144        """
145        if self.custom_listen_host is not None:
146            return self.custom_listen_host
147        elif default is not None:
148            return default
149        else:
150            return ""
151
152    def listen_port(self, default: int | None = None) -> int | None:
153        """
154        Return the port a server for this mode should listen on. This can be either directly
155        specified in the spec, taken from a user-configured global default (`options.listen_port`),
156        or from `ProxyMode.default_port`.
157        May be `None` for modes that don't bind to a specific address, e.g. local redirect mode.
158        """
159        if self.custom_listen_port is not None:
160            return self.custom_listen_port
161        elif self.default_port is None:
162            return None
163        elif default is not None:
164            return default
165        else:
166            return self.default_port
167
168    @classmethod
169    def from_state(cls, state):
170        return ProxyMode.parse(state)
171
172    def get_state(self):
173        return self.full_spec
174
175    def set_state(self, state):
176        if state != self.full_spec:
177            raise dataclasses.FrozenInstanceError("Proxy modes are immutable.")

Parsed representation of a proxy mode spec. Subclassed for each specific mode, which then does its own data validation.

full_spec: str

The full proxy mode spec as entered by the user.

data: str

The (raw) mode data, i.e. the part after the mode name.

custom_listen_host: str | None

A custom listen host, if specified in the spec.

custom_listen_port: int | None

A custom listen port, if specified in the spec.

type_name: ClassVar[str]

The unique name for this proxy mode, e.g. "regular" or "reverse".

description: str
81    @property
82    @abstractmethod
83    def description(self) -> str:
84        """The mode description that will be used in server logs and UI."""

The mode description that will be used in server logs and UI.

default_port: int | None
86    @property
87    def default_port(self) -> int | None:
88        """
89        Default listen port of servers for this mode, see `ProxyMode.listen_port()`.
90        """
91        return 8080

Default listen port of servers for this mode, see ProxyMode.listen_port().

transport_protocol: Literal['tcp', 'udp', 'both']
93    @property
94    @abstractmethod
95    def transport_protocol(self) -> Literal["tcp", "udp", "both"]:
96        """The transport protocol used by this mode's server."""

The transport protocol used by this mode's server.

@classmethod
@cache
def parse(cls, spec: str) -> Self:
 98    @classmethod
 99    @cache
100    def parse(cls, spec: str) -> Self:
101        """
102        Parse a proxy mode specification and return the corresponding `ProxyMode` instance.
103        """
104        head, _, listen_at = spec.rpartition("@")
105        if not head:
106            head = listen_at
107            listen_at = ""
108
109        mode, _, data = head.partition(":")
110
111        if listen_at:
112            if ":" in listen_at:
113                host, _, port_str = listen_at.rpartition(":")
114            else:
115                host = None
116                port_str = listen_at
117            try:
118                port = int(port_str)
119                if port < 0 or 65535 < port:
120                    raise ValueError
121            except ValueError:
122                raise ValueError(f"invalid port: {port_str}")
123        else:
124            host = None
125            port = None
126
127        try:
128            mode_cls = ProxyMode.__types[mode.lower()]
129        except KeyError:
130            raise ValueError(f"unknown mode")
131
132        if not issubclass(mode_cls, cls):
133            raise ValueError(f"{mode!r} is not a spec for a {cls.type_name} mode")
134
135        return mode_cls(
136            full_spec=spec, data=data, custom_listen_host=host, custom_listen_port=port
137        )

Parse a proxy mode specification and return the corresponding ProxyMode instance.

def listen_host(self, default: str | None = None) -> str:
139    def listen_host(self, default: str | None = None) -> str:
140        """
141        Return the address a server for this mode should listen on. This can be either directly
142        specified in the spec or taken from a user-configured global default (`options.listen_host`).
143        By default, return an empty string to listen on all hosts.
144        """
145        if self.custom_listen_host is not None:
146            return self.custom_listen_host
147        elif default is not None:
148            return default
149        else:
150            return ""

Return the address a server for this mode should listen on. This can be either directly specified in the spec or taken from a user-configured global default (options.listen_host). By default, return an empty string to listen on all hosts.

def listen_port(self, default: int | None = None) -> int | None:
152    def listen_port(self, default: int | None = None) -> int | None:
153        """
154        Return the port a server for this mode should listen on. This can be either directly
155        specified in the spec, taken from a user-configured global default (`options.listen_port`),
156        or from `ProxyMode.default_port`.
157        May be `None` for modes that don't bind to a specific address, e.g. local redirect mode.
158        """
159        if self.custom_listen_port is not None:
160            return self.custom_listen_port
161        elif self.default_port is None:
162            return None
163        elif default is not None:
164            return default
165        else:
166            return self.default_port

Return the port a server for this mode should listen on. This can be either directly specified in the spec, taken from a user-configured global default (options.listen_port), or from ProxyMode.default_port. May be None for modes that don't bind to a specific address, e.g. local redirect mode.

TCP: Literal['tcp', 'udp', 'both'] = 'tcp'
UDP: Literal['tcp', 'udp', 'both'] = 'udp'
BOTH: Literal['tcp', 'udp', 'both'] = 'both'
class RegularMode(ProxyMode):
190class RegularMode(ProxyMode):
191    """A regular HTTP(S) proxy that is interfaced with `HTTP CONNECT` calls (or absolute-form HTTP requests)."""
192
193    description = "HTTP(S) proxy"
194    transport_protocol = TCP
195
196    def __post_init__(self) -> None:
197        _check_empty(self.data)

A regular HTTP(S) proxy that is interfaced with HTTP CONNECT calls (or absolute-form HTTP requests).

description = 'HTTP(S) proxy'

The mode description that will be used in server logs and UI.

transport_protocol = 'tcp'

The transport protocol used by this mode's server.

type_name: ClassVar[str] = 'regular'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class TransparentMode(ProxyMode):
200class TransparentMode(ProxyMode):
201    """A transparent proxy, see https://docs.mitmproxy.org/dev/howto-transparent/"""
202
203    description = "Transparent Proxy"
204    transport_protocol = TCP
205
206    def __post_init__(self) -> None:
207        _check_empty(self.data)
description = 'Transparent Proxy'

The mode description that will be used in server logs and UI.

transport_protocol = 'tcp'

The transport protocol used by this mode's server.

type_name: ClassVar[str] = 'transparent'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class UpstreamMode(ProxyMode):
210class UpstreamMode(ProxyMode):
211    """A regular HTTP(S) proxy, but all connections are forwarded to a second upstream HTTP(S) proxy."""
212
213    description = "HTTP(S) proxy (upstream mode)"
214    transport_protocol = TCP
215    scheme: Literal["http", "https"]
216    address: tuple[str, int]
217
218    # noinspection PyDataclass
219    def __post_init__(self) -> None:
220        scheme, self.address = server_spec.parse(self.data, default_scheme="http")
221        if scheme != "http" and scheme != "https":
222            raise ValueError("invalid upstream proxy scheme")
223        self.scheme = scheme

A regular HTTP(S) proxy, but all connections are forwarded to a second upstream HTTP(S) proxy.

description = 'HTTP(S) proxy (upstream mode)'

The mode description that will be used in server logs and UI.

transport_protocol = 'tcp'

The transport protocol used by this mode's server.

scheme: Literal['http', 'https']
address: tuple[str, int]
type_name: ClassVar[str] = 'upstream'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class ReverseMode(ProxyMode):
226class ReverseMode(ProxyMode):
227    """A reverse proxy. This acts like a normal server, but redirects all requests to a fixed target."""
228
229    description = "reverse proxy"
230    transport_protocol = TCP
231    scheme: Literal[
232        "http", "https", "http3", "tls", "dtls", "tcp", "udp", "dns", "quic"
233    ]
234    address: tuple[str, int]
235
236    # noinspection PyDataclass
237    def __post_init__(self) -> None:
238        self.scheme, self.address = server_spec.parse(self.data, default_scheme="https")
239        if self.scheme in ("http3", "dtls", "udp", "quic"):
240            self.transport_protocol = UDP
241        elif self.scheme in ("dns", "https"):
242            self.transport_protocol = BOTH
243        self.description = f"{self.description} to {self.data}"
244
245    @property
246    def default_port(self) -> int | None:
247        if self.scheme == "dns":
248            return 53
249        return super().default_port

A reverse proxy. This acts like a normal server, but redirects all requests to a fixed target.

description = 'reverse proxy'

The mode description that will be used in server logs and UI.

transport_protocol = 'tcp'

The transport protocol used by this mode's server.

scheme: Literal['http', 'https', 'http3', 'tls', 'dtls', 'tcp', 'udp', 'dns', 'quic']
address: tuple[str, int]
default_port: int | None
245    @property
246    def default_port(self) -> int | None:
247        if self.scheme == "dns":
248            return 53
249        return super().default_port

Default listen port of servers for this mode, see ProxyMode.listen_port().

type_name: ClassVar[str] = 'reverse'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class Socks5Mode(ProxyMode):
252class Socks5Mode(ProxyMode):
253    """A SOCKSv5 proxy."""
254
255    description = "SOCKS v5 proxy"
256    default_port = 1080
257    transport_protocol = TCP
258
259    def __post_init__(self) -> None:
260        _check_empty(self.data)

A SOCKSv5 proxy.

description = 'SOCKS v5 proxy'

The mode description that will be used in server logs and UI.

default_port = 1080

Default listen port of servers for this mode, see ProxyMode.listen_port().

transport_protocol = 'tcp'

The transport protocol used by this mode's server.

type_name: ClassVar[str] = 'socks5'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class DnsMode(ProxyMode):
263class DnsMode(ProxyMode):
264    """A DNS server."""
265
266    description = "DNS server"
267    default_port = 53
268    transport_protocol = BOTH
269
270    def __post_init__(self) -> None:
271        _check_empty(self.data)

A DNS server.

description = 'DNS server'

The mode description that will be used in server logs and UI.

default_port = 53

Default listen port of servers for this mode, see ProxyMode.listen_port().

transport_protocol = 'both'

The transport protocol used by this mode's server.

type_name: ClassVar[str] = 'dns'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class WireGuardMode(ProxyMode):
287class WireGuardMode(ProxyMode):
288    """Proxy Server based on WireGuard"""
289
290    description = "WireGuard server"
291    default_port = 51820
292    transport_protocol = UDP
293
294    def __post_init__(self) -> None:
295        pass

Proxy Server based on WireGuard

description = 'WireGuard server'

The mode description that will be used in server logs and UI.

default_port = 51820

Default listen port of servers for this mode, see ProxyMode.listen_port().

transport_protocol = 'udp'

The transport protocol used by this mode's server.

type_name: ClassVar[str] = 'wireguard'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class LocalMode(ProxyMode):
298class LocalMode(ProxyMode):
299    """OS-level transparent proxy."""
300
301    description = "Local redirector"
302    transport_protocol = BOTH
303    default_port = None
304
305    def __post_init__(self) -> None:
306        # should not raise
307        mitmproxy_rs.local.LocalRedirector.describe_spec(self.data)

OS-level transparent proxy.

description = 'Local redirector'

The mode description that will be used in server logs and UI.

transport_protocol = 'both'

The transport protocol used by this mode's server.

default_port = None

Default listen port of servers for this mode, see ProxyMode.listen_port().

type_name: ClassVar[str] = 'local'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class TunMode(ProxyMode):
310class TunMode(ProxyMode):
311    """A Tun interface."""
312
313    description = "TUN interface"
314    default_port = None
315    transport_protocol = BOTH
316
317    def __post_init__(self) -> None:
318        invalid_tun_name = self.data and (
319            # The Rust side is Linux only for the moment, but eventually we may need this.
320            platform.system() == "Darwin" and not re.match(r"^utun\d+$", self.data)
321        )
322        if invalid_tun_name:  # pragma: no cover
323            raise ValueError(
324                f"Invalid tun name: {self.data}. "
325                f"On macOS, the tun name must be the form utunx where x is a number, such as utun3."
326            )

A Tun interface.

description = 'TUN interface'

The mode description that will be used in server logs and UI.

default_port = None

Default listen port of servers for this mode, see ProxyMode.listen_port().

transport_protocol = 'both'

The transport protocol used by this mode's server.

type_name: ClassVar[str] = 'tun'

The unique name for this proxy mode, e.g. "regular" or "reverse".

class OsProxyMode(ProxyMode):
329class OsProxyMode(ProxyMode):  # pragma: no cover
330    """Deprecated alias for LocalMode"""
331
332    description = "Deprecated alias for LocalMode"
333    transport_protocol = BOTH
334    default_port = None
335
336    def __post_init__(self) -> None:
337        raise ValueError(
338            "osproxy mode has been renamed to local mode. Thanks for trying our experimental features!"
339        )

Deprecated alias for LocalMode

description = 'Deprecated alias for LocalMode'

The mode description that will be used in server logs and UI.

transport_protocol = 'both'

The transport protocol used by this mode's server.

default_port = None

Default listen port of servers for this mode, see ProxyMode.listen_port().

type_name: ClassVar[str] = 'osproxy'

The unique name for this proxy mode, e.g. "regular" or "reverse".

built with pdocpdoc logo