def __init__(self, client_conn, server_conn, handshake_flow, live=None): super().__init__("websocket", client_conn, server_conn, live) self.messages = [] # type: List[WebSocketMessage] self.close_sender = 'client' self.close_code = '(status code missing)' self.close_message = '(message missing)' self.close_reason = 'unknown status code' if handshake_flow: self.client_key = websockets.get_client_key( handshake_flow.request.headers) self.client_protocol = websockets.get_protocol( handshake_flow.request.headers) self.client_extensions = websockets.get_extensions( handshake_flow.request.headers) self.server_accept = websockets.get_server_accept( handshake_flow.response.headers) self.server_protocol = websockets.get_protocol( handshake_flow.response.headers) self.server_extensions = websockets.get_extensions( handshake_flow.response.headers) else: self.client_key = '' self.client_protocol = '' self.client_extensions = '' self.server_accept = '' self.server_protocol = '' self.server_extensions = '' self.handshake_flow = handshake_flow
def __init__(self, client_conn, server_conn, handshake_flow, live=None): super().__init__("websocket", client_conn, server_conn, live) self.messages = [] # type: List[WebSocketMessage] self.close_sender = 'client' self.close_code = '(status code missing)' self.close_message = '(message missing)' self.close_reason = 'unknown status code' self.stream = False if handshake_flow: self.client_key = websockets.get_client_key(handshake_flow.request.headers) self.client_protocol = websockets.get_protocol(handshake_flow.request.headers) self.client_extensions = websockets.get_extensions(handshake_flow.request.headers) self.server_accept = websockets.get_server_accept(handshake_flow.response.headers) self.server_protocol = websockets.get_protocol(handshake_flow.response.headers) self.server_extensions = websockets.get_extensions(handshake_flow.response.headers) else: self.client_key = '' self.client_protocol = '' self.client_extensions = '' self.server_accept = '' self.server_protocol = '' self.server_extensions = '' self.handshake_flow = handshake_flow
def __init__(self, client_conn, server_conn, handshake_flow, live=None): super().__init__("websocket", client_conn, server_conn, live) self.messages: List[WebSocketMessage] = [] """A list containing all WebSocketMessage's.""" self.close_sender = 'client' """'client' if the client initiated connection closing.""" self.close_code = CloseReason.NORMAL_CLOSURE """WebSocket close code.""" self.close_message = '(message missing)' """WebSocket close message.""" self.close_reason = 'unknown status code' """WebSocket close reason.""" self.stream = False """True of this connection is streaming directly to the other endpoint.""" self.handshake_flow = handshake_flow """The HTTP flow containing the initial WebSocket handshake.""" if handshake_flow: self.client_key = websockets.get_client_key(handshake_flow.request.headers) self.client_protocol = websockets.get_protocol(handshake_flow.request.headers) self.client_extensions = websockets.get_extensions(handshake_flow.request.headers) self.server_accept = websockets.get_server_accept(handshake_flow.response.headers) self.server_protocol = websockets.get_protocol(handshake_flow.response.headers) self.server_extensions = websockets.get_extensions(handshake_flow.response.headers) else: self.client_key = '' self.client_protocol = '' self.client_extensions = '' self.server_accept = '' self.server_protocol = '' self.server_extensions = ''
def __init__(self, ctx, flow): super().__init__(ctx) self._flow = flow self.client_key = websockets.get_client_key(self._flow.request.headers) self.client_protocol = websockets.get_protocol(self._flow.request.headers) self.client_extensions = websockets.get_extensions(self._flow.request.headers) self.server_accept = websockets.get_server_accept(self._flow.response.headers) self.server_protocol = websockets.get_protocol(self._flow.response.headers) self.server_extensions = websockets.get_extensions(self._flow.response.headers)
def __init__(self, ctx, flow): super().__init__(ctx) self._flow = flow self.client_key = websockets.get_client_key(self._flow.request.headers) self.client_protocol = websockets.get_protocol( self._flow.request.headers) self.client_extensions = websockets.get_extensions( self._flow.request.headers) self.server_accept = websockets.get_server_accept( self._flow.response.headers) self.server_protocol = websockets.get_protocol( self._flow.response.headers) self.server_extensions = websockets.get_extensions( self._flow.response.headers)
def __init__(self, client_conn, server_conn, handshake_flow, live=None): super().__init__("websocket", client_conn, server_conn, live) self.messages: List[WebSocketMessage] = [] """A list containing all WebSocketMessage's.""" self.close_sender = 'client' """'client' if the client initiated connection closing.""" self.close_code = CloseReason.NORMAL_CLOSURE """WebSocket close code.""" self.close_message = '(message missing)' """WebSocket close message.""" self.close_reason = 'unknown status code' """WebSocket close reason.""" self.stream = False """True of this connection is streaming directly to the other endpoint.""" self.handshake_flow = handshake_flow """The HTTP flow containing the initial WebSocket handshake.""" self.ended = False """True when the WebSocket connection has been closed.""" self._inject_messages_client = queue.Queue(maxsize=1) self._inject_messages_server = queue.Queue(maxsize=1) if handshake_flow: self.client_key = websockets.get_client_key( handshake_flow.request.headers) self.client_protocol = websockets.get_protocol( handshake_flow.request.headers) self.client_extensions = websockets.get_extensions( handshake_flow.request.headers) self.server_accept = websockets.get_server_accept( handshake_flow.response.headers) self.server_protocol = websockets.get_protocol( handshake_flow.response.headers) self.server_extensions = websockets.get_extensions( handshake_flow.response.headers) else: self.client_key = '' self.client_protocol = '' self.client_extensions = '' self.server_accept = '' self.server_protocol = '' self.server_extensions = ''
def handle_http_request(self, logger): """ Returns a (handler, log) tuple. handler: Handler for the next request, or None to disconnect log: A dictionary, or None """ with logger.ctx() as lg: try: req = self.protocol.read_request(self.rfile) except exceptions.HttpReadDisconnect: return None, None except exceptions.HttpException as s: s = str(s) lg(s) return None, dict(type="error", msg=s) if req.method == 'CONNECT': return self.protocol.handle_http_connect([req.host, req.port, req.http_version], lg) method = req.method path = req.path http_version = req.http_version headers = req.headers first_line_format = req.first_line_format clientcert = None if self.clientcert: clientcert = dict( cn=self.clientcert.cn, subject=self.clientcert.subject, serial=self.clientcert.serial, notbefore=self.clientcert.notbefore.isoformat(), notafter=self.clientcert.notafter.isoformat(), keyinfo=self.clientcert.keyinfo, ) retlog = dict( type="crafted", protocol="http", request=dict( path=path, method=method, headers=headers.fields, http_version=http_version, sni=self.sni, remote_address=self.address, clientcert=clientcert, first_line_format=first_line_format ), cipher=None, ) if self.ssl_established: retlog["cipher"] = self.get_current_cipher() m = utils.MemBool() valid_websocket_handshake = websockets.check_handshake(headers) self.settings.websocket_key = websockets.get_client_key(headers) # If this is a websocket initiation, we respond with a proper # server response, unless over-ridden. if valid_websocket_handshake: anchor_gen = language.parse_pathod("ws") else: anchor_gen = None for regex, spec in self.server.anchors: if regex.match(path): anchor_gen = language.parse_pathod(spec, self.use_http2) break else: if m(path.startswith(self.server.craftanchor)): spec = urllib.parse.unquote(path)[len(self.server.craftanchor):] if spec: try: anchor_gen = language.parse_pathod(spec, self.use_http2) except language.ParseException as v: lg("Parse error: %s" % v.msg) anchor_gen = iter([self.make_http_error_response( "Parse Error", "Error parsing response spec: %s\n" % ( v.msg + v.marked() ) )]) else: if self.use_http2: anchor_gen = iter([self.make_http_error_response( "Spec Error", "HTTP/2 only supports request/response with the craft anchor point: %s" % self.server.craftanchor )]) if not anchor_gen: anchor_gen = iter([self.make_http_error_response( "Not found", "No valid craft request found" )]) spec = next(anchor_gen) if self.use_http2 and isinstance(spec, language.http2.Response): spec.stream_id = req.stream_id lg("crafting spec: %s" % spec) nexthandler, retlog["response"] = self.http_serve_crafted( spec, lg ) if nexthandler and valid_websocket_handshake: self.protocol = protocols.websockets.WebsocketsProtocol(self) return self.protocol.handle_websocket, retlog else: return nexthandler, retlog
def test_get_client_key(self, input, expected): h = http.Headers(input) assert websockets.get_client_key(h) == expected
def handle_http_request(self, logger): """ Returns a (handler, log) tuple. handler: Handler for the next request, or None to disconnect log: A dictionary, or None """ with logger.ctx() as lg: try: req = self.protocol.read_request(self.rfile) except exceptions.HttpReadDisconnect: return None, None except exceptions.HttpException as s: s = str(s) lg(s) return None, dict(type="error", msg=s) if req.method == 'CONNECT': return self.protocol.handle_http_connect( [req.host, req.port, req.http_version], lg) method = req.method path = req.path http_version = req.http_version headers = req.headers first_line_format = req.first_line_format clientcert = None if self.clientcert: clientcert = dict( cn=self.clientcert.cn, subject=self.clientcert.subject, serial=self.clientcert.serial, notbefore=self.clientcert.notbefore.isoformat(), notafter=self.clientcert.notafter.isoformat(), keyinfo=self.clientcert.keyinfo, ) retlog = dict( type="crafted", protocol="http", request=dict(path=path, method=method, headers=headers.fields, http_version=http_version, sni=self.sni, remote_address=self.address, clientcert=clientcert, first_line_format=first_line_format), cipher=None, ) if self.tls_established: retlog["cipher"] = self.get_current_cipher() m = utils.MemBool() valid_websocket_handshake = websockets.check_handshake(headers) self.settings.websocket_key = websockets.get_client_key(headers) # If this is a websocket initiation, we respond with a proper # server response, unless over-ridden. if valid_websocket_handshake: anchor_gen = language.parse_pathod("ws") else: anchor_gen = None for regex, spec in self.server.anchors: if regex.match(path): anchor_gen = language.parse_pathod(spec, self.use_http2) break else: if m(path.startswith(self.server.craftanchor)): spec = urllib.parse.unquote( path)[len(self.server.craftanchor):] if spec: try: anchor_gen = language.parse_pathod( spec, self.use_http2) except language.ParseException as v: lg("Parse error: %s" % v.msg) anchor_gen = iter([ self.make_http_error_response( "Parse Error", "Error parsing response spec: %s\n" % (v.msg + v.marked())) ]) else: if self.use_http2: anchor_gen = iter([ self.make_http_error_response( "Spec Error", "HTTP/2 only supports request/response with the craft anchor point: %s" % self.server.craftanchor) ]) if not anchor_gen: anchor_gen = iter([ self.make_http_error_response( "Not found", "No valid craft request found") ]) spec = next(anchor_gen) if self.use_http2 and isinstance(spec, language.http2.Response): spec.stream_id = req.stream_id lg("crafting spec: %s" % spec) nexthandler, retlog["response"] = self.http_serve_crafted(spec, lg) if nexthandler and valid_websocket_handshake: self.protocol = protocols.websockets.WebsocketsProtocol(self) return self.protocol.handle_websocket, retlog else: return nexthandler, retlog
def client_key(self): return websockets.get_client_key(self.handshake_flow.request.headers)