| 1 |
module Mime |
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
class Type |
|---|
| 16 |
|
|---|
| 17 |
class AcceptItem |
|---|
| 18 |
attr_accessor :order, :name, :q |
|---|
| 19 |
|
|---|
| 20 |
def initialize(order, name, q=nil) |
|---|
| 21 |
@order = order |
|---|
| 22 |
@name = name.strip |
|---|
| 23 |
q ||= 0.0 if @name == "*/*" |
|---|
| 24 |
@q = ((q || 1.0).to_f * 100).to_i |
|---|
| 25 |
end |
|---|
| 26 |
|
|---|
| 27 |
def to_s |
|---|
| 28 |
@name |
|---|
| 29 |
end |
|---|
| 30 |
|
|---|
| 31 |
def <=>(item) |
|---|
| 32 |
result = item.q <=> q |
|---|
| 33 |
result = order <=> item.order if result == 0 |
|---|
| 34 |
result |
|---|
| 35 |
end |
|---|
| 36 |
|
|---|
| 37 |
def ==(item) |
|---|
| 38 |
name == (item.respond_to?(:name) ? item.name : item) |
|---|
| 39 |
end |
|---|
| 40 |
end |
|---|
| 41 |
|
|---|
| 42 |
class << self |
|---|
| 43 |
def lookup(string) |
|---|
| 44 |
LOOKUP[string] |
|---|
| 45 |
end |
|---|
| 46 |
|
|---|
| 47 |
def register(string, symbol, synonyms = []) |
|---|
| 48 |
Mime.send :const_set, symbol.to_s.upcase, Type.new(string, symbol, synonyms) |
|---|
| 49 |
SET << Mime.send(:const_get, symbol.to_s.upcase) |
|---|
| 50 |
LOOKUP[string] = EXTENSION_LOOKUP[symbol.to_s] = SET.last |
|---|
| 51 |
end |
|---|
| 52 |
|
|---|
| 53 |
def parse(accept_header) |
|---|
| 54 |
|
|---|
| 55 |
index = 0 |
|---|
| 56 |
list = accept_header.split(/,/).map! do |i| |
|---|
| 57 |
AcceptItem.new(index += 1, *i.split(/;\s*q=/)) |
|---|
| 58 |
end.sort! |
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
text_xml = list.index("text/xml") |
|---|
| 62 |
app_xml = list.index("application/xml") |
|---|
| 63 |
|
|---|
| 64 |
if text_xml && app_xml |
|---|
| 65 |
|
|---|
| 66 |
list[app_xml].q = [list[text_xml].q, list[app_xml].q].max |
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 |
if app_xml > text_xml |
|---|
| 70 |
list[app_xml], list[text_xml] = list[text_xml], list[app_xml] |
|---|
| 71 |
app_xml, text_xml = text_xml, app_xml |
|---|
| 72 |
end |
|---|
| 73 |
|
|---|
| 74 |
|
|---|
| 75 |
list.delete_at(text_xml) |
|---|
| 76 |
|
|---|
| 77 |
elsif text_xml |
|---|
| 78 |
list[text_xml].name = "application/xml" |
|---|
| 79 |
end |
|---|
| 80 |
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
if app_xml |
|---|
| 84 |
idx = app_xml |
|---|
| 85 |
app_xml_type = list[app_xml] |
|---|
| 86 |
|
|---|
| 87 |
while(idx < list.length) |
|---|
| 88 |
type = list[idx] |
|---|
| 89 |
break if type.q < app_xml_type.q |
|---|
| 90 |
if type.name =~ /\+xml$/ |
|---|
| 91 |
list[app_xml], list[idx] = list[idx], list[app_xml] |
|---|
| 92 |
app_xml = idx |
|---|
| 93 |
end |
|---|
| 94 |
idx += 1 |
|---|
| 95 |
end |
|---|
| 96 |
end |
|---|
| 97 |
|
|---|
| 98 |
list.map! { |i| Mime::Type.lookup(i.name) }.uniq! |
|---|
| 99 |
list |
|---|
| 100 |
end |
|---|
| 101 |
end |
|---|
| 102 |
|
|---|
| 103 |
def initialize(string, symbol = nil, synonyms = []) |
|---|
| 104 |
@symbol, @synonyms = symbol, synonyms |
|---|
| 105 |
@string = string |
|---|
| 106 |
end |
|---|
| 107 |
|
|---|
| 108 |
def to_s |
|---|
| 109 |
@string |
|---|
| 110 |
end |
|---|
| 111 |
|
|---|
| 112 |
def to_str |
|---|
| 113 |
to_s |
|---|
| 114 |
end |
|---|
| 115 |
|
|---|
| 116 |
def to_sym |
|---|
| 117 |
@symbol || @string.to_sym |
|---|
| 118 |
end |
|---|
| 119 |
|
|---|
| 120 |
def ===(list) |
|---|
| 121 |
if list.is_a?(Array) |
|---|
| 122 |
(@synonyms + [ self ]).any? { |synonym| list.include?(synonym) } |
|---|
| 123 |
else |
|---|
| 124 |
super |
|---|
| 125 |
end |
|---|
| 126 |
end |
|---|
| 127 |
|
|---|
| 128 |
def ==(mime_type) |
|---|
| 129 |
(@synonyms + [ self ]).any? { |synonym| synonym.to_s == mime_type.to_s } if mime_type |
|---|
| 130 |
end |
|---|
| 131 |
end |
|---|
| 132 |
|
|---|
| 133 |
ALL = Type.new "*/*", :all |
|---|
| 134 |
TEXT = Type.new "text/plain", :text |
|---|
| 135 |
HTML = Type.new "text/html", :html, %w( application/xhtml+xml ) |
|---|
| 136 |
JS = Type.new "text/javascript", :js, %w( application/javascript application/x-javascript ) |
|---|
| 137 |
ICS = Type.new "text/calendar", :ics |
|---|
| 138 |
CSV = Type.new "text/csv", :csv |
|---|
| 139 |
XML = Type.new "application/xml", :xml, %w( text/xml application/x-xml ) |
|---|
| 140 |
RSS = Type.new "application/rss+xml", :rss |
|---|
| 141 |
ATOM = Type.new "application/atom+xml", :atom |
|---|
| 142 |
YAML = Type.new "application/x-yaml", :yaml, %w( text/yaml ) |
|---|
| 143 |
JSON = Type.new "application/json", :json, %w( text/x-json ) |
|---|
| 144 |
|
|---|
| 145 |
SET = [ ALL, TEXT, HTML, JS, ICS, XML, RSS, ATOM, YAML, JSON ] |
|---|
| 146 |
|
|---|
| 147 |
LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k == "" } |
|---|
| 148 |
|
|---|
| 149 |
LOOKUP["*/*"] = ALL |
|---|
| 150 |
|
|---|
| 151 |
LOOKUP["text/plain"] = TEXT |
|---|
| 152 |
|
|---|
| 153 |
LOOKUP["text/html"] = HTML |
|---|
| 154 |
LOOKUP["application/xhtml+xml"] = HTML |
|---|
| 155 |
|
|---|
| 156 |
LOOKUP["text/javascript"] = JS |
|---|
| 157 |
LOOKUP["application/javascript"] = JS |
|---|
| 158 |
LOOKUP["application/x-javascript"] = JS |
|---|
| 159 |
|
|---|
| 160 |
LOOKUP["text/calendar"] = ICS |
|---|
| 161 |
|
|---|
| 162 |
LOOKUP["text/csv"] = CSV |
|---|
| 163 |
|
|---|
| 164 |
LOOKUP["application/xml"] = XML |
|---|
| 165 |
LOOKUP["text/xml"] = XML |
|---|
| 166 |
LOOKUP["application/x-xml"] = XML |
|---|
| 167 |
|
|---|
| 168 |
LOOKUP["text/yaml"] = YAML |
|---|
| 169 |
LOOKUP["application/x-yaml"] = YAML |
|---|
| 170 |
|
|---|
| 171 |
LOOKUP["application/rss+xml"] = RSS |
|---|
| 172 |
LOOKUP["application/atom+xml"] = ATOM |
|---|
| 173 |
|
|---|
| 174 |
LOOKUP["application/json"] = JSON |
|---|
| 175 |
LOOKUP["text/x-json"] = JSON |
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 |
EXTENSION_LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k == "" } |
|---|
| 179 |
|
|---|
| 180 |
EXTENSION_LOOKUP["html"] = HTML |
|---|
| 181 |
EXTENSION_LOOKUP["xhtml"] = HTML |
|---|
| 182 |
|
|---|
| 183 |
EXTENSION_LOOKUP["txt"] = TEXT |
|---|
| 184 |
|
|---|
| 185 |
EXTENSION_LOOKUP["xml"] = XML |
|---|
| 186 |
|
|---|
| 187 |
EXTENSION_LOOKUP["js"] = JS |
|---|
| 188 |
|
|---|
| 189 |
EXTENSION_LOOKUP["ics"] = ICS |
|---|
| 190 |
|
|---|
| 191 |
EXTENSION_LOOKUP["csv"] = CSV |
|---|
| 192 |
|
|---|
| 193 |
EXTENSION_LOOKUP["yml"] = YAML |
|---|
| 194 |
EXTENSION_LOOKUP["yaml"] = YAML |
|---|
| 195 |
|
|---|
| 196 |
EXTENSION_LOOKUP["rss"] = RSS |
|---|
| 197 |
EXTENSION_LOOKUP["atom"] = ATOM |
|---|
| 198 |
|
|---|
| 199 |
EXTENSION_LOOKUP["json"] = JSON |
|---|
| 200 |
end |
|---|