aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_server.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_server.py')
-rw-r--r--test/test_server.py169
1 files changed, 127 insertions, 42 deletions
diff --git a/test/test_server.py b/test/test_server.py
index 034fab41..f12fbcee 100644
--- a/test/test_server.py
+++ b/test/test_server.py
@@ -1,6 +1,6 @@
import socket, time
import mock
-from netlib import tcp
+from netlib import tcp, http_auth, http
from libpathod import pathoc
import tutils, tservers
from libmproxy import flow, proxy
@@ -13,11 +13,7 @@ from libmproxy import flow, proxy
for a 200 response.
"""
-class SanityMixin:
- def test_http(self):
- assert self.pathod("304").status_code == 304
- assert self.master.state.view
-
+class CommonMixin:
def test_large(self):
assert len(self.pathod("200:b@50k").content) == 1024*50
@@ -40,27 +36,30 @@ class SanityMixin:
self.master.replay_request(l, block=True)
assert l.error
+ def test_http(self):
+ f = self.pathod("304")
+ assert f.status_code == 304
-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]
+ l = self.master.state.view[0]
+ assert l.request.client_conn.address
+ assert "host" in l.request.headers
+ assert l.response.code == 304
def test_invalid_http(self):
t = tcp.TCPClient("127.0.0.1", self.proxy.port)
t.connect()
- t.wfile.write("invalid\n\n")
+ t.wfile.write("invalid\r\n\r\n")
t.wfile.flush()
assert "Bad Request" in t.rfile.readline()
+
+class TestHTTP(tservers.HTTPProxTest, CommonMixin):
+ def test_app_err(self):
+ p = self.pathoc()
+ ret = p.request("get:'http://errapp/'")
+ assert ret.status_code == 500
+ assert "ValueError" in ret.content
+
def test_invalid_connect(self):
t = tcp.TCPClient("127.0.0.1", self.proxy.port)
t.connect()
@@ -71,16 +70,7 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin):
def test_upstream_ssl_error(self):
p = self.pathoc()
ret = p.request("get:'https://localhost:%s/'"%self.server.port)
- assert ret[1] == 400
-
- def test_http(self):
- f = self.pathod("304")
- assert f.status_code == 304
-
- l = self.master.state.view[0]
- assert l.request.client_conn.address
- assert "host" in l.request.headers
- assert l.response.code == 304
+ assert ret.status_code == 400
def test_connection_close(self):
# Add a body, so we have a content-length header, which combined with
@@ -116,7 +106,7 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin):
# 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")
+ tutils.raises("server disconnect", self.pathod, "304")
def test_get_connection_switching(self):
def switched(l):
@@ -132,30 +122,101 @@ class TestHTTP(tservers.HTTPProxTest, SanityMixin):
def test_get_connection_err(self):
p = self.pathoc()
ret = p.request("get:'http://localhost:0'")
- assert ret[1] == 502
+ assert ret.status_code == 502
+
+ def test_blank_leading_line(self):
+ p = self.pathoc()
+ req = "get:'%s/p/201':i0,'\r\n'"
+ assert p.request(req%self.server.urlbase).status_code == 201
+
+ def test_invalid_headers(self):
+ p = self.pathoc()
+ req = p.request("get:'http://foo':h':foo'='bar'")
+ assert req.status_code == 400
-class TestHTTPS(tservers.HTTPProxTest, SanityMixin):
+class TestHTTPAuth(tservers.HTTPProxTest):
+ authenticator = http_auth.BasicProxyAuth(http_auth.PassManSingleUser("test", "test"), "realm")
+ def test_auth(self):
+ assert self.pathod("202").status_code == 407
+ p = self.pathoc()
+ ret = p.request("""
+ get
+ 'http://localhost:%s/p/202'
+ h'%s'='%s'
+ """%(
+ self.server.port,
+ http_auth.BasicProxyAuth.AUTH_HEADER,
+ http.assemble_http_basic_auth("basic", "test", "test")
+ ))
+ assert ret.status_code == 202
+
+
+class TestHTTPConnectSSLError(tservers.HTTPProxTest):
+ certfile = True
+ def test_go(self):
+ p = self.pathoc()
+ req = "connect:'localhost:%s'"%self.proxy.port
+ assert p.request(req).status_code == 200
+ assert p.request(req).status_code == 400
+
+
+class TestHTTPS(tservers.HTTPProxTest, CommonMixin):
ssl = True
clientcerts = True
def test_clientcert(self):
f = self.pathod("304")
+ assert f.status_code == 304
assert self.server.last_log()["request"]["clientcert"]["keyinfo"]
+ def test_sni(self):
+ f = self.pathod("304", sni="testserver.com")
+ assert f.status_code == 304
+ l = self.server.last_log()
+ assert self.server.last_log()["request"]["sni"] == "testserver.com"
-class TestHTTPSCertfile(tservers.HTTPProxTest, SanityMixin):
+ def test_error_post_connect(self):
+ p = self.pathoc()
+ assert p.request("get:/:i0,'invalid\r\n\r\n'").status_code == 400
+
+
+class TestHTTPSNoUpstream(tservers.HTTPProxTest, CommonMixin):
+ ssl = True
+ no_upstream_cert = True
+ def test_cert_gen_error(self):
+ f = self.pathoc_raw()
+ f.connect((u"foo..bar".encode("utf8"), 0))
+ f.request("get:/")
+ assert "dummy cert" in "".join(self.proxy.log)
+
+
+class TestHTTPSCertfile(tservers.HTTPProxTest, CommonMixin):
ssl = True
certfile = True
def test_certfile(self):
assert self.pathod("304")
-class TestReverse(tservers.ReverseProxTest, SanityMixin):
+class TestReverse(tservers.ReverseProxTest, CommonMixin):
reverse = True
-class TestTransparent(tservers.TransparentProxTest, SanityMixin):
- transparent = True
+class TestTransparent(tservers.TransparentProxTest, CommonMixin):
+ ssl = False
+
+
+class TestTransparentSSL(tservers.TransparentProxTest, CommonMixin):
+ ssl = True
+ def test_sni(self):
+ f = self.pathod("304", sni="testserver.com")
+ assert f.status_code == 304
+ l = self.server.last_log()
+ assert self.server.last_log()["request"]["sni"] == "testserver.com"
+
+ def test_sslerr(self):
+ p = pathoc.Pathoc("localhost", self.proxy.port)
+ p.connect()
+ assert p.request("get:/").status_code == 400
class TestProxy(tservers.HTTPProxTest):
@@ -216,8 +277,7 @@ class MasterFakeResponse(tservers.TestMaster):
class TestFakeResponse(tservers.HTTPProxTest):
masterclass = MasterFakeResponse
- def test_kill(self):
- p = self.pathoc()
+ def test_fake(self):
f = self.pathod("200")
assert "header_response" in f.headers.keys()
@@ -231,8 +291,7 @@ class MasterKillRequest(tservers.TestMaster):
class TestKillRequest(tservers.HTTPProxTest):
masterclass = MasterKillRequest
def test_kill(self):
- p = self.pathoc()
- tutils.raises("empty reply", self.pathod, "200")
+ tutils.raises("server disconnect", self.pathod, "200")
# Nothing should have hit the server
assert not self.server.last_log()
@@ -245,8 +304,34 @@ class MasterKillResponse(tservers.TestMaster):
class TestKillResponse(tservers.HTTPProxTest):
masterclass = MasterKillResponse
def test_kill(self):
- p = self.pathoc()
- tutils.raises("empty reply", self.pathod, "200")
+ tutils.raises("server disconnect", self.pathod, "200")
# The server should have seen a request
assert self.server.last_log()
+
+class EResolver(tservers.TResolver):
+ def original_addr(self, sock):
+ return None
+
+
+class TestTransparentResolveError(tservers.TransparentProxTest):
+ resolver = EResolver
+ def test_resolve_error(self):
+ assert self.pathod("304").status_code == 502
+
+
+
+class MasterIncomplete(tservers.TestMaster):
+ def handle_request(self, m):
+ resp = tutils.tresp()
+ resp.content = flow.CONTENT_MISSING
+ m.reply(resp)
+
+
+class TestIncompleteResponse(tservers.HTTPProxTest):
+ masterclass = MasterIncomplete
+ def test_incomplete(self):
+ assert self.pathod("200").status_code == 502
+
+
+