diff options
author | José Valim <jose.valim@gmail.com> | 2010-07-18 20:00:59 +0200 |
---|---|---|
committer | raggi <jftucker@gmail.com> | 2010-07-19 20:08:29 +0100 |
commit | e344d3256f4e4b59677dcd0401b4bd4816416ae7 (patch) | |
tree | 14c56e99607b4576d3308cf508ee7b99acab932d /lib/rack/conditionalget.rb | |
parent | c73b474525bace3f059a130b15413abd4d917086 (diff) | |
download | rack-e344d3256f4e4b59677dcd0401b4bd4816416ae7.tar.gz |
Make ConditionalGet middleware respect HTTP specification.
The specification says if both IF_NONE_MATCH and IF_MODIFIED_SINCE are sent, both should match in order to return 304. Signed-off-by: raggi <jftucker@gmail.com>
Diffstat (limited to 'lib/rack/conditionalget.rb')
-rw-r--r-- | lib/rack/conditionalget.rb | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/lib/rack/conditionalget.rb b/lib/rack/conditionalget.rb index 046ebdb0..bc6c856b 100644 --- a/lib/rack/conditionalget.rb +++ b/lib/rack/conditionalget.rb @@ -24,7 +24,7 @@ module Rack status, headers, body = @app.call(env) headers = Utils::HeaderHash.new(headers) - if etag_matches?(env, headers) || modified_since?(env, headers) + if fresh?(env, headers) status = 304 headers.delete('Content-Type') headers.delete('Content-Length') @@ -34,14 +34,30 @@ module Rack end private - def etag_matches?(env, headers) - etag = headers['Etag'] and etag == env['HTTP_IF_NONE_MATCH'] + + def fresh?(env, headers) + modified_since = env['HTTP_IF_MODIFIED_SINCE'] + none_match = env['HTTP_IF_NONE_MATCH'] + + return false unless modified_since || none_match + + success = true + success &&= modified_since?(to_rfc2822(modified_since), headers) if modified_since + success &&= etag_matches?(none_match, headers) if none_match + success end - def modified_since?(env, headers) - last_modified = headers['Last-Modified'] and - last_modified == env['HTTP_IF_MODIFIED_SINCE'] + def etag_matches?(none_match, headers) + etag = headers['Etag'] and etag == none_match end - end + def modified_since?(modified_since, headers) + last_modified = to_rfc2822(headers['Last-Modified']) and + modified_since >= last_modified + end + + def to_rfc2822(since) + Time.rfc2822(since) rescue nil + end + end end |