proxy.core.connection package#

Submodules#

Module contents#

proxy.py#

⚡⚡⚡ Fast, Lightweight, Pluggable, TLS interception capable proxy server focused on Network monitoring, controls & Application development, testing, debugging.

copyright
  1. 2013-present by Abhinav Singh and contributors.

license

BSD, see LICENSE for more details.

class proxy.core.connection.TcpClientConnection(conn: Union[ssl.SSLSocket, socket.socket], addr: Optional[Tuple[str, int]] = None)[source]#

Bases: proxy.core.connection.connection.TcpConnection

A buffered client connection object.

_abc_impl = <_abc._abc_data object>#
property address: str#
property connection: Union[ssl.SSLSocket, socket.socket]#

Must return the socket connection to use in this class.

wrap(keyfile: str, certfile: str) None[source]#
class proxy.core.connection.TcpConnection(tag: int)[source]#

Bases: abc.ABC

TCP server/client connection abstraction.

Main motivation of this class is to provide a buffer management when reading and writing into the socket.

Implement the connection property abstract method to return a socket connection object.

_abc_impl = <_abc._abc_data object>#
close() bool[source]#
abstract property connection: Union[ssl.SSLSocket, socket.socket]#

Must return the socket connection to use in this class.

flush(max_send_size: Optional[int] = None) int[source]#

Users must handle BrokenPipeError exceptions

has_buffer() bool[source]#
is_reusable() bool[source]#
mark_inuse() None[source]#
queue(mv: memoryview) None[source]#
recv(buffer_size: int = 131072) Optional[memoryview][source]#

Users must handle socket.error exceptions

reset() None[source]#
send(data: Union[memoryview, bytes]) int[source]#

Users must handle BrokenPipeError exceptions

exception proxy.core.connection.TcpConnectionUninitializedException[source]#

Bases: Exception

class proxy.core.connection.TcpServerConnection(host: str, port: int)[source]#

Bases: proxy.core.connection.connection.TcpConnection

A buffered server connection object.

_abc_impl = <_abc._abc_data object>#
connect(addr: Optional[Tuple[str, int]] = None, source_address: Optional[Tuple[str, int]] = None) None[source]#
property connection: Union[ssl.SSLSocket, socket.socket]#

Must return the socket connection to use in this class.

wrap(hostname: Optional[str] = None, ca_file: Optional[str] = None, as_non_blocking: bool = False, verify_mode: ssl.VerifyMode = VerifyMode.CERT_REQUIRED) None[source]#
class proxy.core.connection.UpstreamConnectionPool[source]#

Bases: proxy.core.work.work.Work[proxy.core.connection.server.TcpServerConnection]

Manages connection pool to upstream servers.

UpstreamConnectionPool avoids need to reconnect with the upstream servers repeatedly when a reusable connection is available in the pool.

A separate pool is maintained for each upstream server. So internally, it’s a pool of pools.

Internal data structure maintains references to connection objects that pool owns or has borrowed. Borrowed connections are marked as NOT reusable.

For reusable connections only, pool listens for read events to detect broken connections. This can happen if pool has opened a connection, which was never used and eventually reaches upstream server timeout limit.

When a borrowed connection is returned back to the pool, the connection is marked as reusable again. However, if returned connection has already been closed, it is removed from the internal data structure.

TODO: Ideally, UpstreamConnectionPool must be shared across all cores to make SSL session cache to also work without additional out-of-bound synchronizations.

TODO: UpstreamConnectionPool currently WON’T work for HTTPS connection. This is because of missing support for session cache, session ticket, abbr TLS handshake and other necessary features to make it work.

NOTE: However, currently for all HTTP only upstream connections, UpstreamConnectionPool can be used to remove slow starts.

_abc_impl = <_abc._abc_data object>#
_add(conn: proxy.core.connection.server.TcpServerConnection) None[source]#

Adds a new connection to internal data structure.

_remove(fileno: int) None[source]#

Remove a connection by descriptor from the internal data structure.

acquire(addr: Tuple[str, int]) Tuple[bool, proxy.core.connection.server.TcpServerConnection][source]#

Returns a reusable connection from the pool.

If none exists, will create and return a new connection.

add(addr: Tuple[str, int]) proxy.core.connection.server.TcpServerConnection[source]#

Creates, connects and adds a new connection to the pool.

Returns newly created connection.

NOTE: You must not use the returned connection, instead use acquire.

static create(*args: Any) proxy.core.connection.server.TcpServerConnection[source]#

Implementations are responsible for creation of work objects from incoming args. This helps keep work core agnostic to creation of externally defined work class objects.

async get_events() Dict[int, int][source]#

Returns read event flag for all reusable connections in the pool.

async handle_events(readables: List[int], _writables: List[int]) bool[source]#

Removes reusable connection from the pool.

When pool is the owner of connection, we don’t expect a read event from upstream server. A read event means either upstream closed the connection or connection has somehow reached an illegal state e.g. upstream sending data for previous connection acquisition lifecycle.

release(conn: proxy.core.connection.server.TcpServerConnection) None[source]#

Release a previously acquired connection.

Releasing a connection will shutdown and close the socket including internal pool cleanup.

retain(conn: proxy.core.connection.server.TcpServerConnection) None[source]#

Retained previously acquired connection in the pool for reusability.