Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable gzip compression for static Rack sites on Heroku Cedar?

Following the Creating Static Sites in Ruby with Rack article, I get a static site on Heroku with a config.ru that looks like this:

use Rack::Static,
  :urls => ["/images", "/js", "/css"],
  :root => "public"

run lambda { |env|
  [
    200, 
    {
      'Content-Type'  => 'text/html', 
      'Cache-Control' => 'public, max-age=86400' 
    },
    File.open('public/index.html', File::RDONLY)
  ]
}

When I run YSlow over the result, it reported none of the files were gzipped. What do I do to compress both the assets and the public/index.html?

like image 664
awendt Avatar asked Dec 27 '22 08:12

awendt


1 Answers

From my previous experience with Sprockets, Sinatra, and the Rack::Deflater, I was pretty sure I was just another use Rack::Deflater line away from what I wanted.

I changed the config.ru to this:

use Rack::Static,
  :urls => ["/images", "/js", "/css"],
  :root => "public"
use Rack::Deflater

run lambda # ...same as in the question

and I was able to verify that responses were sent gzipped:

$ curl -H 'Accept-Encoding: gzip' http://localhost:9292 | file -
/dev/stdin: gzip compressed data

but not for static assets under /css, /js, or /images:

$ curl -H 'Accept-Encoding: gzip' http://localhost:9292/css/bootstrap.min.css | file -
/dev/stdin: ASCII English text, with very long lines

And that's when I realized this was a standard middleware stack—Rack::Static intercepts the call to static files and thus skips the following stack! That's why it worked for public/index.html but not for assets.

The following config.ru worked (note that use Rack::Deflater now precedes use Rack::Static):

use Rack::Deflater
use Rack::Static, 
  :urls => ["/images", "/js", "/css"],
  :root => "public"

run lambda { |env|
  [
    200, 
    {
      'Content-Type'  => 'text/html', 
      'Cache-Control' => 'public, max-age=86400' 
    },
    File.open('public/index.html', File::RDONLY)
  ]
}

Verified with:

$ curl -H 'Accept-Encoding: gzip' http://localhost:9292/css/bootstrap.min.css | file -
/dev/stdin: gzip compressed data, from Unix
like image 143
awendt Avatar answered Jan 05 '23 16:01

awendt