diff options
| author | Aldo Cortesi <aldo@nullcube.com> | 2015-05-02 21:42:09 +1200 | 
|---|---|---|
| committer | Aldo Cortesi <aldo@nullcube.com> | 2015-05-02 21:42:09 +1200 | 
| commit | fffee660e57e1f8be19ae6ffa979c48cfc6cef9e (patch) | |
| tree | 9ef11b3433c63f399e3d587cecf920190971b779 | |
| parent | 0ffd14372af9c4ad3042a7e166e40076183de583 (diff) | |
| download | mitmproxy-fffee660e57e1f8be19ae6ffa979c48cfc6cef9e.tar.gz mitmproxy-fffee660e57e1f8be19ae6ffa979c48cfc6cef9e.tar.bz2 mitmproxy-fffee660e57e1f8be19ae6ffa979c48cfc6cef9e.zip | |
language: create and use Integer and PreValue generics
| -rw-r--r-- | libpathod/language/base.py | 53 | ||||
| -rw-r--r-- | libpathod/language/http.py | 40 | ||||
| -rw-r--r-- | libpathod/language/websockets.py | 10 | ||||
| -rw-r--r-- | test/test_language_base.py | 41 | 
4 files changed, 65 insertions, 79 deletions
| diff --git a/libpathod/language/base.py b/libpathod/language/base.py index f6530d75..4e1900a7 100644 --- a/libpathod/language/base.py +++ b/libpathod/language/base.py @@ -11,6 +11,9 @@ from . import generators, exceptions  TRUNCATE = 1024 +Sep = pp.Optional(pp.Literal(":")).suppress() + +  v_integer = pp.Word(pp.nums)\      .setName("integer")\      .setParseAction(lambda toks: int(toks[0])) @@ -318,28 +321,6 @@ class ShortcutUserAgent(_Header):          return ShortcutUserAgent(self.value.freeze(settings)) -class Body(_Component): -    def __init__(self, value): -        self.value = value - -    @classmethod -    def expr(klass): -        e = pp.Literal("b").suppress() -        e = e + Value -        return e.setParseAction(lambda x: klass(*x)) - -    def values(self, settings): -        return [ -            self.value.get_generator(settings), -        ] - -    def spec(self): -        return "b%s"%(self.value.spec()) - -    def freeze(self, settings): -        return Body(self.value.freeze(settings)) - -  class PathodSpec(_Token):      def __init__(self, value):          self.value = value @@ -457,9 +438,9 @@ class OptionsOrValue(_Component):          return self.__class__(self.value.freeze(settings)) -class Code(_Component): -    def __init__(self, code): -        self.code = str(code) +class Integer(_Component): +    def __init__(self, value): +        self.value = str(value)      @classmethod      def expr(klass): @@ -467,22 +448,25 @@ class Code(_Component):          return e.setParseAction(lambda x: klass(*x))      def values(self, settings): -        return [generators.LiteralGenerator(self.code)] +        return [generators.LiteralGenerator(self.value)]      def spec(self): -        return "%s"%(self.code) +        return "%s"%(self.value)      def freeze(self, settings):          return self -class Reason(_Component): +class PreValue(_Component): +    """ +        A value lead by self.preamble. +    """      def __init__(self, value):          self.value = value      @classmethod      def expr(klass): -        e = pp.Literal("m").suppress() +        e = pp.Literal(klass.preamble).suppress()          e = e + Value          return e.setParseAction(lambda x: klass(*x)) @@ -490,10 +474,10 @@ class Reason(_Component):          return [self.value.get_generator(settings)]      def spec(self): -        return "m%s"%(self.value.spec()) +        return "%s%s"%(self.preamble, self.value.spec())      def freeze(self, settings): -        return Reason(self.value.freeze(settings)) +        return self.__class__(self.value.freeze(settings))  class _Action(_Token): @@ -634,10 +618,6 @@ class _Message(object):          return self.toks(_Action)      @property -    def body(self): -        return self.tok(Body) - -    @property      def headers(self):          return self.toks(_Header) @@ -695,6 +675,3 @@ class _Message(object):      def __repr__(self):          return self.spec() - - -Sep = pp.Optional(pp.Literal(":")).suppress() diff --git a/libpathod/language/http.py b/libpathod/language/http.py index 7966b914..30a5fd9f 100644 --- a/libpathod/language/http.py +++ b/libpathod/language/http.py @@ -20,6 +20,18 @@ class Path(base.SimpleValue):      pass +class Code(base.Integer): +    pass + + +class Reason(base.PreValue): +    preamble = "m" + + +class Body(base.PreValue): +    preamble = "b" + +  class Method(base.OptionsOrValue):      options = [          "get", @@ -47,10 +59,14 @@ def get_header(val, headers):  class _HTTPMessage(base._Message):      version = "HTTP/1.1" +      @property      def raw(self):          return bool(self.tok(Raw)) +    @property +    def body(self): +        return self.tok(Body)      @abc.abstractmethod      def preamble(self, settings): # pragma: no cover @@ -69,7 +85,7 @@ class _HTTPMessage(base._Message):  class Response(_HTTPMessage):      comps = ( -        base.Body, +        Body,          base.Header,          base.PauseAt,          base.DisconnectAt, @@ -77,7 +93,7 @@ class Response(_HTTPMessage):          base.ShortcutContentType,          base.ShortcutLocation,          Raw, -        base.Reason +        Reason      )      logattrs = ["code", "reason", "version", "body"] @@ -87,16 +103,16 @@ class Response(_HTTPMessage):      @property      def code(self): -        return self.tok(base.Code) +        return self.tok(Code)      @property      def reason(self): -        return self.tok(base.Reason) +        return self.tok(Reason)      def preamble(self, settings):          l = [self.version, " "]          l.extend(self.code.values(settings)) -        code = int(self.code.code) +        code = int(self.code.value)          l.append(" ")          if self.reason:              l.extend(self.reason.values(settings)) @@ -121,7 +137,7 @@ class Response(_HTTPMessage):              if not self.code:                  tokens.insert(                      1, -                    base.Code(101) +                    Code(101)                  )              hdrs = netlib.websockets.server_handshake_headers(                  settings.websocket_key @@ -159,9 +175,9 @@ class Response(_HTTPMessage):                  pp.MatchFirst(                      [                          WS.expr() + pp.Optional( -                            base.Sep + base.Code.expr() +                            base.Sep + Code.expr()                          ), -                        base.Code.expr(), +                        Code.expr(),                      ]                  ),                  pp.ZeroOrMore(base.Sep + atom) @@ -176,7 +192,7 @@ class Response(_HTTPMessage):  class Request(_HTTPMessage):      comps = ( -        base.Body, +        Body,          base.Header,          base.PauseAt,          base.DisconnectAt, @@ -285,12 +301,12 @@ class PathodErrorResponse(Response):  def make_error_response(reason, body=None):      tokens = [ -        base.Code("800"), +        Code("800"),          base.Header(              base.ValueLiteral("Content-Type"),              base.ValueLiteral("text/plain")          ), -        base.Reason(base.ValueLiteral(reason)), -        base.Body(base.ValueLiteral("pathod error: " + (body or reason))), +        Reason(base.ValueLiteral(reason)), +        Body(base.ValueLiteral("pathod error: " + (body or reason))),      ]      return PathodErrorResponse(tokens) diff --git a/libpathod/language/websockets.py b/libpathod/language/websockets.py index 7ec4a2b1..b666b2fe 100644 --- a/libpathod/language/websockets.py +++ b/libpathod/language/websockets.py @@ -17,15 +17,23 @@ class WF(base.CaselessLiteral):      TOK = "wf" +class Body(base.PreValue): +    preamble = "b" + +  class WebsocketFrame(base._Message):      comps = ( -        base.Body, +        Body,          base.PauseAt,          base.DisconnectAt,          base.InjectAt      )      logattrs = ["body"] +    @property +    def body(self): +        return self.tok(Body) +      @classmethod      def expr(klass):          parts = [i.expr() for i in klass.comps] diff --git a/test/test_language_base.py b/test/test_language_base.py index 10f11d42..e4458021 100644 --- a/test/test_language_base.py +++ b/test/test_language_base.py @@ -183,24 +183,6 @@ class TestMisc:          s = v.spec()          assert s == v.expr().parseString(s)[0].spec() -    def test_body(self): -        e = base.Body.expr() -        v = e.parseString("b'foo'")[0] -        assert v.value.val == "foo" - -        v = e.parseString("b@100")[0] -        assert str(v.value) == "@100" -        v2 = v.freeze({}) -        v3 = v2.freeze({}) -        assert v2.value.val == v3.value.val - -        v = e.parseString("b@100g,digits", parseAll=True)[0] -        assert v.value.datatype == "digits" -        assert str(v.value) == "@100g,digits" - -        s = v.spec() -        assert s == e.parseString(s)[0].spec() -      def test_pathodspec(self):          e = base.PathodSpec.expr()          v = e.parseString("s'200'")[0] @@ -227,16 +209,10 @@ class TestMisc:          assert e.freeze({})          assert e.values({}) -    def test_code(self): -        e = base.Code.expr() -        v = e.parseString("200")[0] -        assert v.string() == "200" -        assert v.spec() == "200" - -        assert v.freeze({}).code == v.code - -    def test_reason(self): -        e = base.Reason.expr() +    def test_value(self): +        class TT(base.PreValue): +            preamble = "m" +        e = TT.expr()          v = e.parseString("m'msg'")[0]          assert v.value.val == "msg" @@ -472,3 +448,12 @@ def test_options_or_value():      v2 = v.freeze({})      v3 = v2.freeze({})      assert v2.value.val == v3.value.val + + +def test_integer(): +    e = base.Integer.expr() +    v = e.parseString("200")[0] +    assert v.string() == "200" +    assert v.spec() == "200" + +    assert v.freeze({}).value == v.value | 
