""" @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: