diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/http')
-rw-r--r-- | actionpack/lib/action_dispatch/http/mime_negotiation.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/mime_type.rb | 14 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 7 |
3 files changed, 21 insertions, 5 deletions
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb index 498b1e6695..4e81ba12a5 100644 --- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb +++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb @@ -79,6 +79,11 @@ module ActionDispatch else [Mime[:html]] end + + v = v.select do |format| + format.symbol || format.ref == "*/*" + end + set_header k, v end end diff --git a/actionpack/lib/action_dispatch/http/mime_type.rb b/actionpack/lib/action_dispatch/http/mime_type.rb index c3e0ea3c89..88b3a93211 100644 --- a/actionpack/lib/action_dispatch/http/mime_type.rb +++ b/actionpack/lib/action_dispatch/http/mime_type.rb @@ -170,6 +170,7 @@ module Mime def parse(accept_header) if !accept_header.include?(",") accept_header = accept_header.split(PARAMETER_SEPARATOR_REGEXP).first + return [] unless accept_header parse_trailing_star(accept_header) || [Mime::Type.lookup(accept_header)].compact else list, index = [], 0 @@ -221,7 +222,18 @@ module Mime attr_reader :hash + MIME_NAME = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}" + MIME_PARAMETER_KEY = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}" + MIME_PARAMETER_VALUE = "#{Regexp.escape('"')}?[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}#{Regexp.escape('"')}?" + MIME_PARAMETER = "\s*\;\s+#{MIME_PARAMETER_KEY}(?:\=#{MIME_PARAMETER_VALUE})?" + MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?:\s*#{MIME_PARAMETER}\s*)*)\z/ + + class InvalidMimeType < StandardError; end + def initialize(string, symbol = nil, synonyms = []) + unless MIME_REGEXP.match?(string) + raise InvalidMimeType, "#{string.inspect} is not a valid MIME type" + end @symbol, @synonyms = symbol, synonyms @string = string @hash = [@string, @synonyms, @symbol].hash @@ -303,7 +315,7 @@ module Mime include Singleton def initialize - super "*/*", :all + super "*/*", nil end def all?; true; end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 1d38942a31..69798f99e0 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -82,6 +82,7 @@ module ActionDispatch # :nodoc: SET_COOKIE = "Set-Cookie" LOCATION = "Location" NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304] + CONTENT_TYPE_PARSER = /\A(?<type>[^;\s]+)?(?:.*;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?/ # :nodoc: cattr_accessor :default_charset, default: "utf-8" cattr_accessor :default_headers @@ -409,10 +410,8 @@ module ActionDispatch # :nodoc: NullContentTypeHeader = ContentTypeHeader.new nil, nil def parse_content_type(content_type) - if content_type - type, charset = content_type.split(/;\s*charset=/) - type = nil if type && type.empty? - ContentTypeHeader.new(type, charset) + if content_type && match = CONTENT_TYPE_PARSER.match(content_type) + ContentTypeHeader.new(match[:type], match[:charset]) else NullContentTypeHeader end |