Class Rack::Deflater
In: lib/rack/deflater.rb
Parent: Object

Methods

call   deflate   gzip   new  

Constants

DEFLATE_ARGS = [ Zlib::DEFAULT_COMPRESSION, # drop the zlib header which causes both Safari and IE to choke -Zlib::MAX_WBITS, Zlib::DEF_MEM_LEVEL, Zlib::DEFAULT_STRATEGY

Public Class methods

Loosely based on Mongrel‘s Deflate handler

[Source]

    # File lib/rack/deflater.rb, line 77
77:   def self.deflate(body)
78:     deflater = Zlib::Deflate.new(*DEFLATE_ARGS)
79: 
80:     # TODO: Add streaming
81:     body.each { |part| deflater << part }
82: 
83:     return deflater.finish
84:   end

[Source]

    # File lib/rack/deflater.rb, line 56
56:   def self.gzip(body, mtime)
57:     io = StringIO.new
58:     gzip = Zlib::GzipWriter.new(io)
59:     gzip.mtime = mtime
60: 
61:     # TODO: Add streaming
62:     body.each { |part| gzip << part }
63: 
64:     gzip.close
65:     return io.string
66:   end

[Source]

    # File lib/rack/deflater.rb, line 8
 8:   def initialize(app)
 9:     @app = app
10:   end

Public Instance methods

[Source]

    # File lib/rack/deflater.rb, line 12
12:   def call(env)
13:     status, headers, body = @app.call(env)
14:     headers = Utils::HeaderHash.new(headers)
15: 
16:     # Skip compressing empty entity body responses and responses with
17:     # no-transform set.
18:     if Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
19:         headers['Cache-Control'].to_s =~ /\bno-transform\b/
20:       return [status, headers, body]
21:     end
22: 
23:     request = Request.new(env)
24: 
25:     encoding = Utils.select_best_encoding(%w(gzip deflate identity),
26:                                           request.accept_encoding)
27: 
28:     # Set the Vary HTTP header.
29:     vary = headers["Vary"].to_s.split(",").map { |v| v.strip }
30:     unless vary.include?("*") || vary.include?("Accept-Encoding")
31:       headers["Vary"] = vary.push("Accept-Encoding").join(",")
32:     end
33: 
34:     case encoding
35:     when "gzip"
36:       mtime = if headers.key?("Last-Modified") 
37:                 Time.httpdate(headers["Last-Modified"]) 
38:               else 
39:                 Time.now
40:               end
41:       [status,
42:        headers.merge("Content-Encoding" => "gzip"),
43:        self.class.gzip(body, mtime)]
44:     when "deflate"
45:       [status,
46:        headers.merge("Content-Encoding" => "deflate"),
47:        self.class.deflate(body)]
48:     when "identity"
49:       [status, headers, body]
50:     when nil
51:       message = ["An acceptable encoding for the requested resource #{request.fullpath} could not be found."]
52:       [406, {"Content-Type" => "text/plain"}, message]
53:     end
54:   end

[Validate]