1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

The asset_host block takes the controller request as an optional second argument. Example: use a single asset host for SSL requests. Closes #10549.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8578 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jeremy Kemper 2008-01-06 20:53:23 +00:00
parent ca4c7ab362
commit a1b0349362
5 changed files with 78 additions and 7 deletions

View file

@ -1,5 +1,7 @@
*SVN*
* The asset_host block takes the controller request as an optional second argument. Example: use a single asset host for SSL requests. #10549 [Cheah Chu Yeow, Peter B, Tom Taylor]
* Support render :text => nil. #6684 [tjennings, PotatoSalad, Cheah Chu Yeow]
* assert_response failures include the exception message. #10688 [Seth Rasmussen]

View file

@ -3,7 +3,7 @@ require 'action_controller/session/cookie_store'
module ActionController #:nodoc:
class Base
# Process a request extracted from an CGI object and return a response. Pass false as <tt>session_options</tt> to disable
# Process a request extracted from a CGI object and return a response. Pass false as <tt>session_options</tt> to disable
# sessions (large performance increase if sessions are not needed). The <tt>session_options</tt> are the same as for CGI::Session:
#
# * <tt>:database_manager</tt> - standard options are CGI::Session::FileStore, CGI::Session::MemoryStore, and CGI::Session::PStore
@ -17,7 +17,7 @@ module ActionController #:nodoc:
# an ArgumentError is raised.
# * <tt>:session_expires</tt> - the time the current session expires, as a +Time+ object. If not set, the session will continue
# indefinitely.
# * <tt>:session_domain</tt> - the hostname domain for which this session is valid. If not set, defaults to the hostname of the
# * <tt>:session_domain</tt> - the hostname domain for which this session is valid. If not set, defaults to the hostname of the
# server.
# * <tt>:session_secure</tt> - if +true+, this session will only work over HTTPS.
# * <tt>:session_path</tt> - the path for which this session applies. Defaults to the directory of the CGI script.
@ -34,7 +34,8 @@ module ActionController #:nodoc:
class CgiRequest < AbstractRequest #:nodoc:
attr_accessor :cgi, :session_options
class SessionFixationAttempt < StandardError; end #:nodoc:
class SessionFixationAttempt < StandardError #:nodoc:
end
DEFAULT_SESSION_OPTIONS = {
:database_manager => CGI::Session::CookieStore, # store data in cookie

View file

@ -50,8 +50,10 @@ module ActionView
# stylesheet_include_tag("application")
# => <link href="http://assets1.example.com/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
#
# The proc takes a single <tt>source</tt> parameter which is the path of the source asset. This can be used to
# generate a particular asset host depending on the asset path.
# The proc takes a <tt>source</tt> parameter (which is the path of the source asset) and an optional
# <tt>request</tt> parameter (which is an entire instance of an <tt>ActionController::AbstractRequest</tt>
# subclass). This can be used to generate a particular asset host depending on the asset path and the particular
# request.
#
# ActionController::Base.asset_host = Proc.new { |source|
# if source.starts_with?('/images')
@ -65,6 +67,19 @@ module ActionView
# stylesheet_include_tag("application")
# => <link href="http://assets.example.com/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
#
# The optional <tt>request</tt> parameter to the proc is useful in particular for serving assets from an
# SSL-protected page. The example proc below disables asset hosting for HTTPS connections, while still sending
# assets for plain HTTP requests from asset hosts. This is useful for avoiding mixed media warnings when serving
# non-HTTP assets from HTTPS web pages when you don't have an SSL certificate for each of the asset hosts.
#
# ActionController::Base.asset_host = Proc.new { |source, request|
# if request.ssl?
# "#{request.protocol}#{request.host_with_port}"
# else
# "#{request.protocol}assets.example.com"
# end
# }
#
# === Using asset timestamps
#
# By default, Rails will append all asset paths with that asset's timestamp. This allows you to set a cache-expiration date for the
@ -461,7 +476,12 @@ module ActionView
def compute_asset_host(source)
if host = ActionController::Base.asset_host
if host.is_a?(Proc)
host.call(source)
case host.arity
when 2:
host.call(source, @controller.request)
else
host.call(source)
end
else
host % (source.hash % 4)
end

View file

@ -4,6 +4,15 @@ class ERB
module Util
HTML_ESCAPE = { '&' => '&amp;', '"' => '&quot;', '>' => '&gt;', '<' => '&lt;' }
# A utility method for escaping HTML tag characters.
# This method is also aliased as <tt>h</tt>.
#
# In your ERb templates, use this method to escape any unsafe content. For example:
# <%=h @person.name %>
#
# ==== Example:
# puts html_escape("is a > 0 & a < 10?")
# # => is a &gt; 0 &amp; a &lt; 10?
def html_escape(s)
s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
end

View file

@ -34,6 +34,8 @@ class AssetTagHelperTest < Test::Unit::TestCase
@request = Class.new do
def relative_url_root() "" end
def protocol() 'http://' end
def ssl?() false end
def host_with_port() 'localhost' end
end.new
@controller.request = @request
@ -248,7 +250,7 @@ class AssetTagHelperTest < Test::Unit::TestCase
end
def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host
ENV["RAILS_ASSET_ID"] = ""
ENV['RAILS_ASSET_ID'] = ''
ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" }
ActionController::Base.perform_caching = true
@ -264,6 +266,43 @@ class AssetTagHelperTest < Test::Unit::TestCase
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'scripts.js'))
end
def test_caching_javascript_include_tag_when_caching_on_with_2_argument_proc_asset_host
ENV['RAILS_ASSET_ID'] = ''
ActionController::Base.asset_host = Proc.new { |source, request|
if request.ssl?
"#{request.protocol}#{request.host_with_port}"
else
"#{request.protocol}assets#{source.length}.example.com"
end
}
ActionController::Base.perform_caching = true
assert_equal '/javascripts/vanilla.js'.length, 23
assert_dom_equal(
%(<script src="http://assets23.example.com/javascripts/vanilla.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => 'vanilla')
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js'))
class << @controller.request
def protocol() 'https://' end
def ssl?() true end
end
assert_equal '/javascripts/secure.js'.length, 22
assert_dom_equal(
%(<script src="https://localhost/javascripts/secure.js" type="text/javascript"></script>),
javascript_include_tag(:all, :cache => 'secure')
)
assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js'))
ensure
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'vanilla.js'))
FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'secure.js'))
end
def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory
ENV["RAILS_ASSET_ID"] = ""
ActionController::Base.asset_host = 'http://a%d.example.com'