All of a sudden two of the videos we’re hosting on AWS Amazon S3 started getting Cross-Origin Resource Sharing (CORS) errors, saying that there was no header.
Spent a bunch of time with the crossdomain.xml file, permissions of the files as well as the bucket cors configuration.
Found a site to test cors, but am not clear on what is happening. It doesn’t seem to like any of our video URLs, even the ones that are working.
This cURL request from SO:
curl -H "Origin: http://anysite.com" --verbose \
https://bucketID.cloudfront.net/inspiration_ecstasy/index.m3u8
Returns a lot of details, including * Connection #0 to host bucketID.cloudfront.net left intact
. Why is this working from any single domain, when the Cors configuration limits it so specific domains? Ah. Thank you SO:
If your request doesn’t specify an Origin header, S3 won’t include the CORS headers in the response. This really threw me because I kept trying to curl the files to test the CORS but curl doesn’t include Origin.
I need to dig a little deeper!
Success. This little SO answer found the problem.
For a more complex CORS request, the browser sends a “preflight” request, which needs to contain the “origin” and AWS/Cloudfront does not send this by default. So you need to go to your specific Cloudfront Distribution and edit it’s configuration settings.
I edited the Default Behavior and changed Forward Headers from None to Whitelist, then added the following three items to the whitelist:
Access-Control-Request-Headers
Access-Control-Request-Method
Origin
And the video played.
While troubleshooting, I had gone back and opened up the CORS settings to less restrictive:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
I now updated to restrict to our website and the various URLs for the hosted jwplayer instance(s) we utilize:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*.jwplayer.com</AllowedOrigin>
<AllowedOrigin>*.jwpcdn.com</AllowedOrigin>
<AllowedOrigin>*.jwplatform.com</AllowedOrigin>
<AllowedOrigin>*.oursite.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
(Which you can do by making a local file and uploading it from the command line with s3cmd :s3cmd setcors cors.json s3://bucket/directory
.)
This is done for the S3 bucket itself, and specifically the directory within the bucket that you want to configure the CORS rules for.
In the end, for this scenario, the only item that needed to be added to the forwarding whitelist for the CloudFront distribution point was the origin
, so I removed Access-Control-Request-Headers
and Access-Control-Request-Method
.
I then added one line to the CORSRule for testing: <AllowedOrigin>*.test-cors.org</AllowedOrigin>
and now test-cors.org likes the URI.