aboutsummaryrefslogtreecommitdiffstats
path: root/libpathod/language.py
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-10-31 09:32:21 +1300
committerAldo Cortesi <aldo@nullcube.com>2012-10-31 09:32:21 +1300
commit0c9cfb3f381e2c9df5f37dd451b871eac0bdfbd7 (patch)
treef059742726daaa72e290ea9c2cc7e63eebdb4708 /libpathod/language.py
parentf8df0a1e75422e5ffed1c7131d0c017afa227faa (diff)
downloadmitmproxy-0c9cfb3f381e2c9df5f37dd451b871eac0bdfbd7.tar.gz
mitmproxy-0c9cfb3f381e2c9df5f37dd451b871eac0bdfbd7.tar.bz2
mitmproxy-0c9cfb3f381e2c9df5f37dd451b871eac0bdfbd7.zip
Add a .freeze() method to all components.
This expands and freezes all randomly generated values. The message returned can be queried for a precise spec to reproduce the message.
Diffstat (limited to 'libpathod/language.py')
-rw-r--r--libpathod/language.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/libpathod/language.py b/libpathod/language.py
index 706dd6b7..0b49c2de 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -209,6 +209,7 @@ class _Token(object):
"""
return None
+ @abc.abstractmethod
def spec(self): # pragma: no cover
"""
A parseable specification for this token.
@@ -233,6 +234,9 @@ class _ValueLiteral(_Token):
def get_generator(self, settings):
return LiteralGenerator(self.val)
+ def freeze(self, settings):
+ return self
+
class ValueLiteral(_ValueLiteral):
@classmethod
@@ -266,6 +270,10 @@ class ValueGenerate(_Token):
def get_generator(self, settings):
return RandomGenerator(self.datatype, self.bytes())
+ def freeze(self, settings):
+ g = self.get_generator(settings)
+ return ValueLiteral(g[:].encode("string_escape"))
+
@classmethod
def expr(klass):
e = pp.Literal("@").suppress() + v_integer
@@ -297,6 +305,9 @@ class ValueFile(_Token):
e = e + v_naked_literal
return e.setParseAction(lambda x: klass(*x))
+ def freeze(self, settings):
+ return self
+
def get_generator(self, settings):
uf = settings.get("unconstrained_file_access")
sd = settings.get("staticdir")
@@ -353,6 +364,9 @@ class Raw(_Token):
def spec(self):
return "r"
+ def freeze(self, settings):
+ return self
+
class _Component(_Token):
"""
@@ -397,6 +411,9 @@ class Header(_Header):
def spec(self):
return "h%s=%s"%(self.key.spec(), self.value.spec())
+ def freeze(self, settings):
+ return Header(self.key.freeze(settings), self.value.freeze(settings))
+
class ShortcutContentType(_Header):
def __init__(self, value):
@@ -411,6 +428,9 @@ class ShortcutContentType(_Header):
def spec(self):
return "c%s"%(self.value.spec())
+ def freeze(self, settings):
+ return ShortcutContentType(self.value.freeze(settings))
+
class ShortcutLocation(_Header):
def __init__(self, value):
@@ -425,6 +445,9 @@ class ShortcutLocation(_Header):
def spec(self):
return "l%s"%(self.value.spec())
+ def freeze(self, settings):
+ return ShortcutLocation(self.value.freeze(settings))
+
class Body(_Component):
def __init__(self, value):
@@ -444,6 +467,9 @@ class Body(_Component):
def spec(self):
return "b%s"%(self.value.spec())
+ def freeze(self, settings):
+ return Body(self.value.freeze(settings))
+
class Path(_Component):
def __init__(self, value):
@@ -464,6 +490,9 @@ class Path(_Component):
def spec(self):
return "%s"%(self.value.spec())
+ def freeze(self, settings):
+ return Path(self.value.freeze(settings))
+
class Method(_Component):
methods = [
@@ -503,6 +532,9 @@ class Method(_Component):
s = s[1:-1].lower()
return "%s"%s
+ def freeze(self, settings):
+ return Method(self.value.freeze(settings))
+
class Code(_Component):
def __init__(self, code):
@@ -519,6 +551,9 @@ class Code(_Component):
def spec(self):
return "%s"%(self.code)
+ def freeze(self, settings):
+ return Code(self.code)
+
class Reason(_Component):
def __init__(self, value):
@@ -536,6 +571,9 @@ class Reason(_Component):
def spec(self):
return "m%s"%(self.value.spec())
+ def freeze(self, settings):
+ return Reason(self.value.freeze(settings))
+
class _Action(_Token):
"""
@@ -598,6 +636,9 @@ class PauseAt(_Action):
def intermediate(self, settings):
return (self.offset, "pause", self.seconds)
+ def freeze(self, settings):
+ return self
+
class DisconnectAt(_Action):
def __init__(self, offset):
@@ -615,6 +656,9 @@ class DisconnectAt(_Action):
def intermediate(self, settings):
return (self.offset, "disconnect")
+ def freeze(self, settings):
+ return self
+
class InjectAt(_Action):
def __init__(self, offset, value):
@@ -639,6 +683,9 @@ class InjectAt(_Action):
self.value.get_generator(settings)
)
+ def freeze(self, settings):
+ return InjectAt(self.offset, self.value.freeze(settings))
+
class _Message(object):
__metaclass__ = abc.ABCMeta
@@ -758,6 +805,12 @@ class _Message(object):
vals.append(self.body.value.get_generator(settings))
return vals
+ def freeze(self, settings):
+ return self.__class__([i.freeze(settings) for i in self.tokens])
+
+ def __repr__(self):
+ return self.spec()
+
Sep = pp.Optional(pp.Literal(":")).suppress()