aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/app.py21
-rw-r--r--libpathod/cmdline.py4
-rw-r--r--libpathod/language.py9
-rw-r--r--libpathod/pathoc.py15
-rw-r--r--test/test_language.py60
-rw-r--r--test/test_pathoc.py2
6 files changed, 69 insertions, 42 deletions
diff --git a/libpathod/app.py b/libpathod/app.py
index 1a54f712..1910e80e 100644
--- a/libpathod/app.py
+++ b/libpathod/app.py
@@ -4,6 +4,8 @@ import version, language, utils
from netlib import http_uastrings
logging.basicConfig(level="DEBUG")
+
+
def make_app(noapi):
app = Flask(__name__)
@@ -14,20 +16,17 @@ def make_app(noapi):
version = version.IVERSION
)
-
@app.route('/api/log')
def api_log():
return jsonify(
log = app.config["pathod"].get_log()
)
-
@app.route('/api/clear_log')
def api_clear_log():
app.config["pathod"].clear_log()
return "OK"
-
def render(s, cacheable, **kwargs):
kwargs["noapi"] = app.config["pathod"].noapi
kwargs["nocraft"] = app.config["pathod"].nocraft
@@ -37,30 +36,25 @@ def make_app(noapi):
resp.headers["Cache-control"] = "public, max-age=4320"
return resp
-
@app.route('/')
@app.route('/index.html')
def index():
return render("index.html", True, section="main")
-
@app.route('/download')
@app.route('/download.html')
def download():
return render("download.html", True, section="download", version=version.VERSION)
-
@app.route('/about')
@app.route('/about.html')
def about():
return render("about.html", True, section="about")
-
@app.route('/docs/pathod')
def docs_pathod():
return render("docs_pathod.html", True, section="docs", subsection="pathod")
-
@app.route('/docs/language')
def docs_language():
return render(
@@ -69,29 +63,24 @@ def make_app(noapi):
subsection="lang"
)
-
@app.route('/docs/pathoc')
def docs_pathoc():
return render("docs_pathoc.html", True, section="docs", subsection="pathoc")
-
@app.route('/docs/libpathod')
def docs_libpathod():
return render("docs_libpathod.html", True, section="docs", subsection="libpathod")
-
@app.route('/docs/test')
def docs_test():
return render("docs_test.html", True, section="docs", subsection="test")
-
@app.route('/log')
def log():
if app.config["pathod"].noapi:
abort(404)
return render("log.html", False, section="log", log=app.config["pathod"].get_log())
-
@app.route('/log/<int:lid>')
def onelog(lid):
item = app.config["pathod"].log_by_id(int(lid))
@@ -100,7 +89,6 @@ def make_app(noapi):
l = pprint.pformat(item)
return render("onelog.html", False, section="log", alog=l, lid=lid)
-
def _preview(is_request):
if is_request:
template = "request_preview.html"
@@ -121,7 +109,7 @@ def make_app(noapi):
try:
if is_request:
- r = language.parse_request(spec)
+ r = language.parse_requests(spec)[0]
else:
r = language.parse_response(spec)
except language.ParseException, v:
@@ -144,14 +132,11 @@ def make_app(noapi):
args["output"] = utils.escape_unprintables(s.getvalue())
return render(template, False, **args)
-
@app.route('/response_preview')
def response_preview():
return _preview(False)
-
@app.route('/request_preview')
def request_preview():
return _preview(True)
return app
-
diff --git a/libpathod/cmdline.py b/libpathod/cmdline.py
index 1a000a93..affc4015 100644
--- a/libpathod/cmdline.py
+++ b/libpathod/cmdline.py
@@ -155,14 +155,12 @@ def go_pathoc():
data = open(r).read()
r = data
try:
- req = language.parse_request(r)
+ reqs.extend(language.parse_requests(r))
except language.ParseException, v:
print >> sys.stderr, "Error parsing request spec: %s"%v.msg
print >> sys.stderr, v.marked()
sys.exit(1)
- reqs.append(req)
args.request = reqs
-
pathoc.main(args)
diff --git a/libpathod/language.py b/libpathod/language.py
index b4b59167..f40499f6 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -1030,7 +1030,7 @@ def parse_response(s):
raise ParseException(v.msg, v.line, v.col)
-def parse_request(s):
+def parse_requests(s):
"""
May raise ParseException
"""
@@ -1039,6 +1039,11 @@ def parse_request(s):
except UnicodeError:
raise ParseException("Spec must be valid ASCII.", 0, 0)
try:
- return Request(Request.expr().parseString(s, parseAll=True))
+ parts = pp.OneOrMore(
+ pp.Group(
+ Request.expr()
+ )
+ ).parseString(s, parseAll=True)
+ return [Request(i) for i in parts]
except pp.ParseException, v:
raise ParseException(v.msg, v.line, v.col)
diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py
index ae1e98cf..b9b202eb 100644
--- a/libpathod/pathoc.py
+++ b/libpathod/pathoc.py
@@ -18,8 +18,17 @@ class SSLInfo:
class Response:
- def __init__(self, httpversion, status_code, msg, headers, content, sslinfo):
- self.httpversion, self.status_code, self.msg = httpversion, status_code, msg
+ def __init__(
+ self,
+ httpversion,
+ status_code,
+ msg,
+ headers,
+ content,
+ sslinfo
+ ):
+ self.httpversion, self.status_code = httpversion, status_code
+ self.msg = msg
self.headers, self.content = headers, content
self.sslinfo = sslinfo
@@ -91,7 +100,7 @@ class Pathoc(tcp.TCPClient):
May raise language.ParseException, netlib.http.HttpError or
language.FileAccessDenied.
"""
- r = language.parse_request(spec)
+ r = language.parse_requests(spec)[0]
language.serve(r, self.wfile, self.settings, self.address.host)
self.wfile.flush()
ret = list(http.read_response(self.rfile, r.method.string(), None))
diff --git a/test/test_language.py b/test/test_language.py
index 18c68caa..007eb5b7 100644
--- a/test/test_language.py
+++ b/test/test_language.py
@@ -6,6 +6,10 @@ import tutils
language.TESTING = True
+def parse_request(s):
+ return language.parse_requests(s)[0]
+
+
class TestValueNakedLiteral:
def test_expr(self):
v = language.ValueNakedLiteral("foo")
@@ -302,8 +306,8 @@ class TestHeaders:
assert language.parse_response("400:c'foo'").headers[0].key.val == "Content-Type"
assert language.parse_response("400:l'foo'").headers[0].key.val == "Location"
- assert 'Android' in language.parse_request("get:/:ua").headers[0].value.val
- assert language.parse_request("get:/:ua").headers[0].key.val == "User-Agent"
+ assert 'Android' in parse_request("get:/:ua").headers[0].value.val
+ assert parse_request("get:/:ua").headers[0].key.val == "User-Agent"
class TestShortcutUserAgent:
@@ -337,7 +341,7 @@ class Test_Action:
assert l[0].offset == 0
def test_resolve(self):
- r = language.parse_request('GET:"/foo"')
+ r = parse_request('GET:"/foo"')
e = language.DisconnectAt("r")
ret = e.resolve(r, {})
assert isinstance(ret.offset, int)
@@ -446,23 +450,49 @@ class TestPauses:
class TestRequest:
def test_nonascii(self):
- tutils.raises("ascii", language.parse_request, "get:\xf0")
+ tutils.raises("ascii", parse_request, "get:\xf0")
def test_err(self):
- tutils.raises(language.ParseException, language.parse_request, 'GET')
+ tutils.raises(language.ParseException, parse_request, 'GET')
def test_simple(self):
- r = language.parse_request('GET:"/foo"')
+ r = parse_request('GET:"/foo"')
assert r.method.string() == "GET"
assert r.path.string() == "/foo"
- r = language.parse_request('GET:/foo')
+ r = parse_request('GET:/foo')
assert r.path.string() == "/foo"
- r = language.parse_request('GET:@1k')
+ r = parse_request('GET:@1k')
assert len(r.path.string()) == 1024
+ def test_multi(self):
+ r = language.parse_requests("GET:/ PUT:/")
+ assert r[0].method.string() == "GET"
+ assert r[1].method.string() == "PUT"
+ assert len(r) == 2
+
+ l = """
+ GET
+ "/foo"
+ ir,@1
+
+ PUT
+
+ "/foo
+
+
+
+ bar"
+
+ ir,@1
+ """
+ r = language.parse_requests(l)
+ assert len(r) == 2
+ assert r[0].method.string() == "GET"
+ assert r[1].method.string() == "PUT"
+
def test_render(self):
s = cStringIO.StringIO()
- r = language.parse_request("GET:'/foo'")
+ r = parse_request("GET:'/foo'")
assert language.serve(r, s, {}, "foo.com")
def test_multiline(self):
@@ -471,7 +501,7 @@ class TestRequest:
"/foo"
ir,@1
"""
- r = language.parse_request(l)
+ r = parse_request(l)
assert r.method.string() == "GET"
assert r.path.string() == "/foo"
assert r.actions
@@ -487,24 +517,24 @@ class TestRequest:
ir,@1
"""
- r = language.parse_request(l)
+ r = parse_request(l)
assert r.method.string() == "GET"
assert r.path.string().endswith("bar")
assert r.actions
def test_spec(self):
def rt(s):
- s = language.parse_request(s).spec()
- assert language.parse_request(s).spec() == s
+ s = parse_request(s).spec()
+ assert parse_request(s).spec() == s
rt("get:/foo")
rt("get:/foo:da")
def test_freeze(self):
- r = language.parse_request("GET:/:b@100").freeze({})
+ r = parse_request("GET:/:b@100").freeze({})
assert len(r.spec()) > 100
def test_path_generator(self):
- r = language.parse_request("GET:@100").freeze({})
+ r = parse_request("GET:@100").freeze({})
assert len(r.spec()) > 100
diff --git a/test/test_pathoc.py b/test/test_pathoc.py
index 88479b6c..2542b622 100644
--- a/test/test_pathoc.py
+++ b/test/test_pathoc.py
@@ -60,7 +60,7 @@ class _TestDaemon:
s = cStringIO.StringIO()
for i in requests:
c.print_request(
- language.parse_request(i),
+ language.parse_requests(i)[0],
showreq = showreq,
showresp = showresp,
explain = explain,