From 803d631f04f6af5bb54bbb46b3efec39622ca216 Mon Sep 17 00:00:00 2001
From: Wade Catron <onlywade@gmail.com>
Date: Sat, 7 Mar 2015 08:38:18 -0800
Subject: Adding a server replay option to ignore host when searching for
 matching requests

---
 libmproxy/cmdline.py          |  8 +++++++-
 libmproxy/console/__init__.py |  5 ++++-
 libmproxy/console/flowlist.py |  6 ++++--
 libmproxy/dump.py             |  3 +++
 libmproxy/flow.py             | 27 ++++++++++++++++++++-------
 5 files changed, 38 insertions(+), 11 deletions(-)

(limited to 'libmproxy')

diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py
index e45cc54c..b7270fb9 100644
--- a/libmproxy/cmdline.py
+++ b/libmproxy/cmdline.py
@@ -192,7 +192,8 @@ def get_common_options(options):
         nopop=options.nopop,
         replay_ignore_content = options.replay_ignore_content,
         replay_ignore_params = options.replay_ignore_params,
-        replay_ignore_payload_params = options.replay_ignore_payload_params
+        replay_ignore_payload_params = options.replay_ignore_payload_params,
+        replay_ignore_host = options.replay_ignore_host
     )
 
 
@@ -479,6 +480,11 @@ def common_options(parser):
             to replay. Can be passed multiple times.
         """
     )
+    group.add_argument(
+        "--replay-ignore-host",
+        action="store_true", dest="replay_ignore_host", default=False,
+        help="Ignore request's destination host while searching for a saved flow to replay"
+    )
 
     group = parser.add_argument_group(
         "Replacements",
diff --git a/libmproxy/console/__init__.py b/libmproxy/console/__init__.py
index 0db06832..cc8a0c1f 100644
--- a/libmproxy/console/__init__.py
+++ b/libmproxy/console/__init__.py
@@ -528,7 +528,10 @@ class ConsoleMaster(flow.FlowMaster):
                 flows,
                 self.killextra, self.rheaders,
                 False, self.nopop,
-                self.options.replay_ignore_params, self.options.replay_ignore_content, self.options.replay_ignore_payload_params
+                self.options.replay_ignore_params,
+                self.options.replay_ignore_content,
+                self.options.replay_ignore_payload_params,
+                self.options.replay_ignore_host
             )
 
     def spawn_editor(self, data):
diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py
index 9e7c6d69..2a6a98c8 100644
--- a/libmproxy/console/flowlist.py
+++ b/libmproxy/console/flowlist.py
@@ -126,7 +126,8 @@ class ConnectionItem(common.WWrap):
                 self.master.killextra, self.master.rheaders,
                 False, self.master.nopop,
                 self.master.options.replay_ignore_params, self.master.options.replay_ignore_content,
-                self.master.options.replay_ignore_payload_params
+                self.master.options.replay_ignore_payload_params,
+                self.master.options.replay_ignore_host
             )
         elif k == "t":
             self.master.start_server_playback(
@@ -134,7 +135,8 @@ class ConnectionItem(common.WWrap):
                 self.master.killextra, self.master.rheaders,
                 False, self.master.nopop,
                 self.master.options.replay_ignore_params, self.master.options.replay_ignore_content,
-                self.master.options.replay_ignore_payload_params
+                self.master.options.replay_ignore_payload_params,
+                self.master.options.replay_ignore_host
             )
         else:
             self.master.path_prompt(
diff --git a/libmproxy/dump.py b/libmproxy/dump.py
index 59ddcf5f..ab58966f 100644
--- a/libmproxy/dump.py
+++ b/libmproxy/dump.py
@@ -40,6 +40,7 @@ class Options(object):
         "replay_ignore_content",
         "replay_ignore_params",
         "replay_ignore_payload_params",
+        "replay_ignore_host"
     ]
 
     def __init__(self, **kwargs):
@@ -78,6 +79,7 @@ class DumpMaster(flow.FlowMaster):
         self.showhost = options.showhost
         self.replay_ignore_params = options.replay_ignore_params
         self.replay_ignore_content = options.replay_ignore_content
+        self.replay_ignore_host = options.replay_ignore_host
         self.refresh_server_playback = options.refresh_server_playback
         self.replay_ignore_payload_params = options.replay_ignore_payload_params
 
@@ -119,6 +121,7 @@ class DumpMaster(flow.FlowMaster):
                 options.replay_ignore_params,
                 options.replay_ignore_content,
                 options.replay_ignore_payload_params,
+                options.replay_ignore_host
             )
 
         if options.client_replay:
diff --git a/libmproxy/flow.py b/libmproxy/flow.py
index 43580109..8343c183 100644
--- a/libmproxy/flow.py
+++ b/libmproxy/flow.py
@@ -203,12 +203,19 @@ class ClientPlaybackState:
 
 
 class ServerPlaybackState:
-    def __init__(self, headers, flows, exit, nopop, ignore_params, ignore_content, ignore_payload_params):
+    def __init__(self, headers, flows, exit, nopop, ignore_params, ignore_content,
+                 ignore_payload_params, ignore_host):
         """
             headers: Case-insensitive list of request headers that should be
             included in request-response matching.
         """
-        self.headers, self.exit, self.nopop, self.ignore_params, self.ignore_content, self.ignore_payload_params = headers, exit, nopop, ignore_params, ignore_content, ignore_payload_params
+        self.headers = headers
+        self.exit = exit
+        self.nopop = nopop
+        self.ignore_params = ignore_params
+        self.ignore_content = ignore_content
+        self.ignore_payload_params = ignore_payload_params
+        self.ignore_host = ignore_host
         self.fmap = {}
         for i in flows:
             if i.response:
@@ -228,7 +235,6 @@ class ServerPlaybackState:
         queriesArray = urlparse.parse_qsl(query)
 
         key = [
-            str(r.host),
             str(r.port),
             str(r.scheme),
             str(r.method),
@@ -245,6 +251,9 @@ class ServerPlaybackState:
             else:
                 key.append(str(r.content))
 
+        if not self.ignore_host:
+            key.append(r.host)
+
         filtered = []
         ignore_params = self.ignore_params or []
         for p in queriesArray:
@@ -616,6 +625,7 @@ class FlowMaster(controller.Master):
         self.setheaders = SetHeaders()
         self.replay_ignore_params = False
         self.replay_ignore_content = None
+        self.replay_ignore_host = False
 
         self.stream = None
         self.apps = AppRegistry()
@@ -712,16 +722,19 @@ class FlowMaster(controller.Master):
     def stop_client_playback(self):
         self.client_playback = None
 
-    def start_server_playback(self, flows, kill, headers, exit, nopop, ignore_params, ignore_content,
-                              ignore_payload_params):
+    def start_server_playback(self, flows, kill, headers, exit, nopop, ignore_params,
+                              ignore_content, ignore_payload_params, ignore_host):
         """
             flows: List of flows.
             kill: Boolean, should we kill requests not part of the replay?
             ignore_params: list of parameters to ignore in server replay
             ignore_content: true if request content should be ignored in server replay
+            ignore_payload_params: list of content params to ignore in server replay
+            ignore_host: true if request host should be ignored in server replay
         """
-        self.server_playback = ServerPlaybackState(headers, flows, exit, nopop, ignore_params, ignore_content,
-                                                   ignore_payload_params)
+        self.server_playback = ServerPlaybackState(headers, flows, exit, nopop, 
+                                                   ignore_params, ignore_content,
+                                                   ignore_payload_params, ignore_host)
         self.kill_nonreplay = kill
 
     def stop_server_playback(self):
-- 
cgit v1.2.3