Пример #1
0
async def test_http1_request(event_loop: asyncio.AbstractEventLoop) -> None:
    server = TCPServer(
        sanity_framework,
        event_loop,
        Config(),
        WorkerContext(),
        MemoryReader(),
        MemoryWriter()  # type: ignore  # noqa: E501
    )
    task = event_loop.create_task(server.run())
    client = h11.Connection(h11.CLIENT)
    await server.reader.send(  # type: ignore
        client.send(
            h11.Request(
                method="POST",
                target="/",
                headers=[
                    (b"host", b"hypercorn"),
                    (b"connection", b"close"),
                    (b"content-length", b"%d" % len(SANITY_BODY)),
                ],
            )))
    await server.reader.send(client.send(h11.Data(data=SANITY_BODY))
                             )  # type: ignore
    await server.reader.send(client.send(h11.EndOfMessage()))  # type: ignore
    events = []
    while True:
        event = client.next_event()
        if event == h11.NEED_DATA:
            data = await server.writer.receive()  # type: ignore
            client.receive_data(data)
        elif isinstance(event, h11.ConnectionClosed):
            break
        else:
            events.append(event)

    assert events == [
        h11.Response(
            status_code=200,
            headers=[
                (b"content-length", b"15"),
                (b"date", b"Thu, 01 Jan 1970 01:23:20 GMT"),
                (b"server", b"hypercorn-h11"),
                (b"connection", b"close"),
            ],
            http_version=b"1.1",
            reason=b"",
        ),
        h11.Data(data=b"Hello & Goodbye"),
        h11.EndOfMessage(headers=[]),  # type: ignore
    ]
    server.reader.close()  # type: ignore
    await task
Пример #2
0
async def test_spawn_app_error(event_loop: asyncio.AbstractEventLoop,
                               http_scope: HTTPScope) -> None:
    async def _error_app(scope: Scope, receive: Callable,
                         send: Callable) -> None:
        raise Exception()

    app_queue: asyncio.Queue = asyncio.Queue()
    async with TaskGroup(event_loop) as task_group:
        context = Context(task_group)
        await context.spawn_app(_error_app, Config(), http_scope,
                                app_queue.put)
    assert (await app_queue.get()) is None
Пример #3
0
async def _make_upgrade_request(
        request: h11.Request) -> h11.InformationalResponse:
    client_stream, server_stream = trio.testing.memory_stream_pair()
    server_stream.socket = MockSocket()
    async with trio.open_nursery() as nursery:
        nursery.start_soon(serve_stream, echo_framework, Config(),
                           server_stream)
        client = h11.Connection(h11.CLIENT)
        await client_stream.send_all(client.send(request))
        client.receive_data(await client_stream.receive_some(2**16))
        await client_stream.aclose()
    return client.next_event()
Пример #4
0
async def test_protocol_handle_max_incomplete(monkeypatch: MonkeyPatch) -> None:
    config = Config()
    config.h11_max_incomplete_size = 5
    MockHTTPStream = AsyncMock()  # noqa: N806
    MockHTTPStream.return_value = AsyncMock(spec=HTTPStream)
    monkeypatch.setattr(hypercorn.protocol.h11, "HTTPStream", MockHTTPStream)
    MockEvent = AsyncMock()  # noqa: N806
    MockEvent.return_value = AsyncMock(spec=IOEvent)
    protocol = H11Protocol(config, False, None, None, CoroutineMock(), CoroutineMock(), MockEvent)
    await protocol.handle(RawData(data=b"GET / HTTP/1.1\r\nHost: hypercorn\r\n"))
    protocol.send.assert_called()
    assert protocol.send.call_args_list == [
        call(
            RawData(
                data=b"HTTP/1.1 400 \r\ncontent-length: 0\r\nconnection: close\r\n"
                b"date: Thu, 01 Jan 1970 01:23:20 GMT\r\nserver: hypercorn-h11\r\n\r\n"
            )
        ),
        call(RawData(data=b"")),
        call(Closed()),
    ]
Пример #5
0
async def test_asgi_send_invalid_message(data_bytes: Any,
                                         data_text: Any) -> None:
    server = WebsocketMixin()
    server.config = Config()
    server.start_time = 0.0
    server.state = ASGIWebsocketState.CONNECTED
    with pytest.raises((TypeError, ValueError)):
        await server.asgi_send({
            "type": "websocket.send",
            "bytes": data_bytes,
            "text": data_text
        })
Пример #6
0
def test_access_logger_init(
    target: Union[logging.Logger, str, None],
    expected_name: Optional[str],
    expected_handler_type: Optional[Type[logging.Handler]],
) -> None:
    config = Config()
    config.accesslog = target
    config.access_log_format = "%h"
    logger = Logger(config)
    assert logger.access_log_format == "%h"
    assert logger.getEffectiveLevel() == logging.INFO
    if target is None:
        assert logger.access_logger is None
    elif expected_name is None:
        assert logger.access_logger.handlers == []
    else:
        assert logger.access_logger.name == expected_name
        if expected_handler_type is None:
            assert logger.access_logger.handlers == []
        else:
            assert isinstance(logger.access_logger.handlers[0], expected_handler_type)
Пример #7
0
async def test_http2_request(event_loop: asyncio.AbstractEventLoop) -> None:
    server = TCPServer(
        sanity_framework,
        event_loop,
        Config(),
        MemoryReader(),  # type: ignore
        MemoryWriter(http2=True),  # type: ignore
    )
    asyncio.ensure_future(server.run())
    client = h2.connection.H2Connection()
    client.initiate_connection()
    await server.reader.send(client.data_to_send())  # type: ignore
    stream_id = client.get_next_available_stream_id()
    client.send_headers(
        stream_id,
        [
            (":method", "POST"),
            (":path", "/"),
            (":authority", "hypercorn"),
            (":scheme", "https"),
            ("content-length", "%d" % len(SANITY_BODY)),
        ],
    )
    client.send_data(stream_id, SANITY_BODY)
    client.end_stream(stream_id)
    await server.reader.send(client.data_to_send())  # type: ignore
    events = []
    open_ = True
    while open_:
        data = await server.writer.receive()  # type: ignore
        if data == b"":
            open_ = False

        h2_events = client.receive_data(data)
        for event in h2_events:
            if isinstance(event, h2.events.DataReceived):
                client.acknowledge_received_data(event.flow_controlled_length, event.stream_id)
            elif isinstance(
                event,
                (h2.events.ConnectionTerminated, h2.events.StreamEnded, h2.events.StreamReset),
            ):
                open_ = False
                break
            else:
                events.append(event)
        await server.reader.send(client.data_to_send())  # type: ignore
    assert isinstance(events[2], h2.events.ResponseReceived)
    assert events[2].headers == [
        (b":status", b"200"),
        (b"content-length", b"15"),
        (b"date", b"Thu, 01 Jan 1970 01:23:20 GMT"),
        (b"server", b"hypercorn-h2"),
    ]
Пример #8
0
async def test_spawn_app_cancelled(event_loop: asyncio.AbstractEventLoop,
                                   http_scope: HTTPScope) -> None:
    async def _error_app(scope: Scope, receive: Callable,
                         send: Callable) -> None:
        raise asyncio.CancelledError()

    app_queue: asyncio.Queue = asyncio.Queue()
    with pytest.raises(asyncio.CancelledError):
        async with TaskGroup(event_loop) as task_group:
            await task_group.spawn_app(_error_app, Config(), http_scope,
                                       app_queue.put)
    assert (await app_queue.get()) is None
Пример #9
0
async def test_http2_websocket(event_loop: asyncio.AbstractEventLoop) -> None:
    server = TCPServer(  # type: ignore
        sanity_framework, event_loop, Config(), MemoryReader(),
        MemoryWriter(http2=True))
    asyncio.ensure_future(server.run())
    h2_client = h2.connection.H2Connection()
    h2_client.initiate_connection()
    await server.reader.send(h2_client.data_to_send())  # type: ignore
    stream_id = h2_client.get_next_available_stream_id()
    h2_client.send_headers(
        stream_id,
        [
            (":method", "CONNECT"),
            (":path", "/"),
            (":authority", "hypercorn"),
            (":scheme", "https"),
            ("sec-websocket-version", "13"),
        ],
    )
    await server.reader.send(h2_client.data_to_send())  # type: ignore
    events = h2_client.receive_data(await
                                    server.writer.receive())  # type: ignore
    await server.reader.send(h2_client.data_to_send())  # type: ignore
    events = h2_client.receive_data(await
                                    server.writer.receive())  # type: ignore
    events = h2_client.receive_data(await
                                    server.writer.receive())  # type: ignore
    assert isinstance(events[0], h2.events.ResponseReceived)
    assert events[0].headers == [
        (b":status", b"200"),
        (b"date", b"Thu, 01 Jan 1970 01:23:20 GMT"),
        (b"server", b"hypercorn-h2"),
    ]
    client = wsproto.connection.Connection(wsproto.ConnectionType.CLIENT)
    h2_client.send_data(
        stream_id, client.send(wsproto.events.BytesMessage(data=SANITY_BODY)))
    await server.reader.send(h2_client.data_to_send())  # type: ignore
    events = h2_client.receive_data(await
                                    server.writer.receive())  # type: ignore
    client.receive_data(events[0].data)
    assert list(client.events()) == [
        wsproto.events.TextMessage(data="Hello & Goodbye")
    ]
    h2_client.send_data(stream_id,
                        client.send(wsproto.events.CloseConnection(code=1000)))
    await server.reader.send(h2_client.data_to_send())  # type: ignore
    events = h2_client.receive_data(await
                                    server.writer.receive())  # type: ignore
    client.receive_data(events[0].data)
    assert list(client.events()) == [
        wsproto.events.CloseConnection(code=1000, reason="")
    ]
    await server.reader.send(b"")  # type: ignore
Пример #10
0
async def test_httpx_starlette(unused_tcp_port: int,
                               calculator_server_creator) -> None:
    """Test the httpx client/starlette server combo."""
    serv: Server[Calculator, StarletteRequest] = calculator_server_creator(
        StarletteRequest)

    @serv.implement(Calculator.call_none)
    async def call_none(ctx: StarletteRequest) -> int:
        assert ctx.method == "POST"
        return 1

    app = create_starlette_app(serv)

    config = Config()
    config.bind = [f"localhost:{unused_tcp_port}"]
    shutdown_event = Event()

    async def shutdown_trigger():
        await shutdown_event.wait()

    task = create_task(serve(app, config, shutdown_trigger=shutdown_trigger))

    from asyncio import sleep

    await sleep(0.1)  # Wait for the server to start up.

    t = await create_client(
        Calculator,
        httpx_client_adapter(f"http://localhost:{unused_tcp_port}"),
    )
    r = await t.add(1, 2)
    await t.call_none()

    assert r == 3

    await close_client(t)

    shutdown_event.set()

    await task
Пример #11
0
 def run_app_sync(*args, loop=None, shutdown_event=None):
     kwargs = {}
     config = Config()
     cert_file_name, key_file_name = ssl_creds or (None, None)
     if cert_file_name:
         kwargs['certfile'] = cert_file_name
         config.certfile = cert_file_name
     if key_file_name:
         kwargs['keyfile'] = key_file_name
         config.keyfile = key_file_name
     setup_quart_logging()
     config.bind = ['0.0.0.0:%s' % port]
     loop = loop or ensure_event_loop()
     run_kwargs = {}
     if shutdown_event:
         run_kwargs['shutdown_trigger'] = shutdown_event.wait
     try:
         try:
             return loop.run_until_complete(serve(app, config,
                                                  **run_kwargs))
         except Exception as e:
             LOG.info('Error running server event loop on port %s: %s %s' %
                      (port, e, traceback.format_exc()))
             if 'SSL' in str(e):
                 c_exists = os.path.exists(cert_file_name)
                 k_exists = os.path.exists(key_file_name)
                 c_size = len(load_file(cert_file_name)) if c_exists else 0
                 k_size = len(load_file(key_file_name)) if k_exists else 0
                 LOG.warning(
                     'Unable to create SSL context. Cert files exist: %s %s (%sB), %s %s (%sB)'
                     % (cert_file_name, c_exists, c_size, key_file_name,
                        k_exists, k_size))
             raise
     finally:
         try:
             _cancel_all_tasks(loop)
             loop.run_until_complete(loop.shutdown_asyncgens())
         finally:
             asyncio.set_event_loop(None)
             loop.close()
