mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Ported fresh_when into a ConditionalGet module
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
module ActionController
|
||||
autoload :Base, "action_controller/new_base/base"
|
||||
autoload :ConditionalGet, "action_controller/new_base/conditional_get"
|
||||
autoload :HideActions, "action_controller/new_base/hide_actions"
|
||||
autoload :Http, "action_controller/new_base/http"
|
||||
autoload :Layouts, "action_controller/new_base/layouts"
|
||||
|
||||
@@ -10,6 +10,7 @@ module ActionController
|
||||
use ActionController::UrlFor
|
||||
use ActionController::Renderer
|
||||
use ActionController::Layouts
|
||||
use ActionController::ConditionalGet
|
||||
|
||||
# Legacy modules
|
||||
include SessionManagement
|
||||
|
||||
42
actionpack/lib/action_controller/new_base/conditional_get.rb
Normal file
42
actionpack/lib/action_controller/new_base/conditional_get.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
module ActionController
|
||||
module ConditionalGet
|
||||
|
||||
# Sets the etag, last_modified, or both on the response and renders a
|
||||
# "304 Not Modified" response if the request is already fresh.
|
||||
#
|
||||
# Parameters:
|
||||
# * <tt>:etag</tt>
|
||||
# * <tt>:last_modified</tt>
|
||||
# * <tt>:public</tt> By default the Cache-Control header is private, set this to true if you want your application to be cachable by other devices (proxy caches).
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# def show
|
||||
# @article = Article.find(params[:id])
|
||||
# fresh_when(:etag => @article, :last_modified => @article.created_at.utc, :public => true)
|
||||
# end
|
||||
#
|
||||
# This will render the show template if the request isn't sending a matching etag or
|
||||
# If-Modified-Since header and just a "304 Not Modified" response if there's a match.
|
||||
#
|
||||
def fresh_when(options)
|
||||
options.assert_valid_keys(:etag, :last_modified, :public)
|
||||
|
||||
response.etag = options[:etag] if options[:etag]
|
||||
response.last_modified = options[:last_modified] if options[:last_modified]
|
||||
|
||||
if options[:public]
|
||||
cache_control = response.headers["Cache-Control"].split(",").map {|k| k.strip }
|
||||
cache_control.delete("private")
|
||||
cache_control.delete("no-cache")
|
||||
cache_control << "public"
|
||||
response.headers["Cache-Control"] = cache_control.join(', ')
|
||||
end
|
||||
|
||||
if request.fresh?(response)
|
||||
head :not_modified
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -7,6 +7,7 @@ module ActionController
|
||||
@_response = response
|
||||
ret = process(request.parameters[:action])
|
||||
@_response.body = self.response_body
|
||||
@_response.prepare!
|
||||
set_test_assigns
|
||||
ret
|
||||
end
|
||||
|
||||
47
actionpack/test/new_base/etag_test.rb
Normal file
47
actionpack/test/new_base/etag_test.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
|
||||
|
||||
module Etags
|
||||
|
||||
class BasicController < ActionController::Base
|
||||
|
||||
self.view_paths = [ActionView::Template::FixturePath.new(
|
||||
"etags/basic/base.html.erb" => "Hello from without_layout.html.erb",
|
||||
"layouts/etags.html.erb" => "teh <%= yield %> tagz"
|
||||
)]
|
||||
|
||||
def without_layout
|
||||
render :action => "base"
|
||||
end
|
||||
|
||||
def with_layout
|
||||
render :action => "base", :layout => "etag"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class TestBasic < SimpleRouteCase
|
||||
describe "Rendering without any special etag options returns an etag that is an MD5 hash of its text"
|
||||
|
||||
test "an action without a layout" do
|
||||
get "/etags/basic/without_layout"
|
||||
body = "Hello from without_layout.html.erb"
|
||||
assert_body body
|
||||
assert_header "Etag", etag_for(body)
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
test "an action with a layout" do
|
||||
get "/etags/basic/with_layout"
|
||||
body = "teh Hello from without_layout.html.erb tagz"
|
||||
assert_body body
|
||||
assert_header "Etag", etag_for(body)
|
||||
assert_status 200
|
||||
end
|
||||
|
||||
def etag_for(text)
|
||||
%("#{Digest::MD5.hexdigest(text)}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user