From 03f13453856e3af15dc3af81adcf3a80d1358da0 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Wed, 9 Mar 2011 13:15:31 +1300 Subject: [PATCH] Add an --anticache option to mitmdump. This removes all headers that might cause a server to return 304-not-modified. For now, all the new features are going into mitmdump - everything will be ported over to mitmproxy once I have the feature set locked down. --- libmproxy/dump.py | 11 +++++++---- libmproxy/flow.py | 3 +++ libmproxy/proxy.py | 13 +++++++++++++ mitmdump | 6 ++++++ test/test_flow.py | 3 +-- test/test_proxy.py | 9 +++++++++ 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/libmproxy/dump.py b/libmproxy/dump.py index 73ecc54d4..5cbb73896 100644 --- a/libmproxy/dump.py +++ b/libmproxy/dump.py @@ -6,16 +6,17 @@ class DumpError(Exception): pass class Options(object): __slots__ = [ + "anticache", + "client_replay", + "keepserving", "kill", "request_script", "response_script", + "rheaders", "server_replay", - "client_replay", + "stickycookie", "verbosity", "wfile", - "rheaders", - "stickycookie", - "keepserving", ] def __init__(self, **kwargs): for k, v in kwargs.items(): @@ -83,6 +84,8 @@ class DumpMaster(flow.FlowMaster): not options.keepserving ) + self.anticache = options.anticache + def _readflow(self, path): path = os.path.expanduser(path) try: diff --git a/libmproxy/flow.py b/libmproxy/flow.py index dff58fa05..0080f1d42 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -432,6 +432,7 @@ class FlowMaster(controller.Master): self.scripts = {} self.kill_nonreplay = False self.stickycookie_state = False + self.anticache = False def _runscript(self, f, script): #begin nocover @@ -521,6 +522,8 @@ class FlowMaster(controller.Master): self.stickycookie_state.handle_request(f) if "request" in self.scripts: self._runscript(f, self.scripts["request"]) + if self.anticache: + r.anticache() if self.server_playback: pb = self.do_server_playback(f) if not pb: diff --git a/libmproxy/proxy.py b/libmproxy/proxy.py index a4dc3e69e..48884c090 100644 --- a/libmproxy/proxy.py +++ b/libmproxy/proxy.py @@ -139,6 +139,19 @@ class Request(controller.Msg): # Have this request's cookies been modified by sticky cookies? self.stickycookie = False + def anticache(self): + """ + Modifies this request to remove headers that might produce a cached + response. That is, we remove ETags and If-Modified-Since headers. + """ + delheaders = [ + "if-modified-since", + "if-none-match", + ] + for i in delheaders: + if i in self.headers: + del self.headers[i] + def set_replay(self): self.client_conn = None diff --git a/mitmdump b/mitmdump index 814f2af37..972c76665 100755 --- a/mitmdump +++ b/mitmdump @@ -56,6 +56,11 @@ if __name__ == '__main__': action="store_true", dest="quiet", help="Quiet." ) + parser.add_option( + "--anticache", + action="store_true", dest="anticache", default=False, + help="Strip out request headers that might cause the server to return 304-not-modified." + ) parser.add_option( "--reqscript", action="store", dest="request_script", default=None, @@ -131,6 +136,7 @@ if __name__ == '__main__': client_replay = options.client_replay, keepserving = options.keepserving, stickycookie = stickycookie, + anticache = options.anticache ) if args: filt = " ".join(args) diff --git a/test/test_flow.py b/test/test_flow.py index 4090d483c..d72a18946 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -167,8 +167,6 @@ class uFlow(libpry.AutoTree): f.load_state(f2.get_state()) assert f == f2 - - def test_kill(self): f = tutils.tflow() f.request = tutils.treq() @@ -370,6 +368,7 @@ class uFlowMaster(libpry.AutoTree): def test_all(self): s = flow.State() fm = flow.FlowMaster(None, s) + fm.anticache = True req = tutils.treq() fm.handle_clientconnect(req.client_conn) diff --git a/test/test_proxy.py b/test/test_proxy.py index e5b3ed16c..3bc5bcdb8 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -78,6 +78,15 @@ class uRequest(libpry.AutoTree): assert r.url() == u assert r.assemble() + def test_anticache(self): + h = utils.Headers() + r = proxy.Request(None, "host", 22, "https", "GET", "/", h, "content") + h["if-modified-since"] = ["test"] + h["if-none-match"] = ["test"] + r.anticache() + assert not "if-modified-since" in r.headers + assert not "if-none-match" in r.headers + def test_getset_state(self): h = utils.Headers() h["test"] = ["test"]