def test_assemble_request_line():
    assert _assemble_request_line(treq().data) == b"GET /path HTTP/1.1"

    authority_request = treq(method=b"CONNECT", first_line_format="authority").data
    assert _assemble_request_line(authority_request) == b"CONNECT address:22 HTTP/1.1"

    absolute_request = treq(first_line_format="absolute").data
    assert _assemble_request_line(absolute_request) == b"GET http://address:22/path HTTP/1.1"

    with raises(RuntimeError):
        _assemble_request_line(treq(first_line_format="invalid_form").data)
 def test_intercept(self):
     """regression test for https://github.com/mitmproxy/mitmproxy/issues/1605"""
     m = self.mkmaster(intercept="~b bar")
     f = tflow.tflow(req=tutils.treq(content=b"foo"))
     m.addons.handle_lifecycle("request", f)
     assert not m.view[0].intercepted
     f = tflow.tflow(req=tutils.treq(content=b"bar"))
     m.addons.handle_lifecycle("request", f)
     assert m.view[1].intercepted
     f = tflow.tflow(resp=tutils.tresp(content=b"bar"))
     m.addons.handle_lifecycle("request", f)
     assert m.view[2].intercepted
def test_assemble_request():
    assert assemble_request(treq()) == (
        b"GET /path HTTP/1.1\r\n"
        b"header: qvalue\r\n"
        b"content-length: 7\r\n"
        b"host: address:22\r\n"
        b"\r\n"
        b"content"
    )

    with raises(exceptions.HttpException):
        assemble_request(treq(content=None))
 def test_path(self):
     req = treq()
     _test_decoded_attr(req, "path")
     # path can also be None.
     req.path = None
     assert req.path is None
     assert req.data.path is None
Exemple #5
0
 def cycle(self, master, content):
     f = tflow.tflow(req=tutils.treq(content=content))
     master.addons.handle_lifecycle("clientconnect", f.client_conn)
     for i in eventsequence.iterate(f):
         master.addons.handle_lifecycle(*i)
     master.addons.handle_lifecycle("clientdisconnect", f.client_conn)
     return f
 def test_anticache(self):
     request = treq()
     request.headers["If-Modified-Since"] = "foo"
     request.headers["If-None-Match"] = "bar"
     request.anticache()
     assert "If-Modified-Since" not in request.headers
     assert "If-None-Match" not in request.headers
Exemple #7
0
    def test_replay(self):
        opts = options.Options()
        fm = master.Master(opts)
        f = tflow.tflow(resp=True)
        f.request.content = None
        with pytest.raises(ReplayException, match="missing"):
            fm.replay_request(f)

        f.request = None
        with pytest.raises(ReplayException, match="request"):
            fm.replay_request(f)

        f.intercepted = True
        with pytest.raises(ReplayException, match="intercepted"):
            fm.replay_request(f)

        f.live = True
        with pytest.raises(ReplayException, match="live"):
            fm.replay_request(f)

        req = tutils.treq(headers=net_http.Headers(((b":authority", b"foo"), (b"header", b"qvalue"), (b"content-length", b"7"))))
        f = tflow.tflow(req=req)
        f.request.http_version = "HTTP/2.0"
        with mock.patch('mitmproxy.proxy.protocol.http_replay.RequestReplayThread.run'):
            rt = fm.replay_request(f)
            assert rt.f.request.http_version == "HTTP/1.1"
            assert ":authority" not in rt.f.request.headers
Exemple #8
0
def test_read_chunked():
    req = treq(content=None)
    req.headers["Transfer-Encoding"] = "chunked"

    data = b"1\r\na\r\n0\r\n"
    with raises(exceptions.HttpSyntaxException):
        b"".join(_read_chunked(BytesIO(data)))

    data = b"1\r\na\r\n0\r\n\r\n"
    assert b"".join(_read_chunked(BytesIO(data))) == b"a"

    data = b"\r\n\r\n1\r\na\r\n1\r\nb\r\n0\r\n\r\n"
    assert b"".join(_read_chunked(BytesIO(data))) == b"ab"

    data = b"\r\n"
    with raises("closed prematurely"):
        b"".join(_read_chunked(BytesIO(data)))

    data = b"1\r\nfoo"
    with raises("malformed chunked body"):
        b"".join(_read_chunked(BytesIO(data)))

    data = b"foo\r\nfoo"
    with raises(exceptions.HttpSyntaxException):
        b"".join(_read_chunked(BytesIO(data)))

    data = b"5\r\naaaaa\r\n0\r\n\r\n"
    with raises("too large"):
        b"".join(_read_chunked(BytesIO(data), limit=2))
