aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2016-07-25 15:16:16 -0700
committerMaximilian Hils <git@maximilianhils.com>2016-07-25 15:16:16 -0700
commit79ebcb046e8669f80357a6c3046ec76c6adf49be (patch)
tree441981a16f1be1e620584e4a47f41767ce5585b2 /test
parent3254595584e1d711e7ae292ad34753a52f7a0fc1 (diff)
parent56796aeda25dda66621ce78af227ff46049ef811 (diff)
downloadmitmproxy-79ebcb046e8669f80357a6c3046ec76c6adf49be.tar.gz
mitmproxy-79ebcb046e8669f80357a6c3046ec76c6adf49be.tar.bz2
mitmproxy-79ebcb046e8669f80357a6c3046ec76c6adf49be.zip
Merge remote-tracking branch 'origin/master' into flow_editing_v2
Diffstat (limited to 'test')
-rw-r--r--test/mitmproxy/builtins/test_anticache.py5
-rw-r--r--test/mitmproxy/builtins/test_anticomp.py5
-rw-r--r--test/mitmproxy/builtins/test_dumper.py29
-rw-r--r--test/mitmproxy/builtins/test_filestreamer.py13
-rw-r--r--test/mitmproxy/builtins/test_replace.py26
-rw-r--r--test/mitmproxy/builtins/test_script.py49
-rw-r--r--test/mitmproxy/builtins/test_setheaders.py13
-rw-r--r--test/mitmproxy/builtins/test_stickyauth.py5
-rw-r--r--test/mitmproxy/builtins/test_stickycookie.py11
-rw-r--r--test/mitmproxy/data/addonscripts/addon.py22
-rw-r--r--test/mitmproxy/data/addonscripts/recorder.py36
-rw-r--r--test/mitmproxy/data/dumpfile-011bin5465 -> 5046 bytes
-rw-r--r--test/mitmproxy/script/test_concurrent.py2
-rw-r--r--test/mitmproxy/test_addons.py5
-rw-r--r--test/mitmproxy/test_contentview.py4
-rw-r--r--test/mitmproxy/test_examples.py5
-rw-r--r--test/mitmproxy/test_flow.py2
-rw-r--r--test/mitmproxy/test_optmanager.py8
-rw-r--r--test/mitmproxy/test_protocol_http2.py75
-rw-r--r--test/mitmproxy/test_server.py4
-rw-r--r--test/mitmproxy/tservers.py2
-rw-r--r--test/netlib/http/test_message.py37
-rw-r--r--test/netlib/http/test_url.py44
-rw-r--r--test/netlib/test_encoding.py30
-rw-r--r--test/netlib/test_multidict.py14
25 files changed, 270 insertions, 176 deletions
diff --git a/test/mitmproxy/builtins/test_anticache.py b/test/mitmproxy/builtins/test_anticache.py
index 5a00af03..ac321e26 100644
--- a/test/mitmproxy/builtins/test_anticache.py
+++ b/test/mitmproxy/builtins/test_anticache.py
@@ -8,9 +8,10 @@ from mitmproxy import options
class TestAntiCache(mastertest.MasterTest):
def test_simple(self):
s = state.State()
- m = master.FlowMaster(options.Options(anticache = True), None, s)
+ o = options.Options(anticache = True)
+ m = master.FlowMaster(o, None, s)
sa = anticache.AntiCache()
- m.addons.add(sa)
+ m.addons.add(o, sa)
f = tutils.tflow(resp=True)
self.invoke(m, "request", f)
diff --git a/test/mitmproxy/builtins/test_anticomp.py b/test/mitmproxy/builtins/test_anticomp.py
index 6bfd54bb..a5f5a270 100644
--- a/test/mitmproxy/builtins/test_anticomp.py
+++ b/test/mitmproxy/builtins/test_anticomp.py
@@ -8,9 +8,10 @@ from mitmproxy import options
class TestAntiComp(mastertest.MasterTest):
def test_simple(self):
s = state.State()
- m = master.FlowMaster(options.Options(anticomp = True), None, s)
+ o = options.Options(anticomp = True)
+ m = master.FlowMaster(o, None, s)
sa = anticomp.AntiComp()
- m.addons.add(sa)
+ m.addons.add(o, sa)
f = tutils.tflow(resp=True)
self.invoke(m, "request", f)
diff --git a/test/mitmproxy/builtins/test_dumper.py b/test/mitmproxy/builtins/test_dumper.py
index 57e3d036..6287fe86 100644
--- a/test/mitmproxy/builtins/test_dumper.py
+++ b/test/mitmproxy/builtins/test_dumper.py
@@ -15,26 +15,27 @@ class TestDumper(mastertest.MasterTest):
d = dumper.Dumper()
sio = StringIO()
- d.configure(dump.Options(tfile = sio, flow_detail = 0))
+ updated = set(["tfile", "flow_detail"])
+ d.configure(dump.Options(tfile = sio, flow_detail = 0), updated)
d.response(tutils.tflow())
assert not sio.getvalue()
- d.configure(dump.Options(tfile = sio, flow_detail = 4))
+ d.configure(dump.Options(tfile = sio, flow_detail = 4), updated)
d.response(tutils.tflow())
assert sio.getvalue()
sio = StringIO()
- d.configure(dump.Options(tfile = sio, flow_detail = 4))
+ d.configure(dump.Options(tfile = sio, flow_detail = 4), updated)
d.response(tutils.tflow(resp=True))
assert "<<" in sio.getvalue()
sio = StringIO()
- d.configure(dump.Options(tfile = sio, flow_detail = 4))
+ d.configure(dump.Options(tfile = sio, flow_detail = 4), updated)
d.response(tutils.tflow(err=True))
assert "<<" in sio.getvalue()
sio = StringIO()
- d.configure(dump.Options(tfile = sio, flow_detail = 4))
+ d.configure(dump.Options(tfile = sio, flow_detail = 4), updated)
flow = tutils.tflow()
flow.request = netlib.tutils.treq()
flow.request.stickycookie = True
@@ -47,7 +48,7 @@ class TestDumper(mastertest.MasterTest):
assert sio.getvalue()
sio = StringIO()
- d.configure(dump.Options(tfile = sio, flow_detail = 4))
+ d.configure(dump.Options(tfile = sio, flow_detail = 4), updated)
flow = tutils.tflow(resp=netlib.tutils.tresp(content=b"{"))
flow.response.headers["content-type"] = "application/json"
flow.response.status_code = 400
@@ -55,7 +56,7 @@ class TestDumper(mastertest.MasterTest):
assert sio.getvalue()
sio = StringIO()
- d.configure(dump.Options(tfile = sio))
+ d.configure(dump.Options(tfile = sio), updated)
flow = tutils.tflow()
flow.request.content = None
flow.response = models.HTTPResponse.wrap(netlib.tutils.tresp())
@@ -72,15 +73,13 @@ class TestContentView(mastertest.MasterTest):
s = state.State()
sio = StringIO()
- m = mastertest.RecordingMaster(
- dump.Options(
- flow_detail=4,
- verbosity=3,
- tfile=sio,
- ),
- None, s
+ o = dump.Options(
+ flow_detail=4,
+ verbosity=3,
+ tfile=sio,
)
+ m = mastertest.RecordingMaster(o, None, s)
d = dumper.Dumper()
- m.addons.add(d)
+ m.addons.add(o, d)
self.invoke(m, "response", tutils.tflow())
assert "Content viewer failed" in m.event_log[0][1]
diff --git a/test/mitmproxy/builtins/test_filestreamer.py b/test/mitmproxy/builtins/test_filestreamer.py
index c1d5947f..0e69b340 100644
--- a/test/mitmproxy/builtins/test_filestreamer.py
+++ b/test/mitmproxy/builtins/test_filestreamer.py
@@ -20,16 +20,13 @@ class TestStream(mastertest.MasterTest):
return list(r.stream())
s = state.State()
- m = master.FlowMaster(
- options.Options(
- outfile = (p, "wb")
- ),
- None,
- s
+ o = options.Options(
+ outfile = (p, "wb")
)
+ m = master.FlowMaster(o, None, s)
sa = filestreamer.FileStreamer()
- m.addons.add(sa)
+ m.addons.add(o, sa)
f = tutils.tflow(resp=True)
self.invoke(m, "request", f)
self.invoke(m, "response", f)
@@ -39,7 +36,7 @@ class TestStream(mastertest.MasterTest):
m.options.outfile = (p, "ab")
- m.addons.add(sa)
+ m.addons.add(o, sa)
f = tutils.tflow()
self.invoke(m, "request", f)
m.addons.remove(sa)
diff --git a/test/mitmproxy/builtins/test_replace.py b/test/mitmproxy/builtins/test_replace.py
index a0b4b722..5e70ce56 100644
--- a/test/mitmproxy/builtins/test_replace.py
+++ b/test/mitmproxy/builtins/test_replace.py
@@ -8,38 +8,38 @@ from mitmproxy import options
class TestReplace(mastertest.MasterTest):
def test_configure(self):
r = replace.Replace()
+ updated = set(["replacements"])
r.configure(options.Options(
replacements=[("one", "two", "three")]
- ))
+ ), updated)
tutils.raises(
"invalid filter pattern",
r.configure,
options.Options(
replacements=[("~b", "two", "three")]
- )
+ ),
+ updated
)
tutils.raises(
"invalid regular expression",
r.configure,
options.Options(
replacements=[("foo", "+", "three")]
- )
+ ),
+ updated
)
def test_simple(self):
s = state.State()
- m = master.FlowMaster(
- options.Options(
- replacements = [
- ("~q", "foo", "bar"),
- ("~s", "foo", "bar"),
- ]
- ),
- None,
- s
+ o = options.Options(
+ replacements = [
+ ("~q", "foo", "bar"),
+ ("~s", "foo", "bar"),
+ ]
)
+ m = master.FlowMaster(o, None, s)
sa = replace.Replace()
- m.addons.add(sa)
+ m.addons.add(o, sa)
f = tutils.tflow()
f.request.content = b"foo"
diff --git a/test/mitmproxy/builtins/test_script.py b/test/mitmproxy/builtins/test_script.py
index f37c7f94..2870fd17 100644
--- a/test/mitmproxy/builtins/test_script.py
+++ b/test/mitmproxy/builtins/test_script.py
@@ -48,39 +48,41 @@ def test_load_script():
"data/addonscripts/recorder.py"
), []
)
- assert ns["configure"]
+ assert ns.start
class TestScript(mastertest.MasterTest):
def test_simple(self):
s = state.State()
- m = master.FlowMaster(options.Options(), None, s)
+ o = options.Options()
+ m = master.FlowMaster(o, None, s)
sc = script.Script(
tutils.test_data.path(
"data/addonscripts/recorder.py"
)
)
- m.addons.add(sc)
- assert sc.ns["call_log"] == [
+ m.addons.add(o, sc)
+ assert sc.ns.call_log == [
("solo", "start", (), {}),
- ("solo", "configure", (options.Options(),), {})
+ ("solo", "configure", (o, o.keys()), {})
]
- sc.ns["call_log"] = []
+ sc.ns.call_log = []
f = tutils.tflow(resp=True)
self.invoke(m, "request", f)
- recf = sc.ns["call_log"][0]
+ recf = sc.ns.call_log[0]
assert recf[1] == "request"
def test_reload(self):
s = state.State()
- m = mastertest.RecordingMaster(options.Options(), None, s)
+ o = options.Options()
+ m = mastertest.RecordingMaster(o, None, s)
with tutils.tmpdir():
with open("foo.py", "w"):
pass
sc = script.Script("foo.py")
- m.addons.add(sc)
+ m.addons.add(o, sc)
for _ in range(100):
with open("foo.py", "a") as f:
@@ -93,19 +95,22 @@ class TestScript(mastertest.MasterTest):
def test_exception(self):
s = state.State()
- m = mastertest.RecordingMaster(options.Options(), None, s)
+ o = options.Options()
+ m = mastertest.RecordingMaster(o, None, s)
sc = script.Script(
tutils.test_data.path("data/addonscripts/error.py")
)
- m.addons.add(sc)
+ m.addons.add(o, sc)
f = tutils.tflow(resp=True)
self.invoke(m, "request", f)
assert m.event_log[0][0] == "error"
def test_duplicate_flow(self):
s = state.State()
- fm = master.FlowMaster(None, None, s)
+ o = options.Options()
+ fm = master.FlowMaster(o, None, s)
fm.addons.add(
+ o,
script.Script(
tutils.test_data.path("data/addonscripts/duplicate_flow.py")
)
@@ -116,6 +121,20 @@ class TestScript(mastertest.MasterTest):
assert not fm.state.view[0].request.is_replay
assert fm.state.view[1].request.is_replay
+ def test_addon(self):
+ s = state.State()
+ o = options.Options()
+ m = master.FlowMaster(o, None, s)
+ sc = script.Script(
+ tutils.test_data.path(
+ "data/addonscripts/addon.py"
+ )
+ )
+ m.addons.add(o, sc)
+ assert sc.ns.event_log == [
+ 'scriptstart', 'addonstart', 'addonconfigure'
+ ]
+
class TestScriptLoader(mastertest.MasterTest):
def test_simple(self):
@@ -123,7 +142,7 @@ class TestScriptLoader(mastertest.MasterTest):
o = options.Options(scripts=[])
m = master.FlowMaster(o, None, s)
sc = script.ScriptLoader()
- m.addons.add(sc)
+ m.addons.add(o, sc)
assert len(m.addons) == 1
o.update(
scripts = [
@@ -139,7 +158,7 @@ class TestScriptLoader(mastertest.MasterTest):
o = options.Options(scripts=["one", "one"])
m = master.FlowMaster(o, None, s)
sc = script.ScriptLoader()
- tutils.raises(exceptions.OptionsError, m.addons.add, sc)
+ tutils.raises(exceptions.OptionsError, m.addons.add, o, sc)
def test_order(self):
rec = tutils.test_data.path("data/addonscripts/recorder.py")
@@ -154,7 +173,7 @@ class TestScriptLoader(mastertest.MasterTest):
)
m = mastertest.RecordingMaster(o, None, s)
sc = script.ScriptLoader()
- m.addons.add(sc)
+ m.addons.add(o, sc)
debug = [(i[0], i[1]) for i in m.event_log if i[0] == "debug"]
assert debug == [
diff --git a/test/mitmproxy/builtins/test_setheaders.py b/test/mitmproxy/builtins/test_setheaders.py
index 4465719d..41c18360 100644
--- a/test/mitmproxy/builtins/test_setheaders.py
+++ b/test/mitmproxy/builtins/test_setheaders.py
@@ -8,19 +8,20 @@ from mitmproxy import options
class TestSetHeaders(mastertest.MasterTest):
def mkmaster(self, **opts):
s = state.State()
- m = mastertest.RecordingMaster(options.Options(**opts), None, s)
+ o = options.Options(**opts)
+ m = mastertest.RecordingMaster(o, None, s)
sh = setheaders.SetHeaders()
- m.addons.add(sh)
+ m.addons.add(o, sh)
return m, sh
def test_configure(self):
sh = setheaders.SetHeaders()
+ o = options.Options(
+ setheaders = [("~b", "one", "two")]
+ )
tutils.raises(
"invalid setheader filter pattern",
- sh.configure,
- options.Options(
- setheaders = [("~b", "one", "two")]
- )
+ sh.configure, o, o.keys()
)
def test_setheaders(self):
diff --git a/test/mitmproxy/builtins/test_stickyauth.py b/test/mitmproxy/builtins/test_stickyauth.py
index 9233f435..5757fb2d 100644
--- a/test/mitmproxy/builtins/test_stickyauth.py
+++ b/test/mitmproxy/builtins/test_stickyauth.py
@@ -8,9 +8,10 @@ from mitmproxy import options
class TestStickyAuth(mastertest.MasterTest):
def test_simple(self):
s = state.State()
- m = master.FlowMaster(options.Options(stickyauth = ".*"), None, s)
+ o = options.Options(stickyauth = ".*")
+ m = master.FlowMaster(o, None, s)
sa = stickyauth.StickyAuth()
- m.addons.add(sa)
+ m.addons.add(o, sa)
f = tutils.tflow(resp=True)
f.request.headers["authorization"] = "foo"
diff --git a/test/mitmproxy/builtins/test_stickycookie.py b/test/mitmproxy/builtins/test_stickycookie.py
index 81b540db..e9d92c83 100644
--- a/test/mitmproxy/builtins/test_stickycookie.py
+++ b/test/mitmproxy/builtins/test_stickycookie.py
@@ -14,22 +14,23 @@ def test_domain_match():
class TestStickyCookie(mastertest.MasterTest):
def mk(self):
s = state.State()
- m = master.FlowMaster(options.Options(stickycookie = ".*"), None, s)
+ o = options.Options(stickycookie = ".*")
+ m = master.FlowMaster(o, None, s)
sc = stickycookie.StickyCookie()
- m.addons.add(sc)
+ m.addons.add(o, sc)
return s, m, sc
def test_config(self):
sc = stickycookie.StickyCookie()
+ o = options.Options(stickycookie = "~b")
tutils.raises(
"invalid filter",
- sc.configure,
- options.Options(stickycookie = "~b")
+ sc.configure, o, o.keys()
)
def test_simple(self):
s, m, sc = self.mk()
- m.addons.add(sc)
+ m.addons.add(m.options, sc)
f = tutils.tflow(resp=True)
f.response.headers["set-cookie"] = "foo=bar"
diff --git a/test/mitmproxy/data/addonscripts/addon.py b/test/mitmproxy/data/addonscripts/addon.py
new file mode 100644
index 00000000..84173cb6
--- /dev/null
+++ b/test/mitmproxy/data/addonscripts/addon.py
@@ -0,0 +1,22 @@
+event_log = []
+
+
+class Addon:
+ @property
+ def event_log(self):
+ return event_log
+
+ def start(self):
+ event_log.append("addonstart")
+
+ def configure(self, options, updated):
+ event_log.append("addonconfigure")
+
+
+def configure(options, updated):
+ event_log.append("addonconfigure")
+
+
+def start():
+ event_log.append("scriptstart")
+ return Addon()
diff --git a/test/mitmproxy/data/addonscripts/recorder.py b/test/mitmproxy/data/addonscripts/recorder.py
index b6ac8d89..890e6f4e 100644
--- a/test/mitmproxy/data/addonscripts/recorder.py
+++ b/test/mitmproxy/data/addonscripts/recorder.py
@@ -2,24 +2,24 @@ from mitmproxy import controller
from mitmproxy import ctx
import sys
-call_log = []
-if len(sys.argv) > 1:
- name = sys.argv[1]
-else:
- name = "solo"
+class CallLogger:
+ call_log = []
-# Keep a log of all possible event calls
-evts = list(controller.Events) + ["configure"]
-for i in evts:
- def mkprox():
- evt = i
+ def __init__(self, name = "solo"):
+ self.name = name
- def prox(*args, **kwargs):
- lg = (name, evt, args, kwargs)
- if evt != "log":
- ctx.log.info(str(lg))
- call_log.append(lg)
- ctx.log.debug("%s %s" % (name, evt))
- return prox
- globals()[i] = mkprox()
+ def __getattr__(self, attr):
+ if attr in controller.Events:
+ def prox(*args, **kwargs):
+ lg = (self.name, attr, args, kwargs)
+ if attr != "log":
+ ctx.log.info(str(lg))
+ self.call_log.append(lg)
+ ctx.log.debug("%s %s" % (self.name, attr))
+ return prox
+ raise AttributeError
+
+
+def start():
+ return CallLogger(*sys.argv[1:])
diff --git a/test/mitmproxy/data/dumpfile-011 b/test/mitmproxy/data/dumpfile-011
index 2534ad89..936ac0cc 100644
--- a/test/mitmproxy/data/dumpfile-011
+++ b/test/mitmproxy/data/dumpfile-011
Binary files differ
diff --git a/test/mitmproxy/script/test_concurrent.py b/test/mitmproxy/script/test_concurrent.py
index 080746e8..a5f76994 100644
--- a/test/mitmproxy/script/test_concurrent.py
+++ b/test/mitmproxy/script/test_concurrent.py
@@ -23,7 +23,7 @@ class TestConcurrent(mastertest.MasterTest):
"data/addonscripts/concurrent_decorator.py"
)
)
- m.addons.add(sc)
+ m.addons.add(m.options, sc)
f1, f2 = tutils.tflow(), tutils.tflow()
self.invoke(m, "request", f1)
self.invoke(m, "request", f2)
diff --git a/test/mitmproxy/test_addons.py b/test/mitmproxy/test_addons.py
index 1861d4ac..a5085ea0 100644
--- a/test/mitmproxy/test_addons.py
+++ b/test/mitmproxy/test_addons.py
@@ -13,8 +13,9 @@ class TAddon:
def test_simple():
- m = controller.Master(options.Options())
+ o = options.Options()
+ m = controller.Master(o)
a = addons.Addons(m)
- a.add(TAddon("one"))
+ a.add(o, TAddon("one"))
assert a.has_addon("one")
assert not a.has_addon("two")
diff --git a/test/mitmproxy/test_contentview.py b/test/mitmproxy/test_contentview.py
index 2db9ab40..aad53b37 100644
--- a/test/mitmproxy/test_contentview.py
+++ b/test/mitmproxy/test_contentview.py
@@ -59,10 +59,10 @@ class TestContentView:
assert f[0] == "Query"
def test_view_urlencoded(self):
- d = url.encode([("one", "two"), ("three", "four")])
+ d = url.encode([("one", "two"), ("three", "four")]).encode()
v = cv.ViewURLEncoded()
assert v(d)
- d = url.encode([("adsfa", "")])
+ d = url.encode([("adsfa", "")]).encode()
v = cv.ViewURLEncoded()
assert v(d)
diff --git a/test/mitmproxy/test_examples.py b/test/mitmproxy/test_examples.py
index 0ec85f52..34fcc261 100644
--- a/test/mitmproxy/test_examples.py
+++ b/test/mitmproxy/test_examples.py
@@ -27,10 +27,11 @@ class RaiseMaster(master.FlowMaster):
def tscript(cmd, args=""):
+ o = options.Options()
cmd = example_dir.path(cmd) + " " + args
- m = RaiseMaster(options.Options(), None, state.State())
+ m = RaiseMaster(o, None, state.State())
sc = script.Script(cmd)
- m.addons.add(sc)
+ m.addons.add(o, sc)
return m, sc
diff --git a/test/mitmproxy/test_flow.py b/test/mitmproxy/test_flow.py
index 36b212a7..74992130 100644
--- a/test/mitmproxy/test_flow.py
+++ b/test/mitmproxy/test_flow.py
@@ -615,6 +615,7 @@ class TestSerialize:
def test_roundtrip(self):
sio = io.BytesIO()
f = tutils.tflow()
+ f.marked = True
f.request.content = bytes(bytearray(range(256)))
w = flow.FlowWriter(sio)
w.add(f)
@@ -627,6 +628,7 @@ class TestSerialize:
f2 = l[0]
assert f2.get_state() == f.get_state()
assert f2.request == f.request
+ assert f2.marked
def test_load_flows(self):
r = self._treader()
diff --git a/test/mitmproxy/test_optmanager.py b/test/mitmproxy/test_optmanager.py
index 67f76ecd..8414e6b5 100644
--- a/test/mitmproxy/test_optmanager.py
+++ b/test/mitmproxy/test_optmanager.py
@@ -15,6 +15,8 @@ class TO(optmanager.OptManager):
def test_options():
o = TO(two="three")
+ assert o.keys() == set(["one", "two"])
+
assert o.one is None
assert o.two == "three"
o.one = "one"
@@ -29,7 +31,7 @@ def test_options():
rec = []
- def sub(opts):
+ def sub(opts, updated):
rec.append(copy.copy(opts))
o.changed.connect(sub)
@@ -68,7 +70,7 @@ def test_rollback():
rec = []
- def sub(opts):
+ def sub(opts, updated):
rec.append(copy.copy(opts))
recerr = []
@@ -76,7 +78,7 @@ def test_rollback():
def errsub(opts, **kwargs):
recerr.append(kwargs)
- def err(opts):
+ def err(opts, updated):
if opts.one == "ten":
raise exceptions.OptionsError()
diff --git a/test/mitmproxy/test_protocol_http2.py b/test/mitmproxy/test_protocol_http2.py
index afbffb67..aa096a72 100644
--- a/test/mitmproxy/test_protocol_http2.py
+++ b/test/mitmproxy/test_protocol_http2.py
@@ -30,7 +30,7 @@ logging.getLogger("PIL.PngImagePlugin").setLevel(logging.WARNING)
requires_alpn = pytest.mark.skipif(
not netlib.tcp.HAS_ALPN,
- reason="requires OpenSSL with ALPN support")
+ reason='requires OpenSSL with ALPN support')
class _Http2ServerBase(netlib_tservers.ServerTestBase):
@@ -80,7 +80,7 @@ class _Http2ServerBase(netlib_tservers.ServerTestBase):
print(traceback.format_exc())
break
- def handle_server_event(self, h2_conn, rfile, wfile):
+ def handle_server_event(self, event, h2_conn, rfile, wfile):
raise NotImplementedError()
@@ -88,7 +88,6 @@ class _Http2TestBase(object):
@classmethod
def setup_class(cls):
- cls.masteroptions = options.Options()
opts = cls.get_options()
cls.config = ProxyConfig(opts)
@@ -145,12 +144,14 @@ class _Http2TestBase(object):
wfile,
h2_conn,
stream_id=1,
- headers=[],
+ headers=None,
body=b'',
end_stream=None,
priority_exclusive=None,
priority_depends_on=None,
priority_weight=None):
+ if headers is None:
+ headers = []
if end_stream is None:
end_stream = (len(body) == 0)
@@ -172,12 +173,12 @@ class _Http2TestBase(object):
class _Http2Test(_Http2TestBase, _Http2ServerBase):
@classmethod
- def setup_class(self):
+ def setup_class(cls):
_Http2TestBase.setup_class()
_Http2ServerBase.setup_class()
@classmethod
- def teardown_class(self):
+ def teardown_class(cls):
_Http2TestBase.teardown_class()
_Http2ServerBase.teardown_class()
@@ -187,7 +188,7 @@ class TestSimple(_Http2Test):
request_body_buffer = b''
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.RequestReceived):
@@ -214,7 +215,7 @@ class TestSimple(_Http2Test):
wfile.write(h2_conn.data_to_send())
wfile.flush()
elif isinstance(event, h2.events.DataReceived):
- self.request_body_buffer += event.data
+ cls.request_body_buffer += event.data
return True
def test_simple(self):
@@ -225,7 +226,7 @@ class TestSimple(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -269,7 +270,7 @@ class TestSimple(_Http2Test):
class TestRequestWithPriority(_Http2Test):
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.RequestReceived):
@@ -301,14 +302,14 @@ class TestRequestWithPriority(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
],
- priority_exclusive = True,
- priority_depends_on = 42424242,
- priority_weight = 42,
+ priority_exclusive=True,
+ priority_depends_on=42424242,
+ priority_weight=42,
)
done = False
@@ -343,7 +344,7 @@ class TestRequestWithPriority(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -381,11 +382,11 @@ class TestPriority(_Http2Test):
priority_data = None
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.PriorityUpdated):
- self.priority_data = (event.exclusive, event.depends_on, event.weight)
+ cls.priority_data = (event.exclusive, event.depends_on, event.weight)
elif isinstance(event, h2.events.RequestReceived):
import warnings
with warnings.catch_warnings():
@@ -415,7 +416,7 @@ class TestPriority(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -451,11 +452,11 @@ class TestPriorityWithExistingStream(_Http2Test):
priority_data = []
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.PriorityUpdated):
- self.priority_data.append((event.exclusive, event.depends_on, event.weight))
+ cls.priority_data.append((event.exclusive, event.depends_on, event.weight))
elif isinstance(event, h2.events.RequestReceived):
assert not event.priority_updated
@@ -486,7 +487,7 @@ class TestPriorityWithExistingStream(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -527,7 +528,7 @@ class TestPriorityWithExistingStream(_Http2Test):
class TestStreamResetFromServer(_Http2Test):
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.RequestReceived):
@@ -543,7 +544,7 @@ class TestStreamResetFromServer(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -578,7 +579,7 @@ class TestStreamResetFromServer(_Http2Test):
class TestBodySizeLimit(_Http2Test):
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
return True
@@ -592,7 +593,7 @@ class TestBodySizeLimit(_Http2Test):
client.wfile,
h2_conn,
headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -627,7 +628,7 @@ class TestBodySizeLimit(_Http2Test):
class TestPushPromise(_Http2Test):
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.RequestReceived):
@@ -637,14 +638,14 @@ class TestPushPromise(_Http2Test):
h2_conn.send_headers(1, [(':status', '200')])
h2_conn.push_stream(1, 2, [
- (':authority', "127.0.0.1:%s" % self.port),
+ (':authority', "127.0.0.1:{}".format(cls.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/pushed_stream_foo'),
('foo', 'bar')
])
h2_conn.push_stream(1, 4, [
- (':authority', "127.0.0.1:%s" % self.port),
+ (':authority', "127.0.0.1:{}".format(cls.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/pushed_stream_bar'),
@@ -675,7 +676,7 @@ class TestPushPromise(_Http2Test):
client, h2_conn = self._setup_connection()
self._send_request(client.wfile, h2_conn, stream_id=1, headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -728,7 +729,7 @@ class TestPushPromise(_Http2Test):
client, h2_conn = self._setup_connection()
self._send_request(client.wfile, h2_conn, stream_id=1, headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -780,7 +781,7 @@ class TestPushPromise(_Http2Test):
class TestConnectionLost(_Http2Test):
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.RequestReceived):
h2_conn.send_headers(1, [(':status', '200')])
wfile.write(h2_conn.data_to_send())
@@ -791,7 +792,7 @@ class TestConnectionLost(_Http2Test):
client, h2_conn = self._setup_connection()
self._send_request(client.wfile, h2_conn, stream_id=1, headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -822,12 +823,12 @@ class TestConnectionLost(_Http2Test):
class TestMaxConcurrentStreams(_Http2Test):
@classmethod
- def setup_class(self):
+ def setup_class(cls):
_Http2TestBase.setup_class()
_Http2ServerBase.setup_class(h2_server_settings={h2.settings.MAX_CONCURRENT_STREAMS: 2})
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.ConnectionTerminated):
return False
elif isinstance(event, h2.events.RequestReceived):
@@ -848,7 +849,7 @@ class TestMaxConcurrentStreams(_Http2Test):
# this will exceed MAX_CONCURRENT_STREAMS on the server connection
# and cause mitmproxy to throttle stream creation to the server
self._send_request(client.wfile, h2_conn, stream_id=id, headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
@@ -883,7 +884,7 @@ class TestMaxConcurrentStreams(_Http2Test):
class TestConnectionTerminated(_Http2Test):
@classmethod
- def handle_server_event(self, event, h2_conn, rfile, wfile):
+ def handle_server_event(cls, event, h2_conn, rfile, wfile):
if isinstance(event, h2.events.RequestReceived):
h2_conn.close_connection(error_code=5, last_stream_id=42, additional_data=b'foobar')
wfile.write(h2_conn.data_to_send())
@@ -894,7 +895,7 @@ class TestConnectionTerminated(_Http2Test):
client, h2_conn = self._setup_connection()
self._send_request(client.wfile, h2_conn, headers=[
- (':authority', "127.0.0.1:%s" % self.server.server.address.port),
+ (':authority', "127.0.0.1:{}".format(self.server.server.address.port)),
(':method', 'GET'),
(':scheme', 'https'),
(':path', '/'),
diff --git a/test/mitmproxy/test_server.py b/test/mitmproxy/test_server.py
index 233af597..6230fc1f 100644
--- a/test/mitmproxy/test_server.py
+++ b/test/mitmproxy/test_server.py
@@ -291,7 +291,7 @@ class TestHTTP(tservers.HTTPProxyTest, CommonMixin, AppMixin):
s = script.Script(
tutils.test_data.path("data/addonscripts/stream_modify.py")
)
- self.master.addons.add(s)
+ self.master.addons.add(self.master.options, s)
d = self.pathod('200:b"foo"')
assert d.content == b"bar"
self.master.addons.remove(s)
@@ -523,7 +523,7 @@ class TestTransparent(tservers.TransparentProxyTest, CommonMixin, TcpMixin):
s = script.Script(
tutils.test_data.path("data/addonscripts/tcp_stream_modify.py")
)
- self.master.addons.add(s)
+ self.master.addons.add(self.master.options, s)
self._tcpproxy_on()
d = self.pathod('200:b"foo"')
self._tcpproxy_off()
diff --git a/test/mitmproxy/tservers.py b/test/mitmproxy/tservers.py
index f5119166..d364162c 100644
--- a/test/mitmproxy/tservers.py
+++ b/test/mitmproxy/tservers.py
@@ -34,7 +34,7 @@ class TestMaster(flow.FlowMaster):
s = ProxyServer(config)
state = flow.State()
flow.FlowMaster.__init__(self, opts, s, state)
- self.addons.add(*builtins.default_addons())
+ self.addons.add(opts, *builtins.default_addons())
self.apps.add(testapp, "testapp", 80)
self.apps.add(errapp, "errapp", 80)
self.clear_log()
diff --git a/test/netlib/http/test_message.py b/test/netlib/http/test_message.py
index deebd6f2..12e4706c 100644
--- a/test/netlib/http/test_message.py
+++ b/test/netlib/http/test_message.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, division
-import mock
import six
from netlib.tutils import tresp
@@ -71,10 +70,6 @@ class TestMessage(object):
assert resp != 0
- def test_hash(self):
- resp = tresp()
- assert hash(resp)
-
def test_serializable(self):
resp = tresp()
resp2 = http.Response.from_state(resp.get_state())
@@ -117,14 +112,6 @@ class TestMessageContentEncoding(object):
assert r.content == b"message"
assert r.raw_content != b"message"
- r.raw_content = b"foo"
- with mock.patch("netlib.encoding.decode") as e:
- assert r.content
- assert e.call_count == 1
- e.reset_mock()
- assert r.content
- assert e.call_count == 0
-
def test_modify(self):
r = tresp()
assert "content-encoding" not in r.headers
@@ -135,13 +122,6 @@ class TestMessageContentEncoding(object):
r.decode()
assert r.raw_content == b"foo"
- r.encode("identity")
- with mock.patch("netlib.encoding.encode") as e:
- r.content = b"foo"
- assert e.call_count == 0
- r.content = b"bar"
- assert e.call_count == 1
-
with tutils.raises(TypeError):
r.content = u"foo"
@@ -216,15 +196,6 @@ class TestMessageText(object):
r.headers["content-type"] = "text/html; charset=utf8"
assert r.text == u"ü"
- r.encode("identity")
- r.raw_content = b"foo"
- with mock.patch("netlib.encoding.decode") as e:
- assert r.text
- assert e.call_count == 2
- e.reset_mock()
- assert r.text
- assert e.call_count == 0
-
def test_guess_json(self):
r = tresp(content=b'"\xc3\xbc"')
r.headers["content-type"] = "application/json"
@@ -249,14 +220,6 @@ class TestMessageText(object):
assert r.raw_content == b"\xc3\xbc"
assert r.headers["content-length"] == "2"
- r.encode("identity")
- with mock.patch("netlib.encoding.encode") as e:
- e.return_value = b""
- r.text = u"ü"
- assert e.call_count == 0
- r.text = u"ä"
- assert e.call_count == 2
-
def test_unknown_ce(self):
r = tresp()
r.headers["content-type"] = "text/html; charset=wtf"
diff --git a/test/netlib/http/test_url.py b/test/netlib/http/test_url.py
index 26b37230..768e5130 100644
--- a/test/netlib/http/test_url.py
+++ b/test/netlib/http/test_url.py
@@ -1,3 +1,4 @@
+import six
from netlib import tutils
from netlib.http import url
@@ -57,10 +58,49 @@ def test_unparse():
assert url.unparse("https", "foo.com", 443, "") == "https://foo.com"
-def test_urlencode():
+if six.PY2:
+ surrogates = bytes(bytearray(range(256)))
+else:
+ surrogates = bytes(range(256)).decode("utf8", "surrogateescape")
+
+surrogates_quoted = (
+ '%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F'
+ '%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F'
+ '%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-./'
+ '0123456789%3A%3B%3C%3D%3E%3F'
+ '%40ABCDEFGHIJKLMNO'
+ 'PQRSTUVWXYZ%5B%5C%5D%5E_'
+ '%60abcdefghijklmno'
+ 'pqrstuvwxyz%7B%7C%7D%7E%7F'
+ '%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F'
+ '%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F'
+ '%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF'
+ '%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF'
+ '%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF'
+ '%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF'
+ '%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF'
+ '%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF'
+)
+
+
+def test_encode():
assert url.encode([('foo', 'bar')])
+ assert url.encode([('foo', surrogates)])
-def test_urldecode():
+def test_decode():
s = "one=two&three=four"
assert len(url.decode(s)) == 2
+ assert url.decode(surrogates)
+
+
+def test_quote():
+ assert url.quote("foo") == "foo"
+ assert url.quote("foo bar") == "foo%20bar"
+ assert url.quote(surrogates) == surrogates_quoted
+
+
+def test_unquote():
+ assert url.unquote("foo") == "foo"
+ assert url.unquote("foo%20bar") == "foo bar"
+ assert url.unquote(surrogates_quoted) == surrogates
diff --git a/test/netlib/test_encoding.py b/test/netlib/test_encoding.py
index de10fc48..a5e81379 100644
--- a/test/netlib/test_encoding.py
+++ b/test/netlib/test_encoding.py
@@ -1,3 +1,4 @@
+import mock
from netlib import encoding, tutils
@@ -37,3 +38,32 @@ def test_deflate():
)
with tutils.raises(ValueError):
encoding.decode(b"bogus", "deflate")
+
+
+def test_cache():
+ decode_gzip = mock.MagicMock()
+ decode_gzip.return_value = b"decoded"
+ encode_gzip = mock.MagicMock()
+ encode_gzip.return_value = b"encoded"
+
+ with mock.patch.dict(encoding.custom_decode, gzip=decode_gzip):
+ with mock.patch.dict(encoding.custom_encode, gzip=encode_gzip):
+ assert encoding.decode(b"encoded", "gzip") == b"decoded"
+ assert decode_gzip.call_count == 1
+
+ # should be cached
+ assert encoding.decode(b"encoded", "gzip") == b"decoded"
+ assert decode_gzip.call_count == 1
+
+ # the other way around as well
+ assert encoding.encode(b"decoded", "gzip") == b"encoded"
+ assert encode_gzip.call_count == 0
+
+ # different encoding
+ decode_gzip.return_value = b"bar"
+ assert encoding.encode(b"decoded", "deflate") != b"decoded"
+ assert encode_gzip.call_count == 0
+
+ # This is not in the cache anymore
+ assert encoding.encode(b"decoded", "gzip") == b"encoded"
+ assert encode_gzip.call_count == 1
diff --git a/test/netlib/test_multidict.py b/test/netlib/test_multidict.py
index 038441e7..58ae0f98 100644
--- a/test/netlib/test_multidict.py
+++ b/test/netlib/test_multidict.py
@@ -45,7 +45,7 @@ class TestMultiDict(object):
assert md["foo"] == "bar"
with tutils.raises(KeyError):
- md["bar"]
+ assert md["bar"]
md_multi = TMultiDict(
[("foo", "a"), ("foo", "b")]
@@ -101,6 +101,15 @@ class TestMultiDict(object):
assert TMultiDict() != self._multi()
assert TMultiDict() != 42
+ def test_hash(self):
+ """
+ If a class defines mutable objects and implements an __eq__() method,
+ it should not implement __hash__(), since the implementation of hashable
+ collections requires that a key's hash value is immutable.
+ """
+ with tutils.raises(TypeError):
+ assert hash(TMultiDict())
+
def test_get_all(self):
md = self._multi()
assert md.get_all("foo") == ["bar"]
@@ -197,6 +206,9 @@ class TestImmutableMultiDict(object):
with tutils.raises(TypeError):
md.add("foo", "bar")
+ def test_hash(self):
+ assert hash(TImmutableMultiDict())
+
def test_with_delitem(self):
md = TImmutableMultiDict([("foo", "bar")])
assert md.with_delitem("foo").fields == ()