예제 #1
0
def test_cut():
    c = cut.Cut()
    with taddons.context():
        tflows = [tflow.tflow(resp=True)]
        assert c.cut(tflows, ["request.method"]) == [["GET"]]
        assert c.cut(tflows, ["request.scheme"]) == [["http"]]
        assert c.cut(tflows, ["request.host"]) == [["address"]]
        assert c.cut(tflows, ["request.port"]) == [["22"]]
        assert c.cut(tflows, ["request.path"]) == [["/path"]]
        assert c.cut(tflows, ["request.url"]) == [["http://address:22/path"]]
        assert c.cut(tflows, ["request.content"]) == [[b"content"]]
        assert c.cut(tflows, ["request.header[header]"]) == [["qvalue"]]
        assert c.cut(tflows, ["request.header[unknown]"]) == [[""]]

        assert c.cut(tflows, ["response.status_code"]) == [["200"]]
        assert c.cut(tflows, ["response.reason"]) == [["OK"]]
        assert c.cut(tflows, ["response.content"]) == [[b"message"]]
        assert c.cut(tflows, ["response.header[header-response]"]) == [["svalue"]]
        assert c.cut(tflows, ["moo"]) == [[""]]
        with pytest.raises(exceptions.CommandError):
            assert c.cut(tflows, ["__dict__"]) == [[""]]

    with taddons.context():
        tflows = [tflow.tflow(resp=False)]
        assert c.cut(tflows, ["response.reason"]) == [[""]]
        assert c.cut(tflows, ["response.header[key]"]) == [[""]]

    c = cut.Cut()
    with taddons.context():
        tflows = [tflow.ttcpflow()]
        assert c.cut(tflows, ["request.method"]) == [[""]]
        assert c.cut(tflows, ["response.status"]) == [[""]]