Exemple #9
0
def tflow(client_conn=True, server_conn=True, req=True, resp=None, err=None):
    """
    @type client_conn: bool | None | mitmproxy.proxy.connection.ClientConnection
    @type server_conn: bool | None | mitmproxy.proxy.connection.ServerConnection
    @type req:         bool | None | mitmproxy.proxy.protocol.http.HTTPRequest
    @type resp:        bool | None | mitmproxy.proxy.protocol.http.HTTPResponse
    @type err:         bool | None | mitmproxy.proxy.protocol.primitives.Error
    @return:           mitmproxy.proxy.protocol.http.HTTPFlow
    """
    if client_conn is True:
        client_conn = tclient_conn()
    if server_conn is True:
        server_conn = tserver_conn()
    if req is True:
        req = tutils.treq()
    if resp is True:
        resp = tutils.tresp()
    if err is True:
        err = terr()

    if req:
        req = http.HTTPRequest.wrap(req)
    if resp:
        resp = http.HTTPResponse.wrap(resp)

    f = http.HTTPFlow(client_conn, server_conn)
    f.request = req
    f.response = resp
    f.error = err
    f.reply = controller.DummyReply()
    return f
 def test_get_cookies_withequalsign(self):
     request = treq()
     request.headers = Headers(cookie="cookiename=coo=kievalue;othercookiename=othercookievalue")
     result = request.cookies
     assert len(result) == 2
     assert result['cookiename'] == 'coo=kievalue'
     assert result['othercookiename'] == 'othercookievalue'
Exemple #11
0
 def test_response(self, monkeypatch, logger):
     logger.args = []
     monkeypatch.setattr("mitmproxy.ctx.log", logger)
     monkeypatch.setattr(requests, 'get', self.mocked_requests_invuln)
     mocked_flow = tflow.tflow(req=tutils.treq(path=b"index.html?q=1"), resp=tutils.tresp(content=b'<html></html>'))
     xss.response(mocked_flow)
     assert logger.args == []
    def test_host(self):
        request = treq()
        assert request.host == request.data.host.decode("idna")

        # Test IDNA encoding
        # Set str, get raw bytes
        request.host = "ídna.example"
        assert request.data.host == b"xn--dna-qma.example"
        # Set raw bytes, get decoded
        request.data.host = b"xn--idn-gla.example"
        assert request.host == "idná.example"
        # Set bytes, get raw bytes
        request.host = b"xn--dn-qia9b.example"
        assert request.data.host == b"xn--dn-qia9b.example"
        # IDNA encoding is not bijective
        request.host = "fußball"
        assert request.host == "fussball"

        # Don't fail on garbage
        request.data.host = b"foo\xFF\x00bar"
        assert request.host.startswith("foo")
        assert request.host.endswith("bar")
        # foo.bar = foo.bar should not cause any side effects.
        d = request.host
        request.host = d
        assert request.data.host == b"foo\xFF\x00bar"
 def test_response(self, get_request_invuln, logger):
     mocked_flow = tflow.tflow(
         req=tutils.treq(path=b"index.html?q=1"),
         resp=tutils.tresp(content=b'<html></html>')
     )
     xss.response(mocked_flow)
     assert logger.args == []
    def test_get_urlencoded_form(self):
        request = treq(content=b"foobar=baz")
        assert not request.urlencoded_form

        request.headers["Content-Type"] = "application/x-www-form-urlencoded"
        assert list(request.urlencoded_form.items()) == [("foobar", "baz")]
        request.raw_content = b"\xFF"
        assert len(request.urlencoded_form) == 0
Exemple #15
0
def post_request():
    return tflow.tflow(
        req=tutils.treq(
            method=b'POST',
            headers=(),
            content=bytes(range(256))
        )
    )
