From 2cb55ee0f5b00c2c3f4f6d9ba9360c31b82b095c Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Sat, 30 Jun 2012 10:51:13 +1200 Subject: [PATCH] Factor out request printing in to a method, and test it. --- libpathod/pathoc.py | 28 ++++++++++++++++++++++++---- libpathod/pathod.py | 2 +- pathoc | 20 ++++++-------------- test/test_pathoc.py | 20 ++++++++++++++++++-- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py index 9320b1c5e..3791c1168 100644 --- a/libpathod/pathoc.py +++ b/libpathod/pathoc.py @@ -1,3 +1,4 @@ +import sys from netlib import tcp, http import rparse @@ -16,16 +17,35 @@ def print_full(fp, httpversion, code, msg, headers, content): class Pathoc(tcp.TCPClient): def __init__(self, host, port): - try: - tcp.TCPClient.__init__(self, host, port) - except tcp.NetLibError, v: - raise PathocError(v) + tcp.TCPClient.__init__(self, host, port) def request(self, spec): """ Return an (httpversion, code, msg, headers, content) tuple. + + May raise rparse.ParseException and netlib.http.HttpError. """ r = rparse.parse_request({}, spec) r.serve(self.wfile) self.wfile.flush() return http.read_response(self.rfile, r.method, None) + + def print_requests(self, reqs, verbose, fp=sys.stdout): + """ + Performs a series of requests, and prints results to the specified + file pointer. + """ + for i in reqs: + try: + ret = self.request(i) + except rparse.ParseException, v: + print >> fp, "Error parsing request spec: %s"%v.msg + print >> fp, v.marked() + return + except http.HttpError, v: + print >> fp, v.msg + return + if verbose: + print_full(fp, *ret) + else: + print_short(fp, *ret) diff --git a/libpathod/pathod.py b/libpathod/pathod.py index 2d3264f86..50e30c452 100644 --- a/libpathod/pathod.py +++ b/libpathod/pathod.py @@ -124,7 +124,7 @@ class Pathod(tcp.TCPServer): def handle_connection(self, request, client_address): h = PathodHandler(request, client_address, self) - h.handle() + h.handle() h.finish() def add_log(self, d): diff --git a/pathoc b/pathoc index 9dc87c030..e5cc9bf47 100755 --- a/pathoc +++ b/pathoc @@ -1,6 +1,7 @@ #!/usr/bin/env python import argparse, sys from libpathod import pathoc, version, rparse +from netlib import tcp if __name__ == "__main__": parser = argparse.ArgumentParser(description='A perverse HTTP client.') @@ -18,21 +19,12 @@ if __name__ == "__main__": else: port = args.port + p = pathoc.Pathoc(args.host, port) try: - p = pathoc.Pathoc(args.host, port) p.connect() - if args.ssl: - p.convert_to_ssl(sni=args.sni) - for i in args.request: - ret = p.request(i) - if args.verbose: - pathoc.print_full(sys.stdout, *ret) - else: - pathoc.print_short(sys.stdout, *ret) - except pathoc.PathocError, v: + except tcp.NetLibError, v: print >> sys.stderr, str(v) sys.exit(1) - except rparse.ParseException, v: - print >> sys.stderr, "Error parsing request spec: %s"%v.msg - print >> sys.stderr, v.marked() - sys.exit(1) + if args.ssl: + p.convert_to_ssl(sni=args.sni) + p.print_requests(args.request, args.verbose) diff --git a/test/test_pathoc.py b/test/test_pathoc.py index c6128e22b..a9c388709 100644 --- a/test/test_pathoc.py +++ b/test/test_pathoc.py @@ -1,9 +1,8 @@ -import json +import json, cStringIO from libpathod import pathoc, test, version import tutils - class TestDaemon: @classmethod def setUpAll(self): @@ -25,3 +24,20 @@ class TestDaemon: _, _, _, _, content = c.request("get:/api/info") assert tuple(json.loads(content)["version"]) == version.IVERSION + def tval(self, requests, verbose=False): + c = pathoc.Pathoc("127.0.0.1", self.d.port) + c.connect() + s = cStringIO.StringIO() + c.print_requests(requests, verbose, s) + return s.getvalue() + + def test_print_requests(self): + reqs = [ "get:/api/info", "get:/api/info" ] + assert self.tval(reqs, False).count("200") == 2 + assert self.tval(reqs, True).count("Date") == 2 + + def test_parse_err(self): + assert "Error parsing" in self.tval(["foo"]) + + def test_conn_err(self): + assert "Invalid server response" in self.tval(["get:'/p/200:d2'"])