예제 #2
0
def test_cut():
    v = view.View()
    c = cut.Cut()
    with taddons.context() as tctx:
        v.add([tflow.tflow(resp=True)])
        tctx.master.addons.add(v, c)
        assert c.cut("q.method|@all") == [["GET"]]
        assert c.cut("q.scheme|@all") == [["http"]]
        assert c.cut("q.host|@all") == [["address"]]
        assert c.cut("q.port|@all") == [["22"]]
        assert c.cut("q.path|@all") == [["/path"]]
        assert c.cut("q.url|@all") == [["http://*****:*****@all") == [[b"content"]]
        assert c.cut("q.header[header]|@all") == [["qvalue"]]
        assert c.cut("q.header[unknown]|@all") == [[""]]

        assert c.cut("s.status_code|@all") == [["200"]]
        assert c.cut("s.reason|@all") == [["OK"]]
        assert c.cut("s.content|@all") == [[b"message"]]
        assert c.cut("s.header[header-response]|@all") == [["svalue"]]
        assert c.cut("moo") == [[""]]
        with pytest.raises(exceptions.CommandError):
            assert c.cut("__dict__") == [[""]]

    v = view.View()
    c = cut.Cut()
    with taddons.context() as tctx:
        tctx.master.addons.add(v, c)
        v.add([tflow.ttcpflow()])
        assert c.cut("q.method|@all") == [[""]]
        assert c.cut("s.status|@all") == [[""]]
예제 #3
0
def test_decorator():
    with taddons.context() as tctx:
        c = command.CommandManager(tctx.master)
        a = TDec()
        c.collect_commands(a)
        assert "cmd1" in c.commands
        assert c.execute("cmd1 bar") == "ret bar"
        assert "empty" in c.commands
        assert c.execute("empty") is None

    with taddons.context() as tctx:
        tctx.master.addons.add(a)
        assert tctx.master.commands.execute("cmd1 bar") == "ret bar"
예제 #4
0
def test_focus_follow():
    v = view.View()
    with taddons.context() as tctx:
        console_addon = consoleaddons.ConsoleAddon(tctx.master)
        tctx.configure(console_addon)
        tctx.configure(v, console_focus_follow=True, view_filter="~m get")

        v.add([tft(start=5)])
        assert v.focus.index == 0

        v.add([tft(start=4)])
        assert v.focus.index == 0
        assert v.focus.flow.request.timestamp_start == 4

        v.add([tft(start=7)])
        assert v.focus.index == 2
        assert v.focus.flow.request.timestamp_start == 7

        mod = tft(method="put", start=6)
        v.add([mod])
        assert v.focus.index == 2
        assert v.focus.flow.request.timestamp_start == 7

        mod.request.method = "GET"
        v.update([mod])
        assert v.focus.index == 2
        assert v.focus.flow.request.timestamp_start == 6
예제 #5
0
def test_movement():
    v = view.View()
    with taddons.context():
        v.go(0)
        v.add([
            tflow.tflow(),
            tflow.tflow(),
            tflow.tflow(),
            tflow.tflow(),
            tflow.tflow(),
        ])
        assert v.focus.index == 0
        v.go(-1)
        assert v.focus.index == 4
        v.go(0)
        assert v.focus.index == 0
        v.go(1)
        assert v.focus.index == 1
        v.go(999)
        assert v.focus.index == 4
        v.go(-999)
        assert v.focus.index == 0

        v.focus_next()
        assert v.focus.index == 1
        v.focus_prev()
        assert v.focus.index == 0
예제 #6
0
def test_ignore_content():
    s = serverplayback.ServerPlayback()
    with taddons.context(s) as tctx:
        tctx.configure(s, server_replay_ignore_content=False)

        r = tflow.tflow(resp=True)
        r2 = tflow.tflow(resp=True)

        r.request.content = b"foo"
        r2.request.content = b"foo"
        assert s._hash(r) == s._hash(r2)
        r2.request.content = b"bar"
        assert not s._hash(r) == s._hash(r2)

        tctx.configure(s, server_replay_ignore_content=True)
        r = tflow.tflow(resp=True)
        r2 = tflow.tflow(resp=True)
        r.request.content = b"foo"
        r2.request.content = b"foo"
        assert s._hash(r) == s._hash(r2)
        r2.request.content = b"bar"
        assert s._hash(r) == s._hash(r2)
        r2.request.content = b""
        assert s._hash(r) == s._hash(r2)
        r2.request.content = None
        assert s._hash(r) == s._hash(r2)
예제 #7
0
def test_flow_set():
    sa = core.Core()
    with taddons.context(loadcore=False):
        f = tflow.tflow(resp=True)
        assert sa.flow_set_options()

        assert f.request.method != "post"
        sa.flow_set([f], "method", "post")
        assert f.request.method == "POST"

        assert f.request.host != "testhost"
        sa.flow_set([f], "host", "testhost")
        assert f.request.host == "testhost"

        assert f.request.path != "/test/path"
        sa.flow_set([f], "path", "/test/path")
        assert f.request.path == "/test/path"

        assert f.request.url != "http://foo.com/bar"
        sa.flow_set([f], "url", "http://foo.com/bar")
        assert f.request.url == "http://foo.com/bar"
        with pytest.raises(exceptions.CommandError):
            sa.flow_set([f], "url", "oink")

        assert f.response.status_code != 404
        sa.flow_set([f], "status_code", "404")
        assert f.response.status_code == 404
        assert f.response.reason == "Not Found"
        with pytest.raises(exceptions.CommandError):
            sa.flow_set([f], "status_code", "oink")

        assert f.response.reason != "foo"
        sa.flow_set([f], "reason", "foo")
        assert f.response.reason == "foo"
예제 #8
0
    def test_authenticate(self):
        up = proxyauth.ProxyAuth()
        with taddons.context(up, loadcore=False) as ctx:
            ctx.configure(up, proxyauth="any", mode="regular")

            f = tflow.tflow()
            assert not f.response
            up.authenticate(f)
            assert f.response.status_code == 407

            f = tflow.tflow()
            f.request.headers["Proxy-Authorization"] = proxyauth.mkauth(
                "test", "test"
            )
            up.authenticate(f)
            assert not f.response
            assert not f.request.headers.get("Proxy-Authorization")

            f = tflow.tflow()
            ctx.configure(up, mode="reverse")
            assert not f.response
            up.authenticate(f)
            assert f.response.status_code == 401

            f = tflow.tflow()
            f.request.headers["Authorization"] = proxyauth.mkauth(
                "test", "test"
            )
            up.authenticate(f)
            assert not f.response
            assert not f.request.headers.get("Authorization")
예제 #9
0
def test_load():
    s = serverplayback.ServerPlayback()
    with taddons.context(s) as tctx:
        tctx.configure(s)

        r = tflow.tflow(resp=True)
        r.request.headers["key"] = "one"

        r2 = tflow.tflow(resp=True)
        r2.request.headers["key"] = "two"

        s.load_flows([r, r2])

        assert s.count() == 2

        n = s.next_flow(r)
        assert n.request.headers["key"] == "one"
        assert s.count() == 1

        n = s.next_flow(r)
        assert n.request.headers["key"] == "two"
        assert not s.flowmap
        assert s.count() == 0

        assert not s.next_flow(r)
예제 #10
0
    def test_simple(self):
        r = replace.ReplaceFile()
        with tutils.tmpdir() as td:
            rp = os.path.join(td, "replacement")
            with open(rp, "w") as f:
                f.write("bar")
            with taddons.context() as tctx:
                tctx.configure(
                    r,
                    replacement_files = [
                        ("~q", "foo", rp),
                        ("~s", "foo", rp),
                        ("~b nonexistent", "nonexistent", "nonexistent"),
                    ]
                )
                f = tflow.tflow()
                f.request.content = b"foo"
                r.request(f)
                assert f.request.content == b"bar"

                f = tflow.tflow(resp=True)
                f.response.content = b"foo"
                r.response(f)
                assert f.response.content == b"bar"

                f = tflow.tflow()
                f.request.content = b"nonexistent"
                assert not tctx.master.event_log
                r.request(f)
                assert tctx.master.event_log
예제 #11
0
def thash(r, r2, setter):
    s = serverplayback.ServerPlayback()
    with taddons.context(s) as tctx:
        s = serverplayback.ServerPlayback()
        tctx.configure(
            s,
            server_replay_ignore_payload_params=["param1", "param2"]
        )

        setter(r, paramx="x", param1="1")

        setter(r2, paramx="x", param1="1")
        # same parameters
        assert s._hash(r) == s._hash(r2)
        # ignored parameters !=
        setter(r2, paramx="x", param1="2")
        assert s._hash(r) == s._hash(r2)
        # missing parameter
        setter(r2, paramx="x")
        assert s._hash(r) == s._hash(r2)
        # ignorable parameter added
        setter(r2, paramx="x", param1="2")
        assert s._hash(r) == s._hash(r2)
        # not ignorable parameter changed
        setter(r2, paramx="y", param1="1")
        assert not s._hash(r) == s._hash(r2)
        # not ignorable parameter missing
        setter(r2, param1="1")
        r2.request.content = b"param1=1"
        assert not s._hash(r) == s._hash(r2)
예제 #12
0
def test_encoding():
    sa = core.Core()
    with taddons.context():
        f = tflow.tflow()
        assert sa.encode_options()
        sa.encode([f], "request", "deflate")
        assert f.request.headers["content-encoding"] == "deflate"

        sa.encode([f], "request", "br")
        assert f.request.headers["content-encoding"] == "deflate"

        sa.decode([f], "request")
        assert "content-encoding" not in f.request.headers

        sa.encode([f], "request", "br")
        assert f.request.headers["content-encoding"] == "br"

        sa.encode_toggle([f], "request")
        assert "content-encoding" not in f.request.headers
        sa.encode_toggle([f], "request")
        assert f.request.headers["content-encoding"] == "deflate"
        sa.encode_toggle([f], "request")
        assert "content-encoding" not in f.request.headers

        with pytest.raises(exceptions.CommandError):
            sa.encode([f], "request", "invalid")
예제 #13
0
def test_options(tmpdir):
    p = str(tmpdir.join("path"))
    sa = core.Core()
    with taddons.context() as tctx:
        tctx.options.stickycookie = "foo"
        assert tctx.options.stickycookie == "foo"
        sa.options_reset()
        assert tctx.options.stickycookie is None

        tctx.options.stickycookie = "foo"
        tctx.options.stickyauth = "bar"
        sa.options_reset_one("stickycookie")
        assert tctx.options.stickycookie is None
        assert tctx.options.stickyauth == "bar"

        with pytest.raises(exceptions.CommandError):
            sa.options_reset_one("unknown")

        sa.options_save(p)
        with pytest.raises(exceptions.CommandError):
            sa.options_save("/")

        sa.options_reset()
        assert tctx.options.stickyauth is None
        sa.options_load(p)
        assert tctx.options.stickyauth == "bar"

        sa.options_load("/nonexistent")

        with open(p, 'a') as f:
            f.write("'''")
        with pytest.raises(exceptions.CommandError):
            sa.options_load(p)
예제 #14
0
 def test_normal(self, load_flow, tmpdir, data):
     rf = readfile.ReadFileStdin()
     with taddons.context():
         tfile = tmpdir.join("tfile")
         tfile.write(data.getvalue())
         rf.load_flows_from_path(str(tfile))
         assert load_flow.called
예제 #15
0
    def test_playback(self):
        cp = clientplayback.ClientPlayback()
        with taddons.context():
            assert cp.count() == 0
            f = tflow.tflow(resp=True)
            cp.load([f])
            assert cp.count() == 1
            RP = "mitmproxy.proxy.protocol.http_replay.RequestReplayThread"
            with mock.patch(RP) as rp:
                assert not cp.current_thread
                cp.tick()
                assert rp.called
                assert cp.current_thread

            cp.keepserving = False
            cp.flows = None
            cp.current_thread = None
            with mock.patch("mitmproxy.master.Master.shutdown") as sd:
                cp.tick()
                assert sd.called

            cp.current_thread = MockThread()
            with mock.patch("mitmproxy.master.Master.shutdown") as sd:
                cp.tick()
                assert cp.current_thread is None
예제 #16
0
def test_unknown():
    with taddons.context() as tctx:
        b = mitmproxy.types._UnknownType()
        assert b.is_valid(tctx.master.commands, mitmproxy.types.Unknown, "foo") is False
        assert b.is_valid(tctx.master.commands, mitmproxy.types.Unknown, 1) is False
        assert b.completion(tctx.master.commands, mitmproxy.types.Unknown, "") == []
        assert b.parse(tctx.master.commands, mitmproxy.types.Unknown, "foo") == "foo"
예제 #17
0
def test_path():
    with taddons.context() as tctx:
        b = mitmproxy.types._PathType()
        assert b.parse(tctx.master.commands, mitmproxy.types.Path, "/foo") == "/foo"
        assert b.parse(tctx.master.commands, mitmproxy.types.Path, "/bar") == "/bar"
        assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, "foo") is True
        assert b.is_valid(tctx.master.commands, mitmproxy.types.Path, 3) is False

        def normPathOpts(prefix, match):
            ret = []
            for s in b.completion(tctx.master.commands, mitmproxy.types.Path, match):
                s = s[len(prefix):]
                s = s.replace(os.sep, "/")
                ret.append(s)
            return ret

        cd = os.path.normpath(tutils.test_data.path("mitmproxy/completion"))
        assert normPathOpts(cd, cd) == ['/aaa', '/aab', '/aac', '/bbb/']
        assert normPathOpts(cd, os.path.join(cd, "a")) == ['/aaa', '/aab', '/aac']
        with chdir(cd):
            assert normPathOpts("", "./") == ['./aaa', './aab', './aac', './bbb/']
            assert normPathOpts("", "") == ['./aaa', './aab', './aac', './bbb/']
        assert b.completion(
            tctx.master.commands, mitmproxy.types.Path, "nonexistent"
        ) == ["nonexistent"]
