From 3f50930dc06a980ac5dcf012fa23ecc0a70ce1b4 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Wed, 31 Oct 2012 11:23:53 +1300 Subject: Use .freeze to implement the -e explain flags for pathod and pathoc. This now prints (in pathoc) or logs (in pathod) a frozen specification that includes an expanded record of all generated values and locations. --- libpathod/language.py | 5 +++-- libpathod/pathoc.py | 6 ++++++ libpathod/pathod.py | 6 +++++- pathoc | 8 +++++++- pathod | 15 +++++++++++++-- test/test_pathoc.py | 4 ++++ test/tutils.py | 3 ++- 7 files changed, 40 insertions(+), 7 deletions(-) diff --git a/libpathod/language.py b/libpathod/language.py index 654dc37e..3c545fb9 100644 --- a/libpathod/language.py +++ b/libpathod/language.py @@ -805,8 +805,9 @@ 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 freeze(self, settings, request_host=None): + r = self.resolve(settings, request_host=None) + return self.__class__([i.freeze(settings) for i in r.tokens]) def __repr__(self): return self.spec() diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py index b4020a3f..dcee353f 100644 --- a/libpathod/pathoc.py +++ b/libpathod/pathoc.py @@ -62,6 +62,9 @@ class Pathoc(tcp.TCPClient): print >> fp, "File access error: %s"%v return + if explain: + r = r.freeze(self.settings, self.host) + resp, req = None, None if showreq: self.wfile.start_log() @@ -83,6 +86,9 @@ class Pathoc(tcp.TCPClient): if req: if ignorecodes and resp and resp[1] in ignorecodes: return + if explain: + print >> fp, ">> Spec:", r.spec() + if showreq: self._show(fp, ">> Request", self.wfile.get_log(), hexdump) diff --git a/libpathod/pathod.py b/libpathod/pathod.py index fb6a7725..bc5a1825 100644 --- a/libpathod/pathod.py +++ b/libpathod/pathod.py @@ -28,6 +28,9 @@ class PathodHandler(tcp.BaseHandler): ) return False, log + if self.server.explain: + crafted = crafted.freeze(self.server.request_settings, None) + print crafted response_log = language.serve(crafted, self.wfile, self.server.request_settings, None) log = dict( type = "crafted", @@ -171,7 +174,7 @@ class Pathod(tcp.TCPServer): def __init__( self, addr, ssloptions=None, craftanchor="/p/", staticdir=None, anchors=None, sizelimit=None, noweb=False, nocraft=False, noapi=False, nohang=False, - timeout=None, logreq=False, logresp=False, hexdump=False + timeout=None, logreq=False, logresp=False, explain=False, hexdump=False ): """ addr: (address, port) tuple. If port is 0, a free port will be @@ -192,6 +195,7 @@ class Pathod(tcp.TCPServer): self.sizelimit = sizelimit self.noweb, self.nocraft, self.noapi, self.nohang = noweb, nocraft, noapi, nohang self.timeout, self.logreq, self.logresp, self.hexdump = timeout, logreq, logresp, hexdump + self.explain = explain if not noapi: app.api() diff --git a/pathoc b/pathoc index c9290587..96cb9f0a 100755 --- a/pathoc +++ b/pathoc @@ -33,7 +33,13 @@ if __name__ == "__main__": 'request', type=str, nargs="+", help='Request specification' ) - group = parser.add_argument_group('Controlling Output') + group = parser.add_argument_group( + 'Controlling Output', + """ + Some of these options expand generated values for logging - if + you're generating large data, use them with caution. + """ + ) group.add_argument( "-C", dest="ignorecodes", type=str, default="", help="Comma-separated list of response codes to ignore" diff --git a/pathod b/pathod index 41b7578d..09facad4 100755 --- a/pathod +++ b/pathod @@ -92,7 +92,8 @@ def main(parser, args): timeout = args.timeout, logreq = args.logreq, logresp = args.logresp, - hexdump = args.hexdump + hexdump = args.hexdump, + explain = args.explain ) except pathod.PathodError, v: parser.error(str(v)) @@ -164,7 +165,17 @@ if __name__ == "__main__": ) - group = parser.add_argument_group('Controlling Output') + group = parser.add_argument_group( + 'Controlling Logging', + """ + Some of these options expand generated values for logging - if + you're generating large data, use them with caution. + """ + ) + group.add_argument( + "-e", dest="explain", action="store_true", default=False, + help="Explain responses" + ) group.add_argument( "-f", dest='logfile', default=None, type=str, help='Log to file.' diff --git a/test/test_pathoc.py b/test/test_pathoc.py index c22fd4f8..ca25be58 100644 --- a/test/test_pathoc.py +++ b/test/test_pathoc.py @@ -65,6 +65,10 @@ class TestDaemon: assert "Invalid headers" in v assert "HTTP/" in v + def test_explain(self): + reqs = [ "get:/p/200:b@100" ] + assert not "b@100" in self.tval(reqs, explain=True) + def test_showreq(self): reqs = [ "get:/api/info:p0,0", "get:/api/info:p0,0" ] assert self.tval(reqs, showreq=True).count("unprintables escaped") == 2 diff --git a/test/tutils.py b/test/tutils.py index a63ed7eb..3de18417 100644 --- a/test/tutils.py +++ b/test/tutils.py @@ -23,7 +23,8 @@ class DaemonTests: timeout = self.timeout, hexdump = self.hexdump, logreq = True, - logresp = True + logresp = True, + explain = True ) @classmethod -- cgit v1.2.3