aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/protocol.py
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2014-01-05 01:03:55 +0100
committerMaximilian Hils <git@maximilianhils.com>2014-01-05 01:03:55 +0100
commitb34ad82b528b55dabc318f999577fb6a020ccad9 (patch)
tree65490eeb30c4785854a1e76bc7fd275860e87e2c /libmproxy/protocol.py
parentb9d4eb103e6b45cc331b0fc3cd5a0c693f1b669e (diff)
downloadmitmproxy-b34ad82b528b55dabc318f999577fb6a020ccad9.tar.gz
mitmproxy-b34ad82b528b55dabc318f999577fb6a020ccad9.tar.bz2
mitmproxy-b34ad82b528b55dabc318f999577fb6a020ccad9.zip
first steps on tcp proxying
Diffstat (limited to 'libmproxy/protocol.py')
-rw-r--r--libmproxy/protocol.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/libmproxy/protocol.py b/libmproxy/protocol.py
new file mode 100644
index 00000000..5999fb06
--- /dev/null
+++ b/libmproxy/protocol.py
@@ -0,0 +1,88 @@
+from libmproxy.proxy import ProxyError, ConnectionHandler
+from netlib import http
+
+def handle_messages(conntype, connection_handler):
+ handler = None
+ if conntype == "http":
+ handler = HTTPHandler(connection_handler)
+ else:
+ raise NotImplementedError
+
+ return handler.handle_messages()
+
+
+class ProtocolHandler(object):
+ def __init__(self, c):
+ self.c = c
+
+class HTTPHandler(ProtocolHandler):
+
+ def handle_messages(self):
+ while self.handle_request():
+ pass
+ self.c.close = True
+
+ def handle_request(self):
+ request = self.read_request()
+ if request is None:
+ return
+ raise NotImplementedError
+
+ def read_request(self):
+ self.c.client_conn.rfile.reset_timestamps()
+
+ request_line = self.get_line(self.c.client_conn.rfile)
+ method, path, httpversion = http.parse_init(request_line)
+ headers = self.read_headers(authenticate=True)
+
+ if self.mode == "regular":
+ if method == "CONNECT":
+ r = http.parse_init_connect(request_line)
+ if not r:
+ raise ProxyError(400, "Bad HTTP request line: %s"%repr(request_line))
+ host, port, _ = r
+ if self.config.forward_proxy:
+ self.server_conn.wfile.write(request_line)
+ for key, value in headers.items():
+ self.server_conn.wfile.write("%s: %s\r\n"%(key, value))
+ self.server_conn.wfile.write("\r\n")
+ else:
+ self.server_address = (host, port)
+ self.establish_server_connection()
+
+ self.handle_ssl()
+ self.mode = "transparent"
+ return
+ else:
+ r = http.parse_init_proxy(request_line)
+ if not r:
+ raise ProxyError(400, "Bad HTTP request line: %s"%repr(request_line))
+ method, scheme, host, port, path, httpversion = r
+ if not self.config.forward_proxy:
+ if (not self.server_conn) or (self.server_address != (host, port)):
+ self.server_address = (host, port)
+ self.establish_server_connection()
+
+ def get_line(self, fp):
+ """
+ Get a line, possibly preceded by a blank.
+ """
+ line = fp.readline()
+ if line == "\r\n" or line == "\n": # Possible leftover from previous message
+ line = fp.readline()
+ return line
+
+ def read_headers(self, authenticate=False):
+ headers = http.read_headers(self.client_conn.rfile)
+ if headers is None:
+ raise ProxyError(400, "Invalid headers")
+ if authenticate and self.config.authenticator:
+ if self.config.authenticator.authenticate(headers):
+ self.config.authenticator.clean(headers)
+ else:
+ raise ProxyError(
+ 407,
+ "Proxy Authentication Required",
+ self.config.authenticator.auth_challenge_headers()
+ )
+ return headers \ No newline at end of file