Пример #12
0
async def test_http2_websocket(nursery: trio._core._run.Nursery) -> None:
    client_stream, server_stream = trio.testing.memory_stream_pair()
    server_stream.transport_stream = Mock(return_value=PropertyMock(
        return_value=MockSocket()))
    server_stream.do_handshake = AsyncMock()
    server_stream.selected_alpn_protocol = Mock(return_value="h2")
    server = TCPServer(sanity_framework, Config(), WorkerContext(),
                       server_stream)
    nursery.start_soon(server.run)
    h2_client = h2.connection.H2Connection()
    h2_client.initiate_connection()
    await client_stream.send_all(h2_client.data_to_send())
    stream_id = h2_client.get_next_available_stream_id()
    h2_client.send_headers(
        stream_id,
        [
            (":method", "CONNECT"),
            (":path", "/"),
            (":authority", "hypercorn"),
            (":scheme", "https"),
            ("sec-websocket-version", "13"),
        ],
    )
    await client_stream.send_all(h2_client.data_to_send())
    events = h2_client.receive_data(await client_stream.receive_some(1024))
    await client_stream.send_all(h2_client.data_to_send())
    events = h2_client.receive_data(await client_stream.receive_some(1024))
    if not isinstance(events[-1], h2.events.ResponseReceived):
        events = h2_client.receive_data(await client_stream.receive_some(1024))
    assert events[-1].headers == [
        (b":status", b"200"),
        (b"date", b"Thu, 01 Jan 1970 01:23:20 GMT"),
        (b"server", b"hypercorn-h2"),
    ]
    client = wsproto.connection.Connection(wsproto.ConnectionType.CLIENT)
    h2_client.send_data(
        stream_id, client.send(wsproto.events.BytesMessage(data=SANITY_BODY)))
    await client_stream.send_all(h2_client.data_to_send())
    events = h2_client.receive_data(await client_stream.receive_some(1024))
    client.receive_data(events[0].data)
    assert list(client.events()) == [
        wsproto.events.TextMessage(data="Hello & Goodbye")
    ]
    h2_client.send_data(stream_id,
                        client.send(wsproto.events.CloseConnection(code=1000)))
    await client_stream.send_all(h2_client.data_to_send())
    events = h2_client.receive_data(await client_stream.receive_some(1024))
    client.receive_data(events[0].data)
    assert list(client.events()) == [
        wsproto.events.CloseConnection(code=1000, reason="")
    ]
    await client_stream.send_all(b"")
Пример #13
0
def run_http_app(app, host, port):
    from hypercorn.config import Config as HyperConfig
    from hypercorn.asyncio import serve
    from quart.logging import create_serving_logger

    config = HyperConfig()
    config.access_log_format = "%(h)s %(r)s %(s)s %(b)s %(D)s"
    config.access_logger = create_serving_logger()  # type: ignore
    config.bind = [f"{host}:{port}"]
    config.ca_certs = None
    config.certfile = None
    # config.debug = True
    config.error_logger = config.access_logger  # type: ignore
    config.keyfile = None
    config.use_reloader = False
    scheme = 'https' if config.ssl_enabled else 'http'
    print("Listening on {}://{}".format(scheme, config.bind[0]))
    return serve(app, config)
Пример #14
0
async def test_complets_on_half_close(event_loop: asyncio.AbstractEventLoop) -> None:
    server = TCPServer(
        echo_framework, event_loop, Config(), MemoryReader(), MemoryWriter()  # type: ignore
    )
    asyncio.ensure_future(server.run())
    await server.reader.send(b"GET / HTTP/1.1\r\nHost: hypercorn\r\n\r\n")  # type: ignore
    server.reader.close()  # type: ignore
    await asyncio.sleep(0)
    data = await server.writer.receive()  # type: ignore
    assert (
        data
        == b"HTTP/1.1 200 \r\ncontent-length: 335\r\ndate: Thu, 01 Jan 1970 01:23:20 GMT\r\nserver: hypercorn-h11\r\n\r\n"  # noqa: E501
    )
