Esempio n. 1
0
async def test_dummy_setup_roundtrip_resource(aiohttp_client):
    """Test a dummy configuration with a message round-trip."""
    app = web.Application()
    _setup(app)

    app.router.add_resource("/").add_route("GET", handler)

    client = await aiohttp_client(app)

    resp = await client.get('/')
    assert resp.status == 200
    data = await resp.text()

    assert data == TEST_BODY
Esempio n. 2
0
async def test_static_route(aiohttp_client):
    """Test a static route with CORS."""
    app = web.Application()
    cors = _setup(app, defaults={
        "*": ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_methods="*",
            allow_headers=("Content-Type", "X-Header"),
        )
    })

    test_static_path = pathlib.Path(__file__).parent
    cors.add(app.router.add_static("/static", test_static_path,
                                   name='static'))

    client = await aiohttp_client(app)

    resp = await client.options(
        "/static/test_page.html",
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "OPTIONS",
            hdrs.ACCESS_CONTROL_REQUEST_HEADERS: "content-type",
        }
    )
    data = await resp.text()
    assert resp.status == 200
    assert data == ''
Esempio n. 3
0
async def test_preflight_request_headers(aiohttp_client):
    """Test CORS preflight request handlers handling."""
    app = web.Application()
    cors = _setup(app, defaults={
        "*": ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers=("Content-Type", "X-Header"),
        )
    })

    resource = cors.add(app.router.add_resource("/"))
    cors.add(resource.add_route("PUT", handler))

    client = await aiohttp_client(app)

    resp = await client.options(
        '/',
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "PUT",
            hdrs.ACCESS_CONTROL_REQUEST_HEADERS: "content-type",
        }
    )
    assert (await resp.text()) == ""
    assert resp.status == 200
    # Access-Control-Allow-Headers must be compared in case-insensitive
    # way.
    assert (
        resp.headers[hdrs.ACCESS_CONTROL_ALLOW_HEADERS].upper() ==
        "content-type".upper())

    resp = await client.options(
        '/',
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "PUT",
            hdrs.ACCESS_CONTROL_REQUEST_HEADERS: "X-Header,content-type",
        }
    )
    assert resp.status == 200
    # Access-Control-Allow-Headers must be compared in case-insensitive
    # way.
    assert (
        frozenset(resp.headers[hdrs.ACCESS_CONTROL_ALLOW_HEADERS]
                  .upper().split(",")) ==
        {"X-Header".upper(), "content-type".upper()})
    assert (await resp.text()) == ""

    resp = await client.options(
        '/',
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "PUT",
            hdrs.ACCESS_CONTROL_REQUEST_HEADERS: "content-type,Test",
        }
    )
    assert resp.status == 403
    assert hdrs.ACCESS_CONTROL_ALLOW_HEADERS not in resp.headers
    assert "headers are not allowed: TEST" in (await resp.text())
Esempio n. 4
0
async def test_preflight_request_max_age_resource(aiohttp_client):
    """Test CORS preflight handling on resource that is available through
    several routes.
    """
    app = web.Application()
    cors = _setup(app, defaults={
        "*": ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers="*",
            max_age=1200
        )
    })

    resource = cors.add(app.router.add_resource("/{name}"))
    cors.add(resource.add_route("GET", handler))

    client = await aiohttp_client(app)

    resp = await client.options(
        "/user",
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "GET"
        }
    )
    assert resp.status == 200
    assert resp.headers[hdrs.ACCESS_CONTROL_MAX_AGE].upper() == "1200"

    data = await resp.text()
    assert data == ""
Esempio n. 5
0
async def test_preflight_req_multiple_routes_with_one_options(aiohttp_client):
    """Test CORS preflight handling on resource that is available through
    several routes.
    """
    app = web.Application()
    cors = _setup(app, defaults={
        "*": ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers="*",
        )
    })

    cors.add(app.router.add_route("GET", "/{name}", handler))
    cors.add(app.router.add_route("PUT", "/{name}", handler))

    client = await aiohttp_client(app)

    resp = await client.options(
        "/user",
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "PUT"
        }
    )
    assert resp.status == 200

    data = await resp.text()
    assert data == ""
Esempio n. 6
0
    def inner(defaults, route_config):
        app = web.Application()
        cors = _setup(app, defaults=defaults)

        if request.param == 'resource':
            resource = cors.add(app.router.add_resource("/resource"))
            cors.add(resource.add_route("GET", handler), route_config)
        elif request.param == 'view':
            WebViewHandler.cors_config = route_config
            cors.add(app.router.add_route("*", "/resource", WebViewHandler))
        elif request.param == 'route':
            cors.add(app.router.add_route("GET", "/resource", handler),
                     route_config)
        else:
            raise RuntimeError('unknown parameter {}'.format(request.param))

        return app
