Add python-eventlet package to MOS 9.0 repository
[packages/trusty/python-eventlet.git] / python-eventlet / tests / websocket_new_test.py
1 import errno
2 import struct
3
4 import eventlet
5 from eventlet import event
6 from eventlet import websocket
7 from eventlet.green import httplib
8 from eventlet.green import socket
9 from eventlet.support import six
10
11 import tests.wsgi_test
12
13
14 # demo app
15 def handle(ws):
16     if ws.path == '/echo':
17         while True:
18             m = ws.wait()
19             if m is None:
20                 break
21             ws.send(m)
22     elif ws.path == '/range':
23         for i in range(10):
24             ws.send("msg %d" % i)
25             eventlet.sleep(0.01)
26     elif ws.path == '/error':
27         # some random socket error that we shouldn't normally get
28         raise socket.error(errno.ENOTSOCK)
29     else:
30         ws.close()
31
32 wsapp = websocket.WebSocketWSGI(handle)
33
34
35 class TestWebSocket(tests.wsgi_test._TestBase):
36     TEST_TIMEOUT = 5
37
38     def set_site(self):
39         self.site = wsapp
40
41     def test_incomplete_headers_13(self):
42         headers = dict(kv.split(': ') for kv in [
43             "Upgrade: websocket",
44             # NOTE: intentionally no connection header
45             "Host: %s:%s" % self.server_addr,
46             "Origin: http://%s:%s" % self.server_addr,
47             "Sec-WebSocket-Version: 13",
48         ])
49         http = httplib.HTTPConnection(*self.server_addr)
50         http.request("GET", "/echo", headers=headers)
51         resp = http.getresponse()
52
53         self.assertEqual(resp.status, 400)
54         self.assertEqual(resp.getheader('connection'), 'close')
55         self.assertEqual(resp.read(), b'')
56
57         # Now, miss off key
58         headers = dict(kv.split(': ') for kv in [
59             "Upgrade: websocket",
60             "Connection: Upgrade",
61             "Host: %s:%s" % self.server_addr,
62             "Origin: http://%s:%s" % self.server_addr,
63             "Sec-WebSocket-Version: 13",
64         ])
65         http = httplib.HTTPConnection(*self.server_addr)
66         http.request("GET", "/echo", headers=headers)
67         resp = http.getresponse()
68
69         self.assertEqual(resp.status, 400)
70         self.assertEqual(resp.getheader('connection'), 'close')
71         self.assertEqual(resp.read(), b'')
72
73         # No Upgrade now
74         headers = dict(kv.split(': ') for kv in [
75             "Connection: Upgrade",
76             "Host: %s:%s" % self.server_addr,
77             "Origin: http://%s:%s" % self.server_addr,
78             "Sec-WebSocket-Version: 13",
79         ])
80         http = httplib.HTTPConnection(*self.server_addr)
81         http.request("GET", "/echo", headers=headers)
82         resp = http.getresponse()
83
84         self.assertEqual(resp.status, 400)
85         self.assertEqual(resp.getheader('connection'), 'close')
86         self.assertEqual(resp.read(), b'')
87
88     def test_correct_upgrade_request_13(self):
89         for http_connection in ['Upgrade', 'UpGrAdE', 'keep-alive, Upgrade']:
90             connect = [
91                 "GET /echo HTTP/1.1",
92                 "Upgrade: websocket",
93                 "Connection: %s" % http_connection,
94                 "Host: %s:%s" % self.server_addr,
95                 "Origin: http://%s:%s" % self.server_addr,
96                 "Sec-WebSocket-Version: 13",
97                 "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
98             ]
99             sock = eventlet.connect(self.server_addr)
100
101             sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
102             result = sock.recv(1024)
103             # The server responds the correct Websocket handshake
104             print('Connection string: %r' % http_connection)
105             self.assertEqual(result, six.b('\r\n'.join([
106                 'HTTP/1.1 101 Switching Protocols',
107                 'Upgrade: websocket',
108                 'Connection: Upgrade',
109                 'Sec-WebSocket-Accept: ywSyWXCPNsDxLrQdQrn5RFNRfBU=\r\n\r\n',
110             ])))
111
112     def test_send_recv_13(self):
113         connect = [
114             "GET /echo HTTP/1.1",
115             "Upgrade: websocket",
116             "Connection: Upgrade",
117             "Host: %s:%s" % self.server_addr,
118             "Origin: http://%s:%s" % self.server_addr,
119             "Sec-WebSocket-Version: 13",
120             "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
121         ]
122         sock = eventlet.connect(self.server_addr)
123         sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
124         sock.recv(1024)
125         ws = websocket.RFC6455WebSocket(sock, {}, client=True)
126         ws.send(b'hello')
127         assert ws.wait() == b'hello'
128         ws.send(b'hello world!\x01')
129         ws.send(u'hello world again!')
130         assert ws.wait() == b'hello world!\x01'
131         assert ws.wait() == u'hello world again!'
132         ws.close()
133         eventlet.sleep(0.01)
134
135     def test_breaking_the_connection_13(self):
136         error_detected = [False]
137         done_with_request = event.Event()
138         site = self.site
139
140         def error_detector(environ, start_response):
141             try:
142                 try:
143                     return site(environ, start_response)
144                 except:
145                     error_detected[0] = True
146                     raise
147             finally:
148                 done_with_request.send(True)
149         self.site = error_detector
150         self.spawn_server()
151         connect = [
152             "GET /echo HTTP/1.1",
153             "Upgrade: websocket",
154             "Connection: Upgrade",
155             "Host: %s:%s" % self.server_addr,
156             "Origin: http://%s:%s" % self.server_addr,
157             "Sec-WebSocket-Version: 13",
158             "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
159         ]
160         sock = eventlet.connect(self.server_addr)
161         sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
162         sock.recv(1024)  # get the headers
163         sock.close()  # close while the app is running
164         done_with_request.wait()
165         assert not error_detected[0]
166
167     def test_client_closing_connection_13(self):
168         error_detected = [False]
169         done_with_request = event.Event()
170         site = self.site
171
172         def error_detector(environ, start_response):
173             try:
174                 try:
175                     return site(environ, start_response)
176                 except:
177                     error_detected[0] = True
178                     raise
179             finally:
180                 done_with_request.send(True)
181         self.site = error_detector
182         self.spawn_server()
183         connect = [
184             "GET /echo HTTP/1.1",
185             "Upgrade: websocket",
186             "Connection: Upgrade",
187             "Host: %s:%s" % self.server_addr,
188             "Origin: http://%s:%s" % self.server_addr,
189             "Sec-WebSocket-Version: 13",
190             "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
191         ]
192         sock = eventlet.connect(self.server_addr)
193         sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
194         sock.recv(1024)  # get the headers
195         closeframe = struct.pack('!BBIH', 1 << 7 | 8, 1 << 7 | 2, 0, 1000)
196         sock.sendall(closeframe)  # "Close the connection" packet.
197         done_with_request.wait()
198         assert not error_detected[0]
199
200     def test_client_invalid_packet_13(self):
201         error_detected = [False]
202         done_with_request = event.Event()
203         site = self.site
204
205         def error_detector(environ, start_response):
206             try:
207                 try:
208                     return site(environ, start_response)
209                 except:
210                     error_detected[0] = True
211                     raise
212             finally:
213                 done_with_request.send(True)
214         self.site = error_detector
215         self.spawn_server()
216         connect = [
217             "GET /echo HTTP/1.1",
218             "Upgrade: websocket",
219             "Connection: Upgrade",
220             "Host: %s:%s" % self.server_addr,
221             "Origin: http://%s:%s" % self.server_addr,
222             "Sec-WebSocket-Version: 13",
223             "Sec-WebSocket-Key: d9MXuOzlVQ0h+qRllvSCIg==",
224         ]
225         sock = eventlet.connect(self.server_addr)
226         sock.sendall(six.b('\r\n'.join(connect) + '\r\n\r\n'))
227         sock.recv(1024)  # get the headers
228         sock.sendall(b'\x07\xff')  # Weird packet.
229         done_with_request.wait()
230         assert not error_detected[0]