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