Example #1
0
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
Example #2
0
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
Example #3
0
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