class Response(object): """Response(sock, request) -> new Response object A Response object that holds the response to send back to the client. This ensure that the correct data is sent in the correct order. """ chunked = False def __init__(self, sock, request): "initializes x; see x.__class__.__doc__ for signature" self.sock = sock self.request = request self.clear() def __repr__(self): return "<Response %s %s (%d)>" % ( self.status, self.headers["Content-Type"], (len(self.body) if type(self.body) == str else 0)) def output(self): protocol = "HTTP/%d.%d" % self.request.server_protocol status = self.status headers = self.headers body = self.process() or "" yield "%s %s\r\n" % (protocol, status) yield str(headers) if body: if self.chunked: buf = [hex(len(body))[2:], "\r\n", body, "\r\n"] yield "".join(buf) else: yield body def clear(self): self.done = False self.close = False if self.request.server: server_version = self.request.server.version else: server_version = SERVER_VERSION self.headers = Headers([("Server", server_version), ("Date", strftime("%a, %d %b %Y %H:%M:%S %Z")), ("X-Powered-By", server_version)]) self.cookie = self.request.cookie self.stream = False self.body = None self.time = time() self.status = "200 OK" def process(self): for k, v in self.cookie.iteritems(): self.headers.add_header("Set-Cookie", v.OutputString()) status = int(self.status.split(" ", 1)[0]) if status == 413: self.close = True elif "Content-Length" not in self.headers: if status < 200 or status in (204, 205, 304): pass else: if self.protocol == "HTTP/1.1" \ and self.request.method != "HEAD": self.chunked = True self.headers.add_header("Transfer-Encoding", "chunked") else: self.close = True if "Connection" not in self.headers: if self.protocol == "HTTP/1.1": if self.close: self.headers.add_header("Connection", "close") else: if not self.close: self.headers.add_header("Connection", "Keep-Alive") if isinstance(self.body, basestring): self.headers["Content-Length"] = str(len(self.body)) self.headers.setdefault("Content-Type", "text/html") return self.body elif type(self.body) is types.GeneratorType: self.stream = True return self.body.next() elif type(self.body) is types.FileType: st = os.fstat(self.body.fileno()) self.headers.setdefault("Content-Length", str(st.st_size)) self.headers.setdefault("Content-Type", "application/octet-stream") self.stream = True self.file = self.body self.body = file_generator(self.body) return None else: return None
class Response(object): """Response(sock, request) -> new Response object A Response object that holds the response to send back to the client. This ensure that the correct data is sent in the correct order. """ chunked = False body = Body() def __init__(self, sock, request): "initializes x; see x.__class__.__doc__ for signature" self.sock = sock self.request = request self.clear() def __repr__(self): return "<Response %s %s (%d)>" % ( self.status, self.headers["Content-Type"], (len(self.body) if type(self.body) == str else 0)) def __str__(self): self.prepare() protocol = self.protocol status = self.status headers = self.headers return "%s %s\r\n%s" % (protocol, status, headers) def clear(self): self.done = False self.close = False if self.request.server: server_version = self.request.server.version else: server_version = SERVER_VERSION self.headers = Headers([ ("Date", strftime("%a, %d %b %Y %H:%M:%S %Z")), ("X-Powered-By", server_version)]) if self.request.server is not None: self.headers.add_header("Server", server_version) self.cookie = self.request.cookie self.stream = False self._body = [] self.time = time() self.status = "200 OK" self.protocol = "HTTP/%d.%d" % self.request.server_protocol def prepare(self): if self.body and type(self.body) is ListType: if unicode in map(type, self.body): cLength = sum(map(lambda s: len(s.encode("utf-8")), self.body)) else: cLength = sum(map(len, self.body)) self.headers.setdefault("Content-Type", "text/html") self.headers["Content-Length"] = str(cLength) if self.stream: self.headers.setdefault("Content-Type", "application/octet-stream") for k, v in self.cookie.iteritems(): self.headers.add_header("Set-Cookie", v.OutputString()) status = int(self.status.split(" ", 1)[0]) if status == 413: self.close = True elif "Content-Length" not in self.headers: if status < 200 or status in (204, 205, 304): pass else: if self.protocol == "HTTP/1.1" \ and self.request.method != "HEAD" \ and self.request.server is not None: self.chunked = True self.headers.add_header("Transfer-Encoding", "chunked") else: self.close = True if self.request.server is not None and "Connection" not in self.headers: if self.protocol == "HTTP/1.1": if self.close: self.headers.add_header("Connection", "close") else: if not self.close: self.headers.add_header("Connection", "Keep-Alive") if self.headers.get("Transfer-Encoding", "") == "chunked": self.chunked = True
class Response(object): """Response(sock, request) -> new Response object A Response object that holds the response to send back to the client. This ensure that the correct data is sent in the correct order. """ chunked = False body = Body() def __init__(self, sock, request): "initializes x; see x.__class__.__doc__ for signature" self.sock = sock self.request = request self.clear() def __repr__(self): return "<Response %s %s (%d)>" % ( self.status, self.headers["Content-Type"], (len(self.body) if type(self.body) == str else 0)) def __str__(self): self.prepare() protocol = self.protocol status = self.status headers = self.headers return "%s %s\r\n%s" % (protocol, status, headers) def clear(self): self.done = False self.close = False if self.request.server: server_version = self.request.server.version else: server_version = SERVER_VERSION self.headers = Headers([("Date", strftime("%a, %d %b %Y %H:%M:%S %Z")), ("X-Powered-By", server_version)]) if self.request.server is not None: self.headers.add_header("Server", server_version) self.cookie = self.request.cookie self.stream = False self._body = [] self.time = time() self.status = "200 OK" self.protocol = "HTTP/%d.%d" % self.request.server_protocol def prepare(self): if self.body and type(self.body) is ListType: if unicode in map(type, self.body): cLength = sum(map(lambda s: len(s.encode("utf-8")), self.body)) else: cLength = sum(map(len, self.body)) self.headers.setdefault("Content-Type", "text/html") self.headers["Content-Length"] = str(cLength) if self.stream: self.headers.setdefault("Content-Type", "application/octet-stream") for k, v in self.cookie.iteritems(): self.headers.add_header("Set-Cookie", v.OutputString()) status = int(self.status.split(" ", 1)[0]) if status == 413: self.close = True elif "Content-Length" not in self.headers: if status < 200 or status in (204, 205, 304): pass else: if self.protocol == "HTTP/1.1" \ and self.request.method != "HEAD" \ and self.request.server is not None: self.chunked = True self.headers.add_header("Transfer-Encoding", "chunked") else: self.close = True if self.request.server is not None and "Connection" not in self.headers: if self.protocol == "HTTP/1.1": if self.close: self.headers.add_header("Connection", "close") else: if not self.close: self.headers.add_header("Connection", "Keep-Alive") if self.headers.get("Transfer-Encoding", "") == "chunked": self.chunked = True