diff --git a/libmproxy/protocol2/http.py b/libmproxy/protocol2/http.py index 1e774648c..7adeb4195 100644 --- a/libmproxy/protocol2/http.py +++ b/libmproxy/protocol2/http.py @@ -5,7 +5,6 @@ from ..exceptions import InvalidCredentials, HttpException, ProtocolException from .layer import Layer, ServerConnectionMixin from libmproxy import utils from .messages import ChangeServer, Connect, Reconnect, Kill -from .http_proxy import HttpProxy, HttpUpstreamProxy from libmproxy.protocol import KILL from libmproxy.protocol.http import HTTPFlow @@ -66,13 +65,18 @@ def make_connect_response(httpversion): ) -class HttpLayer(Layer, ServerConnectionMixin): +class HttpLayer(Layer): + """ HTTP 1 Layer """ def __init__(self, ctx): super(HttpLayer, self).__init__(ctx) + + # FIXME: Imports + from .http_proxy import HttpProxy, HttpUpstreamProxy + if any(isinstance(l, HttpProxy) for l in self.layers): self.mode = "regular" elif any(isinstance(l, HttpUpstreamProxy) for l in self.layers): @@ -199,7 +203,7 @@ class HttpLayer(Layer, ServerConnectionMixin): self.send_to_server(flow.request) flow.response = HTTP1.read_response( - self.server_conn.protocol, + self.server_conn, flow.request.method, body_size_limit=self.config.body_size_limit, include_body=False, @@ -215,6 +219,7 @@ class HttpLayer(Layer, ServerConnectionMixin): flow.response.content = CONTENT_MISSING else: flow.response.content = HTTP1.read_http_body( + self.server_conn, flow.response.headers, self.config.body_size_limit, flow.request.method, @@ -303,7 +308,7 @@ class HttpLayer(Layer, ServerConnectionMixin): expected_request_forms = { "regular": ("absolute",), # an authority request would already be handled. "upstream": ("authority", "absolute"), - "transparent": ("regular",) + "transparent": ("relative",) } allowed_request_forms = expected_request_forms[self.mode] @@ -314,6 +319,9 @@ class HttpLayer(Layer, ServerConnectionMixin): self.send_to_client(make_error_response(400, err_message)) raise HttpException(err_message) + if self.mode == "regular": + request.form_out = "relative" + def authenticate(self, request): if self.config.authenticator: if self.config.authenticator.authenticate(request.headers): @@ -327,10 +335,10 @@ class HttpLayer(Layer, ServerConnectionMixin): raise InvalidCredentials("Proxy Authentication Required") def send_to_server(self, message): - self.server_conn.wfile.wrie(message) + self.server_conn.send(HTTP1.assemble(message)) + def send_to_client(self, message): # FIXME # - possibly do some http2 stuff here - # - fix message assembly. - self.client_conn.wfile.write(message) + self.client_conn.send(HTTP1.assemble(message)) diff --git a/libmproxy/protocol2/http_protocol_mock.py b/libmproxy/protocol2/http_protocol_mock.py index 5fdb9f2b0..22f3dc147 100644 --- a/libmproxy/protocol2/http_protocol_mock.py +++ b/libmproxy/protocol2/http_protocol_mock.py @@ -1,6 +1,7 @@ """ Temporary mock to sort out API discrepancies """ +from libmproxy.protocol.http_wrappers import HTTPResponse, HTTPRequest from netlib.http.http1 import HTTP1Protocol @@ -10,14 +11,14 @@ class HTTP1(object): """ :type connection: object """ - return HTTP1Protocol(connection).read_request(*args, **kwargs) + return HTTPRequest.wrap(HTTP1Protocol(connection).read_request(*args, **kwargs)) @staticmethod def read_response(connection, *args, **kwargs): """ :type connection: object """ - return HTTP1Protocol(connection).read_response(*args, **kwargs) + return HTTPResponse.wrap(HTTP1Protocol(connection).read_response(*args, **kwargs)) @staticmethod def read_http_body(connection, *args, **kwargs): @@ -28,19 +29,13 @@ class HTTP1(object): @staticmethod - def _assemble_response_first_line(connection, *args, **kwargs): - """ - :type connection: object - """ - return HTTP1Protocol(connection)._assemble_response_first_line(*args, **kwargs) + def _assemble_response_first_line(*args, **kwargs): + return HTTP1Protocol()._assemble_response_first_line(*args, **kwargs) @staticmethod - def _assemble_response_headers(connection, *args, **kwargs): - """ - :type connection: object - """ - return HTTP1Protocol(connection)._assemble_response_headers(*args, **kwargs) + def _assemble_response_headers(*args, **kwargs): + return HTTP1Protocol()._assemble_response_headers(*args, **kwargs) @staticmethod @@ -48,4 +43,8 @@ class HTTP1(object): """ :type connection: object """ - return HTTP1Protocol(connection).read_http_body_chunked(*args, **kwargs) \ No newline at end of file + return HTTP1Protocol(connection).read_http_body_chunked(*args, **kwargs) + + @staticmethod + def assemble(*args, **kwargs): + return HTTP1Protocol().assemble(*args, **kwargs) \ No newline at end of file diff --git a/libmproxy/protocol2/layer.py b/libmproxy/protocol2/layer.py index 2775845eb..f2d6b3fb6 100644 --- a/libmproxy/protocol2/layer.py +++ b/libmproxy/protocol2/layer.py @@ -45,6 +45,7 @@ class _LayerCodeCompletion(object): """ def __init__(self): + super(_LayerCodeCompletion, self).__init__() if True: return self.config = None @@ -94,7 +95,7 @@ class Layer(_LayerCodeCompletion): return [self] + self.ctx.layers def __repr__(self): - return "%s\r\n %s" % (self.__class__.name__, repr(self.ctx)) + return type(self).__name__ class ServerConnectionMixin(object): @@ -103,6 +104,7 @@ class ServerConnectionMixin(object): """ def __init__(self): + super(ServerConnectionMixin, self).__init__() self._server_address = None self.server_conn = None @@ -114,8 +116,11 @@ class ServerConnectionMixin(object): elif message == Connect: self._connect() return True - elif message == ChangeServer: - raise NotImplementedError + elif message == ChangeServer and message.depth == 1: + if self.server_conn: + self._disconnect() + self.server_address = message.address + return True elif message == Kill: self._disconnect() diff --git a/libmproxy/proxy/server.py b/libmproxy/proxy/server.py index defcd4640..ffca55eea 100644 --- a/libmproxy/proxy/server.py +++ b/libmproxy/proxy/server.py @@ -80,7 +80,7 @@ class ConnectionHandler2: self.config, self.channel ) - root_layer = protocol2.Socks5Proxy(root_context) + root_layer = protocol2.HttpProxy(root_context) try: for message in root_layer():