From 2f4aaed7b3feb3be787a316fab3144c06bb21a27 Mon Sep 17 00:00:00 2001 From: Michael Koziarski Date: Fri, 27 Jun 2008 11:29:04 +0300 Subject: Disable the Accept header by default The accept header is poorly implemented by browsers and causes strange errors when used on public sites where crawlers make requests too. You should use formatted urls (e.g. /people/1.xml) to support API clients. Alternatively to re-enable it you need to set: config.action_controller.use_accept_header = true A special case remains for ajax requests which will have a javascript format for the base resource (/people/1) if the X-Requested-With header is present. This lets ajax pages still use format.js despite there being no params[:format] --- actionpack/lib/action_controller/base.rb | 10 +++++++ .../lib/action_controller/caching/actions.rb | 5 +--- actionpack/lib/action_controller/mime_responds.rb | 6 +++- actionpack/lib/action_controller/request.rb | 34 ++++++++++++++++------ 4 files changed, 41 insertions(+), 14 deletions(-) (limited to 'actionpack/lib/action_controller') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 58eb5cabcd..c28e9005cf 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -340,6 +340,16 @@ module ActionController #:nodoc: cattr_accessor :optimise_named_routes self.optimise_named_routes = true + # Indicates whether the response format should be determined by examining the Accept HTTP header, + # or by using the simpler params + ajax rules. + # + # If this is set to +true+ then +respond_to+ and +Request#format+ will take the Accept header into + # account. If it is set to false (the default) then the request format will be determined solely + # by examining params[:format]. If params format is missing, the format will be either HTML or + # Javascript depending on whether the request is an AJAX request. + cattr_accessor :use_accept_header + self.use_accept_header = false + # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. class_inheritable_accessor :allow_forgery_protection self.allow_forgery_protection = true diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index 234ef8ae5b..f3535f8330 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -166,10 +166,7 @@ module ActionController #:nodoc: # If there's no extension in the path, check request.format if extension.nil? - extension = request.format.to_sym.to_s - if extension=='all' - extension = nil - end + extension = request.cache_format end extension end diff --git a/actionpack/lib/action_controller/mime_responds.rb b/actionpack/lib/action_controller/mime_responds.rb index 1dbd8b9e6f..29294476f7 100644 --- a/actionpack/lib/action_controller/mime_responds.rb +++ b/actionpack/lib/action_controller/mime_responds.rb @@ -114,7 +114,11 @@ module ActionController #:nodoc: @request = controller.request @response = controller.response - @mime_type_priority = Array(Mime::Type.lookup_by_extension(@request.parameters[:format]) || @request.accepts) + if ActionController::Base.use_accept_header + @mime_type_priority = Array(Mime::Type.lookup_by_extension(@request.parameters[:format]) || @request.accepts) + else + @mime_type_priority = [@request.format] + end @order = [] @responses = {} diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index c91a3387a0..c76a93f7a1 100755 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -89,14 +89,23 @@ module ActionController end end - # Returns the Mime type for the format used in the request. If there is no format available, the first of the - # accept types will be used. Examples: + # Returns the Mime type for the format used in the request. # # GET /posts/5.xml | request.format => Mime::XML # GET /posts/5.xhtml | request.format => Mime::HTML - # GET /posts/5 | request.format => request.accepts.first (usually Mime::HTML for browsers) + # GET /posts/5 | request.format => Mime::HTML or MIME::JS, or request.accepts.first depending on the value of ActionController::Base.use_accept_header def format - @format ||= parameters[:format] ? Mime::Type.lookup_by_extension(parameters[:format]) : accepts.first + @format ||= begin + if parameters[:format] + Mime::Type.lookup_by_extension(parameters[:format]) + elsif ActionController::Base.use_accept_header + accepts.first + elsif xhr? + Mime::Type.lookup_by_extension("js") + else + Mime::Type.lookup_by_extension("html") + end + end end @@ -116,19 +125,26 @@ module ActionController @format = Mime::Type.lookup_by_extension(parameters[:format]) end + # Returns a symbolized version of the :format parameter of the request. + # If no format is given it returns :jsfor AJAX requests and :html + # otherwise. def template_format parameter_format = parameters[:format] - case - when parameter_format.blank? && !xhr? - :html - when parameter_format.blank? && xhr? + if parameter_format + parameter_format.to_sym + elsif xhr? :js else - parameter_format.to_sym + :html end end + def cache_format + parameter_format = parameters[:format] + parameter_format && parameter_format.to_sym + end + # Returns true if the request's "X-Requested-With" header contains # "XMLHttpRequest". (The Prototype Javascript library sends this header with # every Ajax request.) -- cgit v1.2.3