diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/http/response.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 1515d59df3..516a2af69a 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -1,7 +1,7 @@ -require 'active_support/core_ext/module/attribute_accessors' -require 'action_dispatch/http/filter_redirect' -require 'action_dispatch/http/cache' -require 'monitor' +require "active_support/core_ext/module/attribute_accessors" +require "action_dispatch/http/filter_redirect" +require "action_dispatch/http/cache" +require "monitor" module ActionDispatch # :nodoc: # Represents an HTTP response generated by a controller action. Use it to @@ -39,9 +39,9 @@ module ActionDispatch # :nodoc: super(header) end - def []=(k,v) + def []=(k, v) if @response.sending? || @response.sent? - raise ActionDispatch::IllegalStateError, 'header already sent' + raise ActionDispatch::IllegalStateError, "header already sent" end super @@ -67,7 +67,7 @@ module ActionDispatch # :nodoc: alias_method :headers, :header - delegate :[], :[]=, :to => :@header + delegate :[], :[]=, to: :@header def each(&block) sending! @@ -103,8 +103,8 @@ module ActionDispatch # :nodoc: def body @str_body ||= begin - buf = '' - each { |chunk| buf << chunk } + buf = "" + each { |chunk| buf << chunk } buf end end @@ -224,8 +224,12 @@ module ActionDispatch # :nodoc: # Sets the HTTP content type. def content_type=(content_type) - header_info = parse_content_type - set_content_type content_type.to_s, header_info.charset || self.class.default_charset + return unless content_type + new_header_info = parse_content_type(content_type.to_s) + prev_header_info = parsed_content_type_header + charset = new_header_info.charset || prev_header_info.charset + charset ||= self.class.default_charset unless prev_header_info.mime_type + set_content_type new_header_info.mime_type, charset end # Sets the HTTP response's content MIME type. For example, in the controller @@ -238,7 +242,7 @@ module ActionDispatch # :nodoc: # information. def content_type - parse_content_type.mime_type + parsed_content_type_header.mime_type end def sending_file=(v) @@ -247,13 +251,13 @@ module ActionDispatch # :nodoc: end end - # Sets the HTTP character set. In case of nil parameter + # Sets the HTTP character set. In case of +nil+ parameter # it sets the charset to utf-8. # # response.charset = 'utf-16' # => 'utf-16' # response.charset = nil # => 'utf-8' def charset=(charset) - header_info = parse_content_type + header_info = parsed_content_type_header if false == charset set_header CONTENT_TYPE, header_info.mime_type else @@ -265,7 +269,7 @@ module ActionDispatch # :nodoc: # 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 + header_info = parsed_content_type_header header_info.charset || self.class.default_charset end @@ -329,7 +333,7 @@ module ActionDispatch # :nodoc: # Stream the file's contents if Rack::Sendfile isn't present. def each - File.open(to_path, 'rb') do |file| + File.open(to_path, "rb") do |file| while chunk = file.read(16384) yield chunk end @@ -389,7 +393,7 @@ module ActionDispatch # :nodoc: if header = get_header(SET_COOKIE) header = header.split("\n") if header.respond_to?(:to_str) header.each do |cookie| - if pair = cookie.split(';').first + if pair = cookie.split(";").first key, value = pair.split("=").map { |v| Rack::Utils.unescape(v) } cookies[key] = value end @@ -403,19 +407,24 @@ module ActionDispatch # :nodoc: ContentTypeHeader = Struct.new :mime_type, :charset NullContentTypeHeader = ContentTypeHeader.new nil, nil - def parse_content_type - content_type = get_header CONTENT_TYPE + def parse_content_type(content_type) if content_type type, charset = content_type.split(/;\s*charset=/) - type = nil if type.empty? + type = nil if type && type.empty? ContentTypeHeader.new(type, charset) else NullContentTypeHeader end end + # Small internal convenience method to get the parsed version of the current + # content type header. + def parsed_content_type_header + parse_content_type(get_header(CONTENT_TYPE)) + end + def set_content_type(content_type, charset) - type = (content_type || '').dup + type = (content_type || "").dup type << "; charset=#{charset}" if charset set_header CONTENT_TYPE, type end @@ -450,7 +459,7 @@ module ActionDispatch # :nodoc: def assign_default_content_type_and_charset! return if content_type - ct = parse_content_type + ct = parsed_content_type_header set_content_type(ct.mime_type || Mime[:html].to_s, ct.charset || self.class.default_charset) end @@ -475,7 +484,7 @@ module ActionDispatch # :nodoc: end def respond_to?(method, include_private = false) - if method.to_s == 'to_path' + if method.to_s == "to_path" @response.stream.respond_to?(method) else super @@ -494,7 +503,7 @@ module ActionDispatch # :nodoc: def handle_no_content! if NO_CONTENT_CODES.include?(@status) @header.delete CONTENT_TYPE - @header.delete 'Content-Length' + @header.delete "Content-Length" end end |