Accept empty addr in UDP on_receive

* Fixes #304
This commit is contained in:
Fantix King 2020-04-27 17:49:33 -05:00
parent d51ce36785
commit 9e017e6ee9
2 changed files with 50 additions and 7 deletions

View File

@ -284,6 +284,50 @@ class _TestUDP:
self.loop.run_until_complete(run())
def test_socketpair(self):
peername = asyncio.Future(loop=self.loop)
class Proto(MyDatagramProto):
def datagram_received(self, data, addr):
super().datagram_received(data, addr)
peername.set_result(addr)
s1, s2 = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM, 0)
with s1, s2:
try:
f = self.loop.create_datagram_endpoint(
lambda: Proto(loop=self.loop), sock=s1)
except TypeError as ex:
# asyncio in 3.5.0 doesn't have the 'sock' argument
if 'got an unexpected keyword argument' not in ex.args[0]:
raise
else:
tr, pr = self.loop.run_until_complete(f)
self.assertIsInstance(pr, Proto)
s2.send(b'hello, socketpair')
addr = self.loop.run_until_complete(
asyncio.wait_for(peername, 1, loop=self.loop))
if sys.platform.startswith('linux'):
self.assertEqual(addr, None)
else:
self.assertEqual(addr, '')
self.assertEqual(pr.nbytes, 17)
if not self.is_asyncio_loop():
# asyncio doesn't support sendto(xx) on UDP sockets
# https://git.io/Jfqbw
data = b'from uvloop'
tr.sendto(data)
result = self.loop.run_until_complete(asyncio.wait_for(
self.loop.run_in_executor(None, s2.recv, 1024),
1, loop=self.loop))
self.assertEqual(data, result)
tr.close()
self.loop.run_until_complete(pr.done)
class Test_UV_UDP(_TestUDP, tb.UVTestCase):

View File

@ -344,6 +344,12 @@ cdef void __uv_udp_on_receive(uv.uv_udp_t* handle,
if addr is NULL:
pyaddr = None
elif addr.sa_family == uv.AF_UNSPEC:
# https://github.com/MagicStack/uvloop/issues/304
IF UNAME_SYSNAME == "Linux":
pyaddr = None
ELSE:
pyaddr = ''
else:
try:
pyaddr = __convert_sockaddr_to_pyaddr(addr)
@ -356,13 +362,6 @@ cdef void __uv_udp_on_receive(uv.uv_udp_t* handle,
udp._on_receive(None, exc, pyaddr)
return
if pyaddr is None:
udp._fatal_error(
RuntimeError(
'uv_udp.receive callback: addr is NULL and nread >= 0'),
False)
return
if nread == 0:
data = b''
else: