def test_logentry(): e = log.LogEntry("foo", "info") assert repr(e) == "LogEntry(foo, info)" f = log.LogEntry("foo", "warning") assert e == e assert e != f assert e != 42
def test_simple(self): t = termlog.TermLog() sio = io.StringIO() t.configure(dump.Options(tfile=sio, verbosity=2), set([])) t.log(log.LogEntry("one", "info")) assert "one" in sio.getvalue() t.log(log.LogEntry("two", "debug")) assert "two" not in sio.getvalue()
def test_output(self, outfile, expected_out, expected_err, capfd): t = termlog.TermLog(outfile=outfile) with taddons.context(options=Options(verbosity=2)) as tctx: tctx.configure(t) t.log(log.LogEntry("one", "info")) t.log(log.LogEntry("two", "debug")) t.log(log.LogEntry("three", "warn")) t.log(log.LogEntry("four", "error")) out, err = capfd.readouterr() assert out.strip().splitlines() == expected_out assert err.strip().splitlines() == expected_err
def test_output(capsys): t = termlog.TermLog() with taddons.context(t) as tctx: tctx.options.termlog_verbosity = "info" tctx.configure(t) t.add_log(log.LogEntry("one", "info")) t.add_log(log.LogEntry("two", "debug")) t.add_log(log.LogEntry("three", "warn")) t.add_log(log.LogEntry("four", "error")) out, err = capsys.readouterr() assert out.strip().splitlines() == ["one", "three"] assert err.strip().splitlines() == ["four"]
def test_max_size(): store = eventstore.EventStore(3) assert store.size == 3 store.add_log(log.LogEntry("foo", "info")) store.add_log(log.LogEntry("bar", "info")) store.add_log(log.LogEntry("baz", "info")) assert len(store.data) == 3 assert ["foo", "bar", "baz"] == [x.msg for x in store.data] # overflow store.add_log(log.LogEntry("boo", "info")) assert len(store.data) == 3 assert ["bar", "baz", "boo"] == [x.msg for x in store.data]
def test_simple(): store = eventstore.EventStore() assert not store.data sig_add = mock.Mock(spec=lambda: 42) sig_refresh = mock.Mock(spec=lambda: 42) store.sig_add.connect(sig_add) store.sig_refresh.connect(sig_refresh) assert not sig_add.called assert not sig_refresh.called # test .log() store.log(log.LogEntry("test", "info")) assert store.data assert sig_add.called assert not sig_refresh.called # test .clear() sig_add.reset_mock() store.clear() assert not store.data assert not sig_add.called assert sig_refresh.called
def log(self, message: str, level: str = "info") -> None: x = log.LogEntry(self.log_prefix + message, level) x.reply = controller.DummyReply() # type: ignore asyncio_utils.create_task( self.master.addons.handle_lifecycle("log", x), name="ProxyConnectionHandler.log" )
async def run(): # suppress error that task exception was not retrieved. asyncio.get_running_loop().set_exception_handler(lambda *_: 0) e = ErrorCheck(do_log) e.add_log(log.LogEntry("fatal", "error")) await e.running() await asyncio.sleep(0)
def test_styling(monkeypatch) -> None: f = io.StringIO() t = termlog.TermLog(out=f) t.out_has_vt_codes = True with taddons.context(t) as tctx: tctx.configure(t) t.add_log(log.LogEntry("hello world", "info")) assert f.getvalue() == "\x1b[22mhello world\x1b[0m\n"
def log(self, msg, level, subs=()): """ Send a log message to the master. """ full_msg = ["{}: {}".format(repr(self.client_conn.address), msg)] for i in subs: full_msg.append(" -> " + i) full_msg = "\n".join(full_msg) self.channel.tell("log", log.LogEntry(full_msg, level))
def test_script_print_stdout(): with taddons.context() as tctx: with mock.patch('mitmproxy.ctx.master.tell') as mock_warn: with addonmanager.safecall(): ns = script.load_script( tutils.test_data.path( "mitmproxy/data/addonscripts/print.py")) ns.load(addonmanager.Loader(tctx.master)) mock_warn.assert_called_once_with("log", log.LogEntry("stdoutprint", "warn"))
def safecall(): # resolve ctx.master here. # we want to be threadsafe, and ctx.master may already be cleared when an addon prints(). tell = ctx.master.tell # don't use master.add_log (which is not thread-safe). Instead, put on event queue. stdout_replacement = StreamLog( lambda message: tell("log", log.LogEntry(message, "warn"))) try: with contextlib.redirect_stdout(stdout_replacement): yield except (exceptions.AddonHalt, exceptions.OptionsError): raise except Exception as e: etype, value, tb = sys.exc_info() tb = cut_traceback(tb, "invoke_addon") ctx.log.error("Addon error: %s" % "".join(traceback.format_exception(etype, value, tb)))
def replay(self, f): # pragma: no cover f.live = True r = f.request bsl = human.parse_size(self.options.body_size_limit) first_line_format_backup = r.first_line_format server = None global new, cur_cycle, cur_group try: f.response = None # If we have a channel, run script hooks. request_reply = self.channel.ask("request", f) if isinstance(request_reply, http.HTTPResponse): f.response = request_reply if not f.response: # In all modes, we directly connect to the server displayed if self.options.mode.startswith("upstream:"): server_address = server_spec.parse_with_mode( self.options.mode)[1].address server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": connect_request = http.make_connect_request( (r.data.host, r.port)) server.wfile.write( http1.assemble_request(connect_request)) server.wfile.flush() resp = http1.read_response(server.rfile, connect_request, body_size_limit=bsl) if resp.status_code != 200: raise exceptions.ReplayException( "Upstream server refuses CONNECT request") server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.first_line_format = "relative" else: r.first_line_format = "absolute" else: server_address = (r.host, r.port) server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.first_line_format = "relative" server.wfile.write(http1.assemble_request(r)) server.wfile.flush() if f.server_conn: f.server_conn.close() f.server_conn = server f.response = http.HTTPResponse.wrap( http1.read_response(server.rfile, r, body_size_limit=bsl)) response_reply = self.channel.ask("response", f) #new.append(f) #record the response cur_cycle[cur_group] = f if response_reply == exceptions.Kill: raise exceptions.Kill() except (exceptions.ReplayException, exceptions.NetlibException) as e: f.error = flow.Error(str(e)) self.channel.ask("error", f) except exceptions.Kill: self.channel.tell("log", log.LogEntry("Connection killed", "info")) except Exception as e: self.channel.tell("log", log.LogEntry(repr(e), "error")) finally: r.first_line_format = first_line_format_backup f.live = False if server.connected(): server.finish() server.close()
def test_dont_pick_up_mutations(): x = {"foo": "bar"} e = log.LogEntry(x, "info") x["foo"] = "baz" # this should not affect the log entry anymore. assert repr(e) == "LogEntry({'foo': 'bar'}, info)"
def add_log(self, e, level): """ level: debug, info, warn, error """ self.addons.trigger("log", log.LogEntry(e, level))
def test_has_error(self): m = self.mkmaster(None) ent = log.LogEntry("foo", "error") ent.reply = controller.DummyReply() m.log(ent) assert m.has_errored
def test_logentry(): e = log.LogEntry("foo", "info") assert repr(e) == "LogEntry(foo, info)"
def replay(self, f): # pragma: no cover f.live = True r = f.request bsl = human.parse_size(self.options.body_size_limit) authority_backup = r.authority server = None try: f.response = None # If we have a channel, run script hooks. request_reply = self.channel.ask("request", f) if isinstance(request_reply, http.HTTPResponse): f.response = request_reply if not f.response: # In all modes, we directly connect to the server displayed if self.options.mode.startswith("upstream:"): server_address = server_spec.parse_with_mode( self.options.mode)[1].address server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": connect_request = http.make_connect_request( (r.data.host, r.port)) server.wfile.write( http1.assemble_request(connect_request)) server.wfile.flush() resp = http1.read_response(server.rfile, connect_request, body_size_limit=bsl) if resp.status_code != 200: raise exceptions.ReplayException( "Upstream server refuses CONNECT request") server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.authority = b"" else: r.authority = hostport(r.scheme, r.host, r.port) else: server_address = (r.host, r.port) server = connections.ServerConnection(server_address) server.connect() if r.scheme == "https": server.establish_tls( sni=f.server_conn.sni, **tls.client_arguments_from_options(self.options)) r.authority = "" server.wfile.write(http1.assemble_request(r)) server.wfile.flush() r.timestamp_start = r.timestamp_end = time.time() if f.server_conn: f.server_conn.close() f.server_conn = server f.response = http1.read_response(server.rfile, r, body_size_limit=bsl) response_reply = self.channel.ask("response", f) if response_reply == exceptions.Kill: raise exceptions.Kill() except (exceptions.ReplayException, exceptions.NetlibException) as e: f.error = flow.Error(str(e)) self.channel.ask("error", f) except exceptions.Kill: self.channel.tell("log", log.LogEntry(flow.Error.KILLED_MESSAGE, "info")) except Exception as e: self.channel.tell("log", log.LogEntry(repr(e), "error")) finally: r.authority = authority_backup f.live = False if server and server.connected(): server.finish() server.close()
def log(self, msg, level): msg = "{}: {}".format(human.format_address(self.client_conn.address), msg) self.channel.tell("log", log.LogEntry(msg, level))
def test_has_error(self): m = self.mkmaster() ent = log.LogEntry("foo", "error") ent.reply = controller.DummyReply() m.addons.trigger("log", ent) assert m.errorcheck.has_errored
def add_log(self, e, level): """ level: debug, info, warn, error """ with self.handlecontext(): self.addons("log", log.LogEntry(e, level))
def run(self): r = self.f.request first_line_format_backup = r.first_line_format server = None try: self.f.response = None # If we have a channel, run script hooks. if self.channel: request_reply = self.channel.ask("request", self.f) if isinstance(request_reply, http.HTTPResponse): self.f.response = request_reply if not self.f.response: # In all modes, we directly connect to the server displayed if self.config.options.mode == "upstream": server_address = self.config.upstream_server.address server = connections.ServerConnection(server_address, (self.config.options.listen_host, 0)) server.connect() if r.scheme == "https": connect_request = http.make_connect_request((r.data.host, r.port)) server.wfile.write(http1.assemble_request(connect_request)) server.wfile.flush() resp = http1.read_response( server.rfile, connect_request, body_size_limit=self.config.options.body_size_limit ) if resp.status_code != 200: raise exceptions.ReplayException("Upstream server refuses CONNECT request") server.establish_ssl( self.config.clientcerts, sni=self.f.server_conn.sni ) r.first_line_format = "relative" else: r.first_line_format = "absolute" else: server_address = (r.host, r.port) server = connections.ServerConnection( server_address, (self.config.options.listen_host, 0) ) server.connect() if r.scheme == "https": server.establish_ssl( self.config.clientcerts, sni=self.f.server_conn.sni ) r.first_line_format = "relative" server.wfile.write(http1.assemble_request(r)) server.wfile.flush() self.f.server_conn = server self.f.response = http.HTTPResponse.wrap( http1.read_response( server.rfile, r, body_size_limit=self.config.options.body_size_limit ) ) if self.channel: response_reply = self.channel.ask("response", self.f) if response_reply == exceptions.Kill: raise exceptions.Kill() except (exceptions.ReplayException, exceptions.NetlibException) as e: self.f.error = flow.Error(str(e)) if self.channel: self.channel.ask("error", self.f) except exceptions.Kill: # Kill should only be raised if there's a channel in the # first place. self.channel.tell( "log", log.LogEntry("Connection killed", "info") ) except Exception: self.channel.tell( "log", log.LogEntry(traceback.format_exc(), "error") ) finally: r.first_line_format = first_line_format_backup self.f.live = False if server.connected(): server.finish()
def log(self, message: str, level: str = "info") -> None: x = log.LogEntry(self.log_prefix + message, level) asyncio_utils.create_task(self.master.addons.handle_lifecycle( log.AddLogHook(x)), name="ProxyConnectionHandler.log")