aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2013-03-14 09:19:43 +1300
committerAldo Cortesi <aldo@nullcube.com>2013-03-14 09:19:43 +1300
commitcfb5ba89ce96594b2f8d51f27c9b2ee41ecf18e5 (patch)
tree7bdea72173b7f49e8409f6c5fb0c42e0fe3329ec
parentc34d1e3de6483b1ab8a1a3add53fb84364c68249 (diff)
downloadmitmproxy-cfb5ba89ce96594b2f8d51f27c9b2ee41ecf18e5.tar.gz
mitmproxy-cfb5ba89ce96594b2f8d51f27c9b2ee41ecf18e5.tar.bz2
mitmproxy-cfb5ba89ce96594b2f8d51f27c9b2ee41ecf18e5.zip
Introduce a filtered flow writer, and use it in dump.py
Fixes #104
-rw-r--r--doc-src/scripting/inlinescripts.html2
-rwxr-xr-xexamples/flowbasic8
-rwxr-xr-xexamples/iframe_injector4
-rwxr-xr-xexamples/proxapp4
-rwxr-xr-xexamples/stickycookies4
-rw-r--r--libmproxy/console/__init__.py2
-rw-r--r--libmproxy/dump.py4
-rw-r--r--libmproxy/flow.py17
-rw-r--r--test/test_flow.py21
9 files changed, 48 insertions, 18 deletions
diff --git a/doc-src/scripting/inlinescripts.html b/doc-src/scripting/inlinescripts.html
index 39752b7f..2d53df80 100644
--- a/doc-src/scripting/inlinescripts.html
+++ b/doc-src/scripting/inlinescripts.html
@@ -13,7 +13,7 @@ lets the script interact with the global mitmproxy state. The __response__
event also gets an instance of Flow, which we can use to manipulate the
response itself.
-We can now run this script as follows:
+We can now run this script using mitmdump or mitmproxy as follows:
<pre class="terminal">
> mitmdump -s add_header.py
diff --git a/examples/flowbasic b/examples/flowbasic
index b419f9e7..b8184262 100755
--- a/examples/flowbasic
+++ b/examples/flowbasic
@@ -3,8 +3,8 @@
This example shows how to build a proxy based on mitmproxy's Flow
primitives.
- Note that request and response messages are not automatically acked, so we
- need to implement handlers to do this.
+ Note that request and response messages are not automatically replied to,
+ so we need to implement handlers to do this.
"""
import os
from libmproxy import proxy, flow
@@ -19,13 +19,13 @@ class MyMaster(flow.FlowMaster):
def handle_request(self, r):
f = flow.FlowMaster.handle_request(self, r)
if f:
- r._ack()
+ r.reply()
return f
def handle_response(self, r):
f = flow.FlowMaster.handle_response(self, r)
if f:
- r._ack()
+ r.reply()
print f
return f
diff --git a/examples/iframe_injector b/examples/iframe_injector
index 6dd28674..8b1e02f1 100755
--- a/examples/iframe_injector
+++ b/examples/iframe_injector
@@ -23,14 +23,14 @@ class InjectingMaster(controller.Master):
def handle_request(self, msg):
if 'Accept-Encoding' in msg.headers:
msg.headers["Accept-Encoding"] = 'none'
- msg._ack()
+ msg.reply()
def handle_response(self, msg):
if msg.content:
c = msg.replace('<body>', '<body><iframe src="%s" frameborder="0" height="0" width="0"></iframe>' % self._iframe_url)
if c > 0:
print 'Iframe injected!'
- msg._ack()
+ msg.reply()
def main(argv):
diff --git a/examples/proxapp b/examples/proxapp
index e8179528..eb5bdbb7 100755
--- a/examples/proxapp
+++ b/examples/proxapp
@@ -23,13 +23,13 @@ class MyMaster(flow.FlowMaster):
def handle_request(self, r):
f = flow.FlowMaster.handle_request(self, r)
if f:
- r._ack()
+ r.reply()
return f
def handle_response(self, r):
f = flow.FlowMaster.handle_response(self, r)
if f:
- r._ack()
+ r.reply()
print f
return f
diff --git a/examples/stickycookies b/examples/stickycookies
index 88bf0063..b07820fc 100755
--- a/examples/stickycookies
+++ b/examples/stickycookies
@@ -25,13 +25,13 @@ class StickyMaster(controller.Master):
self.stickyhosts[hid] = msg.headers["cookie"]
elif hid in self.stickyhosts:
msg.headers["cookie"] = self.stickyhosts[hid]
- msg._ack()
+ msg.reply()
def handle_response(self, msg):
hid = (msg.request.host, msg.request.port)
if msg.headers["set-cookie"]:
self.stickyhosts[hid] = msg.headers["set-cookie"]
- msg._ack()
+ msg.reply()
config = proxy.ProxyConfig(
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index 4b5d1274..98904c84 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -426,7 +426,7 @@ class ConsoleMaster(flow.FlowMaster):
path = os.path.expanduser(path)
try:
f = file(path, "wb")
- flow.FlowMaster.start_stream(self, f)
+ flow.FlowMaster.start_stream(self, f, None)
except IOError, v:
return str(v)
self.stream_path = path
diff --git a/libmproxy/dump.py b/libmproxy/dump.py
index 3a315409..d716e433 100644
--- a/libmproxy/dump.py
+++ b/libmproxy/dump.py
@@ -93,7 +93,7 @@ class DumpMaster(flow.FlowMaster):
path = os.path.expanduser(options.wfile)
try:
f = file(path, "wb")
- self.start_stream(f)
+ self.start_stream(f, self.filt)
except IOError, v:
raise DumpError(v.strerror)
@@ -155,6 +155,7 @@ class DumpMaster(flow.FlowMaster):
return "\n".join(" "*n + i for i in l)
def _process_flow(self, f):
+ self.state.delete_flow(f)
if self.filt and not f.match(self.filt):
return
@@ -198,7 +199,6 @@ class DumpMaster(flow.FlowMaster):
print >> self.outfile, "\n"
if self.o.verbosity:
self.outfile.flush()
- self.state.delete_flow(f)
def handle_log(self, l):
self.add_event(l.msg)
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index 4fefee9f..13b32011 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -1588,8 +1588,8 @@ class FlowMaster(controller.Master):
self.stream.add(i)
self.stop_stream()
- def start_stream(self, fp):
- self.stream = FlowWriter(fp)
+ def start_stream(self, fp, filt):
+ self.stream = FilteredFlowWriter(fp, filt)
def stop_stream(self):
self.stream.fo.close()
@@ -1635,3 +1635,16 @@ class FlowReader:
return
raise FlowReadError("Invalid data format.")
+
+class FilteredFlowWriter:
+ def __init__(self, fo, filt):
+ self.fo = fo
+ self.filt = filt
+
+ def add(self, f):
+ if self.filt and not f.match(self.filt):
+ return
+ d = f._get_state()
+ tnetstring.dump(d, self.fo)
+
+
diff --git a/test/test_flow.py b/test/test_flow.py
index 6aa898ad..c1ae1a9f 100644
--- a/test/test_flow.py
+++ b/test/test_flow.py
@@ -497,6 +497,23 @@ class TestSerialize:
fm = flow.FlowMaster(None, s)
fm.load_flows(r)
assert len(s._flow_list) == 6
+
+ def test_filter(self):
+ sio = StringIO()
+ fl = filt.parse("~c 200")
+ w = flow.FilteredFlowWriter(sio, fl)
+
+ f = tutils.tflow_full()
+ f.response.code = 200
+ w.add(f)
+
+ f = tutils.tflow_full()
+ f.response.code = 201
+ w.add(f)
+
+ sio.seek(0)
+ r = flow.FlowReader(sio)
+ assert len(list(r.stream()))
def test_error(self):
@@ -723,7 +740,7 @@ class TestFlowMaster:
fm = flow.FlowMaster(None, s)
tf = tutils.tflow_full()
- fm.start_stream(file(p, "ab"))
+ fm.start_stream(file(p, "ab"), None)
fm.handle_request(tf.request)
fm.handle_response(tf.response)
fm.stop_stream()
@@ -731,7 +748,7 @@ class TestFlowMaster:
assert r()[0].response
tf = tutils.tflow_full()
- fm.start_stream(file(p, "ab"))
+ fm.start_stream(file(p, "ab"), None)
fm.handle_request(tf.request)
fm.shutdown()