New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aiohttp client does not support ipv6 addresses #559

Closed
mx2323 opened this Issue Oct 8, 2015 · 6 comments

Comments

Projects
None yet
4 participants
@mx2323

mx2323 commented Oct 8, 2015

attempting to get a webpage from an ipv6 address doesnt appear to work in aiohttp 0.17.4

when i run the ipv6 address through curl it works.

i also tried the ipv4 address through the aiohttp client and that worked as well.

http://[::1]:9001/foo fails with the following exception
**
socket.gaierror: [Errno -9] Address family for hostname not supported
**

 Cannot connect to host ::1:9001 ssl:False http://[::1]:9001/foo
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/aiohttp/connector.py", line 571, in _create_connection
    server_hostname=hinfo['hostname'] if sslcontext else None)
  File "/usr/lib/python3.4/asyncio/base_events.py", line 581, in create_connection
    infos = f1.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 275, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/lib/python3.4/socket.py", line 533, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -9] **Address family for hostname not supported**

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/aiohttp/connector.py", line 292, in connect
    transport, proto = yield from self._create_connection(req)
  File "/usr/local/lib/python3.4/dist-packages/aiohttp/connector.py", line 588, in _create_connection
    (req.host, req.port)) from exc
aiohttp.errors.ClientOSError: Can not connect to ::1:9001
@mx2323

This comment has been minimized.

mx2323 commented Oct 8, 2015

looks like through a client with a session, it has to be specified via the connector, which is not intuitive or called out clearly in the documentation imo.

@asvetlov

This comment has been minimized.

Member

asvetlov commented Oct 9, 2015

That makes sense, I see no objections for relaxing default family param from IPv4 to both IPv4 and IPv6.

@asvetlov asvetlov reopened this Oct 9, 2015

@asvetlov asvetlov added this to the 0.18 milestone Oct 9, 2015

@asvetlov asvetlov self-assigned this Oct 9, 2015

asvetlov added a commit that referenced this issue Oct 10, 2015

Merge pull request #561 from KeepSafe/family_zero
TCPConnector processes both IPv4 and IPv6 by default #559
@asvetlov

This comment has been minimized.

Member

asvetlov commented Oct 10, 2015

Fixed

@asvetlov asvetlov closed this Oct 10, 2015

@gwillem

This comment has been minimized.

Contributor

gwillem commented Oct 27, 2016

@asvetlov relaxing family breaks (cryptically) on systems with an IPv6 stack, aiodns installed but no IPv6 route. See saghul/aiodns#23

Not sure if pycares should default to IPv4 for gethostbyname. If not, then perhaps the aiohttp docs should include a warning about this situation.

@asvetlov

This comment has been minimized.

Member

asvetlov commented Nov 1, 2016

aiodns is disabled by default by 9fbb7d7

@asvetlov asvetlov closed this Nov 1, 2016

@brunsgaard

This comment has been minimized.

brunsgaard commented Nov 1, 2016

For other people wanting to use aiodns, but force IPv4, the solution is to make a custom connector, with family bound to socket.AF_INET (IPv4).

import aiohttp
import asyncio
import socket

async def main(loop):
    url = 'http://requestb.in/yn6p4wyn'

    conn = aiohttp.TCPConnector(family=socket.AF_INET)
    async with aiohttp.ClientSession(connector=conn) as session:
        async with session.get(url) as resp:
            await resp.release()

loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()

I would just point that out, as I think it might be helpfull to some people out there ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment