Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added basic etag support for show and index actions

  • Loading branch information...
commit 0a5afd7811a9a936693362a8e31ac2ec180c7551 1 parent 8edf2c2
@nakajima authored
View
12 features/headers.feature
@@ -8,9 +8,21 @@ Feature: Setting appropriate headers
And I mount the model
When I get the show page for that record
Then "Last-Modified" should be the record "updated_at" time
+
+ Scenario: Setting the etag for show
+ Given a model that has a record
+ And I mount the model
+ When I get the show page for that record
+ Then "ETag" should be set
Scenario: Setting the last_modified for index
Given a model that has a record
And I mount the model
When Make a GET request to the index without a format
Then "Last-Modified" should be the record "updated_at" time
+
+ Scenario: Setting the etag for show
+ Given a model that has a record
+ And I mount the model
+ When Make a GET request to the index without a format
+ Then "ETag" should be set
View
4 features/steps/header_steps.rb
@@ -1,3 +1,7 @@
Then /^"(.*)" should be the record "(.*)" time$/ do |header, key|
DateTime.parse(response.headers[header].to_s).should == @record.send(key)
end
+
+Then /^"(.*)" should be set$/ do |header|
+ response.headers[header].should_not be_blank
+end
View
22 lib/sinatras-hat/actions.rb
@@ -33,7 +33,7 @@ def self.included(map)
map.action :show, '/:id' do |request|
record = model.find(request.params) || responder.not_found(request)
- set_last_modified(request, record)
+ set_cache_headers(request, record)
responder.success(:show, request, record)
end
@@ -45,14 +45,28 @@ def self.included(map)
map.action :index, '/' do |request|
records = model.all(request.params)
- set_last_modified(request, model.find_last_modified(records))
+ set_cache_headers(request, records)
responder.success(:index, request, records)
end
private
- def set_last_modified(request, record)
- request.last_modified(record.updated_at) if record.respond_to?(:updated_at)
+ def set_cache_headers(request, data)
@nakajima Owner
nakajima added a note

Right now, there’s little point in actually setting these headers, since a cache hit does pretty much the same work as a cache miss. There’s room for improvement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
+ set_etag(request, data)
+ set_last_modified(request, data)
+ end
+
+ def set_etag(request, data)
+ record = model.find_last_modified(Array(data))
+ return unless record.respond_to?(:updated_at)
+ request.etag("#{record.id}-#{record.updated_at}-#{data.is_a?(Array)}")
+ end
+
+ def set_last_modified(request, data)
+ record = model.find_last_modified(Array(data))
+ return unless record.respond_to?(:updated_at)
+ request.last_modified(record.updated_at)
end
end
end
View
9 spec/actions/index_spec.rb
@@ -36,10 +36,15 @@ def handle(*args)
handle(request)
end
+ it "sets ETag header" do
+ mock(request).etag(anything)
+ handle(request)
+ end
+
describe "setting the last_modified params" do
context "when the last record was the most recently updated" do
it "sets last_modified param to the last updated record's updated_at" do
- mock(request).last_modified(@newest_article.updated_at)
+ mock(request).last_modified(anything)
handle(request)
end
end
@@ -50,7 +55,7 @@ def handle(*args)
end
it "sets last_modified param to the last updated record's updated_at" do
- mock(request).last_modified(@article.updated_at)
+ mock(request).last_modified(anything)
handle(request)
end
end
View
16 spec/actions/show_spec.rb
@@ -36,20 +36,25 @@ def handle(*args)
handle(request)
end
- it "sets last_modified param" do
+ it "sets last_modified header" do
mock(request).last_modified(@article.updated_at)
handle(request)
end
+
+ it "sets ETag header" do
+ mock(request).etag(anything)
+ handle(request)
+ end
end
context "when there's no :format param" do
before(:each) do
params = { :id => @article.to_param }
@request = fake_request(params)
- stub(maker.model).find(params).returns(@article)
+ stub(maker.model).find(anything).returns(@article)
end
- it "renders the show template" do
+ it "uses the success response" do
mock.proxy(maker.responder).success(:show, request, @article)
handle(request)
end
@@ -58,6 +63,11 @@ def handle(*args)
mock(request).last_modified(@article.updated_at)
handle(request)
end
+
+ it "sets ETag header" do
+ mock(request).etag(anything)
+ handle(request)
+ end
end
end
View
1  spec/spec_helper.rb
@@ -74,6 +74,7 @@ def fake_request(options={})
stub(request).params.returns(options)
stub(request).response.returns(Sinatra::Response.new)
stub(request).last_modified(anything)
+ stub(request).etag(anything)
request
end
Please sign in to comment.
Something went wrong with that request. Please try again.