aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2011-03-11 11:56:10 +1300
committerAldo Cortesi <aldo@nullcube.com>2011-03-11 11:56:10 +1300
commitdaa9653ebebe73e1056d6dae14b11b0842ecbc2a (patch)
tree570350fc9807ea7c58a77f1bd3f31e950b86cc33 /libmproxy
parente99b1d1949c6a140895f8f10c4863ec41528cccf (diff)
downloadmitmproxy-daa9653ebebe73e1056d6dae14b11b0842ecbc2a.tar.gz
mitmproxy-daa9653ebebe73e1056d6dae14b11b0842ecbc2a.tar.bz2
mitmproxy-daa9653ebebe73e1056d6dae14b11b0842ecbc2a.zip
Add --norefresh to stop refreshing server playback to mitmdump.
Also, make cookie parsing for refreshing more error-tolerant.
Diffstat (limited to 'libmproxy')
-rw-r--r--libmproxy/dump.py2
-rw-r--r--libmproxy/flow.py6
-rw-r--r--libmproxy/proxy.py29
3 files changed, 35 insertions, 2 deletions
diff --git a/libmproxy/dump.py b/libmproxy/dump.py
index 5cbb7389..9e439aaf 100644
--- a/libmproxy/dump.py
+++ b/libmproxy/dump.py
@@ -10,6 +10,7 @@ class Options(object):
"client_replay",
"keepserving",
"kill",
+ "refresh_server_playback",
"request_script",
"response_script",
"rheaders",
@@ -85,6 +86,7 @@ class DumpMaster(flow.FlowMaster):
)
self.anticache = options.anticache
+ self.refresh_server_playback = options.refresh_server_playback
def _readflow(self, path):
path = os.path.expanduser(path)
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index 0080f1d4..e5f9c35f 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -140,6 +140,8 @@ class StickyCookieState:
def handle_response(self, f):
for i in f.response.headers.get("set-cookie", []):
+ # FIXME: We now know that Cookie.py screws up some cookies with
+ # valid RFC 822/1123 datetime specifications for expiry. Sigh.
c = Cookie.SimpleCookie(i)
m = c.values()[0]
k = self.ckey(m, f)
@@ -432,7 +434,9 @@ class FlowMaster(controller.Master):
self.scripts = {}
self.kill_nonreplay = False
self.stickycookie_state = False
+
self.anticache = False
+ self.refresh_server_playback = False
def _runscript(self, f, script):
#begin nocover
@@ -480,6 +484,8 @@ class FlowMaster(controller.Master):
response = proxy.Response.from_state(flow.request, rflow.response.get_state())
response.set_replay()
flow.response = response
+ if self.refresh_server_playback:
+ response.refresh()
flow.request.ack(response)
return True
return None
diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py
index 3a3db2e7..caa93f58 100644
--- a/libmproxy/proxy.py
+++ b/libmproxy/proxy.py
@@ -5,7 +5,7 @@
Development started from Neil Schemenauer's munchy.py
"""
-import sys, os, string, socket, urlparse, re, select, copy, base64, time
+import sys, os, string, socket, urlparse, re, select, copy, base64, time, Cookie
from email.utils import parsedate_tz, formatdate, mktime_tz
import shutil, tempfile
import optparse, SocketServer, ssl
@@ -281,6 +281,28 @@ class Response(controller.Msg):
controller.Msg.__init__(self)
self.replay = False
+ def _refresh_cookie(self, c, delta):
+ """
+ Takes a cookie string c and a time delta in seconds, and returns
+ a refreshed cookie string.
+ """
+ c = Cookie.SimpleCookie(str(c))
+ for i in c.values():
+ if "expires" in i:
+ d = parsedate_tz(i["expires"])
+ if d:
+ d = mktime_tz(d) + delta
+ i["expires"] = formatdate(d)
+ else:
+ # This can happen when the expires tag is invalid.
+ # reddit.com sends a an expires tag like this: "Thu, 31 Dec
+ # 2037 23:59:59 GMT", which is valid RFC 1123, but not
+ # strictly correct according tot he cookie spec. Browsers
+ # appear to parse this tolerantly - maybe we should too.
+ # For now, we just ignore this.
+ del i["expires"]
+ return c.output(header="").strip()
+
def refresh(self, now=None):
"""
This fairly complex and heuristic function refreshes a server
@@ -302,8 +324,11 @@ class Response(controller.Msg):
d = parsedate_tz(self.headers[i][0])
new = mktime_tz(d) + delta
self.headers[i] = [formatdate(new)]
+ c = []
for i in self.headers.get("set-cookie", []):
- pass
+ c.append(self._refresh_cookie(i, delta))
+ if c:
+ self.headers["set-cookie"] = c
def set_replay(self):
self.replay = True