class Rack::GzipFile

Rack::File with gzip pre-compressed files support and extraction for a client whitch does not support gzip.

Constants

CONTENT_ENCODING
CONTENT_LENGTH
CONTENT_TYPE
DOT_GZ
GZIP
HTTP_ACCEPT_ENCODING
PATH_INFO
TEXT_PLAIN

Public Class Methods

new(*args) click to toggle source
# File lib/rack/gzip_file.rb, line 17
def initialize(*args)
  @file_server = Rack::File.new(*args)
  @default_mime = args[2] || TEXT_PLAIN
end

Public Instance Methods

call(env) click to toggle source
# File lib/rack/gzip_file.rb, line 22
def call(env)
  path = env[PATH_INFO]
  env[PATH_INFO] = path + DOT_GZ
  status, headers, body = result = @file_server.call(env)
  case status
  when 200  # OK
    mime = Rack::Mime.mime_type(::File.extname(path), @default_mime)
    headers[CONTENT_TYPE] = mime if mime
    enc = env[HTTP_ACCEPT_ENCODING]
    if enc && enc.include?(GZIP)
      headers[CONTENT_ENCODING] = GZIP
    else
      # inflate body for a client which does not support gzip
      body = [Zlib::GzipReader.open(body.to_path) {|f| f.read }]
      headers[CONTENT_LENGTH] = body[0].bytesize.to_s
      headers.delete CONTENT_ENCODING
    end
    [status, headers, body]
  when 304  # not modified
    result
  else      # retry with the original path
    env[PATH_INFO] = path
    @file_server.call(env)
  end
end