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