Skip to content

Commit a714616

Browse files
author
Yury Selivanov
committed
asyncio: Fix getaddrinfo to accept service names (for port)
Patch by A. Jesse Jiryu Davis
1 parent a8f895f commit a714616

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

Lib/asyncio/base_events.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,26 @@ def _ipaddr_info(host, port, family, type, proto):
102102
else:
103103
return None
104104

105-
if port in {None, '', b''}:
105+
if port is None:
106106
port = 0
107-
elif isinstance(port, (bytes, str)):
108-
port = int(port)
107+
elif isinstance(port, bytes):
108+
if port == b'':
109+
port = 0
110+
else:
111+
try:
112+
port = int(port)
113+
except ValueError:
114+
# Might be a service name like b"http".
115+
port = socket.getservbyname(port.decode('ascii'))
116+
elif isinstance(port, str):
117+
if port == '':
118+
port = 0
119+
else:
120+
try:
121+
port = int(port)
122+
except ValueError:
123+
# Might be a service name like "http".
124+
port = socket.getservbyname(port)
109125

110126
if hasattr(socket, 'inet_pton'):
111127
if family == socket.AF_UNSPEC:

Lib/test/test_asyncio/test_base_events.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,26 @@ def test_port_parameter_types(self):
146146
(INET, STREAM, TCP, '', ('1.2.3.4', 1)),
147147
base_events._ipaddr_info('1.2.3.4', b'1', INET, STREAM, TCP))
148148

149+
def test_getaddrinfo_servname(self):
150+
INET = socket.AF_INET
151+
STREAM = socket.SOCK_STREAM
152+
TCP = socket.IPPROTO_TCP
153+
154+
self.assertEqual(
155+
(INET, STREAM, TCP, '', ('1.2.3.4', 80)),
156+
base_events._ipaddr_info('1.2.3.4', 'http', INET, STREAM, TCP))
157+
158+
self.assertEqual(
159+
(INET, STREAM, TCP, '', ('1.2.3.4', 80)),
160+
base_events._ipaddr_info('1.2.3.4', b'http', INET, STREAM, TCP))
161+
162+
# Raises "service/proto not found".
163+
with self.assertRaises(OSError):
164+
base_events._ipaddr_info('1.2.3.4', 'nonsense', INET, STREAM, TCP)
165+
166+
with self.assertRaises(OSError):
167+
base_events._ipaddr_info('1.2.3.4', 'nonsense', INET, STREAM, TCP)
168+
149169
@patch_socket
150170
def test_ipaddr_info_no_inet_pton(self, m_socket):
151171
del m_socket.inet_pton

0 commit comments

Comments
 (0)