async def _wait_for_either_until_neither( self, stdout: asyncio.StreamReader, stderr: asyncio.StreamReader) -> None: """ Wait for a line of data from either stdout or stderr and log this data as received. When both are EOF then exit. :returns: Tuple of stdout, stderr """ future_out = asyncio.ensure_future(stdout.readline()) future_err = asyncio.ensure_future(stderr.readline()) pending = set([future_out, future_err]) # type: typing.Set[asyncio.Future] done = set() # type: typing.Set[asyncio.Future] while len(pending) > 0: done, pending = await asyncio.wait(pending) for future_done in done: result = future_done.result().strip() if len(result) > 0: line = result.decode(errors='replace') if future_done == future_err: future_err = asyncio.ensure_future(stderr.readline()) pending.add(future_err) self._logger.error(line) else: future_out = asyncio.ensure_future(stdout.readline()) pending.add(future_out) self._logger.info(line.strip())
async def _get_message(cls, reader: asyncio.StreamReader, writer: asyncio.StreamWriter) -> str: """Gets the next message. Args: reader: The reader to receive messages from the client. writer: The writer to send messages to the client. Returns: The next message received from the client. """ message = "" try: line = await asyncio.wait_for(reader.readline(), timeout=5) message = line.decode("latin-1").strip() except asyncio.TimeoutError: pass # Check that we're still connected if we didn't get a message if not message and not await cls._send(writer, ["S,SERVER CONNECTED"]): raise BrokenPipeError("Client disconnected") return message
async def _listen_for_messages(self, username: str, reader: StreamReader): #D try: while (data := await asyncio.wait_for(reader.readline(), 60)) != b'': await self._notify_all(f'{username}: {data.decode()}') await self._notify_all(f'{username} has left the chat\n')
async def read_stream(reader: StreamReader, writer: StreamWriter, log: bool = True) -> AsyncGenerator[str, None]: """Reading line from stream.""" reconnect_counter = 0 try: while not reader.at_eof(): data = await asyncio.wait_for(reader.readline(), timeout=60) message = data.decode('utf-8').strip() if log: logger.debug(message) yield message except asyncio.TimeoutError: logger.exception(f'TimeoutError -> StreamReader timeout get message', exc_info=False) except Exception as ex: logger.exception(f'OtherError -> {ex.__class__.__name__}: {ex}', exc_info=False) finally: reconnect_counter += 1 await asyncio.sleep(60 if reconnect_counter > 60 else reconnect_counter )
async def json_lines_with_timeout(reader: asyncio.StreamReader, timeout: 'seconds' = DEFAULT_TIMEOUT): while not reader.at_eof(): line = await asyncio.wait_for(reader.readline(), timeout) try: yield json.loads(line) except json.JSONDecodeError as e: pass
async def _tcp_reader(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter): timeout = 30 while True: raw_data = await asyncio.wait_for(reader.readline(), timeout=timeout) if raw_data: try: data = json.loads(raw_data.decode("utf-8")) self._log.info('Message recieved') await queue.put(data) except: self._log.error("Parsing data failed") writer.close()
async def qemu_log_reader(self, log_tag: str, reader: asyncio.StreamReader, bufname: str): while not self.shared_state.qemu_sock_stopdebug: try: line = await asyncio.wait_for(reader.readline(), 1) except asyncio.exceptions.TimeoutError: continue setattr(self.shared_state, bufname, getattr(self.shared_state, bufname) + line) if self.shared_state.config['qemu_debug']: print(Color.YELLOW + f"{log_tag}:" + Color.RESET, ansi_escape.sub(b'', line).decode(errors="replace"), end='')
async def read_stream(self, stream_name: str, stream: asyncio.StreamReader): """ log lines read in from this stream. Args: command_name: the name of the command run. This helps the logger identify where the message came from. Return when EOF has been received. """ contents = await stream.readline() while contents: self.write(stream_name, contents.decode()) contents = await (stream.readline())
async def read_to_logger(command_name: str, stream: asyncio.StreamReader): """ log lines read in from this stream. Args: command_name: the name of the command run. This helps the logger identify where the message came from. Return when EOF has been received. """ logger = logging.getLogger(command_name) contents = await stream.readline() while contents: logger.info(contents) contents = await (stream.readline())
async def handle_connection(reader: asyncio.StreamReader, writer: asyncio.StreamWriter): try: cliipaddr = writer.get_extra_info('peername') ownipaddr = writer.get_extra_info('sockname') logging.debug('{} <-- {}'.format(ownipaddr, cliipaddr)) protocol_indicator = await asyncio.wait_for(reader.read(4), timeout) if protocol_indicator == b'DKG ': await respond_to_nonce_with_signature(reader, writer, node.private_key, timeout) cliethaddr = await determine_address_via_nonce(reader, writer, timeout) if cliethaddr is None: logging.debug('(s) could not verify client signature; closing connection') return if cliethaddr not in accepted_addresses: logging.debug('(s) client address {:40x} not accepted'.format(cliethaddr)) return await establish_channel(cliethaddr, reader, writer, node) elif len(protocol_indicator) > 0: req = HTTPRequest(protocol_indicator + await asyncio.wait_for(reader.readline(), timeout), reader) contentlen = req.headers.get('Content-Length') if contentlen is not None: contentlen = int(contentlen) req.body = await reader.read(contentlen) res = JSONRPCResponseManager.handle(req.body, default_dispatcher) res_data = await get_response_data(res, timeout) db.Session.remove() if res_data is None: writer.write(b'HTTP/1.1 204 No Content\r\n\r\n') else: res_str = json.dumps(res_data, indent=2, sort_keys=True).encode('UTF-8') writer.write(b'HTTP/1.1 200 OK\r\n' b'Content-Type: application/json; charset=UTF-8\r\n' b'Content-Length: ') writer.write(str(len(res_str) + 1).encode('UTF-8')) writer.write(b'\r\n\r\n') writer.write(res_str) writer.write(b'\n') finally: writer.close()
class HttpBodyReader(): _expect_sent = None _waiting = None def __init__(self, headers, parser, transport, **kw): self.headers = headers self.parser = parser self.reader = StreamReader(**kw) self.reader.set_transport(transport) self.feed_data = self.reader.feed_data self.feed_eof = self.reader.feed_eof def waiting_expect(self): '''``True`` when the client is waiting for 100 Continue. ''' if self._expect_sent is None: if (not self.reader.at_eof() and self.headers.has('expect', '100-continue')): return True self._expect_sent = '' return False def can_continue(self): if self.waiting_expect(): if self.parser.get_version() < (1, 1): raise HttpException(status=417) else: msg = '%s 100 Continue\r\n\r\n' % http_protocol(self.parser) self._expect_sent = msg self.reader._transport.write(msg.encode(DEFAULT_CHARSET)) def fail(self): if self.waiting_expect(): raise HttpException(status=417) def read(self, n=-1): self.can_continue() return self.reader.read(n=n) def readline(self): self.can_continue() return self.reader.readline() def readexactly(self, n): self.can_continue() return self.reader.readexactly(n)
def test_get(self, loop): result = 39 result_queue = Queue() called_queue = Queue() reader = StreamReader() unix_socket = UnixSocket(None, loop) unix_socket.reader = reader async def readline(): called_queue.put(True) return unix_socket.encode(result) reader.readline = readline async def run(): unix_socket.ready.set() result = await unix_socket.get() result_queue.put(result) loop.run_until_complete(run()) check_queue(called_queue, True) check_queue(result_queue, result)
def handle_connection(self, client_reader: asyncio.StreamReader, client_writer: asyncio.StreamWriter, user_dict: dict): """ Example of how to handle a new connection. """ client_writer.write( 'Greetings. Lines will be echoed back to you. Type EOF to exit.\n' .encode(ExampleLineEchoNonblockingServer.ENCODING)) yield from client_writer.drain() # Non-blocking from_client = None while from_client != 'EOF': # Magic kill word from client # Discussion: I think it might be a bug (or "feature") in the Python 3.4.3 I'm developing on # that there is not a proper error thrown with this readline or the following write. # There's a note here: https://github.com/aaugustin/websockets/issues/23 # In any event, wrapping the read in an asyncio.async(..) solves the problem. # Without async(..) when a connection is dropped externally, the code goes into an infinite loop # reading an empty string b'' and then writing with the should-be-exception getting swallowed # somewhere inside Python's codebase. # from_client = yield from client_reader.readline() # This should be OK, but it's not, strangely # from_client = yield from asyncio.shield(client_reader.readline()) # Also works # from_client = yield from asyncio.ensure_future(client_reader.readline()) # Use this instead from_client = yield from client_reader.readline() if from_client == b'': # Connection probably closed from_client = "EOF" else: from_client = from_client.decode('utf-8').strip() print("Recvd: [{}]".format(from_client)) response = "{}\n".format(from_client).encode( ExampleLineEchoNonblockingServer.ENCODING) client_writer.write(response) yield from client_writer.drain() # Non-blocking