diff options
Diffstat (limited to 'libmproxy')
-rw-r--r-- | libmproxy/dump.py | 2 | ||||
-rw-r--r-- | libmproxy/flow.py | 6 | ||||
-rw-r--r-- | libmproxy/proxy.py | 29 |
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 |