Skip to content

Commit cc83a2c

Browse files
committed
Codes used from now
1 parent ef19ed4 commit cc83a2c

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

websocket.py

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,44 @@
66
from base64 import b64encode
77
from hashlib import sha1
88

9-
109
if sys.version_info[0] < 3 :
1110
from SocketServer import ThreadingMixIn, TCPServer, StreamRequestHandler
1211
else:
1312
from socketserver import ThreadingMixIn, TCPServer, StreamRequestHandler
1413

1514

1615

16+
# ---------------------- Websocket bits in bytes -----------------------
17+
'''
18+
+-+-+-+-+-------+-+-------------+-------------------------------+
19+
0 1 2 3
20+
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
21+
+-+-+-+-+-------+-+-------------+-------------------------------+
22+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
23+
|I|S|S|S| (4) |A| (7) | (16/64) |
24+
|N|V|V|V| |S| | (if payload len==126/127) |
25+
| |1|2|3| |K| | |
26+
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
27+
| Extended payload length continued, if payload len == 127 |
28+
+ - - - - - - - - - - - - - - - +-------------------------------+
29+
| Payload Data continued ... |
30+
+---------------------------------------------------------------+
31+
'''
32+
33+
FIN = 0x80
34+
OPCODE = 0x0f
35+
MASKED = 0x80
36+
PAYLOAD_LEN = 0x7f
37+
PAYLOAD_LEN_EXT16 = 0x7e
38+
PAYLOAD_LEN_EXT64 = 0x7f
39+
40+
OPCODE_TEXT = 0x01
41+
CLOSE_CONN = 0x8
42+
43+
44+
45+
# -------------------------------- API ---------------------------------
46+
1747
class API():
1848
def run_forever(self):
1949
try:
@@ -44,12 +74,14 @@ def send_message_to_all(self, msg):
4474

4575

4676

77+
# ------------------------- Implementation -----------------------------
78+
4779
class WebSocketsServer(ThreadingMixIn, TCPServer, API):
4880

4981
allow_reuse_address = True
5082
daemon_threads = True # comment to keep threads alive until finished
5183

52-
# clients is list of:
84+
# clients is list of dict:
5385
# {
5486
# 'id' : id,
5587
# 'handler' : handler,
@@ -116,32 +148,31 @@ def handle(self):
116148

117149

118150
def read_next_message(self):
119-
120-
b1 = self.rfile.read(1)
121-
b2 = self.rfile.read(1)
122-
FIN = ord(b1) & 0b10000000
123-
OPCODE = ord(b1) & 0b00001111
124-
MASKED = ord(b2) & 0b10000000
125-
LENGTH = ord(b2) & 0b01111111
151+
152+
b1, b2 = self.rfile.read(2)
153+
154+
fin = ord(b1) & FIN
155+
opcode = ord(b1) & OPCODE
156+
masked = ord(b2) & MASKED
157+
payload_length = ord(b2) & PAYLOAD_LEN
126158

127159
if not b1:
128160
print("Client closed connection.")
129161
self.keep_alive = 0
130162
return
131-
if OPCODE == 8:
163+
if opcode == CLOSE_CONN:
132164
print("Client asked to close connection.")
133165
self.keep_alive = 0
134166
return
135-
if not MASKED:
167+
if not masked:
136168
print("Client must always be masked.")
137169
self.keep_alive = 0
138170
return
139171

140-
length = LENGTH
141-
if LENGTH == 126:
142-
length = struct.unpack(">H", self.rfile.read(2))[0]
143-
elif LENGTH == 127:
144-
length = struct.unpack(">Q", self.rfile.read(8))[0]
172+
if payload_length == 126:
173+
payload_length = struct.unpack(">H", self.rfile.read(2))[0]
174+
elif payload_length == 127:
175+
payload_length = struct.unpack(">Q", self.rfile.read(8))[0]
145176

146177
# python3 gives ordinal of byte directly
147178
if sys.version_info[0] < 3:
@@ -150,7 +181,7 @@ def read_next_message(self):
150181
masks = [b for b in self.rfile.read(4)]
151182

152183
decoded = ""
153-
for char in self.rfile.read(length):
184+
for char in self.rfile.read(payload_length):
154185
if isinstance(char, str): # python2 fix
155186
char = ord(char)
156187
char ^= masks[len(decoded) % 4]
@@ -164,29 +195,10 @@ def send_message(self, message):
164195

165196
def send_text(self, message):
166197
'''
167-
+-+-+-+-+-------+-+-------------+-------------------------------+
168-
0 1 2 3
169-
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
170-
+-+-+-+-+-------+-+-------------+-------------------------------+
171-
|F|R|R|R| opcode|M| Payload len | Extended payload length |
172-
|I|S|S|S| (4) |A| (7) | (16/64) |
173-
|N|V|V|V| |S| | (if payload len==126/127) |
174-
| |1|2|3| |K| | |
175-
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
176-
| Extended payload length continued, if payload len == 127 |
177-
+ - - - - - - - - - - - - - - - +-------------------------------+
178-
| Payload Data continued ... |
179-
+---------------------------------------------------------------+
180-
181198
NOTES
182199
Fragmented(=continuation) messages are not being used since their usage
183200
is needed in very limited cases - when we don't know the payload length.
184201
'''
185-
186-
FIN = 0x80
187-
OPCODE_TEXT = 0x01
188-
EXT_PAYLOAD_16BITS = 0x7e
189-
EXT_PAYLOAD_64BITS = 0x7f
190202

191203
# Validate message
192204
if isinstance(message, bytes):
@@ -212,13 +224,13 @@ def send_text(self, message):
212224
# Extended payload
213225
elif payload_length >= 126 and payload_length <= 65535:
214226
header.append(FIN | OPCODE_TEXT)
215-
header.append(EXT_PAYLOAD_16BITS)
227+
header.append(PAYLOAD_LEN_EXT16)
216228
header.extend(struct.pack(">H", payload_length))
217229

218230
# Huge extended payload
219231
elif payload_length < 18446744073709551616:
220232
header.append(FIN | OPCODE_TEXT)
221-
header.append(EXT_PAYLOAD_64BITS)
233+
header.append(PAYLOAD_LEN_EXT64)
222234
header.extend(struct.pack(">Q", payload_length))
223235

224236
else:

0 commit comments

Comments
 (0)