aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_controller
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_controller')
-rw-r--r--actionpack/lib/action_controller/base.rb2
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb68
-rw-r--r--actionpack/lib/action_controller/caching/fragments.rb58
-rw-r--r--actionpack/lib/action_controller/caching/pages.rb20
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb3
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb4
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb22
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb38
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb47
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb10
-rw-r--r--actionpack/lib/action_controller/metal/responder.rb4
-rw-r--r--actionpack/lib/action_controller/metal/testing.rb9
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb4
-rw-r--r--actionpack/lib/action_controller/railtie.rb4
-rw-r--r--actionpack/lib/action_controller/railties/paths.rb12
-rw-r--r--actionpack/lib/action_controller/test_case.rb11
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb6
17 files changed, 179 insertions, 143 deletions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 48308cbb60..81c0698fb8 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -24,7 +24,7 @@ module ActionController
#
# Actions, by default, render a template in the <tt>app/views</tt> directory corresponding to the name of the controller and action
# after executing code in the action. For example, the +index+ action of the PostsController would render the
- # template <tt>app/views/posts/index.erb</tt> by default after populating the <tt>@posts</tt> instance variable.
+ # template <tt>app/views/posts/index.html.erb</tt> by default after populating the <tt>@posts</tt> instance variable.
#
# Unlike index, the create action will not render a template. After performing its main purpose (creating a
# new post), it initiates a redirect instead. This redirect works by returning an external
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index d69d96b974..a4bac3caed 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -4,25 +4,26 @@ module ActionController #:nodoc:
module Caching
# Action caching is similar to page caching by the fact that the entire
# output of the response is cached, but unlike page caching, every
- # request still goes through the Action Pack. The key benefit
- # of this is that filters are run before the cache is served, which
- # allows for authentication and other restrictions on whether someone
- # is allowed to see the cache. Example:
+ # request still goes through Action Pack. The key benefit of this is
+ # that filters run before the cache is served, which allows for
+ # authentication and other restrictions on whether someone is allowed
+ # to execute such action. Example:
#
# class ListsController < ApplicationController
# before_filter :authenticate, :except => :public
+ #
# caches_page :public
- # caches_action :index, :show, :feed
+ # caches_action :index, :show
# end
#
- # In this example, the public action doesn't require authentication,
- # so it's possible to use the faster page caching method. But both
- # the show and feed action are to be shielded behind the authenticate
- # filter, so we need to implement those as action caches.
+ # In this example, the +public+ action doesn't require authentication
+ # so it's possible to use the faster page caching. On the other hand
+ # +index+ and +show+ require authentication. They can still be cached,
+ # but we need action caching for them.
#
- # Action caching internally uses the fragment caching and an around
- # filter to do the job. The fragment cache is named according to both
- # the current host and the path. So a page that is accessed at
+ # Action caching uses fragment caching internally and an around
+ # filter to do the job. The fragment cache is named according to
+ # the host and path of the request. A page that is accessed at
# <tt>http://david.example.com/lists/show/1</tt> will result in a fragment named
# <tt>david.example.com/lists/show/1</tt>. This allows the cacher to
# differentiate between <tt>david.example.com/lists/</tt> and
@@ -38,19 +39,23 @@ module ActionController #:nodoc:
# <tt>:action => 'list', :format => :xml</tt>.
#
# You can set modify the default action cache path by passing a
- # :cache_path option. This will be passed directly to
- # ActionCachePath.path_for. This is handy for actions with multiple
- # possible routes that should be cached differently. If a block is
- # given, it is called with the current controller instance.
+ # <tt>:cache_path</tt> option. This will be passed directly to
+ # <tt>ActionCachePath.path_for</tt>. This is handy for actions with
+ # multiple possible routes that should be cached differently. If a
+ # block is given, it is called with the current controller instance.
+ #
+ # And you can also use <tt>:if</tt> (or <tt>:unless</tt>) to pass a
+ # proc that specifies when the action should be cached.
#
- # And you can also use :if (or :unless) to pass a Proc that
- # specifies when the action should be cached.
+ # Finally, if you are using memcached, you can also pass <tt>:expires_in</tt>.
#
- # Finally, if you are using memcached, you can also pass :expires_in.
+ # The following example depicts some of the points made above:
#
# class ListsController < ApplicationController
# before_filter :authenticate, :except => :public
- # caches_page :public
+ #
+ # caches_page :public
+ #
# caches_action :index, :if => proc do |c|
# !c.request.format.json? # cache if is not a JSON request
# end
@@ -58,19 +63,28 @@ module ActionController #:nodoc:
# caches_action :show, :cache_path => { :project => 1 },
# :expires_in => 1.hour
#
- # caches_action :feed, :cache_path => proc do |controller|
- # if controller.params[:user_id]
- # controller.send(:user_list_url,
- # controller.params[:user_id], controller.params[:id])
+ # caches_action :feed, :cache_path => proc do |c|
+ # if c.params[:user_id]
+ # c.send(:user_list_url,
+ # c.params[:user_id], c.params[:id])
# else
- # controller.send(:list_url, controller.params[:id])
+ # c.send(:list_url, c.params[:id])
# end
# end
# end
#
- # If you pass :layout => false, it will only cache your action
- # content. It is useful when your layout has dynamic information.
+ # If you pass <tt>:layout => false</tt>, it will only cache your action
+ # content. That's useful when your layout has dynamic information.
+ #
+ # Warning: If the format of the request is determined by the Accept HTTP
+ # header the Content-Type of the cached response could be wrong because
+ # no information about the MIME type is stored in the cache key. So, if
+ # you first ask for MIME type M in the Accept header, a cache entry is
+ # created, and then perform a second resquest to the same resource asking
+ # for a different MIME type, you'd get the content cached for M.
#
+ # The <tt>:format</tt> parameter is taken into account though. The safest
+ # way to cache by MIME type is to pass the format in the route.
module Actions
extend ActiveSupport::Concern
diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb
index 37c155b9cd..0be04b70a1 100644
--- a/actionpack/lib/action_controller/caching/fragments.rb
+++ b/actionpack/lib/action_controller/caching/fragments.rb
@@ -1,52 +1,72 @@
module ActionController #:nodoc:
module Caching
- # Fragment caching is used for caching various blocks within templates without caching the entire action as a whole. This is useful when
- # certain elements of an action change frequently or depend on complicated state while other parts rarely change or can be shared amongst multiple
- # parties. The caching is done using the cache helper available in the Action View. A template with caching might look something like:
+ # Fragment caching is used for caching various blocks within
+ # views without caching the entire action as a whole. This is
+ # useful when certain elements of an action change frequently or
+ # depend on complicated state while other parts rarely change or
+ # can be shared amongst multiple parties. The caching is done using
+ # the <tt>cache</tt> helper available in the Action View. A
+ # template with fragment caching might look like:
#
# <b>Hello <%= @name %></b>
+ #
# <% cache do %>
# All the topics in the system:
# <%= render :partial => "topic", :collection => Topic.find(:all) %>
# <% end %>
#
- # This cache will bind to the name of the action that called it, so if this code was part of the view for the topics/list action, you would
- # be able to invalidate it using <tt>expire_fragment(:controller => "topics", :action => "list")</tt>.
+ # This cache will bind the name of the action that called it, so if
+ # this code was part of the view for the topics/list action, you
+ # would be able to invalidate it using:
+ #
+ # expire_fragment(:controller => "topics", :action => "list")
#
- # This default behavior is of limited use if you need to cache multiple fragments per action or if the action itself is cached using
- # <tt>caches_action</tt>, so we also have the option to qualify the name of the cached fragment with something like:
+ # This default behavior is limited if you need to cache multiple
+ # fragments per action or if the action itself is cached using
+ # <tt>caches_action</tt>. To remedy this, there is an option to
+ # qualify the name of the cached fragment by using the
+ # <tt>:action_suffix</tt> option:
#
# <% cache(:action => "list", :action_suffix => "all_topics") do %>
#
- # That would result in a name such as <tt>/topics/list/all_topics</tt>, avoiding conflicts with the action cache and with any fragments that use a
- # different suffix. Note that the URL doesn't have to really exist or be callable - the url_for system is just used to generate unique
- # cache names that we can refer to when we need to expire the cache.
+ # That would result in a name such as
+ # <tt>/topics/list/all_topics</tt>, avoiding conflicts with the
+ # action cache and with any fragments that use a different suffix.
+ # Note that the URL doesn't have to really exist or be callable
+ # - the url_for system is just used to generate unique cache names
+ # that we can refer to when we need to expire the cache.
#
# The expiration call for this example is:
#
- # expire_fragment(:controller => "topics", :action => "list", :action_suffix => "all_topics")
+ # expire_fragment(:controller => "topics",
+ # :action => "list",
+ # :action_suffix => "all_topics")
module Fragments
- # Given a key (as described in <tt>expire_fragment</tt>), returns a key suitable for use in reading,
- # writing, or expiring a cached fragment. If the key is a hash, the generated key is the return
- # value of url_for on that hash (without the protocol). All keys are prefixed with <tt>views/</tt> and uses
+ # Given a key (as described in <tt>expire_fragment</tt>), returns
+ # a key suitable for use in reading, writing, or expiring a
+ # cached fragment. If the key is a hash, the generated key is the
+ # return value of url_for on that hash (without the protocol).
+ # All keys are prefixed with <tt>views/</tt> and uses
# ActiveSupport::Cache.expand_cache_key for the expansion.
def fragment_cache_key(key)
ActiveSupport::Cache.expand_cache_key(key.is_a?(Hash) ? url_for(key).split("://").last : key, :views)
end
- # Writes <tt>content</tt> to the location signified by <tt>key</tt> (see <tt>expire_fragment</tt> for acceptable formats)
+ # Writes <tt>content</tt> to the location signified by
+ # <tt>key</tt> (see <tt>expire_fragment</tt> for acceptable formats).
def write_fragment(key, content, options = nil)
return content unless cache_configured?
key = fragment_cache_key(key)
instrument_fragment_cache :write_fragment, key do
- content = content.html_safe.to_str if content.respond_to?(:html_safe)
+ content = content.to_str
cache_store.write(key, content, options)
end
content
end
- # Reads a cached fragment from the location signified by <tt>key</tt> (see <tt>expire_fragment</tt> for acceptable formats)
+ # Reads a cached fragment from the location signified by <tt>key</tt>
+ # (see <tt>expire_fragment</tt> for acceptable formats).
def read_fragment(key, options = nil)
return unless cache_configured?
@@ -57,7 +77,8 @@ module ActionController #:nodoc:
end
end
- # Check if a cached fragment from the location signified by <tt>key</tt> exists (see <tt>expire_fragment</tt> for acceptable formats)
+ # Check if a cached fragment from the location signified by
+ # <tt>key</tt> exists (see <tt>expire_fragment</tt> for acceptable formats)
def fragment_exist?(key, options = nil)
return unless cache_configured?
key = fragment_cache_key(key)
@@ -70,6 +91,7 @@ module ActionController #:nodoc:
# Removes fragments from the cache.
#
# +key+ can take one of three forms:
+ #
# * String - This would normally take the form of a path, like
# <tt>pages/45/notes</tt>.
# * Hash - Treated as an implicit call to +url_for+, like
diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb
index 104157d0b1..3e57d2c236 100644
--- a/actionpack/lib/action_controller/caching/pages.rb
+++ b/actionpack/lib/action_controller/caching/pages.rb
@@ -70,9 +70,9 @@ module ActionController #:nodoc:
# Manually cache the +content+ in the key determined by +path+. Example:
# cache_page "I'm the cached content", "/lists/show"
- def cache_page(content, path)
+ def cache_page(content, path, extension = nil)
return unless perform_caching
- path = page_cache_path(path)
+ path = page_cache_path(path, extension)
instrument_page_cache :write_page, path do
FileUtils.makedirs(File.dirname(path))
@@ -97,14 +97,16 @@ module ActionController #:nodoc:
end
private
- def page_cache_file(path)
+ def page_cache_file(path, extension)
name = (path.empty? || path == "/") ? "/index" : URI.parser.unescape(path.chomp('/'))
- name << page_cache_extension unless (name.split('/').last || name).include? '.'
+ unless (name.split('/').last || name).include? '.'
+ name << (extension || self.page_cache_extension)
+ end
return name
end
- def page_cache_path(path)
- page_cache_directory + page_cache_file(path)
+ def page_cache_path(path, extension = nil)
+ page_cache_directory + page_cache_file(path, extension)
end
def instrument_page_cache(name, path)
@@ -145,7 +147,11 @@ module ActionController #:nodoc:
request.path
end
- self.class.cache_page(content || response.body, path)
+ if (type = Mime::LOOKUP[self.content_type]) && (type_symbol = type.symbol).present?
+ extension = ".#{type_symbol}"
+ end
+
+ self.class.cache_page(content || response.body, path, extension)
end
end
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index d14831b763..91a88ab68a 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -53,8 +53,9 @@ module ActionController
include AbstractController::Helpers
included do
- config_accessor :helpers_path
+ config_accessor :helpers_path, :include_all_helpers
self.helpers_path ||= []
+ self.include_all_helpers = true
end
module ClassMethods
diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb
index 282dcf66b3..cfa7004048 100644
--- a/actionpack/lib/action_controller/metal/implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/implicit_render.rb
@@ -12,10 +12,10 @@ module ActionController
def method_for_action(action_name)
super || begin
- if template_exists?(action_name.to_s, _prefix)
+ if template_exists?(action_name.to_s, _prefixes)
"default_render"
end
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index c6d4c6d936..a2e06fe0a6 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -63,13 +63,13 @@ module ActionController #:nodoc:
# might look something like this:
#
# def index
- # @people = Person.find(:all)
+ # @people = Person.all
# end
#
# Here's the same action, with web-service support baked in:
#
# def index
- # @people = Person.find(:all)
+ # @people = Person.all
#
# respond_to do |format|
# format.html
@@ -155,7 +155,7 @@ module ActionController #:nodoc:
# Respond to also allows you to specify a common block for different formats by using any:
#
# def index
- # @people = Person.find(:all)
+ # @people = Person.all
#
# respond_to do |format|
# format.html
@@ -178,7 +178,7 @@ module ActionController #:nodoc:
# respond_to :html, :xml, :json
#
# def index
- # @people = Person.find(:all)
+ # @people = Person.all
# respond_with(@person)
# end
# end
@@ -208,8 +208,8 @@ module ActionController #:nodoc:
# It also accepts a block to be given. It's used to overwrite a default
# response:
#
- # def destroy
- # @user = User.find(params[:id])
+ # def create
+ # @user = User.new(params[:user])
# flash[:notice] = "User was successfully created." if @user.save
#
# respond_with(@user) do |format|
@@ -227,7 +227,7 @@ module ActionController #:nodoc:
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
if response = retrieve_response_from_mimes(&block)
- options = resources.extract_options!
+ options = resources.size == 1 ? {} : resources.extract_options!
options.merge!(:default_response => response)
(options.delete(:responder) || self.class.responder).call(self, resources, options)
end
@@ -258,9 +258,8 @@ module ActionController #:nodoc:
# nil if :not_acceptable was sent to the client.
#
def retrieve_response_from_mimes(mimes=nil, &block)
- collector = Collector.new { default_render }
mimes ||= collect_mimes_from_class_level
- mimes.each { |mime| collector.send(mime) }
+ collector = Collector.new(mimes) { default_render }
block.call(collector) if block_given?
if format = request.negotiate_mime(collector.order)
@@ -277,8 +276,9 @@ module ActionController #:nodoc:
include AbstractController::Collector
attr_accessor :order
- def initialize(&block)
+ def initialize(mimes, &block)
@order, @responses, @default_response = [], {}, block
+ mimes.each { |mime| send(mime) }
end
def any(*args, &block)
@@ -291,7 +291,7 @@ module ActionController #:nodoc:
alias :all :any
def custom(mime_type, &block)
- mime_type = mime_type.is_a?(Mime::Type) ? mime_type : Mime::Type.lookup(mime_type.to_s)
+ mime_type = Mime::Type.lookup(mime_type.to_s) unless mime_type.is_a?(Mime::Type)
@order << mime_type
@responses[mime_type] ||= block
end
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index f9b226b7c9..d6f6ab1855 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -15,30 +15,12 @@ module ActionController
end
module ClassMethods
- def _write_render_options
- renderers = _renderers.map do |name, value|
- <<-RUBY_EVAL
- if options.key?(:#{name})
- _process_options(options)
- return _render_option_#{name}(options.delete(:#{name}), options)
- end
- RUBY_EVAL
- end
-
- class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
- def _handle_render_options(options)
- #{renderers.join}
- end
- RUBY_EVAL
- end
-
def use_renderers(*args)
new = _renderers.dup
args.each do |key|
new[key] = RENDERERS[key]
end
self._renderers = new.freeze
- _write_render_options
end
alias use_renderer use_renderers
end
@@ -47,31 +29,33 @@ module ActionController
_handle_render_options(options) || super
end
+ def _handle_render_options(options)
+ _renderers.each do |name, value|
+ if options.key?(name.to_sym)
+ _process_options(options)
+ return send("_render_option_#{name}", options.delete(name.to_sym), options)
+ end
+ end
+ nil
+ end
+
RENDERERS = {}
def self.add(key, &block)
define_method("_render_option_#{key}", &block)
RENDERERS[key] = block
- All._write_render_options
end
module All
extend ActiveSupport::Concern
include Renderers
- INCLUDED = []
included do
self._renderers = RENDERERS
- _write_render_options
- INCLUDED << self
- end
-
- def self._write_render_options
- INCLUDED.each(&:_write_render_options)
end
end
add :json do |json, options|
- json = json.to_json(options) unless json.respond_to?(:to_str)
+ json = json.to_json(options) unless json.kind_of?(String)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = json
diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb
index e524e546ad..14cc547dd0 100644
--- a/actionpack/lib/action_controller/metal/rendering.rb
+++ b/actionpack/lib/action_controller/metal/rendering.rb
@@ -20,36 +20,35 @@ module ActionController
private
- # Normalize arguments by catching blocks and setting them on :update.
- def _normalize_args(action=nil, options={}, &blk) #:nodoc:
- options = super
- options[:update] = blk if block_given?
- options
- end
-
- # Normalize both text and status options.
- def _normalize_options(options) #:nodoc:
- if options.key?(:text) && options[:text].respond_to?(:to_text)
- options[:text] = options[:text].to_text
- end
+ # Normalize arguments by catching blocks and setting them on :update.
+ def _normalize_args(action=nil, options={}, &blk) #:nodoc:
+ options = super
+ options[:update] = blk if block_given?
+ options
+ end
- if options[:status]
- options[:status] = Rack::Utils.status_code(options[:status])
- end
+ # Normalize both text and status options.
+ def _normalize_options(options) #:nodoc:
+ if options.key?(:text) && options[:text].respond_to?(:to_text)
+ options[:text] = options[:text].to_text
+ end
- super
+ if options[:status]
+ options[:status] = Rack::Utils.status_code(options[:status])
end
- # Process controller specific options, as status, content-type and location.
- def _process_options(options) #:nodoc:
- status, content_type, location = options.values_at(:status, :content_type, :location)
+ super
+ end
- self.status = status if status
- self.content_type = content_type if content_type
- self.headers["Location"] = url_for(location) if location
+ # Process controller specific options, as status, content-type and location.
+ def _process_options(options) #:nodoc:
+ status, content_type, location = options.values_at(:status, :content_type, :location)
- super
- end
+ self.status = status if status
+ self.content_type = content_type if content_type
+ self.headers["Location"] = url_for(location) if location
+ super
+ end
end
end
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 02f577647e..148efbb081 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -53,9 +53,13 @@ module ActionController #:nodoc:
# class FooController < ApplicationController
# protect_from_forgery :except => :index
#
- # # you can disable csrf protection on controller-by-controller basis:
- # skip_before_filter :verify_authenticity_token
- # end
+ # You can disable csrf protection on controller-by-controller basis:
+ #
+ # skip_before_filter :verify_authenticity_token
+ #
+ # It can also be disabled for specific controller actions:
+ #
+ # skip_before_filter :verify_authenticity_token, :except => [:create]
#
# Valid Options:
#
diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb
index 38d32211cc..cffef29f83 100644
--- a/actionpack/lib/action_controller/metal/responder.rb
+++ b/actionpack/lib/action_controller/metal/responder.rb
@@ -115,7 +115,7 @@ module ActionController #:nodoc:
# Main entry point for responder responsible to dispatch to the proper format.
#
def respond
- method = :"to_#{format}"
+ method = "to_#{format}"
respond_to?(method) ? send(method) : to_format
end
@@ -171,7 +171,7 @@ module ActionController #:nodoc:
# Checks whether the resource responds to the current format or not.
#
def resourceful?
- resource.respond_to?(:"to_#{format}")
+ resource.respond_to?("to_#{format}")
end
# Returns the resource location by retrieving it from the options or
diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb
index 4b8c452d50..f4efeb33ba 100644
--- a/actionpack/lib/action_controller/metal/testing.rb
+++ b/actionpack/lib/action_controller/metal/testing.rb
@@ -14,18 +14,9 @@ module ActionController
cookies.write(@_response)
end
@_response.prepare!
- set_test_assigns
ret
end
- def set_test_assigns
- @assigns = {}
- (instance_variable_names - self.class.protected_instance_variables).each do |var|
- name, value = var[1..-1], instance_variable_get(var)
- @assigns[name] = value
- end
- end
-
# TODO : Rewrite tests using controller.headers= to use Rack env
def headers=(new_headers)
@_response ||= ActionDispatch::Response.new
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index 333eeaeffb..6fc0cf1fb8 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -6,7 +6,8 @@ module ActionController
def url_options
@_url_options ||= super.reverse_merge(
- :host => request.host_with_port,
+ :host => request.host,
+ :port => request.optional_port,
:protocol => request.protocol,
:_path_segments => request.symbolized_path_parameters
).freeze
@@ -20,5 +21,6 @@ module ActionController
@_url_options
end
end
+
end
end
diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb
index c5a661f2b0..f0c29825ba 100644
--- a/actionpack/lib/action_controller/railtie.rb
+++ b/actionpack/lib/action_controller/railtie.rb
@@ -27,8 +27,8 @@ module ActionController
options.page_cache_directory ||= paths["public"].first
# make sure readers methods get compiled
- options.asset_path ||= nil
- options.asset_host ||= nil
+ options.asset_path ||= app.config.asset_path
+ options.asset_host ||= app.config.asset_host
ActiveSupport.on_load(:action_controller) do
include app.routes.mounted_helpers
diff --git a/actionpack/lib/action_controller/railties/paths.rb b/actionpack/lib/action_controller/railties/paths.rb
index 7a59d4f2f3..dce3c2fe88 100644
--- a/actionpack/lib/action_controller/railties/paths.rb
+++ b/actionpack/lib/action_controller/railties/paths.rb
@@ -13,7 +13,17 @@ module ActionController
end
klass.helpers_path = paths
- klass.helper :all if klass.superclass == ActionController::Base
+ if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers
+ klass.helper :all
+ end
+
+ if app.config.serve_static_assets && namespace
+ paths = namespace._railtie.config.paths
+
+ klass.config.assets_dir = paths["public"].first
+ klass.config.javascripts_dir = paths["public/javascripts"].first
+ klass.config.stylesheets_dir = paths["public/stylesheets"].first
+ end
end
end
end
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 0c26071379..0f43527a56 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -1,6 +1,7 @@
require 'rack/session/abstract/id'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/object/to_query'
+require 'active_support/core_ext/class/attribute'
module ActionController
module TemplateAssertions
@@ -325,11 +326,11 @@ module ActionController
def controller_class=(new_class)
prepare_controller_class(new_class) if new_class
- write_inheritable_attribute(:controller_class, new_class)
+ self._controller_class = new_class
end
def controller_class
- if current_controller_class = read_inheritable_attribute(:controller_class)
+ if current_controller_class = self._controller_class
current_controller_class
else
self.controller_class = determine_default_controller_class(name)
@@ -411,8 +412,9 @@ module ActionController
@controller.request = @request
@controller.params.merge!(parameters)
build_request_uri(action, parameters)
- Base.class_eval { include Testing }
+ @controller.class.class_eval { include Testing }
@controller.process_with_new_base_test(@request, @response)
+ @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
@request.session.delete('flash') if @request.session['flash'].blank?
@response
end
@@ -441,6 +443,7 @@ module ActionController
included do
include ActionController::TemplateAssertions
include ActionDispatch::Assertions
+ class_attribute :_controller_class
setup :setup_controller_request_and_response
end
@@ -448,7 +451,7 @@ module ActionController
def build_request_uri(action, parameters)
unless @request.env["PATH_INFO"]
- options = @controller.__send__(:url_options).merge(parameters)
+ options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
options.update(
:only_path => true,
:action => action,
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
index dceddb9b80..09dd08898c 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -1,5 +1,5 @@
require 'set'
-require 'active_support/core_ext/class/inheritable_attributes'
+require 'active_support/core_ext/class/attribute'
module HTML
class Sanitizer
@@ -60,7 +60,7 @@ module HTML
class WhiteListSanitizer < Sanitizer
[:protocol_separator, :uri_attributes, :allowed_attributes, :allowed_tags, :allowed_protocols, :bad_tags,
:allowed_css_properties, :allowed_css_keywords, :shorthand_css_properties].each do |attr|
- class_inheritable_accessor attr, :instance_writer => false
+ class_attribute attr, :instance_writer => false
end
# A regular expression of the valid characters used to separate protocols like
@@ -170,7 +170,7 @@ module HTML
def contains_bad_protocols?(attr_name, value)
uri_attributes.include?(attr_name) &&
- (value =~ /(^[^\/:]*):|(&#0*58)|(&#x70)|(%|&#37;)3A/ && !allowed_protocols.include?(value.split(protocol_separator).first))
+ (value =~ /(^[^\/:]*):|(&#0*58)|(&#x70)|(%|&#37;)3A/ && !allowed_protocols.include?(value.split(protocol_separator).first.downcase))
end
end
end