pathoc: add a flag to dump request information.

This commit is contained in:
Aldo Cortesi 2012-07-21 20:20:37 +12:00
parent 059a232903
commit 86fe199988
5 changed files with 40 additions and 17 deletions

View File

@ -6,11 +6,11 @@ class PathocError(Exception): pass
def print_short(fp, httpversion, code, msg, headers, content): def print_short(fp, httpversion, code, msg, headers, content):
print >> fp, "%s %s: %s bytes"%(code, msg, len(content)) print >> fp, "<< %s %s: %s bytes"%(code, msg, len(content))
def print_full(fp, httpversion, code, msg, headers, content): def print_full(fp, httpversion, code, msg, headers, content):
print >> fp, "HTTP%s/%s %s %s"%(httpversion[0], httpversion[1], code, msg) print >> fp, "<< HTTP%s/%s %s %s"%(httpversion[0], httpversion[1], code, msg)
print >> fp, headers print >> fp, headers
print >> fp, content print >> fp, content
@ -26,18 +26,28 @@ class Pathoc(tcp.TCPClient):
May raise rparse.ParseException and netlib.http.HttpError. May raise rparse.ParseException and netlib.http.HttpError.
""" """
r = rparse.parse_request({}, spec) r = rparse.parse_request({}, spec)
r.serve(self.wfile) ret = r.serve(self.wfile)
self.wfile.flush() self.wfile.flush()
return http.read_response(self.rfile, r.method, None) return http.read_response(self.rfile, r.method, None)
def print_requests(self, reqs, verbose, fp=sys.stdout): def print_requests(self, reqs, respdump, reqdump, fp=sys.stdout):
""" """
Performs a series of requests, and prints results to the specified Performs a series of requests, and prints results to the specified
file pointer. file pointer.
""" """
for i in reqs: for i in reqs:
try: try:
ret = self.request(i) r = rparse.parse_request({}, i)
req = r.serve(self.wfile)
if reqdump:
print >> fp, ">>", req["method"], req["path"]
for a in req["actions"]:
print >> fp, "\t",
for x in a:
print x,
print
self.wfile.flush()
resp = self.request(i)
except rparse.ParseException, v: except rparse.ParseException, v:
print >> fp, "Error parsing request spec: %s"%v.msg print >> fp, "Error parsing request spec: %s"%v.msg
print >> fp, v.marked() print >> fp, v.marked()
@ -48,7 +58,7 @@ class Pathoc(tcp.TCPClient):
except tcp.NetLibTimeout: except tcp.NetLibTimeout:
print >> fp, "Timeout" print >> fp, "Timeout"
else: else:
if verbose: if respdump:
print_full(fp, *ret) print_full(fp, *resp)
else: else:
print_short(fp, *ret) print_short(fp, *resp)

View File

@ -130,21 +130,28 @@ class LiteralGenerator:
def __getslice__(self, a, b): def __getslice__(self, a, b):
return self.s.__getslice__(a, b) return self.s.__getslice__(a, b)
def __repr__(self):
return '"%s"'%self.s
class RandomGenerator: class RandomGenerator:
def __init__(self, chars, length): def __init__(self, dtype, length):
self.chars = chars self.dtype = dtype
self.length = length self.length = length
def __len__(self): def __len__(self):
return self.length return self.length
def __getitem__(self, x): def __getitem__(self, x):
return random.choice(self.chars) return random.choice(DATATYPES[self.dtype])
def __getslice__(self, a, b): def __getslice__(self, a, b):
b = min(b, self.length) b = min(b, self.length)
return "".join(random.choice(self.chars) for x in range(a, b)) chars = DATATYPES[self.dtype]
return "".join(random.choice(chars) for x in range(a, b))
def __repr__(self):
return "%s random from %s"%(self.length, self.dtype)
class FileGenerator: class FileGenerator:
@ -205,7 +212,7 @@ class ValueGenerate:
return self.usize * self.UNITS[self.unit] return self.usize * self.UNITS[self.unit]
def get_generator(self, settings): def get_generator(self, settings):
return RandomGenerator(DATATYPES[self.datatype], self.bytes()) return RandomGenerator(self.datatype, self.bytes())
@classmethod @classmethod
def expr(klass): def expr(klass):

6
pathoc
View File

@ -17,6 +17,10 @@ if __name__ == "__main__":
"-p", dest="port", type=int, default=None, "-p", dest="port", type=int, default=None,
help="Port. Defaults to 80, or 443 if SSL is active." help="Port. Defaults to 80, or 443 if SSL is active."
) )
parser.add_argument(
"-d", dest="reqdump", action="store_true", default=False,
help="Print request record before each response."
)
parser.add_argument( parser.add_argument(
"-s", dest="ssl", action="store_true", default=False, "-s", dest="ssl", action="store_true", default=False,
help="Connect with SSL." help="Connect with SSL."
@ -56,4 +60,4 @@ if __name__ == "__main__":
p.convert_to_ssl(sni=args.sni) p.convert_to_ssl(sni=args.sni)
if args.timeout: if args.timeout:
p.settimeout(args.timeout) p.settimeout(args.timeout)
p.print_requests(args.request, args.verbose) p.print_requests(args.request, args.verbose, args.reqdump)

View File

@ -28,11 +28,11 @@ class TestDaemon:
c = pathoc.Pathoc("127.0.0.1", self.d.port) c = pathoc.Pathoc("127.0.0.1", self.d.port)
c.connect() c.connect()
s = cStringIO.StringIO() s = cStringIO.StringIO()
c.print_requests(requests, verbose, s) c.print_requests(requests, verbose, True, s)
return s.getvalue() return s.getvalue()
def test_print_requests(self): def test_print_requests(self):
reqs = [ "get:/api/info", "get:/api/info" ] reqs = [ "get:/api/info:p0,0", "get:/api/info:p0,0" ]
assert self.tval(reqs, False).count("200") == 2 assert self.tval(reqs, False).count("200") == 2
assert self.tval(reqs, True).count("Date") == 2 assert self.tval(reqs, True).count("Date") == 2

View File

@ -12,7 +12,8 @@ class TestMisc:
assert g[:] == "val" assert g[:] == "val"
def test_randomgenerator(self): def test_randomgenerator(self):
g = rparse.RandomGenerator("one", 100) g = rparse.RandomGenerator("bytes", 100)
assert repr(g)
assert len(g[:10]) == 10 assert len(g[:10]) == 10
assert len(g[1:10]) == 9 assert len(g[1:10]) == 9
assert len(g[:1000]) == 100 assert len(g[:1000]) == 100
@ -21,6 +22,7 @@ class TestMisc:
def test_literalgenerator(self): def test_literalgenerator(self):
g = rparse.LiteralGenerator("one") g = rparse.LiteralGenerator("one")
assert repr(g)
assert g == "one" assert g == "one"
assert g[:] == "one" assert g[:] == "one"
assert g[1] == "n" assert g[1] == "n"