diff options
Diffstat (limited to 'libmproxy/protocol/primitives.py')
-rw-r--r-- | libmproxy/protocol/primitives.py | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/libmproxy/protocol/primitives.py b/libmproxy/protocol/primitives.py index 160c50c7..1bf7f832 100644 --- a/libmproxy/protocol/primitives.py +++ b/libmproxy/protocol/primitives.py @@ -1,5 +1,6 @@ from __future__ import absolute_import import copy +import uuid import netlib.tcp from .. import stateobject, utils, version from ..proxy.connection import ClientConnection, ServerConnection @@ -8,14 +9,14 @@ from ..proxy.connection import ClientConnection, ServerConnection KILL = 0 # const for killed requests -class Error(stateobject.SimpleStateObject): +class Error(stateobject.StateObject): """ An Error. - This is distinct from an protocol error response (say, a HTTP code 500), which - is represented by a normal HTTPResponse object. This class is responsible - for indicating errors that fall outside of normal protocol communications, - like interrupted connections, timeouts, protocol errors. + This is distinct from an protocol error response (say, a HTTP code 500), + which is represented by a normal HTTPResponse object. This class is + responsible for indicating errors that fall outside of normal protocol + communications, like interrupted connections, timeouts, protocol errors. Exposes the following attributes: @@ -41,9 +42,11 @@ class Error(stateobject.SimpleStateObject): return self.msg @classmethod - def _from_state(cls, state): - f = cls(None) # the default implementation assumes an empty constructor. Override accordingly. - f._load_state(state) + def from_state(cls, state): + # the default implementation assumes an empty constructor. Override + # accordingly. + f = cls(None) + f.load_state(state) return f def copy(self): @@ -51,13 +54,14 @@ class Error(stateobject.SimpleStateObject): return c -class Flow(stateobject.SimpleStateObject): +class Flow(stateobject.StateObject): """ A Flow is a collection of objects representing a single transaction. This class is usually subclassed for each protocol, e.g. HTTPFlow. """ - def __init__(self, conntype, client_conn, server_conn, live=None): - self.conntype = conntype + def __init__(self, type, client_conn, server_conn, live=None): + self.type = type + self.id = str(uuid.uuid4()) self.client_conn = client_conn """@type: ClientConnection""" self.server_conn = server_conn @@ -70,14 +74,15 @@ class Flow(stateobject.SimpleStateObject): self._backup = None _stateobject_attributes = dict( + id=str, error=Error, client_conn=ClientConnection, server_conn=ServerConnection, - conntype=str + type=str ) - def _get_state(self): - d = super(Flow, self)._get_state() + def get_state(self, short=False): + d = super(Flow, self).get_state(short) d.update(version=version.IVERSION) return d @@ -99,7 +104,7 @@ class Flow(stateobject.SimpleStateObject): Has this Flow been modified? """ if self._backup: - return self._backup != self._get_state() + return self._backup != self.get_state() else: return False @@ -109,14 +114,14 @@ class Flow(stateobject.SimpleStateObject): call to .revert(). """ if not self._backup: - self._backup = self._get_state() + self._backup = self.get_state() def revert(self): """ Revert to the last backed up state. """ if self._backup: - self._load_state(self._backup) + self.load_state(self._backup) self._backup = None @@ -133,31 +138,35 @@ class ProtocolHandler(object): def handle_messages(self): """ - This method gets called if a client connection has been made. Depending on the proxy settings, - a server connection might already exist as well. + This method gets called if a client connection has been made. Depending + on the proxy settings, a server connection might already exist as well. """ raise NotImplementedError # pragma: nocover def handle_server_reconnect(self, state): """ - This method gets called if a server connection needs to reconnect and there's a state associated - with the server connection (e.g. a previously-sent CONNECT request or a SOCKS proxy request). - This method gets called after the connection has been restablished but before SSL is established. + This method gets called if a server connection needs to reconnect and + there's a state associated with the server connection (e.g. a + previously-sent CONNECT request or a SOCKS proxy request). This method + gets called after the connection has been restablished but before SSL is + established. """ raise NotImplementedError # pragma: nocover def handle_error(self, error): """ - This method gets called should there be an uncaught exception during the connection. - This might happen outside of handle_messages, e.g. if the initial SSL handshake fails in transparent mode. + This method gets called should there be an uncaught exception during the + connection. This might happen outside of handle_messages, e.g. if the + initial SSL handshake fails in transparent mode. """ raise error # pragma: nocover class LiveConnection(object): """ - This facade allows interested parties (FlowMaster, inline scripts) to interface with a live connection, - without requiring to expose the internals of the ConnectionHandler. + This facade allows interested parties (FlowMaster, inline scripts) to + interface with a live connection, without exposing the internals + of the ConnectionHandler. """ def __init__(self, c): self.c = c @@ -182,18 +191,23 @@ class LiveConnection(object): if ssl_mismatch or address_mismatch or force: - self.c.log("Change server connection: %s:%s -> %s:%s [persistent: %s]" % ( - self.c.server_conn.address.host, - self.c.server_conn.address.port, - address.host, - address.port, - persistent_change - ), "debug") + self.c.log( + "Change server connection: %s:%s -> %s:%s [persistent: %s]" % ( + self.c.server_conn.address.host, + self.c.server_conn.address.port, + address.host, + address.port, + persistent_change + ), + "debug" + ) if not self._backup_server_conn and not persistent_change: self._backup_server_conn = self.c.server_conn self.c.server_conn = None - else: # This is at least the second temporary change. We can kill the current connection. + else: + # This is at least the second temporary change. We can kill the + # current connection. self.c.del_server_connection() self.c.set_server_address(address) @@ -204,8 +218,9 @@ class LiveConnection(object): return False def restore_server(self): - # TODO: Similar to _backup_server_conn, introduce _cache_server_conn, which keeps the changed connection open - # This may be beneficial if a user is rewriting all requests from http to https or similar. + # TODO: Similar to _backup_server_conn, introduce _cache_server_conn, + # which keeps the changed connection open This may be beneficial if a + # user is rewriting all requests from http to https or similar. if not self._backup_server_conn: return @@ -218,4 +233,4 @@ class LiveConnection(object): self.c.del_server_connection() self.c.server_conn = self._backup_server_conn - self._backup_server_conn = None
\ No newline at end of file + self._backup_server_conn = None |