From 4d34868a35dbbf02f0a7ae18bc3eceacb78e7f71 Mon Sep 17 00:00:00 2001 From: Ian Good Date: Sun, 20 Sep 2020 21:45:31 -0400 Subject: [PATCH] Use unique ID instead of fd in logging --- .travis.yml | 19 ++++++++++++------- README.md | 2 +- pymap/context.py | 2 +- pymap/imap/__init__.py | 20 +++++++++++--------- setup.py | 4 ++-- test/server/mocktransport.py | 7 +++++-- 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b78e6f8..d2c86e38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,11 +17,16 @@ after_success: branches: only: - master + - /^\d+\.\d+.*$/ # version tags deploy: - provider: pages - skip_cleanup: true - github_token: $GH_TOKEN - keep_history: true - on: - branch: master - local_dir: doc/build/html + - provider: pages:git + local_dir: doc/build/html + on: + tags: true + edge: true + - provider: pypi + distributions: sdist bdist_wheel + skip_existing: true + on: + tags: true + edge: true diff --git a/README.md b/README.md index da869255..b91954a9 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This project attempts to simplify the complexity of the [IMAP protocol][1] into a set of clean Python APIs that can be implemented by pluggable backends. Everything runs in an [asyncio][2] event loop. -#### [API Documentation](http://icgood.github.io/pymap/) +#### [API Documentation](https://icgood.github.io/pymap/) ### Table of Contents diff --git a/pymap/context.py b/pymap/context.py index ca088f26..96921884 100644 --- a/pymap/context.py +++ b/pymap/context.py @@ -9,7 +9,7 @@ primitives. current_command: The currently executing :class:`~pymap.parsing.command.Command`. - socket_info: :class:`~pymap.sockinfo.SocketInfo` about the currently + socket_info: :class:`~proxyprotocol.sock.SocketInfo` about the currently connected client. language_code: The language code string, e.g. ``en``. connection_exit: The active :class:`~contextlib.AsyncExitStack` that will diff --git a/pymap/imap/__init__.py b/pymap/imap/__init__.py index 6b46b2d9..d720263b 100644 --- a/pymap/imap/__init__.py +++ b/pymap/imap/__init__.py @@ -12,6 +12,7 @@ from base64 import b64encode, b64decode from contextlib import closing, AsyncExitStack from typing import TypeVar, Union, Optional, Iterable, List, Awaitable +from uuid import uuid4 from proxyprotocol import ProxyProtocolResult from proxyprotocol.sock import SocketInfo @@ -153,7 +154,8 @@ def _reset_streams(self, reader: StreamReader, writer: StreamWriter) -> None: self.reader = reader self.writer = writer - socket_info.set(SocketInfo(writer, self.pp_result)) + socket_info.set(SocketInfo(writer, self.pp_result, + unique_id=uuid4().bytes)) async def _read_proxy_protocol(self) -> None: self.pp_result = await self.config.proxy_protocol.read(self.reader) @@ -165,14 +167,14 @@ def close(self) -> None: @classmethod def _print(cls, log_format: str, output: Union[str, bytes]) -> None: if _log.isEnabledFor(logging.DEBUG): - fd = socket_info.get().socket.fileno() + uid = socket_info.get().unique_id.hex() if not isinstance(output, str): output = str(output, 'utf-8', 'replace') lines = cls._lines.split(output) if not lines[-1]: lines = lines[:-1] for line in lines: - _log.debug(log_format, fd, line) + _log.debug(log_format, uid, line) def _exec(self, future: Awaitable[_Ret]) -> Awaitable[_Ret]: return subsystem.get().execute(future) @@ -191,12 +193,12 @@ async def readline(self) -> memoryview: buf += await self.reader.readexactly(literal_length) buf += await self.reader.readline() else: - self._print('%d -->| %s', buf) + self._print('%s -->| %s', buf) return memoryview(buf) async def read_continuation(self, literal_length: int) -> memoryview: extra_literal = await self.reader.readexactly(literal_length) - self._print('%d -->| %s', extra_literal) + self._print('%s -->| %s', extra_literal) extra_line = await self.readline() extra = extra_literal + bytes(extra_line) return memoryview(extra) @@ -267,7 +269,7 @@ async def write_response(self, resp: Response) -> None: except ConnectionError: pass else: - self._print('%d <--| %s', bytes(resp)) + self._print('%s <--| %s', bytes(resp)) async def start_tls(self) -> None: loop = asyncio.get_event_loop() @@ -280,7 +282,7 @@ async def start_tls(self) -> None: new_writer = StreamWriter(new_transport, new_protocol, self.reader, loop) self._reset_streams(self.reader, new_writer) - self._print('%d <->| %s', b'') + self._print('%s <->| %s', b'') async def send_error_disconnect(self) -> None: _, exc, _ = sys.exc_info() @@ -345,7 +347,7 @@ async def run(self, state: ConnectionState) -> None: """ await self._read_proxy_protocol() - self._print('%d +++| %s', str(socket_info.get())) + self._print('%s +++| %s', str(socket_info.get())) bad_commands = 0 try: greeting = await self._exec(state.do_greeting()) @@ -415,4 +417,4 @@ async def run(self, state: ConnectionState) -> None: finally: await state.do_cleanup() current_command.reset(prev_cmd) - self._print('%d ---| %s', b'') + self._print('%s ---| %s', b'') diff --git a/setup.py b/setup.py index 0c5eb978..639febb6 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ license = f.read() setup(name='pymap', - version='0.20.0', + version='0.20.1', author='Ian Good', author_email='icgood@gmail.com', description='Lightweight, asynchronous IMAP serving in Python.', @@ -50,7 +50,7 @@ packages=find_packages(), install_requires=[ 'pysasl >= 0.6.1', - 'proxy-protocol >= 0.1.0', + 'proxy-protocol >= 0.5.0', 'typing-extensions'], extras_require={ 'redis': ['aioredis >= 1.3.0', 'msgpack >= 1.0'], diff --git a/test/server/mocktransport.py b/test/server/mocktransport.py index a7da7b57..39058369 100644 --- a/test/server/mocktransport.py +++ b/test/server/mocktransport.py @@ -3,6 +3,7 @@ import enum import inspect import re +import socket import traceback from collections import deque from itertools import zip_longest @@ -21,7 +22,7 @@ class _Socket: def __init__(self, fd: int) -> None: self.fd = fd - self.family = None + self.family = socket.AF_INET def fileno(self): return self.fd @@ -195,7 +196,9 @@ def get_extra_info(self, name: str, default=None): if name == 'socket': return self.socket elif name == 'peername': - return 'test' + return ('1.2.3.4', 1234) + elif name == 'sockname': + return ('5.6.7.8', 5678) async def readline(self) -> bytes: where, data, wait, set = self._pop_expected(_Type.READLINE)