def __call__(self): self.flow = WebSocketFlow(self.client_conn, self.server_conn, self.handshake_flow, self) self.flow.metadata['websocket_handshake'] = self.handshake_flow.id self.handshake_flow.metadata['websocket_flow'] = self.flow.id self.channel.ask("websocket_start", self.flow) conns = [c.connection for c in self.connections.keys()] close_received = False try: while not self.channel.should_exit.is_set(): r = tcp.ssl_read_select(conns, 0.1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (source_conn == self.server_conn) frame = websockets.Frame.from_file(source_conn.rfile) self.connections[source_conn].receive_bytes(bytes(frame)) source_conn.send(self.connections[source_conn].bytes_to_send()) if close_received: return for event in self.connections[source_conn].events(): if not self._handle_event(event, source_conn, other_conn, is_server): if not close_received: close_received = True except (socket.error, exceptions.TcpException, SSL.Error) as e: s = 'server' if is_server else 'client' self.flow.error = flow.Error("WebSocket connection closed unexpectedly by {}: {}".format(s, repr(e))) self.channel.tell("websocket_error", self.flow) finally: self.channel.tell("websocket_end", self.flow)
def __call__(self): client = self.client_conn.connection server = self.server_conn.connection conns = [client, server] try: while not self.channel.should_exit.is_set(): r = tcp.ssl_read_select(conns, 1) for conn in r: source_conn = self.client_conn if conn == client else self.server_conn other_conn = self.server_conn if conn == client else self.client_conn is_server = (conn == self.server_conn.connection) frame = websockets.Frame.from_file(source_conn.rfile) if not self._handle_frame(frame, source_conn, other_conn, is_server): return except (socket.error, exceptions.TcpException, SSL.Error) as e: self.log( "WebSockets connection closed unexpectedly by {}: {}".format( "server" if is_server else "client", repr(e)), "info") except Exception as e: # pragma: no cover raise exceptions.ProtocolException( "Error in WebSockets connection: {}".format(repr(e)))
def __call__(self): self.flow = WebSocketFlow(self.client_conn, self.server_conn, self.handshake_flow, self) self.flow.metadata['websocket_handshake'] = self.handshake_flow.id self.handshake_flow.metadata['websocket_flow'] = self.flow.id self.channel.ask("websocket_start", self.flow) client = self.client_conn.connection server = self.server_conn.connection conns = [client, server] close_received = False try: while not self.channel.should_exit.is_set(): r = tcp.ssl_read_select(conns, 0.1) for conn in r: source_conn = self.client_conn if conn == client else self.server_conn other_conn = self.server_conn if conn == client else self.client_conn is_server = (conn == self.server_conn.connection) frame = websockets.Frame.from_file(source_conn.rfile) cont = self._handle_frame(frame, source_conn, other_conn, is_server) if not cont: if close_received: return else: close_received = True except (socket.error, exceptions.TcpException, SSL.Error) as e: s = 'server' if is_server else 'client' self.flow.error = flow.Error("WebSocket connection closed unexpectedly by {}: {}".format(s, repr(e))) self.channel.tell("websocket_error", self.flow) finally: self.channel.tell("websocket_end", self.flow)
def __call__(self): self.flow = WebSocketFlow(self.client_conn, self.server_conn, self.handshake_flow, self) self.flow.metadata['websocket_handshake'] = self.handshake_flow self.handshake_flow.metadata['websocket_flow'] = self.flow self.channel.ask("websocket_start", self.flow) client = self.client_conn.connection server = self.server_conn.connection conns = [client, server] try: while not self.channel.should_exit.is_set(): r = tcp.ssl_read_select(conns, 1) for conn in r: source_conn = self.client_conn if conn == client else self.server_conn other_conn = self.server_conn if conn == client else self.client_conn is_server = (conn == self.server_conn.connection) frame = websockets.Frame.from_file(source_conn.rfile) if not self._handle_frame(frame, source_conn, other_conn, is_server): return except (socket.error, exceptions.TcpException, SSL.Error) as e: self.flow.error = flow.Error("WebSocket connection closed unexpectedly: {}".format(repr(e))) self.channel.tell("websocket_error", self.flow) finally: self.channel.tell("websocket_end", self.flow)
def __call__(self): self.flow = WebSocketFlow(self.client_conn, self.server_conn, self.handshake_flow) self.flow.metadata['websocket_handshake'] = self.handshake_flow.id self.handshake_flow.metadata['websocket_flow'] = self.flow.id self.channel.ask("websocket_start", self.flow) conns = [c.connection for c in self.connections.keys()] close_received = False try: while not self.channel.should_exit.is_set(): self._inject_messages(self.client_conn, self.flow._inject_messages_client) self._inject_messages(self.server_conn, self.flow._inject_messages_server) r = tcp.ssl_read_select(conns, 0.1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (source_conn == self.server_conn) header, frame, consumed_bytes = websocket.read_frame( source_conn.rfile) self.log( "WebSocket Frame from {}: {}, {}".format( "server" if is_server else "client", header, frame, ), "debug") data = self.connections[source_conn].receive_data( consumed_bytes) source_conn.send(data) if close_received: return for event in self.connections[source_conn].events(): if not self._handle_event(event, source_conn, other_conn, is_server): if not close_received: close_received = True except (socket.error, exceptions.TcpException, SSL.Error) as e: s = 'server' if is_server else 'client' self.flow.error = flow.Error( "WebSocket connection closed unexpectedly by {}: {}".format( s, repr(e))) self.channel.tell("websocket_error", self.flow) finally: self.flow.ended = True self.channel.tell("websocket_end", self.flow)
def __call__(self): self.connect() client = self.client_conn.connection server = self.server_conn.connection buf = memoryview(bytearray(self.chunk_size)) # send CONNECT, expect 200 OK connect_req = make_connect_request((self.host, self.port)) server.send(assemble_request(connect_req)) resp = server.recv(1024).decode() if not resp.startswith('HTTP/1.1 200 OK'): raise BubbleFlexPassthruException('CONNECT request error: ' + resp) conns = [client, server] # https://github.com/openssl/openssl/issues/6234 for conn in conns: if isinstance(conn, SSL.Connection) and hasattr( SSL._lib, "SSL_clear_mode"): SSL._lib.SSL_clear_mode(conn._ssl, SSL._lib.SSL_MODE_AUTO_RETRY) try: while not self.channel.should_exit.is_set(): r = ssl_read_select(conns, 10) for conn in r: dst = server if conn == client else client try: size = conn.recv_into(buf, self.chunk_size) except (SSL.WantReadError, SSL.WantWriteError): continue if not size: conns.remove(conn) # Shutdown connection to the other peer if isinstance(conn, SSL.Connection): # We can't half-close a connection, so we just close everything here. # Sockets will be cleaned up on a higher level. return else: dst.shutdown(socket.SHUT_WR) if len(conns) == 0: return continue tcp_message = tcp.TCPMessage(dst == server, buf[:size].tobytes()) dst.sendall(tcp_message.content) except (socket.error, exceptions.TcpException, SSL.Error) as e: bubble_log.error('exception: ' + repr(e))
def __call__(self): self._initiate_server_conn() self._complete_handshake() client = self.client_conn.connection server = self.server_conn.connection conns = [client, server] try: while True: r = tcp.ssl_read_select(conns, 1) for conn in r: source_conn = self.client_conn if conn == client else self.server_conn other_conn = self.server_conn if conn == client else self.client_conn is_server = (conn == self.server_conn.connection) with source_conn.h2.lock: try: raw_frame = b''.join( http2.read_raw_frame(source_conn.rfile)) except: # read frame failed: connection closed self._kill_all_streams() return if source_conn.h2.state_machine.state == h2.connection.ConnectionState.CLOSED: self.log( "HTTP/2 connection entered closed state already", "debug") return incoming_events = source_conn.h2.receive_data( raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in incoming_events: if not self._handle_event(event, source_conn, other_conn, is_server): # connection terminated: GoAway self._kill_all_streams() return self._cleanup_streams() except Exception as e: # pragma: no cover self.log(repr(e), "info") self.log(traceback.format_exc(), "debug") self._kill_all_streams()
def __call__(self): self._initiate_server_conn() self._complete_handshake() conns = [c.connection for c in self.connections.keys()] try: while True: r = tcp.ssl_read_select(conns, 0.1) for conn in r: source_conn = self.client_conn if conn == self.client_conn.connection else self.server_conn other_conn = self.server_conn if conn == self.client_conn.connection else self.client_conn is_server = (source_conn == self.server_conn) with self.connections[source_conn].lock: try: _, consumed_bytes = http2.read_frame( source_conn.rfile) except: # read frame failed: connection closed self._kill_all_streams() return if self.connections[ source_conn].state_machine.state == h2.connection.ConnectionState.CLOSED: self.log( "HTTP/2 connection entered closed state already", "debug") return incoming_events = self.connections[ source_conn].receive_data(consumed_bytes) source_conn.send( self.connections[source_conn].data_to_send()) for event in incoming_events: if not self._handle_event(event, source_conn, other_conn, is_server): # connection terminated: GoAway self._kill_all_streams() return self._cleanup_streams() except Exception as e: # pragma: no cover self.log(repr(e), "info") self._kill_all_streams()
def __call__(self): self._initiate_server_conn() self._complete_handshake() client = self.client_conn.connection server = self.server_conn.connection conns = [client, server] try: while True: r = tcp.ssl_read_select(conns, 1) for conn in r: source_conn = self.client_conn if conn == client else self.server_conn other_conn = self.server_conn if conn == client else self.client_conn is_server = (conn == self.server_conn.connection) with source_conn.h2.lock: try: raw_frame = b''.join(http2.read_raw_frame(source_conn.rfile)) except: # read frame failed: connection closed self._kill_all_streams() return if source_conn.h2.state_machine.state == h2.connection.ConnectionState.CLOSED: self.log("HTTP/2 connection entered closed state already", "debug") return incoming_events = source_conn.h2.receive_data(raw_frame) source_conn.send(source_conn.h2.data_to_send()) for event in incoming_events: if not self._handle_event(event, source_conn, other_conn, is_server): # connection terminated: GoAway self._kill_all_streams() return self._cleanup_streams() except Exception as e: # pragma: no cover self.log(repr(e), "info") self.log(traceback.format_exc(), "debug") self._kill_all_streams()
def __call__(self): client = self.client_conn.connection server = self.server_conn.connection conns = [client, server] try: while not self.channel.should_exit.is_set(): r = tcp.ssl_read_select(conns, 1) for conn in r: source_conn = self.client_conn if conn == client else self.server_conn other_conn = self.server_conn if conn == client else self.client_conn is_server = (conn == self.server_conn.connection) frame = websockets.Frame.from_file(source_conn.rfile) if not self._handle_frame(frame, source_conn, other_conn, is_server): return except (socket.error, exceptions.TcpException, SSL.Error) as e: self.log("WebSockets connection closed unexpectedly by {}: {}".format( "server" if is_server else "client", repr(e)), "info") except Exception as e: # pragma: no cover raise exceptions.ProtocolException("Error in WebSockets connection: {}".format(repr(e)))