Пример #15
0
 def __init__(
     self,
     path: str,
     event_loop: asyncio.AbstractEventLoop,
     *,
     framework: Type[ASGIFramework] = EchoFramework,
 ) -> None:
     self.transport = MockTransport()
     self.server = WebsocketServer(  # type: ignore
         framework, event_loop, Config(), self.transport)
     self.connection = WSConnection(ConnectionType.CLIENT)
     self.server.data_received(
         self.connection.send(Request(target=path, host="hypercorn")))
Пример #16
0
    def start_app(self, debug):
        ssl_context = None
        self.logger.debug("Preparing to start rest-service")
        if self.get_use_ssl() and self.get_key_pem() is not None and \
                self.get_cert_pem() is not None:
            self.logger.debug(
                "Preparing ssl_context with cert:{} and key:{}".format(
                    self.get_cert_pem(), self.get_key_pem()))
            ssl_context = (self.get_cert_pem(), self.get_key_pem())
        self.logger.info("Starting the application {}:{} using ssl? {}".format(
            self.get_listening_host(), self.get_listening_port(),
            ssl_context is None))

        # looked at the hypercorn and quart Python project to figure out
        # how to start the application separately, without going through
        # the Quart.app.run APIs
        self.app.debug = debug
        config = HyperConfig()
        config.debug = debug
        config.access_log_format = "%(h)s %(r)s %(s)s %(b)s %(D)s"
        config.accesslog = self.logger.logger
        config.bind = [
            "{host}:{port}".format(
                **{
                    'host': self.get_listening_host(),
                    'port': self.get_listening_port()
                })
        ]
        config.certfile = self.get_cert_pem() if self.get_use_ssl() else None
        config.keyfile = self.get_key_pem() if self.get_use_ssl() else None

        config.errorlog = config.accesslog
        config.use_reloader = True
        scheme = "https" if config.ssl_enabled else "http"

        self.logger.info("Running on {}://{} (CTRL + C to quit)".format(
            scheme, config.bind[0]))
        loop = asyncio.get_event_loop()
        if loop is not None:
            loop.set_debug(debug or False)
            loop.run_until_complete(serve(self.app, config))
        else:
            asyncio.run(serve(self.app, config), debug=config.debug)
Пример #17
0
async def test_h2_prior_knowledge(
        event_loop: asyncio.AbstractEventLoop) -> None:
    client = h2.connection.H2Connection()
    client.initiate_connection()
    client.ping(b"12345678")
    server = Server(EchoFramework, event_loop, Config())
    transport = MockTransport()
    server.connection_made(transport)  # type: ignore
    server.data_received(client.data_to_send())
    await transport.updated.wait()
    events = client.receive_data(transport.data)
    client.close_connection()
    server.data_received(client.data_to_send())
    assert isinstance(events[-1], h2.events.PingAcknowledged)
Пример #18
0
async def test_h2_prior_knowledge() -> None:
    client_stream, server_stream = trio.testing.memory_stream_pair()
    server_stream.socket = MockSocket()
    async with trio.open_nursery() as nursery:
        nursery.start_soon(serve_stream, EchoFramework, Config(),
                           server_stream)
        client = h2.connection.H2Connection()
        client.initiate_connection()
        client.ping(b"12345678")
        await client_stream.send_all(client.data_to_send())
        events = client.receive_data(await client_stream.receive_some(2**16))
        client.close_connection()
        await client_stream.send_all(client.data_to_send())
    assert isinstance(events[-1], h2.events.PingAcknowledged)
Пример #19
0
def start_hypercorn(app: Application, app_config: Dict[str, Any]) -> None:
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)

    shutdown_event = asyncio.Event()

    def _signal_handler(*_):
        shutdown_event.set()

    loop.add_signal_handler(signal.SIGTERM, _signal_handler)
    loop.add_signal_handler(signal.SIGINT, _signal_handler)

    host = app_config['host']
    port = app_config['port']

    config = Config()
    config.bind = [f"{host}:{port}"]

    loop.run_until_complete(
        serve(
            app,
            config,
            shutdown_trigger=shutdown_event.wait  # type: ignore
        ))
