aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2012-04-29 14:20:27 +1200
committerAldo Cortesi <aldo@nullcube.com>2012-04-29 14:20:27 +1200
commit6d4500c67943d03cf0910256ef9dab46789f366f (patch)
tree7d2d68047e6241c081560a042d4dcdeaae0dbffe
parentf03ce8107075567ea902b88ace2964ee035d45aa (diff)
downloadmitmproxy-6d4500c67943d03cf0910256ef9dab46789f366f.tar.gz
mitmproxy-6d4500c67943d03cf0910256ef9dab46789f366f.tar.bz2
mitmproxy-6d4500c67943d03cf0910256ef9dab46789f366f.zip
Regularize language even further
- Unify offset specifcation syntax, so there's now oly one form for specify pauses and disconnects. - Use @ instead of ! for content generation. Mildy more convenient in the shell.
-rw-r--r--libpathod/rparse.py93
-rw-r--r--notes23
-rw-r--r--test/test_rparse.py103
-rw-r--r--todo18
4 files changed, 116 insertions, 121 deletions
diff --git a/libpathod/rparse.py b/libpathod/rparse.py
index b47681cc..de69e9b9 100644
--- a/libpathod/rparse.py
+++ b/libpathod/rparse.py
@@ -146,18 +146,18 @@ class ValueGenerate:
@classmethod
def expr(klass):
- e = pp.Literal("!").suppress() + v_integer
+ e = pp.Literal("@").suppress() + v_integer
u = reduce(operator.or_, [pp.Literal(i) for i in klass.UNITS.keys()])
e = e + pp.Optional(u, default=None)
- s = pp.Literal("-").suppress()
+ s = pp.Literal(",").suppress()
s += reduce(operator.or_, [pp.Literal(i) for i in DATATYPES.keys()])
e += pp.Optional(s, default="bytes")
return e.setParseAction(lambda x: klass(*x))
def __str__(self):
- return "!%s%s-%s"%(self.usize, self.unit, self.datatype)
+ return "@%s%s,%s"%(self.usize, self.unit, self.datatype)
class ValueFile:
@@ -245,60 +245,50 @@ class Body:
return e.setParseAction(lambda x: klass(*x))
-class _Pause:
- def __init__(self, value):
- self.value = value
+class PauseAt:
+ def __init__(self, seconds, offset):
+ self.seconds, self.offset = seconds, offset
@classmethod
def expr(klass):
- e = pp.Literal("p%s"%klass.sub).suppress()
- e = e + pp.MatchFirst(
+ e = pp.Literal("p").suppress()
+ e +=pp.MatchFirst(
+ [
+ v_integer,
+ pp.Literal("f")
+ ]
+ )
+ e += pp.Literal(",").suppress()
+ e += pp.MatchFirst(
[
v_integer,
- pp.Literal("forever")
+ pp.Literal("r"),
+ pp.Literal("a"),
]
)
return e.setParseAction(lambda x: klass(*x))
-
-class PauseBefore(_Pause):
- sub = "b"
- def mod_response(self, settings, r):
- r.actions.append((0, "pause", self.value))
-
-
-class PauseAfter(_Pause):
- sub = "a"
- def mod_response(self, settings, r):
- r.actions.append((sys.maxint, "pause", self.value))
-
-
-class PauseRandom(_Pause):
- sub = "r"
def mod_response(self, settings, r):
- r.actions.append(("random", "pause", self.value))
+ r.actions.append((self.offset, "pause", self.seconds))
-class _Disconnect:
+class DisconnectAt:
def __init__(self, value):
self.value = value
- @classmethod
- def expr(klass):
- e = pp.Literal("d%s"%klass.sub)
- return e.setParseAction(klass)
-
-
-class DisconnectBefore(_Disconnect):
- sub = "b"
def mod_response(self, settings, r):
- r.actions.append((0, "disconnect"))
+ r.actions.append((self.value, "disconnect"))
-
-class DisconnectRandom(_Disconnect):
- sub = "r"
- def mod_response(self, settings, r):
- r.actions.append(("random", "disconnect"))
+ @classmethod
+ def expr(klass):
+ e = pp.Literal("d").suppress()
+ e = e + pp.MatchFirst(
+ [
+ v_integer,
+ pp.Literal("r")
+ ]
+ )
+ return e.setParseAction(lambda x: klass(*x))
class Header:
@@ -346,11 +336,8 @@ class Response:
comps = (
Body,
Header,
- PauseBefore,
- PauseAfter,
- PauseRandom,
- DisconnectBefore,
- DisconnectRandom,
+ PauseAt,
+ DisconnectAt,
ShortcutContentType,
ShortcutLocation,
)
@@ -391,13 +378,15 @@ class Response:
l += len(self.body)
return l
- def ready_randoms(self, l, lst):
+ def ready_actions(self, l, lst):
ret = []
- for k, v in lst:
- if k == "random":
- ret.append((random.randrange(l), v))
- else:
- ret.append((k, v))
+ for i in lst:
+ itms = list(i)
+ if i[0] == "r":
+ itms[0] = random.randrange(l)
+ if i[0] == "a":
+ itms[0] = l+1
+ ret.append(tuple(itms))
ret.sort()
return ret
@@ -469,7 +458,7 @@ class Response:
self.body
])
vals.reverse()
- actions = self.ready_randoms(self.length(), self.actions)
+ actions = self.ready_actions(self.length(), self.actions)
actions.reverse()
return self.write_values(fp, vals, actions)
diff --git a/notes b/notes
index 3d3d9f34..632c5064 100644
--- a/notes
+++ b/notes
@@ -6,21 +6,18 @@ Response:
Features:
- hVALUE=VALUE Set header
- bVALUE Set body
- db Disconnect before sending data
- dr Disconnect randomly
- pbNUM|forever Pause before sending data for NUM seconds or forever
- paNUM|forever Pause after sending all data for NUM seconds or forever
- prNUM|forever Pause randomly for NUM seconds or forever
- cVALUE Set Content-Type header
- lVALUE Set Location header
+ hVALUE=VALUE Set header
+ bVALUE Set body
+ cVALUE Set Content-Type header
+ lVALUE Set Location header
+ dOFF|r Disconnect after OFF bytes, measured from the beginning of the response.
+ pNUM|f,OFF|r|a Pause for NUM seconds after OFF bytes.
Value Specifiers:
- !500k - 500k of random data
- !500k-utf8 - 500k of utf8. Other specifiers: utf8,alphanum,alpha,printable
+ @500k - 500k of random data
+ @500k,utf8 - 500k of utf8. Other specifiers: utf8,alphanum,alpha,printable
"foo" - literal
<path - load from path under data directory
<"path" - load from path under data directory
@@ -28,8 +25,8 @@ Value Specifiers:
Examples:
200:b500k
- 404:pb5:b1k-printable
- 200:t"text/json":pr5,b1k
+ 404:pb5:b1k,printable
+ 200:t"text/json":pr5:b1k
200:b1k:xr
diff --git a/test/test_rparse.py b/test/test_rparse.py
index c854b0c6..67fac11e 100644
--- a/test/test_rparse.py
+++ b/test/test_rparse.py
@@ -82,23 +82,23 @@ class uMisc(libpry.AutoTree):
libpry.raises("no static directory", v.get_generator, dict())
def test_generated_value(self):
- v = rparse.Value.parseString("!10b")[0]
+ v = rparse.Value.parseString("@10b")[0]
assert v.usize == 10
assert v.unit == "b"
assert v.bytes() == 10
- v = rparse.Value.parseString("!10")[0]
+ v = rparse.Value.parseString("@10")[0]
assert v.unit == "b"
- v = rparse.Value.parseString("!10k")[0]
+ v = rparse.Value.parseString("@10k")[0]
assert v.bytes() == 10240
- v = rparse.Value.parseString("!10g")[0]
+ v = rparse.Value.parseString("@10g")[0]
assert v.bytes() == 1024**3 * 10
- v = rparse.Value.parseString("!10g-digits")[0]
+ v = rparse.Value.parseString("@10g,digits")[0]
assert v.datatype == "digits"
g = v.get_generator({})
assert g[:100]
- v = rparse.Value.parseString("!10-digits")[0]
+ v = rparse.Value.parseString("@10,digits")[0]
assert v.unit == "b"
assert v.datatype == "digits"
@@ -112,12 +112,12 @@ class uMisc(libpry.AutoTree):
v = e.parseString("b'foo'")[0]
assert v.value.val == "foo"
- v = e.parseString("b!100")[0]
- assert str(v.value) == "!100b-bytes"
+ v = e.parseString("b@100")[0]
+ assert str(v.value) == "@100b,bytes"
- v = e.parseString("b!100g-digits", parseAll=True)[0]
+ v = e.parseString("b@100g,digits", parseAll=True)[0]
assert v.value.datatype == "digits"
- assert str(v.value) == "!100g-digits"
+ assert str(v.value) == "@100g,digits"
def test_header(self):
e = rparse.Header.expr()
@@ -157,24 +157,21 @@ class uMisc(libpry.AutoTree):
class uDisconnects(libpry.AutoTree):
def test_parse(self):
- assert (0, "disconnect") in rparse.parse({}, "400:db").actions
- assert ("random", "disconnect") in rparse.parse({}, "400:dr").actions
+ assert (0, "disconnect") in rparse.parse({}, "400:d0").actions
+ assert ("r", "disconnect") in rparse.parse({}, "400:dr").actions
- def test_before(self):
- e = rparse.DisconnectBefore.expr()
- v = e.parseString("db")[0]
- assert isinstance(v, rparse.DisconnectBefore)
+ def test_at(self):
+ e = rparse.DisconnectAt.expr()
+ v = e.parseString("d0")[0]
+ assert isinstance(v, rparse.DisconnectAt)
+ assert v.value == 0
- v = e.parseString("db")[0]
- assert isinstance(v, rparse.DisconnectBefore)
+ v = e.parseString("d100")[0]
+ assert v.value == 100
- def test_random(self):
- e = rparse.DisconnectRandom.expr()
+ e = rparse.DisconnectAt.expr()
v = e.parseString("dr")[0]
- assert isinstance(v, rparse.DisconnectRandom)
-
- v = e.parseString("dr")[0]
- assert isinstance(v, rparse.DisconnectRandom)
+ assert v.value == "r"
class uShortcuts(libpry.AutoTree):
@@ -184,27 +181,27 @@ class uShortcuts(libpry.AutoTree):
class uPauses(libpry.AutoTree):
- def test_before(self):
- e = rparse.PauseBefore.expr()
- v = e.parseString("pb10")[0]
- assert v.value == 10
+ def test_parse(self):
+ e = rparse.PauseAt.expr()
+ v = e.parseString("p10,10")[0]
+ assert v.seconds == 10
+ assert v.offset == 10
- v = e.parseString("pbforever")[0]
- assert v.value == "forever"
+ v = e.parseString("pf,10")[0]
+ assert v.seconds == "f"
- def test_after(self):
- e = rparse.PauseAfter.expr()
- v = e.parseString("pa10")[0]
- assert v.value == 10
+ v = e.parseString("pf,r")[0]
+ assert v.offset == "r"
- def test_random(self):
- e = rparse.PauseRandom.expr()
- v = e.parseString("pr10")[0]
- assert v.value == 10
+ v = e.parseString("pf,a")[0]
+ assert v.offset == "a"
+ def test_request(self):
+ r = rparse.parse({}, '400:p10,10')
+ assert r.actions[0] == (10, "pause", 10)
-class uparse(libpry.AutoTree):
+class uparse(libpry.AutoTree):
def test_parse_err(self):
libpry.raises(rparse.ParseException, rparse.parse, {}, "400:msg,b:")
try:
@@ -218,16 +215,16 @@ class uparse(libpry.AutoTree):
assert r.get_header("foo") == "bar"
def test_parse_pause_before(self):
- r = rparse.parse({}, "400:pb10")
+ r = rparse.parse({}, "400:p10,0")
assert (0, "pause", 10) in r.actions
def test_parse_pause_after(self):
- r = rparse.parse({}, "400:pa10")
- assert (sys.maxint, "pause", 10) in r.actions
+ r = rparse.parse({}, "400:p10,a")
+ assert ("a", "pause", 10) in r.actions
def test_parse_pause_random(self):
- r = rparse.parse({}, "400:pr10")
- assert ("random", "pause", 10) in r.actions
+ r = rparse.parse({}, "400:p10,r")
+ assert ("r", "pause", 10) in r.actions
class uResponse(libpry.AutoTree):
@@ -239,23 +236,27 @@ class uResponse(libpry.AutoTree):
assert r.code == 400
assert r.msg == "msg"
- r = rparse.parse({}, "400'msg':b!100b")
+ r = rparse.parse({}, "400'msg':b@100b")
assert r.msg == "msg"
assert r.body[:]
assert str(r)
- def test_ready_randoms(self):
+ def test_ready_actions(self):
r = rparse.parse({}, "400'msg'")
x = [(0, 5)]
- assert r.ready_randoms(100, x) == x
+ assert r.ready_actions(100, x) == x
- x = [("random", 5)]
- ret = r.ready_randoms(100, x)
+ x = [("r", 5)]
+ ret = r.ready_actions(100, x)
assert 0 <= ret[0][0] < 100
+ x = [("a", "pause", 5)]
+ ret = r.ready_actions(100, x)
+ assert ret[0][0] > 100
+
x = [(1, 5), (0, 5)]
- assert r.ready_randoms(100, x) == sorted(x)
+ assert r.ready_actions(100, x) == sorted(x)
def test_write_values_disconnects(self):
r = self.dummy_response()
@@ -304,7 +305,7 @@ class uResponse(libpry.AutoTree):
assert x.length() == len(s.getvalue())
testlen(rparse.parse({}, "400'msg'"))
testlen(rparse.parse({}, "400'msg':h'foo'='bar'"))
- testlen(rparse.parse({}, "400'msg':h'foo'='bar':b!100b"))
+ testlen(rparse.parse({}, "400'msg':h'foo'='bar':b@100b"))
tests = [
diff --git a/todo b/todo
index 28e64b55..112aed22 100644
--- a/todo
+++ b/todo
@@ -1,5 +1,13 @@
-- Disconnect or pause at specified byte offset
-- Logs
-- API
- - Logs, log reset, log retrieval
- - Anchor management
+
+0.1:
+ - Disconnect or pause at specified byte offset
+ - Logs
+ - API
+ - Logs, log reset, log retrieval
+ - Anchor management
+
+0.2:
+ - Shortcuts for cookies, auth
+ - Various SSL errors (expired certs, etc.)
+ - Caching
+