Permalink
Browse files

Fix for requests made with accepts text/*

This area of code has been improved a good deal in rails/master but these changes have not been
backported to rails/2-3-stable.

This is a partial backport of the changes that can be found here
rails@c937ddb...21fd93c

There is further discussion on
https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/6022-content-negotiation-fails-for-some-headers-regression#ticket-6022-18
  • Loading branch information...
1 parent 222e3e9 commit 9749e6e5a3c8fb5e87e4cc4b32134b1a06f1426d @mocoso mocoso committed with jongilbraith Feb 7, 2011
Showing with 34 additions and 10 deletions.
  1. +28 −10 actionpack/lib/action_controller/mime_type.rb
  2. +6 −0 actionpack/test/controller/mime_type_test.rb
View
38 actionpack/lib/action_controller/mime_type.rb
@@ -62,6 +62,8 @@ def ==(item)
end
class << self
+ TRAILING_STAR_REGEXP = /(text|application)\/\*/
+
def lookup(string)
LOOKUP[string]
end
@@ -87,14 +89,20 @@ def register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], s
def parse(accept_header)
if accept_header !~ /,/
- [Mime::Type.lookup(accept_header.split(';').first)]
+ param = accept_header.split(';').first
+ if param =~ TRAILING_STAR_REGEXP
+ parse_data_with_trailing_star($1)
+ else
+ [Mime::Type.lookup(param)]
+ end
+
else
# keep track of creation order to keep the subsequent sort stable
list = []
- accept_header.split(/,/).each_with_index do |header, index|
- params, q = header.split(/;\s*q=/)
+ accept_header.split(/,/).each_with_index do |header, index|
+ params, q = header.split(/;\s*q=/)
if params
- params.strip!
+ params.strip!
list << AcceptItem.new(index, params, q) unless params.empty?
end
end
@@ -142,21 +150,31 @@ def parse(accept_header)
list
end
end
+
+ # input: 'text'
+ # returned value: [Mime::JSON, Mime::XML, Mime::ICS, Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]
+ #
+ # input: 'application'
+ # returned value: [Mime::HTML, Mime::JS, Mime::XML, Mime::YAML, Mime::ATOM, Mime::JSON, Mime::RSS, Mime::URL_ENCODED_FORM
+ def parse_data_with_trailing_star(input)
+ keys = LOOKUP.keys.select{|k| k.include?(input)}
+ LOOKUP.values_at(*keys).uniq
+ end
end
def initialize(string, symbol = nil, synonyms = [])
@symbol, @synonyms = symbol, synonyms
@string = string
end
-
+
def to_s
@string
end
-
+
def to_str
to_s
end
-
+
def to_sym
@symbol || @string.to_sym
end
@@ -168,11 +186,11 @@ def ===(list)
super
end
end
-
+
def ==(mime_type)
return false if mime_type.blank?
- (@synonyms + [ self ]).any? do |synonym|
- synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
+ (@synonyms + [ self ]).any? do |synonym|
+ synonym.to_s == mime_type.to_s || synonym.to_sym == mime_type.to_sym
end
end
View
6 actionpack/test/controller/mime_type_test.rb
@@ -16,6 +16,12 @@ def test_parse_without_q
assert_equal expect, Mime::Type.parse(accept)
end
+ def test_parse_with_text_star
+ accept = "text/*"
+ expect = [Mime::JSON, Mime::XML, Mime::ICS, Mime::HTML, Mime::CSS, Mime::CSV, Mime::JS, Mime::YAML, Mime::TEXT]
+ assert_equal expect, Mime::Type.parse(accept)
+ end
+
def test_parse_with_q
accept = "text/xml,application/xhtml+xml,text/yaml; q=0.3,application/xml,text/html; q=0.8,image/png,text/plain; q=0.5,application/pdf,*/*; q=0.2"
expect = [Mime::HTML, Mime::XML, Mime::PNG, Mime::PDF, Mime::TEXT, Mime::YAML, Mime::ALL]

0 comments on commit 9749e6e

Please sign in to comment.