4 from nose.tools import eq_
7 from eventlet import event
8 from eventlet import websocket
9 from eventlet.green import httplib
10 from eventlet.green import socket
11 from eventlet import websocket
12 from eventlet.support import six
14 from tests.wsgi_test import _TestBase
19 if ws.path == '/echo':
25 elif ws.path == '/range':
29 elif ws.path == '/error':
30 # some random socket error that we shouldn't normally get
31 raise socket.error(errno.ENOTSOCK)
35 wsapp = websocket.WebSocketWSGI(handle)
38 class TestWebSocket(_TestBase):
44 def test_incomplete_headers_13(self):
45 headers = dict(kv.split(': ') for kv in [
47 # NOTE: intentionally no connection header
48 "Host: localhost:%s" % self.port,
49 "Origin: http://localhost:%s" % self.port,
50 "Sec-WebSocket-Version: 13",
52 http = httplib.HTTPConnection('localhost', self.port)
53 http.request("GET", "/echo", headers=headers)
54 resp = http.getresponse()
56 self.assertEqual(resp.status, 400)
57 self.assertEqual(resp.getheader('connection'), 'close')
58 self.assertEqual(resp.read(), b'')
61 headers = dict(kv.split(': ') for kv in [
63 "Connection: Upgrade",
64 "Host: localhost:%s" % self.port,
65 "Origin: http://localhost:%s" % self.port,
66 "Sec-WebSocket-Version: 13",
68 http = httplib.HTTPConnection('localhost', self.port)
69 http.request("GET", "/echo", headers=headers)
70 resp = http.getresponse()
72 self.assertEqual(resp.status, 400)
73 self.assertEqual(resp.getheader('connection'), 'close')
74 self.assertEqual(resp.read(), b'')
77 headers = dict(kv.split(': ') for kv in [
78 "Connection: Upgrade",
79 "Host: localhost:%s" % self.port,
80 "Origin: http://localhost:%s" % self.port,
81 "Sec-WebSocket-Version: 13",
83 http = httplib.HTTPConnection('localhost', self.port)
84 http.request("GET", "/echo", headers=headers)
85 resp = http.getresponse()
87 self.assertEqual(resp.status, 400)
88 self.assertEqual(resp.getheader('connection'), 'close')
89 self.assertEqual(resp.read(), b'')
91 def test_correct_upgrade_request_13(self):
92 for http_connection in ['Upgrade', 'UpGrAdE', 'keep-alive, Upgrade']:
96 "Connection: %s" % http_connection,
97 "Host: localhost:%s" % self.port,
98 "Origin: http://localhost:%s" % self.port,
99 "Sec-WebSocket-Version: 13",
100 "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
102 sock = eventlet.connect(('localhost', self.port))
104 sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
105 result = sock.recv(1024)
106 # The server responds the correct Websocket handshake
107 print('Connection string: %r' % http_connection)
108 self.assertEqual(result, six.b('\r\n'.join([
109 'HTTP/1.1 101 Switching Protocols',
110 'Upgrade: websocket',
111 'Connection: Upgrade',
112 'Sec-WebSocket-Accept: ywSyWXCPNsDxLrQdQrn5RFNRfBU=\r\n\r\n',
115 def test_send_recv_13(self):
117 "GET /echo HTTP/1.1",
118 "Upgrade: websocket",
119 "Connection: Upgrade",
120 "Host: localhost:%s" % self.port,
121 "Origin: http://localhost:%s" % self.port,
122 "Sec-WebSocket-Version: 13",
123 "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
125 sock = eventlet.connect(
126 ('localhost', self.port))
128 sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
130 ws = websocket.RFC6455WebSocket(sock, {}, client=True)
132 eq_(ws.wait(), b'hello')
133 ws.send(b'hello world!\x01')
134 ws.send(u'hello world again!')
135 eq_(ws.wait(), b'hello world!\x01')
136 eq_(ws.wait(), u'hello world again!')
140 def test_breaking_the_connection_13(self):
141 error_detected = [False]
142 done_with_request = event.Event()
145 def error_detector(environ, start_response):
148 return site(environ, start_response)
150 error_detected[0] = True
153 done_with_request.send(True)
154 self.site = error_detector
157 "GET /echo HTTP/1.1",
158 "Upgrade: websocket",
159 "Connection: Upgrade",
160 "Host: localhost:%s" % self.port,
161 "Origin: http://localhost:%s" % self.port,
162 "Sec-WebSocket-Version: 13",
163 "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
165 sock = eventlet.connect(
166 ('localhost', self.port))
167 sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
168 sock.recv(1024) # get the headers
169 sock.close() # close while the app is running
170 done_with_request.wait()
171 assert not error_detected[0]
173 def test_client_closing_connection_13(self):
174 error_detected = [False]
175 done_with_request = event.Event()
178 def error_detector(environ, start_response):
181 return site(environ, start_response)
183 error_detected[0] = True
186 done_with_request.send(True)
187 self.site = error_detector
190 "GET /echo HTTP/1.1",
191 "Upgrade: websocket",
192 "Connection: Upgrade",
193 "Host: localhost:%s" % self.port,
194 "Origin: http://localhost:%s" % self.port,
195 "Sec-WebSocket-Version: 13",
196 "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
198 sock = eventlet.connect(
199 ('localhost', self.port))
200 sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
201 sock.recv(1024) # get the headers
202 closeframe = struct.pack('!BBIH', 1 << 7 | 8, 1 << 7 | 2, 0, 1000)
203 sock.sendall(closeframe) # "Close the connection" packet.
204 done_with_request.wait()
205 assert not error_detected[0]
207 def test_client_invalid_packet_13(self):
208 error_detected = [False]
209 done_with_request = event.Event()
212 def error_detector(environ, start_response):
215 return site(environ, start_response)
217 error_detected[0] = True
220 done_with_request.send(True)
221 self.site = error_detector
224 "GET /echo HTTP/1.1",
225 "Upgrade: websocket",
226 "Connection: Upgrade",
227 "Host: localhost:%s" % self.port,
228 "Origin: http://localhost:%s" % self.port,
229 "Sec-WebSocket-Version: 13",
230 "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
232 sock = eventlet.connect(
233 ('localhost', self.port))
234 sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
235 sock.recv(1024) # get the headers
236 sock.sendall(b'\x07\xff') # Weird packet.
237 done_with_request.wait()
238 assert not error_detected[0]