core/homeassistant/components/http/cors.py

78 lines
1.8 KiB
Python
Raw Normal View History

2018-08-19 20:29:08 +00:00
"""Provide CORS support for the HTTP component."""
2019-07-25 11:52:27 +00:00
from aiohttp.web_urldispatcher import Resource, ResourceRoute, StaticResource
from aiohttp.hdrs import ACCEPT, CONTENT_TYPE, ORIGIN, AUTHORIZATION
2019-07-31 19:25:30 +00:00
from homeassistant.const import HTTP_HEADER_HA_AUTH, HTTP_HEADER_X_REQUESTED_WITH
from homeassistant.core import callback
# mypy: allow-untyped-defs, no-check-untyped-defs
ALLOWED_CORS_HEADERS = [
2019-07-31 19:25:30 +00:00
ORIGIN,
ACCEPT,
HTTP_HEADER_X_REQUESTED_WITH,
CONTENT_TYPE,
HTTP_HEADER_HA_AUTH,
AUTHORIZATION,
]
2019-07-25 11:52:27 +00:00
VALID_CORS_TYPES = (Resource, ResourceRoute, StaticResource)
@callback
def setup_cors(app, origins):
2018-08-19 20:29:08 +00:00
"""Set up CORS."""
import aiohttp_cors
2019-07-31 19:25:30 +00:00
cors = aiohttp_cors.setup(
app,
defaults={
host: aiohttp_cors.ResourceOptions(
allow_headers=ALLOWED_CORS_HEADERS, allow_methods="*"
)
for host in origins
},
)
cors_added = set()
def _allow_cors(route, config=None):
2018-08-19 20:29:08 +00:00
"""Allow CORS on a route."""
2019-07-31 19:25:30 +00:00
if hasattr(route, "resource"):
path = route.resource
else:
path = route
2019-06-03 18:43:13 +00:00
if not isinstance(path, VALID_CORS_TYPES):
return
path = path.canonical
if path.startswith("/api/hassio_ingress/"):
return
if path in cors_added:
return
cors.add(route, config)
cors_added.add(path)
2019-07-31 19:25:30 +00:00
app["allow_cors"] = lambda route: _allow_cors(
route,
{
"*": aiohttp_cors.ResourceOptions(
allow_headers=ALLOWED_CORS_HEADERS, allow_methods="*"
)
},
)
if not origins:
return
async def cors_startup(app):
2018-08-19 20:29:08 +00:00
"""Initialize CORS when app starts up."""
2019-07-25 11:52:27 +00:00
for resource in list(app.router.resources()):
_allow_cors(resource)
app.on_startup.append(cors_startup)