Currently the included Rack::Deflater will fail (and surely other
modules can fail too) if gzip encoding is used and some other conditions
are met. Like the ConditionalGet plugin is run first.
The appropriate code in Deflater:
mtime = headers.key?("Last-Modified") ?
Time.httpdate(headers("Last-Modified"]) : Time.now
Time.httpdate(nil) will cause an Exception. Based on the above code,
that shouldn't happen, but it does.
Turned out that in the ConditionalGet.modified_since function
headers['Last-Modified'] is read and that causes the error.
The real problem lies in HeaderHash.[]:
super(@names[k] ||= @names[k.downcase])
In the above situation where @names is a Hash, @names[k] (and
@names[k.downcase]) will return nil first and then a Hash entry will be
created in @names and set to nil. The above code will work fine
whatsoever, but afterwards HeaderHash.include? will erroneously report
that header key as present.
The attached patch fixes this issue. Note, you can still set a http
header to nil after the patch (the []= isn't involved).
Simple way to reproduce the error:
headers = Utils::HeaderHash.new(headers)
headers['wont-be-there']
puts "error" if headers.include?('wont-be-there')
--
Alex Beregszaszi
Any comments on this?
--
Alex Beregszaszi
Applied and pushed to master in f6f3c60.
Thanks,
Ryan