mitmproxy.connection
1import dataclasses 2import time 3import uuid 4import warnings 5from abc import ABCMeta 6from collections.abc import Sequence 7from dataclasses import dataclass 8from dataclasses import field 9from enum import Flag 10from typing import Literal 11 12from mitmproxy import certs 13from mitmproxy.coretypes import serializable 14from mitmproxy.net import server_spec 15from mitmproxy.proxy import mode_specs 16from mitmproxy.utils import human 17 18 19class ConnectionState(Flag): 20 """The current state of the underlying socket.""" 21 22 CLOSED = 0 23 CAN_READ = 1 24 CAN_WRITE = 2 25 OPEN = CAN_READ | CAN_WRITE 26 27 28TransportProtocol = Literal["tcp", "udp"] 29 30 31# practically speaking we may have IPv6 addresses with flowinfo and scope_id, 32# but type checking isn't good enough to properly handle tuple unions. 33# this version at least provides useful type checking messages. 34Address = tuple[str, int] 35 36kw_only = {"kw_only": True} 37 38 39# noinspection PyDataclass 40@dataclass(**kw_only) 41class Connection(serializable.SerializableDataclass, metaclass=ABCMeta): 42 """ 43 Base class for client and server connections. 44 45 The connection object only exposes metadata about the connection, but not the underlying socket object. 46 This is intentional, all I/O should be handled by `mitmproxy.proxy.server` exclusively. 47 """ 48 49 peername: Address | None 50 """The remote's `(ip, port)` tuple for this connection.""" 51 sockname: Address | None 52 """Our local `(ip, port)` tuple for this connection.""" 53 54 state: ConnectionState = field( 55 default=ConnectionState.CLOSED, metadata={"serialize": False} 56 ) 57 """The current connection state.""" 58 59 # all connections have a unique id. While 60 # f.client_conn == f2.client_conn already holds true for live flows (where we have object identity), 61 # we also want these semantics for recorded flows. 62 id: str = field(default_factory=lambda: str(uuid.uuid4())) 63 """A unique UUID to identify the connection.""" 64 transport_protocol: TransportProtocol = field(default="tcp") 65 """The connection protocol in use.""" 66 error: str | None = None 67 """ 68 A string describing a general error with connections to this address. 69 70 The purpose of this property is to signal that new connections to the particular endpoint should not be attempted, 71 for example because it uses an untrusted TLS certificate. Regular (unexpected) disconnects do not set the error 72 property. This property is only reused per client connection. 73 """ 74 75 tls: bool = False 76 """ 77 `True` if TLS should be established, `False` otherwise. 78 Note that this property only describes if a connection should eventually be protected using TLS. 79 To check if TLS has already been established, use `Connection.tls_established`. 80 """ 81 certificate_list: Sequence[certs.Cert] = () 82 """ 83 The TLS certificate list as sent by the peer. 84 The first certificate is the end-entity certificate. 85 86 > [RFC 8446] Prior to TLS 1.3, "certificate_list" ordering required each 87 > certificate to certify the one immediately preceding it; however, 88 > some implementations allowed some flexibility. Servers sometimes 89 > send both a current and deprecated intermediate for transitional 90 > purposes, and others are simply configured incorrectly, but these 91 > cases can nonetheless be validated properly. For maximum 92 > compatibility, all implementations SHOULD be prepared to handle 93 > potentially extraneous certificates and arbitrary orderings from any 94 > TLS version, with the exception of the end-entity certificate which 95 > MUST be first. 96 """ 97 alpn: bytes | None = None 98 """The application-layer protocol as negotiated using 99 [ALPN](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation).""" 100 alpn_offers: Sequence[bytes] = () 101 """The ALPN offers as sent in the ClientHello.""" 102 # we may want to add SSL_CIPHER_description here, but that's currently not exposed by cryptography 103 cipher: str | None = None 104 """The active cipher name as returned by OpenSSL's `SSL_CIPHER_get_name`.""" 105 cipher_list: Sequence[str] = () 106 """Ciphers accepted by the proxy server on this connection.""" 107 tls_version: str | None = None 108 """The active TLS version.""" 109 sni: str | None = None 110 """ 111 The [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) sent in the ClientHello. 112 """ 113 114 timestamp_start: float | None = None 115 timestamp_end: float | None = None 116 """*Timestamp:* Connection has been closed.""" 117 timestamp_tls_setup: float | None = None 118 """*Timestamp:* TLS handshake has been completed successfully.""" 119 120 @property 121 def connected(self) -> bool: 122 """*Read-only:* `True` if Connection.state is ConnectionState.OPEN, `False` otherwise.""" 123 return self.state is ConnectionState.OPEN 124 125 @property 126 def tls_established(self) -> bool: 127 """*Read-only:* `True` if TLS has been established, `False` otherwise.""" 128 return self.timestamp_tls_setup is not None 129 130 def __eq__(self, other): 131 if isinstance(other, Connection): 132 return self.id == other.id 133 return False 134 135 def __hash__(self): 136 return hash(self.id) 137 138 def __repr__(self): 139 attrs = { 140 # ensure these come first. 141 "id": None, 142 "address": None, 143 } 144 for f in dataclasses.fields(self): 145 val = getattr(self, f.name) 146 if val != f.default: 147 if f.name == "cipher_list": 148 val = f"<{len(val)} ciphers>" 149 elif f.name == "id": 150 val = f"…{val[-6:]}" 151 attrs[f.name] = val 152 return f"{type(self).__name__}({attrs!r})" 153 154 @property 155 def alpn_proto_negotiated(self) -> bytes | None: # pragma: no cover 156 """*Deprecated:* An outdated alias for Connection.alpn.""" 157 warnings.warn( 158 "Connection.alpn_proto_negotiated is deprecated, use Connection.alpn instead.", 159 DeprecationWarning, 160 stacklevel=2, 161 ) 162 return self.alpn 163 164 165# noinspection PyDataclass 166@dataclass(eq=False, repr=False, **kw_only) 167class Client(Connection): 168 """A connection between a client and mitmproxy.""" 169 170 peername: Address 171 """The client's address.""" 172 sockname: Address 173 """The local address we received this connection on.""" 174 175 mitmcert: certs.Cert | None = None 176 """ 177 The certificate used by mitmproxy to establish TLS with the client. 178 """ 179 180 proxy_mode: mode_specs.ProxyMode = field( 181 default=mode_specs.ProxyMode.parse("regular") 182 ) 183 """The proxy server type this client has been connecting to.""" 184 185 timestamp_start: float = field(default_factory=time.time) 186 """*Timestamp:* TCP SYN received""" 187 188 def __str__(self): 189 if self.alpn: 190 tls_state = f", alpn={self.alpn.decode(errors='replace')}" 191 elif self.tls_established: 192 tls_state = ", tls" 193 else: 194 tls_state = "" 195 state = self.state.name 196 assert state 197 return f"Client({human.format_address(self.peername)}, state={state.lower()}{tls_state})" 198 199 @property 200 def address(self): # pragma: no cover 201 """*Deprecated:* An outdated alias for Client.peername.""" 202 warnings.warn( 203 "Client.address is deprecated, use Client.peername instead.", 204 DeprecationWarning, 205 stacklevel=2, 206 ) 207 return self.peername 208 209 @address.setter 210 def address(self, x): # pragma: no cover 211 warnings.warn( 212 "Client.address is deprecated, use Client.peername instead.", 213 DeprecationWarning, 214 stacklevel=2, 215 ) 216 self.peername = x 217 218 @property 219 def cipher_name(self) -> str | None: # pragma: no cover 220 """*Deprecated:* An outdated alias for Connection.cipher.""" 221 warnings.warn( 222 "Client.cipher_name is deprecated, use Client.cipher instead.", 223 DeprecationWarning, 224 stacklevel=2, 225 ) 226 return self.cipher 227 228 @property 229 def clientcert(self) -> certs.Cert | None: # pragma: no cover 230 """*Deprecated:* An outdated alias for Connection.certificate_list[0].""" 231 warnings.warn( 232 "Client.clientcert is deprecated, use Client.certificate_list instead.", 233 DeprecationWarning, 234 stacklevel=2, 235 ) 236 if self.certificate_list: 237 return self.certificate_list[0] 238 else: 239 return None 240 241 @clientcert.setter 242 def clientcert(self, val): # pragma: no cover 243 warnings.warn( 244 "Client.clientcert is deprecated, use Client.certificate_list instead.", 245 DeprecationWarning, 246 stacklevel=2, 247 ) 248 if val: 249 self.certificate_list = [val] 250 else: 251 self.certificate_list = [] 252 253 254# noinspection PyDataclass 255@dataclass(eq=False, repr=False, **kw_only) 256class Server(Connection): 257 """A connection between mitmproxy and an upstream server.""" 258 259 address: Address | None # type: ignore 260 """ 261 The server's `(host, port)` address tuple. 262 263 The host can either be a domain or a plain IP address. 264 Which of those two will be present depends on the proxy mode and the client. 265 For explicit proxies, this value will reflect what the client instructs mitmproxy to connect to. 266 For example, if the client starts off a connection with `CONNECT example.com HTTP/1.1`, it will be `example.com`. 267 For transparent proxies such as WireGuard mode, this value will be an IP address. 268 """ 269 270 peername: Address | None = None 271 """ 272 The server's resolved `(ip, port)` tuple. Will be set during connection establishment. 273 May be `None` in upstream proxy mode when the address is resolved by the upstream proxy only. 274 """ 275 sockname: Address | None = None 276 277 timestamp_start: float | None = None 278 """ 279 *Timestamp:* Connection establishment started. 280 281 For IP addresses, this corresponds to sending a TCP SYN; for domains, this corresponds to starting a DNS lookup. 282 """ 283 timestamp_tcp_setup: float | None = None 284 """*Timestamp:* TCP ACK received.""" 285 286 via: server_spec.ServerSpec | None = None 287 """An optional proxy server specification via which the connection should be established.""" 288 289 def __str__(self): 290 if self.alpn: 291 tls_state = f", alpn={self.alpn.decode(errors='replace')}" 292 elif self.tls_established: 293 tls_state = ", tls" 294 else: 295 tls_state = "" 296 if self.sockname: 297 local_port = f", src_port={self.sockname[1]}" 298 else: 299 local_port = "" 300 state = self.state.name 301 assert state 302 return f"Server({human.format_address(self.address)}, state={state.lower()}{tls_state}{local_port})" 303 304 def __setattr__(self, name, value): 305 if name in ("address", "via"): 306 connection_open = ( 307 self.__dict__.get("state", ConnectionState.CLOSED) 308 is ConnectionState.OPEN 309 ) 310 # assigning the current value is okay, that may be an artifact of calling .set_state(). 311 attr_changed = self.__dict__.get(name) != value 312 if connection_open and attr_changed: 313 raise RuntimeError(f"Cannot change server.{name} on open connection.") 314 return super().__setattr__(name, value) 315 316 @property 317 def ip_address(self) -> Address | None: # pragma: no cover 318 """*Deprecated:* An outdated alias for `Server.peername`.""" 319 warnings.warn( 320 "Server.ip_address is deprecated, use Server.peername instead.", 321 DeprecationWarning, 322 stacklevel=2, 323 ) 324 return self.peername 325 326 @property 327 def cert(self) -> certs.Cert | None: # pragma: no cover 328 """*Deprecated:* An outdated alias for `Connection.certificate_list[0]`.""" 329 warnings.warn( 330 "Server.cert is deprecated, use Server.certificate_list instead.", 331 DeprecationWarning, 332 stacklevel=2, 333 ) 334 if self.certificate_list: 335 return self.certificate_list[0] 336 else: 337 return None 338 339 @cert.setter 340 def cert(self, val): # pragma: no cover 341 warnings.warn( 342 "Server.cert is deprecated, use Server.certificate_list instead.", 343 DeprecationWarning, 344 stacklevel=2, 345 ) 346 if val: 347 self.certificate_list = [val] 348 else: 349 self.certificate_list = [] 350 351 352__all__ = ["Connection", "Client", "Server", "ConnectionState"]
41@dataclass(**kw_only) 42class Connection(serializable.SerializableDataclass, metaclass=ABCMeta): 43 """ 44 Base class for client and server connections. 45 46 The connection object only exposes metadata about the connection, but not the underlying socket object. 47 This is intentional, all I/O should be handled by `mitmproxy.proxy.server` exclusively. 48 """ 49 50 peername: Address | None 51 """The remote's `(ip, port)` tuple for this connection.""" 52 sockname: Address | None 53 """Our local `(ip, port)` tuple for this connection.""" 54 55 state: ConnectionState = field( 56 default=ConnectionState.CLOSED, metadata={"serialize": False} 57 ) 58 """The current connection state.""" 59 60 # all connections have a unique id. While 61 # f.client_conn == f2.client_conn already holds true for live flows (where we have object identity), 62 # we also want these semantics for recorded flows. 63 id: str = field(default_factory=lambda: str(uuid.uuid4())) 64 """A unique UUID to identify the connection.""" 65 transport_protocol: TransportProtocol = field(default="tcp") 66 """The connection protocol in use.""" 67 error: str | None = None 68 """ 69 A string describing a general error with connections to this address. 70 71 The purpose of this property is to signal that new connections to the particular endpoint should not be attempted, 72 for example because it uses an untrusted TLS certificate. Regular (unexpected) disconnects do not set the error 73 property. This property is only reused per client connection. 74 """ 75 76 tls: bool = False 77 """ 78 `True` if TLS should be established, `False` otherwise. 79 Note that this property only describes if a connection should eventually be protected using TLS. 80 To check if TLS has already been established, use `Connection.tls_established`. 81 """ 82 certificate_list: Sequence[certs.Cert] = () 83 """ 84 The TLS certificate list as sent by the peer. 85 The first certificate is the end-entity certificate. 86 87 > [RFC 8446] Prior to TLS 1.3, "certificate_list" ordering required each 88 > certificate to certify the one immediately preceding it; however, 89 > some implementations allowed some flexibility. Servers sometimes 90 > send both a current and deprecated intermediate for transitional 91 > purposes, and others are simply configured incorrectly, but these 92 > cases can nonetheless be validated properly. For maximum 93 > compatibility, all implementations SHOULD be prepared to handle 94 > potentially extraneous certificates and arbitrary orderings from any 95 > TLS version, with the exception of the end-entity certificate which 96 > MUST be first. 97 """ 98 alpn: bytes | None = None 99 """The application-layer protocol as negotiated using 100 [ALPN](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation).""" 101 alpn_offers: Sequence[bytes] = () 102 """The ALPN offers as sent in the ClientHello.""" 103 # we may want to add SSL_CIPHER_description here, but that's currently not exposed by cryptography 104 cipher: str | None = None 105 """The active cipher name as returned by OpenSSL's `SSL_CIPHER_get_name`.""" 106 cipher_list: Sequence[str] = () 107 """Ciphers accepted by the proxy server on this connection.""" 108 tls_version: str | None = None 109 """The active TLS version.""" 110 sni: str | None = None 111 """ 112 The [Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication) sent in the ClientHello. 113 """ 114 115 timestamp_start: float | None = None 116 timestamp_end: float | None = None 117 """*Timestamp:* Connection has been closed.""" 118 timestamp_tls_setup: float | None = None 119 """*Timestamp:* TLS handshake has been completed successfully.""" 120 121 @property 122 def connected(self) -> bool: 123 """*Read-only:* `True` if Connection.state is ConnectionState.OPEN, `False` otherwise.""" 124 return self.state is ConnectionState.OPEN 125 126 @property 127 def tls_established(self) -> bool: 128 """*Read-only:* `True` if TLS has been established, `False` otherwise.""" 129 return self.timestamp_tls_setup is not None 130 131 def __eq__(self, other): 132 if isinstance(other, Connection): 133 return self.id == other.id 134 return False 135 136 def __hash__(self): 137 return hash(self.id) 138 139 def __repr__(self): 140 attrs = { 141 # ensure these come first. 142 "id": None, 143 "address": None, 144 } 145 for f in dataclasses.fields(self): 146 val = getattr(self, f.name) 147 if val != f.default: 148 if f.name == "cipher_list": 149 val = f"<{len(val)} ciphers>" 150 elif f.name == "id": 151 val = f"…{val[-6:]}" 152 attrs[f.name] = val 153 return f"{type(self).__name__}({attrs!r})" 154 155 @property 156 def alpn_proto_negotiated(self) -> bytes | None: # pragma: no cover 157 """*Deprecated:* An outdated alias for Connection.alpn.""" 158 warnings.warn( 159 "Connection.alpn_proto_negotiated is deprecated, use Connection.alpn instead.", 160 DeprecationWarning, 161 stacklevel=2, 162 ) 163 return self.alpn
Base class for client and server connections.
The connection object only exposes metadata about the connection, but not the underlying socket object.
This is intentional, all I/O should be handled by mitmproxy.proxy.server
exclusively.
A string describing a general error with connections to this address.
The purpose of this property is to signal that new connections to the particular endpoint should not be attempted, for example because it uses an untrusted TLS certificate. Regular (unexpected) disconnects do not set the error property. This property is only reused per client connection.
True
if TLS should be established, False
otherwise.
Note that this property only describes if a connection should eventually be protected using TLS.
To check if TLS has already been established, use Connection.tls_established
.
The TLS certificate list as sent by the peer. The first certificate is the end-entity certificate.
[RFC 8446] Prior to TLS 1.3, "certificate_list" ordering required each certificate to certify the one immediately preceding it; however, some implementations allowed some flexibility. Servers sometimes send both a current and deprecated intermediate for transitional purposes, and others are simply configured incorrectly, but these cases can nonetheless be validated properly. For maximum compatibility, all implementations SHOULD be prepared to handle potentially extraneous certificates and arbitrary orderings from any TLS version, with the exception of the end-entity certificate which MUST be first.
Ciphers accepted by the proxy server on this connection.
121 @property 122 def connected(self) -> bool: 123 """*Read-only:* `True` if Connection.state is ConnectionState.OPEN, `False` otherwise.""" 124 return self.state is ConnectionState.OPEN
Read-only: True
if Connection.state is ConnectionState.OPEN, False
otherwise.
126 @property 127 def tls_established(self) -> bool: 128 """*Read-only:* `True` if TLS has been established, `False` otherwise.""" 129 return self.timestamp_tls_setup is not None
Read-only: True
if TLS has been established, False
otherwise.
155 @property 156 def alpn_proto_negotiated(self) -> bytes | None: # pragma: no cover 157 """*Deprecated:* An outdated alias for Connection.alpn.""" 158 warnings.warn( 159 "Connection.alpn_proto_negotiated is deprecated, use Connection.alpn instead.", 160 DeprecationWarning, 161 stacklevel=2, 162 ) 163 return self.alpn
Deprecated: An outdated alias for Connection.alpn.
Inherited Members
- mitmproxy.coretypes.serializable.Serializable
- copy
167@dataclass(eq=False, repr=False, **kw_only) 168class Client(Connection): 169 """A connection between a client and mitmproxy.""" 170 171 peername: Address 172 """The client's address.""" 173 sockname: Address 174 """The local address we received this connection on.""" 175 176 mitmcert: certs.Cert | None = None 177 """ 178 The certificate used by mitmproxy to establish TLS with the client. 179 """ 180 181 proxy_mode: mode_specs.ProxyMode = field( 182 default=mode_specs.ProxyMode.parse("regular") 183 ) 184 """The proxy server type this client has been connecting to.""" 185 186 timestamp_start: float = field(default_factory=time.time) 187 """*Timestamp:* TCP SYN received""" 188 189 def __str__(self): 190 if self.alpn: 191 tls_state = f", alpn={self.alpn.decode(errors='replace')}" 192 elif self.tls_established: 193 tls_state = ", tls" 194 else: 195 tls_state = "" 196 state = self.state.name 197 assert state 198 return f"Client({human.format_address(self.peername)}, state={state.lower()}{tls_state})" 199 200 @property 201 def address(self): # pragma: no cover 202 """*Deprecated:* An outdated alias for Client.peername.""" 203 warnings.warn( 204 "Client.address is deprecated, use Client.peername instead.", 205 DeprecationWarning, 206 stacklevel=2, 207 ) 208 return self.peername 209 210 @address.setter 211 def address(self, x): # pragma: no cover 212 warnings.warn( 213 "Client.address is deprecated, use Client.peername instead.", 214 DeprecationWarning, 215 stacklevel=2, 216 ) 217 self.peername = x 218 219 @property 220 def cipher_name(self) -> str | None: # pragma: no cover 221 """*Deprecated:* An outdated alias for Connection.cipher.""" 222 warnings.warn( 223 "Client.cipher_name is deprecated, use Client.cipher instead.", 224 DeprecationWarning, 225 stacklevel=2, 226 ) 227 return self.cipher 228 229 @property 230 def clientcert(self) -> certs.Cert | None: # pragma: no cover 231 """*Deprecated:* An outdated alias for Connection.certificate_list[0].""" 232 warnings.warn( 233 "Client.clientcert is deprecated, use Client.certificate_list instead.", 234 DeprecationWarning, 235 stacklevel=2, 236 ) 237 if self.certificate_list: 238 return self.certificate_list[0] 239 else: 240 return None 241 242 @clientcert.setter 243 def clientcert(self, val): # pragma: no cover 244 warnings.warn( 245 "Client.clientcert is deprecated, use Client.certificate_list instead.", 246 DeprecationWarning, 247 stacklevel=2, 248 ) 249 if val: 250 self.certificate_list = [val] 251 else: 252 self.certificate_list = []
A connection between a client and mitmproxy.
200 @property 201 def address(self): # pragma: no cover 202 """*Deprecated:* An outdated alias for Client.peername.""" 203 warnings.warn( 204 "Client.address is deprecated, use Client.peername instead.", 205 DeprecationWarning, 206 stacklevel=2, 207 ) 208 return self.peername
Deprecated: An outdated alias for Client.peername.
219 @property 220 def cipher_name(self) -> str | None: # pragma: no cover 221 """*Deprecated:* An outdated alias for Connection.cipher.""" 222 warnings.warn( 223 "Client.cipher_name is deprecated, use Client.cipher instead.", 224 DeprecationWarning, 225 stacklevel=2, 226 ) 227 return self.cipher
Deprecated: An outdated alias for Connection.cipher.
229 @property 230 def clientcert(self) -> certs.Cert | None: # pragma: no cover 231 """*Deprecated:* An outdated alias for Connection.certificate_list[0].""" 232 warnings.warn( 233 "Client.clientcert is deprecated, use Client.certificate_list instead.", 234 DeprecationWarning, 235 stacklevel=2, 236 ) 237 if self.certificate_list: 238 return self.certificate_list[0] 239 else: 240 return None
Deprecated: An outdated alias for Connection.certificate_list[0].
Inherited Members
- Connection
- state
- id
- transport_protocol
- error
- tls
- certificate_list
- alpn
- alpn_offers
- cipher
- cipher_list
- tls_version
- sni
- timestamp_end
- timestamp_tls_setup
- connected
- tls_established
- alpn_proto_negotiated
- mitmproxy.coretypes.serializable.Serializable
- copy
256@dataclass(eq=False, repr=False, **kw_only) 257class Server(Connection): 258 """A connection between mitmproxy and an upstream server.""" 259 260 address: Address | None # type: ignore 261 """ 262 The server's `(host, port)` address tuple. 263 264 The host can either be a domain or a plain IP address. 265 Which of those two will be present depends on the proxy mode and the client. 266 For explicit proxies, this value will reflect what the client instructs mitmproxy to connect to. 267 For example, if the client starts off a connection with `CONNECT example.com HTTP/1.1`, it will be `example.com`. 268 For transparent proxies such as WireGuard mode, this value will be an IP address. 269 """ 270 271 peername: Address | None = None 272 """ 273 The server's resolved `(ip, port)` tuple. Will be set during connection establishment. 274 May be `None` in upstream proxy mode when the address is resolved by the upstream proxy only. 275 """ 276 sockname: Address | None = None 277 278 timestamp_start: float | None = None 279 """ 280 *Timestamp:* Connection establishment started. 281 282 For IP addresses, this corresponds to sending a TCP SYN; for domains, this corresponds to starting a DNS lookup. 283 """ 284 timestamp_tcp_setup: float | None = None 285 """*Timestamp:* TCP ACK received.""" 286 287 via: server_spec.ServerSpec | None = None 288 """An optional proxy server specification via which the connection should be established.""" 289 290 def __str__(self): 291 if self.alpn: 292 tls_state = f", alpn={self.alpn.decode(errors='replace')}" 293 elif self.tls_established: 294 tls_state = ", tls" 295 else: 296 tls_state = "" 297 if self.sockname: 298 local_port = f", src_port={self.sockname[1]}" 299 else: 300 local_port = "" 301 state = self.state.name 302 assert state 303 return f"Server({human.format_address(self.address)}, state={state.lower()}{tls_state}{local_port})" 304 305 def __setattr__(self, name, value): 306 if name in ("address", "via"): 307 connection_open = ( 308 self.__dict__.get("state", ConnectionState.CLOSED) 309 is ConnectionState.OPEN 310 ) 311 # assigning the current value is okay, that may be an artifact of calling .set_state(). 312 attr_changed = self.__dict__.get(name) != value 313 if connection_open and attr_changed: 314 raise RuntimeError(f"Cannot change server.{name} on open connection.") 315 return super().__setattr__(name, value) 316 317 @property 318 def ip_address(self) -> Address | None: # pragma: no cover 319 """*Deprecated:* An outdated alias for `Server.peername`.""" 320 warnings.warn( 321 "Server.ip_address is deprecated, use Server.peername instead.", 322 DeprecationWarning, 323 stacklevel=2, 324 ) 325 return self.peername 326 327 @property 328 def cert(self) -> certs.Cert | None: # pragma: no cover 329 """*Deprecated:* An outdated alias for `Connection.certificate_list[0]`.""" 330 warnings.warn( 331 "Server.cert is deprecated, use Server.certificate_list instead.", 332 DeprecationWarning, 333 stacklevel=2, 334 ) 335 if self.certificate_list: 336 return self.certificate_list[0] 337 else: 338 return None 339 340 @cert.setter 341 def cert(self, val): # pragma: no cover 342 warnings.warn( 343 "Server.cert is deprecated, use Server.certificate_list instead.", 344 DeprecationWarning, 345 stacklevel=2, 346 ) 347 if val: 348 self.certificate_list = [val] 349 else: 350 self.certificate_list = []
A connection between mitmproxy and an upstream server.
The server's (host, port)
address tuple.
The host can either be a domain or a plain IP address.
Which of those two will be present depends on the proxy mode and the client.
For explicit proxies, this value will reflect what the client instructs mitmproxy to connect to.
For example, if the client starts off a connection with CONNECT example.com HTTP/1.1
, it will be example.com
.
For transparent proxies such as WireGuard mode, this value will be an IP address.
The server's resolved (ip, port)
tuple. Will be set during connection establishment.
May be None
in upstream proxy mode when the address is resolved by the upstream proxy only.
Timestamp: Connection establishment started.
For IP addresses, this corresponds to sending a TCP SYN; for domains, this corresponds to starting a DNS lookup.
An optional proxy server specification via which the connection should be established.
317 @property 318 def ip_address(self) -> Address | None: # pragma: no cover 319 """*Deprecated:* An outdated alias for `Server.peername`.""" 320 warnings.warn( 321 "Server.ip_address is deprecated, use Server.peername instead.", 322 DeprecationWarning, 323 stacklevel=2, 324 ) 325 return self.peername
Deprecated: An outdated alias for Server.peername
.
327 @property 328 def cert(self) -> certs.Cert | None: # pragma: no cover 329 """*Deprecated:* An outdated alias for `Connection.certificate_list[0]`.""" 330 warnings.warn( 331 "Server.cert is deprecated, use Server.certificate_list instead.", 332 DeprecationWarning, 333 stacklevel=2, 334 ) 335 if self.certificate_list: 336 return self.certificate_list[0] 337 else: 338 return None
Deprecated: An outdated alias for Connection.certificate_list[0]
.
Inherited Members
- Connection
- state
- id
- transport_protocol
- error
- tls
- certificate_list
- alpn
- alpn_offers
- cipher
- cipher_list
- tls_version
- sni
- timestamp_end
- timestamp_tls_setup
- connected
- tls_established
- alpn_proto_negotiated
- mitmproxy.coretypes.serializable.Serializable
- copy
20class ConnectionState(Flag): 21 """The current state of the underlying socket.""" 22 23 CLOSED = 0 24 CAN_READ = 1 25 CAN_WRITE = 2 26 OPEN = CAN_READ | CAN_WRITE
The current state of the underlying socket.
Inherited Members
- enum.Enum
- name
- value