Exemple #16
0
def get_request():
    return tflow.tflow(
        req=tutils.treq(
            method=b'GET',
            content=b'',
            path=b"/path?a=foo&a=bar&b=baz"
        )
    )
 def test_set_query(self):
     request = treq()
     assert not request.query
     request.query["foo"] = "bar"
     assert request.query["foo"] == "bar"
     assert request.path == "/path?foo=bar"
     request.query = [('foo', 'bar')]
     assert request.query["foo"] == "bar"
     assert request.path == "/path?foo=bar"
 def test_set_cookies(self):
     request = treq()
     request.headers = Headers(cookie="cookiename=cookievalue")
     result = request.cookies
     result["cookiename"] = "foo"
     assert request.cookies["cookiename"] == "foo"
     request.cookies = [["one", "uno"], ["two", "due"]]
     assert request.cookies["one"] == "uno"
     assert request.cookies["two"] == "due"
Exemple #19
0
def test_read_response(input):
    req = treq()
    rfile = BytesIO(input)
    r = read_response(rfile, req)
    assert r.http_version == "HTTP/1.1"
    assert r.status_code == 418
    assert r.reason == "I'm a teapot"
    assert r.content == b"body"
    assert r.timestamp_end
Exemple #20
0
    def replace(self):
        r = treq()
        r.path = b"foobarfoo"
        r.replace(b"foo", "bar")
        assert r.path == b"barbarbar"

        r.path = b"foobarfoo"
        r.replace(b"foo", "bar", count=1)
        assert r.path == b"barbarfoo"
    def test_host_update_also_updates_header(self):
        request = treq()
        assert "host" not in request.headers
        request.host = "example.com"
        assert "host" not in request.headers

        request.headers["Host"] = "foo"
        request.host = "example.org"
        assert request.headers["Host"] == "example.org"
def test_assemble_request_headers_host_header():
    r = treq()
    r.headers = Headers()
    c = _assemble_request_headers(r.data)
    assert b"host" in c

    r.host = None
    c = _assemble_request_headers(r.data)
    assert b"host" not in c
    def test_get_host_header(self):
        no_hdr = treq()
        assert no_hdr.host_header is None

        h1 = treq(headers=(
            (b"host", b"example.com"),
        ))
        assert h1.host_header == "example.com"

        h2 = treq(headers=(
            (b":authority", b"example.org"),
        ))
        assert h2.host_header == "example.org"

        both_hdrs = treq(headers=(
            (b"host", b"example.org"),
            (b":authority", b"example.com"),
        ))
        assert both_hdrs.host_header == "example.com"
Exemple #24
0
 def cycle(self, master, content):
     f = tflow.tflow(req=tutils.treq(content=content))
     layer = mock.Mock("mitmproxy.proxy.protocol.base.Layer")
     layer.client_conn = f.client_conn
     layer.reply = controller.DummyReply()
     master.addons.handle_lifecycle("clientconnect", layer)
     for i in eventsequence.iterate(f):
         master.addons.handle_lifecycle(*i)
     master.addons.handle_lifecycle("clientdisconnect", layer)
     return f
    def test_get_multipart_form(self):
        request = treq(content=b"foobar")
        assert not request.multipart_form

        request.headers["Content-Type"] = "multipart/form-data"
        assert list(request.multipart_form.items()) == []

        with mock.patch('mitmproxy.net.http.multipart.decode') as m:
            m.side_effect = ValueError
            assert list(request.multipart_form.items()) == []
Exemple #26
0
    def test_modify_querystring(self):
        m, sc = tscript("simple/modify_querystring.py")
        f = tflow.tflow(req=tutils.treq(path="/search?q=term"))

        m.request(f)
        assert f.request.query["mitmproxy"] == "rocks"

        f.request.path = "/"
        m.request(f)
        assert f.request.query["mitmproxy"] == "rocks"
    def test_constrain_encoding(self):
        request = treq()

        h = request.headers.copy()
        request.constrain_encoding()  # no-op if there is no accept_encoding header.
        assert request.headers == h

        request.headers["Accept-Encoding"] = "identity, gzip, foo"
        request.constrain_encoding()
        assert "foo" not in request.headers["Accept-Encoding"]
        assert "gzip" in request.headers["Accept-Encoding"]
 def test_pretty_url(self):
     request = treq()
     # Without host header
     assert request.url == "http://address:22/path"
     assert request.pretty_url == "http://address:22/path"
     # Same port as self.port (22)
     request.headers["host"] = "other:22"
     assert request.pretty_url == "http://other:22/path"
     # Different ports
     request.headers["host"] = "other"
     assert request.pretty_url == "http://address:22/path"
