last_modified response helper / conditional GET support

ResponseHelpers#last_modified sets the Last-Modified response header
and (potentially) halts execution if an If-Modified-Since request
header is present and matches the time given.
This commit is contained in:
Ryan Tomayko 2008-03-31 09:10:40 -04:00
parent ccc19b0436
commit 302a03cc37
2 changed files with 36 additions and 0 deletions

View File

@ -440,6 +440,25 @@ module Sinatra
response.header['Content-Type'] = type
end
# Set the last modified time of the resource (HTTP 'Last-Modified' header)
# 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.
#
# Calling this method before perfoming heavy processing (e.g., lengthy
# database queries, template rendering, complex logic) can dramatically
# increase overall throughput with caching clients.
def last_modified(time)
time = time.to_time if time.respond_to?(:to_time)
time = time.httpdate if time.respond_to?(:httpdate)
response.header['Last-Modified'] = time
throw :halt, 304 if time == request.env['HTTP_IF_MODIFIED_SINCE']
time
end
end
module RenderingHelpers

View File

@ -135,6 +135,23 @@ context "Sinatra" do
body.should.equal '<feed></feed>'
end
specify "supports conditional GETs with last_modified" do
modified_at = Time.now
get '/maybe' do
last_modified modified_at
'response body, maybe'
end
get_it '/maybe'
should.be.ok
body.should.equal 'response body, maybe'
get_it '/maybe', {},
'HTTP_IF_MODIFIED_SINCE' => modified_at.httpdate
status.should.equal 304
body.should.equal ''
end
specify "delegates HEAD requests to GET handlers" do
get '/invisible' do
"I am invisible to the world"