diff options
Diffstat (limited to 'libmproxy/proxy.py')
-rw-r--r-- | libmproxy/proxy.py | 87 |
1 files changed, 41 insertions, 46 deletions
diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index 2d4ee988..41f101d8 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -450,14 +450,43 @@ class ProxyHandler(SocketServer.StreamRequestHandler): self.rfile = FileLike(self.connection) self.wfile = FileLike(self.connection) + def read_contents(self, client_conn, headers, httpminor): + 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') + self.wfile.write('Proxy-agent: %s\r\n'%version.NAMEVERSION) + self.wfile.write('\r\n') + del headers['expect'] + else: + raise ProxyError(417, 'Unmet expect: %s'%expect) + if httpminor == 0: + client_conn.close = True + if "connection" in headers: + for value in ",".join(headers['connection']).split(","): + value = value.strip() + if value == "close": + client_conn.close = True + if value == "keep-alive": + client_conn.close = False + return read_http_body(self.rfile, client_conn, headers, False, self.config.body_size_limit) + def read_request(self, client_conn): line = self.rfile.readline() if line == "\r\n" or line == "\n": # Possible leftover from previous message line = self.rfile.readline() if line == "": return None - method, scheme, host, port, path, httpminor = parse_request_line(line) - if method == "CONNECT": + + if self.config.reverse_proxy: + scheme, host, port = self.config.reverse_proxy + method, path, httpmajor, httpminor = parse_init_http(line) + headers = read_headers(self.rfile) + content = self.read_contents(client_conn, headers, httpminor) + return flow.Request(client_conn, host, port, "http", method, path, headers, content) + elif line.startswith("CONNECT"): + host, port, httpmajor, httpminor = parse_init_connect(line) # FIXME: Discard additional headers sent to the proxy. Should I expose # these to users? while 1: @@ -472,50 +501,16 @@ class ProxyHandler(SocketServer.StreamRequestHandler): self.wfile.flush() 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" - headers = read_headers(self.rfile) - if host is None and "host" in headers: - netloc = headers["host"][0] - if ':' in netloc: - host, port = string.split(netloc, ':') - port = int(port) - else: - host = netloc - if scheme == "https": - port = 443 - else: - port = 80 - port = int(port) - if host is None: - if self.config.reverse_proxy: - scheme, host, port = self.config.reverse_proxy - else: - # FIXME: We only specify the first part of the invalid request in this error. - # 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') - self.wfile.write('Proxy-agent: %s\r\n'%version.NAMEVERSION) - self.wfile.write('\r\n') - del headers['expect'] - else: - raise ProxyError(417, 'Unmet expect: %s'%expect) - if httpminor == 0: - client_conn.close = True - if "connection" in headers: - for value in ",".join(headers['connection']).split(","): - value = value.strip() - if value == "close": - client_conn.close = True - if value == "keep-alive": - client_conn.close = False - content = read_http_body(self.rfile, client_conn, headers, False, self.config.body_size_limit) - return flow.Request(client_conn, host, port, scheme, method, path, headers, content) + + method, path, httpmajor, httpminor = parse_init_http(self.rfile.readline(line)) + headers = read_headers(self.rfile) + content = self.read_contents(client_conn, headers, httpminor) + return flow.Request(client_conn, host, port, "https", method, path, headers, content) + else: + method, scheme, host, port, path, httpmajor, httpminor = parse_init_proxy(line) + headers = read_headers(self.rfile) + content = self.read_contents(client_conn, headers, httpminor) + return flow.Request(client_conn, host, port, scheme, method, path, headers, content) def send_response(self, response): d = response._assemble() |