def test_protocol_version(message, transport): message.headers.extend([('Upgrade', 'websocket'), ('Connection', 'upgrade')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) message.headers.extend([('Upgrade', 'websocket'), ('Connection', 'upgrade'), ('Sec-Websocket-Version', '1')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport)
def test_protocol_version(message, transport): message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '1')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport)
def handle_request(self, message, payload): websock_chan_id = message.headers.get('websock-chan-id') upgrade = 'websocket' in message.headers.get('UPGRADE', '').lower() if upgrade: status, headers, parser, writer = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response(self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() connection = yield from asyncio_redis.Connection.create( host='127.0.0.1', port=6379) subscriber = yield from connection.start_subscribe() yield from subscriber.subscribe([str(websock_chan_id)]) while True: try: data = yield from subscriber.next_published() print(data) writer.send(data.value.encode()) except Exception as e: print(e) break self.clients[websock_chan_id].remove(writer)
def _handle_websocket(self, message, payload): # websocket handshake logging.info("WS Connect") status, headers, parser, writer = websocket.do_handshake( message.method, message.headers, self.transport) resp = Response(self.transport, status) resp.add_headers(*headers) resp.send_headers() dataqueue = self.reader.set_parser(parser) while True: try: msg = yield from dataqueue.read() except EofStream: # client dropped connection break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_CLOSE: break elif msg.tp == websocket.MSG_TEXT: command, args = json.loads(msg.data) logging.info("Got Command: {} ({})".format(command, args)) self.send_command(command, *args) result = yield from self.read_result() writer.send(result) logging.info("WS Disconnect") self.send_command('stop')
def handle_request(self, message, payload): websock_chan_id = message.headers.get('websock-chan-id') upgrade = 'websocket' in message.headers.get('UPGRADE', '').lower() if upgrade: status, headers, parser, writer = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response( self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() connection = yield from asyncio_redis.Connection.create(host='127.0.0.1', port=6379) subscriber = yield from connection.start_subscribe() yield from subscriber.subscribe([str(websock_chan_id)]) while True: try: data = yield from subscriber.next_published() print(data) writer.send(data.value.encode()) except Exception as e: print(e) break self.clients[websock_chan_id].remove(writer)
def handle_request(self, message, payload): print('Client connected') upgrade = 'websocket' in message.headers.get('UPGRADE', '').lower() if not upgrade: response = aiohttp.Response( self.writer, 426, http_version=message.version) response.add_header('Content-type', 'application/json') response.send_headers() response.write(json.dumps({'error': 'WebSockets Required'})) yield from response.write_eof() return print ('Upgrading connection') # websocket handshake status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response( self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() # install websocket parser self._reader = self.reader.set_parser(parser) self._writer = writer # Expect # {"type": "handshake", "client": "<name>", "protocol" : "<protocol>"} try: msg = yield from self.get_json() assert msg['type'] == 'handshake' protocol = msg['protocol'] print(protocol) client = msg['client'] except: traceback.print_exc() self.send_json(error='Invalid Handshake') return print('{} client connected'.format(client)) self.send_json(type='handshake', message='Connected') if protocol == 'nlu': yield from self.handle_nlu() elif protocol == 'muse': yield from self.handle_muse() elif protocol == 'muse_src': yield from self.handle_muse_src() else: pass # return error writer.close()
def test_handshake_protocol_agreement(message, transport): '''Tests if the right protocol is selected given multiple''' best_proto = 'worse_proto' wanted_protos = ['best', 'chat', 'worse_proto'] server_protos = 'worse_proto,chat' message.headers.extend(gen_ws_headers(server_protos)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( message.method, message.headers, transport, protocols=wanted_protos) assert protocol == best_proto
def _r(request, *args, **kwargs): status, headers, parser, writer, _ = websocket.do_handshake( request.message.method, request.message.headers, request.handler.transport) resp = aiohttp.Response(request.handler.writer, status, http_version=request.message.version) resp.add_headers(*headers) resp.send_headers() request.writer = writer request.reader = request.handler.reader.set_parser(parser) yield from fn(request, *args, **kwargs)
def test_handshake_protocol_agreement(self): '''Tests if the right protocol is selected given multiple''' best_proto = 'worse_proto' wanted_protos = ['best', 'chat', 'worse_proto'] server_protos = 'worse_proto,chat' self.headers.extend(self.gen_ws_headers(server_protos)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( self.message.method, self.message.headers, self.transport, protocols=wanted_protos) self.assertEqual(protocol, best_proto)
def test_handshake_protocol_agreement(self): """Tests if the right protocol is selected given multiple""" best_proto = "chat" wanted_protos = ["best", "chat", "worse_proto"] server_protos = "worse_proto,chat" self.headers.extend(self.gen_ws_headers(server_protos)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( self.message.method, self.message.headers, self.transport, protocols=wanted_protos ) self.assertEqual(protocol, best_proto)
def test_handshake_protocol_unsupported(log, message, transport): '''Tests if a protocol mismatch handshake warns and returns None''' proto = 'chat' message.headers.extend(gen_ws_headers('test')[0]) with log('aiohttp.websocket') as ctx: _, _, _, _, protocol = websocket.do_handshake( message.method, message.headers, transport, protocols=[proto]) assert protocol is None assert (ctx.records[-1].msg == 'Client protocols %r don’t overlap server-known ones %r')
def test_handshake(message, transport): hdrs, sec_key = gen_ws_headers() message.headers.extend(hdrs) status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, transport) assert status == 101 assert protocol is None key = base64.b64encode( hashlib.sha1(sec_key.encode() + websocket.WS_KEY).digest()) headers = dict(headers) assert headers['SEC-WEBSOCKET-ACCEPT'] == key.decode()
def test_handshake(self): hdrs, sec_key = self.gen_ws_headers() self.headers.extend(hdrs) status, headers, parser, writer, protocol = websocket.do_handshake( self.message.method, self.message.headers, self.transport) self.assertEqual(status, 101) self.assertIsNone(protocol) key = base64.b64encode( hashlib.sha1(sec_key.encode() + websocket.WS_KEY).digest()) headers = dict(headers) self.assertEqual(headers['SEC-WEBSOCKET-ACCEPT'], key.decode())
def test_handshake_protocol(message, transport): '''Tests if one protocol is returned by do_handshake''' proto = 'chat' message.headers.extend(gen_ws_headers(proto)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( message.method, message.headers, transport, protocols=[proto]) assert protocol == proto # also test if we reply with the protocol resp_headers = dict(resp_headers) assert resp_headers['SEC-WEBSOCKET-PROTOCOL'] == proto
def test_handshake_protocol(self): '''Tests if one protocol is returned by do_handshake''' proto = 'chat' self.headers.extend(self.gen_ws_headers(proto)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake( self.message.method, self.message.headers, self.transport, protocols=[proto]) self.assertEqual(protocol, proto) # also test if we reply with the protocol resp_headers = dict(resp_headers) self.assertEqual(resp_headers['SEC-WEBSOCKET-PROTOCOL'], proto)
def test_handshake_protocol_unsupported(log, message, transport): '''Tests if a protocol mismatch handshake warns and returns None''' proto = 'chat' message.headers.extend(gen_ws_headers('test')[0]) with log('aiohttp.websocket') as ctx: _, _, _, _, protocol = websocket.do_handshake(message.method, message.headers, transport, protocols=[proto]) assert protocol is None assert (ctx.records[-1].msg == 'Client protocols %r don’t overlap server-known ones %r')
def test_handshake_protocol(message, transport): '''Tests if one protocol is returned by do_handshake''' proto = 'chat' message.headers.extend(gen_ws_headers(proto)[0]) _, resp_headers, _, _, protocol = websocket.do_handshake(message.method, message.headers, transport, protocols=[proto]) assert protocol == proto # also test if we reply with the protocol resp_headers = dict(resp_headers) assert resp_headers['SEC-WEBSOCKET-PROTOCOL'] == proto
def test_handshake(self): sec_key = base64.b64encode(os.urandom(16)).decode() self.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13'), ('SEC-WEBSOCKET-KEY', sec_key)]) status, headers, parser, writer = websocket.do_handshake( self.message.method, self.message.headers, self.transport) self.assertEqual(status, 101) key = base64.b64encode( hashlib.sha1(sec_key.encode() + websocket.WS_KEY).digest()) headers = dict(headers) self.assertEqual(headers['SEC-WEBSOCKET-ACCEPT'], key.decode())
def response(environ, start_response): reader = self.request.environ['async.reader'] writer = self.request.environ['async.writer'] req_headers = self.request.headers try: shake_result = websocket.do_handshake('GET', req_headers, writer) except HttpBadRequest: error = BadRequest('websocket upgrade expected') return error(environ, start_response) status, headers, parser, writer = shake_result write = start_response('%s Switching Protocols' % status, headers) datastream = reader.set_parser(parser) end_future = asyncio.Future() asyncio.Task(self._task(datastream, writer, end_future)) return [end_future]
def test_handshake_protocol_unsupported(self, m_websocket_warn): '''Tests if a protocol mismatch handshake warns and returns None''' warn_called = False def websocket_warn(msg, *fmts): nonlocal warn_called warn_called = True m_websocket_warn.side_effect = websocket_warn proto = 'chat' self.headers.extend(self.gen_ws_headers('test')[0]) _, _, _, _, protocol = websocket.do_handshake( self.message.method, self.message.headers, self.transport, protocols=[proto]) self.assertTrue(warn_called, 'protocol mismatch didn’t warn') self.assertIsNone(protocol)
def test_protocol_key(message, transport): message.headers.extend([('Upgrade', 'websocket'), ('Connection', 'upgrade'), ('Sec-Websocket-Version', '13')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) message.headers.extend([('Upgrade', 'websocket'), ('Connection', 'upgrade'), ('Sec-Websocket-Version', '13'), ('Sec-Websocket-Key', '123')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) sec_key = base64.b64encode(os.urandom(2)) message.headers.extend([('Upgrade', 'websocket'), ('Connection', 'upgrade'), ('Sec-Websocket-Version', '13'), ('Sec-Websocket-Key', sec_key.decode())]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport)
def test_protocol_key(message, transport): message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13'), ('SEC-WEBSOCKET-KEY', '123')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport) sec_key = base64.b64encode(os.urandom(2)) message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'upgrade'), ('SEC-WEBSOCKET-VERSION', '13'), ('SEC-WEBSOCKET-KEY', sec_key.decode())]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport)
def handle_request(self, message, payload): upgrade = "websocket" in message.headers.get("UPGRADE", "").lower() if upgrade: # websocket handshake status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, self.transport ) resp = aiohttp.Response(self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() # install websocket parser dataqueue = self.reader.set_parser(parser) # notify everybody print("{}: Someone joined.".format(os.getpid())) for wsc in self.clients: wsc.send(b"Someone joined.") self.clients.append(writer) self.parent.send(b"Someone joined.") # chat dispatcher while True: try: msg = yield from dataqueue.read() except: # client dropped connection break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_TEXT: data = msg.data.strip() print("{}: {}".format(os.getpid(), data)) for wsc in self.clients: if wsc is not writer: wsc.send(data.encode()) self.parent.send(data) elif msg.tp == websocket.MSG_CLOSE: break # notify everybody print("{}: Someone disconnected.".format(os.getpid())) self.parent.send(b"Someone disconnected.") self.clients.remove(writer) for wsc in self.clients: wsc.send(b"Someone disconnected.") else: # send html page with js chat response = aiohttp.Response(self.writer, 200, http_version=message.version) response.add_header("Transfer-Encoding", "chunked") response.add_header("Content-type", "text/html") response.send_headers() try: with open(WS_FILE, "rb") as fp: chunk = fp.read(8192) while chunk: if not response.write(chunk): break chunk = fp.read(8192) except OSError: response.write(b"Cannot open") yield from response.write_eof() if response.keep_alive(): self.keep_alive(True)
def test_not_get(message, transport): with pytest.raises(errors.HttpProcessingError): websocket.do_handshake('POST', message.headers, transport)
def test_no_upgrade(message, transport): with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport)
def handle_request(self, message, payload): upgrade = 'websocket' in message.headers.get('UPGRADE', '').lower() if upgrade: # websocket handshake status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response(self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() # install websocket parser dataqueue = self.reader.set_parser(parser) # notify everybody print('{}: Someone joined.'.format(os.getpid())) for wsc in self.clients: wsc.send(b'Someone joined.') self.clients.append(writer) self.parent.send(b'Someone joined.') # chat dispatcher while True: try: msg = yield from dataqueue.read() except: # client dropped connection break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_TEXT: data = msg.data.strip() print('{}: {}'.format(os.getpid(), data)) for wsc in self.clients: if wsc is not writer: wsc.send(data.encode()) self.parent.send(data) elif msg.tp == websocket.MSG_CLOSE: break # notify everybody print('{}: Someone disconnected.'.format(os.getpid())) self.parent.send(b'Someone disconnected.') self.clients.remove(writer) for wsc in self.clients: wsc.send(b'Someone disconnected.') else: # send html page with js chat response = aiohttp.Response(self.writer, 200, http_version=message.version) response.add_header('Transfer-Encoding', 'chunked') response.add_header('Content-type', 'text/html') response.send_headers() try: with open(WS_FILE, 'rb') as fp: chunk = fp.read(8192) while chunk: if not response.write(chunk): break chunk = fp.read(8192) except OSError: response.write(b'Cannot open') yield from response.write_eof() if response.keep_alive(): self.keep_alive(True)
def test_no_connection(message, transport): message.headers.extend([('UPGRADE', 'websocket'), ('CONNECTION', 'keep-alive')]) with pytest.raises(errors.HttpBadRequest): websocket.do_handshake(message.method, message.headers, transport)
def handle_request(self, message, payload): upgrade = False for hdr, val in message.headers: if hdr == 'UPGRADE': upgrade = 'websocket' in val.lower() break if upgrade: # websocket handshake status, headers, parser, writer = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response(self.transport, status) resp.add_headers(*headers) resp.send_headers() # install websocket parser dataqueue = self.stream.set_parser(parser) # notify everybody print('{}: Someone joined.'.format(os.getpid())) for wsc in self.clients: wsc.send(b'Someone joined.') self.clients.append(writer) self.parent.send(b'Someone joined.') # chat dispatcher while True: try: msg = yield from dataqueue.read() except aiohttp.EofStream: # client droped connection break if msg.tp == websocket.MSG_PING: writer.pong() elif msg.tp == websocket.MSG_TEXT: data = msg.data.strip() print('{}: {}'.format(os.getpid(), data)) for wsc in self.clients: if wsc is not writer: wsc.send(data.encode()) self.parent.send(data) elif msg.tp == websocket.MSG_CLOSE: break # notify everybody print('{}: Someone disconnected.'.format(os.getpid())) self.parent.send(b'Someone disconnected.') self.clients.remove(writer) for wsc in self.clients: wsc.send(b'Someone disconnected.') else: # send html page with js chat response = aiohttp.Response(self.transport, 200) response.add_header('Transfer-Encoding', 'chunked') response.add_header('Content-type', 'text/html') response.send_headers() try: with open(WS_FILE, 'rb') as fp: chunk = fp.read(8196) while chunk: if not response.write(chunk): break chunk = fp.read(8196) except OSError: response.write(b'Cannot open') response.write_eof() if response.keep_alive(): self.keep_alive(True)
def handle_request(self, message, payload): print('Client connected') upgrade = 'websocket' in message.headers.get('UPGRADE', '').lower() if not upgrade: response = aiohttp.Response( self.writer, 426, http_version=message.version) response.add_header('Content-type', 'application/json') response.send_headers() response.write(json.dumps({'error': 'WebSockets Required'})) yield from response.write_eof() return print ('Upgrading connection') # websocket handshake status, headers, parser, writer, protocol = websocket.do_handshake( message.method, message.headers, self.transport) resp = aiohttp.Response( self.writer, status, http_version=message.version) resp.add_headers(*headers) resp.send_headers() # install websocket parser self._reader = self.reader.set_parser(parser) self._writer = writer # Expect # {"type": "handshake", "client": "<name>"} try: msg = yield from self.get_json() assert msg['type'] == 'handshake' client = msg['client'] except: traceback.print_exc() self.send_json(error='Invalid Handshake') return print('{} client connected'.format(client)) self.send_json(type='handshake', message='Connected') encoder = speex.WBEncoder() frame_size = encoder.frame_size * 2 # two bytes per sample client = WebsocketConnection() yield from client.connect(URL, APP_ID, binascii.unhexlify(APP_KEY)) client.send_message({ 'message': 'connect', 'device_id': DEVICE_ID, 'codec': 'audio/x-speex;mode=wb' }) tp, msg = yield from client.receive() log(msg) # Should be a connected message while True: print('Waiting for NLU transaction') # Expect: # {"type": "nlu", "command": "start"} try: msg = yield from self.get_json() assert msg['type'] == 'nlu' assert msg['command'] == 'start' except: traceback.print_exc() self.send_json(error='Expected NLU transaction') return print('Starting NLU transaction') self.transaction_id += 1 client.send_message({ 'message': 'query_begin', 'transaction_id': self.transaction_id, 'command': 'NDSP_ASR_APP_CMD', 'language': 'eng-USA', 'context_tag': CONTEXT_TAG, }) client.send_message({ 'message': 'query_parameter', 'transaction_id': self.transaction_id, 'parameter_name': 'AUDIO_INFO', 'parameter_type': 'audio', 'audio_id': self.transaction_id }) client.send_message({ 'message': 'query_end', 'transaction_id': self.transaction_id }) client.send_message({ 'message': 'audio', 'audio_id': self.transaction_id, }) print('Streaming audio') while True: try: msg = yield from self._reader.read() if msg.tp == websocket.MSG_TEXT: break; assert msg.tp == websocket.MSG_BINARY assert len(msg.data) == frame_size except: traceback.print_exc() self.send_json(error='Bad Audio Format') return frame = encoder.encode(msg.data) client.send_audio(frame) # Expect: # {"type": "nlu", "command": "end"} try: assert msg.tp == websocket.MSG_TEXT msg = json.loads(msg.data) assert msg['type'] == 'nlu' assert msg['command'] == 'stop' except: traceback.print_exc() self.send_json(error='Expected NLU transaction terminator') return print('Done streaming audio') client.send_message({ 'message': 'audio_end', 'audio_id': self.transaction_id, }) print('Waiting for result') while True: tp,msg = yield from client.receive() log(msg) if msg['message'] == 'query_end': break client.close() writer.close()