From ece15b3c8af790e425ebcaa6807d6e133d810ff6 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 8 Sep 2014 14:43:05 +0200 Subject: reverse proxy: adjust dst when reading flows, fix #346 --- test/test_flow.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/test_flow.py b/test/test_flow.py index a297bf5f..399c8827 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -5,8 +5,9 @@ import mock from libmproxy import filt, protocol, controller, utils, tnetstring, flow from libmproxy.protocol.primitives import Error, Flow from libmproxy.protocol.http import decoded, CONTENT_MISSING -from libmproxy.proxy.connection import ClientConnection, ServerConnection -from netlib import tcp +from libmproxy.proxy import ProxyConfig +from libmproxy.proxy.server import DummyServer +from libmproxy.proxy.connection import ClientConnection import tutils @@ -491,6 +492,14 @@ class TestSerialize: fm.load_flows(r) assert len(s._flow_list) == 6 + def test_load_flows_reverse(self): + r = self._treader() + s = flow.State() + conf = ProxyConfig(mode="reverse", upstream_server=[True,True,"use-this-domain",80]) + fm = flow.FlowMaster(DummyServer(conf), s) + fm.load_flows(r) + assert s._flow_list[0].request.host == "use-this-domain" + def test_filter(self): sio = StringIO() fl = filt.parse("~c 200") -- cgit v1.2.3 From d7341e77986fb944ebdac629424f677eb923a79f Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 17 Oct 2014 17:08:41 +0200 Subject: add test case for #375 --- test/tools/passive_close.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 test/tools/passive_close.py (limited to 'test') diff --git a/test/tools/passive_close.py b/test/tools/passive_close.py new file mode 100644 index 00000000..d0b36e7f --- /dev/null +++ b/test/tools/passive_close.py @@ -0,0 +1,21 @@ +import SocketServer +from threading import Thread +from time import sleep + +class service(SocketServer.BaseRequestHandler): + def handle(self): + data = 'dummy' + print "Client connected with ", self.client_address + while True: + self.request.send("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: 7\r\n\r\ncontent") + data = self.request.recv(1024) + if not len(data): + print "Connection closed by remote: ", self.client_address + sleep(3600) + + +class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): + pass + +server = ThreadedTCPServer(('',1520), service) +server.serve_forever() -- cgit v1.2.3 From e1148584380058f264b7aa7e9493115e4e8f2bbe Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 18 Oct 2014 18:29:35 +0200 Subject: add generic tcp proxying, fix #374 --- test/test_flow.py | 12 ++++---- test/test_server.py | 89 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 86 insertions(+), 15 deletions(-) (limited to 'test') diff --git a/test/test_flow.py b/test/test_flow.py index b74119dd..f0844536 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -5,8 +5,8 @@ import mock from libmproxy import filt, protocol, controller, utils, tnetstring, flow from libmproxy.protocol.primitives import Error, Flow from libmproxy.protocol.http import decoded, CONTENT_MISSING -from libmproxy.proxy.connection import ClientConnection, ServerConnection -from netlib import tcp +from libmproxy.proxy.connection import ClientConnection +from libmproxy.proxy.config import HostMatcher import tutils @@ -584,11 +584,11 @@ class TestFlowMaster: def test_getset_ignore(self): p = mock.Mock() - p.config.ignore = [] + p.config.check_ignore = HostMatcher() fm = flow.FlowMaster(p, flow.State()) - assert not fm.get_ignore() - fm.set_ignore(["^apple\.com:", ":443$"]) - assert fm.get_ignore() + assert not fm.get_ignore_filter() + fm.set_ignore_filter(["^apple\.com:", ":443$"]) + assert fm.get_ignore_filter() def test_replay(self): s = flow.State() diff --git a/test/test_server.py b/test/test_server.py index 0ce5d056..6035b3a4 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -1,5 +1,5 @@ import socket, time -from libmproxy.proxy.config import parse_host_pattern +from libmproxy.proxy.config import HostMatcher from netlib import tcp, http_auth, http from libpathod import pathoc, pathod from netlib.certutils import SSLCert @@ -79,11 +79,14 @@ class CommonMixin: class TcpMixin: def _ignore_on(self): - ignore = parse_host_pattern([".+:%s" % self.server.port])[0] - self.config.ignore.append(ignore) + assert not hasattr(self, "_ignore_backup") + self._ignore_backup = self.config.check_ignore + self.config.check_ignore = HostMatcher([".+:%s" % self.server.port] + self.config.check_ignore.patterns) def _ignore_off(self): - self.config.ignore.pop() + assert hasattr(self, "_ignore_backup") + self.config.check_ignore = self._ignore_backup + del self._ignore_backup def test_ignore(self): spec = '304:h"Alternate-Protocol"="mitmproxy-will-remove-this"' @@ -114,6 +117,40 @@ class TcpMixin: tutils.raises("invalid server response", self.pathod, spec) # pathoc tries to parse answer as HTTP self._ignore_off() + def _tcpproxy_on(self): + assert not hasattr(self, "_tcpproxy_backup") + self._tcpproxy_backup = self.config.check_tcp + self.config.check_tcp = HostMatcher([".+:%s" % self.server.port] + self.config.check_tcp.patterns) + + def _tcpproxy_off(self): + assert hasattr(self, "_tcpproxy_backup") + self.config.check_ignore = self._tcpproxy_backup + del self._tcpproxy_backup + + + def test_tcp(self): + spec = '304:h"Alternate-Protocol"="mitmproxy-will-remove-this"' + n = self.pathod(spec) + self._tcpproxy_on() + i = self.pathod(spec) + i2 = self.pathod(spec) + self._tcpproxy_off() + + assert i.status_code == i2.status_code == n.status_code == 304 + assert "Alternate-Protocol" in i.headers + assert "Alternate-Protocol" in i2.headers + assert "Alternate-Protocol" not in n.headers + + # Test that we get the original SSL cert + if self.ssl: + i_cert = SSLCert(i.sslinfo.certchain[0]) + i2_cert = SSLCert(i2.sslinfo.certchain[0]) + n_cert = SSLCert(n.sslinfo.certchain[0]) + + assert i_cert == i2_cert == n_cert + + # Make sure that TCP messages are in the event log. + assert any("mitmproxy-will-remove-this" in m for m in self.master.log) class AppMixin: def test_app(self): @@ -579,16 +616,50 @@ class TestUpstreamProxy(tservers.HTTPUpstreamProxTest, CommonMixin, AppMixin): class TestUpstreamProxySSL(tservers.HTTPUpstreamProxTest, CommonMixin, TcpMixin): ssl = True + def _host_pattern_on(self, attr): + """ + Updates config.check_tcp or check_ignore, depending on attr. + """ + assert not hasattr(self, "_ignore_%s_backup" % attr) + backup = [] + for proxy in self.chain: + old_matcher = getattr(proxy.tmaster.server.config, "check_%s" % attr) + backup.append(old_matcher) + setattr( + proxy.tmaster.server.config, + "check_%s" % attr, + HostMatcher([".+:%s" % self.server.port] + old_matcher.patterns) + ) + + setattr(self, "_ignore_%s_backup" % attr, backup) + + def _host_pattern_off(self, attr): + backup = getattr(self, "_ignore_%s_backup" % attr) + for proxy in reversed(self.chain): + setattr( + proxy.tmaster.server.config, + "check_%s" % attr, + backup.pop() + ) + + assert not backup + delattr(self, "_ignore_%s_backup" % attr) + def _ignore_on(self): super(TestUpstreamProxySSL, self)._ignore_on() - ignore = parse_host_pattern([".+:%s" % self.server.port])[0] - for proxy in self.chain: - proxy.tmaster.server.config.ignore.append(ignore) + self._host_pattern_on("ignore") def _ignore_off(self): super(TestUpstreamProxySSL, self)._ignore_off() - for proxy in self.chain: - proxy.tmaster.server.config.ignore.pop() + self._host_pattern_off("ignore") + + def _tcpproxy_on(self): + super(TestUpstreamProxySSL, self)._tcpproxy_on() + self._host_pattern_on("tcp") + + def _tcpproxy_off(self): + super(TestUpstreamProxySSL, self)._tcpproxy_off() + self._host_pattern_off("tcp") def test_simple(self): p = self.pathoc() -- cgit v1.2.3 From 37cc6ae0bbb32e528435f821469d36055574a810 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 19 Oct 2014 01:26:08 +0200 Subject: fix race conditions in tests --- test/test_flow.py | 3 +++ test/test_server.py | 12 ++++++++++++ 2 files changed, 15 insertions(+) (limited to 'test') diff --git a/test/test_flow.py b/test/test_flow.py index f0844536..92c5b19d 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -600,6 +600,9 @@ class TestFlowMaster: f.intercepting = True assert "intercepting" in fm.replay_request(f) + f.live = True + assert "live" in fm.replay_request(f) + def test_script_reqerr(self): s = flow.State() fm = flow.FlowMaster(None, s) diff --git a/test/test_server.py b/test/test_server.py index 6035b3a4..c81eab2b 100644 --- a/test/test_server.py +++ b/test/test_server.py @@ -19,6 +19,17 @@ class CommonMixin: def test_large(self): assert len(self.pathod("200:b@50k").content) == 1024*50 + @staticmethod + def wait_until_not_live(flow): + """ + Race condition: We don't want to replay the flow while it is still live. + """ + s = time.time() + while flow.live: + time.sleep(0.001) + if time.time() - s > 5: + raise RuntimeError("Flow is live for too long.") + def test_replay(self): assert self.pathod("304").status_code == 304 if isinstance(self, tservers.HTTPUpstreamProxTest) and self.ssl: @@ -28,6 +39,7 @@ class CommonMixin: l = self.master.state.view[-1] assert l.response.code == 304 l.request.path = "/p/305" + self.wait_until_not_live(l) rt = self.master.replay_request(l, block=True) assert l.response.code == 305 -- cgit v1.2.3 From efd6fdb0e24532de757fc90a8d3ae984b7170c51 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 26 Oct 2014 17:13:25 +1300 Subject: Start a fuzzing architecture for mitmproxy --- test/fuzzing/.env | 6 ++++++ test/fuzzing/README | 14 ++++++++++++++ test/fuzzing/client_patterns | 4 ++++ test/fuzzing/go_proxy | 15 +++++++++++---- test/fuzzing/reverse_patterns | 9 +++++++++ test/fuzzing/straight_stream | 4 ++++ test/fuzzing/straight_stream_patterns | 5 +++++ 7 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 test/fuzzing/.env create mode 100644 test/fuzzing/README create mode 100644 test/fuzzing/client_patterns create mode 100644 test/fuzzing/reverse_patterns create mode 100644 test/fuzzing/straight_stream create mode 100644 test/fuzzing/straight_stream_patterns (limited to 'test') diff --git a/test/fuzzing/.env b/test/fuzzing/.env new file mode 100644 index 00000000..e2cf7829 --- /dev/null +++ b/test/fuzzing/.env @@ -0,0 +1,6 @@ + +MITMDUMP=../../mitmdump +PATHOD=../../../pathod/pathod +PATHOC=../../../pathod/pathoc +FUZZ_SETTINGS=-remTt 1 -n 0 -I 200,400,405,502 + diff --git a/test/fuzzing/README b/test/fuzzing/README new file mode 100644 index 00000000..2760506f --- /dev/null +++ b/test/fuzzing/README @@ -0,0 +1,14 @@ + +A fuzzing architecture for mitmproxy +==================================== + +Quick start: + + honcho -f ./straight_stream start + + +Notes: + + - Processes are managed using honcho (pip install honcho) + - Paths and common settings live in .env + diff --git a/test/fuzzing/client_patterns b/test/fuzzing/client_patterns new file mode 100644 index 00000000..83457b6f --- /dev/null +++ b/test/fuzzing/client_patterns @@ -0,0 +1,4 @@ +get:'http://localhost:9999/p/200':ir,"\n" +get:'http://localhost:9999/p/200':ir,"\0" +get:'http://localhost:9999/p/200':ir,@5 +get:'http://localhost:9999/p/200':dr diff --git a/test/fuzzing/go_proxy b/test/fuzzing/go_proxy index c9b6aef6..ea29400f 100755 --- a/test/fuzzing/go_proxy +++ b/test/fuzzing/go_proxy @@ -3,20 +3,27 @@ # mitmproxy/mitmdump is running on port 8080 in straight proxy mode. # pathod is running on port 9999 -BASE_HTTP="/Users/aldo/git/public/pathod/pathoc -Tt 1 -eo -I 200,400,405,502 -p 8080 localhost " +BASE="../../../" +BASE_HTTP=$BASE"/pathod/pathoc -Tt 1 -e -I 200,400,405,502 -p 8080 localhost " +BASE_HTTPS=$BASE"/pathod/pathoc -sc localhost:9999 -Tt 1 -eo -I 200,400,404,405,502,800 -p 8080 localhost " + #$BASE_HTTP -n 10000 "get:'http://localhost:9999':ir,@1" #$BASE_HTTP -n 100 "get:'http://localhost:9999':dr" -#$BASE_HTTP -n 10000 "get:'http://localhost:9999/p/200:ir,@300.0 +#$BASE_HTTP -n 10000 "get:'http://localhost:9999/p/200':ir,@300" + +#$BASE_HTTP -n 10000 "get:'http://localhost:9999/p/200:ir,@1'" +#$BASE_HTTP -n 100 "get:'http://localhost:9999/p/200:dr'" +#$BASE_HTTP -n 10000 "get:'http://localhost:9999/p/200:ir,@100'" # Assuming: # mitmproxy/mitmdump is running on port 8080 in straight proxy mode. # pathod with SSL enabled is running on port 9999 -BASE_HTTPS="/Users/aldo/git/public/pathod/pathoc -sc localhost:9999 -Tt 1 -eo -I 200,400,404,405,502,800 -p 8080 localhost " -$BASE_HTTPS -en 10000 "get:'/p/200:b@10:ir,@1'" +#$BASE_HTTPS -en 10000 "get:'/p/200:b@100:ir,@1'" #$BASE_HTTPS -en 10000 "get:'/p/200:ir,@1'" #$BASE_HTTPS -n 100 "get:'/p/200:dr'" #$BASE_HTTPS -n 10000 "get:'/p/200:ir,@3000'" #$BASE_HTTPS -n 10000 "get:'/p/200:ir,\"\\n\"'" + diff --git a/test/fuzzing/reverse_patterns b/test/fuzzing/reverse_patterns new file mode 100644 index 00000000..8d1d76a2 --- /dev/null +++ b/test/fuzzing/reverse_patterns @@ -0,0 +1,9 @@ +get:'/p/200':b@10:ir,"\n" +get:'/p/200':b@10:ir,"\r\n" +get:'/p/200':b@10:ir,"\0" +get:'/p/200':b@10:ir,@5 +get:'/p/200':b@10:dr + +get:'/p/200:b@10:ir,@1' +get:'/p/200:b@10:dr' +get:'/p/200:b@10:ir,@100' diff --git a/test/fuzzing/straight_stream b/test/fuzzing/straight_stream new file mode 100644 index 00000000..64feae45 --- /dev/null +++ b/test/fuzzing/straight_stream @@ -0,0 +1,4 @@ + +mitmdump: $MITMDUMP -q --stream 1 +pathod: $PATHOD -q +pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns \ No newline at end of file diff --git a/test/fuzzing/straight_stream_patterns b/test/fuzzing/straight_stream_patterns new file mode 100644 index 00000000..f5ae06f2 --- /dev/null +++ b/test/fuzzing/straight_stream_patterns @@ -0,0 +1,5 @@ +get:'http://localhost:9999/p/':s'200:b"foo"':ir,'\n' +get:'http://localhost:9999/p/':s'200:b"foo"':ir,'a' +get:'http://localhost:9999/p/':s'200:b"foo"':ir,'9' +get:'http://localhost:9999/p/':s'200:b"foo"':ir,':' +get:'http://localhost:9999/p/':s'200:b"foo"':ir,'"' -- cgit v1.2.3 From 16654ad6a4ba4f12287d5707dafe3794b6e33fb8 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 26 Oct 2014 17:58:36 +1300 Subject: Fix crash while streaming Found using fuzzing. Reproduction with pathoc, given "mitmproxy -s" and pathod running on 9999: get:'http://localhost:9999/p/':s'200:b\'foo\':h\'Content-Length\'=\'3\'':i58,'\x1a':r return flow.FlowMaster.run(self) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/controller.py", line 111, in run self.tick(self.masterq, 0.01) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/flow.py", line 613, in tick return controller.Master.tick(self, q, timeout) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/controller.py", line 101, in tick self.handle(*msg) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/controller.py", line 118, in handle m(obj) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/flow.py", line 738, in handle_responseheaders self.stream_large_bodies.run(f, False) File "/Users/aldo/mitmproxy/mitmproxy/libmproxy/flow.py", line 155, in run r.headers, is_request, flow.request.method, code File "/Users/aldo/mitmproxy/mitmproxy/netlib/http.py", line 401, in expected_http_body_size raise HttpError(400 if is_request else 502, "Invalid content-length header: %s" % headers["content-length"]) netlib.http.HttpError: Invalid content-length header: ['\x1a3'] --- test/fuzzing/straight_stream | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/fuzzing/straight_stream b/test/fuzzing/straight_stream index 64feae45..a716a085 100644 --- a/test/fuzzing/straight_stream +++ b/test/fuzzing/straight_stream @@ -1,4 +1,6 @@ mitmdump: $MITMDUMP -q --stream 1 pathod: $PATHOD -q -pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns \ No newline at end of file +#pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns +pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 /tmp/err + -- cgit v1.2.3 From 340d0570bfe7ceae68d7d592e3b7283480c351b0 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 26 Oct 2014 18:32:45 +1300 Subject: Legibility --- test/fuzzing/straight_stream | 4 ++-- test/fuzzing/straight_stream_patterns | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/fuzzing/straight_stream b/test/fuzzing/straight_stream index a716a085..99af212f 100644 --- a/test/fuzzing/straight_stream +++ b/test/fuzzing/straight_stream @@ -1,6 +1,6 @@ mitmdump: $MITMDUMP -q --stream 1 pathod: $PATHOD -q -#pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns -pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 /tmp/err +pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns +#pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 /tmp/err diff --git a/test/fuzzing/straight_stream_patterns b/test/fuzzing/straight_stream_patterns index f5ae06f2..591bf20d 100644 --- a/test/fuzzing/straight_stream_patterns +++ b/test/fuzzing/straight_stream_patterns @@ -3,3 +3,5 @@ get:'http://localhost:9999/p/':s'200:b"foo"':ir,'a' get:'http://localhost:9999/p/':s'200:b"foo"':ir,'9' get:'http://localhost:9999/p/':s'200:b"foo"':ir,':' get:'http://localhost:9999/p/':s'200:b"foo"':ir,'"' +get:'http://localhost:9999/p/':s'200:b"foo"':ir,'-' +get:'http://localhost:9999/p/':s'200:b"foo"':dr -- cgit v1.2.3 From 2c64b90a3d239c76bca4c334f89d7b53a965d35b Mon Sep 17 00:00:00 2001 From: Wade 524 Date: Fri, 31 Oct 2014 11:49:45 -0700 Subject: Adding some test coverage for handling HTTP OPTIONS requests. --- test/test_protocol_http.py | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index ea6cf3fd..f5b9e0a1 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -23,7 +23,7 @@ def test_stripped_chunked_encoding_no_content(): class TestHTTPRequest: - def test_asterisk_form(self): + def test_asterisk_form_in(self): s = StringIO("OPTIONS * HTTP/1.1") f = tutils.tflow(req=None) f.request = HTTPRequest.from_stream(s) @@ -33,7 +33,7 @@ class TestHTTPRequest: f.request.scheme = "http" assert f.request.assemble() == "OPTIONS * HTTP/1.1\r\nHost: address:22\r\n\r\n" - def test_origin_form(self): + def test_relative_form_in(self): s = StringIO("GET /foo\xff HTTP/1.1") tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s) s = StringIO("GET /foo HTTP/1.1\r\nConnection: Upgrade\r\nUpgrade: h2c") @@ -52,8 +52,7 @@ class TestHTTPRequest: r.update_host_header() assert "Host" in r.headers - - def test_authority_form(self): + def test_authority_form_in(self): s = StringIO("CONNECT oops-no-port.com HTTP/1.1") tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s) s = StringIO("CONNECT address:22 HTTP/1.1") @@ -62,13 +61,37 @@ class TestHTTPRequest: assert r.assemble() == "CONNECT address:22 HTTP/1.1\r\nHost: address:22\r\n\r\n" assert r.pretty_url(False) == "address:22" - def test_absolute_form(self): + def test_absolute_form_in(self): s = StringIO("GET oops-no-protocol.com HTTP/1.1") tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s) s = StringIO("GET http://address:22/ HTTP/1.1") r = HTTPRequest.from_stream(s) assert r.assemble() == "GET http://address:22/ HTTP/1.1\r\nHost: address:22\r\n\r\n" + def test_http_options_relative_form_in(self): + """ + Exercises fix for Issue #xxx. + """ + s = StringIO("OPTIONS /secret/resource HTTP/1.1") + r = HTTPRequest.from_stream(s) + r.host = 'address' + r.port = 80 + r.scheme = "http" + assert r.assemble() == ("OPTIONS " + "/secret/resource " + "HTTP/1.1\r\nHost: address\r\n\r\n") + + def test_http_options_absolute_form_in(self): + s = StringIO("OPTIONS http://address/secret/resource HTTP/1.1") + r = HTTPRequest.from_stream(s) + r.host = 'address' + r.port = 80 + r.scheme = "http" + assert r.assemble() == ("OPTIONS " + "http://address:80/secret/resource " + "HTTP/1.1\r\nHost: address\r\n\r\n") + + def test_assemble_unknown_form(self): r = tutils.treq() tutils.raises("Invalid request form", r.assemble, "antiauthority") @@ -133,4 +156,4 @@ class TestInvalidRequests(tservers.HTTPProxTest): p.connect() r = p.request("get:/p/200") assert r.status_code == 400 - assert "Invalid HTTP request form" in r.content \ No newline at end of file + assert "Invalid HTTP request form" in r.content -- cgit v1.2.3 From c4c42fa040f4e0177516e9830591ca36a3660f3f Mon Sep 17 00:00:00 2001 From: Wade 524 Date: Fri, 31 Oct 2014 12:45:31 -0700 Subject: Updating OPTIONS test with related issue number. --- test/test_protocol_http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index f5b9e0a1..db262950 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -70,7 +70,7 @@ class TestHTTPRequest: def test_http_options_relative_form_in(self): """ - Exercises fix for Issue #xxx. + Exercises fix for Issue #392. """ s = StringIO("OPTIONS /secret/resource HTTP/1.1") r = HTTPRequest.from_stream(s) -- cgit v1.2.3 From d0de490ef1ced7597471c1867d30213b162a7e89 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sun, 2 Nov 2014 18:04:57 +1300 Subject: Release prep: binaries build script, release checklist, fuzzing --- test/fuzzing/.env | 2 +- test/fuzzing/straight_stream | 6 +++--- test/fuzzing/straight_stream_patterns | 12 +++++++++++- test/fuzzing/straight_stream_ssl | 6 ++++++ 4 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 test/fuzzing/straight_stream_ssl (limited to 'test') diff --git a/test/fuzzing/.env b/test/fuzzing/.env index e2cf7829..82ae6a8d 100644 --- a/test/fuzzing/.env +++ b/test/fuzzing/.env @@ -2,5 +2,5 @@ MITMDUMP=../../mitmdump PATHOD=../../../pathod/pathod PATHOC=../../../pathod/pathoc -FUZZ_SETTINGS=-remTt 1 -n 0 -I 200,400,405,502 +FUZZ_SETTINGS=-remTt 1 -n 0 diff --git a/test/fuzzing/straight_stream b/test/fuzzing/straight_stream index 99af212f..41e2a6e1 100644 --- a/test/fuzzing/straight_stream +++ b/test/fuzzing/straight_stream @@ -1,6 +1,6 @@ -mitmdump: $MITMDUMP -q --stream 1 -pathod: $PATHOD -q +mitmdump: $MITMDUMP +pathod: $PATHOD pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns -#pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 /tmp/err +#pathoc: sleep 2 && $PATHOC localhost:8080 /tmp/err diff --git a/test/fuzzing/straight_stream_patterns b/test/fuzzing/straight_stream_patterns index 591bf20d..93a066e6 100644 --- a/test/fuzzing/straight_stream_patterns +++ b/test/fuzzing/straight_stream_patterns @@ -4,4 +4,14 @@ get:'http://localhost:9999/p/':s'200:b"foo"':ir,'9' get:'http://localhost:9999/p/':s'200:b"foo"':ir,':' get:'http://localhost:9999/p/':s'200:b"foo"':ir,'"' get:'http://localhost:9999/p/':s'200:b"foo"':ir,'-' -get:'http://localhost:9999/p/':s'200:b"foo"':dr + +get:'http://localhost:9999/p/':s'200:b"foo":ir,"\n"' +get:'http://localhost:9999/p/':s'200:b"foo":ir,"a"' +get:'http://localhost:9999/p/':s'200:b"foo":ir,"9"' +get:'http://localhost:9999/p/':s'200:b"foo":ir,":"' +get:'http://localhost:9999/p/':s"200:b'foo':ir,'\"'" +get:'http://localhost:9999/p/':s'200:b"foo":ir,"-"' +get:'http://localhost:9999/p/':s'200:b"foo":dr' + +get:'http://localhost:9999/p/':s'200:b"foo"':ir,@2 +get:'http://localhost:9999/p/':s'200:b"foo":ir,@2' diff --git a/test/fuzzing/straight_stream_ssl b/test/fuzzing/straight_stream_ssl new file mode 100644 index 00000000..708ff0b3 --- /dev/null +++ b/test/fuzzing/straight_stream_ssl @@ -0,0 +1,6 @@ + +mitmdump: $MITMDUMP -q --stream 1 +pathod: $PATHOD +pathoc: sleep 2 && $PATHOC $FUZZ_SETTINGS localhost:8080 ./straight_stream_patterns +#pathoc: sleep 2 && $PATHOC localhost:8080 /tmp/err + -- cgit v1.2.3 From 0fe83ce87bd1e3cf00fb06d2cc06e1bf3b0dbe85 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 6 Nov 2014 10:35:00 +1300 Subject: Fix bug in flow dumping, add unit test that should have caught this in the first place --- test/test_dump.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_dump.py b/test/test_dump.py index 2e58e073..e9cb4d33 100644 --- a/test/test_dump.py +++ b/test/test_dump.py @@ -1,10 +1,12 @@ import os from cStringIO import StringIO -from libmproxy import dump, flow, proxy +from libmproxy import dump, flow +from libmproxy.protocol import http from libmproxy.proxy.primitives import Log import tutils import mock + def test_strfuncs(): t = tutils.tresp() t.is_replay = True @@ -58,6 +60,18 @@ class TestDumpMaster: assert m.handle_error(f) assert "error" in cs.getvalue() + def test_missing_content(self): + cs = StringIO() + o = dump.Options(flow_detail=3) + m = dump.DumpMaster(None, o, outfile=cs) + f = tutils.tflow() + f.request.content = http.CONTENT_MISSING + m.handle_request(f) + f.response = tutils.tresp() + f.response.content = http.CONTENT_MISSING + m.handle_response(f) + assert "content missing" in cs.getvalue() + def test_replay(self): cs = StringIO() -- cgit v1.2.3 From 4d090e09c7b6440176a22b541e37a0b1a0a08570 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 7 Nov 2014 09:59:11 +0100 Subject: fix tests --- test/test_protocol_http.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index db262950..16870777 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -31,7 +31,9 @@ class TestHTTPRequest: f.request.host = f.server_conn.address.host f.request.port = f.server_conn.address.port f.request.scheme = "http" - assert f.request.assemble() == "OPTIONS * HTTP/1.1\r\nHost: address:22\r\n\r\n" + assert f.request.assemble() == ("OPTIONS * HTTP/1.1\r\n" + "Host: address:22\r\n" + "Content-Length: 0\r\n\r\n") def test_relative_form_in(self): s = StringIO("GET /foo\xff HTTP/1.1") @@ -58,7 +60,9 @@ class TestHTTPRequest: s = StringIO("CONNECT address:22 HTTP/1.1") r = HTTPRequest.from_stream(s) r.scheme, r.host, r.port = "http", "address", 22 - assert r.assemble() == "CONNECT address:22 HTTP/1.1\r\nHost: address:22\r\n\r\n" + assert r.assemble() == ("CONNECT address:22 HTTP/1.1\r\n" + "Host: address:22\r\n" + "Content-Length: 0\r\n\r\n") assert r.pretty_url(False) == "address:22" def test_absolute_form_in(self): @@ -66,7 +70,7 @@ class TestHTTPRequest: tutils.raises("Bad HTTP request line", HTTPRequest.from_stream, s) s = StringIO("GET http://address:22/ HTTP/1.1") r = HTTPRequest.from_stream(s) - assert r.assemble() == "GET http://address:22/ HTTP/1.1\r\nHost: address:22\r\n\r\n" + assert r.assemble() == "GET http://address:22/ HTTP/1.1\r\nHost: address:22\r\nContent-Length: 0\r\n\r\n" def test_http_options_relative_form_in(self): """ @@ -77,9 +81,9 @@ class TestHTTPRequest: r.host = 'address' r.port = 80 r.scheme = "http" - assert r.assemble() == ("OPTIONS " - "/secret/resource " - "HTTP/1.1\r\nHost: address\r\n\r\n") + assert r.assemble() == ("OPTIONS /secret/resource HTTP/1.1\r\n" + "Host: address\r\n" + "Content-Length: 0\r\n\r\n") def test_http_options_absolute_form_in(self): s = StringIO("OPTIONS http://address/secret/resource HTTP/1.1") @@ -87,9 +91,9 @@ class TestHTTPRequest: r.host = 'address' r.port = 80 r.scheme = "http" - assert r.assemble() == ("OPTIONS " - "http://address:80/secret/resource " - "HTTP/1.1\r\nHost: address\r\n\r\n") + assert r.assemble() == ("OPTIONS http://address:80/secret/resource HTTP/1.1\r\n" + "Host: address\r\n" + "Content-Length: 0\r\n\r\n") def test_assemble_unknown_form(self): -- cgit v1.2.3 From a325ae638b07a8a08018403e57c05ab8d4119161 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Tue, 11 Nov 2014 13:09:05 +0100 Subject: fix tests --- test/test_flow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_flow.py b/test/test_flow.py index 6ed279c2..8c197153 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -692,7 +692,8 @@ class TestFlowMaster: f = tutils.tflow(resp=True) pb = [tutils.tflow(resp=True), f] - fm = flow.FlowMaster(None, s) + + fm = flow.FlowMaster(DummyServer(ProxyConfig()), s) assert not fm.start_server_playback(pb, False, [], False, False, None, False) assert not fm.start_client_playback(pb, False) -- cgit v1.2.3 From 0c52b4e3b9137e22f6c8c649d6b584d44d7f4b75 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 14 Nov 2014 00:26:22 +0100 Subject: handle script hooks in replay, fix tests, fix #402 --- test/test_flow.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/test_flow.py b/test/test_flow.py index 8c197153..22abb4d4 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -86,19 +86,20 @@ class TestClientPlaybackState: fm = flow.FlowMaster(None, s) fm.start_client_playback([first, tutils.tflow()], True) c = fm.client_playback + c.testing = True assert not c.done() assert not s.flow_count() assert c.count() == 2 - c.tick(fm, testing=True) + c.tick(fm) assert s.flow_count() assert c.count() == 1 - c.tick(fm, testing=True) + c.tick(fm) assert c.count() == 1 c.clear(c.current) - c.tick(fm, testing=True) + c.tick(fm) assert c.count() == 0 c.clear(c.current) assert c.done() @@ -696,6 +697,7 @@ class TestFlowMaster: fm = flow.FlowMaster(DummyServer(ProxyConfig()), s) assert not fm.start_server_playback(pb, False, [], False, False, None, False) assert not fm.start_client_playback(pb, False) + fm.client_playback.testing = True q = Queue.Queue() assert not fm.state.flow_count() -- cgit v1.2.3 From 9c88622e25033cab300d2bbde2811c346c3caa8c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 15 Nov 2014 16:17:05 +1300 Subject: Adjust tests --- test/test_proxy.py | 12 ++++++------ test/tservers.py | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'test') diff --git a/test/test_proxy.py b/test/test_proxy.py index c396183b..641b4f47 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -70,9 +70,9 @@ class TestProcessProxyOptions: def test_simple(self): assert self.p() - def test_confdir(self): - with tutils.tmpdir() as confdir: - self.assert_noerr("--confdir", confdir) + def test_cadir(self): + with tutils.tmpdir() as cadir: + self.assert_noerr("--cadir", cadir) @mock.patch("libmproxy.platform.resolver", None) def test_no_transparent(self): @@ -94,12 +94,12 @@ class TestProcessProxyOptions: self.assert_err("mutually exclusive", "-R", "http://localhost", "-T") def test_client_certs(self): - with tutils.tmpdir() as confdir: - self.assert_noerr("--client-certs", confdir) + with tutils.tmpdir() as cadir: + self.assert_noerr("--client-certs", cadir) self.assert_err("directory does not exist", "--client-certs", "nonexistent") def test_certs(self): - with tutils.tmpdir() as confdir: + with tutils.tmpdir() as cadir: self.assert_noerr("--cert", tutils.test_data.path("data/testkey.pem")) self.assert_err("does not exist", "--cert", "nonexistent") diff --git a/test/tservers.py b/test/tservers.py index 93c8a80a..12154ba7 100644 --- a/test/tservers.py +++ b/test/tservers.py @@ -99,7 +99,7 @@ class ProxTestBase(object): @classmethod def teardownAll(cls): - shutil.rmtree(cls.confdir) + shutil.rmtree(cls.cadir) cls.proxy.shutdown() cls.server.shutdown() cls.server2.shutdown() @@ -116,10 +116,10 @@ class ProxTestBase(object): @classmethod def get_proxy_config(cls): - cls.confdir = os.path.join(tempfile.gettempdir(), "mitmproxy") + cls.cadir = os.path.join(tempfile.gettempdir(), "mitmproxy") return dict( no_upstream_cert = cls.no_upstream_cert, - confdir = cls.confdir, + cadir = cls.cadir, authenticator = cls.authenticator, certforward = cls.certforward, ssl_ports=([cls.server.port, cls.server2.port] if cls.ssl else []), -- cgit v1.2.3 From 09c503563ad2e42812bf8043aedd9ecf980babf6 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 15 Nov 2014 17:25:05 +1300 Subject: Enable config file parsing We support 4 different config files: ~/.mitmproxy/common.conf: Options that are common to all tools ~/.mitmproxy/mitmproxy.conf: Options for mitmproxy ~/.mitmproxy/mitmdump.conf: Options for mitmdump ~/.mitmproxy/mitmweb.conf: Options for mitmweb Options in the tool-specific config files over-ride options in common.conf. If a non-common option is put in common.conf, an error will be raised if a non-supporting tool is used. --- test/test_cmdline.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_cmdline.py b/test/test_cmdline.py index 12e8aa89..476fc620 100644 --- a/test/test_cmdline.py +++ b/test/test_cmdline.py @@ -1,7 +1,6 @@ import argparse from libmproxy import cmdline import tutils -import os.path def test_parse_replace_hook(): @@ -51,6 +50,7 @@ def test_parse_setheaders(): x = cmdline.parse_setheader("/foo/bar/voing") assert x == ("foo", "bar", "voing") + def test_common(): parser = argparse.ArgumentParser() cmdline.common_options(parser) @@ -108,3 +108,19 @@ def test_common(): assert len(v) == 1 assert v[0][2].strip() == "replacecontents" + +def test_mitmproxy(): + ap = cmdline.mitmproxy() + assert ap + + +def test_mitmdump(): + ap = cmdline.mitmdump() + assert ap + + +def test_mitmweb(): + ap = cmdline.mitmweb() + assert ap + + -- cgit v1.2.3 From 667fe0c20b43e2c5af5380591015b122da79b013 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 15 Nov 2014 23:10:25 +0100 Subject: fix tests --- test/test_examples.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/test_examples.py b/test/test_examples.py index fd42e6f0..a5a212cd 100644 --- a/test/test_examples.py +++ b/test/test_examples.py @@ -1,10 +1,8 @@ import glob -import mock from libmproxy import utils, script from libmproxy.proxy import config import tservers -@mock.patch.dict("sys.modules", {"bs4": mock.Mock()}) def test_load_scripts(): example_dir = utils.Data("libmproxy").path("../examples") scripts = glob.glob("%s/*.py" % example_dir) @@ -12,6 +10,8 @@ def test_load_scripts(): tmaster = tservers.TestMaster(config.ProxyConfig()) for f in scripts: + if "har_extractor" in f: + f += " foo" if "iframe_injector" in f: f += " foo" # one argument required if "modify_response_body" in f: -- cgit v1.2.3 From a7a9ef826c206ca93c20ae26c20f5e5a2d5de8e6 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Mon, 1 Dec 2014 03:36:04 +0100 Subject: fix tests --- test/test_examples.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/test_examples.py b/test/test_examples.py index a5a212cd..deb97b49 100644 --- a/test/test_examples.py +++ b/test/test_examples.py @@ -16,4 +16,5 @@ def test_load_scripts(): f += " foo" # one argument required if "modify_response_body" in f: f += " foo bar" # two arguments required - script.Script(f, tmaster) # Loads the script file. \ No newline at end of file + s = script.Script(f, tmaster) # Loads the script file. + s.unload() \ No newline at end of file -- cgit v1.2.3