Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #11184: 0001-Improve-ActionCaching-s-format-handling.patch

File 0001-Improve-ActionCaching-s-format-handling.patch, 6.5 kB (added by Catfish, 4 months ago)
  • a/actionpack/lib/action_controller/caching/actions.rb

    old new  
    6464 
    6565          if options[:action].is_a?(Array) 
    6666            options[:action].dup.each do |action| 
    67               expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }))) 
     67              expire_fragment(ActionCachePath.path_for(self, options.merge({ :action => action }), false)) 
    6868            end 
    6969          else 
    70             expire_fragment(ActionCachePath.path_for(self, options)) 
     70            expire_fragment(ActionCachePath.path_for(self, options, false)) 
    7171          end 
    7272        end 
    7373 
     
    111111        attr_reader :path, :extension 
    112112 
    113113        class << self 
    114           def path_for(controller, options
    115             new(controller, options).path 
     114          def path_for(controller, options, infer_extension=true
     115            new(controller, options, infer_extension).path 
    116116          end 
    117117        end 
    118  
    119         def initialize(controller, options = {}) 
    120           @extension = extract_extension(controller.request.path) 
     118         
     119        # When true, infer_extension will look up the cache path extension from the request's path & format. 
     120        # This is desirable when reading and writing the cache, but not when expiring the cache -  expire_action should expire the same files regardless of the request format. 
     121        def initialize(controller, options = {}, infer_extension=true) 
     122          if infer_extension and options.is_a? Hash 
     123            request_extension = extract_extension(controller.request) 
     124            options = options.reverse_merge(:format => request_extension) 
     125          end 
    121126          path = controller.url_for(options).split('://').last 
    122127          normalize!(path) 
    123           add_extension!(path, @extension) 
     128          if infer_extension 
     129            @extension = request_extension 
     130            add_extension!(path, @extension) 
     131          end 
    124132          @path = URI.unescape(path) 
    125133        end 
    126134 
     
    130138          end 
    131139 
    132140          def add_extension!(path, extension) 
    133             path << ".#{extension}" if extension 
     141            path << ".#{extension}" if extension and !path.ends_with?(extension) 
    134142          end 
    135  
    136           def extract_extension(file_path
     143           
     144          def extract_extension(request
    137145            # Don't want just what comes after the last '.' to accommodate multi part extensions 
    138146            # such as tar.gz. 
    139             file_path[/^[^.]+\.(.+)$/, 1] 
     147            extension = request.path[/^[^.]+\.(.+)$/, 1] 
     148 
     149            # If there's no extension in the path, check request.format 
     150            if extension.nil? 
     151              extension = request.format.to_sym.to_s 
     152              if extension=='all' 
     153                extension = nil 
     154              end 
     155            end 
     156            extension 
    140157          end 
    141158      end 
    142159    end 
  • a/actionpack/test/controller/caching_test.rb

    old new  
    186186    expire_action :controller => 'action_caching_test', :action => 'index' 
    187187    render :nothing => true 
    188188  end 
     189  def expire_xml 
     190    expire_action :controller => 'action_caching_test', :action => 'index', :format => 'xml' 
     191    render :nothing => true 
     192  end 
    189193end 
    190194 
    191195class MockTime < Time 
     
    211215    mocked_path = @mock_path 
    212216    Object.new.instance_eval(<<-EVAL) 
    213217      def path; '#{@mock_path}' end 
     218      def format; 'all' end 
    214219      self 
    215220    EVAL 
    216221  end 
     
    311316    assert_equal new_cached_time, @response.body 
    312317  end 
    313318 
     319  def test_cache_expiration_isnt_affected_by_request_format 
     320    get :index 
     321    cached_time = content_to_cache 
     322    reset! 
     323 
     324    @request.set_REQUEST_URI "/action_caching_test/expire.xml" 
     325    get :expire, :format => :xml 
     326    reset! 
     327 
     328    get :index 
     329    new_cached_time = content_to_cache 
     330    assert_not_equal cached_time, @response.body 
     331  end 
     332 
    314333  def test_cache_is_scoped_by_subdomain 
    315334    @request.host = 'jamis.hostname.com' 
    316335    get :index 
     
    355374  end 
    356375 
    357376  def test_xml_version_of_resource_is_treated_as_different_cache 
    358     @mock_controller.mock_url_for = 'http://example.org/posts/' 
    359     @mock_controller.mock_path    = '/posts/index.xml' 
    360     path_object = @path_class.new(@mock_controller, {}) 
    361     assert_equal 'xml', path_object.extension 
    362     assert_equal 'example.org/posts/index.xml', path_object.path 
     377    with_routing do |set| 
     378      ActionController::Routing::Routes.draw do |map| 
     379        map.connect ':controller/:action.:format' 
     380        map.connect ':controller/:action' 
     381      end 
     382 
     383      get :index, :format => 'xml' 
     384      cached_time = content_to_cache 
     385      assert_equal cached_time, @response.body 
     386      assert fragment_exist?('hostname.com/action_caching_test/index.xml') 
     387      reset! 
     388 
     389      get :index, :format => 'xml' 
     390      assert_equal cached_time, @response.body 
     391      assert_equal 'application/xml', @response.content_type 
     392      reset! 
     393 
     394      @request.env['HTTP_ACCEPT'] = "application/xml" 
     395      get :index 
     396      assert_equal cached_time, @response.body 
     397      assert_equal 'application/xml', @response.content_type 
     398      reset! 
     399 
     400      get :expire_xml 
     401      reset! 
     402 
     403      get :index, :format => 'xml' 
     404      assert_not_equal cached_time, @response.body 
     405    end 
    363406  end 
    364407 
    365408  def test_correct_content_type_is_returned_for_cache_hit