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

Changeset 6158

Show
Ignore:
Timestamp:
02/17/07 18:16:44 (1 year ago)
Author:
david
Message:

Added that rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified and the response body will be set to an empty string. [DHH]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r6157 r6158  
    11*SVN* 
     2 
     3* Added that rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified and the response body will be set to an empty string. [DHH] 
    24 
    35* Added X-Runtime to all responses with the request run time [DHH] 
  • trunk/actionpack/lib/action_controller/base.rb

    r6125 r6158  
    88require 'drb' 
    99require 'set' 
     10require 'md5' 
    1011 
    1112module ActionController #:nodoc: 
     
    649650      # <tt>render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {})</tt>. 
    650651      # 
     652      # == Automatic etagging 
     653      # 
     654      # Rendering will automatically insert the etag header on 200 OK responses. The etag is calculated using MD5 of the 
     655      # response body. If a request comes in that has a matching etag, the response will be changed to a 304 Not Modified 
     656      # and the response body will be set to an empty string. 
     657      # 
    651658      # === Rendering a template 
    652659      # 
     
    871878          response.body = text 
    872879        end 
     880 
     881        if response.headers['Status'] == "200 OK" && response.body.size > 0 
     882          response.headers['Etag'] = "\"#{MD5.new(text).to_s}\"" 
     883           
     884          if request.headers['HTTP_IF_NONE_MATCH'] == response.headers['Etag'] 
     885            response.headers['Status'] = "304 Not Modified" 
     886            response.body = '' 
     887          end 
     888        end 
     889         
     890        response.body 
    873891      end 
    874892 
  • trunk/actionpack/lib/action_controller/request.rb

    r6155 r6158  
    5050    def head? 
    5151      @env['REQUEST_METHOD'].downcase.to_sym == :head 
     52    end 
     53 
     54    def headers 
     55      @env 
    5256    end 
    5357 
  • trunk/actionpack/test/controller/render_test.rb

    r6120 r6158  
    6868    @name = "David" 
    6969    render "test/hello" 
     70  end 
     71 
     72  def heading 
     73    head :ok 
    7074  end 
    7175 
     
    287291  end 
    288292 
     293  def test_render_200_should_set_etag 
     294    get :render_hello_world_from_variable 
     295    assert_equal etag_for("hello david"), @response.headers['Etag'] 
     296  end 
     297 
     298  def test_render_against_etag_request_should_304_when_match 
     299    @request.headers["HTTP_IF_NONE_MATCH"] = etag_for("hello david") 
     300    get :render_hello_world_from_variable 
     301    assert_equal "304 Not Modified", @response.headers['Status'] 
     302    assert @response.body.empty? 
     303  end 
     304 
     305  def test_render_against_etag_request_should_200_when_no_match 
     306    @request.headers["HTTP_IF_NONE_MATCH"] = etag_for("hello somewhere else") 
     307    get :render_hello_world_from_variable 
     308    assert_equal "200 OK", @response.headers['Status'] 
     309    assert !@response.body.empty? 
     310  end 
     311 
     312  def test_render_with_etag 
     313    get :render_hello_world_from_variable 
     314    expected_etag = "\"#{MD5.new("hello david").to_s}\"" 
     315    assert_equal expected_etag, @response.headers['Etag'] 
     316     
     317    @request.headers["HTTP_IF_NONE_MATCH"] = expected_etag 
     318    get :render_hello_world_from_variable 
     319    assert_equal "304 Not Modified", @response.headers['Status'] 
     320     
     321    @request.headers["HTTP_IF_NONE_MATCH"] = "\"diftag\"" 
     322    get :render_hello_world_from_variable 
     323    assert_equal "200 OK", @response.headers['Status'] 
     324  end 
     325 
     326  def render_with_404_shouldnt_have_etag 
     327    get :render_custom_code 
     328    assert_nil @response.headers['Etag'] 
     329  end 
     330 
    289331  protected 
    290332    def assert_deprecated_render(&block) 
    291333      assert_deprecated(/render/, &block) 
    292334    end 
     335     
     336    def etag_for(text) 
     337      "\"#{MD5.new(text).to_s}\"" 
     338    end 
    293339end