diff options
Diffstat (limited to 'actionpack/lib/action_controller/response.rb')
-rw-r--r--[-rwxr-xr-x] | actionpack/lib/action_controller/response.rb | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index 8f2672425f..da352b6993 100755..100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -32,7 +32,7 @@ module ActionController # :nodoc: class AbstractResponse DEFAULT_HEADERS = { "Cache-Control" => "no-cache" } attr_accessor :request - + # The body content (e.g. HTML) of the response, as a String. attr_accessor :body # The headers of the response, as a Hash. It maps header names to header values. @@ -83,20 +83,48 @@ module ActionController # :nodoc: set_content_length! end + # Sets the Last-Modified response header. Returns whether it's older than + # the If-Modified-Since request header. + def last_modified!(utc_time) + headers['Last-Modified'] ||= utc_time.httpdate + if request && since = request.headers['HTTP_IF_MODIFIED_SINCE'] + utc_time <= Time.rfc2822(since) + end + end + + # Sets the ETag response header. Returns whether it matches the + # If-None-Match request header. + def etag!(tag) + headers['ETag'] ||= %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(tag))}") + if request && request.headers['HTTP_IF_NONE_MATCH'] == headers['ETag'] + true + end + end private def handle_conditional_get! - if body.is_a?(String) && (headers['Status'] ? headers['Status'][0..2] == '200' : true) && !body.empty? - self.headers['ETag'] ||= %("#{Digest::MD5.hexdigest(body)}") - self.headers['Cache-Control'] = 'private, max-age=0, must-revalidate' if headers['Cache-Control'] == DEFAULT_HEADERS['Cache-Control'] + if nonempty_ok_response? + set_conditional_cache_control! - if request.headers['HTTP_IF_NONE_MATCH'] == headers['ETag'] - self.headers['Status'] = '304 Not Modified' + if etag!(body) + headers['Status'] = '304 Not Modified' self.body = '' end end end + def nonempty_ok_response? + status = headers['Status'] + ok = !status || status[0..2] == '200' + ok && body.is_a?(String) && !body.empty? + end + + def set_conditional_cache_control! + if headers['Cache-Control'] == DEFAULT_HEADERS['Cache-Control'] + headers['Cache-Control'] = 'private, max-age=0, must-revalidate' + end + end + def convert_content_type! if content_type = headers.delete("Content-Type") self.headers["type"] = content_type |