class HerokuDeflater::ServeZippedAssets

Public Class Methods

new(app, root, assets_path, cache_control_manager) click to toggle source
# File lib/heroku-deflater/serve_zipped_assets.rb, line 12
def initialize(app, root, assets_path, cache_control_manager)
  @app = app
  @assets_path = assets_path.chomp('/') + '/'
  if rails_version_5?
    @file_handler = ActionDispatch::FileHandler.new(root, headers: cache_control_manager.cache_control_headers)
  else
    @file_handler = ActionDispatch::FileHandler.new(root, cache_control_manager.cache_control_headers)
  end
end

Public Instance Methods

call(env) click to toggle source
# File lib/heroku-deflater/serve_zipped_assets.rb, line 22
def call(env)
  if env['REQUEST_METHOD'] == 'GET'
    request = Rack::Request.new(env)
    encoding = Rack::Utils.select_best_encoding(%w(gzip identity), request.accept_encoding)

    if encoding == 'gzip'
      # See if gzipped version exists in assets directory
      compressed_path = env['PATH_INFO'] + '.gz'

      if compressed_path.start_with?(@assets_path) && (match = @file_handler.match?(compressed_path))
        # Get the FileHandler to serve up the gzipped file, then strip the .gz suffix
        env['PATH_INFO'] = match
        status, headers, body = @file_handler.call(env)
        env['PATH_INFO'].chomp!('.gz')

        # Set the Vary HTTP header.
        vary = headers['Vary'].to_s.split(',').map(&:strip)

        unless vary.include?('*') || vary.include?('Accept-Encoding')
          headers['Vary'] = vary.push('Accept-Encoding').join(',')
        end

        # Add encoding and type
        headers['Content-Encoding'] = 'gzip'
        headers['Content-Type'] = Rack::Mime.mime_type(File.extname(env['PATH_INFO']), 'text/plain')

        body.close if body.respond_to?(:close)
        return [status, headers, body]
      end
    end
  end

  @app.call(env)
end

Private Instance Methods

rails_version_5?() click to toggle source
# File lib/heroku-deflater/serve_zipped_assets.rb, line 58
def rails_version_5?
  Rails::VERSION::MAJOR >= 5
end