diff options
Diffstat (limited to 'libpathod')
-rw-r--r-- | libpathod/language.py | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/libpathod/language.py b/libpathod/language.py index a93d4dca..03cf66c7 100644 --- a/libpathod/language.py +++ b/libpathod/language.py @@ -85,6 +85,7 @@ def serve(msg, fp, settings, request_host=None): Calling this function may modify the object. """ + msg = msg.resolve(settings, request_host) started = time.time() hdrs = msg.headervals(settings, request_host) @@ -96,7 +97,11 @@ def serve(msg, fp, settings, request_host=None): if msg.body: vals.append(msg.body.value.get_generator(settings)) vals.reverse() - actions = msg.ready_actions(settings, request_host) + + actions = msg.actions[:] + actions.sort() + actions.reverse() + actions = [i.intermediate(settings) for i in actions] disconnect = write_values(fp, vals, actions[:]) duration = time.time() - started @@ -105,18 +110,7 @@ def serve(msg, fp, settings, request_host=None): started = started, duration = duration, ) - for i in msg.logattrs: - v = getattr(msg, i) - # Careful not to log any VALUE specs without sanitizing them first. We truncate at 1k. - if hasattr(v, "values"): - v = [x[:TRUNCATE] for x in v.values(settings)] - v = "".join(v).encode("string_escape") - elif hasattr(v, "__len__"): - v = v[:TRUNCATE] - v = v.encode("string_escape") - ret[i] = v - ret["spec"] = msg.spec() - ret.update(msg.logflags) + ret.update(msg.log(settings)) return ret @@ -228,7 +222,7 @@ class _Token(object): """ return None - def resolve(self, msg): # pragma: no cover + def resolve(self, msg, settings, request_host): # pragma: no cover """ Resolves this token to ready it for transmission. This means that the calculated offsets of actions are fixed. @@ -559,7 +553,7 @@ class _Action(_Token): def __init__(self, offset): self.offset = offset - def resolve_offset(self, msg, settings, request_host): + def resolve(self, msg, settings, request_host): """ Resolves offset specifications to a numeric offset. Returns a copy of the action object. @@ -713,11 +707,11 @@ class _Message(object): l += len(i.value.get_generator(settings)) return l - def headervals(self, settings, request_host): - hdrs = self.headers[:] + def resolve(self, settings, request_host): + tokens = self.tokens[:] if not self.raw: if self.body and not utils.get_header("Content-Length", self.headers): - hdrs.append( + tokens.append( Header( ValueLiteral("Content-Length"), ValueLiteral(str(len(self.body.value.get_generator(settings)))), @@ -725,7 +719,7 @@ class _Message(object): ) if request_host: if not utils.get_header("Host", self.headers): - hdrs.append( + tokens.append( Header( ValueLiteral("Host"), ValueLiteral(request_host) @@ -733,23 +727,21 @@ class _Message(object): ) else: if not utils.get_header("Date", self.headers): - hdrs.append( + tokens.append( Header( ValueLiteral("Date"), ValueLiteral(formatdate(timeval=None, localtime=False, usegmt=True)) ) ) + intermediate = self.__class__(tokens) + return self.__class__([i.resolve(intermediate, settings, request_host) for i in tokens]) + + def headervals(self, settings, request_host): values = [] - for h in hdrs: + for h in self.headers: values.extend(h.values(settings)) return values - def ready_actions(self, settings, request_host): - actions = [i.resolve_offset(self, settings, request_host) for i in self.actions] - actions.sort() - actions.reverse() - return [i.intermediate(settings) for i in actions] - @abc.abstractmethod def preamble(self, settings): # pragma: no cover pass @@ -758,6 +750,24 @@ class _Message(object): def expr(klass): # pragma: no cover pass + def log(self, settings): + """ + A dictionary that should be logged if this message is served. + """ + ret = {} + for i in self.logattrs: + v = getattr(self, i) + # Careful not to log any VALUE specs without sanitizing them first. We truncate at 1k. + if hasattr(v, "values"): + v = [x[:TRUNCATE] for x in v.values(settings)] + v = "".join(v).encode("string_escape") + elif hasattr(v, "__len__"): + v = v[:TRUNCATE] + v = v.encode("string_escape") + ret[i] = v + ret["spec"] = self.spec() + return ret + Sep = pp.Optional(pp.Literal(":")).suppress() @@ -774,7 +784,6 @@ class Response(_Message): Reason ) logattrs = ["code", "reason", "version", "body"] - logflags = dict() @property def code(self): return self._get_token(Code) @@ -820,7 +829,6 @@ class Request(_Message): Raw ) logattrs = ["method", "path", "body"] - logflags = dict() @property def method(self): return self._get_token(Method) @@ -855,16 +863,14 @@ class Request(_Message): return ":".join([i.spec() for i in self.tokens]) -class PathodErrorResponse(Response): - logflags = dict(internal=True) - def __init__(self, reason, body=None): - tokens = [ - Code("800"), - Header(ValueLiteral("Content-Type"), ValueLiteral("text/plain")), - Reason(ValueLiteral(reason)), - Body(ValueLiteral("pathod error: " + (body or reason))), - ] - Response.__init__(self, tokens) +def PathodErrorResponse(reason, body=None): + tokens = [ + Code("800"), + Header(ValueLiteral("Content-Type"), ValueLiteral("text/plain")), + Reason(ValueLiteral(reason)), + Body(ValueLiteral("pathod error: " + (body or reason))), + ] + return Response(tokens) FILESTART = "+" |