HTML5 is booming and plugin based media distribution is diminishing. This however brings a number of new challenges like granting HTML5 players access to the actual media content. This can be complex as web browsers come with strict security restrictions on which content can and can't be loaded. One way to allow content to be accessed on other pages, is using Cross Origin Resource Sharing.
What is Cross Origin Resource Sharing (CORS)?
Making resources available across origins is one of the painful problems on the internet today. However, recent evolutions shouldn't make it so hard. A first question however, is why this is so difficult.
The reason of this, is the Same-Origin Policy, allowing browsers to only load resources which are originating from the same origin, roughly the same (sub)domain. The same-origin policy was called to life in order to prevent malicious websites from accessing content on other websites using the users credentials and log-in information. However, there are some kinds of resources you want to make available for other origins also, for example an API made available on a subdomain, or content located on a CDN. In order to do this, multiple techniques were developed like JSONP, a technique which is suited for API-calls when, for example, JSON data needs to be passed. An other popular technique is setting up a reverse proxy, hosted on the same origin, which can be used to make the data available without the need for contacting a different origin. While these methods provide workarounds, they are not a clean solution and either modify the content or require you to retransmit it.
The clean solution called CORS
As a solution for this, the Cross Origin Resource Sharing, or CORS, standard was contrived.
Cross Origin Resource Sharing allows to signal which information can be retrieved by different origins, and makes use of HTTP-headers. The method is actually similar to the crossdomain.xml-files which are used to signal cross domain access in the Flash plugin-environment and which lists which domains can access content. You might remember adding crossdomain.xml-files to your streaming servers, for example:
<allow-access-from domain="*.theoplayer.com" />
Most popular HTML5 platforms these days provide support for Cross Origin Resource Sharing, with support on all popular browsers on both desktop and mobile and modern devices such as Chromecast and smart TVs. The modern HTML5 players such as the THEOplayer HLS and DASH player and the dash.js reference player require CORS to be enabled on content when streaming from a different origin.
How does Cross Origin Resource Sharing work?
There are many different levels of CORS configurations. In it's most basic form, it suffices to return an Access-Control-Allow-Origin response header whenever an Origin request header is received. By setting the value of this header to the value of the Origin header, the browser will be signalled it is safe to use the content. For example, a browser might perform the following request:
GET /video/sintel/index.m3u8 HTTP/1.1
Accept-Encoding:gzip, deflate, sdch
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
In order to signal the browser it is allowed to use the response of this request, the server could return the following response headers:
HTTP/1.1 200 OK
Date:Tue, 13 Oct 2015 20:01:46 GMT
Last-Modified:Thu, 30 Jul 2015 13:07:39 GMT
Via:1.1 289241c3af05a479dc26e3b6a8f02210.cloudfront.net (CloudFront)
X-Cache:Hit from cloudfront
In this response, note the Access-Control-Allow-* headers.
- "Access-Control-Allow-Methods:GET" shows GET-requests are allowed and can be used to allow other methods such as POST or PUT.
- "Access-Control-Allow-Origin:https://www.theoplayer.com" provides access to the https://www.theoplayer.com origin. Alternatively a wildcard "*" can be used to allow all origins.
- "Access-Control-Max-Age:3000" indicates the browser should re-check the CORS authorisation in 3000 seconds.
In the case the browser is performing other than a simple cross-origin request, the Cross Origin Resource Sharing specification specifies a preflight OPTIONS request in order to retrieve which actions the browser is allowed to perform. Using the preflight request, it is possible to allow other HTTP methods, expose custom headers and can allow credentials to be shared. The following response headers are also defined in the CORS specification and are usually sent in answer to a preflight request:
- "Access-Control-Allow-Credentials" can be used to allow credentials, such as cookies, to be sent with the CORS request.
- "Access-Control-Allow-Headers" signals the browser which headers it can send to the server when sending the actual cross origin request.
Enabling basic CORS support can be as easy as adding a single header "Access-Control-Allow-Origin:*". Below this article, we have added a listing of how CORS can be enabled on popular media servers and CDNs. This list is a growing work in progress and will be updated over time when new information becomes available. A reference of how you can enable CORS on standard web servers, can be found on the enable-cors website.
Cross Origin Resource Sharing and media players
When playing media with modern HTML5 based video players, such as THEOplayer HLS player, or using a Chromecast device, CORS is a requirement when streaming video from a different origin. As content is usually streamed from a different origin, leveraging the benefits like scalability of content delivery networks, publishers will more frequently need CORS to be enabled on their streaming servers during their move away plugins such as Flash and Silverlight towards cross platform HTML5 players.
In most cases, players will only perform simple cross-origin requests and it suffices to add the "Access-Control-Allow-Origin:*"-header. In other cases, for example when cookies need to be sent to the content server, a more advanced configuration is required, returning also a "Access-Control-Allow-Credentials:true"-header. Chromecast for example has an even more strict requirement and requires a list of additional headers to be exposed, such as the "Content-Type", "Accept-Encoding", and "Range" headers.
Below this article, we will be building a listing of often used CDNs and media servers on how CORS can be enabled. In case you have more information on how CORS can be enabled on an unlisted CDN or server, or in case you have a more detailed guide on how Cross Origin Resource Sharing can be enabled on a server or CDN which is listed, please contact us so we can build a more complete guide for internet users.
Cross Origin Resource Sharing on (streaming) servers
Adobe Media Server
Adobe Media Server is an Apache based server. CORS can be enabled by updating or adding the .htaccess file:
Header set Access-Control-Allow-Origin *
Apache based servers
Apache based servers allow you to enable CORS by adding the following line to the appropriate configuration, or by adding the following line to an .htaccess file.
Header set Access-Control-Allow-Origin "*"
In order to allow CORS to be enabled, you will require mod_headers to be enabled. In case this module is not enabled, you can enable it by running:
Wowza Media Server
Wowza Media Server allows you to set headers on HLS streams by updating the appropriate Application.xml (there can be multiple different files for live streams and on demand streams) and setting the cupertinoUserHTTPHeaders property:
Cross Origin Resource Sharing for standard web servers
The enable-cors website provides a detailed list of how CORS can be enabled on web servers such as nginx, IIS and Tomcat.
Cross Origin Resource Sharing on CDNs
CORS has been verified to be available on following list of CDNs. While most CDNs will also forward CORS headers which are served by the origin server, some CDNs also allow to inject Cross Origin Resource Sharing headers.
In order to inject CORS headers on Akamai, you can use the following approach:
- Create a new version from the existing active production version of the property management configuration
- Click on Add Rule
- Select the Rule template "Protection"
- Select CORS headers
- Click "Insert Rule"
- Configure the Access-Control-Allow-Origin-header and any other headers as required
Alternatively, you can contact the Akamai support, who can enable it for you.
For Microsoft Azure, CORS can be enabled by adding CORS rules to the service properties of a service. An example of a Cross Origin Resource Sharing configuration would be:
Cloudfront will forward CORS headers served by the origin. In case you are using an Amazon S3 origin, you can activate CORS by:
- Open the S3 web console and navigate to the appropriate bucket
- Open the "Properties" panel
- Click the "Permissions" heading
- Click the "Edit CORS Configuration" button
- Add CORS rules as required, for example:
<?xml version="1.0" encoding="UTF-8"?>
CORS headers can be injected on Edgecast using the Rule-engine.
KeyCDN forwards Cross Origin Resource Sharing headers which are served from the origin server, but can also inject CORS headers for you. In the KeyCDN control panel, you can enable CORS in the drop-down menu.
Other CDNs on which CORS has been verified to work are:
- Level 3