actionpack 2.3.3 → 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +12 -1
- data/Rakefile +9 -8
- data/lib/action_controller/assertions/response_assertions.rb +3 -1
- data/lib/action_controller/base.rb +6 -2
- data/lib/action_controller/cookies.rb +1 -1
- data/lib/action_controller/dispatcher.rb +21 -6
- data/lib/action_controller/http_authentication.rb +3 -2
- data/lib/action_controller/params_parser.rb +6 -0
- data/lib/action_controller/reloader.rb +30 -21
- data/lib/action_controller/request_forgery_protection.rb +2 -1
- data/lib/action_controller/resources.rb +17 -13
- data/lib/action_controller/response.rb +6 -0
- data/lib/action_controller/routing.rb +3 -0
- data/lib/action_controller/routing/route_set.rb +18 -5
- data/lib/action_controller/streaming.rb +3 -1
- data/lib/action_controller/url_rewriter.rb +1 -1
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +3 -2
- data/lib/action_view/helpers/form_options_helper.rb +69 -1
- data/lib/action_view/helpers/tag_helper.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +20 -11
- data/lib/action_view/helpers/url_helper.rb +1 -1
- data/lib/action_view/locale/en.yml +4 -0
- data/test/abstract_unit.rb +16 -0
- data/test/controller/caching_test.rb +1 -1
- data/test/controller/cookie_test.rb +6 -0
- data/test/controller/dispatcher_test.rb +50 -11
- data/test/controller/filter_params_test.rb +2 -1
- data/test/controller/http_basic_authentication_test.rb +25 -0
- data/test/controller/http_digest_authentication_test.rb +29 -6
- data/test/controller/rack_test.rb +18 -1
- data/test/controller/redirect_test.rb +1 -1
- data/test/controller/reloader_test.rb +47 -20
- data/test/controller/request/json_params_parsing_test.rb +24 -4
- data/test/controller/request/xml_params_parsing_test.rb +15 -0
- data/test/controller/request_forgery_protection_test.rb +6 -5
- data/test/controller/resources_test.rb +44 -0
- data/test/controller/routing_test.rb +7 -2
- data/test/controller/send_file_test.rb +11 -1
- data/test/controller/url_rewriter_test.rb +29 -3
- data/test/fixtures/public/absolute/test.css +23 -0
- data/test/fixtures/public/absolute/test.js +63 -0
- data/test/template/atom_feed_helper_test.rb +29 -0
- data/test/template/form_helper_test.rb +26 -0
- data/test/template/form_options_helper_i18n_test.rb +27 -0
- data/test/template/form_options_helper_test.rb +34 -0
- data/test/template/text_helper_test.rb +23 -0
- data/test/template/url_helper_test.rb +8 -0
- metadata +10 -94
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,4 +1,13 @@ | |
| 1 | 
            -
            *2.3. | 
| 1 | 
            +
            *2.3.4 (September 4, 2009)*
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Sanitize multibyte strings before escaping them with escape_once. CVE-2009-3009
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Introduce grouped_collection_select helper.  #1249 [Dan Codeape, Erik Ostrom]
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Ruby 1.9: fix Content-Length for multibyte send_data streaming.  #2661 [Sava Chankov]
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
            *2.3.3 (July 12, 2009)*
         | 
| 2 11 |  | 
| 3 12 | 
             
            * Fixed that TestResponse.cookies was returning cookies unescaped #1867 [Doug McInnes]
         | 
| 4 13 |  | 
| @@ -7,6 +16,8 @@ | |
| 7 16 |  | 
| 8 17 | 
             
            * Fixed that redirection would just log the options, not the final url (which lead to "Redirected to #<Post:0x23150b8>") [DHH]
         | 
| 9 18 |  | 
| 19 | 
            +
            * Don't check authenticity tokens for any AJAX requests [Ross Kaffenberger/Bryan Helmkamp]
         | 
| 20 | 
            +
             | 
| 10 21 | 
             
            * Added ability to pass in :public => true to fresh_when, stale?, and expires_in to make the request proxy cachable #2095 [Gregg Pollack]
         | 
| 11 22 |  | 
| 12 23 | 
             
            * Fixed that passing a custom form builder would be forwarded to nested fields_for calls #2023 [Eloy Duran/Nate Wiger]
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -29,7 +29,7 @@ Rake::TestTask.new(:test_action_pack) do |t| | |
| 29 29 |  | 
| 30 30 | 
             
              # make sure we include the tests in alphabetical order as on some systems
         | 
| 31 31 | 
             
              # this will not happen automatically and the tests (as a whole) will error
         | 
| 32 | 
            -
              t.test_files = Dir.glob( "test/[ | 
| 32 | 
            +
              t.test_files = Dir.glob( "test/[cftv]*/**/*_test.rb" ).sort
         | 
| 33 33 |  | 
| 34 34 | 
             
              t.verbose = true
         | 
| 35 35 | 
             
              #t.warning = true
         | 
| @@ -79,7 +79,7 @@ spec = Gem::Specification.new do |s| | |
| 79 79 | 
             
              s.has_rdoc = true
         | 
| 80 80 | 
             
              s.requirements << 'none'
         | 
| 81 81 |  | 
| 82 | 
            -
              s.add_dependency('activesupport', '= 2.3. | 
| 82 | 
            +
              s.add_dependency('activesupport', '= 2.3.4' + PKG_BUILD)
         | 
| 83 83 | 
             
              s.add_dependency('rack', '~> 1.0.0')
         | 
| 84 84 |  | 
| 85 85 | 
             
              s.require_path = 'lib'
         | 
| @@ -149,11 +149,12 @@ end | |
| 149 149 |  | 
| 150 150 | 
             
            desc "Publish the release files to RubyForge."
         | 
| 151 151 | 
             
            task :release => [ :package ] do
         | 
| 152 | 
            -
               | 
| 152 | 
            +
              require 'rubyforge'
         | 
| 153 | 
            +
              require 'rake/contrib/rubyforgepublisher'
         | 
| 153 154 |  | 
| 154 | 
            -
               | 
| 155 | 
            -
             | 
| 156 | 
            -
             | 
| 157 | 
            -
             | 
| 158 | 
            -
               | 
| 155 | 
            +
              packages = %w( gem tgz zip ).collect{ |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              rubyforge = RubyForge.new
         | 
| 158 | 
            +
              rubyforge.login
         | 
| 159 | 
            +
              rubyforge.add_release(PKG_NAME, PKG_NAME, "REL #{PKG_VERSION}", *packages)
         | 
| 159 160 | 
             
            end
         | 
| @@ -64,7 +64,9 @@ module ActionController | |
| 64 64 | 
             
                      # Support partial arguments for hash redirections
         | 
| 65 65 | 
             
                      if options.is_a?(Hash) && @response.redirected_to.is_a?(Hash)
         | 
| 66 66 | 
             
                        if options.all? {|(key, value)| @response.redirected_to[key] == value}
         | 
| 67 | 
            -
                           | 
| 67 | 
            +
                          callstack = caller.dup
         | 
| 68 | 
            +
                          callstack.slice!(0, 2)
         | 
| 69 | 
            +
                          ::ActiveSupport::Deprecation.warn("Using assert_redirected_to with partial hash arguments is deprecated. Specify the full set arguments instead", callstack)
         | 
| 68 70 | 
             
                          return true
         | 
| 69 71 | 
             
                        end
         | 
| 70 72 | 
             
                      end
         | 
| @@ -493,7 +493,12 @@ module ActionController #:nodoc: | |
| 493 493 | 
             
                          filtered_parameters[key] = filter_parameters(value)
         | 
| 494 494 | 
             
                        elsif value.is_a?(Array)
         | 
| 495 495 | 
             
                          filtered_parameters[key] = value.collect do |item|
         | 
| 496 | 
            -
                             | 
| 496 | 
            +
                            case item
         | 
| 497 | 
            +
                            when Hash, Array
         | 
| 498 | 
            +
                              filter_parameters(item)
         | 
| 499 | 
            +
                            else
         | 
| 500 | 
            +
                              item
         | 
| 501 | 
            +
                            end
         | 
| 497 502 | 
             
                          end
         | 
| 498 503 | 
             
                        elsif block_given?
         | 
| 499 504 | 
             
                          key = key.dup
         | 
| @@ -814,7 +819,6 @@ module ActionController #:nodoc: | |
| 814 819 | 
             
                  #   render :text => proc { |response, output|
         | 
| 815 820 | 
             
                  #     10_000_000.times do |i|
         | 
| 816 821 | 
             
                  #       output.write("This is line #{i}\n")
         | 
| 817 | 
            -
                  #       output.flush
         | 
| 818 822 | 
             
                  #     end
         | 
| 819 823 | 
             
                  #   }
         | 
| 820 824 | 
             
                  #
         | 
| @@ -2,13 +2,12 @@ module ActionController | |
| 2 2 | 
             
              # Dispatches requests to the appropriate controller and takes care of
         | 
| 3 3 | 
             
              # reloading the app after each request when Dependencies.load? is true.
         | 
| 4 4 | 
             
              class Dispatcher
         | 
| 5 | 
            +
                @@cache_classes = true
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
                class << self
         | 
| 6 8 | 
             
                  def define_dispatcher_callbacks(cache_classes)
         | 
| 9 | 
            +
                    @@cache_classes = cache_classes
         | 
| 7 10 | 
             
                    unless cache_classes
         | 
| 8 | 
            -
                      unless self.middleware.include?(Reloader)
         | 
| 9 | 
            -
                        self.middleware.insert_after(Failsafe, Reloader)
         | 
| 10 | 
            -
                      end
         | 
| 11 | 
            -
             | 
| 12 11 | 
             
                      ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
         | 
| 13 12 | 
             
                    end
         | 
| 14 13 |  | 
| @@ -79,7 +78,7 @@ module ActionController | |
| 79 78 | 
             
                # DEPRECATE: Remove arguments, since they are only used by CGI
         | 
| 80 79 | 
             
                def initialize(output = $stdout, request = nil, response = nil)
         | 
| 81 80 | 
             
                  @output = output
         | 
| 82 | 
            -
                   | 
| 81 | 
            +
                  build_middleware_stack if @@cache_classes
         | 
| 83 82 | 
             
                end
         | 
| 84 83 |  | 
| 85 84 | 
             
                def dispatch
         | 
| @@ -103,7 +102,18 @@ module ActionController | |
| 103 102 | 
             
                end
         | 
| 104 103 |  | 
| 105 104 | 
             
                def call(env)
         | 
| 106 | 
            -
                   | 
| 105 | 
            +
                  if @@cache_classes
         | 
| 106 | 
            +
                    @app.call(env)
         | 
| 107 | 
            +
                  else
         | 
| 108 | 
            +
                    Reloader.run do
         | 
| 109 | 
            +
                      # When class reloading is turned on, we will want to rebuild the
         | 
| 110 | 
            +
                      # middleware stack every time we process a request. If we don't
         | 
| 111 | 
            +
                      # rebuild the middleware stack, then the stack may contain references
         | 
| 112 | 
            +
                      # to old classes metal classes, which will b0rk class reloading.
         | 
| 113 | 
            +
                      build_middleware_stack
         | 
| 114 | 
            +
                      @app.call(env)
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                  end
         | 
| 107 117 | 
             
                end
         | 
| 108 118 |  | 
| 109 119 | 
             
                def _call(env)
         | 
| @@ -114,5 +124,10 @@ module ActionController | |
| 114 124 | 
             
                def flush_logger
         | 
| 115 125 | 
             
                  Base.logger.flush
         | 
| 116 126 | 
             
                end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                private
         | 
| 129 | 
            +
                  def build_middleware_stack
         | 
| 130 | 
            +
                    @app = @@middleware.build(lambda { |env| self.dup._call(env) })
         | 
| 131 | 
            +
                  end
         | 
| 117 132 | 
             
              end
         | 
| 118 133 | 
             
            end
         | 
| @@ -139,7 +139,7 @@ module ActionController | |
| 139 139 | 
             
                  end
         | 
| 140 140 |  | 
| 141 141 | 
             
                  def decode_credentials(request)
         | 
| 142 | 
            -
                    ActiveSupport::Base64.decode64(authorization(request).split.last || '')
         | 
| 142 | 
            +
                    ActiveSupport::Base64.decode64(authorization(request).split(' ', 2).last || '')
         | 
| 143 143 | 
             
                  end
         | 
| 144 144 |  | 
| 145 145 | 
             
                  def encode_credentials(user_name, password)
         | 
| @@ -195,9 +195,10 @@ module ActionController | |
| 195 195 | 
             
                      return false unless password
         | 
| 196 196 |  | 
| 197 197 | 
             
                      method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
         | 
| 198 | 
            +
                      uri    = credentials[:uri][0,1] == '/' ? request.request_uri : request.url
         | 
| 198 199 |  | 
| 199 200 | 
             
                     [true, false].any? do |password_is_ha1|
         | 
| 200 | 
            -
                       expected = expected_response(method,  | 
| 201 | 
            +
                       expected = expected_response(method, uri, credentials, password, password_is_ha1)
         | 
| 201 202 | 
             
                       expected == credentials[:response]
         | 
| 202 203 | 
             
                     end
         | 
| 203 204 | 
             
                    end
         | 
| @@ -47,6 +47,8 @@ module ActionController | |
| 47 47 | 
             
                        false
         | 
| 48 48 | 
             
                    end
         | 
| 49 49 | 
             
                  rescue Exception => e # YAML, XML or Ruby code block errors
         | 
| 50 | 
            +
                    logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}"
         | 
| 51 | 
            +
             | 
| 50 52 | 
             
                    raise
         | 
| 51 53 | 
             
                      { "body" => request.raw_post,
         | 
| 52 54 | 
             
                        "content_type" => request.content_type,
         | 
| @@ -67,5 +69,9 @@ module ActionController | |
| 67 69 |  | 
| 68 70 | 
             
                    nil
         | 
| 69 71 | 
             
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def logger
         | 
| 74 | 
            +
                    defined?(Rails.logger) ? Rails.logger : Logger.new($stderr)
         | 
| 75 | 
            +
                  end
         | 
| 70 76 | 
             
              end
         | 
| 71 77 | 
             
            end
         | 
| @@ -1,14 +1,21 @@ | |
| 1 | 
            +
            require 'thread'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module ActionController
         | 
| 2 4 | 
             
              class Reloader
         | 
| 5 | 
            +
                @@default_lock = Mutex.new
         | 
| 6 | 
            +
                cattr_accessor :default_lock
         | 
| 7 | 
            +
             | 
| 3 8 | 
             
                class BodyWrapper
         | 
| 4 | 
            -
                  def initialize(body)
         | 
| 9 | 
            +
                  def initialize(body, lock)
         | 
| 5 10 | 
             
                    @body = body
         | 
| 11 | 
            +
                    @lock = lock
         | 
| 6 12 | 
             
                  end
         | 
| 7 13 |  | 
| 8 14 | 
             
                  def close
         | 
| 9 15 | 
             
                    @body.close if @body.respond_to?(:close)
         | 
| 10 16 | 
             
                  ensure
         | 
| 11 17 | 
             
                    Dispatcher.cleanup_application
         | 
| 18 | 
            +
                    @lock.unlock
         | 
| 12 19 | 
             
                  end
         | 
| 13 20 |  | 
| 14 21 | 
             
                  def method_missing(*args, &block)
         | 
| @@ -20,26 +27,28 @@ module ActionController | |
| 20 27 | 
             
                  end
         | 
| 21 28 | 
             
                end
         | 
| 22 29 |  | 
| 23 | 
            -
                def  | 
| 24 | 
            -
                   | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
                   | 
| 42 | 
            -
             | 
| 30 | 
            +
                def self.run(lock = @@default_lock)
         | 
| 31 | 
            +
                  lock.lock
         | 
| 32 | 
            +
                  begin
         | 
| 33 | 
            +
                    Dispatcher.reload_application
         | 
| 34 | 
            +
                    status, headers, body = yield
         | 
| 35 | 
            +
                    # We do not want to call 'cleanup_application' in an ensure block
         | 
| 36 | 
            +
                    # because the returned Rack response body may lazily generate its data. This
         | 
| 37 | 
            +
                    # is for example the case if one calls
         | 
| 38 | 
            +
                    #
         | 
| 39 | 
            +
                    #   render :text => lambda { ... code here which refers to application models ... }
         | 
| 40 | 
            +
                    #
         | 
| 41 | 
            +
                    # in an ActionController.
         | 
| 42 | 
            +
                    #
         | 
| 43 | 
            +
                    # Instead, we will want to cleanup the application code after the request is
         | 
| 44 | 
            +
                    # completely finished. So we wrap the body in a BodyWrapper class so that
         | 
| 45 | 
            +
                    # when the Rack handler calls #close during the end of the request, we get to
         | 
| 46 | 
            +
                    # run our cleanup code.
         | 
| 47 | 
            +
                    [status, headers, BodyWrapper.new(body, lock)]
         | 
| 48 | 
            +
                  rescue Exception
         | 
| 49 | 
            +
                    lock.unlock
         | 
| 50 | 
            +
                    raise
         | 
| 51 | 
            +
                  end
         | 
| 43 52 | 
             
                end
         | 
| 44 53 | 
             
              end
         | 
| 45 54 | 
             
            end
         | 
| @@ -81,12 +81,13 @@ module ActionController #:nodoc: | |
| 81 81 |  | 
| 82 82 | 
             
                  # Returns true or false if a request is verified.  Checks:
         | 
| 83 83 | 
             
                  #
         | 
| 84 | 
            -
                  # * is the format restricted?  By default, only HTML  | 
| 84 | 
            +
                  # * is the format restricted?  By default, only HTML requests are checked.
         | 
| 85 85 | 
             
                  # * is it a GET request?  Gets should be safe and idempotent
         | 
| 86 86 | 
             
                  # * Does the form_authenticity_token match the given token value from the params?
         | 
| 87 87 | 
             
                  def verified_request?
         | 
| 88 88 | 
             
                    !protect_against_forgery?     ||
         | 
| 89 89 | 
             
                      request.method == :get      ||
         | 
| 90 | 
            +
                      request.xhr?                ||
         | 
| 90 91 | 
             
                      !verifiable_request_format? ||
         | 
| 91 92 | 
             
                      form_authenticity_token == params[request_forgery_protection_token]
         | 
| 92 93 | 
             
                  end
         | 
| @@ -317,9 +317,10 @@ module ActionController | |
| 317 317 | 
             
                #       notes.resources :attachments
         | 
| 318 318 | 
             
                #     end
         | 
| 319 319 | 
             
                #
         | 
| 320 | 
            -
                # * <tt>:path_names</tt> - Specify different names for the  | 
| 320 | 
            +
                # * <tt>:path_names</tt> - Specify different path names for the actions. For example:
         | 
| 321 321 | 
             
                #     # new_products_path == '/productos/nuevo'
         | 
| 322 | 
            -
                #      | 
| 322 | 
            +
                #     # bids_product_path(1) == '/productos/1/licitacoes'
         | 
| 323 | 
            +
                #     map.resources :products, :as => 'productos', :member => { :bids => :get }, :path_names => { :new => 'nuevo', :bids => 'licitacoes' }
         | 
| 323 324 | 
             
                #
         | 
| 324 325 | 
             
                #   You can also set default action names from an environment, like this:
         | 
| 325 326 | 
             
                #     config.action_controller.resources_path_names = { :new => 'nuevo', :edit => 'editar' }
         | 
| @@ -525,16 +526,16 @@ module ActionController | |
| 525 526 | 
             
                    resource = Resource.new(entities, options)
         | 
| 526 527 |  | 
| 527 528 | 
             
                    with_options :controller => resource.controller do |map|
         | 
| 528 | 
            -
                      map_collection_actions(map, resource)
         | 
| 529 | 
            -
                      map_default_collection_actions(map, resource)
         | 
| 530 | 
            -
                      map_new_actions(map, resource)
         | 
| 531 | 
            -
                      map_member_actions(map, resource)
         | 
| 532 | 
            -
             | 
| 533 529 | 
             
                      map_associations(resource, options)
         | 
| 534 530 |  | 
| 535 531 | 
             
                      if block_given?
         | 
| 536 532 | 
             
                        with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
         | 
| 537 533 | 
             
                      end
         | 
| 534 | 
            +
             | 
| 535 | 
            +
                      map_collection_actions(map, resource)
         | 
| 536 | 
            +
                      map_default_collection_actions(map, resource)
         | 
| 537 | 
            +
                      map_new_actions(map, resource)
         | 
| 538 | 
            +
                      map_member_actions(map, resource)
         | 
| 538 539 | 
             
                    end
         | 
| 539 540 | 
             
                  end
         | 
| 540 541 |  | 
| @@ -542,16 +543,16 @@ module ActionController | |
| 542 543 | 
             
                    resource = SingletonResource.new(entities, options)
         | 
| 543 544 |  | 
| 544 545 | 
             
                    with_options :controller => resource.controller do |map|
         | 
| 545 | 
            -
                      map_collection_actions(map, resource)
         | 
| 546 | 
            -
                      map_new_actions(map, resource)
         | 
| 547 | 
            -
                      map_member_actions(map, resource)
         | 
| 548 | 
            -
                      map_default_singleton_actions(map, resource)
         | 
| 549 | 
            -
             | 
| 550 546 | 
             
                      map_associations(resource, options)
         | 
| 551 547 |  | 
| 552 548 | 
             
                      if block_given?
         | 
| 553 549 | 
             
                        with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
         | 
| 554 550 | 
             
                      end
         | 
| 551 | 
            +
             | 
| 552 | 
            +
                      map_collection_actions(map, resource)
         | 
| 553 | 
            +
                      map_new_actions(map, resource)
         | 
| 554 | 
            +
                      map_member_actions(map, resource)
         | 
| 555 | 
            +
                      map_default_singleton_actions(map, resource)
         | 
| 555 556 | 
             
                    end
         | 
| 556 557 | 
             
                  end
         | 
| 557 558 |  | 
| @@ -586,7 +587,10 @@ module ActionController | |
| 586 587 | 
             
                    resource.collection_methods.each do |method, actions|
         | 
| 587 588 | 
             
                      actions.each do |action|
         | 
| 588 589 | 
             
                        [method].flatten.each do |m|
         | 
| 589 | 
            -
                           | 
| 590 | 
            +
                          action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
         | 
| 591 | 
            +
                          action_path ||= action
         | 
| 592 | 
            +
             | 
| 593 | 
            +
                          map_resource_routes(map, resource, action, "#{resource.path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.name_prefix}#{resource.plural}", m)
         | 
| 590 594 | 
             
                        end
         | 
| 591 595 | 
             
                      end
         | 
| 592 596 | 
             
                    end
         | 
| @@ -166,6 +166,12 @@ module ActionController # :nodoc: | |
| 166 166 | 
             
                  str
         | 
| 167 167 | 
             
                end
         | 
| 168 168 |  | 
| 169 | 
            +
                def flush #:nodoc:
         | 
| 170 | 
            +
                  ActiveSupport::Deprecation.warn(
         | 
| 171 | 
            +
                    'Calling output.flush is no longer needed for streaming output ' +
         | 
| 172 | 
            +
                    'because ActionController::Response automatically handles it', caller)
         | 
| 173 | 
            +
                end
         | 
| 174 | 
            +
             | 
| 169 175 | 
             
                def set_cookie(key, value)
         | 
| 170 176 | 
             
                  if value.has_key?(:http_only)
         | 
| 171 177 | 
             
                    ActiveSupport::Deprecation.warn(
         | 
| @@ -271,6 +271,9 @@ module ActionController | |
| 271 271 |  | 
| 272 272 | 
             
                ALLOWED_REQUIREMENTS_FOR_OPTIMISATION = [:controller, :action].to_set
         | 
| 273 273 |  | 
| 274 | 
            +
                mattr_accessor :generate_best_match
         | 
| 275 | 
            +
                self.generate_best_match = true
         | 
| 276 | 
            +
             | 
| 274 277 | 
             
                # The root paths which may contain controller files
         | 
| 275 278 | 
             
                mattr_accessor :controller_paths
         | 
| 276 279 | 
             
                self.controller_paths = []
         | 
| @@ -405,11 +405,14 @@ module ActionController | |
| 405 405 | 
             
                      end
         | 
| 406 406 |  | 
| 407 407 | 
             
                      # don't use the recalled keys when determining which routes to check
         | 
| 408 | 
            -
                       | 
| 408 | 
            +
                      future_routes, deprecated_routes = routes_by_controller[controller][action][options.reject {|k,v| !v}.keys.sort_by { |x| x.object_id }]
         | 
| 409 | 
            +
                      routes = Routing.generate_best_match ? deprecated_routes : future_routes
         | 
| 409 410 |  | 
| 410 | 
            -
                      routes. | 
| 411 | 
            +
                      routes.each_with_index do |route, index|
         | 
| 411 412 | 
             
                        results = route.__send__(method, options, merged, expire_on)
         | 
| 412 | 
            -
                         | 
| 413 | 
            +
                        if results && (!results.is_a?(Array) || results.first)
         | 
| 414 | 
            +
                          return results
         | 
| 415 | 
            +
                        end
         | 
| 413 416 | 
             
                      end
         | 
| 414 417 | 
             
                    end
         | 
| 415 418 |  | 
| @@ -448,7 +451,10 @@ module ActionController | |
| 448 451 | 
             
                    @routes_by_controller ||= Hash.new do |controller_hash, controller|
         | 
| 449 452 | 
             
                      controller_hash[controller] = Hash.new do |action_hash, action|
         | 
| 450 453 | 
             
                        action_hash[action] = Hash.new do |key_hash, keys|
         | 
| 451 | 
            -
                          key_hash[keys] =  | 
| 454 | 
            +
                          key_hash[keys] = [
         | 
| 455 | 
            +
                            routes_for_controller_and_action_and_keys(controller, action, keys),
         | 
| 456 | 
            +
                            deprecated_routes_for_controller_and_action_and_keys(controller, action, keys)
         | 
| 457 | 
            +
                          ]
         | 
| 452 458 | 
             
                        end
         | 
| 453 459 | 
             
                      end
         | 
| 454 460 | 
             
                    end
         | 
| @@ -460,10 +466,11 @@ module ActionController | |
| 460 466 | 
             
                    merged = options if expire_on[:controller]
         | 
| 461 467 | 
             
                    action = merged[:action] || 'index'
         | 
| 462 468 |  | 
| 463 | 
            -
                    routes_by_controller[controller][action][merged.keys]
         | 
| 469 | 
            +
                    routes_by_controller[controller][action][merged.keys][1]
         | 
| 464 470 | 
             
                  end
         | 
| 465 471 |  | 
| 466 472 | 
             
                  def routes_for_controller_and_action(controller, action)
         | 
| 473 | 
            +
                    ActiveSupport::Deprecation.warn "routes_for_controller_and_action() has been deprecated. Please use routes_for()"
         | 
| 467 474 | 
             
                    selected = routes.select do |route|
         | 
| 468 475 | 
             
                      route.matches_controller_and_action? controller, action
         | 
| 469 476 | 
             
                    end
         | 
| @@ -471,6 +478,12 @@ module ActionController | |
| 471 478 | 
             
                  end
         | 
| 472 479 |  | 
| 473 480 | 
             
                  def routes_for_controller_and_action_and_keys(controller, action, keys)
         | 
| 481 | 
            +
                    routes.select do |route|
         | 
| 482 | 
            +
                      route.matches_controller_and_action? controller, action
         | 
| 483 | 
            +
                    end
         | 
| 484 | 
            +
                  end
         | 
| 485 | 
            +
             | 
| 486 | 
            +
                  def deprecated_routes_for_controller_and_action_and_keys(controller, action, keys)
         | 
| 474 487 | 
             
                    selected = routes.select do |route|
         | 
| 475 488 | 
             
                      route.matches_controller_and_action? controller, action
         | 
| 476 489 | 
             
                    end
         | 
| @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require 'active_support/core_ext/string/bytesize'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module ActionController #:nodoc:
         | 
| 2 4 | 
             
              # Methods for sending arbitrary data and for streaming files to the browser,
         | 
| 3 5 | 
             
              # instead of rendering.
         | 
| @@ -137,7 +139,7 @@ module ActionController #:nodoc: | |
| 137 139 | 
             
                  # instead. See ActionController::Base#render for more information.
         | 
| 138 140 | 
             
                  def send_data(data, options = {}) #:doc:
         | 
| 139 141 | 
             
                    logger.info "Sending data #{options[:filename]}" if logger
         | 
| 140 | 
            -
                    send_file_headers! options.merge(:length => data. | 
| 142 | 
            +
                    send_file_headers! options.merge(:length => data.bytesize)
         | 
| 141 143 | 
             
                    @performed_render = false
         | 
| 142 144 | 
             
                    render :status => options[:status], :text => data
         | 
| 143 145 | 
             
                  end
         |