Skip to content

Commit

Permalink
Fix bind unspecified address controller will raise TimeoutError
Browse files Browse the repository at this point in the history
The controller throws a TimeoutError when binding a unspecified address (e.g. 0.0.0.0)
  • Loading branch information
wevsty committed Jun 6, 2021
1 parent 215b854 commit 1a9d4df
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
12 changes: 10 additions & 2 deletions aiosmtpd/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,14 @@ def get_localhost() -> Literal["::1", "127.0.0.1"]:
raise


@public
def is_unspecified_address(address: str) -> bool:
unspecified_address_list = [None, '', '0.0.0.0', '::']
if address in unspecified_address_list:
return True
return False


class _FakeServer(asyncio.StreamReaderProtocol):
"""
Returned by _factory_invoker() in lieu of an SMTP instance in case
Expand Down Expand Up @@ -397,7 +405,7 @@ def __init__(
**kwargs,
)
self._localhost = get_localhost()
self.hostname = self._localhost if hostname is None else hostname
self.hostname = self._localhost if is_unspecified_address(hostname) is True else hostname
self.port = port

def _create_server(self) -> Coroutine:
Expand All @@ -421,7 +429,7 @@ def _trigger_server(self):
"""
# At this point, if self.hostname is Falsy, it most likely is "" (bind to all
# addresses). In such case, it should be safe to connect to localhost)
hostname = self.hostname or self._localhost
hostname = self.hostname
with ExitStack() as stk:
s = stk.enter_context(create_connection((hostname, self.port), 1.0))
if self.ssl_context:
Expand Down
2 changes: 1 addition & 1 deletion aiosmtpd/docs/NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Fixed/Improved
--------------
* All Controllers now have more rationale design, as they are now composited from a Base + a Mixin
* A whole bunch of annotations

* Fix bind unspecified address controller will raise TimeoutError

1.4.2 (2021-03-08)
=====================
Expand Down
13 changes: 13 additions & 0 deletions aiosmtpd/tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,13 @@ def test_hostname_none(self):
cont.start()
finally:
cont.stop()

def test_hostname_unspecified(self):
cont = Controller(Sink(), hostname="0.0.0.0")
try:
cont.start()
finally:
cont.stop()

def test_testconn_raises(self, mocker: MockFixture):
mocker.patch("socket.socket.recv", side_effect=RuntimeError("MockError"))
Expand Down Expand Up @@ -347,6 +354,12 @@ def test_getlocalhost_error(self, mocker):
assert exc.value.errno == errno.EFAULT
mock_makesock.assert_called_with(socket.AF_INET6, socket.SOCK_STREAM)

def test_is_unspecified_address(self):
assert is_unspecified_address("127.0.0.1") is False
assert is_unspecified_address("0.0.0.0") is True
assert is_unspecified_address("::") is True
assert is_unspecified_address("") is True

def test_stop_default(self):
controller = Controller(Sink())
with pytest.raises(AssertionError, match="SMTP daemon not running"):
Expand Down

0 comments on commit 1a9d4df

Please sign in to comment.