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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
import time
import six
from mod_pywebsocket import msgutil
# see the list of tests in test_websocket.html
def web_socket_do_extra_handshake(request):
# must set request.ws_protocol to the selected version from ws_requested_protocols
for x in request.ws_requested_protocols:
if x != "test-does-not-exist":
request.ws_protocol = x
break
if request.ws_protocol == "test-2.1":
time.sleep(3)
elif request.ws_protocol == "test-9":
time.sleep(3)
elif request.ws_protocol == "test-10":
time.sleep(3)
elif request.ws_protocol == "test-19":
raise ValueError("Aborting (test-19)")
elif request.ws_protocol == "test-20" or request.ws_protocol == "test-17":
time.sleep(3)
elif request.ws_protocol == "test-22":
# The timeout is 5 seconds
time.sleep(13)
elif request.ws_protocol == "test-41b":
request.sts = "max-age=100"
elif request.ws_protocol == "test-49":
# subprotocols are compared case-sensitively, so this should fail
request.ws_protocol = "teST-49"
else:
pass
# Behave according to recommendation of RFC 6455, section # 5.5.1:
# "When sending a Close frame in response, the endpoint typically echos the
# status code it received."
# - Without this, pywebsocket replies with 1000 to any close code.
#
# Note that this function is only called when the client initiates the close
def web_socket_passive_closing_handshake(request):
if request.ws_close_code == 1005:
return None, None
return request.ws_close_code, request.ws_close_reason
def web_socket_transfer_data(request):
if request.ws_protocol == "test-2.1" or request.ws_protocol == "test-2.2":
msgutil.close_connection(request)
elif request.ws_protocol == "test-6":
resp = "wrong message"
if msgutil.receive_message(request) == "1":
resp = "2"
msgutil.send_message(request, six.ensure_text(resp))
resp = "wrong message"
if msgutil.receive_message(request) == "3":
resp = "4"
msgutil.send_message(request, six.ensure_text(resp))
resp = "wrong message"
if msgutil.receive_message(request) == "5":
resp = (
b"\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a".decode(
"utf-8"
)
)
msgutil.send_message(request, six.ensure_text(resp))
msgutil.close_connection(request)
elif request.ws_protocol == "test-7":
msgutil.send_message(request, "test-7 data")
elif request.ws_protocol == "test-10":
msgutil.close_connection(request)
elif request.ws_protocol == "test-11":
resp = "wrong message"
if msgutil.receive_message(request) == "client data":
resp = "server data"
msgutil.send_message(request, six.ensure_text(resp))
elif request.ws_protocol == "test-12":
msg = msgutil.receive_message(request)
if msg == u"a\ufffdb":
# converted unpaired surrogate in UTF-16 to UTF-8 OK
msgutil.send_message(request, "SUCCESS")
else:
msgutil.send_message(
request,
"FAIL got '" + msg + "' instead of string with replacement char'",
)
elif request.ws_protocol == "test-13":
# first one binary message containing the byte 0x61 ('a')
request.connection.write(b"\xff\x01\x61")
# after a bad utf8 message
request.connection.write(b"\x01\x61\xff")
msgutil.close_connection(request)
elif request.ws_protocol == "test-14":
msgutil.close_connection(request)
msgutil.send_message(request, "server data")
elif request.ws_protocol == "test-15":
# DISABLED: close_connection hasn't supported 2nd 'abort' argument for a
# long time. Passing extra arg was causing exception, which conveniently
# caused abort :) but as of pywebsocket v606 raising an exception here no
# longer aborts, and there's no obvious way to close TCP connection w/o
# sending websocket CLOSE.
raise RuntimeError("test-15 should be disabled for now")
# msgutil.close_connection(request, True) # OBSOLETE 2nd arg
# return
elif request.ws_protocol == "test-17" or request.ws_protocol == "test-21":
time.sleep(2)
resp = "wrong message"
if msgutil.receive_message(request) == "client data":
resp = "server data"
msgutil.send_message(request, six.ensure_text(resp))
time.sleep(2)
msgutil.close_connection(request)
elif request.ws_protocol == "test-20":
msgutil.send_message(request, "server data")
msgutil.close_connection(request)
elif request.ws_protocol == "test-34":
request.ws_stream.close_connection(1001, "going away now")
elif request.ws_protocol == "test-35a":
while not request.client_terminated:
msgutil.receive_message(request)
global test35code
test35code = request.ws_close_code
global test35reason
test35reason = request.ws_close_reason
elif request.ws_protocol == "test-35b":
request.ws_stream.close_connection(test35code + 1, test35reason)
elif request.ws_protocol == "test-37b":
while not request.client_terminated:
msgutil.receive_message(request)
global test37code
test37code = request.ws_close_code
global test37reason
test37reason = request.ws_close_reason
elif request.ws_protocol == "test-37c":
request.ws_stream.close_connection(test37code, test37reason)
elif request.ws_protocol == "test-42":
# Echo back 3 messages
msgutil.send_message(request, msgutil.receive_message(request))
msgutil.send_message(request, msgutil.receive_message(request))
msgutil.send_message(request, msgutil.receive_message(request))
elif request.ws_protocol == "test-44":
rcv = six.ensure_text(msgutil.receive_message(request))
# check we received correct binary msg
if len(rcv) == 3 and ord(rcv[0]) == 5 and ord(rcv[1]) == 0 and ord(rcv[2]) == 7:
# reply with binary msg 0x04
msgutil.send_message(request, b"\x00\x04", True, True)
else:
msgutil.send_message(request, "incorrect binary msg received!")
elif request.ws_protocol == "test-45":
rcv = msgutil.receive_message(request)
# check we received correct binary msg
if six.ensure_text(rcv) == "flob":
# send back same blob as binary msg
msgutil.send_message(request, rcv, True, True)
else:
msgutil.send_message(
request, "incorrect binary msg received: '" + rcv + "'"
)
elif request.ws_protocol == "test-46":
msgutil.send_message(request, "client must drop this if close was called")
while not request.client_terminated:
msgutil.receive_message(request)
|