Пример #20
0
 def __init__(self, log_collector, broker, config_manager, config=dict()):
     self.log_collector = log_collector
     self.broker = broker
     self.config_manager = config_manager
     self.config = config
     self.log = self.log_collector.get_logger('web')
     self.host = config.get('host', '0.0.0.0')
     self.port = config.get('port', 80)
     # Hypercorn
     self.task = None
     self.shutdown_event = asyncio.Event()
     self.hypercorn_config = Config()
     self.hypercorn_config.bind = ['{}:{}'.format(self.host, self.port)]
     self.hypercorn_config.logconfig_dict = self.get_log_config()
     self.app = App(config_manager=self.config_manager)
Пример #21
0
def hypercorn_config_from_env() -> Config:
    """Fill in a hypercorn Config object with environment variables"""

    # this grabs all the attributes of the Config class used for configuration
    # skipping over methods and other unusable attributes
    config_attrs = [
        config_attr for config_attr in dir(Config)
        if not config_attr.startswith("_")
        and not callable(getattr(Config, config_attr))
    ]

    hypercorn_config = Config()
    for config_attr in config_attrs:
        if (config_value := os.getenv(config_attr.upper())) is not None:
            setattr(hypercorn_config, config_attr, config_value)
Пример #22
0
async def test_spawn_app(event_loop: asyncio.AbstractEventLoop) -> None:
    async def _echo_app(scope: dict, receive: Callable,
                        send: Callable) -> None:
        while True:
            message = await receive()
            if message is None:
                return
            await send(message)

    app_queue: asyncio.Queue = asyncio.Queue()
    put = await spawn_app(_echo_app, event_loop, Config(), {"asgi": {}},
                          app_queue.put)
    await put({"type": "message"})
    assert (await app_queue.get()) == {"type": "message"}
    await put(None)
Пример #23
0
def run(bind,
        port,
        shutdown_trigger: Optional[Event] = None,
        use_uvloop: bool = True):
    if use_uvloop:
        logger.debug('Using uvloop')
        asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    loop = asyncio.get_event_loop()
    shutdown_trigger = shutdown_trigger or asyncio.Event()

    def _signal_handler(*_):
        print('')
        logger.warning('Shutting down web server')
        shutdown_trigger.set()

    for signal in (SIGHUP, SIGTERM, SIGINT):
        loop.add_signal_handler(signal, _signal_handler)

    hyper_config = HypercornConfig()
    hyper_config.bind = [f'{bind}:{port}']

    logger.info('Starting web server')
    loop.run_until_complete(hypercorn_serve(
        app, hyper_config, shutdown_trigger=shutdown_trigger.wait))
Пример #24
0
def run(campaign, session_manager, port=80):
    app = create_app(campaign, session_manager)

    shutdown_event = asyncio.Event()

    def _signal_handler(*_):
        shutdown_event.set()

    def _exception_handler(context):
        exception = context.get("exception")
        shutdown_event.set()
        raise (exception)

    loop = asyncio.get_event_loop()
    loop.set_exception_handler(_exception_handler)
    if is_posix():
        loop.add_signal_handler(signal.SIGINT, _signal_handler)
        loop.add_signal_handler(signal.SIGTERM, _signal_handler)

    config = Config()
    config.bind = ["0.0.0.0:" + str(port)]

    loop.run_until_complete(
        serve(app, config, shutdown_trigger=shutdown_event.wait))
Пример #25
0
async def startQuart(si):
    print(f"{si['serviceName']}({si['instanceID']})(v{si['serviceVersion']}) running at {si['serviceIP']}:{si['servicePort']}")
    config = Config()
    config.bind = [f"{si['serviceIP']}:{si['servicePort']}"]
    # config.bind = [f"0.0.0.0:{si['servicePort']}"]
    config.access_log_format = '%(h)s %(r)s %(s)s %(b)s %(D)s'
    config.accesslog = create_serving_logger()
    config.errorlog = config.accesslog
    loop = asyncio.get_event_loop()
    await loop.create_task(serve(app, config))