예제 #18
0
def test_arg():
    with taddons.context() as tctx:
        b = mitmproxy.types._ArgType()
        assert b.completion(tctx.master.commands, mitmproxy.types.Arg, "") == []
        assert b.parse(tctx.master.commands, mitmproxy.types.Arg, "foo") == "foo"
        assert b.is_valid(tctx.master.commands, mitmproxy.types.Arg, "foo") is True
        assert b.is_valid(tctx.master.commands, mitmproxy.types.Arg, 1) is False
예제 #19
0
def test_str():
    with taddons.context() as tctx:
        b = mitmproxy.types._StrType()
        assert b.is_valid(tctx.master.commands, str, "foo") is True
        assert b.is_valid(tctx.master.commands, str, 1) is False
        assert b.completion(tctx.master.commands, str, "") == []
        assert b.parse(tctx.master.commands, str, "foo") == "foo"
예제 #20
0
def test_simple():
    sa = streambodies.StreamBodies()
    with taddons.context() as tctx:
        with pytest.raises(exceptions.OptionsError):
            tctx.configure(sa, stream_large_bodies = "invalid")
        tctx.configure(sa, stream_large_bodies = "10")

        f = tflow.tflow()
        f.request.content = b""
        f.request.headers["Content-Length"] = "1024"
        assert not f.request.stream
        sa.requestheaders(f)
        assert f.request.stream

        f = tflow.tflow(resp=True)
        f.response.content = b""
        f.response.headers["Content-Length"] = "1024"
        assert not f.response.stream
        sa.responseheaders(f)
        assert f.response.stream

        f = tflow.tflow(resp=True)
        f.response.headers["content-length"] = "invalid"
        tctx.cycle(sa, f)

        tctx.configure(sa, stream_websockets = True)
        f = tflow.twebsocketflow()
        assert not f.stream
        sa.websocket_start(f)
        assert f.stream
예제 #21
0
def test_echo_request_line():
    sio = io.StringIO()
    d = dumper.Dumper(sio)
    with taddons.context(options=options.Options()) as ctx:
        ctx.configure(d, flow_detail=3, showhost=True)
        f = tflow.tflow(client_conn=None, server_conn=True, resp=True)
        f.request.is_replay = True
        d._echo_request_line(f)
        assert "[replay]" in sio.getvalue()
        sio.truncate(0)

        f = tflow.tflow(client_conn=None, server_conn=True, resp=True)
        f.request.is_replay = False
        d._echo_request_line(f)
        assert "[replay]" not in sio.getvalue()
        sio.truncate(0)

        f = tflow.tflow(client_conn=None, server_conn=True, resp=True)
        f.request.http_version = "nonstandard"
        d._echo_request_line(f)
        assert "nonstandard" in sio.getvalue()
        sio.truncate(0)

        ctx.configure(d, flow_detail=0, showhost=True)
        f = tflow.tflow(client_conn=None, server_conn=True, resp=True)
        terminalWidth = max(shutil.get_terminal_size()[0] - 25, 50)
        f.request.url = "http://address:22/" + ("x" * terminalWidth) + "textToBeTruncated"
        d._echo_request_line(f)
        assert "textToBeTruncated" not in sio.getvalue()
        sio.truncate(0)
예제 #22
0
    def test_handlers(self):
        up = proxyauth.ProxyAuth()
        with taddons.context(up) as ctx:
            ctx.configure(up, proxyauth="any", mode="regular")

            f = tflow.tflow()
            assert not f.response
            up.requestheaders(f)
            assert f.response.status_code == 407

            f = tflow.tflow()
            f.request.method = "CONNECT"
            assert not f.response
            up.http_connect(f)
            assert f.response.status_code == 407

            f = tflow.tflow()
            f.request.method = "CONNECT"
            f.request.headers["Proxy-Authorization"] = proxyauth.mkauth(
                "test", "test"
            )
            up.http_connect(f)
            assert not f.response

            f2 = tflow.tflow(client_conn=f.client_conn)
            up.requestheaders(f2)
            assert not f2.response
            assert f2.metadata["proxyauth"] == ('test', 'test')
예제 #23
0
    def test_check_alpn(self):
        msg = 'ALPN support missing'

        with taddons.context() as tctx:
            a = check_alpn.CheckALPN()
            tctx.configure(a)
            assert not tctx.master.has_log(msg)
예제 #24
0
def test_bind():
    with taddons.context() as tctx:
        km = keymap.Keymap(tctx.master)
        km.executor = mock.Mock()

        with pytest.raises(ValueError):
            km.add("foo", "bar", ["unsupported"])

        km.add("key", "str", ["options", "commands"])
        assert km.get("options", "key")
        assert km.get("commands", "key")
        assert not km.get("flowlist", "key")
        assert len((km.list("commands"))) == 1

        km.handle("unknown", "unknown")
        assert not km.executor.called

        km.handle("options", "key")
        assert km.executor.called

        km.add("glob", "str", ["global"])
        km.executor = mock.Mock()
        km.handle("options", "glob")
        assert km.executor.called

        assert len((km.list("global"))) == 1
예제 #25
0
def test_simple():
    with taddons.context() as tctx:
        a = tctx.master.addons

        assert len(a) == 0
        a.add(TAddon("one"))
        assert a.get("one")
        assert not a.get("two")
        assert len(a) == 1
        a.clear()
        assert len(a) == 0
        assert not a.chain

        a.add(TAddon("one"))
        a.trigger("done")
        a.trigger("tick")
        assert tctx.master.has_log("not callable")

        tctx.master.clear()
        a.get("one").tick = addons
        a.trigger("tick")
        assert not tctx.master.has_log("not callable")

        a.remove(a.get("one"))
        assert not a.get("one")

        ta = TAddon("one")
        a.add(ta)
        a.trigger("custom")
        assert ta.custom_called

        assert ta in a
    def test_playback(self):
        cp = clientplayback.ClientPlayback()
        with taddons.context() as tctx:
            assert cp.count() == 0
            f = tflow.tflow(resp=True)
            cp.start_replay([f])
            assert cp.count() == 1
            RP = "mitmproxy.proxy.protocol.http_replay.RequestReplayThread"
            with mock.patch(RP) as rp:
                assert not cp.current_thread
                cp.tick()
                assert rp.called
                assert cp.current_thread

            cp.flows = []
            cp.current_thread.is_alive.return_value = False
            assert cp.count() == 1
            cp.tick()
            assert cp.count() == 0
            assert tctx.master.has_event("update")
            assert tctx.master.has_event("processing_complete")

            cp.current_thread = MockThread()
            cp.tick()
            assert cp.current_thread is None

            cp.start_replay([f])
            cp.stop_replay()
            assert not cp.flows
예제 #27
0
def test_options(tmpdir):
    p = str(tmpdir.join("path"))
    sa = core.Core()
    with taddons.context() as tctx:
        tctx.options.listen_host = "foo"
        assert tctx.options.listen_host == "foo"
        sa.options_reset_one("listen_host")
        assert tctx.options.listen_host != "foo"

        with pytest.raises(exceptions.CommandError):
            sa.options_reset_one("unknown")

        tctx.options.listen_host = "foo"
        sa.options_save(p)
        with pytest.raises(exceptions.CommandError):
            sa.options_save("/")

        sa.options_reset()
        assert tctx.options.listen_host == ""
        sa.options_load(p)
        assert tctx.options.listen_host == "foo"

        sa.options_load("/nonexistent")

        with open(p, 'a') as f:
            f.write("'''")
        with pytest.raises(exceptions.CommandError):
            sa.options_load(p)
예제 #28
0
def test_simple():
    with taddons.context() as tctx:
        c = command.CommandManager(tctx.master)
        a = TAddon()
        c.add("one.two", a.cmd1)
        assert c.commands["one.two"].help == "cmd1 help"
        assert(c.execute("one.two foo") == "ret foo")
        assert(c.call("one.two", "foo") == "ret foo")
        with pytest.raises(exceptions.CommandError, match="Unknown"):
            c.execute("nonexistent")
        with pytest.raises(exceptions.CommandError, match="Invalid"):
            c.execute("")
        with pytest.raises(exceptions.CommandError, match="argument mismatch"):
            c.execute("one.two too many args")
        with pytest.raises(exceptions.CommandError, match="Unknown"):
            c.call("nonexistent")
        with pytest.raises(exceptions.CommandError, match="No escaped"):
            c.execute("\\")

        c.add("empty", a.empty)
        c.execute("empty")

        fp = io.StringIO()
        c.dump(fp)
        assert fp.getvalue()
예제 #29
0
 def fill_history(self, commands):
     with taddons.context() as tctx:
         history = commander.CommandHistory(tctx.master, size=3)
         for c in commands:
             cbuf = commander.CommandBuffer(tctx.master, c)
             history.add_command(cbuf)
     return history, tctx.master
예제 #30
0
def test_simple():
    r = intercept.Intercept()
    with taddons.context(options=Options()) as tctx:
        assert not r.filt
        tctx.configure(r, intercept="~q")
        assert r.filt
        with pytest.raises(exceptions.OptionsError):
            tctx.configure(r, intercept="~~")
        tctx.configure(r, intercept=None)
        assert not r.filt

        tctx.configure(r, intercept="~s")

        f = tflow.tflow(resp=True)
        tctx.cycle(r, f)
        assert f.intercepted

        f = tflow.tflow(resp=False)
        tctx.cycle(r, f)
        assert not f.intercepted

        f = tflow.tflow(resp=True)
        f.reply._state = "handled"
        r.response(f)
        assert f.intercepted
예제 #31
0
    def test_simple(self):
        with taddons.context() as tctx:
            sc = script.Script(
                tutils.test_data.path(
                    "mitmproxy/data/addonscripts/recorder/recorder.py"))
            tctx.master.addons.add(sc)
            tctx.configure(sc)
            sc.tick()

            rec = tctx.master.addons.get("recorder")

            assert rec.call_log[0][0:2] == ("recorder", "load")

            rec.call_log = []
            f = tflow.tflow(resp=True)
            tctx.master.addons.trigger("request", f)

            assert rec.call_log[0][1] == "request"
예제 #32
0
 def test_configure(self):
     mr = mapremote.MapRemote()
     with taddons.context(mr) as tctx:
         tctx.configure(mr, map_remote=["one/two/three"])
         with pytest.raises(
                 Exception,
                 match="Cannot parse map_remote .* Invalid number"):
             tctx.configure(mr, map_remote=["/"])
         with pytest.raises(
                 Exception,
                 match="Cannot parse map_remote .* Invalid filter"):
             tctx.configure(mr, map_remote=["/~b/two/three"])
         with pytest.raises(
                 Exception,
                 match=
                 "Cannot parse map_remote .* Invalid regular expression"):
             tctx.configure(mr, map_remote=["/foo/+/three"])
         tctx.configure(mr, map_remote=["/a/b/c/"])
예제 #33
0
    async def test_script_deletion(self, tdata):
        tdir = tdata.path("mitmproxy/data/addonscripts/")
        with open(tdir + "/dummy.py", 'w') as f:
            f.write("\n")

        with taddons.context() as tctx:
            sl = script.ScriptLoader()
            tctx.master.addons.add(sl)
            tctx.configure(
                sl,
                scripts=[tdata.path("mitmproxy/data/addonscripts/dummy.py")])
            await tctx.master.await_log("Loading")

            os.remove(tdata.path("mitmproxy/data/addonscripts/dummy.py"))

            await tctx.master.await_log("Removing")
            assert not tctx.options.scripts
            assert not sl.addons
예제 #34
0
    def test_response_weird(self):
        sc = stickycookie.StickyCookie()
        with taddons.context(sc) as tctx:
            tctx.configure(sc, stickycookie=".*")

            # Test setting of weird cookie keys
            f = tflow.tflow(req=ntutils.treq(host="www.google.com", port=80),
                            resp=True)
            cs = [
                "foo/bar=hello",
                "foo:bar=world",
                "foo@bar=fizz",
            ]
            for c in cs:
                f.response.headers["Set-Cookie"] = c
                sc.response(f)
            googlekey = list(sc.jar.keys())[0]
            assert len(sc.jar[googlekey].keys()) == len(cs)
예제 #35
0
def test_cutspec():
    with taddons.context() as tctx:
        b = mitmproxy.types._CutSpecType()
        b.parse(tctx.master.commands, mitmproxy.types.CutSpec,
                "foo,bar") == ["foo", "bar"]
        assert b.is_valid(tctx.master.commands, mitmproxy.types.CutSpec,
                          1) is False
        assert b.is_valid(tctx.master.commands, mitmproxy.types.CutSpec,
                          "foo") is False
        assert b.is_valid(tctx.master.commands, mitmproxy.types.CutSpec,
                          "request.path") is True

        assert b.completion(tctx.master.commands, mitmproxy.types.CutSpec,
                            "request.p") == b.valid_prefixes
        ret = b.completion(tctx.master.commands, mitmproxy.types.CutSpec,
                           "request.port,f")
        assert ret[0].startswith("request.port,")
        assert len(ret) == len(b.valid_prefixes)
예제 #36
0
    def test_client_cert_file(self, tdata, client_certs):
        ta = tlsconfig.TlsConfig()
        with taddons.context(ta) as tctx:
            ctx = context.Context(connection.Client(("client", 1234), ("127.0.0.1", 8080), 1605699329), tctx.options)
            ctx.server.address = ("example.mitmproxy.org", 443)
            tctx.configure(
                ta,
                client_certs=tdata.path(client_certs),
                ssl_verify_upstream_trusted_ca=tdata.path("mitmproxy/net/data/verificationcerts/trusted-root.crt"),
            )

            tls_start = tls.TlsStartData(ctx.server, context=ctx)
            ta.tls_start_server(tls_start)
            tssl_client = tls_start.ssl_conn
            tssl_server = test_tls.SSLTest(server_side=True)

            assert self.do_handshake(tssl_client, tssl_server)
            assert tssl_server.obj.getpeercert()
예제 #37
0
def test_loader():
    with taddons.context() as tctx:
        l = addonmanager.Loader(tctx.master)
        l.add_option("custom_option", bool, False, "help")
        assert "custom_option" in l.master.options

        # calling this again with the same signature is a no-op.
        l.add_option("custom_option", bool, False, "help")
        assert not tctx.master.has_log("Over-riding existing option")

        # a different signature should emit a warning though.
        l.add_option("custom_option", bool, True, "help")
        assert tctx.master.has_log("Over-riding existing option")

        def cmd(a: str) -> str:
            return "foo"

        l.add_command("test.command", cmd)
예제 #38
0
    def test_make_top_layer(self):
        nl = NextLayer()
        ctx = MagicMock()
        with taddons.context(nl) as tctx:
            tctx.configure(nl, mode="regular")
            assert isinstance(nl.make_top_layer(ctx), layers.modes.HttpProxy)

            tctx.configure(nl, mode="transparent")
            assert isinstance(nl.make_top_layer(ctx),
                              layers.modes.TransparentProxy)

            tctx.configure(nl, mode="reverse:http://example.com")
            assert isinstance(nl.make_top_layer(ctx),
                              layers.modes.ReverseProxy)

            tctx.configure(nl, mode="socks5")
            with pytest.raises(NotImplementedError):
                nl.make_top_layer(ctx)
예제 #39
0
def test_simple(tmpdir):
    sa = save.Save()
    with taddons.context(sa) as tctx:
        p = str(tmpdir.join("foo"))

        tctx.configure(sa, save_stream_file=p)

        f = tflow.tflow(resp=True)
        sa.request(f)
        sa.response(f)
        tctx.configure(sa, save_stream_file=None)
        assert rd(p)[0].response

        tctx.configure(sa, save_stream_file="+" + p)
        f = tflow.tflow()
        sa.request(f)
        tctx.configure(sa, save_stream_file=None)
        assert not rd(p)[1].response
예제 #40
0
    def test_script_deletion(self):
        tdir = tutils.test_data.path("mitmproxy/data/addonscripts/")
        with open(tdir + "/dummy.py", 'w') as f:
            f.write("\n")
        with taddons.context() as tctx:
            sl = script.ScriptLoader()
            tctx.master.addons.add(sl)
            tctx.configure(sl,
                           scripts=[
                               tutils.test_data.path(
                                   "mitmproxy/data/addonscripts/dummy.py")
                           ])

            os.remove(
                tutils.test_data.path("mitmproxy/data/addonscripts/dummy.py"))
            tctx.invoke(sl, "tick")
            assert not tctx.options.scripts
            assert not sl.addons
예제 #41
0
 def test_simple(self):
     sc = script.ScriptLoader()
     with taddons.context(loadcore=False) as tctx:
         tctx.master.addons.add(sc)
         sc.running()
         assert len(tctx.master.addons) == 1
         tctx.master.options.update(
             scripts = [
                 tutils.test_data.path(
                     "mitmproxy/data/addonscripts/recorder/recorder.py"
                 )
             ]
         )
         assert len(tctx.master.addons) == 1
         assert len(sc.addons) == 1
         tctx.master.options.update(scripts = [])
         assert len(tctx.master.addons) == 1
         assert len(sc.addons) == 0
예제 #42
0
async def test_load(tmpdir):
    path = str(tmpdir.join("path"))
    v = view.View()
    with taddons.context() as tctx:
        tctx.master.addons.add(v)
        tdump(path, [tflow.tflow(resp=True), tflow.tflow(resp=True)])
        v.load_file(path)
        assert len(v) == 2
        v.load_file(path)
        assert len(v) == 4
        try:
            v.load_file("nonexistent_file_path")
        except OSError:
            assert False
        with open(path, "wb") as f:
            f.write(b"invalidflows")
        v.load_file(path)
        assert await tctx.master.await_log("Invalid data format.")
예제 #43
0
def test_configure():
    v = view.View()
    with taddons.context(options=Options()) as tctx:
        tctx.configure(v, filter="~q")
        tutils.raises("invalid interception filter",
                      tctx.configure,
                      v,
                      filter="~~")

        tctx.configure(v, order="method")
        tutils.raises("unknown flow order", tctx.configure, v, order="no")

        tctx.configure(v, order_reversed=True)

        tctx.configure(v, order=None)

        tctx.configure(v, focus_follow=True)
        assert v.focus_follow
예제 #44
0
def test_save_command(tmpdir):
    sa = save.Save()
    with taddons.context() as tctx:
        p = str(tmpdir.join("foo"))
        sa.save([tflow.tflow(resp=True)], p)
        assert len(rd(p)) == 1
        sa.save([tflow.tflow(resp=True)], p)
        assert len(rd(p)) == 1
        sa.save([tflow.tflow(resp=True)], "+" + p)
        assert len(rd(p)) == 2

        with pytest.raises(exceptions.CommandError):
            sa.save([tflow.tflow(resp=True)], str(tmpdir))

        v = view.View()
        tctx.master.addons.add(v)
        tctx.master.addons.add(sa)
        tctx.master.commands.execute("save.file @shown %s" % p)
예제 #45
0
    def test_create_proxy_server_ssl_conn_insecure(self):
        ta = tlsconfig.TlsConfig()
        with taddons.context(ta) as tctx:
            ctx = context.Context(
                context.Client(("client", 1234), ("127.0.0.1", 8080),
                               1605699329), tctx.options)
            ctx.server.address = ("example.mitmproxy.org", 443)

            tctx.configure(ta,
                           ssl_verify_upstream_trusted_ca=None,
                           ssl_insecure=True,
                           http2=False,
                           ciphers_server="ALL")
            tls_start = tls.TlsStartData(ctx.server, context=ctx)
            ta.tls_start(tls_start)
            tssl_client = tls_start.ssl_conn
            tssl_server = test_tls.SSLTest(server_side=True)
            assert self.do_handshake(tssl_client, tssl_server)
예제 #46
0
def test_hash():
    s = serverplayback.ServerPlayback()
    with taddons.context(s) as tctx:
        tctx.configure(s)

        r = tflow.tflow()
        r2 = tflow.tflow()

        assert s._hash(r)
        assert s._hash(r) == s._hash(r2)
        r.request.headers["foo"] = "bar"
        assert s._hash(r) == s._hash(r2)
        r.request.path = "voing"
        assert s._hash(r) != s._hash(r2)

        r.request.path = "path?blank_value"
        r2.request.path = "path?"
        assert s._hash(r) != s._hash(r2)
예제 #47
0
    def test_create_proxy_server_ssl_conn_verify_failed(self):
        ta = tlsconfig.TlsConfig()
        with taddons.context(ta) as tctx:
            ctx = context.Context(
                context.Client(("client", 1234), ("127.0.0.1", 8080),
                               1605699329), tctx.options)
            ctx.client.alpn_offers = [b"h2"]
            ctx.client.cipher_list = [
                "TLS_AES_256_GCM_SHA384", "ECDHE-RSA-AES128-SHA"
            ]
            ctx.server.address = ("example.mitmproxy.org", 443)

            tls_start = tls.TlsStartData(ctx.server, context=ctx)
            ta.tls_start(tls_start)
            tssl_client = tls_start.ssl_conn
            tssl_server = test_tls.SSLTest(server_side=True)
            with pytest.raises(SSL.Error, match="certificate verify failed"):
                assert self.do_handshake(tssl_client, tssl_server)
예제 #48
0
def test_cut_clip():
    v = view.View()
    c = cut.Cut()
    with taddons.context() as tctx:
        tctx.master.addons.add(v, c)
        v.add([tflow.tflow(resp=True)])

        with mock.patch('pyperclip.copy') as pc:
            tctx.command(c.clip, "@all", "request.method")
            assert pc.called

        with mock.patch('pyperclip.copy') as pc:
            tctx.command(c.clip, "@all", "request.content")
            assert pc.called

        with mock.patch('pyperclip.copy') as pc:
            tctx.command(c.clip, "@all", "request.method,request.content")
            assert pc.called
예제 #49
0
    def test_simple(self):
        sc = stickycookie.StickyCookie()
        with taddons.context() as tctx:
            tctx.configure(sc, stickycookie=".*")
            f = tflow.tflow(resp=True)
            f.response.headers["set-cookie"] = "foo=bar"
            sc.request(f)

            f.reply.acked = False
            sc.response(f)

            assert sc.jar
            assert "cookie" not in f.request.headers

            f = f.copy()
            f.reply.acked = False
            sc.request(f)
            assert f.request.headers["cookie"] == "foo=bar"
예제 #50
0
def test_configure():
    up = proxyauth.ProxyAuth()
    with taddons.context() as ctx:
        with pytest.raises(exceptions.OptionsError):
            ctx.configure(up, proxyauth="foo")

        ctx.configure(up, proxyauth="foo:bar")
        assert up.singleuser == ["foo", "bar"]

        ctx.configure(up, proxyauth=None)
        assert up.singleuser is None

        ctx.configure(up, proxyauth="any")
        assert up.nonanonymous
        ctx.configure(up, proxyauth=None)
        assert not up.nonanonymous

        with pytest.raises(exceptions.OptionsError):
            ctx.configure(
                up,
                proxyauth= "@" + tutils.test_data.path("mitmproxy/net/data/server.crt")
            )
        with pytest.raises(exceptions.OptionsError):
            ctx.configure(up, proxyauth="@nonexistent")

        ctx.configure(
            up,
            proxyauth= "@" + tutils.test_data.path(
                "mitmproxy/net/data/htpasswd"
            )
        )
        assert up.htpasswd
        assert up.htpasswd.check_password("test", "test")
        assert not up.htpasswd.check_password("test", "foo")
        ctx.configure(up, proxyauth=None)
        assert not up.htpasswd

        with pytest.raises(exceptions.OptionsError):
            ctx.configure(up, proxyauth="any", mode="transparent")
        with pytest.raises(exceptions.OptionsError):
            ctx.configure(up, proxyauth="any", mode="socks5")

        ctx.configure(up, mode="regular")
        assert up.mode == "regular"
예제 #51
0
    async def test_read(self, tmpdir, data, corrupt_data):
        rf = readfile.ReadFile()
        with taddons.context(rf) as tctx:
            assert not rf.reading()

            tf = tmpdir.join("tfile")

            with mock.patch('mitmproxy.master.Master.load_flow') as mck:
                tf.write(data.getvalue())
                tctx.configure(rf, rfile=str(tf), readfile_filter=".*")
                mck.assert_not_awaited()
                rf.running()
                await asyncio.sleep(0)
                mck.assert_awaited()

            tf.write(corrupt_data.getvalue())
            tctx.configure(rf, rfile=str(tf))
            rf.running()
            assert await tctx.master.await_log("corrupted")
예제 #52
0
async def test_loader():
    with taddons.context() as tctx:
        with mock.patch("mitmproxy.ctx.log.warn") as warn:
            l = addonmanager.Loader(tctx.master)
            l.add_option("custom_option", bool, False, "help")
            assert "custom_option" in l.master.options

            # calling this again with the same signature is a no-op.
            l.add_option("custom_option", bool, False, "help")
            assert not warn.called

            # a different signature should emit a warning though.
            l.add_option("custom_option", bool, True, "help")
            assert warn.called

            def cmd(a: str) -> str:
                return "foo"

            l.add_command("test.command", cmd)
예제 #53
0
def test_order():
    v = view.View()
    with taddons.context() as tctx:
        v.request(tft(method="get", start=1))
        v.request(tft(method="put", start=2))
        v.request(tft(method="get", start=3))
        v.request(tft(method="put", start=4))
        assert [i.request.timestamp_start for i in v] == [1, 2, 3, 4]

        tctx.configure(v, view_order="method")
        assert [i.request.method for i in v] == ["GET", "GET", "PUT", "PUT"]
        v.set_reversed(True)
        assert [i.request.method for i in v] == ["PUT", "PUT", "GET", "GET"]

        tctx.configure(v, view_order="time")
        assert [i.request.timestamp_start for i in v] == [4, 3, 2, 1]

        v.set_reversed(False)
        assert [i.request.timestamp_start for i in v] == [1, 2, 3, 4]
예제 #54
0
    def test_simple(self):
        r = replace.Replace()
        with taddons.context() as tctx:
            tctx.configure(
                r,
                replacements=[
                    "/~q/foo/bar",
                    "/~s/foo/bar",
                ]
            )
            f = tflow.tflow()
            f.request.content = b"foo"
            r.request(f)
            assert f.request.content == b"bar"

            f = tflow.tflow(resp=True)
            f.response.content = b"foo"
            r.response(f)
            assert f.response.content == b"bar"
예제 #55
0
def test_ignore_params():
    s = serverplayback.ServerPlayback()
    with taddons.context(s) as tctx:
        tctx.configure(
            s,
            server_replay_ignore_params=["param1", "param2"]
        )

        r = tflow.tflow(resp=True)
        r.request.path = "/test?param1=1"
        r2 = tflow.tflow(resp=True)
        r2.request.path = "/test"
        assert s._hash(r) == s._hash(r2)
        r2.request.path = "/test?param1=2"
        assert s._hash(r) == s._hash(r2)
        r2.request.path = "/test?param2=1"
        assert s._hash(r) == s._hash(r2)
        r2.request.path = "/test?param3=2"
        assert not s._hash(r) == s._hash(r2)
예제 #56
0
def test_export(tmpdir):
    f = str(tmpdir.join("path"))
    e = export.Export()
    with taddons.context():
        assert e.formats() == ["curl", "httpie", "raw"]
        with pytest.raises(exceptions.CommandError):
            e.file("nonexistent", tflow.tflow(resp=True), f)

        e.file("raw", tflow.tflow(resp=True), f)
        assert qr(f)
        os.unlink(f)

        e.file("curl", tflow.tflow(resp=True), f)
        assert qr(f)
        os.unlink(f)

        e.file("httpie", tflow.tflow(resp=True), f)
        assert qr(f)
        os.unlink(f)
예제 #57
0
def test_ignore_payload_params_other_content_type():
    s = serverplayback.ServerPlayback()
    with taddons.context(s) as tctx:
        tctx.configure(
            s,
            server_replay_ignore_content=False,
            server_replay_ignore_payload_params=["param1", "param2"])

        r = tflow.tflow(resp=True)
        r.request.headers["Content-Type"] = "application/json"
        r.request.content = b'{"param1":"1"}'
        r2 = tflow.tflow(resp=True)
        r2.request.headers["Content-Type"] = "application/json"
        r2.request.content = b'{"param1":"1"}'
        # same content
        assert s._hash(r) == s._hash(r2)
        # distint content (note only x-www-form-urlencoded payload is analysed)
        r2.request.content = b'{"param1":"2"}'
        assert not s._hash(r) == s._hash(r2)
예제 #58
0
def test_simple():
    sa = streamfile.StreamFile()
    with taddons.context() as tctx:
        with tutils.tmpdir() as tdir:
            p = os.path.join(tdir, "foo")

            tctx.configure(sa, streamfile=p)

            f = tflow.tflow(resp=True)
            sa.request(f)
            sa.response(f)
            tctx.configure(sa, streamfile=None)
            assert rd(p)[0].response

            tctx.configure(sa, streamfile=p, streamfile_append=True)
            f = tflow.tflow()
            sa.request(f)
            tctx.configure(sa, streamfile=None)
            assert not rd(p)[1].response
예제 #59
0
async def test_allowremote(allow_remote, ip, should_be_killed):
    ar = allowremote.AllowRemote()
    up = proxyauth.ProxyAuth()
    with taddons.context(ar, up) as tctx:
        tctx.options.allow_remote = allow_remote

        with mock.patch('mitmproxy.proxy.protocol.base.Layer') as layer:
            layer.client_conn.address = (ip, 12345)

            ar.clientconnect(layer)
            if should_be_killed:
                assert await tctx.master.await_log("Client connection was killed", "warn")
            else:
                assert tctx.master.logs == []
            tctx.master.clear()

            tctx.options.proxyauth = "any"
            ar.clientconnect(layer)
            assert tctx.master.logs == []
def test_simple():
    sa = core_option_validation.CoreOptionValidation()
    with taddons.context() as tctx:
        with pytest.raises(exceptions.OptionsError):
            tctx.configure(sa, body_size_limit = "invalid")
        tctx.configure(sa, body_size_limit = "1m")
        assert tctx.options._processed["body_size_limit"]

        with pytest.raises(exceptions.OptionsError, match="mutually exclusive"):
            tctx.configure(
                sa,
                add_upstream_certs_to_client_chain = True,
                upstream_cert = False
            )
        with pytest.raises(exceptions.OptionsError, match="Invalid mode"):
            tctx.configure(
                sa,
                mode = "Flibble"
            )