Changeset 3917
- Timestamp:
- 03/18/06 06:15:28 (2 years ago)
- Files:
-
- trunk/actionpack/CHANGELOG (modified) (1 diff)
- trunk/actionpack/lib/action_controller/mime_type.rb (modified) (2 diffs)
- trunk/actionpack/test/controller/mime_type_test.rb (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/actionpack/CHANGELOG
r3915 r3917 1 1 *SVN* 2 3 * Make Mime::Type.parse consider q values (if any) [Jamis Buck] 2 4 3 5 * XML-formatted requests are typecast according to "type" attributes for :xml_simple [Jamis Buck] trunk/actionpack/lib/action_controller/mime_type.rb
r3873 r3917 1 1 module Mime 2 2 class Type 3 4 # A simple helper class used in parsing the accept header 5 class AcceptItem #:nodoc: 6 attr_accessor :order, :name, :q 7 8 def initialize(order, name, q=nil) 9 @order = order 10 @name = name.strip 11 q ||= 0.0 if @name == "*/*" # default "*/*" to end of list 12 @q = ((q || 1.0).to_f * 100).to_i 13 end 14 15 def to_s 16 @name 17 end 18 19 def <=>(item) 20 result = item.q <=> q 21 result = order <=> item.order if result == 0 22 result 23 end 24 25 def ==(item) 26 name == (item.respond_to?(:name) ? item.name : item) 27 end 28 end 29 3 30 class << self 4 31 def lookup(string) … … 7 34 8 35 def parse(accept_header) 9 mime_types = accept_header.split(",").collect! do |mime_type| 10 mime_type.split(";").first.strip 36 # keep track of creation order to keep the subsequent sort stable 37 index = 0 38 list = accept_header.split(/,/). 39 map! { |i| AcceptItem.new(index += 1, *i.split(/;\s*q=/)) }.sort! 40 41 # Take care of the broken text/xml entry by renaming or deleting it 42 43 text_xml = list.index("text/xml") 44 app_xml = list.index("application/xml") 45 46 if text_xml && app_xml 47 # set the q value to the max of the two 48 list[app_xml].q = [list[text_xml].q, list[app_xml].q].max 49 50 # make sure app_xml is ahead of text_xml in the list 51 if app_xml > text_xml 52 list[app_xml], list[text_xml] = list[text_xml], list[app_xml] 53 app_xml, text_xml = text_xml, app_xml 54 end 55 56 # delete text_xml from the list 57 list.delete_at(text_xml) 58 59 elsif text_xml 60 list[text_xml].name = "application/xml" 11 61 end 12 62 13 reorder_xml_types!(mime_types) 14 mime_types.collect! { |mime_type| Mime::Type.lookup(mime_type) } 15 end 16 17 private 18 def reorder_xml_types!(mime_types) 19 mime_types.delete("text/xml") if mime_types.include?("application/xml") 63 # Look for more specific xml-based types and sort them ahead of app/xml 20 64 21 if index_for_generic_xml = mime_types.index("application/xml") 22 specific_xml_types = mime_types[index_for_generic_xml..-1].grep(/application\/[a-z]*\+xml/) 65 if app_xml 66 idx = app_xml 67 app_xml_type = list[app_xml] 23 68 24 for specific_xml_type in specific_xml_types.reverse 25 mime_types.insert(index_for_generic_xml, mime_types.delete(specific_xml_type)) 69 while(idx < list.length) 70 type = list[idx] 71 break if type.q < app_xml_type.q 72 if type.name =~ /\+xml$/ 73 list[app_xml], list[idx] = list[idx], list[app_xml] 74 app_xml = idx 26 75 end 76 idx += 1 27 77 end 28 78 end 79 80 list.map! { |i| Mime::Type.lookup(i.name) }.uniq! 81 list 82 end 29 83 end 30 84