Esempio n. 7
0
async def test_preflight_request_mult_routes_with_one_options_webview(
        aiohttp_client):
    """Test CORS preflight handling on resource that is available through
    several routes.
    """
    app = web.Application()
    cors = _setup(app, defaults={
        "*": ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers="*",
        )
    })

    class TestView(web.View, CorsViewMixin):
        async def get(self):
            resp = web.Response(text=TEST_BODY)

            resp.headers[SERVER_CUSTOM_HEADER_NAME] = \
                SERVER_CUSTOM_HEADER_VALUE

            return resp

        put = get

    cors.add(app.router.add_route("*", "/{name}", TestView))

    client = await aiohttp_client(app)

    resp = await client.options(
        "/user",
        headers={
            hdrs.ORIGIN: "http://example.org",
            hdrs.ACCESS_CONTROL_REQUEST_METHOD: "PUT"
        }
    )
    assert resp.status == 200

    data = await resp.text()
    assert data == ""
Esempio n. 8
0
async def test_dummy_setup(aiohttp_server):
    """Test a dummy configuration."""
    app = web.Application()
    _setup(app)

    await aiohttp_server(app)
    async def start_servers(self):
        test_page_path = pathlib.Path(__file__).with_name("test_page.html")

        async def handle_test_page(request: web.Request) -> web.StreamResponse:
            with test_page_path.open("r", encoding="utf-8") as f:
                return web.Response(text=f.read(),
                                    headers={hdrs.CONTENT_TYPE: "text/html"})

        async def handle_no_cors(request: web.Request) -> web.StreamResponse:
            return web.Response(
                text="""{"type": "no_cors.json"}""",
                headers={hdrs.CONTENT_TYPE: "application/json"})

        async def handle_resource(request: web.Request) -> web.StreamResponse:
            return web.Response(
                text="""{"type": "resource"}""",
                headers={hdrs.CONTENT_TYPE: "application/json"})

        async def handle_servers_addresses(
                request: web.Request) -> web.StreamResponse:
            servers_addresses = \
                {name: descr.url for name, descr in self.servers.items()}
            return web.Response(text=json.dumps(servers_addresses))

        class ResourceView(web.View, CorsViewMixin):
            async def get(self) -> web.StreamResponse:
                return await handle_resource(self.request)

        # For most resources:
        # "origin" server has no CORS configuration.
        # "allowing" server explicitly allows CORS requests to "origin" server.
        # "denying" server explicitly disallows CORS requests to "origin"
        # server.
        # "free_for_all" server allows CORS requests for all origins server.
        # "no_cors" server has no CORS configuration.
        cors_server_names = ["allowing", "denying", "free_for_all"]
        server_names = cors_server_names + ["origin", "no_cors"]

        for server_name in server_names:
            assert server_name not in self.servers
            self.servers[server_name] = _ServerDescr()

        server_sockets = {}

        # Create applications and sockets.
        for server_name, server_descr in self.servers.items():
            server_descr.app = web.Application()

            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.bind(("127.0.0.1", 0))
            sock.listen(10)
            server_sockets[server_name] = sock

            hostaddr, port = sock.getsockname()
            server_descr.url = "http://{host}:{port}".format(host=hostaddr,
                                                             port=port)

        # Server test page from origin server.
        self.servers["origin"].app.router.add_route("GET", "/",
                                                    handle_test_page)
        self.servers["origin"].app.router.add_route("GET",
                                                    "/servers_addresses",
                                                    handle_servers_addresses)

        # Add routes to all servers.
        for server_name in server_names:
            app = self.servers[server_name].app
            app.router.add_route("GET", "/no_cors.json", handle_no_cors)
            if self.use_webview:
                app.router.add_route("*",
                                     "/cors_resource",
                                     ResourceView,
                                     name="cors_resource")
            else:
                app.router.add_route("GET",
                                     "/cors_resource",
                                     handle_resource,
                                     name="cors_resource")

        cors_default_configs = {
            "allowing": {
                self.servers["origin"].url:
                ResourceOptions(allow_credentials=True,
                                expose_headers="*",
                                allow_headers="*")
            },
            "denying": {
                # Allow requests to other than "origin" server.
                self.servers["allowing"].url:
                ResourceOptions(allow_credentials=True,
                                expose_headers="*",
                                allow_headers="*")
            },
            "free_for_all": {
                "*":
                ResourceOptions(allow_credentials=True,
                                expose_headers="*",
                                allow_headers="*")
            },
        }

        # Configure CORS.
        for server_name, server_descr in self.servers.items():
            default_config = cors_default_configs.get(server_name)
            if default_config is None:
                continue
            server_descr.cors = _setup(server_descr.app,
                                       defaults=default_config)

        # Add CORS routes.
        for server_name in cors_server_names:
            server_descr = self.servers[server_name]
            # TODO: Starting from aiohttp 0.21.0 name-based access returns
            # Resource, not Route. Manually get route while aiohttp_cors
            # doesn't support configuring for Resources.
            resource = server_descr.app.router["cors_resource"]
            route = next(iter(resource))
            if self.use_resources:
                server_descr.cors.add(resource)
                server_descr.cors.add(route)

            elif self.use_webview:
                server_descr.cors.add(route)

            else:
                server_descr.cors.add(route)

        # Start servers.
        for server_name, server_descr in self.servers.items():
            handler = server_descr.app.make_handler()
            server = await self.loop.create_server(
                handler, sock=server_sockets[server_name])
            server_descr.handler = handler
            server_descr.server = server

            self._logger.info("Started server '%s' at '%s'", server_name,
                              server_descr.url)