Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/aiohttp/resolver.py
7763 views
1
import asyncio
2
import socket
3
from typing import Any, Dict, List, Optional, Type, Union
4
5
from .abc import AbstractResolver
6
from .helpers import get_running_loop
7
8
__all__ = ("ThreadedResolver", "AsyncResolver", "DefaultResolver")
9
10
try:
11
import aiodns
12
13
# aiodns_default = hasattr(aiodns.DNSResolver, 'gethostbyname')
14
except ImportError: # pragma: no cover
15
aiodns = None
16
17
aiodns_default = False
18
19
20
class ThreadedResolver(AbstractResolver):
21
"""Threaded resolver.
22
23
Uses an Executor for synchronous getaddrinfo() calls.
24
concurrent.futures.ThreadPoolExecutor is used by default.
25
"""
26
27
def __init__(self, loop: Optional[asyncio.AbstractEventLoop] = None) -> None:
28
self._loop = get_running_loop(loop)
29
30
async def resolve(
31
self, hostname: str, port: int = 0, family: int = socket.AF_INET
32
) -> List[Dict[str, Any]]:
33
infos = await self._loop.getaddrinfo(
34
hostname,
35
port,
36
type=socket.SOCK_STREAM,
37
family=family,
38
flags=socket.AI_ADDRCONFIG,
39
)
40
41
hosts = []
42
for family, _, proto, _, address in infos:
43
if family == socket.AF_INET6:
44
if len(address) < 3:
45
# IPv6 is not supported by Python build,
46
# or IPv6 is not enabled in the host
47
continue
48
if address[3]: # type: ignore[misc]
49
# This is essential for link-local IPv6 addresses.
50
# LL IPv6 is a VERY rare case. Strictly speaking, we should use
51
# getnameinfo() unconditionally, but performance makes sense.
52
host, _port = socket.getnameinfo(
53
address, socket.NI_NUMERICHOST | socket.NI_NUMERICSERV
54
)
55
port = int(_port)
56
else:
57
host, port = address[:2]
58
else: # IPv4
59
assert family == socket.AF_INET
60
host, port = address # type: ignore[misc]
61
hosts.append(
62
{
63
"hostname": hostname,
64
"host": host,
65
"port": port,
66
"family": family,
67
"proto": proto,
68
"flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
69
}
70
)
71
72
return hosts
73
74
async def close(self) -> None:
75
pass
76
77
78
class AsyncResolver(AbstractResolver):
79
"""Use the `aiodns` package to make asynchronous DNS lookups"""
80
81
def __init__(
82
self,
83
loop: Optional[asyncio.AbstractEventLoop] = None,
84
*args: Any,
85
**kwargs: Any
86
) -> None:
87
if aiodns is None:
88
raise RuntimeError("Resolver requires aiodns library")
89
90
self._loop = get_running_loop(loop)
91
self._resolver = aiodns.DNSResolver(*args, loop=loop, **kwargs)
92
93
if not hasattr(self._resolver, "gethostbyname"):
94
# aiodns 1.1 is not available, fallback to DNSResolver.query
95
self.resolve = self._resolve_with_query # type: ignore
96
97
async def resolve(
98
self, host: str, port: int = 0, family: int = socket.AF_INET
99
) -> List[Dict[str, Any]]:
100
try:
101
resp = await self._resolver.gethostbyname(host, family)
102
except aiodns.error.DNSError as exc:
103
msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"
104
raise OSError(msg) from exc
105
hosts = []
106
for address in resp.addresses:
107
hosts.append(
108
{
109
"hostname": host,
110
"host": address,
111
"port": port,
112
"family": family,
113
"proto": 0,
114
"flags": socket.AI_NUMERICHOST | socket.AI_NUMERICSERV,
115
}
116
)
117
118
if not hosts:
119
raise OSError("DNS lookup failed")
120
121
return hosts
122
123
async def _resolve_with_query(
124
self, host: str, port: int = 0, family: int = socket.AF_INET
125
) -> List[Dict[str, Any]]:
126
if family == socket.AF_INET6:
127
qtype = "AAAA"
128
else:
129
qtype = "A"
130
131
try:
132
resp = await self._resolver.query(host, qtype)
133
except aiodns.error.DNSError as exc:
134
msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed"
135
raise OSError(msg) from exc
136
137
hosts = []
138
for rr in resp:
139
hosts.append(
140
{
141
"hostname": host,
142
"host": rr.host,
143
"port": port,
144
"family": family,
145
"proto": 0,
146
"flags": socket.AI_NUMERICHOST,
147
}
148
)
149
150
if not hosts:
151
raise OSError("DNS lookup failed")
152
153
return hosts
154
155
async def close(self) -> None:
156
self._resolver.cancel()
157
158
159
_DefaultType = Type[Union[AsyncResolver, ThreadedResolver]]
160
DefaultResolver: _DefaultType = AsyncResolver if aiodns_default else ThreadedResolver
161
162