예제 #1
0
async def test_start_stop():
    async def server_handler(reader: asyncio.StreamReader,
                             writer: asyncio.StreamWriter):
        assert await reader.readuntil(b"\r\n\r\n"
                                      ) == b"GET /hello HTTP/1.1\r\n\r\n"
        writer.write(b"HTTP/1.1 204 No Content\r\n\r\n")
        await writer.drain()
        writer.close()

    ps = Proxyserver()
    with taddons.context(ps) as tctx:
        state = HelperAddon()
        tctx.master.addons.add(state)
        async with tcp_server(server_handler) as addr:
            tctx.configure(ps, listen_host="127.0.0.1", listen_port=0)
            assert not ps.server
            ps.running()
            await tctx.master.await_log("Proxy server listening", level="info")
            assert ps.server

            proxy_addr = ps.server.sockets[0].getsockname()[:2]
            reader, writer = await asyncio.open_connection(*proxy_addr)
            req = f"GET http://{addr[0]}:{addr[1]}/hello HTTP/1.1\r\n\r\n"
            writer.write(req.encode())
            assert await reader.readuntil(
                b"\r\n\r\n") == b"HTTP/1.1 204 No Content\r\n\r\n"

            tctx.configure(ps, server=False)
            await tctx.master.await_log("Stopping server", level="info")
            assert not ps.server
            assert state.flows
            assert state.flows[0].request.path == "/hello"
            assert state.flows[0].response.status_code == 204
예제 #2
0
async def test_asgi_full():
    ps = Proxyserver()
    addons = [
        asgiapp.WSGIApp(tapp, "testapp", 80),
        asgiapp.ASGIApp(errapp, "errapp", 80),
        asgiapp.ASGIApp(noresponseapp, "noresponseapp", 80),
    ]
    with taddons.context(ps, *addons) as tctx:
        tctx.master.addons.add(next_layer.NextLayer())
        tctx.configure(ps, listen_host="127.0.0.1", listen_port=0)
        ps.running()
        await tctx.master.await_log("Proxy server listening", level="info")
        proxy_addr = ps.server.sockets[0].getsockname()[:2]

        reader, writer = await asyncio.open_connection(*proxy_addr)
        req = f"GET http://testapp:80/ HTTP/1.1\r\n\r\n"
        writer.write(req.encode())
        header = await reader.readuntil(b"\r\n\r\n")
        assert header.startswith(b"HTTP/1.1 200 OK")
        body = await reader.readuntil(b"testapp")
        assert body == b"testapp"

        reader, writer = await asyncio.open_connection(*proxy_addr)
        req = f"GET http://testapp:80/parameters?param1=1&param2=2 HTTP/1.1\r\n\r\n"
        writer.write(req.encode())
        header = await reader.readuntil(b"\r\n\r\n")
        assert header.startswith(b"HTTP/1.1 200 OK")
        body = await reader.readuntil(b"}")
        assert body == b'{"param1": "1", "param2": "2"}'

        reader, writer = await asyncio.open_connection(*proxy_addr)
        req = f"POST http://testapp:80/requestbody HTTP/1.1\r\nContent-Length: 6\r\n\r\nHello!"
        writer.write(req.encode())
        header = await reader.readuntil(b"\r\n\r\n")
        assert header.startswith(b"HTTP/1.1 200 OK")
        body = await reader.readuntil(b"}")
        assert body == b'{"body": "Hello!"}'

        reader, writer = await asyncio.open_connection(*proxy_addr)
        req = f"GET http://errapp:80/?foo=bar HTTP/1.1\r\n\r\n"
        writer.write(req.encode())
        header = await reader.readuntil(b"\r\n\r\n")
        assert header.startswith(b"HTTP/1.1 500")
        body = await reader.readuntil(b"ASGI Error")
        assert body == b"ASGI Error"

        reader, writer = await asyncio.open_connection(*proxy_addr)
        req = f"GET http://noresponseapp:80/ HTTP/1.1\r\n\r\n"
        writer.write(req.encode())
        header = await reader.readuntil(b"\r\n\r\n")
        assert header.startswith(b"HTTP/1.1 500")
        body = await reader.readuntil(b"ASGI Error")
        assert body == b"ASGI Error"