Exemple #29
0
    def test_modify_querystring(self, tdata):
        with taddons.context() as tctx:
            sc = tctx.script(tdata.path("../examples/simple/modify_querystring.py"))
            f = tflow.tflow(req=tutils.treq(path="/search?q=term"))

            sc.request(f)
            assert f.request.query["mitmproxy"] == "rocks"

            f.request.path = "/"
            sc.request(f)
            assert f.request.query["mitmproxy"] == "rocks"
Exemple #30
0
    def flow(self, resp_content=b'message'):
        times = dict(
            timestamp_start=746203272,
            timestamp_end=746203272,
        )

        # Create a dummy flow for testing
        return tflow.tflow(
            req=tutils.treq(method=b'GET', **times),
            resp=tutils.tresp(content=resp_content, **times)
        )
Exemple #31
0
 def test_redirect_requests(self):
     m, sc = tscript("redirect_requests.py")
     f = tutils.tflow(req=netutils.treq(host="example.org"))
     m.request(f)
     assert f.request.host == "mitmproxy.org"
Exemple #32
0
 def test_response(self, get_request_invuln, logger):
     mocked_flow = tflow.tflow(req=tutils.treq(path=b"index.html?q=1"),
                               resp=tutils.tresp(content=b'<html></html>'))
     xss.response(mocked_flow)
     assert logger.args == []
Exemple #33
0
 def test_first_line_format(self):
     assert treq(method=b"CONNECT").first_line_format == "authority"
     assert treq(authority=b"example.com").first_line_format == "absolute"
     assert treq(authority=b"").first_line_format == "relative"
Exemple #34
0
def test_assemble_request_head():
    c = assemble_request_head(treq(content=b"foo"))
    assert b"GET" in c
    assert b"qvalue" in c
    assert b"content-length" in c
    assert b"foo" not in c
Exemple #35
0
def test_expected_http_body_size():
    # Expect: 100-continue
    assert expected_http_body_size(
        treq(headers=Headers(expect="100-continue", content_length="42")),
        expect_continue_as_0=True) == 0
    # Expect: 100-continue
    assert expected_http_body_size(
        treq(headers=Headers(expect="100-continue", content_length="42")),
        expect_continue_as_0=False) == 42

    # http://tools.ietf.org/html/rfc7230#section-3.3
    assert expected_http_body_size(
        treq(method=b"HEAD"), tresp(headers=Headers(content_length="42"))) == 0
    assert expected_http_body_size(treq(method=b"CONNECT"), tresp()) == 0
    for code in (100, 204, 304):
        assert expected_http_body_size(treq(), tresp(status_code=code)) == 0

    # chunked
    assert expected_http_body_size(
        treq(headers=Headers(transfer_encoding="chunked")), ) is None

    # explicit length
    for val in (b"foo", b"-7"):
        with pytest.raises(exceptions.HttpSyntaxException):
            expected_http_body_size(treq(headers=Headers(content_length=val)))
    assert expected_http_body_size(
        treq(headers=Headers(content_length="42"))) == 42

    # more than 1 content-length headers with same value
    assert expected_http_body_size(
        treq(headers=Headers([(b'content-length',
                               b'42'), (b'content-length', b'42')]))) == 42

    # more than 1 content-length headers with conflicting value
    with pytest.raises(exceptions.HttpSyntaxException):
        expected_http_body_size(
            treq(headers=Headers([(b'content-length',
                                   b'42'), (b'content-length', b'45')])))

    # no length
    assert expected_http_body_size(treq(headers=Headers())) == 0
    assert expected_http_body_size(treq(headers=Headers()),
                                   tresp(headers=Headers())) == -1
Exemple #36
0
 def test_pretty_url_authority(self):
     request = treq(first_line_format="authority")
     assert request.pretty_url == "address:22"
Exemple #37
0
 def test_first_line_format(self):
     _test_passthrough_attr(treq(), "first_line_format")
Exemple #38
0
 def test_pretty_url_authority(self):
     request = treq(method=b"CONNECT", authority="address:22")
     assert request.pretty_url == "address:22"
Exemple #39
0
 def test_pretty_url_options(self):
     request = treq(method=b"OPTIONS", path=b"*")
     assert request.pretty_url == "http://address:22"
Exemple #40
0
 def test_url_authority(self):
     request = treq(method=b"CONNECT")
     assert request.url == "address:22"
