aiortc / aioquic

QUIC and HTTP/3 implementation in Python
BSD 3-Clause "New" or "Revised" License
1.69k stars 238 forks source link

asyncio API example doesn't work #28

Closed iwanbk closed 5 years ago

iwanbk commented 5 years ago

Hi, I just tried asyncio API example from https://aioquic.readthedocs.io/en/latest/asyncio.html#asyncio-api and it failed for me. The script

#!/usr/bin/env python

import asyncio
import sys
from aioquic.asyncio import connect

async def http_client(host, port):
    async with connect(host, port) as connection:
        reader, writer = await connection.create_stream()
        writer.write(b"GET /\r\n")
        writer.write_eof()

        response = await reader.read()
        sys.stdout.buffer.write(response)

asyncio.get_event_loop().run_until_complete(
    http_client("quic.aiortc.org", 4433))

error message

# python client.py
Traceback (most recent call last):
  File "client.py", line 17, in <module>
    http_client("quic.aiortc.org", 4433))
  File "/usr/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
    return future.result()
  File "client.py", line 8, in http_client
    async with connect(host, port) as connection:
  File "/root/quic/aioquic/aioquic/asyncio/compat.py", line 17, in __aenter__
    return await self.gen.__anext__()
  File "/root/quic/aioquic/aioquic/asyncio/client.py", line 77, in connect
    await protocol.wait_connected()
  File "/root/quic/aioquic/aioquic/asyncio/protocol.py", line 122, in wait_connected
    await asyncio.shield(self._connected_waiter)
ConnectionError

i use python 3.6.5 on Ubuntu 18.04 I got same result with python 3.7.3 on Mac.

Any idea?

jlaine commented 5 years ago

Hi! This fails because the demo server validates you present an ALPN protocol it understands.

You can fix this like so:

import asyncio
import sys

from aioquic.asyncio import connect
from aioquic.quic.configuration import QuicConfiguration

async def http_client(host, port):
    configuration = QuicConfiguration(alpn_protocols=["hq-22"])
    async with connect(host, port, configuration=configuration) as connection:
        reader, writer = await connection.create_stream()
        writer.write(b"GET /\r\n")
        writer.write_eof()

        response = await reader.read()
        sys.stdout.buffer.write(response)

asyncio.get_event_loop().run_until_complete(http_client("quic.aiortc.org", 4433))