aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy/protocol')
-rw-r--r--libmproxy/protocol/__init__.py2
-rw-r--r--libmproxy/protocol/handle.py5
-rw-r--r--libmproxy/protocol/http.py101
-rw-r--r--libmproxy/protocol/primitives.py13
-rw-r--r--libmproxy/protocol/tcp.py3
5 files changed, 93 insertions, 31 deletions
diff --git a/libmproxy/protocol/__init__.py b/libmproxy/protocol/__init__.py
index f5d6a2d0..bbc20dba 100644
--- a/libmproxy/protocol/__init__.py
+++ b/libmproxy/protocol/__init__.py
@@ -1 +1 @@
-from .primitives import * \ No newline at end of file
+from .primitives import *
diff --git a/libmproxy/protocol/handle.py b/libmproxy/protocol/handle.py
index 100c7368..49cb3c1b 100644
--- a/libmproxy/protocol/handle.py
+++ b/libmproxy/protocol/handle.py
@@ -6,6 +6,7 @@ protocols = {
'tcp': dict(handler=tcp.TCPHandler)
}
+
def protocol_handler(protocol):
"""
@type protocol: str
@@ -14,4 +15,6 @@ def protocol_handler(protocol):
if protocol in protocols:
return protocols[protocol]["handler"]
- raise NotImplementedError("Unknown Protocol: %s" % protocol) # pragma: nocover \ No newline at end of file
+ raise NotImplementedError(
+ "Unknown Protocol: %s" %
+ protocol) # pragma: nocover
diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py
index 324a188f..91e74567 100644
--- a/libmproxy/protocol/http.py
+++ b/libmproxy/protocol/http.py
@@ -305,7 +305,18 @@ class HTTPRequest(HTTPMessage):
@classmethod
def from_state(cls, state):
- f = cls(None, None, None, None, None, None, None, None, None, None, None)
+ f = cls(
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None)
f.load_state(state)
return f
@@ -315,7 +326,12 @@ class HTTPRequest(HTTPMessage):
)
@classmethod
- def from_stream(cls, rfile, include_body=True, body_size_limit=None, wfile=None):
+ def from_stream(
+ cls,
+ rfile,
+ include_body=True,
+ body_size_limit=None,
+ wfile=None):
"""
Parse an HTTP request from a file stream
@@ -403,7 +419,8 @@ class HTTPRequest(HTTPMessage):
self.host,
self.port)]
- # If content is defined (i.e. not None or CONTENT_MISSING), we always add a content-length header.
+ # If content is defined (i.e. not None or CONTENT_MISSING), we always
+ # add a content-length header.
if self.content or self.content == "":
headers["Content-Length"] = [str(len(self.content))]
@@ -460,9 +477,9 @@ class HTTPRequest(HTTPMessage):
decode appropriately.
"""
if self.headers["accept-encoding"]:
- self.headers["accept-encoding"] = [', '.join(
- e for e in encoding.ENCODINGS if e in self.headers["accept-encoding"][0]
- )]
+ self.headers["accept-encoding"] = [
+ ', '.join(
+ e for e in encoding.ENCODINGS if e in self.headers["accept-encoding"][0])]
def update_host_header(self):
"""
@@ -489,13 +506,22 @@ class HTTPRequest(HTTPMessage):
Returns an empty ODict if there is no data or the content-type
indicates non-form data.
"""
- if self.content and self.headers.in_any("content-type", HDR_FORM_URLENCODED, True):
- return odict.ODict(utils.urldecode(self.content))
+ if self.content and self.headers.in_any(
+ "content-type",
+ HDR_FORM_URLENCODED,
+ True):
+ return odict.ODict(utils.urldecode(self.content))
return odict.ODict([])
def get_form_multipart(self):
- if self.content and self.headers.in_any("content-type", HDR_FORM_MULTIPART, True):
- return odict.ODict(utils.multipartdecode(self.headers, self.content))
+ if self.content and self.headers.in_any(
+ "content-type",
+ HDR_FORM_MULTIPART,
+ True):
+ return odict.ODict(
+ utils.multipartdecode(
+ self.headers,
+ self.content))
return odict.ODict([])
def set_form_urlencoded(self, odict):
@@ -664,8 +690,15 @@ class HTTPResponse(HTTPMessage):
timestamp_end: Timestamp indicating when request transmission ended
"""
- def __init__(self, httpversion, code, msg, headers, content, timestamp_start=None,
- timestamp_end=None):
+ def __init__(
+ self,
+ httpversion,
+ code,
+ msg,
+ headers,
+ content,
+ timestamp_start=None,
+ timestamp_end=None):
assert isinstance(headers, odict.ODictCaseless) or headers is None
HTTPMessage.__init__(
self,
@@ -710,7 +743,12 @@ class HTTPResponse(HTTPMessage):
)
@classmethod
- def from_stream(cls, rfile, request_method, include_body=True, body_size_limit=None):
+ def from_stream(
+ cls,
+ rfile,
+ request_method,
+ include_body=True,
+ body_size_limit=None):
"""
Parse an HTTP response from a file stream
"""
@@ -760,7 +798,8 @@ class HTTPResponse(HTTPMessage):
if not preserve_transfer_encoding:
del headers['Transfer-Encoding']
- # If content is defined (i.e. not None or CONTENT_MISSING), we always add a content-length header.
+ # If content is defined (i.e. not None or CONTENT_MISSING), we always
+ # add a content-length header.
if self.content or self.content == "":
headers["Content-Length"] = [str(len(self.content))]
@@ -1008,7 +1047,7 @@ class HTTPHandler(ProtocolHandler):
include_body=False
)
break
- except (tcp.NetLibError, http.HttpErrorConnClosed), v:
+ except (tcp.NetLibError, http.HttpErrorConnClosed) as v:
self.c.log(
"error in server communication: %s" % repr(v),
level="debug"
@@ -1079,7 +1118,8 @@ class HTTPHandler(ProtocolHandler):
if request_reply is None or request_reply == KILL:
raise KillSignal()
- self.process_server_address(flow) # The inline script may have changed request.host
+ # The inline script may have changed request.host
+ self.process_server_address(flow)
if isinstance(request_reply, HTTPResponse):
flow.response = request_reply
@@ -1090,7 +1130,9 @@ class HTTPHandler(ProtocolHandler):
# we can safely set it as the final attribute value here.
flow.server_conn = self.c.server_conn
- self.c.log("response", "debug", [flow.response._assemble_first_line()])
+ self.c.log(
+ "response", "debug", [
+ flow.response._assemble_first_line()])
response_reply = self.c.channel.ask("response", flow)
if response_reply is None or response_reply == KILL:
raise KillSignal()
@@ -1117,7 +1159,8 @@ class HTTPHandler(ProtocolHandler):
}
)
)
- if not self.process_connect_request((flow.request.host, flow.request.port)):
+ if not self.process_connect_request(
+ (flow.request.host, flow.request.port)):
return False
# If the user has changed the target server on this connection,
@@ -1130,7 +1173,7 @@ class HTTPHandler(ProtocolHandler):
http.HttpError,
proxy.ProxyError,
tcp.NetLibError,
- ), e:
+ ) as e:
self.handle_error(e, flow)
except KillSignal:
self.c.log("Connection killed", "info")
@@ -1226,7 +1269,8 @@ class HTTPHandler(ProtocolHandler):
# Determine .scheme, .host and .port attributes
# For absolute-form requests, they are directly given in the request.
# For authority-form requests, we only need to determine the request scheme.
- # For relative-form requests, we need to determine host and port as well.
+ # For relative-form requests, we need to determine host and port as
+ # well.
if not request.scheme:
request.scheme = "https" if flow.server_conn and flow.server_conn.ssl_established else "http"
if not request.host:
@@ -1253,8 +1297,8 @@ class HTTPHandler(ProtocolHandler):
flow.server_conn = self.c.server_conn
self.c.establish_server_connection()
self.c.client_conn.send(
- ('HTTP/%s.%s 200 ' % (request.httpversion[0],request.httpversion[1])) +
- 'Connection established\r\n' +
+ ('HTTP/%s.%s 200 ' % (request.httpversion[0], request.httpversion[1])) +
+ 'Connection established\r\n' +
'Content-Length: 0\r\n' +
('Proxy-agent: %s\r\n' % self.c.config.server_version) +
'\r\n'
@@ -1372,10 +1416,15 @@ class HTTPHandler(ProtocolHandler):
semantics. Returns True, if so.
"""
close_connection = (
- http.connection_close(flow.request.httpversion, flow.request.headers) or
- http.connection_close(flow.response.httpversion, flow.response.headers) or
- http.expected_http_body_size(flow.response.headers, False, flow.request.method,
- flow.response.code) == -1)
+ http.connection_close(
+ flow.request.httpversion,
+ flow.request.headers) or http.connection_close(
+ flow.response.httpversion,
+ flow.response.headers) or http.expected_http_body_size(
+ flow.response.headers,
+ False,
+ flow.request.method,
+ flow.response.code) == -1)
if close_connection:
if flow.request.form_in == "authority" and flow.response.code == 200:
# Workaround for
diff --git a/libmproxy/protocol/primitives.py b/libmproxy/protocol/primitives.py
index f9c22e1a..2f8ea3e0 100644
--- a/libmproxy/protocol/primitives.py
+++ b/libmproxy/protocol/primitives.py
@@ -24,6 +24,7 @@ class Error(stateobject.StateObject):
msg: Message describing the error
timestamp: Seconds since the epoch
"""
+
def __init__(self, msg, timestamp=None):
"""
@type msg: str
@@ -59,6 +60,7 @@ 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, type, client_conn, server_conn, live=None):
self.type = type
self.id = str(uuid.uuid4())
@@ -165,12 +167,12 @@ class Flow(stateobject.StateObject):
master.handle_accept_intercept(self)
-
class ProtocolHandler(object):
"""
A ProtocolHandler implements an application-layer protocol, e.g. HTTP.
See: libmproxy.protocol.http.HTTPHandler
"""
+
def __init__(self, c):
self.c = c
"""@type: libmproxy.proxy.server.ConnectionHandler"""
@@ -209,13 +211,20 @@ class LiveConnection(object):
interface with a live connection, without exposing the internals
of the ConnectionHandler.
"""
+
def __init__(self, c):
self.c = c
"""@type: libmproxy.proxy.server.ConnectionHandler"""
self._backup_server_conn = None
"""@type: libmproxy.proxy.connection.ServerConnection"""
- def change_server(self, address, ssl=None, sni=None, force=False, persistent_change=False):
+ def change_server(
+ self,
+ address,
+ ssl=None,
+ sni=None,
+ force=False,
+ persistent_change=False):
"""
Change the server connection to the specified address.
@returns:
diff --git a/libmproxy/protocol/tcp.py b/libmproxy/protocol/tcp.py
index 5314b577..0feb77c6 100644
--- a/libmproxy/protocol/tcp.py
+++ b/libmproxy/protocol/tcp.py
@@ -79,7 +79,8 @@ class TCPHandler(ProtocolHandler):
),
"info"
)
- # Do not use dst.connection.send here, which may raise OpenSSL-specific errors.
+ # Do not use dst.connection.send here, which may raise
+ # OpenSSL-specific errors.
dst.send(contents)
else:
# socket.socket.send supports raw bytearrays/memoryviews