예제 #3
0
async def test_warn_no_nextlayer():
    """
    Test that we log an error if the proxy server is started without NextLayer addon.
    That is a mean trap to fall into when writing end-to-end tests.
    """
    ps = Proxyserver()
    with taddons.context(ps) as tctx:
        tctx.configure(ps, listen_host="127.0.0.1", listen_port=0)
        ps.running()
        assert await tctx.master.await_log("Proxy server listening at", level="info")
        assert tctx.master.has_log("Warning: Running proxyserver without nextlayer addon!", level="warn")
        await ps.shutdown_server()
예제 #4
0
async def test_start_stop():
    async def server_handler(reader: asyncio.StreamReader,
                             writer: asyncio.StreamWriter):
        assert await reader.readuntil(b"\r\n\r\n"
                                      ) == b"GET /hello HTTP/1.1\r\n\r\n"
        writer.write(b"HTTP/1.1 204 No Content\r\n\r\n")
        await writer.drain()
        writer.close()

    ps = Proxyserver()
    with taddons.context(ps) as tctx:
        state = HelperAddon()
        tctx.master.addons.add(state)
        async with tcp_server(server_handler) as addr:
            tctx.configure(ps, listen_host="127.0.0.1", listen_port=0)
            assert not ps.server
            ps.running()
            await tctx.master.await_log("Proxy server listening", level="info")
            assert ps.server

            proxy_addr = ps.server.sockets[0].getsockname()[:2]
            reader, writer = await asyncio.open_connection(*proxy_addr)
            req = f"GET http://{addr[0]}:{addr[1]}/hello HTTP/1.1\r\n\r\n"
            writer.write(req.encode())
            assert await reader.readuntil(
                b"\r\n\r\n") == b"HTTP/1.1 204 No Content\r\n\r\n"
            assert repr(ps) == "ProxyServer(running, 1 active conns)"

            tctx.configure(ps, server=False)
            await tctx.master.await_log("Stopping server", level="info")
            assert not ps.server
            assert state.flows
            assert state.flows[0].request.path == "/hello"
            assert state.flows[0].response.status_code == 204

            # Waiting here until everything is really torn down... takes some effort.
            conn_handler = list(ps._connections.values())[0]
            client_handler = conn_handler.transports[
                conn_handler.client].handler
            writer.close()
            await writer.wait_closed()
            try:
                await client_handler
            except asyncio.CancelledError:
                pass
            for _ in range(5):
                # Get all other scheduled coroutines to run.
                await asyncio.sleep(0)
            assert repr(ps) == "ProxyServer(stopped, 0 active conns)"
예제 #5
0

@pytest.mark.asyncio
async def test_inject():
    async def server_handler(reader: asyncio.StreamReader,
                             writer: asyncio.StreamWriter):
        while s := await reader.read(1):
            writer.write(s.upper())

    ps = Proxyserver()
    with taddons.context(ps) as tctx:
        state = HelperAddon()
        tctx.master.addons.add(state)
        async with tcp_server(server_handler) as addr:
            tctx.configure(ps, listen_host="127.0.0.1", listen_port=0)
            ps.running()
            await tctx.master.await_log("Proxy server listening", level="info")
            proxy_addr = ps.server.sockets[0].getsockname()[:2]
            reader, writer = await asyncio.open_connection(*proxy_addr)

            req = f"CONNECT {addr[0]}:{addr[1]} HTTP/1.1\r\n\r\n"
            writer.write(req.encode())
            assert await reader.readuntil(
                b"\r\n\r\n") == b"HTTP/1.1 200 Connection established\r\n\r\n"

            writer.write(b"a")
            assert await reader.read(1) == b"A"
            ps.inject_tcp(state.flows[0], False, "b")
            assert await reader.read(1) == b"B"
            ps.inject_tcp(state.flows[0], True, "c")
            assert await reader.read(1) == b"c"