Skip to content

Commit 448eea3

Browse files
committed
loop: Make loop.getaddrinfo behave like socket.getaddrinfo in edge cases
1 parent 32a9803 commit 448eea3

File tree

3 files changed

+58
-16
lines changed

3 files changed

+58
-16
lines changed

tests/test_dns.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ def _test_getaddrinfo(self, *args, **kwargs):
2626
if err is not None:
2727
self.assertEqual(ex.args, err.args)
2828
else:
29-
raise
29+
ex.__context__ = err
30+
raise ex
31+
except OSError as ex:
32+
ex.__context__ = err
33+
raise ex
3034
else:
31-
if err is not None:
32-
self.fail(
33-
'uv failed, but blocking getaddrinfo run without error')
34-
35-
self.assertEqual(a1, a2)
35+
if err is None:
36+
self.assertEqual(a1, a2)
3637

3738
def _test_getnameinfo(self, *args, **kwargs):
3839
err = None
@@ -54,8 +55,7 @@ def _test_getnameinfo(self, *args, **kwargs):
5455
raise
5556
else:
5657
if err is not None:
57-
self.fail(
58-
'uv failed, but blocking getnameinfo run without error')
58+
raise err
5959

6060
self.assertEqual(a1, a2)
6161

@@ -77,6 +77,24 @@ def test_getaddrinfo_5(self):
7777
def test_getaddrinfo_6(self):
7878
self._test_getaddrinfo(_HOST.encode(), str(_PORT).encode())
7979

80+
def test_getaddrinfo_7(self):
81+
self._test_getaddrinfo(None, 0)
82+
83+
def test_getaddrinfo_8(self):
84+
self._test_getaddrinfo('', 0)
85+
86+
def test_getaddrinfo_9(self):
87+
self._test_getaddrinfo(b'', 0)
88+
89+
def test_getaddrinfo_10(self):
90+
self._test_getaddrinfo(None, None)
91+
92+
def test_getaddrinfo_11(self):
93+
self._test_getaddrinfo(_HOST.encode(), str(_PORT))
94+
95+
def test_getaddrinfo_12(self):
96+
self._test_getaddrinfo(_HOST.encode(), str(_PORT).encode())
97+
8098
######
8199

82100
def test_getnameinfo_1(self):
@@ -117,3 +135,5 @@ async def run():
117135

118136
class Test_AIO_DNS(BaseTestDNS, tb.AIOTestCase):
119137
pass
138+
def test_getaddrinfo_11(self):
139+
self._test_getaddrinfo(_HOST.encode(), str(_PORT))

uvloop/dns.pyx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,27 @@ cdef class AddrInfoRequest(UVRequest):
153153
int family, int type, int proto, int flags,
154154
object callback):
155155

156-
cdef int err
156+
cdef:
157+
int err
158+
char *chost
159+
char *cport
160+
161+
if host is None:
162+
chost = NULL
163+
else:
164+
chost = <char*>host
165+
166+
if port is None:
167+
cport = NULL
168+
else:
169+
cport = <char*>port
170+
171+
if cport is NULL and chost is NULL:
172+
self.on_done()
173+
msg = system.gai_strerror(socket_EAI_NONAME).decode('utf-8')
174+
ex = socket_gaierror(socket_EAI_NONAME, msg)
175+
callback(ex)
176+
return
157177

158178
memset(&self.hints, 0, sizeof(system.addrinfo))
159179
self.hints.ai_flags = flags
@@ -173,8 +193,8 @@ cdef class AddrInfoRequest(UVRequest):
173193
err = uv.uv_getaddrinfo(loop.uvloop,
174194
<uv.uv_getaddrinfo_t*>self.request,
175195
__on_addrinfo_resolved,
176-
host,
177-
port,
196+
chost,
197+
cport,
178198
&self.hints)
179199

180200
if err < 0:

uvloop/loop.pyx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -497,18 +497,20 @@ cdef class Loop:
497497
int proto, int flags,
498498
int unpack):
499499

500-
if port is None:
501-
port = 0
502500
if isinstance(port, str):
503501
port = port.encode()
504502
elif isinstance(port, int):
505503
port = str(port).encode()
506-
if not isinstance(port, bytes):
504+
if port is not None and not isinstance(port, bytes):
507505
raise TypeError('port must be a str, bytes or int')
506+
508507
if isinstance(host, str):
509508
host = host.encode()
510-
if not isinstance(host, bytes):
511-
raise TypeError('host must be a str or bytes')
509+
if host is not None:
510+
if not isinstance(host, bytes):
511+
raise TypeError('host must be a str or bytes')
512+
if host == b'':
513+
host = None
512514

513515
fut = self._new_future()
514516

0 commit comments

Comments
 (0)