diff options
Diffstat (limited to 'test')
23 files changed, 221 insertions, 41 deletions
diff --git a/test/bench/benchmark.py b/test/bench/benchmark.py index 84ec6005..076ad6c9 100644 --- a/test/bench/benchmark.py +++ b/test/bench/benchmark.py @@ -31,7 +31,8 @@ class Benchmark: stdout=asyncio.subprocess.PIPE ) stdout, _ = await traf.communicate() - open(ctx.options.benchmark_save_path + ".bench", mode="wb").write(stdout) + with open(ctx.options.benchmark_save_path + ".bench", mode="wb") as f: + f.write(stdout) ctx.log.error("Proxy saw %s requests, %s responses" % (self.reqs, self.resps)) ctx.log.error(stdout.decode("ascii")) backend.kill() diff --git a/test/mitmproxy/addons/test_dumper.py b/test/mitmproxy/addons/test_dumper.py index c24801e4..7a41c7b9 100644 --- a/test/mitmproxy/addons/test_dumper.py +++ b/test/mitmproxy/addons/test_dumper.py @@ -32,37 +32,50 @@ def test_configure(): def test_simple(): sio = io.StringIO() - d = dumper.Dumper(sio) + 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() @@ -75,6 +88,8 @@ def test_simple(): 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"{")) @@ -83,6 +98,8 @@ def test_simple(): 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() @@ -92,6 +109,8 @@ def test_simple(): d.response(flow) assert "content missing" in sio.getvalue() sio.truncate(0) + assert not sio_err.getvalue() + sio_err.truncate(0) def test_echo_body(): @@ -100,7 +119,8 @@ def test_echo_body(): f.response.content = b"foo bar voing\n" * 100 sio = io.StringIO() - d = dumper.Dumper(sio) + sio_err = io.StringIO() + d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3) d._echo_message(f.response) @@ -110,7 +130,8 @@ def test_echo_body(): def test_echo_request_line(): sio = io.StringIO() - d = dumper.Dumper(sio) + sio_err = io.StringIO() + d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.tflow(client_conn=None, server_conn=True, resp=True) @@ -146,7 +167,8 @@ class TestContentView: with mock.patch("mitmproxy.contentviews.auto.ViewAuto.__call__") as va: va.side_effect = exceptions.ContentViewException("") sio = io.StringIO() - d = dumper.Dumper(sio) + sio_err = io.StringIO() + d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=4) d.response(tflow.tflow()) @@ -155,7 +177,8 @@ class TestContentView: def test_tcp(): sio = io.StringIO() - d = dumper.Dumper(sio) + sio_err = io.StringIO() + d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.ttcpflow() @@ -165,12 +188,13 @@ def test_tcp(): f = tflow.ttcpflow(client_conn=True, err=True) d.tcp_error(f) - assert "Error in TCP" in sio.getvalue() + assert "Error in TCP" in sio_err.getvalue() def test_websocket(): sio = io.StringIO() - d = dumper.Dumper(sio) + sio_err = io.StringIO() + d = dumper.Dumper(sio, sio_err) with taddons.context(d) as ctx: ctx.configure(d, flow_detail=3, showhost=True) f = tflow.twebsocketflow() @@ -183,4 +207,4 @@ def test_websocket(): f = tflow.twebsocketflow(client_conn=True, err=True) d.websocket_error(f) - assert "Error in WebSocket" in sio.getvalue() + assert "Error in WebSocket" in sio_err.getvalue() diff --git a/test/mitmproxy/addons/test_readfile.py b/test/mitmproxy/addons/test_readfile.py index 3d28d8b7..94e18cdb 100644 --- a/test/mitmproxy/addons/test_readfile.py +++ b/test/mitmproxy/addons/test_readfile.py @@ -30,8 +30,8 @@ def data(): @pytest.fixture -def corrupt_data(): - f = data() +def corrupt_data(data): + f = io.BytesIO(data.getvalue()) f.seek(0, io.SEEK_END) f.write(b"qibble") f.seek(0) diff --git a/test/mitmproxy/addons/test_session.py b/test/mitmproxy/addons/test_session.py index 20feb69d..97351426 100644 --- a/test/mitmproxy/addons/test_session.py +++ b/test/mitmproxy/addons/test_session.py @@ -68,7 +68,8 @@ class TestSession: os.remove(path) con = sqlite3.connect(path) script_path = pkg_data.path("io/sql/session_create.sql") - qry = open(script_path, 'r').read() + with open(script_path) as f: + qry = f.read() with con: con.executescript(qry) blob = b'blob_of_data' diff --git a/test/mitmproxy/addons/test_view.py b/test/mitmproxy/addons/test_view.py index 976c14b7..f5088a68 100644 --- a/test/mitmproxy/addons/test_view.py +++ b/test/mitmproxy/addons/test_view.py @@ -471,7 +471,7 @@ def test_focus(): v = view.View() v.add([tft()]) f = view.Focus(v) - assert f.index is 0 + assert f.index == 0 assert f.flow is v[0] # Start empty diff --git a/test/mitmproxy/contentviews/test_base.py b/test/mitmproxy/contentviews/test_base.py index c94d8be2..cd879bfd 100644 --- a/test/mitmproxy/contentviews/test_base.py +++ b/test/mitmproxy/contentviews/test_base.py @@ -15,3 +15,18 @@ def test_format_dict(): f_d = base.format_dict(d) with pytest.raises(StopIteration): next(f_d) + + +def test_format_pairs(): + d = [("a", "c"), ("b", "d")] + f_d = base.format_pairs(d) + assert next(f_d) + + d = [("abc", "")] + f_d = base.format_pairs(d) + assert next(f_d) + + d = [] + f_d = base.format_pairs(d) + with pytest.raises(StopIteration): + next(f_d) diff --git a/test/mitmproxy/contentviews/test_query.py b/test/mitmproxy/contentviews/test_query.py index 741b23f1..1ae1b3ac 100644 --- a/test/mitmproxy/contentviews/test_query.py +++ b/test/mitmproxy/contentviews/test_query.py @@ -6,8 +6,8 @@ from . import full_eval def test_view_query(): d = "" v = full_eval(query.ViewQuery()) - f = v(d, query=multidict.MultiDict([("foo", "bar")])) + f = v(d, query=multidict.MultiDict([("foo", "bar"), ("foo", "baz")])) assert f[0] == "Query" - assert f[1] == [[("header", "foo: "), ("text", "bar")]] + assert f[1] == [[("header", "foo: "), ("text", "bar")], [("header", "foo: "), ("text", "baz")]] assert v(d) == ("Query", []) diff --git a/test/mitmproxy/coretypes/test_basethread.py b/test/mitmproxy/coretypes/test_basethread.py index 4a383fea..6b0ae154 100644 --- a/test/mitmproxy/coretypes/test_basethread.py +++ b/test/mitmproxy/coretypes/test_basethread.py @@ -4,4 +4,4 @@ from mitmproxy.coretypes import basethread def test_basethread(): t = basethread.BaseThread('foobar') - assert re.match('foobar - age: \d+s', t._threadinfo()) + assert re.match(r'foobar - age: \d+s', t._threadinfo()) diff --git a/test/mitmproxy/net/http/test_cookies.py b/test/mitmproxy/net/http/test_cookies.py index 74233cca..06cfe1d3 100644 --- a/test/mitmproxy/net/http/test_cookies.py +++ b/test/mitmproxy/net/http/test_cookies.py @@ -27,7 +27,7 @@ cookie_pairs = [ [["one", "uno"], ["two", "due"]] ], [ - 'one="uno"; two="\due"', + 'one="uno"; two="\\due"', [["one", "uno"], ["two", "due"]] ], [ @@ -70,7 +70,7 @@ def test_read_key(): def test_read_quoted_string(): tokens = [ [('"foo" x', 0), ("foo", 5)], - [('"f\oo" x', 0), ("foo", 6)], + [('"f\\oo" x', 0), ("foo", 6)], [(r'"f\\o" x', 0), (r"f\o", 6)], [(r'"f\\" x', 0), (r"f" + '\\', 5)], [('"fo\\\"" x', 0), ("fo\"", 6)], diff --git a/test/mitmproxy/net/http/test_encoding.py b/test/mitmproxy/net/http/test_encoding.py index 8dac12cb..7f768f39 100644 --- a/test/mitmproxy/net/http/test_encoding.py +++ b/test/mitmproxy/net/http/test_encoding.py @@ -19,6 +19,7 @@ def test_identity(encoder): 'gzip', 'br', 'deflate', + 'zstd', ]) def test_encoders(encoder): """ diff --git a/test/mitmproxy/net/http/test_headers.py b/test/mitmproxy/net/http/test_headers.py index e8eb31d3..8fc8b027 100644 --- a/test/mitmproxy/net/http/test_headers.py +++ b/test/mitmproxy/net/http/test_headers.py @@ -75,7 +75,7 @@ class TestHeaders: def test_replace_multi(self): headers = self._2host() - headers.replace(r"Host: example\.com", r"Host: example.de") + headers.replace(r"Host: example.com", r"Host: example.de") assert headers.get_all("Host") == ["example.de", "example.org"] def test_replace_remove_spacer(self): diff --git a/test/mitmproxy/net/http/test_message.py b/test/mitmproxy/net/http/test_message.py index 512f3199..7ad7890c 100644 --- a/test/mitmproxy/net/http/test_message.py +++ b/test/mitmproxy/net/http/test_message.py @@ -229,6 +229,16 @@ class TestMessageText: r.headers["content-type"] = "application/json" assert r.text == u'"ü"' + def test_guess_meta_charset(self): + r = tutils.tresp(content=b'<meta http-equiv="content-type" ' + b'content="text/html;charset=gb2312">\xe6\x98\x8e\xe4\xbc\xaf') + # "鏄庝集" is decoded form of \xe6\x98\x8e\xe4\xbc\xaf in gb18030 + assert u"鏄庝集" in r.text + + def test_guess_latin_1(self): + r = tutils.tresp(content=b"\xF0\xE2") + assert r.text == u"ðâ" + def test_none(self): r = tutils.tresp(content=None) assert r.text is None diff --git a/test/mitmproxy/net/http/test_response.py b/test/mitmproxy/net/http/test_response.py index f3470384..27c16be6 100644 --- a/test/mitmproxy/net/http/test_response.py +++ b/test/mitmproxy/net/http/test_response.py @@ -148,7 +148,7 @@ class TestResponseUtils: def test_refresh(self): r = tresp() n = time.time() - r.headers["date"] = email.utils.formatdate(n) + r.headers["date"] = email.utils.formatdate(n, usegmt=True) pre = r.headers["date"] r.refresh(946681202) assert pre == r.headers["date"] diff --git a/test/mitmproxy/net/http/test_url.py b/test/mitmproxy/net/http/test_url.py index ecf8e896..48277859 100644 --- a/test/mitmproxy/net/http/test_url.py +++ b/test/mitmproxy/net/http/test_url.py @@ -49,6 +49,17 @@ def test_parse(): url.parse('http://lo[calhost') +def test_ascii_check(): + + test_url = "https://xyz.tax-edu.net?flag=selectCourse&lc_id=42825&lc_name=茅莽莽猫氓猫氓".encode() + scheme, host, port, full_path = url.parse(test_url) + assert scheme == b'https' + assert host == b'xyz.tax-edu.net' + assert port == 443 + assert full_path == b'/?flag%3DselectCourse%26lc_id%3D42825%26lc_name%3D%E8%8C%85%E8%8E%BD%E8%8E' \ + b'%BD%E7%8C%AB%E6%B0%93%E7%8C%AB%E6%B0%93' + + @pytest.mark.skipif(sys.version_info < (3, 6), reason='requires Python 3.6 or higher') def test_parse_port_range(): # Port out of range @@ -61,6 +72,7 @@ def test_unparse(): assert url.unparse("http", "foo.com", 80, "/bar") == "http://foo.com/bar" assert url.unparse("https", "foo.com", 80, "") == "https://foo.com:80" assert url.unparse("https", "foo.com", 443, "") == "https://foo.com" + assert url.unparse("https", "foo.com", 443, "*") == "https://foo.com" # We ignore the byte 126: '~' because of an incompatibility in Python 3.6 and 3.7 @@ -131,3 +143,7 @@ def test_unquote(): assert url.unquote("foo") == "foo" assert url.unquote("foo%20bar") == "foo bar" assert url.unquote(surrogates_quoted) == surrogates + + +def test_hostport(): + assert url.hostport(b"https", b"foo.com", 8080) == b"foo.com:8080" diff --git a/test/mitmproxy/net/test_tcp.py b/test/mitmproxy/net/test_tcp.py index b6bb7cc1..22a306dc 100644 --- a/test/mitmproxy/net/test_tcp.py +++ b/test/mitmproxy/net/test_tcp.py @@ -102,7 +102,7 @@ class TestServerBind(tservers.ServerTestBase): # We may get an ipv4-mapped ipv6 address here, e.g. ::ffff:127.0.0.1. # Those still appear as "127.0.0.1" in the table, so we need to strip the prefix. peername = self.connection.getpeername() - address = re.sub("^::ffff:(?=\d+.\d+.\d+.\d+$)", "", peername[0]) + address = re.sub(r"^::ffff:(?=\d+.\d+.\d+.\d+$)", "", peername[0]) port = peername[1] self.wfile.write(str((address, port)).encode()) diff --git a/test/mitmproxy/proxy/test_config.py b/test/mitmproxy/proxy/test_config.py index 1da031c6..1319d1a9 100644 --- a/test/mitmproxy/proxy/test_config.py +++ b/test/mitmproxy/proxy/test_config.py @@ -17,3 +17,12 @@ class TestProxyConfig: opts.certs = [tdata.path("mitmproxy/data/dumpfile-011")] with pytest.raises(exceptions.OptionsError, match="Invalid certificate format"): ProxyConfig(opts) + + def test_cannot_set_both_allow_and_filter_options(self): + opts = options.Options() + opts.ignore_hosts = ["foo"] + opts.allow_hosts = ["bar"] + with pytest.raises(exceptions.OptionsError, match="--ignore-hosts and --allow-hosts are " + "mutually exclusive; please choose " + "one."): + ProxyConfig(opts) diff --git a/test/mitmproxy/proxy/test_server.py b/test/mitmproxy/proxy/test_server.py index 01ab068d..b5852d60 100644 --- a/test/mitmproxy/proxy/test_server.py +++ b/test/mitmproxy/proxy/test_server.py @@ -78,6 +78,16 @@ class TcpMixin: self.options.ignore_hosts = self._ignore_backup del self._ignore_backup + def _allow_on(self): + assert not hasattr(self, "_allow_backup") + self._allow_backup = self.options.allow_hosts + self.options.allow_hosts = ["(127.0.0.1|None):\\d+"] + self.options.allow_hosts + + def _allow_off(self): + assert hasattr(self, "_allow_backup") + self.options.allow_hosts = self._allow_backup + del self._allow_backup + def test_ignore(self): n = self.pathod("304") self._ignore_on() @@ -111,6 +121,40 @@ class TcpMixin: self._ignore_off() + def test_allow(self): + n = self.pathod("304") + self._allow_on() + i = self.pathod("305") + i2 = self.pathod("306") + self._allow_off() + + assert n.status_code == 304 + assert i.status_code == 305 + assert i2.status_code == 306 + + assert any(f.response.status_code == 304 for f in self.master.state.flows) + assert any(f.response.status_code == 305 for f in self.master.state.flows) + assert any(f.response.status_code == 306 for f in self.master.state.flows) + + # Test that we get the original SSL cert + if self.ssl: + i_cert = certs.Cert(i.sslinfo.certchain[0]) + i2_cert = certs.Cert(i2.sslinfo.certchain[0]) + n_cert = certs.Cert(n.sslinfo.certchain[0]) + + assert i_cert == i2_cert + assert i_cert != n_cert + + # Test Non-HTTP traffic + spec = "200:i0,@100:d0" # this results in just 100 random bytes + # mitmproxy responds with bad gateway + assert self.pathod(spec).status_code == 502 + self._allow_on() + + self.pathod(spec) # pathoc parses answer as HTTP + + self._allow_off() + def _tcpproxy_on(self): assert not hasattr(self, "_tcpproxy_backup") self._tcpproxy_backup = self.options.tcp_hosts @@ -852,10 +896,12 @@ class TestUpstreamProxySSL( def _host_pattern_on(self, attr): """ - Updates config.check_tcp or check_ignore, depending on attr. + Updates config.check_tcp or check_filter, depending on attr. """ assert not hasattr(self, "_ignore_%s_backup" % attr) backup = [] + handle = attr + attr = "filter" if attr in ["allow", "ignore"] else attr for proxy in self.chain: old_matcher = getattr( proxy.tmaster.server.config, @@ -865,12 +911,13 @@ class TestUpstreamProxySSL( setattr( proxy.tmaster.server.config, "check_%s" % attr, - HostMatcher([".+:%s" % self.server.port] + old_matcher.patterns) + HostMatcher(handle, [".+:%s" % self.server.port] + old_matcher.patterns) ) setattr(self, "_ignore_%s_backup" % attr, backup) def _host_pattern_off(self, attr): + attr = "filter" if attr in ["allow", "ignore"] else attr backup = getattr(self, "_ignore_%s_backup" % attr) for proxy in reversed(self.chain): setattr( diff --git a/test/mitmproxy/script/test_concurrent.py b/test/mitmproxy/script/test_concurrent.py index 3ec58760..70d41511 100644 --- a/test/mitmproxy/script/test_concurrent.py +++ b/test/mitmproxy/script/test_concurrent.py @@ -43,17 +43,17 @@ class TestConcurrent(tservers.MasterTest): assert await tctx.master.await_log("decorator not supported") def test_concurrent_class(self, tdata): - with taddons.context() as tctx: - sc = tctx.script( - tdata.path( - "mitmproxy/data/addonscripts/concurrent_decorator_class.py" - ) + with taddons.context() as tctx: + sc = tctx.script( + tdata.path( + "mitmproxy/data/addonscripts/concurrent_decorator_class.py" ) - f1, f2 = tflow.tflow(), tflow.tflow() - tctx.cycle(sc, f1) - tctx.cycle(sc, f2) - start = time.time() - while time.time() - start < 5: - if f1.reply.state == f2.reply.state == "committed": - return - raise ValueError("Script never acked") + ) + f1, f2 = tflow.tflow(), tflow.tflow() + tctx.cycle(sc, f1) + tctx.cycle(sc, f2) + start = time.time() + while time.time() - start < 5: + if f1.reply.state == f2.reply.state == "committed": + return + raise ValueError("Script never acked") diff --git a/test/mitmproxy/test_certs.py b/test/mitmproxy/test_certs.py index 12d3dc96..b8ad1d36 100644 --- a/test/mitmproxy/test_certs.py +++ b/test/mitmproxy/test_certs.py @@ -1,5 +1,6 @@ import os from mitmproxy import certs +from ..conftest import skip_windows # class TestDNTree: # def test_simple(self): @@ -111,6 +112,14 @@ class TestCertStore: certs.CertStore.load_dhparam(filename) assert os.path.exists(filename) + @skip_windows + def test_umask_secret(self, tmpdir): + filename = str(tmpdir.join("secret")) + with certs.CertStore.umask_secret(), open(filename, "wb"): + pass + # TODO: How do we actually attempt to read that file as another user? + assert os.stat(filename).st_mode & 0o77 == 0 + class TestDummyCert: @@ -120,18 +129,22 @@ class TestDummyCert: ca.default_privatekey, ca.default_ca, b"foo.com", - [b"one.com", b"two.com", b"*.three.com", b"127.0.0.1"] + [b"one.com", b"two.com", b"*.three.com", b"127.0.0.1"], + b"Foo Ltd." ) assert r.cn == b"foo.com" assert r.altnames == [b'one.com', b'two.com', b'*.three.com'] + assert r.organization == b"Foo Ltd." r = certs.dummy_cert( ca.default_privatekey, ca.default_ca, None, - [] + [], + None ) assert r.cn is None + assert r.organization is None assert r.altnames == [] @@ -143,6 +156,7 @@ class TestCert: c1 = certs.Cert.from_pem(d) assert c1.cn == b"google.com" assert len(c1.altnames) == 436 + assert c1.organization == b"Google Inc" with open(tdata.path("mitmproxy/net/data/text_cert_2"), "rb") as f: d = f.read() diff --git a/test/mitmproxy/test_flowfilter.py b/test/mitmproxy/test_flowfilter.py index 4eb37d81..d53cec7d 100644 --- a/test/mitmproxy/test_flowfilter.py +++ b/test/mitmproxy/test_flowfilter.py @@ -28,6 +28,9 @@ class TestParsing: self._dump(p) assert len(p.lst) == 2 + def test_non_ascii(self): + assert flowfilter.parse("~s шгн") + def test_naked_url(self): a = flowfilter.parse("foobar ~h rex") assert a.lst[0].expr == "foobar" @@ -173,10 +176,30 @@ class TestMatchingHTTPFlow: assert not self.q("~bq message", q) assert not self.q("~bq message", s) + s.response.text = 'яч' # Cyrillic + assert self.q("~bs яч", s) + s.response.text = '测试' # Chinese + assert self.q('~bs 测试', s) + s.response.text = 'ॐ' # Hindi + assert self.q('~bs ॐ', s) + s.response.text = 'لله' # Arabic + assert self.q('~bs لله', s) + s.response.text = 'θεός' # Greek + assert self.q('~bs θεός', s) + s.response.text = 'לוהים' # Hebrew + assert self.q('~bs לוהים', s) + s.response.text = '神' # Japanese + assert self.q('~bs 神', s) + s.response.text = '하나님' # Korean + assert self.q('~bs 하나님', s) + s.response.text = 'Äÿ' # Latin + assert self.q('~bs Äÿ', s) + assert not self.q("~bs nomatch", s) assert not self.q("~bs content", q) assert not self.q("~bs content", s) assert not self.q("~bs message", q) + s.response.text = 'message' assert self.q("~bs message", s) def test_body(self): diff --git a/test/mitmproxy/test_http.py b/test/mitmproxy/test_http.py index 49e61e25..8a299d8e 100644 --- a/test/mitmproxy/test_http.py +++ b/test/mitmproxy/test_http.py @@ -49,7 +49,7 @@ class TestHTTPRequest: r.path = "path/foo" r.headers["Foo"] = "fOo" r.content = b"afoob" - assert r.replace("foo(?i)", "boo") == 4 + assert r.replace("(?i)foo", "boo") == 4 assert r.path == "path/boo" assert b"foo" not in r.content assert r.headers["boo"] == "boo" @@ -82,7 +82,7 @@ class TestHTTPResponse: r = http.HTTPResponse.wrap(mitmproxy.test.tutils.tresp()) r.headers["Foo"] = "fOo" r.content = b"afoob" - assert r.replace("foo(?i)", "boo") == 3 + assert r.replace("(?i)foo", "boo") == 3 assert b"foo" not in r.content assert r.headers["boo"] == "boo" diff --git a/test/mitmproxy/test_proxy.py b/test/mitmproxy/test_proxy.py index 00086c4b..c8cf6c33 100644 --- a/test/mitmproxy/test_proxy.py +++ b/test/mitmproxy/test_proxy.py @@ -1,4 +1,5 @@ import argparse +import platform from unittest import mock import pytest @@ -52,8 +53,11 @@ class TestProcessProxyOptions: class TestProxyServer: @skip_windows + @pytest.mark.skipif(platform.mac_ver()[0].split('.')[:2] == ['10', '14'], + reason='Skipping due to macOS Mojave') def test_err(self): - # binding to 0.0.0.0:1 works without special permissions on Windows + # binding to 0.0.0.0:1 works without special permissions on Windows and + # macOS Mojave conf = ProxyConfig(options.Options(listen_port=1)) with pytest.raises(Exception, match="Error starting proxy server"): ProxyServer(conf) diff --git a/test/mitmproxy/tools/console/test_keymap.py b/test/mitmproxy/tools/console/test_keymap.py index 3e6f7c2e..0d6f9e88 100644 --- a/test/mitmproxy/tools/console/test_keymap.py +++ b/test/mitmproxy/tools/console/test_keymap.py @@ -117,6 +117,21 @@ def test_load_path(tmpdir): kmc.load_path(km, dst) assert(km.get("chooser", "key1")) + km.add("key123", "str", ["flowlist", "flowview"]) + with open(dst, 'w') as f: + f.write( + """ + - key: key123 + ctx: [options] + cmd: foo + """ + ) + kmc.load_path(km, dst) + for b in km.bindings: + if b.key == "key123": + assert b.contexts == ["options"] + break + def test_parse(): kmc = keymap.KeymapConfig() |