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

Changeset 6165

Show
Ignore:
Timestamp:
02/19/07 00:27:19 (1 year ago)
Author:
david
Message:

Move etagging down to response, so renders with layouts dont screw it up [DHH]

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/lib/action_controller/base.rb

    r6164 r6165  
    88require 'drb' 
    99require 'set' 
    10 require 'digest/md5' 
    1110 
    1211module ActionController #:nodoc: 
     
    475474 
    476475        assign_default_content_type_and_charset 
     476 
     477        response.request = request 
     478        response.prepare! 
    477479        response 
    478480      ensure 
     
    877879        else 
    878880          response.body = text 
    879  
    880           if text.is_a?(String) 
    881             if response.headers['Status'][0..2] == '200' && !response.body.empty? 
    882               response.headers['Etag'] = %("#{Digest::MD5.hexdigest(text)}") 
    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           end 
    890         end 
    891  
    892         response.body 
     881        end 
    893882      end 
    894883 
  • trunk/actionpack/lib/action_controller/cgi_process.rb

    r6143 r6165  
    185185 
    186186    def out(output = $stdout) 
    187       convert_content_type! 
    188       set_content_length! 
    189  
    190187      output.binmode      if output.respond_to?(:binmode) 
    191188      output.sync = false if output.respond_to?(:sync=) 
     
    210207      end 
    211208    end 
    212  
    213     private 
    214       def convert_content_type! 
    215         if content_type = @headers.delete("Content-Type") 
    216           @headers["type"] = content_type 
    217         end 
    218         if content_type = @headers.delete("Content-type") 
    219           @headers["type"] = content_type 
    220         end 
    221         if content_type = @headers.delete("content-type") 
    222           @headers["type"] = content_type 
    223         end 
    224       end 
    225        
    226       # Don't set the Content-Length for block-based bodies as that would mean reading it all into memory. Not nice 
    227       # for, say, a 2GB streaming file. 
    228       def set_content_length! 
    229         @headers["Content-Length"] = @body.size unless @body.respond_to?(:call) 
    230       end 
    231209  end 
    232210end 
  • trunk/actionpack/lib/action_controller/response.rb

    r5634 r6165  
     1require 'digest/md5' 
     2 
    13module ActionController 
    24  class AbstractResponse #:nodoc: 
    35    DEFAULT_HEADERS = { "Cache-Control" => "no-cache" } 
     6    attr_accessor :request 
    47    attr_accessor :body, :headers, :session, :cookies, :assigns, :template, :redirected_to, :redirected_to_method_params, :layout 
    58 
     
    912 
    1013    def content_type=(mime_type) 
    11       @headers["Content-Type"] = charset ? "#{mime_type}; charset=#{charset}" : mime_type 
     14      self.headers["Content-Type"] = charset ? "#{mime_type}; charset=#{charset}" : mime_type 
    1215    end 
    1316     
    1417    def content_type 
    15       content_type = String(@headers["Content-Type"]).split(";")[0] 
     18      content_type = String(headers["Content-Type"] || headers["type"]).split(";")[0] 
    1619      content_type.blank? ? nil : content_type 
    1720    end 
    1821     
    1922    def charset=(encoding) 
    20       @headers["Content-Type"] = "#{content_type || "text/html"}; charset=#{encoding}" 
     23      self.headers["Content-Type"] = "#{content_type || "text/html"}; charset=#{encoding}" 
    2124    end 
    2225     
    2326    def charset 
    24       charset = String(@headers["Content-Type"]).split(";")[1] 
     27      charset = String(headers["Content-Type"] || headers["type"]).split(";")[1] 
    2528      charset.blank? ? nil : charset.strip.split("=")[1] 
    2629    end 
    2730 
    2831    def redirect(to_url, permanently = false) 
    29       @headers["Status"]   = "302 Found" unless @headers["Status"] == "301 Moved Permanently" 
    30       @headers["Location"] = to_url 
     32      self.headers["Status"]   = "302 Found" unless headers["Status"] == "301 Moved Permanently" 
     33      self.headers["Location"] = to_url 
    3134 
    32       @body = "<html><body>You are being <a href=\"#{to_url}\">redirected</a>.</body></html>" 
     35      self.body = "<html><body>You are being <a href=\"#{to_url}\">redirected</a>.</body></html>" 
    3336    end 
     37 
     38    def prepare! 
     39      handle_conditional_get! 
     40      convert_content_type! 
     41      set_content_length! 
     42    end 
     43 
     44    private 
     45      def handle_conditional_get! 
     46        if body.is_a?(String) && headers['Status'][0..2] == '200' && !body.empty? 
     47          self.headers['Etag'] ||= %("#{Digest::MD5.hexdigest(body)}") 
     48 
     49          if request.headers['HTTP_IF_NONE_MATCH'] == headers['Etag'] 
     50            self.headers['Status'] = '304 Not Modified' 
     51            self.body = '' 
     52          end 
     53        end 
     54      end 
     55 
     56      def convert_content_type! 
     57        if content_type = headers.delete("Content-Type") 
     58          self.headers["type"] = content_type 
     59        end 
     60        if content_type = headers.delete("Content-type") 
     61          self.headers["type"] = content_type 
     62        end 
     63        if content_type = headers.delete("content-type") 
     64          self.headers["type"] = content_type 
     65        end 
     66      end 
     67     
     68      # Don't set the Content-Length for block-based bodies as that would mean reading it all into memory. Not nice 
     69      # for, say, a 2GB streaming file. 
     70      def set_content_length! 
     71        self.headers["Content-Length"] = body.size unless body.respond_to?(:call) 
     72      end 
    3473  end 
    3574end 
  • trunk/actionpack/test/controller/render_test.rb

    r6164 r6165  
    338338  def test_etag_should_govern_renders_with_layouts_too 
    339339    get :builder_layout_test 
     340    assert_equal "<wrapper>\n<html>\n  <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n", @response.body 
    340341    assert_equal etag_for("<wrapper>\n<html>\n  <p>Hello </p>\n<p>This is grand!</p>\n</html>\n</wrapper>\n"), @response.headers['Etag'] 
    341342  end