Http.py
2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""
@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: