Skip to content

Commit

Permalink
Added the address and peer_address properties to SocketStream (nedbat…
Browse files Browse the repository at this point in the history
  • Loading branch information
agronholm authored Mar 23, 2020
1 parent 437a7e9 commit ef086d3
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 1 deletion.
8 changes: 8 additions & 0 deletions anyio/_networking.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ def getsockopt(self, level, optname, *args):
def setsockopt(self, level, optname, value, *args) -> None:
self._socket.setsockopt(level, optname, value, *args)

@property
def address(self) -> Union[Tuple[str, int], Tuple[str, int, int, int], str]:
return self._socket.getsockname()

@property
def peer_address(self) -> Union[Tuple[str, int], Tuple[str, int, int, int], str]:
return self._socket.getpeername()

@property
def buffered_data(self) -> bytes:
return self._buffer
Expand Down
24 changes: 24 additions & 0 deletions anyio/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,30 @@ def setsockopt(self, level, optname, value, *args) -> None:
This calls :meth:`~socket.socket.setsockopt` on the underlying socket.
"""

@property
def address(self) -> Union[Tuple[str, int], Tuple[str, int, int, int], str]:
"""
Return the bound address of the underlying local socket.
For IPv4 TCP streams, this is a tuple of (IP address, port).
For IPv6 TCP streams, this is a tuple of (IP address, port, flowinfo, scopeid).
For UNIX socket streams, this is the path to the socket.
"""
raise NotImplementedError

@property
def peer_address(self) -> Union[Tuple[str, int], Tuple[str, int, int, int], str]:
"""
Return the address this socket is connected to.
For IPv4 TCP streams, this is a tuple of (IP address, port).
For IPv6 TCP streams, this is a tuple of (IP address, port, flowinfo, scopeid).
For UNIX socket streams, this is the path to the socket.
"""
raise NotImplementedError

@abstractmethod
async def start_tls(self, context: Optional[SSLContext] = None) -> None:
"""
Expand Down
1 change: 1 addition & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This library adheres to `Semantic Versioning 2.0 <http://semver.org/>`_.
- Fixed compatibility with Curio 1.0
- Made it possible to assert fine grained control over which AnyIO backends and backend options are
being used with each test
- Added the ``address`` and ``peer_address`` properties to the ``SocketStream`` interface

**1.2.3**

Expand Down
3 changes: 2 additions & 1 deletion tests/test_networking.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ async def receive_data():
@pytest.mark.anyio
async def test_happy_eyeballs(self, interface, expected_addr, fake_localhost_dns):
async def handle_client(stream):
addr, port, *rest = stream._socket._raw_socket.getpeername()
addr, port, *rest = stream.peer_address
await stream.send_all(addr.encode() + b'\n')

async def server():
Expand All @@ -295,6 +295,7 @@ async def server():
await tg.spawn(server)
async with await connect_tcp('localhost', stream_server.port) as client:
assert await client.receive_until(b'\n', 100) == expected_addr
assert client.address[0] == expected_addr.decode()

await stream_server.close()

Expand Down

0 comments on commit ef086d3

Please sign in to comment.