except ImportError: # pragma: no cover
_have_requests = False
+_have_httpx = False
+_have_http2 = False
try:
import httpx
_have_httpx = True
+ try:
+ # See if http2 support is available.
+ with httpx.Client(http2=True):
+ _have_http2 = True
+ except Exception:
+ pass
except ImportError: # pragma: no cover
- _have_httpx = False
+ pass
have_doh = _have_requests or _have_httpx
"""
if not have_doh:
- raise NoDOH # pragma: no cover
+ raise NoDOH('Neither httpx nor requests is available.') # pragma: no cover
- _httpx_ok = True
+ _httpx_ok = _have_httpx
wire = q.to_wire()
(af, _, source) = _destination_and_source(where, port, source, source_port,
if _have_requests:
transport_adapter = SourceAddressAdapter(source)
+ if session:
+ _is_httpx = isinstance(session, httpx.Client)
+ if _is_httpx and not _httpx_ok:
+ raise NoDOH('Session is httpx, but httpx cannot be used for '
+ 'the requested operation.')
+ else:
+ _is_httpx = _httpx_ok
+
if not _httpx_ok and not _have_requests:
raise NoDOH('Cannot use httpx for this operation, and '
'requests is not available.')
with contextlib.ExitStack() as stack:
- if session:
- if _have_httpx:
- _is_httpx = isinstance(session, httpx.Client)
- else:
- _is_httpx = False
- if _is_httpx and not _httpx_ok:
- # we can't use this session
- session = None
if not session:
- if _have_httpx and _httpx_ok:
- _is_httpx = True
+ if _is_httpx:
session = stack.enter_context(httpx.Client(http1=True,
- http2=True,
+ http2=_have_http2,
verify=verify,
transport=transport))
else:
- _is_httpx = False
session = stack.enter_context(requests.sessions.Session())
if transport_adapter:
timeout=4)
self.assertTrue(q.is_response(r))
+ def test_get_request_http1(self):
+ saved_have_http2 = dns.query._have_http2
+ try:
+ dns.query._have_http2 = False
+ nameserver_url = random.choice(KNOWN_ANYCAST_DOH_RESOLVER_URLS)
+ q = dns.message.make_query('example.com.', dns.rdatatype.A)
+ r = dns.query.https(q, nameserver_url, session=self.session, post=False,
+ timeout=4)
+ self.assertTrue(q.is_response(r))
+ finally:
+ dns.query._have_http2 = saved_have_http2
+
def test_post_request(self):
nameserver_url = random.choice(KNOWN_ANYCAST_DOH_RESOLVER_URLS)
q = dns.message.make_query('example.com.', dns.rdatatype.A)
post=False, timeout=4)
self.assertTrue(q.is_response(r))
- def test_bootstrap_address(self):
+ def test_bootstrap_address_fails(self):
# We test this to see if v4 is available
if resolver_v4_addresses:
ip = '185.228.168.168'
with self.assertRaises(httpx.ConnectError):
dns.query.https(q, invalid_tls_url, session=self.session,
timeout=4)
- # use host header
- r = dns.query.https(q, valid_tls_url, session=self.session,
+ # We can't do the Host header and SNI magic with httpx, but
+ # we are demanding httpx be used by providing a session, so
+ # we should get a NoDOH exception.
+ with self.assertRaises(dns.query.NoDOH):
+ dns.query.https(q, valid_tls_url, session=self.session,
bootstrap_address=ip, timeout=4)
- self.assertTrue(q.is_response(r))
def test_new_session(self):
nameserver_url = random.choice(KNOWN_ANYCAST_DOH_RESOLVER_URLS)