Exemplo n.º 1
0
def test_connection_close():
    h = odict.ODictCaseless()
    assert HTTP1Protocol.connection_close((1, 0), h)
    assert not HTTP1Protocol.connection_close((1, 1), h)

    h["connection"] = ["keep-alive"]
    assert not HTTP1Protocol.connection_close((1, 1), h)

    h["connection"] = ["close"]
    assert HTTP1Protocol.connection_close((1, 1), h)
Exemplo n.º 2
0
def test_connection_close():
    headers = Headers()
    assert HTTP1Protocol.connection_close((1, 0), headers)
    assert not HTTP1Protocol.connection_close((1, 1), headers)

    headers["connection"] = "keep-alive"
    assert not HTTP1Protocol.connection_close((1, 1), headers)

    headers["connection"] = "close"
    assert HTTP1Protocol.connection_close((1, 1), headers)
Exemplo n.º 3
0
def test_parse_init_connect():
    assert HTTP1Protocol._parse_init_connect("CONNECT host.com:443 HTTP/1.0")
    assert not HTTP1Protocol._parse_init_connect("C\xfeONNECT host.com:443 HTTP/1.0")
    assert not HTTP1Protocol._parse_init_connect("CONNECT \0host.com:443 HTTP/1.0")
    assert not HTTP1Protocol._parse_init_connect("CONNECT host.com:444444 HTTP/1.0")
    assert not HTTP1Protocol._parse_init_connect("bogus")
    assert not HTTP1Protocol._parse_init_connect("GET host.com:443 HTTP/1.0")
    assert not HTTP1Protocol._parse_init_connect("CONNECT host.com443 HTTP/1.0")
    assert not HTTP1Protocol._parse_init_connect("CONNECT host.com:443 foo/1.0")
    assert not HTTP1Protocol._parse_init_connect("CONNECT host.com:foo HTTP/1.0")
Exemplo n.º 4
0
def test_parse_init_proxy():
    u = "GET http://foo.com:8888/test HTTP/1.1"
    m, s, h, po, pa, httpversion = HTTP1Protocol._parse_init_proxy(u)
    assert m == "GET"
    assert s == "http"
    assert h == "foo.com"
    assert po == 8888
    assert pa == "/test"
    assert httpversion == (1, 1)

    u = "G\xfeET http://foo.com:8888/test HTTP/1.1"
    assert not HTTP1Protocol._parse_init_proxy(u)

    assert not HTTP1Protocol._parse_init_proxy("invalid")
    assert not HTTP1Protocol._parse_init_proxy("GET invalid HTTP/1.1")
    assert not HTTP1Protocol._parse_init_proxy("GET http://foo.com:8888/test foo/1.1")
Exemplo n.º 5
0
def test_expected_http_body_size():
    # gibber in the content-length field
    headers = Headers(content_length="foo")
    assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) is None
    # negative number in the content-length field
    headers = Headers(content_length="-7")
    assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) is None
    # explicit length
    headers = Headers(content_length="5")
    assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) == 5
    # no length
    headers = Headers()
    assert HTTP1Protocol.expected_http_body_size(headers, False, "GET", 200) == -1
    # no length request
    headers = Headers()
    assert HTTP1Protocol.expected_http_body_size(headers, True, "GET", None) == 0
Exemplo n.º 6
0
    def handle(self):
        self.log("clientconnect", "info")

        root_layer = self._create_root_layer()
        root_layer = self.channel.ask("clientconnect", root_layer)
        if root_layer == Kill:

            def root_layer():
                raise Kill()

        try:
            root_layer()
        except Kill:
            self.log("Connection killed", "info")
        except ProtocolException as e:
            self.log(e, "info")
            # If an error propagates to the topmost level,
            # we send an HTTP error response, which is both
            # understandable by HTTP clients and humans.
            try:
                error_response = make_error_response(502, repr(e))
                self.client_conn.send(HTTP1Protocol().assemble(error_response))
            except NetLibError:
                pass
        except Exception:
            self.log(traceback.format_exc(), "error")
            print(traceback.format_exc(), file=sys.stderr)
            print("mitmproxy has crashed!", file=sys.stderr)
            print(
                "Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy",
                file=sys.stderr)

        self.log("clientdisconnect", "info")
        self.channel.tell("clientdisconnect", root_layer)
        self.client_conn.finish()
Exemplo n.º 7
0
    def test_simple(self):
        resp = tutils.tresp()
        b = HTTP1Protocol().assemble_response(resp)
        assert b == match_http_string("""
            HTTP/1.1 200 OK
            header_response: svalue
            Content-Length: 7

            message""")
Exemplo n.º 8
0
def test_expected_http_body_size():
    # gibber in the content-length field
    h = odict.ODictCaseless()
    h["content-length"] = ["foo"]
    assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) is None
    # negative number in the content-length field
    h = odict.ODictCaseless()
    h["content-length"] = ["-7"]
    assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) is None
    # explicit length
    h = odict.ODictCaseless()
    h["content-length"] = ["5"]
    assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) == 5
    # no length
    h = odict.ODictCaseless()
    assert HTTP1Protocol.expected_http_body_size(h, False, "GET", 200) == -1
    # no length request
    h = odict.ODictCaseless()
    assert HTTP1Protocol.expected_http_body_size(h, True, "GET", None) == 0
Exemplo n.º 9
0
    def test_simple(self):
        req = tutils.treq()
        b = HTTP1Protocol().assemble_request(req)
        assert b == match_http_string("""
            GET /path HTTP/1.1
            header: qvalue
            Host: address:22
            Content-Length: 7

            content""")
Exemplo n.º 10
0
    def handshake(self):
        http1_protocol = HTTP1Protocol(self)

        req = http1_protocol.read_request()
        key = self.protocol.check_client_handshake(req.headers)

        preamble = 'HTTP/1.1 101 %s' % status_codes.RESPONSES.get(101)
        self.wfile.write(preamble + "\r\n")
        headers = self.protocol.server_handshake_headers(key)
        self.wfile.write(str(headers) + "\r\n")
        self.wfile.flush()
        self.handshake_done = True
Exemplo n.º 11
0
    def handshake(self):
        http1_protocol = HTTP1Protocol(self)

        client_hs = http1_protocol.read_request()
        self.protocol.check_client_handshake(client_hs.headers)

        preamble = 'HTTP/1.1 101 %s' % status_codes.RESPONSES.get(101)
        self.wfile.write(preamble + "\r\n")
        headers = self.protocol.server_handshake_headers("malformed key")
        self.wfile.write(headers.format() + "\r\n")
        self.wfile.flush()
        self.handshake_done = True
Exemplo n.º 12
0
def test_parse_http_protocol():
    assert HTTP1Protocol._parse_http_protocol("HTTP/1.1") == (1, 1)
    assert HTTP1Protocol._parse_http_protocol("HTTP/0.0") == (0, 0)
    assert not HTTP1Protocol._parse_http_protocol("HTTP/a.1")
    assert not HTTP1Protocol._parse_http_protocol("HTTP/1.a")
    assert not HTTP1Protocol._parse_http_protocol("foo/0.0")
    assert not HTTP1Protocol._parse_http_protocol("HTTP/x")
Exemplo n.º 13
0
    def connect(self):
        super(WebSocketsClient, self).connect()

        http1_protocol = HTTP1Protocol(self)

        preamble = 'GET / HTTP/1.1'
        self.wfile.write(preamble + "\r\n")
        headers = self.protocol.client_handshake_headers()
        self.client_nonce = headers["sec-websocket-key"]
        self.wfile.write(str(headers) + "\r\n")
        self.wfile.flush()

        resp = http1_protocol.read_response("GET", None)
        server_nonce = self.protocol.check_server_handshake(resp.headers)

        if not server_nonce == self.protocol.create_server_nonce(
                self.client_nonce):
            self.close()
Exemplo n.º 14
0
def test_parse_init_http():
    u = "GET /test HTTP/1.1"
    m, u, httpversion = HTTP1Protocol._parse_init_http(u)
    assert m == "GET"
    assert u == "/test"
    assert httpversion == (1, 1)

    u = "G\xfeET /test HTTP/1.1"
    assert not HTTP1Protocol._parse_init_http(u)

    assert not HTTP1Protocol._parse_init_http("invalid")
    assert not HTTP1Protocol._parse_init_http("GET invalid HTTP/1.1")
    assert not HTTP1Protocol._parse_init_http("GET /test foo/1.1")
    assert not HTTP1Protocol._parse_init_http("GET /test\xc0 HTTP/1.1")
Exemplo n.º 15
0
 def test_not_a_request(self):
     tutils.raises(AssertionError, HTTP1Protocol().assemble_response, 'foo')
Exemplo n.º 16
0
 def test_body_missing(self):
     resp = tutils.tresp(content=semantics.CONTENT_MISSING)
     tutils.raises(http.HttpError, HTTP1Protocol().assemble_response, resp)
Exemplo n.º 17
0
 def connect(self):
     self.ctx.connect()
     self.server_protocol = HTTP1Protocol(self.server_conn)
Exemplo n.º 18
0
 def set_server(self, *args, **kwargs):
     self.ctx.set_server(*args, **kwargs)
     self.server_protocol = HTTP1Protocol(self.server_conn)
Exemplo n.º 19
0
 def test_no_content_length(self):
     c = tcp.TCPClient(("127.0.0.1", self.port))
     c.connect()
     resp = HTTP1Protocol(c).read_response("GET", None)
     assert resp.body == "bar\r\n\r\n"
Exemplo n.º 20
0
def test_has_chunked_encoding():
    headers = http.Headers()
    assert not HTTP1Protocol.has_chunked_encoding(headers)
    headers["transfer-encoding"] = "chunked"
    assert HTTP1Protocol.has_chunked_encoding(headers)
Exemplo n.º 21
0
 def __init__(self, ctx, mode):
     super(Http1Layer, self).__init__(ctx)
     self.mode = mode
     self.client_protocol = HTTP1Protocol(self.client_conn)
     self.server_protocol = HTTP1Protocol(self.server_conn)
Exemplo n.º 22
0
def test_has_chunked_encoding():
    h = odict.ODictCaseless()
    assert not HTTP1Protocol.has_chunked_encoding(h)
    h["transfer-encoding"] = ["chunked"]
    assert HTTP1Protocol.has_chunked_encoding(h)
Exemplo n.º 23
0
    def run(self):
        r = self.flow.request
        form_out_backup = r.form_out
        try:
            self.flow.response = None

            # If we have a channel, run script hooks.
            if self.channel:
                request_reply = self.channel.ask("request", self.flow)
                if request_reply == Kill:
                    raise Kill()
                elif isinstance(request_reply, HTTPResponse):
                    self.flow.response = request_reply

            if not self.flow.response:
                # In all modes, we directly connect to the server displayed
                if self.config.mode == "upstream":
                    server_address = self.config.upstream_server.address
                    server = ServerConnection(server_address)
                    server.connect()
                    protocol = HTTP1Protocol(server)
                    if r.scheme == "https":
                        connect_request = make_connect_request(
                            (r.host, r.port))
                        server.send(protocol.assemble(connect_request))
                        resp = protocol.read_response("CONNECT")
                        if resp.code != 200:
                            raise HttpError(
                                502, "Upstream server refuses CONNECT request")
                        server.establish_ssl(self.config.clientcerts,
                                             sni=self.flow.server_conn.sni)
                        r.form_out = "relative"
                    else:
                        r.form_out = "absolute"
                else:
                    server_address = (r.host, r.port)
                    server = ServerConnection(server_address)
                    server.connect()
                    protocol = HTTP1Protocol(server)
                    if r.scheme == "https":
                        server.establish_ssl(self.config.clientcerts,
                                             sni=self.flow.server_conn.sni)
                    r.form_out = "relative"

                server.send(protocol.assemble(r))
                self.flow.server_conn = server
                self.flow.response = HTTPResponse.from_protocol(
                    protocol,
                    r.method,
                    body_size_limit=self.config.body_size_limit,
                )
            if self.channel:
                response_reply = self.channel.ask("response", self.flow)
                if response_reply == Kill:
                    raise Kill()
        except (HttpError, NetLibError) as v:
            self.flow.error = Error(repr(v))
            if self.channel:
                self.channel.ask("error", self.flow)
        except Kill:
            # Kill should only be raised if there's a channel in the
            # first place.
            from ..proxy.root_context import Log
            self.channel.tell("log", Log("Connection killed", "info"))
        finally:
            r.form_out = form_out_backup
Exemplo n.º 24
0
def mock_protocol(data=''):
    rfile = cStringIO.StringIO(data)
    wfile = cStringIO.StringIO()
    return HTTP1Protocol(rfile=rfile, wfile=wfile)