Merge remote-tracking branch 'taiste/server-replay-pop'

This commit is contained in:
Aldo Cortesi 2012-03-10 13:36:50 +13:00
commit d3aad7a185
4 changed files with 42 additions and 13 deletions

View File

@ -45,6 +45,7 @@ def get_common_options(options):
stickyauth = stickyauth, stickyauth = stickyauth,
wfile = options.wfile, wfile = options.wfile,
verbosity = options.verbose, verbosity = options.verbose,
nopop = options.nopop,
) )
@ -183,6 +184,12 @@ def common_options(parser):
help= "Disable response refresh, " help= "Disable response refresh, "
"which updates times in cookies and headers for replayed responses." "which updates times in cookies and headers for replayed responses."
) )
group.add_option(
"--no-pop",
action="store_true", dest="nopop", default=False,
help="Disable response pop from response flow. "
"This makes it possible to replay same response multiple times."
)
parser.add_option_group(group) parser.add_option_group(group)
proxy.certificate_option_group(parser) proxy.certificate_option_group(parser)

View File

@ -126,6 +126,9 @@ class StatusBar(common.WWrap):
if self.master.server_playback: if self.master.server_playback:
r.append("[") r.append("[")
r.append(("heading_key", "splayback")) r.append(("heading_key", "splayback"))
if self.master.nopop:
r.append(":%s in file]"%self.master.server_playback.count())
else:
r.append(":%s to go]"%self.master.server_playback.count()) r.append(":%s to go]"%self.master.server_playback.count())
if self.master.state.intercept_txt: if self.master.state.intercept_txt:
r.append("[") r.append("[")
@ -297,6 +300,7 @@ class Options(object):
"stickyauth", "stickyauth",
"verbosity", "verbosity",
"wfile", "wfile",
"nopop",
] ]
def __init__(self, **kwargs): def __init__(self, **kwargs):
for k, v in kwargs.items(): for k, v in kwargs.items():
@ -350,6 +354,7 @@ class ConsoleMaster(flow.FlowMaster):
self.anticomp = options.anticomp self.anticomp = options.anticomp
self.killextra = options.kill self.killextra = options.kill
self.rheaders = options.rheaders self.rheaders = options.rheaders
self.nopop = options.nopop
self.eventlog = options.eventlog self.eventlog = options.eventlog
self.eventlist = urwid.SimpleListWalker([]) self.eventlist = urwid.SimpleListWalker([])
@ -422,7 +427,7 @@ class ConsoleMaster(flow.FlowMaster):
self.start_server_playback( self.start_server_playback(
ret, ret,
self.killextra, self.rheaders, self.killextra, self.rheaders,
False False, self.nopop
) )
def spawn_editor(self, data): def spawn_editor(self, data):

View File

@ -768,12 +768,12 @@ class ClientPlaybackState:
class ServerPlaybackState: class ServerPlaybackState:
def __init__(self, headers, flows, exit): def __init__(self, headers, flows, exit, nopop):
""" """
headers: Case-insensitive list of request headers that should be headers: Case-insensitive list of request headers that should be
included in request-response matching. included in request-response matching.
""" """
self.headers, self.exit = headers, exit self.headers, self.exit, self.nopop = headers, exit, nopop
self.fmap = {} self.fmap = {}
for i in flows: for i in flows:
if i.response: if i.response:
@ -815,9 +815,14 @@ class ServerPlaybackState:
l = self.fmap.get(self._hash(request)) l = self.fmap.get(self._hash(request))
if not l: if not l:
return None return None
if self.nopop:
return l[0]
else:
return l.pop(0) return l.pop(0)
class StickyCookieState: class StickyCookieState:
def __init__(self, flt): def __init__(self, flt):
""" """
@ -1251,12 +1256,12 @@ class FlowMaster(controller.Master):
def stop_client_playback(self): def stop_client_playback(self):
self.client_playback = None self.client_playback = None
def start_server_playback(self, flows, kill, headers, exit): def start_server_playback(self, flows, kill, headers, exit, nopop):
""" """
flows: List of flows. flows: List of flows.
kill: Boolean, should we kill requests not part of the replay? kill: Boolean, should we kill requests not part of the replay?
""" """
self.server_playback = ServerPlaybackState(headers, flows, exit) self.server_playback = ServerPlaybackState(headers, flows, exit, nopop)
self.kill_nonreplay = kill self.kill_nonreplay = kill
def stop_server_playback(self): def stop_server_playback(self):

