aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/cmdline.py
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-03-17 17:20:34 +1300
committerAldo Cortesi <aldo@nullcube.com>2012-03-17 17:20:34 +1300
commit76175672ad554812ea890cca015a7da57285395b (patch)
tree4522d1b7d6649d7d8d2236b09831a746b3179276 /libmproxy/cmdline.py
parentc8ae1e85b33e80f0c84ccdc8b3759affe4ef3900 (diff)
downloadmitmproxy-76175672ad554812ea890cca015a7da57285395b.tar.gz
mitmproxy-76175672ad554812ea890cca015a7da57285395b.tar.bz2
mitmproxy-76175672ad554812ea890cca015a7da57285395b.zip
Add specification of replacement patterns on the command line.
Diffstat (limited to 'libmproxy/cmdline.py')
-rw-r--r--libmproxy/cmdline.py97
1 files changed, 96 insertions, 1 deletions
diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py
index 27819294..483adfc0 100644
--- a/libmproxy/cmdline.py
+++ b/libmproxy/cmdline.py
@@ -14,7 +14,61 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import proxy
-import optparse
+import optparse, re, filt, textwrap
+
+
+class ParseReplaceException(Exception): pass
+class OptionException(Exception): pass
+
+
+def parse_replace_hook(s):
+ """
+ Returns a (pattern, regex, replacement) tuple.
+
+ The general form for a replacement hook is as follows:
+
+ /patt/regex/replacement
+
+ The first character specifies the separator. Example:
+
+ :~q:foo:bar
+
+ If only two clauses are specified, the pattern is set to match
+ universally (i.e. ".*"). Example:
+
+ /foo/bar/
+
+ Clauses are parsed from left to right. Extra separators are taken to be
+ part of the final clause. For instance, the replacement clause below is
+ "foo/bar/":
+
+ /one/two/foo/bar/
+
+ Checks that pattern and regex are both well-formed. Raises
+ ParseReplaceException on error.
+ """
+ sep, rem = s[0], s[1:]
+ parts = rem.split(sep, 2)
+ if len(parts) == 2:
+ patt = ".*"
+ regex, replacement = parts
+ elif len(parts) == 3:
+ patt, regex, replacement = parts
+ else:
+ raise ParseReplaceException("Malformed replacement specifier - too few clauses: %s"%s)
+
+ if not regex:
+ raise ParseReplaceException("Empty replacement regex: %s"%str(patt))
+
+ try:
+ re.compile(regex)
+ except re.error, e:
+ raise ParseReplaceException("Malformed replacement regex: %s"%str(e.message))
+
+ if not filt.parse(patt):
+ raise ParseReplaceException("Malformed replacement filter pattern: %s"%patt)
+
+ return patt, regex, replacement
def get_common_options(options):
@@ -29,6 +83,24 @@ def get_common_options(options):
elif options.stickyauth_filt:
stickyauth = options.stickyauth_filt
+ reps = []
+ for i in options.replace:
+ try:
+ p = parse_replace_hook(i)
+ except ParseReplaceException, e:
+ raise OptionException(e.message)
+ reps.append(p)
+ for i in options.replace_file:
+ try:
+ patt, rex, path = parse_replace_hook(i)
+ except ParseReplaceException, e:
+ raise OptionException(e.message)
+ try:
+ v = open(path, "r").read()
+ except IOError, e:
+ raise OptionException("Could not read replace file: %s"%path)
+ reps.append((patt, rex, v))
+
return dict(
anticache = options.anticache,
anticomp = options.anticomp,
@@ -39,6 +111,7 @@ def get_common_options(options):
refresh_server_playback = not options.norefresh,
rheaders = options.rheaders,
rfile = options.rfile,
+ replacements = reps,
server_replay = options.server_replay,
script = options.script,
stickycookie = stickycookie,
@@ -190,6 +263,28 @@ def common_options(parser):
help="Disable response pop from response flow. "
"This makes it possible to replay same response multiple times."
)
+
+ group = optparse.OptionGroup(
+ parser,
+ "Replacements",
+ """
+ Replacements are of the form "/pattern/regex/replacement", where
+ the separator can be any character. Please see the documentation
+ for more information.
+ """.strip()
+ )
+ group.add_option(
+ "--replace",
+ action="append", type="str", dest="replace", default=[],
+ metavar="PATTERN",
+ help="Replacement pattern."
+ )
+ group.add_option(
+ "--replace-from-file",
+ action="append", type="str", dest="replace_file", default=[],
+ metavar="PATTERN",
+ help="Replacement pattern, where the replacement clause is a path to a file."
+ )
parser.add_option_group(group)
proxy.certificate_option_group(parser)