L
Welcome to my blog. I write about lots of topics, but I mostly keep it to technical and personal things.

Serving Fonts off AWS Cloudfront

Feb. 15th 2012 18:06:10

This will be brisk, but I intend to cover all of the caveats involved in distributing webfonts via AWS's CloudFront CDN.

As browser support for @font-face CSS directives has improved to the point where they are now well supported, browsers have also been converging on a single font format to support. In addition to that, although there were lots of headaches, a solid syntax for webfonts has also been developed. Unfortunately, to maximize the number of users who see your fonts, you will need at least 3, probably 4, different font formats:

  • woff for IE9+, FF, Chrome (technically, eot+ttf cover these browsers)
  • ttf/otf for Safari & Opera
  • svg for older iOS & Android devices
  • eot for IE8 and older

There are solid services for webfonts, but if you want to serve your own off CloudFront, there's a big problem. FireFox and IE9+ implement HTTP access control, designed to restrict the type of content which can be successfully hotlinked off of other sites. From the foundry point of view, they don't want to sell access to a webfont to one site and have it show up everywhere else for free; from a customers point of view, they don't want to pay for delivery of licensed content to other domains.

The way to authorize cross-domain font access is via the HTTP Header Access-Control-Allow-Origin, which can be set to a domain or to * to match all domains. The big snag for serving webfonts off of CloudFront is that S3 and CloudFront do not support this header. A request was made to AWS in June 2009, and nearly 3 years later no action's been taken.

This blog post wouldn't exist if there wasn't a way around this, though. CloudFront, while integrating quite nicely with S3, can also be used to front a regular HTTP resource, called a "Custom Origin" in CloudFront's help literature. When you hit your CloudFront URL, it will proxy that request to the Origin you give it, and then cache it to be served locally until it times out (which you also have control over via Expires headers).

This means you can start up a t1.micro EC2 instance with a simple HTTP server serving your font files and CSS, and front that with CloudFront rather than an S3 bucket. A simple nginx config like this would work:

server {
    listen 80;
    access_log /var/log/nginx/static.log
    autoindex on;

    location / {
        root /var/www/static/;
        add_header Access-Control-Allow-Origin example.com;
    }
}

After this is set up, create a CloudFront distribution with the DNS name of your EC2 t1.micro, wait for it to become "Deployed", and hit a font endpoint that you have set up on your EC2 box. CloudFront will be faithful to the headers you've set; once you are starting to get cache hits on CloudFront, you can inspect the headers and see something like:

HTTP/1.0 200 OK
Server: nginx/0.7.65
Date: Wed, 15 Feb 2012 22:14:45 GMT
Content-Type: font/woff
Content-Length: 281981
Last-Modified: Wed, 15 Feb 2012 21:56:25 GMT
Access-Control-Allow-Origin: example.com
Accept-Ranges: bytes
Age: 2570
X-Cache: Hit from cloudfront

With the ACAO header, new bulletproof CSS syntax, and font formats described above, your fonts will serve from the AWS CDN and work in nearly every browser that supports webfonts including old versions of IE and mobile devices!

Linux Mint 12: Oneiric Revisited

Jan. 8th 2012 21:30:55

After my disastrous experience with Oneiric left me with an ugly and half-working xfce/compiz amalgam, I promised myself that when the next version of Linux Mint shipped with the erstwhile Gnome2 fork "Mate", I'd give it a go.

It shipped, and while it changed some things that I didn't need changing (like un-unifying the gtk3 application menus), the Gnome3 experience was still unfortunately pretty terrible. The Mint folks warn that MATE is still a beta quality experience (much unlike Ubuntu, who foist their broken shit upon the masses and expect congratulations for it), and that was unfortunately a bit of an understatement.

Mint's modified Gnome3 was a decent effort, but the most annoying things about Gnome3 were the muscle-memory workflow-destroying unconfigurable changes: auto-workspace-management, completely dominating the super-key breaking any other apps that might use it, lack of true HUD support, a clock/calendar app that ditched the world-clock which I actually came to rely upon to deal with coworkers in other continents, alt-tab switching apps and changing my workspace, and broken multi-monitor support when using multi-desktops.

What did Mint fix? Well, it got rid of the shared menu, it installed some necessary things like gnome-tweak-tool by default (and gave it the unscary name of "advanced settings"), and it made everything pretty attractive by default, and enabled icons on the desktop by default. This, given the previous paragraph just wasn't enough. So I started my search on the internet once more; I knew people were living with Gnome3, but how?

Gnome3, because of it puts its eggs all in a single mod-key-bound basket, requires graphics hardware acceleration to function properly. If that's not available, it runs in a fallback mode. Some clever people discovered that the Gnome3 fallback mode is better than Gnome3 itself, tweakable under Linux Mint to give an experience almost identical to Gnome2; specifically, you get two panels, with an applications and places menu, many of the same applets from Gnome2 (perhaps this is a 3.2 or a Mint addition because earlier adopters complained the applets were all gone), a functional world-clock calendar with weather, a functional heads up system monitor, proper window and virtual desktop management, and (what I wanted in the first place) python2.7!

The very last thing I got working was mousewheel desktop workspace switching; under CCSM -> Viewport Switcher -> Desktop-based Viewport Switching, I had Button4/5 bound to "Move Left" and "Move Right", which didn't function, but swapping them out for "Move Next" and "Move Prev" got it working like a charm.

Doubts remain about how much love this fallback mode will continue to receive from Gnome as they continue to work on their terrible full version. Hopefully the distributions can step in and start to fix the remaining niggles (the unattractively large top-panel chief among them), and perhaps some will start to ship a tweaked fallback mode by default.

Err 01 on Canon 500d w/ Tamron 17-50mm lens

Dec. 29th 2011 04:55:01

On a short jaunt in Okinawa last week, I was perplexed/upset/disappointed to see that my trusty Tamron 17-50mm F2.8 lens had apparently crapped out, giving an internet-famous "Err 01: Communication between the camera and lens is faulty."

I've been using this lens for a few years now, but since I had a perfectly nice Canon 28-135mm USM (gosh is USM nice) lens with me, I just decided to use that and skip on the wider shots for the rest of my trip. Today however, I had a small bit of time to investigate.

At first, I tried cleaning the contacts on the lens and then the contacts in the camera. But they were pretty spotless already, and polishing them didn't do a whole lot. I searched around on the internet a bit, and found a tip from a telescope user who said that unseating the lens might worked. I had nothing better to do, so I held the lens release button, turned the lens slightly until "F00" showed up on the screen (meaning that comms had been lost) and snapped a photo.

It didn't error! I snapped the lens back into place, auto-focused, then unseated again and snapped, and it worked still. Bravely, I snapped the lens back into its full seated position and took a photo without argument. Finally, I completely removed the lens, then re-attached, and it worked!

I don't know exactly what was going on here. Perhaps there was some kind of software comms issue that got reset when the camera snapped the photo with the lens unseated. Perhaps I did permanent damage to my camera by using it in this way. Perhaps there is no scientific explanation for why this worked, but my lens seems to be functioning quite readily again.

Now that my service to the internet has been completed, I'm off to tst to see if I can't snap some photos!

Education and Entitlement

Dec. 15th 2011 15:56:11

A friend of mine recently left a life in an industry he never wanted to be in to become a teacher. It wasn't the university professorship he was hoping for when he put in the long yards to get his PhD, but it was a position teaching CS at a prestigious escalator school in a wealthy area.

Python serialization

Nov. 1st 2011 23:56:24

Python has lots of built-in serialization methods. It has had a standard module called pickle for a very long time, and exposes its built-in trusted data marshaling routines in the marshal module. Since the release of Python 2.6 in October, 2008 it has also had a standard, well-tested json library.

Oneiric First Impressions

Oct. 14th 2011 03:15:49

Shit. Utter unusable shit.

Steve Jobs

Oct. 6th 2011 19:39:58

Buggs Bunny promised me a future that never materialized; a future with flying cars and rocket boots and Illudium Pu-36 explosive space modulators. As 2000 approached, it became clear that the world I thought I'd live in as a child would never come to pass.

What is Node.js for?

Oct. 3rd 2011 14:07:18

Ted Dzubia, an internet-notorious opinionated windbag and adept comedic writer, recently wrote a scathing post about Node.js, which was half in reply to a somewhat bizarre rant by its author Ryan Dahl on the state of software and a desire to retreat to the simplicity and stability of the Unix Philosophy.

Darkening a color

Sept. 11th 2011 22:11:14

I recently wrote a small patch for gvim to display text shadows for all text. The idea was there are lots of interesting dark background color themes that suffer from decreased color contrast by not being on a black background, so adding a text shadow would make it look better. I grabbed a very naive and fast "color darkening" algorithm from a StackOverflow response:

FP Militancy

Sept. 10th 2011 13:35:48

I really like the idea of Lambda the Ultimate, a blog/community/forum of people interested in and in many cases actively pushing the boundaries of programming languages. But there's this caustic edge to the people there that is pretty shocking.