15

Fonts served via Cloudfront are broken in Firefox due to the "bad URI or cross-site access not allowed" issue. To fix this, I understand that I need to set the "Access-Control-Allow-Origin" header to a wildcard or the source domain.

The problem that I am having is that Cloudfront does not seem to be accepting headers from the origin.

For example, the following is the list of headers I get when I ping my server for the font:

curl -I -s "https://mysite.com/wp-content/themes/my-theme/includes/fonts/ProximaNova-Reg-webfont.ttf"
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 29 Jan 2014 16:03:03 GMT
Content-Type: application/x-font-ttf
Content-Length: 44992
Last-Modified: Tue, 28 Jan 2014 22:21:41 GMT
Connection: keep-alive
ETag: "52e82d75-afc0"
Expires: Thu, 29 Jan 2015 16:03:03 GMT
Cache-Control: max-age=31536000
Access-Control-Allow-Origin: https://mysite.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3600
Accept-Ranges: bytes

Everything looks good with this response; however, when I ping Cloudfront for the same resource, I get:

curl -I -s "https://ds6dj5kp03o39.cloudfront.net/wp-content/themes/my-theme/includes/fonts/ProximaNova-Reg-webfont.ttf"
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 44992
Connection: keep-alive
Date: Wed, 29 Jan 2014 16:22:30 GMT
Server: Apache/2.2.16 (Debian) mod_ssl/2.2.16 OpenSSL/0.9.8o
Last-Modified: Wed, 22 Jan 2014 02:44:45 GMT
ETag: "5d633-afc0-4f0861b87a140"
Accept-Ranges: bytes
Cache-Control: max-age=3600
Expires: Wed, 29 Jan 2014 17:22:30 GMT
X-Cache: Miss from cloudfront
Via: 1.1 850e11212c3f83bfb138469e9b3b7718.cloudfront.net (CloudFront)
X-Amz-Cf-Id: M4qkj9FwjdAUW91U4WeZzxEI0m7vOmiQvryS55WwoeU5Ks11IC71ig==

It seems that all of the origin headers are completely ignored. My question is, how do I get Cloudfront to accept my asset headers, especially the critical "Access-Control-Allow-Origin" header?

Thanks for the help!

Community
  • 1
  • 1
tollmanz
  • 3,113
  • 4
  • 29
  • 34
  • Hey, I still do not understand how the linked question does get answered by: set headers on your server. My thinking is, you have to set the headers on the server you are connecting to. Good that one cannot downvote comments, because I must be a total idiot here. – loveNoHate Jan 29 '14 at 16:35
  • Yeah...this might be my problem too ;) I think what is *supposed* to happen is that some of the headers that you set on your server are persisted by CloudFront. They will obviously override a number of them, but I thought they'd persist some of them. A lot of people have written articles about this method, but it does not work for me. Perhaps this assumption is just flat wrong. – tollmanz Jan 29 '14 at 17:34
  • Does that work: http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html ? – loveNoHate Jan 29 '14 at 22:26

4 Answers4

17

If you are coming to this at a later date, and have this issue with a custom origin that IS correctly serving the Access-Control-Allow-Origin header already, here's two things I checked / tried:

  1. Check if your nginx or apache config has the * in quotes, if it does, try removing them.
  2. Make sure you're passing the correct content types for woff and ttf files. This was the quickest link I found on the subject - https://github.com/fontello/fontello/wiki/How-to-setup-server-to-serve-fonts

Apache

To set right mime-types for font files, add this lines to config:

AddType application/vnd.ms-fontobject    .eot
AddType application/x-font-ttf           .ttf
AddType application/font-woff            .woff

If you can't edit config, create .htaccess file in folder with your project and add lines there.

For CORS headers add the code below:

<FilesMatch ".(eot|ttf|otf|woff)">
  Header set Access-Control-Allow-Origin "*"
</FilesMatch>

You will need to run service apache2 restart once you make these changes and if you receive the error Invalid command 'Header' then it means you haven't enabled the mod_header module in Apache which you can do with a2enmod headers

nginx

By default nginx has no default mime types for fonts, and wrong mimy type for .eot files. Got to folder with configs and find where mime types are defiled. Usually, that's in mimes.conf file.

Search .eot and string with it. Add strings below:

application/vnd.ms-fontobject    eot;
application/x-font-ttf           ttf;
application/font-woff            woff;

For CORS headers, add something like this to your vhost config

location ~* \.(eot|ttf|woff)$ {
    add_header Access-Control-Allow-Origin *;
}
jgraft
  • 918
  • 8
  • 15
streetlogics
  • 4,640
  • 33
  • 33
7

In its default configuration, CloudFront doesn't inspect headers or cache their values. A likely culprit for you is that your resource is first getting requested without an "Origin" header, and hence S3 is not serving up CORS headers in response. The response is cached and when you later make cross-origin request, the cached response is served up without them.

You can configure CloudFront to forward the Origin header to S3 and cache different responses for different header values, which will result in CloudFront caching the CORS headers when needed. See http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-cors.

Alex North
  • 1,189
  • 13
  • 12
6

What you did is right, but CloudFront caches the results, hence you're getting the old cached version. You can see this in the headers: from your site:

Last-Modified: Tue, 28 Jan 2014 22:21:41 GMT

from cloudfront:

Last-Modified: Wed, 22 Jan 2014 02:44:45 GMT

Now, how to get it working again:

a) wait for the object to expire, then request it again. CloudFront will update it then.

b) Invalidate the object(s) using your amazon aws console > cloudfront > distribution > Invalidations. See http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html for details on how to use this

c) change the name or start using a versioned name for the file, e.g. ProximaNova-Reg-webfont_2.ttf

  • 1
    I was going nuts on this. S3 had the Access-Control-Allow-Origin header set to * and through cloudfront request, that header wasn't set. After reading this I uploaded a new file and it had the header now set :) makes sense. thank you! – mwm Jan 23 '15 at 17:28
3

There is an explicit configuration for your buckets to evaluate CoRS headers dynamically.

  1. See the AWS CORS docs
  2. Also a detailed explanation of their use

Trying to set CORS headers or otherwise for CF or S3 will be discarded because it would break their caching model.

Joseph Lust
  • 19,340
  • 7
  • 85
  • 83