Flash movie (.swf) won't load in Rails 4

2014-07-24

I work on a Rails project that serves Flash .swf files out of Rails controllers, like this:

send_file swf_filename, disposition: 'inline'

I know that’s a crazy approach, but the reason is that these movies should only be seen by logged-in users. (Also I didn’t set it up like this. :-)

Recently some customers complained that Flash movies wouldn’t load. I was pulling my hair out figuring out why. I couldn’t reproduce it. The Rails and nginx logs showed no errors. Their browsers were retrieving the file, but then they would just display a blank white page, sometimes with a thin border where the movie should be.

Finally I was able to reproduce it on a different machine, and from there I eventually figured out it only happened for people running on the latest version of Flash. I installed the Flash debugger, I turned on tracing, but that didn’t detect any errors.

Another clue was that the problem wasn’t happening on another site that shares this codebase. By comparing browser requests between the sites, I was able to figure out the cause was an X-Content-Type-Options HTTP header with a nosniff value.

It turns out that Rails 4 adds this header by default, and although the working site was still on Rails 3, my predecessor had upgraded the problem site to 4. So one fix is to turn off that header like this:

response.headers.except! 'X-Content-Type-Options'

But a better fix would be to add a header that indicates the correct Content Type. We were serving the file as application/octet-stream, so with nosniff the browser couldn’t figure out how to handle the file. We needed to serve the .swf file as application/x-shockwave-flash instead:

response.headers['Content-Type'] = 'application/x-shockwave-flash'

Hopefully this will help someone else out there!

blog comments powered by Disqus Prev: Postgres CTE for Threaded Comments Next: Dates and Time Zones in Rails