Allow specification of multiple patterns from file and on command line
This commit is contained in:
parent
d4e6c25d45
commit
6d8431ab3e
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue