def handshake(self, response): """Websocket handshake, handled by `websockets` """ def get_header(k): return self.request.headers.get(k.upper(), '') def set_header(k, v): response.headers[k] = v try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise RuntimeError('Invalid websocket request') subprotocol = None ws_protocol = get_header('Sec-Websocket-Protocol') subprotocols = self.request.route.payload.get('subprotocols') if subprotocols and ws_protocol: # select a subprotocol client_subprotocols = tuple( (p.strip() for p in ws_protocol.split(','))) for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # Return the subprotocol agreed upon, if any self.subprotocol = subprotocol
async def websocket_handshake(self, request): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue) self.websocket.connection_made(request.transport) return self.websocket
async def websocket_handshake(self, request): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue ) self.websocket.connection_made(request.transport) return self.websocket
def __init__(self, request, switch_protocols): http11 = request._version == (1, 1) get_header = lambda k: dict(request.headers)[k.upper()] key = handshake.check_request(get_header) if not http11 or not key: super('Invalid WebSocket handshake.\n', status=400) else: headers = dict() set_header = headers.__setitem__ handshake.build_response(set_header, key) self.switch_protocols = switch_protocols super().__init__(status=101, headers=headers) self._keep_alive = True request.transport.close = switch_protocols
def __init__(self, environ, switch_protocols): super().__init__() http_1_1 = environ['SERVER_PROTOCOL'] == 'HTTP/1.1' get_header = lambda k: environ['HTTP_' + k.upper().replace('-', '_')] key = handshake.check_request(get_header) if not http_1_1 or key is None: self.status_code = 400 self.content = "Invalid WebSocket handshake.\n" else: self._headers = {} # Reset headers (private API!) set_header = self.__setitem__ handshake.build_response(set_header, key) self.close = switch_protocols
async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: raise InvalidUsage("Invalid websocket request") subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = MyWebSocketCommonProtocol( close_timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit, ping_interval=self.websocket_ping_interval, ping_timeout=self.websocket_ping_timeout, ) # Following two lines are required for websockets 8.x self.websocket.is_client = False self.websocket.side = "server" self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') subprotocol = None if subprotocols and 'Sec-Websocket-Protocol' in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers['Sec-Websocket-Protocol'].split(',') ] for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def websocket_handshake(self, request, subprotocols=None): headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: msg = "Invalid websocket request received." if self.debug: msg += "\n" + traceback.format_exc() self.logger.error(msg) self.on_response(msg) raise RuntimeError(msg) subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.config.ws_timeout, max_size=self.config.ws_max_size, max_queue=self.config.ws_max_queue, read_limit=self.config.ws_read_limit, write_limit=self.config.ws_write_limit, ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = [] def get_header(k): return request.headers.get(k, '') def set_header(k, v): headers.append((k, v)) try: key = handshake.check_request(get_header) handshake.build_response(set_header, key) except InvalidHandshake: raise InvalidUsage('Invalid websocket request') subprotocol = None if subprotocols and 'Sec-Websocket-Protocol' in request.headers: # select a subprotocol client_subprotocols = [p.strip() for p in request.headers[ 'Sec-Websocket-Protocol'].split(',')] for p in client_subprotocols: if p in subprotocols: subprotocol = p set_header('Sec-Websocket-Protocol', subprotocol) break # write the 101 response back to the client rv = b'HTTP/1.1 101 Switching Protocols\r\n' for k, v in headers: rv += k.encode('utf-8') + b': ' + v.encode('utf-8') + b'\r\n' rv += b'\r\n' request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( max_size=self.websocket_max_size, max_queue=self.websocket_max_queue ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
async def websocket_handshake(self, request, subprotocols=None): # let the websockets package do the handshake with the client headers = {} try: key = handshake.check_request(request.headers) handshake.build_response(headers, key) except InvalidHandshake: raise InvalidUsage("Invalid websocket request") subprotocol = None if subprotocols and "Sec-Websocket-Protocol" in request.headers: # select a subprotocol client_subprotocols = [ p.strip() for p in request.headers["Sec-Websocket-Protocol"].split(",") ] for p in client_subprotocols: if p in subprotocols: subprotocol = p headers["Sec-Websocket-Protocol"] = subprotocol break # write the 101 response back to the client rv = b"HTTP/1.1 101 Switching Protocols\r\n" for k, v in headers.items(): rv += k.encode("utf-8") + b": " + v.encode("utf-8") + b"\r\n" rv += b"\r\n" request.transport.write(rv) # hook up the websocket protocol self.websocket = WebSocketCommonProtocol( timeout=self.websocket_timeout, max_size=self.websocket_max_size, max_queue=self.websocket_max_queue, read_limit=self.websocket_read_limit, write_limit=self.websocket_write_limit, ) self.websocket.subprotocol = subprotocol self.websocket.connection_made(request.transport) self.websocket.connection_open() return self.websocket
def data_received(self, data): try: if self.enabled: self.websocket.data_received(data) else: self.parser.feed_data(data) except HttpParserError as err: logger.debug(err) import ipdb; ipdb.set_trace() exception = panic_exceptions.InvalidUsage('Bad Request') self.write_error(exception) except HttpParserUpgrade as err: logger.debug(err) self.enabled = True response = panic_response.Response(b'') try: key = handshake.check_request(lambda x: self.headers.get(x).value) handshake.build_response(response.assimilate, key) except InvalidHandshake: exception = panic_exceptions.InvalidUsage('Invalid websocket request') self.write_error(exception) else: self.transport.write(response.channel('1.1')) self.websocket = WebSocketCommonProtocol( timeout=self.timeout, max_size=self.max_size, max_queue=self.max_queue, read_limit=self.read_limit, write_limit=self.write_limit) self.websocket.subprotocol = None #subprotocol self.websocket.connection_made(self.transport) self.websocket.connection_open() self._request_handler_task = self.params.loop.create_task( self.params.request_handler(self.request, self.websocket, self.transport))
def general_handshake(self): """ Try to perform the server side of the opening websocket handshake. If it fails, switch self._type to HTTP and return. Returns the (method, url, headers, body) Copy of WebSocketServerProtocol.handshake with HTTP flavour. """ # Read handshake request. try: method, url, headers, body = yield from read_request(self.reader) except Exception as exc: raise HTTPError(code=500) from exc get_header = lambda k: headers.get(k, '') try: key = check_request(get_header) except InvalidHandshake: self._type = 'HTTP' # switching to HTTP here return (method, url, headers, body) # Send handshake response. Since the headers only contain ASCII # characters, we can keep this simple. response = ['HTTP/1.1 101 Switching Protocols'] set_header = lambda k, v: response.append('{}: {}'.format(k, v)) set_header('Server', USER_AGENT) build_response(set_header, key) response.append('\r\n') response = '\r\n'.join(response).encode() self.writer.write(response) self.state = 'OPEN' self.opening_handshake.set_result(True) return ('GET', url, None, None)
def wrong_build_response(headers, key): return build_response(headers, '42')