diff options
Diffstat (limited to 'actionpack/lib/action_controller')
5 files changed, 50 insertions, 35 deletions
diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb index 369741fb12..374645c9ce 100644 --- a/actionpack/lib/action_controller/metal/data_streaming.rb +++ b/actionpack/lib/action_controller/metal/data_streaming.rb @@ -8,10 +8,8 @@ module ActionController #:nodoc: include ActionController::Rendering - DEFAULT_SEND_FILE_OPTIONS = { - :type => 'application/octet-stream'.freeze, - :disposition => 'attachment'.freeze, - }.freeze + DEFAULT_SEND_FILE_TYPE = 'application/octet-stream'.freeze #:nodoc: + DEFAULT_SEND_FILE_DISPOSITION = 'attachment'.freeze #:nodoc: protected # Sends the file. This uses a server-appropriate method (such as X-Sendfile) @@ -127,7 +125,7 @@ module ActionController #:nodoc: # # See +send_file+ for more information on HTTP Content-* headers and caching. def send_data(data, options = {}) #:doc: - send_file_headers! options.dup + send_file_headers! options render options.slice(:status, :content_type).merge(:text => data) end @@ -135,15 +133,8 @@ module ActionController #:nodoc: def send_file_headers!(options) type_provided = options.has_key?(:type) - options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options)) - [:type, :disposition].each do |arg| - raise ArgumentError, ":#{arg} option required" if options[arg].nil? - end - - disposition = options[:disposition] - disposition += %(; filename="#{options[:filename]}") if options[:filename] - - content_type = options[:type] + content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE) + raise ArgumentError, ":type option required" if content_type.nil? if content_type.is_a?(Symbol) extension = Mime[content_type] @@ -157,10 +148,13 @@ module ActionController #:nodoc: self.content_type = content_type end - headers.merge!( - 'Content-Disposition' => disposition, - 'Content-Transfer-Encoding' => 'binary' - ) + disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION) + unless disposition.nil? + disposition += %(; filename="#{options[:filename]}") if options[:filename] + headers['Content-Disposition'] = disposition + end + + headers['Content-Transfer-Encoding'] = 'binary' response.sending_file = true diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index 35ded8a56c..5e7bd44562 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -45,6 +45,16 @@ module ActionController # integer, or a symbol representing the downcased, underscored and symbolized description. # Note that the status code must be a 3xx HTTP code, or redirection will not occur. # + # If you are using XHR requests other than GET or POST and redirecting after the + # request then some browsers will follow the redirect using the original request + # method. This may lead to undesirable behavior such as a double DELETE. To work + # around this you can return a <tt>303 See Other</tt> status code which will be + # followed using a GET request. + # + # Examples: + # redirect_to posts_url, :status => :see_other + # redirect_to :action => 'index', :status => 303 + # # It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names # +alert+ and +notice+ as well as a general purpose +flash+ bucket. # diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index 6e9ce450ac..4a0c1c7dd7 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -91,9 +91,14 @@ module ActionController add :json do |json, options| json = json.to_json(options) unless json.kind_of?(String) - json = "#{options[:callback]}(#{json})" unless options[:callback].blank? - self.content_type ||= Mime::JSON - json + + if options[:callback].present? + self.content_type ||= Mime::JS + "#{options[:callback]}(#{json})" + else + self.content_type ||= Mime::JSON + json + end end add :js do |js, options| diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 5c40889f6b..e7af3f5b8d 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -75,12 +75,7 @@ module ActionController def record_key_for_dom_id(record) record = record.to_model if record.respond_to?(:to_model) key = record.to_key - key ? sanitize_dom_id(key.join('_')) : key - end - - # Replaces characters that are invalid in HTML DOM ids with valid ones. - def sanitize_dom_id(candidate_id) - candidate_id # TODO implement conversion to valid DOM id values + key ? key.join('_') : key end end end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 7db7d270e5..21997c4d79 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -147,17 +147,23 @@ module ActionController extra_keys = routes.extra_keys(parameters) non_path_parameters = get? ? query_parameters : request_parameters parameters.each do |key, value| - if value.is_a? Fixnum - value = value.to_s - elsif value.is_a? Array - value = Result.new(value.map { |v| v.is_a?(String) ? v.dup : v }) - elsif value.is_a? String + if value.is_a?(Array) && (value.frozen? || value.any?(&:frozen?)) + value = value.map{ |v| v.duplicable? ? v.dup : v } + elsif value.is_a?(Hash) && (value.frozen? || value.any?{ |k,v| v.frozen? }) + value = Hash[value.map{ |k,v| [k, v.duplicable? ? v.dup : v] }] + elsif value.frozen? && value.duplicable? value = value.dup end if extra_keys.include?(key.to_sym) non_path_parameters[key] = value else + if value.is_a?(Array) + value = Result.new(value.map(&:to_param)) + else + value = value.to_param + end + path_parameters[key.to_s] = value end end @@ -453,7 +459,7 @@ module ActionController # Ensure that numbers and symbols passed as params are converted to # proper params, as is the case when engaging rack. - parameters = paramify_values(parameters) + parameters = paramify_values(parameters) if html_format?(parameters) @request.recycle! @response.recycle! @@ -466,14 +472,13 @@ module ActionController parameters ||= {} controller_class_name = @controller.class.anonymous? ? - "anonymous_controller" : + "anonymous" : @controller.class.name.underscore.sub(/_controller$/, '') @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters) @request.session.update(session) if session @request.session["flash"] = @request.flash.update(flash || {}) - @request.session["flash"].sweep @controller.request = @request build_request_uri(action, parameters) @@ -546,6 +551,12 @@ module ActionController @request.env["QUERY_STRING"] = query_string || "" end end + + def html_format?(parameters) + return true unless parameters.is_a?(Hash) + format = Mime[parameters[:format]] + format.nil? || format.html? + end end # When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline |