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") == [[""]]
def test_focus(): # Special case - initialising with a view that already contains data v = view.View() v.add(tft()) f = view.Focus(v) assert f.index is 0 assert f.flow is v[0] # Start empty v = view.View() f = view.Focus(v) assert f.index is None assert f.flow is None v.add(tft(start=1)) assert f.index == 0 assert f.flow is v[0] v.add(tft(start=0)) assert f.index == 1 assert f.flow is v[1] v.add(tft(start=2)) assert f.index == 1 assert f.flow is v[1] v.remove(v[1]) assert f.index == 1 assert f.flow is v[1] v.remove(v[1]) assert f.index == 0 assert f.flow is v[0] v.remove(v[0]) assert f.index is None assert f.flow is None v.add(tft(method="get", start=0)) v.add(tft(method="get", start=1)) v.add(tft(method="put", start=2)) v.add(tft(method="get", start=3)) f.flow = v[2] assert f.flow.request.method == "PUT" filt = flowfilter.parse("~m get") v.set_filter(filt) assert f.index == 2 filt = flowfilter.parse("~m oink") v.set_filter(filt) assert f.index is None
def __init__(self, opts): super().__init__(opts) self.view = view.View() # type: view.View self.stream_path = None self.keymap = keymap.Keymap(self) defaultkeys.map(self.keymap) self.options.errored.connect(self.options_error) self.view_stack = [] signals.call_in.connect(self.sig_call_in) signals.sig_add_log.connect(self.sig_add_log) self.addons.add(consoleaddons.Logger()) self.addons.add(*addons.default_addons()) self.addons.add( intercept.Intercept(), self.view, consoleaddons.UnsupportedLog(), readfile.ReadFile(), consoleaddons.ConsoleAddon(self), ) def sigint_handler(*args, **kwargs): self.prompt_for_exit() signal.signal(signal.SIGINT, sigint_handler) self.window = None
def __init__(self, options, server): super().__init__(options, server) self.view = view.View() # type: view.View self.view.sig_view_update.connect(signals.flow_change.send) self.stream_path = None # This line is just for type hinting self.options = self.options # type: Options self.keymap = keymap.Keymap(self) default_keymap(self.keymap) self.options.errored.connect(self.options_error) self.logbuffer = urwid.SimpleListWalker([]) self.view_stack = [] signals.call_in.connect(self.sig_call_in) signals.pop_view_state.connect(self.sig_pop_view_state) signals.replace_view_state.connect(self.sig_replace_view_state) signals.push_view_state.connect(self.sig_push_view_state) signals.sig_add_log.connect(self.sig_add_log) self.addons.add(Logger()) self.addons.add(*addons.default_addons()) self.addons.add( intercept.Intercept(), self.view, UnsupportedLog(), readfile.ReadFile(), ConsoleCommands(self), ) def sigint_handler(*args, **kwargs): self.prompt_for_exit() signal.signal(signal.SIGINT, sigint_handler)
def __init__(self, opts): super().__init__(opts) self.view: view.View = view.View() self.events = eventstore.EventStore() self.events.sig_add.connect(self.sig_add_log) self.stream_path = None self.keymap = keymap.Keymap(self) defaultkeys.map(self.keymap) self.options.errored.connect(self.options_error) self.view_stack = [] self.addons.add(*addons.default_addons()) self.addons.add( intercept.Intercept(), self.view, self.events, readfile.ReadFile(), consoleaddons.ConsoleAddon(self), keymap.KeymapConfig(), errorcheck.ErrorCheck(log_to_stderr=True), ) self.window = None
def test_filter(): v = view.View() v.request(tft(method="get")) v.request(tft(method="put")) v.request(tft(method="get")) v.request(tft(method="put")) assert(len(v)) == 4 v.set_filter_cmd("~m get") assert [i.request.method for i in v] == ["GET", "GET"] assert len(v._store) == 4 v.set_filter(None) assert len(v) == 4 v.toggle_marked() assert len(v) == 0 v.toggle_marked() assert len(v) == 4 with pytest.raises(exceptions.CommandError): v.set_filter_cmd("~notafilter regex") v[1].marked = True v.toggle_marked() assert len(v) == 1 assert v[0].marked v.toggle_marked() assert len(v) == 4
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 with mock.patch('pyperclip.copy') as pc: log_message = "Pyperclip could not find a " \ "copy/paste mechanism for your system." pc.side_effect = pyperclip.PyperclipException(log_message) tctx.command(c.clip, "@all", "request.method") assert tctx.master.has_log(log_message, level="error")
def __init__(self, options, with_termlog=True): super().__init__(options) self.view = view.View() self.view.sig_view_add.connect(self._sig_view_add) self.view.sig_view_remove.connect(self._sig_view_remove) self.view.sig_view_update.connect(self._sig_view_update) self.view.sig_view_refresh.connect(self._sig_view_refresh) self.events = eventstore.EventStore() self.events.sig_add.connect(self._sig_events_add) self.events.sig_refresh.connect(self._sig_events_refresh) self.options.changed.connect(self._sig_options_update) self.options.changed.connect(self._sig_settings_update) self.addons.add(*addons.default_addons()) self.addons.add( webaddons.WebAddon(), intercept.Intercept(), readfile.ReadFile(), static_viewer.StaticViewer(), self.view, self.events, ) if with_termlog: self.addons.add(termlog.TermLog(), termstatus.TermStatus()) self.app = app.Application( self, self.options.web_debug )
def __init__(self, options, server, with_termlog=True): super().__init__(options, server) self.view = view.View() self.view.sig_view_add.connect(self._sig_view_add) self.view.sig_view_remove.connect(self._sig_view_remove) self.view.sig_view_update.connect(self._sig_view_update) self.view.sig_view_refresh.connect(self._sig_view_refresh) self.events = eventstore.EventStore() self.events.sig_add.connect(self._sig_events_add) self.events.sig_refresh.connect(self._sig_events_refresh) self.options.changed.connect(self._sig_options_update) self.addons.add(*addons.default_addons()) self.addons.add( intercept.Intercept(), self.view, self.events, ) if with_termlog: self.addons.add(termlog.TermLog(), termstatus.TermStatus()) self.app = app.Application(self, self.options.web_debug) # This line is just for type hinting self.options = self.options # type: Options
def __init__(self, opts): super().__init__(opts) self.start_err: typing.Optional[log.LogEntry] = None self.view: view.View = view.View() self.events = eventstore.EventStore() self.events.sig_add.connect(self.sig_add_log) self.stream_path = None self.keymap = keymap.Keymap(self) defaultkeys.map(self.keymap) self.options.errored.connect(self.options_error) self.view_stack = [] self.addons.add(*addons.default_addons()) self.addons.add( intercept.Intercept(), self.view, self.events, readfile.ReadFile(), consoleaddons.ConsoleAddon(self), keymap.KeymapConfig(), ) def sigint_handler(*args, **kwargs): self.prompt_for_exit() signal.signal(signal.SIGINT, sigint_handler) self.window = None
def test_filter(): v = view.View() f = flowfilter.parse("~m get") v.request(tft(method="get")) v.request(tft(method="put")) v.request(tft(method="get")) v.request(tft(method="put")) assert(len(v)) == 4 v.set_filter(f) assert [i.request.method for i in v] == ["GET", "GET"] assert len(v._store) == 4 v.set_filter(None) assert len(v) == 4 v.toggle_marked() assert len(v) == 0 v.toggle_marked() assert len(v) == 4 v[1].marked = True v.toggle_marked() assert len(v) == 1 assert v[0].marked v.toggle_marked() assert len(v) == 4
def __init__(self, options, server, with_termlog=True): super().__init__(options, server) self.view = view.View() self.view.sig_view_add.connect(self._sig_view_add) self.view.sig_view_remove.connect(self._sig_view_remove) self.view.sig_view_update.connect(self._sig_view_update) self.view.sig_view_refresh.connect(self._sig_view_refresh) self.events = eventstore.EventStore() self.events.sig_add.connect(self._sig_events_add) self.events.sig_refresh.connect(self._sig_events_refresh) self.options.changed.connect(self._sig_options_update) self.addons.add(*addons.default_addons()) self.addons.add( intercept.Intercept(), self.view, self.events, ) if with_termlog: self.addons.add(termlog.TermLog()) self.app = app.Application(self, self.options.wdebug) # This line is just for type hinting self.options = self.options # type: Options if options.rfile: try: self.load_flows_file(options.rfile) except exceptions.FlowReadException as v: self.add_log("Could not read flow file: %s" % v, "error")
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
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
def test_simple(): v = view.View() f = tflow.tflow() f.request.timestamp_start = 1 v.request(f) assert list(v) == [f] v.request(f) assert list(v) == [f] assert len(v._store) == 1 f2 = tflow.tflow() f2.request.timestamp_start = 3 v.request(f2) assert list(v) == [f, f2] v.request(f2) assert list(v) == [f, f2] assert len(v._store) == 2 f3 = tflow.tflow() f3.request.timestamp_start = 2 v.request(f3) assert list(v) == [f, f3, f2] v.request(f3) assert list(v) == [f, f3, f2] assert len(v._store) == 3 v.clear() assert len(v) == 0 assert len(v._store) == 0
def __init__(self, options, server): super().__init__(options, server) self.view = view.View() # type: view.View self.stream_path = None # This line is just for type hinting self.options = self.options # type: Options self.options.errored.connect(self.options_error) self.logbuffer = urwid.SimpleListWalker([]) self.view_stack = [] signals.call_in.connect(self.sig_call_in) signals.pop_view_state.connect(self.sig_pop_view_state) signals.replace_view_state.connect(self.sig_replace_view_state) signals.push_view_state.connect(self.sig_push_view_state) signals.sig_add_log.connect(self.sig_add_log) self.addons.add(Logger()) self.addons.add(*addons.default_addons()) self.addons.add(intercept.Intercept(), self.view) def sigint_handler(*args, **kwargs): self.prompt_for_exit() signal.signal(signal.SIGINT, sigint_handler)
def test_focus_follow(): v = view.View() with taddons.context(options=options.Options()) as tctx: 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
def test_remove(): v = view.View() with taddons.context(): f = [tflow.tflow(), tflow.tflow()] v.add(f) assert len(v) == 2 v.remove(f) assert len(v) == 0
def test_create(): v = view.View() with taddons.context(): v.create("get", "http://foo.com") assert len(v) == 1 assert v[0].request.url == "http://foo.com/" v.create("get", "http://foo.com") assert len(v) == 2
def test_properties(): v = view.View() f = tft() v.request(f) assert v.get_length() == 1 assert not v.get_marked() v.toggle_marked() assert v.get_length() == 0 assert v.get_marked()
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
def test_signals(): v = view.View() rec_add = Record() rec_update = Record() rec_remove = Record() rec_refresh = Record() def clearrec(): rec_add.calls = [] rec_update.calls = [] rec_remove.calls = [] rec_refresh.calls = [] v.sig_view_add.connect(rec_add) v.sig_view_update.connect(rec_update) v.sig_view_remove.connect(rec_remove) v.sig_view_refresh.connect(rec_refresh) assert not any([rec_add, rec_update, rec_remove, rec_refresh]) # Simple add v.add([tft()]) assert rec_add assert not any([rec_update, rec_remove, rec_refresh]) # Filter change triggers refresh clearrec() v.set_filter(flowfilter.parse("~m put")) assert rec_refresh assert not any([rec_update, rec_add, rec_remove]) v.set_filter(flowfilter.parse("~m get")) # An update that results in a flow being added to the view clearrec() v[0].request.method = "PUT" v.update([v[0]]) assert rec_remove assert not any([rec_update, rec_refresh, rec_add]) # An update that does not affect the view just sends update v.set_filter(flowfilter.parse("~m put")) clearrec() v.update([v[0]]) assert rec_update assert not any([rec_remove, rec_refresh, rec_add]) # An update for a flow in state but not view does not do anything f = v[0] v.set_filter(flowfilter.parse("~m get")) assert not len(v) clearrec() v.update([f]) assert not any([rec_add, rec_update, rec_remove, rec_refresh])
def test_settings(): v = view.View() f = tft() tutils.raises(KeyError, v.settings.__getitem__, f) v.add(f) v.settings[f]["foo"] = "bar" assert v.settings[f]["foo"] == "bar" assert len(list(v.settings)) == 1 v.remove(f) tutils.raises(KeyError, v.settings.__getitem__, f) assert not v.settings.keys()
def test_duplicate(): v = view.View() with taddons.context(): f = [ tflow.tflow(), tflow.tflow(), ] v.add(f) assert len(v) == 2 v.duplicate(f) assert len(v) == 4 assert v.focus.index == 2
def test_cut_save_open(exception, log_message, tmpdir): f = str(tmpdir.join("path")) 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("mitmproxy.addons.cut.open") as m: m.side_effect = exception(log_message) tctx.command(c.save, "@all", "request.method", f) assert tctx.master.has_log(log_message, level="error")
def test_create(): v = view.View() with taddons.context(): v.create("get", "http://foo.com") assert len(v) == 1 assert v[0].request.url == "http://foo.com/" v.create("get", "http://foo.com") assert len(v) == 2 with pytest.raises(exceptions.CommandError, match="Invalid URL"): v.create("get", "http://foo.com\\") with pytest.raises(exceptions.CommandError, match="Invalid URL"): v.create("get", "http://")
def test_setgetval(): v = view.View() with taddons.context(): f = tflow.tflow() v.add([f]) v.setvalue([f], "key", "value") assert v.getvalue(f, "key", "default") == "value" assert v.getvalue(f, "unknow", "default") == "default" v.setvalue_toggle([f], "key") assert v.getvalue(f, "key", "default") == "true" v.setvalue_toggle([f], "key") assert v.getvalue(f, "key", "default") == "false"
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)
def test_simple_tcp(): v = view.View() f = tflow.ttcpflow() assert v.store_count() == 0 v.tcp_start(f) assert list(v) == [f] # These all just call update v.tcp_start(f) v.tcp_message(f) v.tcp_error(f) v.tcp_end(f) assert list(v) == [f]
def test_resolve(): v = view.View() with taddons.context() as tctx: f = tft(method="get") assert tctx.command(v.resolve, "@all") == [] assert tctx.command(v.resolve, "@focus") == [] assert tctx.command(v.resolve, "@shown") == [] assert tctx.command(v.resolve, "@hidden") == [] assert tctx.command(v.resolve, "@marked") == [] assert tctx.command(v.resolve, "@unmarked") == [] assert tctx.command(v.resolve, f"@{f.id}") == [] assert tctx.command(v.resolve, "~m get") == [] v.requestheaders(f) assert len(tctx.command(v.resolve, "~m get")) == 1 assert len(tctx.command(v.resolve, "@focus")) == 1 assert len(tctx.command(v.resolve, "@all")) == 1 assert len(tctx.command(v.resolve, "@shown")) == 1 assert len(tctx.command(v.resolve, "@unmarked")) == 1 assert len(tctx.command(v.resolve, f"@{f.id}")) == 1 assert tctx.command(v.resolve, "@hidden") == [] assert tctx.command(v.resolve, "@marked") == [] v.requestheaders(tft(method="put")) assert len(tctx.command(v.resolve, f"@{f.id}")) == 1 assert len(tctx.command(v.resolve, "@focus")) == 1 assert len(tctx.command(v.resolve, "@shown")) == 2 assert len(tctx.command(v.resolve, "@all")) == 2 assert tctx.command(v.resolve, "@hidden") == [] assert tctx.command(v.resolve, "@marked") == [] v.requestheaders(tft(method="get")) v.requestheaders(tft(method="put")) f = flowfilter.parse("~m get") v.set_filter(f) v[0].marked = True def m(l): return [i.request.method for i in l] assert m(tctx.command(v.resolve, "~m get")) == ["GET", "GET"] assert m(tctx.command(v.resolve, "~m put")) == ["PUT", "PUT"] assert m(tctx.command(v.resolve, "@shown")) == ["GET", "GET"] assert m(tctx.command(v.resolve, "@hidden")) == ["PUT", "PUT"] assert m(tctx.command(v.resolve, "@marked")) == ["GET"] assert m(tctx.command(v.resolve, "@unmarked")) == ["PUT", "GET", "PUT"] assert m(tctx.command(v.resolve, "@all")) == ["GET", "PUT", "GET", "PUT"] with pytest.raises(exceptions.CommandError, match="Invalid filter expression"): tctx.command(v.resolve, "~")