Пример #26
0
async def test_http1_request(nursery: trio._core._run.Nursery) -> None:
    client_stream, server_stream = trio.testing.memory_stream_pair()
    server_stream.socket = MockSocket()
    server = TCPServer(sanity_framework, Config(), WorkerContext(),
                       server_stream)
    nursery.start_soon(server.run)
    client = h11.Connection(h11.CLIENT)
    await client_stream.send_all(
        client.send(
            h11.Request(
                method="POST",
                target="/",
                headers=[
                    (b"host", b"hypercorn"),
                    (b"connection", b"close"),
                    (b"content-length", b"%d" % len(SANITY_BODY)),
                ],
            )))
    await client_stream.send_all(client.send(h11.Data(data=SANITY_BODY)))
    await client_stream.send_all(client.send(h11.EndOfMessage()))
    events = []
    while True:
        event = client.next_event()
        if event == h11.NEED_DATA:
            # bytes cast is key otherwise b"" is lost
            data = bytes(await client_stream.receive_some(1024))
            client.receive_data(data)
        elif isinstance(event, h11.ConnectionClosed):
            break
        else:
            events.append(event)

    assert events == [
        h11.Response(
            status_code=200,
            headers=[
                (b"content-length", b"15"),
                (b"date", b"Thu, 01 Jan 1970 01:23:20 GMT"),
                (b"server", b"hypercorn-h11"),
                (b"connection", b"close"),
            ],
            http_version=b"1.1",
            reason=b"",
        ),
        h11.Data(data=b"Hello & Goodbye"),
        h11.EndOfMessage(headers=[]),  # type: ignore
    ]
Пример #27
0
async def test_asgi_send_invalid_http_message(status: Any, headers: Any,
                                              body: Any) -> None:
    server = WebsocketMixin()
    server.config = Config()
    server.start_time = 0.0
    server.state = ASGIWebsocketState.HANDSHAKE
    server.scope = {"method": "GET"}
    with pytest.raises((TypeError, ValueError)):
        await server.asgi_send({
            "type": "websocket.http.response.start",
            "headers": headers,
            "status": status
        })
        await server.asgi_send({
            "type": "websocket.http.response.body",
            "body": body
        })
Пример #28
0
async def test_http_server_drain(event_loop: asyncio.AbstractEventLoop) -> None:
    transport = MockTransport()
    server = HTTPServer(event_loop, Config(), transport, "")  # type: ignore
    server.pause_writing()

    async def write() -> None:
        server.write(b"Pre drain")
        await server.drain()
        server.write(b"Post drain")

    asyncio.ensure_future(write())
    await transport.updated.wait()
    assert bytes(transport.data) == b"Pre drain"
    transport.clear()
    server.resume_writing()
    await transport.updated.wait()
    assert bytes(transport.data) == b"Post drain"
Пример #29
0
 def __init__(
     self,
     event_loop: asyncio.AbstractEventLoop,
     *,
     framework: Type[ASGIFramework] = WebsocketFramework,
     path: str = '/ws',
 ) -> None:
     self.transport = MockTransport()
     self.server = WebsocketServer(
         framework, event_loop, Config(),
         self.transport)  # type: ignore # noqa: E501
     self.connection = wsproto.connection.WSConnection(
         wsproto.connection.CLIENT,
         host='hypercorn.com',
         resource=path,
     )
     self.server.data_received(self.connection.bytes_to_send())
Пример #30
0
async def test_spawn_app(event_loop: asyncio.AbstractEventLoop,
                         http_scope: HTTPScope) -> None:
    async def _echo_app(scope: Scope, receive: Callable,
                        send: Callable) -> None:
        while True:
            message = await receive()
            if message is None:
                return
            await send(message)

    app_queue: asyncio.Queue = asyncio.Queue()
    async with TaskGroup(event_loop) as task_group:
        put = await task_group.spawn_app(_echo_app, Config(), http_scope,
                                         app_queue.put)
        await put({"type": "http.disconnect"})  # type: ignore
        assert (await app_queue.get()) == {"type": "http.disconnect"}
        await put(None)