diff --git a/pathod/language/base.py b/pathod/language/base.py index 3b33c5edc..97871e7e6 100644 --- a/pathod/language/base.py +++ b/pathod/language/base.py @@ -8,7 +8,6 @@ from mitmproxy.utils import human import typing # noqa from . import generators from . import exceptions -from . import message # noqa class Settings: @@ -539,43 +538,3 @@ class IntField(_Component): def spec(self): return "%s%s" % (self.preamble, self.origvalue) - - -class NestedMessage(Token): - - """ - A nested message, as an escaped string with a preamble. - """ - preamble = "" - nest_type = None # type: typing.Optional[typing.Type[message.Message]] - - def __init__(self, value): - Token.__init__(self) - self.value = value - try: - self.parsed = self.nest_type( - self.nest_type.expr().parseString( - value.val.decode(), - parseAll=True - ) - ) - except pp.ParseException as v: - raise exceptions.ParseException(v.msg, v.line, v.col) - - @classmethod - def expr(cls): - e = pp.Literal(cls.preamble).suppress() - e = e + TokValueLiteral.expr() - return e.setParseAction(lambda x: cls(*x)) - - def values(self, settings): - return [ - self.value.get_generator(settings), - ] - - def spec(self): - return "%s%s" % (self.preamble, self.value.spec()) - - def freeze(self, settings): - f = self.parsed.freeze(settings).spec() - return self.__class__(TokValueLiteral(strutils.bytes_to_escaped_str(f.encode(), escape_single_quotes=True))) diff --git a/pathod/language/http.py b/pathod/language/http.py index 1ea55d75a..5a962145d 100644 --- a/pathod/language/http.py +++ b/pathod/language/http.py @@ -253,7 +253,7 @@ class Response(_HTTPMessage): return ":".join([i.spec() for i in self.tokens]) -class NestedResponse(base.NestedMessage): +class NestedResponse(message.NestedMessage): preamble = "s" nest_type = Response diff --git a/pathod/language/http2.py b/pathod/language/http2.py index dc842e594..5b27d5bf9 100644 --- a/pathod/language/http2.py +++ b/pathod/language/http2.py @@ -205,7 +205,7 @@ class Response(_HTTP2Message): return ":".join([i.spec() for i in self.tokens]) -class NestedResponse(base.NestedMessage): +class NestedResponse(message.NestedMessage): preamble = "s" nest_type = Response diff --git a/pathod/language/message.py b/pathod/language/message.py index 6b4c5021a..5dda654b9 100644 --- a/pathod/language/message.py +++ b/pathod/language/message.py @@ -1,8 +1,11 @@ import abc -from . import actions, exceptions -from mitmproxy.utils import strutils import typing # noqa +import pyparsing as pp + +from mitmproxy.utils import strutils +from . import actions, exceptions, base + LOG_TRUNCATE = 1024 @@ -96,3 +99,46 @@ class Message: def __repr__(self): return self.spec() + + +class NestedMessage(base.Token): + """ + A nested message, as an escaped string with a preamble. + """ + preamble = "" + nest_type = None # type: typing.Optional[typing.Type[Message]] + + def __init__(self, value): + super().__init__() + self.value = value + try: + self.parsed = self.nest_type( + self.nest_type.expr().parseString( + value.val.decode(), + parseAll=True + ) + ) + except pp.ParseException as v: + raise exceptions.ParseException(v.msg, v.line, v.col) + + @classmethod + def expr(cls): + e = pp.Literal(cls.preamble).suppress() + e = e + base.TokValueLiteral.expr() + return e.setParseAction(lambda x: cls(*x)) + + def values(self, settings): + return [ + self.value.get_generator(settings), + ] + + def spec(self): + return "%s%s" % (self.preamble, self.value.spec()) + + def freeze(self, settings): + f = self.parsed.freeze(settings).spec() + return self.__class__( + base.TokValueLiteral( + strutils.bytes_to_escaped_str(f.encode(), escape_single_quotes=True) + ) + ) diff --git a/pathod/language/websockets.py b/pathod/language/websockets.py index 681679649..cc00bcf17 100644 --- a/pathod/language/websockets.py +++ b/pathod/language/websockets.py @@ -236,7 +236,7 @@ class WebsocketFrame(message.Message): return ":".join([i.spec() for i in self.tokens]) -class NestedFrame(base.NestedMessage): +class NestedFrame(message.NestedMessage): preamble = "f" nest_type = WebsocketFrame