Http.py 2.96 KB
"""
@author Georg Hopp

"""
from base64 import b64encode, b64decode
from hashlib import sha1

from ..Protocol import Protocol

from Parser import Parser
from Composer import Composer
from Message import Message

from Protocol.Websocket.Websocket import Websocket

class Http(Protocol):
    def __init__(self):
        self.parser   = Parser()
        self.composer = Composer()

    def getParser(self):
        return self.parser

    def getComposer(self):
        return self.composer

    def createMessage(self, remote):
        return Message(remote)

    def createRequest(self, method=Message.METHOD_GET, uri='/', remote=None):
        request = self.createMessage(remote)
        request.setRequestLine(method, uri, 'HTTP/1.1')
        self._addCommonHeaders(request)

        return request

    def createResponse(self, request, code=200, resp_message='OK', remote=None):
        version  = request.getHttpVersion()
        response = self.createMessage(remote)
        response.setStateLine(version, code, resp_message)

        self._addCommonHeaders(response)
        response.setHeader('Content-Length', '0')

        con_header = request.getHeader('Connection').lower()
        if 'keep-alive' in con_header:
            response.setHeader('Connection', 'Keep-Alive')
        if 'close' in con_header:
            response.setHeader('Connection', 'Close')

        return response

    def createUpgradeRequest(self, host, subprotocol=None):
        """
        currently only for websocket updates
        """
        request = self.createRequest()
        request.setHeaders([
            ('Host', host),
            ('Connection', 'Upgrade'),
            ('Upgrade', 'websocket'),
            ('Sec-WebSocket-Version', '13'),
            ('Sec-WebSocket-Key', b64encode(''.join(chr(randint(0,255))
                for _ in range(16))))])
        if subprotocol:
            request.setHeader('Sec-WebSocket-Protocol', protocol)
        return request

    def createUpgradeResponse(self, request):
        """
        currently only for websocket updates
        """
        key = request.getHeader('Sec-WebSocket-Key')
        if not key:
            response = self.createResponse(request, 400, 'Bad Request')
        else:
            response = self.createResponse(request, 101, 'Switching Protocols')
            response.setHeaders([
                ('Connection', 'Upgrade'),
                ('Upgrade', 'websocket'),
                ('Sec-WebSocket-Accept', b64encode(sha1(key+Websocket.WS_UUID).digest()))])

        return response

    def upgrade(self, message):
        """
        TODO decide by the message which protocol to upgrade to.
        """
        return Websocket()


    def _addCommonHeaders(self, message):
        from wsgiref.handlers import format_date_time
        from datetime import datetime
        from time import mktime

        date = format_date_time(mktime(datetime.now().timetuple()))
        message.setHeader('Date', date)

# vim: set ft=python et ts=8 sw=4 sts=4: