aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/console/help.py25
-rw-r--r--libmproxy/proxy.py97
2 files changed, 91 insertions, 31 deletions
diff --git a/libmproxy/console/help.py b/libmproxy/console/help.py
index c75d2ae2..64428fcc 100644
--- a/libmproxy/console/help.py
+++ b/libmproxy/console/help.py
@@ -31,18 +31,6 @@ class HelpView(urwid.ListBox):
self.helptext()
)
- def keypress(self, size, key):
- key = common.shortcuts(key)
- if key == "q":
- self.master.statusbar = self.state[0]
- self.master.body = self.state[1]
- self.master.header = self.state[2]
- self.master.make_view()
- return None
- elif key == "?":
- key = None
- return urwid.ListBox.keypress(self, size, key)
-
def helptext(self):
text = []
text.append(urwid.Text([("head", "Keys for this view:\n")]))
@@ -174,3 +162,16 @@ class HelpView(urwid.ListBox):
text.extend(common.format_keyvals(examples, key="key", val="text", indent=4))
return text
+ def keypress(self, size, key):
+ key = common.shortcuts(key)
+ if key == "q":
+ self.master.statusbar = self.state[0]
+ self.master.body = self.state[1]
+ self.master.header = self.state[2]
+ self.master.make_view()
+ return None
+ elif key == "?":
+ key = None
+ return urwid.ListBox.keypress(self, size, key)
+
+
diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py
index 912f3f31..2c0fa57b 100644
--- a/libmproxy/proxy.py
+++ b/libmproxy/proxy.py
@@ -127,6 +127,61 @@ def read_http_body(rfile, connection, headers, all, limit):
return content
+def parse_http_protocol(s):
+ if not s.startswith("HTTP/"):
+ return None
+ major, minor = s.split('/')[1].split('.')
+ major = int(major)
+ minor = int(minor)
+ return major, minor
+
+
+def parse_init_connect(line):
+ try:
+ method, url, protocol = string.split(line)
+ except ValueError:
+ return None
+ if method != 'CONNECT':
+ return None
+ try:
+ host, port = url.split(":")
+ except ValueError:
+ return None
+ port = int(port)
+ mm = parse_http_protocol(protocol)
+ if not mm:
+ return None
+ return host, port, mm[0], mm[1]
+
+
+def parse_init_proxy(line):
+ try:
+ method, url, protocol = string.split(line)
+ except ValueError:
+ return None
+ parts = utils.parse_url(url)
+ if not parts:
+ return None
+ scheme, host, port, path = parts
+ mm = parse_http_protocol(protocol)
+ if not mm:
+ return None
+ return method, scheme, host, port, path, mm[0], mm[1]
+
+
+def parse_init_http(line):
+ try:
+ method, url, protocol = string.split(line)
+ except ValueError:
+ return None
+ if not (url.startswith("/") or url == "*"):
+ return None
+ mm = parse_http_protocol(protocol)
+ if not mm:
+ return None
+ return method, url, mm[0], mm[1]
+
+
#FIXME: Return full HTTP version specification from here. Allow non-HTTP
#protocol specs, and make it all editable.
def parse_request_line(request):
@@ -146,14 +201,13 @@ def parse_request_line(request):
except ValueError:
raise ProxyError(400, "Can't parse request")
port = int(port)
- else:
- if url.startswith("/") or url == "*":
+ elif url.startswith("/") or url == "*":
scheme, port, host, path = None, None, None, url
- else:
- parts = utils.parse_url(url)
- if not parts:
- raise ProxyError(400, "Invalid url: %s"%url)
- scheme, host, port, path = parts
+ else:
+ parts = utils.parse_url(url)
+ if not parts:
+ raise ProxyError(400, "Invalid url: %s"%url)
+ scheme, host, port, path = parts
if not protocol.startswith("HTTP/"):
raise ProxyError(400, "Unsupported protocol")
major,minor = protocol.split('/')[1].split('.')
@@ -382,6 +436,20 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
raise ProxyError(502, "mitmproxy: Unable to generate dummy cert.")
return ret
+ def convert_to_ssl(self, cert):
+ kwargs = dict(
+ certfile = cert,
+ keyfile = self.config.certfile or self.config.cacert,
+ server_side = True,
+ ssl_version = ssl.PROTOCOL_SSLv23,
+ do_handshake_on_connect = True,
+ )
+ if sys.version_info[1] > 6:
+ kwargs["ciphers"] = self.config.ciphers
+ self.connection = ssl.wrap_socket(self.connection, **kwargs)
+ self.rfile = FileLike(self.connection)
+ self.wfile = FileLike(self.connection)
+
def read_request(self, client_conn):
line = self.rfile.readline()
if line == "\r\n" or line == "\n": # Possible leftover from previous message
@@ -402,18 +470,8 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
'\r\n'
)
self.wfile.flush()
- kwargs = dict(
- certfile = self.find_cert(host, port),
- keyfile = self.config.certfile or self.config.cacert,
- server_side = True,
- ssl_version = ssl.PROTOCOL_SSLv23,
- do_handshake_on_connect = True,
- )
- if sys.version_info[1] > 6:
- kwargs["ciphers"] = self.config.ciphers
- self.connection = ssl.wrap_socket(self.connection, **kwargs)
- self.rfile = FileLike(self.connection)
- self.wfile = FileLike(self.connection)
+ certfile = self.find_cert(host, port)
+ self.convert_to_ssl(certfile)
method, scheme, host, port, path, httpminor = parse_request_line(self.rfile.readline())
if scheme is None:
scheme = "https"
@@ -438,6 +496,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
# We should gather up everything read from the socket, and specify it all.
raise ProxyError(400, 'Invalid request: %s'%line)
if "expect" in headers:
+ # FIXME: Should be forwarded upstream
expect = ",".join(headers['expect'])
if expect == "100-continue" and httpminor >= 1:
self.wfile.write('HTTP/1.1 100 Continue\r\n')