diff options
author | Yehuda Katz <wycats@gmail.com> | 2009-08-14 22:32:40 -0700 |
---|---|---|
committer | Yehuda Katz <wycats@gmail.com> | 2009-08-15 12:32:02 -0700 |
commit | 1310231c15742bf7d99e2f143d88b383c32782d3 (patch) | |
tree | 7f32ae8257410a19e1b9d4b189cc65803879c8e3 /actionpack/lib | |
parent | 9b552fb300c4606fe517eadaa30708e9d75498a6 (diff) | |
download | rails-1310231c15742bf7d99e2f143d88b383c32782d3.tar.gz rails-1310231c15742bf7d99e2f143d88b383c32782d3.tar.bz2 rails-1310231c15742bf7d99e2f143d88b383c32782d3.zip |
Got tests to pass with some more changes.
* request.formats is much simpler now
* For XHRs or Accept headers with a single item, we use the Accept header
* For other requests, we use params[:format] or fallback to HTML
* This is primarily to work around the fact that browsers provide completely
broken Accept headers, so we have to whitelist the few cases we can
specifically isolate and treat other requests as coming from the browser
* For APIs, we can support single-item Accept headers, which disambiguates
from the browsers
* Requests to an action that only has an XML template from the browser will
no longer find the template. This worked previously because most browsers
provide a catch-all */*, but this was mostly accidental behavior. If you
want to serve XML, either use the :xml format in links, or explicitly
specify the XML template: render "template.xml".
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_controller/metal/rendering_controller.rb | 22 | ||||
-rw-r--r-- | actionpack/lib/action_controller/testing/process.rb | 2 | ||||
-rwxr-xr-x | actionpack/lib/action_dispatch/http/request.rb | 36 | ||||
-rw-r--r-- | actionpack/lib/action_view/base.rb | 13 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/prototype_helper.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/resolver.rb | 2 |
6 files changed, 44 insertions, 36 deletions
diff --git a/actionpack/lib/action_controller/metal/rendering_controller.rb b/actionpack/lib/action_controller/metal/rendering_controller.rb index 46a69b6b57..4da32ca1b3 100644 --- a/actionpack/lib/action_controller/metal/rendering_controller.rb +++ b/actionpack/lib/action_controller/metal/rendering_controller.rb @@ -8,12 +8,17 @@ module ActionController attr_accessor :hash def initialize(klass, formats, locale) + @formats, @locale = formats, locale @hash = [formats, locale].hash end alias_method :eql?, :equal? + + def inspect + "#<HashKey -- formats: #{@formats} locale: #{@locale}>" + end end - + module RenderingController extend ActiveSupport::Concern @@ -25,7 +30,7 @@ module ActionController template_cache.clear super end - + def template_cache @template_cache ||= Hash.new {|h,k| h[k] = {} } end @@ -33,16 +38,19 @@ module ActionController def process_action(*) self.formats = request.formats.map {|x| x.to_sym} - Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale) + + super + end + + def _determine_template(*) super end def render(options) + Thread.current[:format_locale_key] = HashKey.get(self.class, formats, I18n.locale) + super - self.content_type ||= begin - mime = options[:_template].mime_type - formats.include?(mime && mime.to_sym) || formats.include?(:all) ? mime : Mime::Type.lookup_by_extension(formats.first) - end.to_s + self.content_type ||= options[:_template].mime_type.to_s response_body end diff --git a/actionpack/lib/action_controller/testing/process.rb b/actionpack/lib/action_controller/testing/process.rb index 09b1a59254..6bc7d60d76 100644 --- a/actionpack/lib/action_controller/testing/process.rb +++ b/actionpack/lib/action_controller/testing/process.rb @@ -148,7 +148,7 @@ module ActionController #:nodoc: def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil) @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' - @request.env['HTTP_ACCEPT'] = [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ') + @request.env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ') returning __send__(request_method, action, parameters, session, flash) do @request.env.delete 'HTTP_X_REQUESTED_WITH' @request.env.delete 'HTTP_ACCEPT' diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index b23306af62..bff030f0e4 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -106,16 +106,10 @@ module ActionDispatch @env["action_dispatch.request.accepts"] ||= begin header = @env['HTTP_ACCEPT'].to_s.strip - fallback = xhr? ? Mime::JS : Mime::HTML - if header.empty? - [content_type, fallback, Mime::ALL].compact + [content_type] else - ret = Mime::Type.parse(header) - if ret.last == Mime::ALL - ret.insert(-2, fallback) - end - ret + Mime::Type.parse(header) end end end @@ -163,26 +157,20 @@ module ActionDispatch # GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first depending on the value of <tt>ActionController::Base.use_accept_header</tt> # def format(view_path = []) - @env["action_dispatch.request.format"] ||= - if parameters[:format] - Mime[parameters[:format]] - elsif ActionController::Base.use_accept_header && !(accepts == ONLY_ALL) - accepts.first - elsif xhr? then Mime::JS - else Mime::HTML - end + formats.first end def formats - if ActionController::Base.use_accept_header - if param = parameters[:format] - Array.wrap(Mime[param]) + accept = @env['HTTP_ACCEPT'] + + @env["action_dispatch.request.formats"] ||= + if parameters[:format] + [Mime[parameters[:format]]] + elsif xhr? || (accept && !accept.include?(?,)) + accepts else - accepts.dup + [Mime::HTML] end - else - [format] - end end # Sets the \format by string extension, which can be used to force custom formats @@ -198,7 +186,7 @@ module ActionDispatch # end def format=(extension) parameters[:format] = extension.to_s - @env["action_dispatch.request.format"] = Mime::Type.lookup_by_extension(parameters[:format]) + @env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])] end # Returns a symbolized version of the <tt>:format</tt> parameter of the request. diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index edfd1fd71c..ec1b07797b 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -175,6 +175,17 @@ module ActionView #:nodoc: attr_accessor :controller attr_internal :captures + def reset_formats(formats) + @formats = formats + + if defined?(ActionController) + # This is expensive, but we need to reset this when the format is updated, + # which currently only happens + Thread.current[:format_locale_key] = + ActionController::HashKey.get(self.class, formats, I18n.locale) + end + end + class << self delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true @@ -240,7 +251,7 @@ module ActionView #:nodoc: end def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: - @formats = formats || [:html] + @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @controller = controller @helpers = self.class.helpers || Module.new diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 624b537ad2..03f1dabb4e 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -991,12 +991,13 @@ module ActionView def render(*options_for_render) old_formats = @context && @context.formats - @context.formats = [:html] if @context + + @context.reset_formats([:html]) if @context Hash === options_for_render.first ? @context.render(*options_for_render) : options_for_render.first.to_s ensure - @context.formats = old_formats if @context + @context.reset_formats(old_formats) if @context end def javascript_object_for(object) diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 10f664736f..fe657166d5 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -42,7 +42,7 @@ module ActionView def handler_glob @handler_glob ||= begin - e = TemplateHandlers.extensions.map{|h| ".#{h},"}.join + e = TemplateHandlers.extensions.map{|h| ".#{h}"}.join(",") "{#{e}}" end end |