2015-06-07 01:18:33 +00:00
|
|
|
import itertools
|
2015-05-02 04:17:00 +00:00
|
|
|
import time
|
|
|
|
|
2015-05-02 22:11:51 +00:00
|
|
|
import pyparsing as pp
|
2015-05-02 04:17:00 +00:00
|
|
|
|
2015-06-08 08:45:17 +00:00
|
|
|
from . import http, http2, websockets, writer, exceptions
|
2015-05-02 04:17:00 +00:00
|
|
|
|
|
|
|
from exceptions import *
|
2015-05-15 21:42:47 +00:00
|
|
|
from base import Settings
|
2015-05-30 05:50:46 +00:00
|
|
|
assert Settings # prevent pyflakes from messing with this
|
2015-05-02 04:17:00 +00:00
|
|
|
|
|
|
|
|
2015-06-07 04:11:32 +00:00
|
|
|
def expand(msg):
|
|
|
|
times = getattr(msg, "times", None)
|
|
|
|
if times:
|
2015-06-18 16:05:09 +00:00
|
|
|
for j_ in xrange(int(times.value)):
|
2015-06-07 04:11:32 +00:00
|
|
|
yield msg.strike_token("times")
|
|
|
|
else:
|
|
|
|
yield msg
|
|
|
|
|
|
|
|
|
2015-06-11 14:13:22 +00:00
|
|
|
def parse_pathod(s, use_http2=False):
|
2015-05-02 04:17:00 +00:00
|
|
|
"""
|
|
|
|
May raise ParseException
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
s = s.decode("ascii")
|
|
|
|
except UnicodeError:
|
|
|
|
raise exceptions.ParseException("Spec must be valid ASCII.", 0, 0)
|
|
|
|
try:
|
2015-06-11 14:13:22 +00:00
|
|
|
if use_http2:
|
|
|
|
expressions = [
|
|
|
|
# http2.Frame.expr(),
|
|
|
|
http2.Response.expr(),
|
|
|
|
]
|
|
|
|
else:
|
|
|
|
expressions = [
|
2015-06-04 05:18:06 +00:00
|
|
|
websockets.WebsocketFrame.expr(),
|
|
|
|
http.Response.expr(),
|
|
|
|
]
|
2015-06-11 14:13:22 +00:00
|
|
|
reqs = pp.Or(expressions).parseString(s, parseAll=True)
|
2015-05-30 00:03:13 +00:00
|
|
|
except pp.ParseException as v:
|
2015-05-02 04:17:00 +00:00
|
|
|
raise exceptions.ParseException(v.msg, v.line, v.col)
|
2015-06-07 04:11:32 +00:00
|
|
|
return itertools.chain(*[expand(i) for i in reqs])
|
2015-06-07 01:18:33 +00:00
|
|
|
|
|
|
|
|
2015-06-08 08:45:17 +00:00
|
|
|
def parse_pathoc(s, use_http2=False):
|
2015-05-02 04:17:00 +00:00
|
|
|
try:
|
|
|
|
s = s.decode("ascii")
|
|
|
|
except UnicodeError:
|
|
|
|
raise exceptions.ParseException("Spec must be valid ASCII.", 0, 0)
|
|
|
|
try:
|
2015-06-08 08:45:17 +00:00
|
|
|
if use_http2:
|
|
|
|
expressions = [
|
|
|
|
# http2.Frame.expr(),
|
|
|
|
http2.Request.expr(),
|
|
|
|
]
|
|
|
|
else:
|
|
|
|
expressions = [
|
|
|
|
websockets.WebsocketClientFrame.expr(),
|
|
|
|
http.Request.expr(),
|
|
|
|
]
|
|
|
|
reqs = pp.OneOrMore(pp.Or(expressions)).parseString(s, parseAll=True)
|
2015-05-30 00:03:13 +00:00
|
|
|
except pp.ParseException as v:
|
2015-05-02 04:17:00 +00:00
|
|
|
raise exceptions.ParseException(v.msg, v.line, v.col)
|
2015-06-07 01:18:33 +00:00
|
|
|
return itertools.chain(*[expand(i) for i in reqs])
|
2015-05-02 04:17:00 +00:00
|
|
|
|
|
|
|
|
2015-06-04 11:57:23 +00:00
|
|
|
def parse_websocket_frame(s):
|
2015-06-07 04:11:32 +00:00
|
|
|
"""
|
|
|
|
May raise ParseException
|
|
|
|
"""
|
2015-06-04 11:57:23 +00:00
|
|
|
try:
|
2015-06-07 22:58:12 +00:00
|
|
|
reqs = pp.OneOrMore(
|
|
|
|
websockets.WebsocketFrame.expr()
|
|
|
|
).parseString(
|
2015-06-04 11:57:23 +00:00
|
|
|
s,
|
|
|
|
parseAll = True
|
2015-06-07 22:58:12 +00:00
|
|
|
)
|
2015-06-04 11:57:23 +00:00
|
|
|
except pp.ParseException as v:
|
|
|
|
raise exceptions.ParseException(v.msg, v.line, v.col)
|
2015-06-07 22:58:12 +00:00
|
|
|
return itertools.chain(*[expand(i) for i in reqs])
|
2015-06-04 11:57:23 +00:00
|
|
|
|
|
|
|
|
2015-05-02 04:17:00 +00:00
|
|
|
def serve(msg, fp, settings):
|
|
|
|
"""
|
|
|
|
fp: The file pointer to write to.
|
|
|
|
|
|
|
|
request_host: If this a request, this is the connecting host. If
|
|
|
|
None, we assume it's a response. Used to decide what standard
|
|
|
|
modifications to make if raw is not set.
|
|
|
|
|
|
|
|
Calling this function may modify the object.
|
|
|
|
"""
|
|
|
|
msg = msg.resolve(settings)
|
|
|
|
started = time.time()
|
|
|
|
|
|
|
|
vals = msg.values(settings)
|
|
|
|
vals.reverse()
|
|
|
|
|
2015-05-30 00:03:13 +00:00
|
|
|
actions = sorted(msg.actions[:])
|
2015-05-02 04:17:00 +00:00
|
|
|
actions.reverse()
|
|
|
|
actions = [i.intermediate(settings) for i in actions]
|
|
|
|
|
|
|
|
disconnect = writer.write_values(fp, vals, actions[:])
|
|
|
|
duration = time.time() - started
|
|
|
|
ret = dict(
|
|
|
|
disconnect = disconnect,
|
|
|
|
started = started,
|
|
|
|
duration = duration,
|
|
|
|
)
|
|
|
|
ret.update(msg.log(settings))
|
|
|
|
return ret
|