From 1ccb2c5dea9530682aae83d489f1738d9286fa4e Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 16 Feb 2013 16:46:16 +1300 Subject: Test WSGI app calling. - Factor out test servers into a separate file - Adjust docs to note new Flask dependency --- test/test_server.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index 0a2f142e..58dfee58 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -1,7 +1,7 @@ import socket, time from netlib import tcp from libpathod import pathoc -import tutils +import tutils, tservers """ Note that the choice of response code in these tests matters more than you @@ -39,7 +39,19 @@ class SanityMixin: assert l.error -class TestHTTP(tutils.HTTPProxTest, SanityMixin): +class TestHTTP(tservers.HTTPProxTest, SanityMixin): + def test_app(self): + p = self.pathoc() + ret = p.request("get:'http://testapp/'") + assert ret[1] == 200 + assert ret[4] == "testapp" + + def test_app_err(self): + p = self.pathoc() + ret = p.request("get:'http://errapp/'") + assert ret[1] == 500 + assert "ValueError" in ret[4] + def test_invalid_http(self): t = tcp.TCPClient("127.0.0.1", self.proxy.port) t.connect() @@ -69,7 +81,7 @@ class TestHTTP(tutils.HTTPProxTest, SanityMixin): assert l.response.code == 304 -class TestHTTPS(tutils.HTTPProxTest, SanityMixin): +class TestHTTPS(tservers.HTTPProxTest, SanityMixin): ssl = True clientcerts = True def test_clientcert(self): @@ -77,15 +89,15 @@ class TestHTTPS(tutils.HTTPProxTest, SanityMixin): assert self.last_log()["request"]["clientcert"]["keyinfo"] -class TestReverse(tutils.ReverseProxTest, SanityMixin): +class TestReverse(tservers.ReverseProxTest, SanityMixin): reverse = True -class TestTransparent(tutils.TransparentProxTest, SanityMixin): +class TestTransparent(tservers.TransparentProxTest, SanityMixin): transparent = True -class TestProxy(tutils.HTTPProxTest): +class TestProxy(tservers.HTTPProxTest): def test_http(self): f = self.pathod("304") assert f.status_code == 304 -- cgit v1.2.3 From 269780c57780d155c4d8bd95fcc2af2104effa5b Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 23 Feb 2013 16:34:59 +1300 Subject: Unit test dummy response functions. --- test/test_server.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index 58dfee58..5cba891c 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -2,6 +2,7 @@ import socket, time from netlib import tcp from libpathod import pathoc import tutils, tservers +from libmproxy import flow """ Note that the choice of response code in these tests matters more than you @@ -144,3 +145,18 @@ class TestProxy(tservers.HTTPProxTest): request = self.master.state.view[1].request assert request.timestamp_end - request.timestamp_start <= 0.1 + + +class MasterFakeResponse(tservers.TestMaster): + def handle_request(self, m): + resp = tutils.tresp() + m.reply(resp) + + +class TestFakeResponse(tservers.HTTPProxTest): + masterclass = MasterFakeResponse + def test_kill(self): + p = self.pathoc() + f = self.pathod("200") + assert "header_response" in f.headers.keys() + -- cgit v1.2.3 From 05e4d4468ec372adb73649e6980c525a185e9c07 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 23 Feb 2013 21:59:25 +1300 Subject: Test request and response kill functionality. --- test/test_server.py | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index 5cba891c..8aefa4b8 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -2,7 +2,7 @@ import socket, time from netlib import tcp from libpathod import pathoc import tutils, tservers -from libmproxy import flow +from libmproxy import flow, proxy """ Note that the choice of response code in these tests matters more than you @@ -147,6 +147,7 @@ class TestProxy(tservers.HTTPProxTest): assert request.timestamp_end - request.timestamp_start <= 0.1 + class MasterFakeResponse(tservers.TestMaster): def handle_request(self, m): resp = tutils.tresp() @@ -160,3 +161,32 @@ class TestFakeResponse(tservers.HTTPProxTest): f = self.pathod("200") assert "header_response" in f.headers.keys() + + +class MasterKillRequest(tservers.TestMaster): + def handle_request(self, m): + m.reply(proxy.KILL) + + +class TestKillRequest(tservers.HTTPProxTest): + masterclass = MasterKillRequest + def test_kill(self): + p = self.pathoc() + tutils.raises("empty reply", self.pathod, "200") + # Nothing should have hit the server + assert not self.last_log() + + +class MasterKillResponse(tservers.TestMaster): + def handle_response(self, m): + m.reply(proxy.KILL) + + +class TestKillResponse(tservers.HTTPProxTest): + masterclass = MasterKillResponse + def test_kill(self): + p = self.pathoc() + tutils.raises("empty reply", self.pathod, "200") + # The server should have seen a request + assert self.last_log() + -- cgit v1.2.3 From 51de9f9fdf6ec4cd345e0b2c8607453cc22c5045 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 10:51:14 +1300 Subject: Test client connection close conditions. --- test/test_server.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index 8aefa4b8..a2c65275 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -81,6 +81,22 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): assert "host" in l.request.headers assert l.response.code == 304 + def test_connection_close(self): + # Add a body, so we have a content-length header, which combined with + # HTTP1.1 means the connection is kept alive. + response = '%s/p/200:b@1'%self.urlbase + + # Lets sanity check that the connection does indeed stay open by + # issuing two requests over the same connection + p = self.pathoc() + assert p.request("get:'%s'"%response) + assert p.request("get:'%s'"%response) + + # Now check that the connection is closed as the client specifies + p = self.pathoc() + assert p.request("get:'%s':h'Connection'='close'"%response) + tutils.raises("disconnect", p.request, "get:'%s'"%response) + class TestHTTPS(tservers.HTTPProxTest, SanityMixin): ssl = True -- cgit v1.2.3 From 64285140f959eaa939c4cf35585cfe21cbf1a449 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 11:34:01 +1300 Subject: Test a difficult-to-trigger IOError, fix cert generation in test suite. --- test/test_server.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index a2c65275..9df88400 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -1,4 +1,5 @@ import socket, time +import mock from netlib import tcp from libpathod import pathoc import tutils, tservers @@ -97,6 +98,14 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): assert p.request("get:'%s':h'Connection'='close'"%response) tutils.raises("disconnect", p.request, "get:'%s'"%response) + def test_proxy_ioerror(self): + # Tests a difficult-to-trigger condition, where an IOError is raised + # within our read loop. + with mock.patch("libmproxy.proxy.ProxyHandler.read_request") as m: + m.side_effect = IOError("error!") + tutils.raises("empty reply", self.pathod, "304") + + class TestHTTPS(tservers.HTTPProxTest, SanityMixin): ssl = True -- cgit v1.2.3 From d0639e8925541bd6f6f386386c982d23b3828d3d Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 14:04:56 +1300 Subject: Handle server disconnects better. Server connections can be closed for legitimate reasons, like timeouts. If we've already pumped data over a server connection, we reconnect on error. If not, we treat it as a legitimate error and pass it on to the client. Fixes #85 --- test/test_server.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index 9df88400..924b63b7 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -98,6 +98,19 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): assert p.request("get:'%s':h'Connection'='close'"%response) tutils.raises("disconnect", p.request, "get:'%s'"%response) + def test_reconnect(self): + req = "get:'%s/p/200:b@1:da'"%self.urlbase + p = self.pathoc() + assert p.request(req) + # Server has disconnected. Mitmproxy should detect this, and reconnect. + assert p.request(req) + assert p.request(req) + + # However, if the server disconnects on our first try, it's an error. + req = "get:'%s/p/200:b@1:d0'"%self.urlbase + p = self.pathoc() + tutils.raises("server disconnect", p.request, req) + def test_proxy_ioerror(self): # Tests a difficult-to-trigger condition, where an IOError is raised # within our read loop. @@ -106,7 +119,6 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): tutils.raises("empty reply", self.pathod, "304") - class TestHTTPS(tservers.HTTPProxTest, SanityMixin): ssl = True clientcerts = True -- cgit v1.2.3 From 02578151410fff4b3c018303290e2f843e244a89 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 22:24:21 +1300 Subject: Significantly simplify server connection handling, and test. --- test/test_server.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index 924b63b7..f93ddbb3 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -85,7 +85,7 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): def test_connection_close(self): # Add a body, so we have a content-length header, which combined with # HTTP1.1 means the connection is kept alive. - response = '%s/p/200:b@1'%self.urlbase + response = '%s/p/200:b@1'%self.server.urlbase # Lets sanity check that the connection does indeed stay open by # issuing two requests over the same connection @@ -99,7 +99,7 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): tutils.raises("disconnect", p.request, "get:'%s'"%response) def test_reconnect(self): - req = "get:'%s/p/200:b@1:da'"%self.urlbase + req = "get:'%s/p/200:b@1:da'"%self.server.urlbase p = self.pathoc() assert p.request(req) # Server has disconnected. Mitmproxy should detect this, and reconnect. @@ -107,7 +107,7 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): assert p.request(req) # However, if the server disconnects on our first try, it's an error. - req = "get:'%s/p/200:b@1:d0'"%self.urlbase + req = "get:'%s/p/200:b@1:d0'"%self.server.urlbase p = self.pathoc() tutils.raises("server disconnect", p.request, req) @@ -118,13 +118,29 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin): m.side_effect = IOError("error!") tutils.raises("empty reply", self.pathod, "304") + def test_get_connection_switching(self): + def switched(l): + for i in l: + if "switching" in i: + return True + req = "get:'%s/p/200:b@1'" + p = self.pathoc() + assert p.request(req%self.server.urlbase) + assert p.request(req%self.server2.urlbase) + assert switched(self.proxy.log) + + def test_get_connection_err(self): + p = self.pathoc() + ret = p.request("get:'http://localhost:0'") + assert ret[1] == 502 + class TestHTTPS(tservers.HTTPProxTest, SanityMixin): ssl = True clientcerts = True def test_clientcert(self): f = self.pathod("304") - assert self.last_log()["request"]["clientcert"]["keyinfo"] + assert self.server.last_log()["request"]["clientcert"]["keyinfo"] class TestReverse(tservers.ReverseProxTest, SanityMixin): @@ -211,7 +227,7 @@ class TestKillRequest(tservers.HTTPProxTest): p = self.pathoc() tutils.raises("empty reply", self.pathod, "200") # Nothing should have hit the server - assert not self.last_log() + assert not self.server.last_log() class MasterKillResponse(tservers.TestMaster): @@ -225,5 +241,5 @@ class TestKillResponse(tservers.HTTPProxTest): p = self.pathoc() tutils.raises("empty reply", self.pathod, "200") # The server should have seen a request - assert self.last_log() + assert self.server.last_log() -- cgit v1.2.3 From b077189dd5230b6c440a200d867c70c6ce031b66 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 24 Feb 2013 22:52:59 +1300 Subject: Test cert file specification, spruce up server testing truss a bit. --- test/test_server.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test/test_server.py') diff --git a/test/test_server.py b/test/test_server.py index f93ddbb3..034fab41 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -143,6 +143,13 @@ class TestHTTPS(tservers.HTTPProxTest, SanityMixin): assert self.server.last_log()["request"]["clientcert"]["keyinfo"] +class TestHTTPSCertfile(tservers.HTTPProxTest, SanityMixin): + ssl = True + certfile = True + def test_certfile(self): + assert self.pathod("304") + + class TestReverse(tservers.ReverseProxTest, SanityMixin): reverse = True -- cgit v1.2.3