changes the date comparison in last_modified

last_modified was halting only when the 'If-Modified-Since' header date
was equal to the time specified. Now, it halts when is equal or later
than the time specified.

Signed-off-by: Konstantin Haase <konstantin.mailinglists@googlemail.com>
This commit is contained in:
Gabriel Andretta 2010-10-06 22:54:29 -03:00 committed by Konstantin Haase
parent e7862ac4bf
commit 4c9add8265
2 changed files with 69 additions and 19 deletions

View File

@ -246,16 +246,19 @@ module Sinatra
# and halt if conditional GET matches. The +time+ argument is a Time,
# DateTime, or other object that responds to +to_time+.
#
# When the current request includes an 'If-Modified-Since' header that
# matches the time specified, execution is immediately halted with a
# '304 Not Modified' response.
# When the current request includes an 'If-Modified-Since' header that is
# equal or later than the time specified, execution is immediately halted
# with a '304 Not Modified' response.
def last_modified(time)
return unless time
time = time.to_time if time.respond_to?(:to_time)
time = Time.parse time.strftime('%FT%T%:z') if time.respond_to?(:strftime)
time = time.httpdate if time.respond_to?(:httpdate)
response['Last-Modified'] = time.to_s
halt 304 if time == request.env['HTTP_IF_MODIFIED_SINCE']
begin
halt 304 if time <= Time.httpdate(request.env['HTTP_IF_MODIFIED_SINCE']).httpdate
rescue ArgumentError
end
time
end

View File

@ -472,34 +472,81 @@ class HelpersTest < Test::Unit::TestCase
[Time, DateTime].each do |klass|
describe "with #{klass.name}" do
setup do
now = klass.now
last_modified_time = klass.now
mock_app do
get '/' do
body { 'Hello World' }
last_modified now
last_modified last_modified_time
'Boo!'
end
end
@now = Time.parse now.to_s
@last_modified_time = Time.parse last_modified_time.to_s
end
context "when there's no If-Modified-Since header" do
it 'sets the Last-Modified header to a valid RFC 2616 date value' do
get '/'
assert_equal @now.httpdate, response['Last-Modified']
assert_equal @last_modified_time.httpdate, response['Last-Modified']
end
it 'returns a body when conditional get misses' do
it 'conditional GET misses and returns a body' do
get '/'
assert_equal 200, status
assert_equal 'Boo!', body
end
end
it 'halts when a conditional GET matches' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => @now.httpdate }
context "when there's an invalid If-Modified-Since header" do
it 'sets the Last-Modified header to a valid RFC 2616 date value' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => 'a really weird date' }
assert_equal @last_modified_time.httpdate, response['Last-Modified']
end
it 'conditional GET misses and returns a body' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => 'a really weird date' }
assert_equal 200, status
assert_equal 'Boo!', body
end
end
context "when the resource has been modified since the If-Modified-Since header date" do
it 'sets the Last-Modified header to a valid RFC 2616 date value' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => (@last_modified_time - 1).httpdate }
assert_equal @last_modified_time.httpdate, response['Last-Modified']
end
it 'conditional GET misses and returns a body' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => (@last_modified_time - 1).httpdate }
assert_equal 200, status
assert_equal 'Boo!', body
end
end
context "when the resource has been modified on the exact If-Modified-Since header date" do
it 'sets the Last-Modified header to a valid RFC 2616 date value' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => @last_modified_time.httpdate }
assert_equal @last_modified_time.httpdate, response['Last-Modified']
end
it 'conditional GET matches and halts' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => @last_modified_time.httpdate }
assert_equal 304, status
assert_equal '', body
end
end
context "when the resource hasn't been modified since the If-Modified-Since header date" do
it 'sets the Last-Modified header to a valid RFC 2616 date value' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => (@last_modified_time + 1).httpdate }
assert_equal @last_modified_time.httpdate, response['Last-Modified']
end
it 'conditional GET matches and halts' do
get '/', {}, { 'HTTP_IF_MODIFIED_SINCE' => (@last_modified_time + 1).httpdate }
assert_equal 304, status
assert_equal '', body
end
end
end
end
end