aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmproxy/flow.py31
-rw-r--r--libmproxy/proxy.py12
-rw-r--r--test/test_flow.py17
3 files changed, 52 insertions, 8 deletions
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index 9596d416..6031a009 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -2,9 +2,9 @@
This module provides more sophisticated flow tracking. These match requests
with their responses, and provide filtering and interception facilities.
"""
-import subprocess, base64, sys
+import subprocess, base64, sys, json
from contrib import bson
-import proxy, threading
+import proxy, threading, netstring
class RunException(Exception):
def __init__(self, msg, returncode, errout):
@@ -302,3 +302,30 @@ class State:
rt = ReplayThread(f, masterq)
rt.start()
#end nocover
+
+
+
+class FlowWriter:
+ def __init__(self, fo):
+ self.fo = fo
+ self.ns = netstring.FileEncoder(fo)
+
+ def add(self, flow):
+ d = flow.get_state()
+ s = json.dumps(d)
+ self.ns.write(s)
+
+
+class FlowReader:
+ def __init__(self, fo):
+ self.fo = fo
+ self.ns = netstring.decode_file(fo)
+
+ def stream(self):
+ """
+ Yields Flow objects from the dump.
+ """
+ for i in self.ns:
+ data = json.loads(i)
+ yield Flow.from_state(data)
+
diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py
index 0941155f..ba47ce7b 100644
--- a/libmproxy/proxy.py
+++ b/libmproxy/proxy.py
@@ -5,7 +5,7 @@
Development started from Neil Schemenauer's munchy.py
"""
-import sys, os, time, string, socket, urlparse, re, select, copy
+import sys, os, time, string, socket, urlparse, re, select, copy, base64
import SocketServer, ssl
import utils, controller
@@ -147,7 +147,7 @@ class Request(controller.Msg):
method = self.method,
path = self.path,
headers = self.headers.get_state(),
- content = self.content,
+ content = base64.encodestring(self.content),
timestamp = self.timestamp,
)
@@ -161,7 +161,7 @@ class Request(controller.Msg):
state["method"],
state["path"],
utils.Headers.from_state(state["headers"]),
- state["content"],
+ base64.decodestring(state["content"]),
state["timestamp"]
)
@@ -242,7 +242,7 @@ class Response(controller.Msg):
msg = self.msg,
headers = self.headers.get_state(),
timestamp = self.timestamp,
- content = self.content
+ content = base64.encodestring(self.content)
)
@classmethod
@@ -252,7 +252,7 @@ class Response(controller.Msg):
state["code"],
state["msg"],
utils.Headers.from_state(state["headers"]),
- state["content"],
+ base64.decodestring(state["content"]),
state["timestamp"],
)
@@ -307,7 +307,7 @@ class ClientConnection(controller.Msg):
controller.Msg.__init__(self)
def get_state(self):
- return self.address
+ return list(self.address)
@classmethod
def from_state(klass, state):
diff --git a/test/test_flow.py b/test/test_flow.py
index b71ce6af..4dfa059e 100644
--- a/test/test_flow.py
+++ b/test/test_flow.py
@@ -1,3 +1,4 @@
+from cStringIO import StringIO
from libmproxy import console, proxy, filt, flow
import utils
import libpry
@@ -249,8 +250,24 @@ class uState(libpry.AutoTree):
c.accept_all()
+class uSerialize(libpry.AutoTree):
+ def test_roundtrip(self):
+ sio = StringIO()
+ f = utils.tflow()
+ w = flow.FlowWriter(sio)
+ w.add(f)
+
+ sio.seek(0)
+ r = flow.FlowReader(sio)
+ l = list(r.stream())
+ assert len(l) == 1
+ assert l[0] == f
+
+
+
tests = [
uFlow(),
uState(),
+ uSerialize()
]