diff options
author | Dan Kubb <dan.kubb@autopilotmarketing.com> | 2008-12-20 13:36:22 -0800 |
---|---|---|
committer | Dan Kubb <dan.kubb@autopilotmarketing.com> | 2008-12-20 13:36:22 -0800 |
commit | e44d908849c226f3d86930423f51228a4e1c7395 (patch) | |
tree | 2d0dc43cbc3d56128a624146295b4bb014949dac | |
parent | c868880e376c79a61bc5884ee48061d7092d0a04 (diff) | |
download | rack-e44d908849c226f3d86930423f51228a4e1c7395.tar.gz |
Fixed Rack::Deflater to handle responses with Last-Modified header
* There was a bug when performing gzip compression where the Last-Modified response header was assumed to be a Time object, and passed directly to Zlib::GzipWriter#mtime, causing an exception since it is always a String. This fix parses the Last-Modified header using Time.httpdate and returns a Time obejct, which can be safely passed to Zlib::GzipWriter#mtime.
-rw-r--r-- | lib/rack/deflater.rb | 3 | ||||
-rw-r--r-- | test/spec_rack_deflater.rb | 17 |
2 files changed, 19 insertions, 1 deletions
diff --git a/lib/rack/deflater.rb b/lib/rack/deflater.rb index fa71bcac..e28dd082 100644 --- a/lib/rack/deflater.rb +++ b/lib/rack/deflater.rb @@ -1,5 +1,6 @@ require "zlib" require "stringio" +require "time" # for Time.httpdate module Rack @@ -28,7 +29,7 @@ class Deflater case encoding when "gzip" - mtime = headers["Last-Modified"] || Time.now + mtime = headers.key?("Last-Modified") ? Time.httpdate(headers["Last-Modified"]) : Time.now [status, headers.merge("Content-Encoding" => "gzip"), self.class.gzip(body, mtime)] when "deflate" [status, headers.merge("Content-Encoding" => "deflate"), self.class.deflate(body)] diff --git a/test/spec_rack_deflater.rb b/test/spec_rack_deflater.rb index f86d0a21..63546215 100644 --- a/test/spec_rack_deflater.rb +++ b/test/spec_rack_deflater.rb @@ -3,6 +3,7 @@ require 'test/spec' require 'rack/mock' require 'rack/deflater' require 'stringio' +require 'time' # for Time#httpdate context "Rack::Deflater" do def build_response(status, body, accept_encoding, headers = {}) @@ -75,4 +76,20 @@ context "Rack::Deflater" do response2[1].should.equal({"Content-Type" => "text/plain"}) response2[2].should.equal("An acceptable encoding for the requested resource /foo/bar could not be found.") end + + specify "should handle gzip response with Last-Modified header" do + last_modified = Time.now.httpdate + + app = lambda { |env| [200, { "Last-Modified" => last_modified }, "Hello World!"] } + request = Rack::MockRequest.env_for("", "HTTP_ACCEPT_ENCODING" => "gzip") + response = Rack::Deflater.new(app).call(request) + + response[0].should.equal(200) + response[1].should.equal({ "Content-Encoding" => "gzip", "Vary" => "Accept-Encoding", "Last-Modified" => last_modified }) + + io = StringIO.new(response[2].to_s) + gz = Zlib::GzipReader.new(io) + gz.read.should.equal("Hello World!") + gz.close + end end |