| Class | Rack::Deflater |
| In: |
lib/rack/deflater.rb
|
| Parent: | Object |
| 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 |
Loosely based on Mongrel‘s Deflate handler
# 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
# 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
# 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