aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpathod/app.py4
-rw-r--r--libpathod/cmdline.py33
-rw-r--r--libpathod/language.py8
-rw-r--r--libpathod/pathoc.py4
-rw-r--r--libpathod/pathod.py6
-rw-r--r--libpathod/templates/docs_lang.html8
-rw-r--r--test/test_language.py112
-rw-r--r--test/test_pathoc.py5
8 files changed, 88 insertions, 92 deletions
diff --git a/libpathod/app.py b/libpathod/app.py
index fb1d6a2d..1a54f712 100644
--- a/libpathod/app.py
+++ b/libpathod/app.py
@@ -121,9 +121,9 @@ def make_app(noapi):
try:
if is_request:
- r = language.parse_request(app.config["pathod"].request_settings, spec)
+ r = language.parse_request(spec)
else:
- r = language.parse_response(app.config["pathod"].request_settings, spec)
+ r = language.parse_response(spec)
except language.ParseException, v:
args["syntaxerror"] = str(v)
args["marked"] = v.marked()
diff --git a/libpathod/cmdline.py b/libpathod/cmdline.py
index 6d1573f1..2c6e094e 100644
--- a/libpathod/cmdline.py
+++ b/libpathod/cmdline.py
@@ -1,7 +1,8 @@
#!/usr/bin/env python
import argparse
-import sys
import os
+import os.path
+import sys
from . import pathoc, pathod, version, utils
from netlib import http_uastrings
@@ -50,9 +51,11 @@ def go_pathoc():
)
parser.add_argument(
'request', type=str, nargs="+",
- help='Request specification'
+ help="""
+ Request specification, or path to a file containing a request
+ specifcation
+ """
)
-
group = parser.add_argument_group(
'SSL',
)
@@ -141,6 +144,16 @@ def go_pathoc():
args.connect_to = parts
else:
args.connect_to = None
+
+ reqs = []
+ for r in args.request:
+ if os.path.exists(r):
+ data = open(r).read()
+ reqs.append(data)
+ else:
+ reqs.append(r)
+ args.request = reqs
+
pathoc.main(args)
@@ -174,7 +187,10 @@ def go_pathod():
type=str,
action="append",
metavar="ANCHOR",
- help='Add an anchor. Specified as a string with the form pattern=pagespec'
+ help="""
+ Add an anchor. Specified as a string with the form pattern=pagespec, or
+ pattern=filepath
+ """
)
parser.add_argument(
"-c", dest='craftanchor', default="/p/", type=str,
@@ -310,5 +326,14 @@ def go_pathod():
parser.error(v)
args.sizelimit = sizelimit
+ anchors = []
+ for patt, spec in anchors:
+ if os.path.exists(spec):
+ data = open(spec).read()
+ anchors.append((patt, data))
+ else:
+ anchors.append((patt, spec))
+ args.anchors = anchors
+
pathod.main(args)
diff --git a/libpathod/language.py b/libpathod/language.py
index 286a1a8e..002c8205 100644
--- a/libpathod/language.py
+++ b/libpathod/language.py
@@ -961,7 +961,7 @@ def read_file(settings, s):
return file(s, "rb").read()
-def parse_response(settings, s):
+def parse_response(s):
"""
May raise ParseException or FileAccessDenied
"""
@@ -969,15 +969,13 @@ def parse_response(settings, s):
s = s.decode("ascii")
except UnicodeError:
raise ParseException("Spec must be valid ASCII.", 0, 0)
- if s.startswith(FILESTART):
- s = read_file(settings, s)
try:
return Response(Response.expr().parseString(s, parseAll=True))
except pp.ParseException, v:
raise ParseException(v.msg, v.line, v.col)
-def parse_request(settings, s):
+def parse_request(s):
"""
May raise ParseException or FileAccessDenied
"""
@@ -985,8 +983,6 @@ def parse_request(settings, s):
s = s.decode("ascii")
except UnicodeError:
raise ParseException("Spec must be valid ASCII.", 0, 0)
- if s.startswith(FILESTART):
- s = read_file(settings, s)
try:
return Request(Request.expr().parseString(s, parseAll=True))
except pp.ParseException, v:
diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py
index 9ff03eca..e534bba5 100644
--- a/libpathod/pathoc.py
+++ b/libpathod/pathoc.py
@@ -80,7 +80,7 @@ class Pathoc(tcp.TCPClient):
May raise language.ParseException, netlib.http.HttpError or
language.FileAccessDenied.
"""
- r = language.parse_request(self.settings, spec)
+ r = language.parse_request(spec)
language.serve(r, self.wfile, self.settings, self.address.host)
self.wfile.flush()
ret = list(http.read_response(self.rfile, r.method.string(), None))
@@ -115,7 +115,7 @@ class Pathoc(tcp.TCPClient):
Returns True if we have a non-ignored response.
"""
try:
- r = language.parse_request(self.settings, spec)
+ r = language.parse_request(spec)
except language.ParseException, v:
print >> fp, "Error parsing request spec: %s"%v.msg
print >> fp, v.marked()
diff --git a/libpathod/pathod.py b/libpathod/pathod.py
index 37b07bb6..92e5b2db 100644
--- a/libpathod/pathod.py
+++ b/libpathod/pathod.py
@@ -169,7 +169,7 @@ class PathodHandler(tcp.BaseHandler):
for i in self.server.anchors:
if i[0].match(path):
self.info("crafting anchor: %s" % path)
- aresp = language.parse_response(self.server.request_settings, i[1])
+ aresp = language.parse_response(i[1])
again, retlog["response"] = self.serve_crafted(aresp)
return again, retlog
@@ -177,7 +177,7 @@ class PathodHandler(tcp.BaseHandler):
spec = urllib.unquote(path)[len(self.server.craftanchor):]
self.info("crafting spec: %s" % spec)
try:
- crafted = language.parse_response(self.server.request_settings, spec)
+ crafted = language.parse_response(spec)
except language.ParseException, v:
self.info("Parse error: %s" % v.msg)
crafted = language.make_error_response(
@@ -299,7 +299,7 @@ class Pathod(tcp.TCPServer):
except re.error:
raise PathodError("Invalid regex in anchor: %s" % i[0])
try:
- language.parse_response(self.request_settings, i[1])
+ language.parse_response(i[1])
except language.ParseException, v:
raise PathodError("Invalid page spec in anchor: '%s', %s" % (i[1], str(v)))
self.anchors.append((arex, i[1]))
diff --git a/libpathod/templates/docs_lang.html b/libpathod/templates/docs_lang.html
index aef12a8d..7cb3fc5f 100644
--- a/libpathod/templates/docs_lang.html
+++ b/libpathod/templates/docs_lang.html
@@ -183,14 +183,6 @@
</div>
-<section id="specifying_requests">
- <div class="page-header">
- <h1>Executing specs from file</h1>
- </div>
-
- <pre class="example">+./path/to/spec</pre>
-
-</section>
<section id="specifying_requests">
<div class="page-header">
diff --git a/test/test_language.py b/test/test_language.py
index 5e9176ab..73b4583f 100644
--- a/test/test_language.py
+++ b/test/test_language.py
@@ -298,11 +298,11 @@ class TestHeaders:
assert v2.value.val == v3.value.val
def test_shortcuts(self):
- 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 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 language.parse_request("get:/:ua").headers[0].value.val
+ assert language.parse_request("get:/:ua").headers[0].key.val == "User-Agent"
class TestShortcutUserAgent:
@@ -336,7 +336,7 @@ class Test_Action:
assert l[0].offset == 0
def test_resolve(self):
- r = language.parse_request({}, 'GET:"/foo"')
+ r = language.parse_request('GET:"/foo"')
e = language.DisconnectAt("r")
ret = e.resolve(r, {})
assert isinstance(ret.offset, int)
@@ -352,9 +352,9 @@ class Test_Action:
class TestDisconnects:
def test_parse_response(self):
- a = language.parse_response({}, "400:d0").actions[0]
+ a = language.parse_response("400:d0").actions[0]
assert a.spec() == "d0"
- a = language.parse_response({}, "400:dr").actions[0]
+ a = language.parse_response("400:dr").actions[0]
assert a.spec() == "dr"
def test_at(self):
@@ -377,12 +377,12 @@ class TestDisconnects:
class TestInject:
def test_parse_response(self):
- a = language.parse_response({}, "400:ir,@100").actions[0]
+ a = language.parse_response("400:ir,@100").actions[0]
assert a.offset == "r"
assert a.value.datatype == "bytes"
assert a.value.usize == 100
- a = language.parse_response({}, "400:ia,@100").actions[0]
+ a = language.parse_response("400:ia,@100").actions[0]
assert a.offset == "a"
def test_at(self):
@@ -397,7 +397,7 @@ class TestInject:
def test_serve(self):
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:i0,'foo'")
+ r = language.parse_response("400:i0,'foo'")
assert language.serve(r, s, {})
def test_spec(self):
@@ -430,7 +430,7 @@ class TestPauses:
assert v.offset == "a"
def test_request(self):
- r = language.parse_response({}, '400:p10,10')
+ r = language.parse_response('400:p10,10')
assert r.actions[0].spec() == "p10,10"
def test_spec(self):
@@ -444,30 +444,24 @@ class TestPauses:
class TestRequest:
- def test_file(self):
- p = tutils.test_data.path("data")
- d = dict(staticdir=p)
- r = language.parse_request(d, "+request")
- assert r.path.values({})[0][:] == "/foo"
-
def test_nonascii(self):
- tutils.raises("ascii", language.parse_request, {}, "get:\xf0")
+ tutils.raises("ascii", language.parse_request, "get:\xf0")
def test_err(self):
- tutils.raises(language.ParseException, language.parse_request, {}, 'GET')
+ tutils.raises(language.ParseException, language.parse_request, 'GET')
def test_simple(self):
- r = language.parse_request({}, 'GET:"/foo"')
+ r = language.parse_request('GET:"/foo"')
assert r.method.string() == "GET"
assert r.path.string() == "/foo"
- r = language.parse_request({}, 'GET:/foo')
+ r = language.parse_request('GET:/foo')
assert r.path.string() == "/foo"
- r = language.parse_request({}, 'GET:@1k')
+ r = language.parse_request('GET:@1k')
assert len(r.path.string()) == 1024
def test_render(self):
s = cStringIO.StringIO()
- r = language.parse_request({}, "GET:'/foo'")
+ r = language.parse_request("GET:'/foo'")
assert language.serve(r, s, {}, "foo.com")
def test_multiline(self):
@@ -476,7 +470,7 @@ class TestRequest:
"/foo"
ir,@1
"""
- r = language.parse_request({}, l)
+ r = language.parse_request(l)
assert r.method.string() == "GET"
assert r.path.string() == "/foo"
assert r.actions
@@ -493,24 +487,24 @@ class TestRequest:
ir,@1
"""
- r = language.parse_request({}, l)
+ r = language.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 = language.parse_request(s).spec()
+ assert language.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 = language.parse_request("GET:/:b@100").freeze({})
assert len(r.spec()) > 100
def test_path_generator(self):
- r = language.parse_request({}, "GET:@100").freeze({})
+ r = language.parse_request("GET:@100").freeze({})
assert len(r.spec()) > 100
@@ -580,59 +574,53 @@ class TestWriteValues:
def test_write_values_after(self):
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:da")
+ r = language.parse_response("400:da")
language.serve(r, s, {})
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:pa,0")
+ r = language.parse_response("400:pa,0")
language.serve(r, s, {})
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:ia,'xx'")
+ r = language.parse_response("400:ia,'xx'")
language.serve(r, s, {})
assert s.getvalue().endswith('xx')
class TestResponse:
def dummy_response(self):
- return language.parse_response({}, "400'msg'")
-
- def test_file(self):
- p = tutils.test_data.path("data")
- d = dict(staticdir=p)
- r = language.parse_response(d, "+response")
- assert r.code.string() == "202"
+ return language.parse_response("400'msg'")
def test_response(self):
- r = language.parse_response({}, "400:m'msg'")
+ r = language.parse_response("400:m'msg'")
assert r.code.string() == "400"
assert r.reason.string() == "msg"
- r = language.parse_response({}, "400:m'msg':b@100b")
+ r = language.parse_response("400:m'msg':b@100b")
assert r.reason.string() == "msg"
assert r.body.values({})
assert str(r)
- r = language.parse_response({}, "200")
+ r = language.parse_response("200")
assert r.code.string() == "200"
assert not r.reason
assert "OK" in [i[:] for i in r.preamble({})]
def test_render(self):
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:m'msg'")
+ r = language.parse_response("400:m'msg'")
assert language.serve(r, s, {})
def test_raw(self):
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:b'foo'")
+ r = language.parse_response("400:b'foo'")
language.serve(r, s, {})
v = s.getvalue()
assert "Content-Length" in v
assert "Date" in v
s = cStringIO.StringIO()
- r = language.parse_response({}, "400:b'foo':r")
+ r = language.parse_response("400:b'foo':r")
language.serve(r, s, {})
v = s.getvalue()
assert not "Content-Length" in v
@@ -643,9 +631,9 @@ class TestResponse:
s = cStringIO.StringIO()
language.serve(x, s, {})
assert x.length({}) == len(s.getvalue())
- testlen(language.parse_response({}, "400:m'msg':r"))
- testlen(language.parse_response({}, "400:m'msg':h'foo'='bar':r"))
- testlen(language.parse_response({}, "400:m'msg':h'foo'='bar':b@100b:r"))
+ testlen(language.parse_response("400:m'msg':r"))
+ testlen(language.parse_response("400:m'msg':h'foo'='bar':r"))
+ testlen(language.parse_response("400:m'msg':h'foo'='bar':b@100b:r"))
def test_maximum_length(self):
def testlen(x):
@@ -654,59 +642,59 @@ class TestResponse:
language.serve(x, s, {})
assert m >= len(s.getvalue())
- r = language.parse_response({}, "400:m'msg':b@100:d0")
+ r = language.parse_response("400:m'msg':b@100:d0")
testlen(r)
- r = language.parse_response({}, "400:m'msg':b@100:d0:i0,'foo'")
+ r = language.parse_response("400:m'msg':b@100:d0:i0,'foo'")
testlen(r)
- r = language.parse_response({}, "400:m'msg':b@100:d0:i0,'foo'")
+ r = language.parse_response("400:m'msg':b@100:d0:i0,'foo'")
testlen(r)
def test_render(self):
- r = language.parse_response({}, "400:p0,100:dr")
+ r = language.parse_response("400:p0,100:dr")
assert "p0" in r.spec()
s = r.preview_safe()
assert not "p0" in s.spec()
def test_parse_err(self):
- tutils.raises(language.ParseException, language.parse_response, {}, "400:msg,b:")
+ tutils.raises(language.ParseException, language.parse_response, "400:msg,b:")
try:
- language.parse_response({}, "400'msg':b:")
+ language.parse_response("400'msg':b:")
except language.ParseException, v:
assert v.marked()
assert str(v)
def test_nonascii(self):
- tutils.raises("ascii", language.parse_response, {}, "foo:b\xf0")
+ tutils.raises("ascii", language.parse_response, "foo:b\xf0")
def test_parse_header(self):
- r = language.parse_response({}, '400:h"foo"="bar"')
+ r = language.parse_response('400:h"foo"="bar"')
assert utils.get_header("foo", r.headers)
def test_parse_pause_before(self):
- r = language.parse_response({}, "400:p0,10")
+ r = language.parse_response("400:p0,10")
assert r.actions[0].spec() == "p0,10"
def test_parse_pause_after(self):
- r = language.parse_response({}, "400:pa,10")
+ r = language.parse_response("400:pa,10")
assert r.actions[0].spec() == "pa,10"
def test_parse_pause_random(self):
- r = language.parse_response({}, "400:pr,10")
+ r = language.parse_response("400:pr,10")
assert r.actions[0].spec() == "pr,10"
def test_parse_stress(self):
# While larger values are known to work on linux,
# len() technically returns an int and a python 2.7 int on windows has 32bit precision.
# Therefore, we should keep the body length < 2147483647 bytes in our tests.
- r = language.parse_response({}, "400:b@1g")
+ r = language.parse_response("400:b@1g")
assert r.length({})
def test_spec(self):
def rt(s):
- s = language.parse_response({}, s).spec()
- assert language.parse_response({}, s).spec() == s
+ s = language.parse_response(s).spec()
+ assert language.parse_response(s).spec() == s
rt("400:b@100g")
rt("400")
rt("400:da")
diff --git a/test/test_pathoc.py b/test/test_pathoc.py
index fe7adc4d..5172d85f 100644
--- a/test/test_pathoc.py
+++ b/test/test_pathoc.py
@@ -139,11 +139,6 @@ class TestDaemon(_TestDaemon):
def test_conn_err(self):
assert "Invalid server response" in self.tval(["get:'/p/200:d2'"])
- def test_fileread(self):
- d = tutils.test_data.path("data/request")
- assert "foo" in self.tval(["+%s"%d], showreq=True)
- assert "File" in self.tval(["+/nonexistent"])
-
def test_connect_fail(self):
to = ("foobar", 80)
c = pathoc.Pathoc(("127.0.0.1", self.d.port))