Exemple #41
0
 def test_path(self):
     _test_decoded_attr(treq(), "path")
Exemple #42
0
 def test_port(self):
     _test_passthrough_attr(treq(), "port")
Exemple #43
0
 def test_scheme(self):
     _test_decoded_attr(treq(), "scheme")
Exemple #44
0
 def test_method(self):
     _test_decoded_attr(treq(), "method")
Exemple #45
0
 def test_set_multipart_form(self):
     request = treq()
     request.multipart_form = [(b"file", b"shell.jpg"), (b"file_size", b"1000")]
     assert request.headers["Content-Type"].startswith('multipart/form-data')
     assert list(request.multipart_form.items()) == [(b"file", b"shell.jpg"), (b"file_size", b"1000")]
Exemple #46
0
 def test_scheme(self):
     _test_decoded_attr(treq(), "scheme")
     assert treq(scheme=None).scheme is None
Exemple #47
0
    def test_get_query(self):
        request = treq()
        assert not request.query

        request.url = "http://localhost:80/foo?bar=42"
        assert dict(request.query) == {"bar": "42"}
Exemple #48
0
 def test_set_multipart_form(self):
     request = treq(content=b"foobar")
     with pytest.raises(NotImplementedError):
         request.multipart_form = "foobar"
Exemple #49
0
 def test_get_cookies_none(self):
     request = treq()
     request.headers = Headers()
     assert not request.cookies
Exemple #50
0
 def test_send_reply_from_proxy(self):
     m, sc = tscript("simple/send_reply_from_proxy.py")
     f = tflow.tflow(req=tutils.treq(host="example.com", port=80))
     m.request(f)
     assert f.response.content == b"Hello World"
Exemple #51
0
 def test_get_cookies_single(self):
     request = treq()
     request.headers = Headers(cookie="cookiename=cookievalue")
     assert len(request.cookies) == 1
     assert request.cookies['cookiename'] == 'cookievalue'
Exemple #52
0
def test_assemble_request_headers():
    # https://github.com/mitmproxy/mitmproxy/issues/186
    r = treq(content=b"")
    r.headers["Transfer-Encoding"] = "chunked"
    c = _assemble_request_headers(r.data)
    assert b"Transfer-Encoding" in c
Exemple #53
0
 def test_get_path_components(self):
     request = treq(path=b"/foo/bar")
     assert request.path_components == ("foo", "bar")
Exemple #54
0
 def test_get_cookies(self):
     mocked_req = tutils.treq()
     mocked_req.cookies = [("cookieName2", "cookieValue2")]
     mocked_flow = tflow.tflow(req=mocked_req)
     # It only uses the request cookies
     assert xss.get_cookies(mocked_flow) == {"cookieName2": "cookieValue2"}
Exemple #55
0
def test_simple():
    sio = io.StringIO()
    sio_err = io.StringIO()
    d = dumper.Dumper(sio, sio_err)
    with taddons.context(d) as ctx:
        ctx.configure(d, flow_detail=0)
        d.response(tflow.tflow(resp=True))
        assert not sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=1)
        d.response(tflow.tflow(resp=True))
        assert sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=1)
        d.error(tflow.tflow(err=True))
        assert sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=4)
        d.response(tflow.tflow(resp=True))
        assert sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=4)
        d.response(tflow.tflow(resp=True))
        assert "<<" in sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=4)
        d.response(tflow.tflow(err=True))
        assert "<<" in sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=4)
        flow = tflow.tflow()
        flow.request = tutils.treq()
        flow.client_conn = mock.MagicMock()
        flow.client_conn.address[0] = "foo"
        flow.response = tutils.tresp(content=None)
        flow.response.is_replay = True
        flow.response.status_code = 300
        d.response(flow)
        assert sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=4)
        flow = tflow.tflow(resp=tutils.tresp(content=b"{"))
        flow.response.headers["content-type"] = "application/json"
        flow.response.status_code = 400
        d.response(flow)
        assert sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)

        ctx.configure(d, flow_detail=4)
        flow = tflow.tflow()
        flow.request.content = None
        flow.response = http.HTTPResponse.wrap(tutils.tresp())
        flow.response.content = None
        d.response(flow)
        assert "content missing" in sio.getvalue()
        sio.truncate(0)
        assert not sio_err.getvalue()
        sio_err.truncate(0)