aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-06-03 06:04:57 -0700
committerAldo Cortesi <aldo@nullcube.com>2012-06-03 06:04:57 -0700
commite9109812e114385a9d87d0aade7850a613684d16 (patch)
treee1fca359bc7b34322b79846809053f98c5f24495
parent0a25c2263db1a43ad3f359fbefe98dd947fca0e8 (diff)
downloadmitmproxy-e9109812e114385a9d87d0aade7850a613684d16.tar.gz
mitmproxy-e9109812e114385a9d87d0aade7850a613684d16.tar.bz2
mitmproxy-e9109812e114385a9d87d0aade7850a613684d16.zip
Split parsing of intial line into separate protocols.
-rw-r--r--libmproxy/proxy.py56
-rw-r--r--test/test_proxy.py52
2 files changed, 108 insertions, 0 deletions
diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py
index 2481ed12..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):
@@ -441,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')
diff --git a/test/test_proxy.py b/test/test_proxy.py
index fccef977..c67e93a0 100644
--- a/test/test_proxy.py
+++ b/test/test_proxy.py
@@ -135,7 +135,59 @@ class u_read_headers(libpry.AutoTree):
assert headers["header"] == ['one\r\n two']
+class u_parse_http_protocol(libpry.AutoTree):
+ def test_simple(self):
+ assert proxy.parse_http_protocol("HTTP/1.1") == (1, 1)
+ assert proxy.parse_http_protocol("HTTP/0.0") == (0, 0)
+ assert not proxy.parse_http_protocol("foo/0.0")
+
+
+class u_parse_init_connect(libpry.AutoTree):
+ def test_simple(self):
+ assert proxy.parse_init_connect("CONNECT host.com:443 HTTP/1.0")
+ assert not proxy.parse_init_connect("bogus")
+ assert not proxy.parse_init_connect("GET host.com:443 HTTP/1.0")
+ assert not proxy.parse_init_connect("CONNECT host.com443 HTTP/1.0")
+ assert not proxy.parse_init_connect("CONNECT host.com:443 foo/1.0")
+
+
+class u_parse_init_proxy(libpry.AutoTree):
+ def test_simple(self):
+ u = "GET http://foo.com:8888/test HTTP/1.1"
+ m, s, h, po, pa, major, minor = proxy.parse_init_proxy(u)
+ assert m == "GET"
+ assert s == "http"
+ assert h == "foo.com"
+ assert po == 8888
+ assert pa == "/test"
+ assert major == 1
+ assert minor == 1
+
+ assert not proxy.parse_init_proxy("invalid")
+ assert not proxy.parse_init_proxy("GET invalid HTTP/1.1")
+ assert not proxy.parse_init_proxy("GET http://foo.com:8888/test foo/1.1")
+
+
+class u_parse_init_http(libpry.AutoTree):
+ def test_simple(self):
+ u = "GET /test HTTP/1.1"
+ m, u, major, minor = proxy.parse_init_http(u)
+ assert m == "GET"
+ assert u == "/test"
+ assert major == 1
+ assert minor == 1
+
+ assert not proxy.parse_init_http("invalid")
+ assert not proxy.parse_init_http("GET invalid HTTP/1.1")
+ assert not proxy.parse_init_http("GET /test foo/1.1")
+
+
+
tests = [
+ u_parse_http_protocol(),
+ u_parse_init_connect(),
+ u_parse_init_proxy(),
+ u_parse_init_http(),
uProxyError(),
uFileLike(),
u_parse_request_line(),