X-Git-Url: http://dolda2000.com/gitweb/?p=wrw.git;a=blobdiff_plain;f=wrw%2Fresp.py;h=e6810b4f0d69923110fc1e7d7a3f068bce8a4e4f;hp=965df6c8c18a76e41e659f92eccf08ef57f4fe30;hb=HEAD;hpb=d38b200493b3ed263dbf10581d6d204462ed68c4 diff --git a/wrw/resp.py b/wrw/resp.py index 965df6c..e6810b4 100644 --- a/wrw/resp.py +++ b/wrw/resp.py @@ -1,3 +1,4 @@ +import sys, os, math from . import dispatch, proto, env from .sp import xhtml h = xhtml.cons() @@ -84,3 +85,52 @@ class unmodified(dispatch.restart): req.status(304, "Not Modified") req.ohead["Content-Length"] = "0" return [] + +class fileiter(object): + def __init__(self, fp): + self.fp = fp + + def __iter__(self): + return self + + def __next__(self): + if self.fp is None: + raise StopIteration() + data = self.fp.read(16384) + if data == b"": + self.fp.close() + self.fp = None + raise StopIteration() + return data + + def close(self): + if self.fp is not None: + self.fp.close() + self.fp = None + +class fileresp(dispatch.restart): + def __init__(self, fp, ctype, charset=None, cachable=True): + self.fp = fp + self.ctype = ctype + if charset is None and ctype.startswith("text/"): + charset = sys.getdefaultencoding() + self.charset = charset + self.cachable = cachable + + def handle(self, req): + sb = None + if hasattr(self.fp, "fileno"): + sb = os.fstat(self.fp.fileno()) + if self.cachable and sb and sb.st_mtime != 0: + if "If-Modified-Since" in req.ihead: + rtime = proto.phttpdate(req.ihead["If-Modified-Since"]) + if rtime is not None and rtime >= math.floor(sb.st_mtime): + raise unmodified() + req.ohead["Last-Modified"] = proto.httpdate(sb.st_mtime) + ctype = self.ctype + if self.charset is not None: + ctype += "; charset=%s" % (self.charset) + req.ohead["Content-Type"] = ctype + if sb and sb.st_size > 0: + req.ohead["Content-Length"] = str(sb.st_size) + return fileiter(self.fp)