diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2015-09-08 15:05:19 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2015-09-08 16:14:47 -0700 |
commit | 1cc315c83c6d823a6041361bf468b82c541d31ee (patch) | |
tree | e2ed67649ccaba53e0c10160cfa0f1e822594cda /actionpack/lib | |
parent | 25791b46dc48bec4375a8953d9b2def52761e237 (diff) | |
download | rails-1cc315c83c6d823a6041361bf468b82c541d31ee.tar.gz rails-1cc315c83c6d823a6041361bf468b82c541d31ee.tar.bz2 rails-1cc315c83c6d823a6041361bf468b82c541d31ee.zip |
make Content-Type header the canonical location for content-type info
Instead of storing content type information in an ivar and a header,
lets move to just store the content type info in just the header.
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 84 |
1 files changed, 50 insertions, 34 deletions
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index e841db77b6..74aa109b5b 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -38,8 +38,6 @@ module ActionDispatch # :nodoc: # The HTTP status code. attr_reader :status - attr_writer :sending_file - # Get headers for this response. attr_reader :header @@ -48,20 +46,6 @@ module ActionDispatch # :nodoc: delegate :[], :[]=, :to => :@header delegate :each, :to => :@stream - # Sets the HTTP response's content MIME type. For example, in the controller - # you could write this: - # - # response.content_type = "text/plain" - # - # If a character set has been defined for this response (see charset=) then - # the character set information will also be included in the content type - # information. - attr_reader :content_type - - # The charset of the response. HTML wants to know the encoding of the - # content you're giving them, so we need to send that along. - attr_reader :charset - CONTENT_TYPE = "Content-Type".freeze SET_COOKIE = "Set-Cookie".freeze LOCATION = "Location".freeze @@ -130,31 +114,39 @@ module ActionDispatch # :nodoc: self.body, self.status = body, status - @sending_file = false @blank = false @cv = new_cond @committed = false @sending = false @sent = false - content_type = parse_content_type self[CONTENT_TYPE] - @content_type = content_type.mime_type - @charset = content_type.charset - prepare_cache_control! yield self if block_given? end + # Sets the HTTP response's content MIME type. For example, in the controller + # you could write this: + # + # response.content_type = "text/plain" + # + # If a character set has been defined for this response (see charset=) then + # the character set information will also be included in the content type + # information. + + def content_type + type = parse_content_type(self[CONTENT_TYPE]).mime_type + type && type.to_s + end + ContentTypeHeader = Struct.new :mime_type, :charset def parse_content_type(content_type) if content_type type, charset = content_type.split(/;\s*charset=/) - ContentTypeHeader.new(Mime::Type.lookup(type), - charset || self.class.default_charset) + ContentTypeHeader.new(Mime::Type.lookup(type), charset) else - ContentTypeHeader.new(nil, self.class.default_charset) + ContentTypeHeader.new(nil, nil) end end @@ -207,7 +199,25 @@ module ActionDispatch # :nodoc: # Sets the HTTP content type. def content_type=(content_type) - @content_type = content_type.to_s + header_info = parse_content_type(get_header(CONTENT_TYPE)) + type = content_type.to_s.dup + type << "; charset=#{header_info.charset || self.class.default_charset}" + + set_header CONTENT_TYPE, type + end + + # The charset of the response. HTML wants to know the encoding of the + # content you're giving them, so we need to send that along. + + def charset + header_info = parse_content_type(get_header(CONTENT_TYPE)) + header_info.charset || self.class.default_charset + end + + def sending_file=(v) + if true == v + self.charset = false + end end # Sets the HTTP character set. In case of nil parameter @@ -216,7 +226,16 @@ module ActionDispatch # :nodoc: # response.charset = 'utf-16' # => 'utf-16' # response.charset = nil # => 'utf-8' def charset=(charset) - @charset = charset.nil? ? self.class.default_charset : charset + header_info = parse_content_type(get_header(CONTENT_TYPE)) + charset = charset.nil? ? self.class.default_charset : charset + if false == charset + set_header CONTENT_TYPE, header_info.mime_type.to_s + else + content_type = header_info.mime_type || Mime::TEXT + type = content_type.to_s.dup + type << "; charset=#{charset}" + set_header CONTENT_TYPE, type + end end # The response code of the request. @@ -340,18 +359,15 @@ module ActionDispatch # :nodoc: def assign_default_content_type_and_charset! return if get_header(CONTENT_TYPE).present? - @content_type ||= Mime::HTML - - type = @content_type.to_s.dup - type << "; charset=#{charset}" if append_charset? + ct = parse_content_type get_header(CONTENT_TYPE) + content_type = ct.mime_type || Mime::HTML + charset = ct.charset || self.class.default_charset + type = content_type.to_s.dup + type << "; charset=#{charset}" set_header CONTENT_TYPE, type end - def append_charset? - !@sending_file && @charset != false - end - class RackBody def initialize(response) @response = response |