View File

@ -87,7 +87,7 @@ class uClientPlaybackState(libpry.AutoTree):
class uServerPlaybackState(libpry.AutoTree): class uServerPlaybackState(libpry.AutoTree):
def test_hash(self): def test_hash(self):
s = flow.ServerPlaybackState(None, [], False) s = flow.ServerPlaybackState(None, [], False, False)
r = tutils.tflow() r = tutils.tflow()
r2 = tutils.tflow() r2 = tutils.tflow()
@ -99,7 +99,7 @@ class uServerPlaybackState(libpry.AutoTree):
assert s._hash(r) != s._hash(r2) assert s._hash(r) != s._hash(r2)
def test_headers(self): def test_headers(self):
s = flow.ServerPlaybackState(["foo"], [], False) s = flow.ServerPlaybackState(["foo"], [], False, False)
r = tutils.tflow_full() r = tutils.tflow_full()
r.request.headers["foo"] = ["bar"] r.request.headers["foo"] = ["bar"]
r2 = tutils.tflow_full() r2 = tutils.tflow_full()
@ -120,7 +120,7 @@ class uServerPlaybackState(libpry.AutoTree):
r2 = tutils.tflow_full() r2 = tutils.tflow_full()
r2.request.headers["key"] = ["two"] r2.request.headers["key"] = ["two"]
s = flow.ServerPlaybackState(None, [r, r2], False) s = flow.ServerPlaybackState(None, [r, r2], False, False)
assert s.count() == 2 assert s.count() == 2
assert len(s.fmap.keys()) == 1 assert len(s.fmap.keys()) == 1
@ -134,6 +134,18 @@ class uServerPlaybackState(libpry.AutoTree):
assert not s.next_flow(r) assert not s.next_flow(r)
def test_load_with_nopop(self):
r = tutils.tflow_full()
r.request.headers["key"] = ["one"]
r2 = tutils.tflow_full()
r2.request.headers["key"] = ["two"]
s = flow.ServerPlaybackState(None, [r, r2], False, True)
assert s.count() == 2
n = s.next_flow(r)
assert s.count() == 2
class uFlow(libpry.AutoTree): class uFlow(libpry.AutoTree):
def test_copy(self): def test_copy(self):
@ -547,7 +559,7 @@ class uFlowMaster(libpry.AutoTree):
f = tutils.tflow_full() f = tutils.tflow_full()
pb = [tutils.tflow_full(), f] pb = [tutils.tflow_full(), f]
fm = flow.FlowMaster(None, s) fm = flow.FlowMaster(None, s)
assert not fm.start_server_playback(pb, False, [], False) assert not fm.start_server_playback(pb, False, [], False, False)
assert not fm.start_client_playback(pb, False) assert not fm.start_client_playback(pb, False)
q = Queue.Queue() q = Queue.Queue()
@ -568,10 +580,10 @@ class uFlowMaster(libpry.AutoTree):
fm.refresh_server_playback = True fm.refresh_server_playback = True
assert not fm.do_server_playback(tutils.tflow()) assert not fm.do_server_playback(tutils.tflow())
fm.start_server_playback(pb, False, [], False) fm.start_server_playback(pb, False, [], False, False)
assert fm.do_server_playback(tutils.tflow()) assert fm.do_server_playback(tutils.tflow())
fm.start_server_playback(pb, False, [], True) fm.start_server_playback(pb, False, [], True, False)
r = tutils.tflow() r = tutils.tflow()
r.request.content = "gibble" r.request.content = "gibble"
assert not fm.do_server_playback(r) assert not fm.do_server_playback(r)