bct (owner)

Revisions

gist: 52666 Download_button fork
public
Public Clone URL: git://gist.github.com/52666.git
Embed All Files: show embed
Diff #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
Index: mimeparse.rb
===================================================================
--- mimeparse.rb (revision 10)
+++ mimeparse.rb (working copy)
@@ -117,6 +117,16 @@
   quality_parsed(mime_type, parsed_ranges)
 end
 
+def _best_match(supported, parsed_header, &comparator)
+ weighted_matches = supported.map do |mime_type|
+ [comparator.call(mime_type, parsed_header), -supported.index(mime_type), mime_type]
+ end
+
+ weighted_matches.sort!
+
+ weighted_matches.last[0][1].zero? ? nil : weighted_matches.last[2]
+end
+
 # Takes a list of supported mime-types and finds the best match
 # for all the media-ranges listed in header. The value of header
 # must be a string that conforms to the format of the HTTP Accept:
@@ -127,15 +137,44 @@
 def best_match(supported, header)
   parsed_header = header.split(",").map { |r| parse_media_range(r) }
 
- weighted_matches = supported.map do |mime_type|
- [fitness_and_quality_parsed(mime_type, parsed_header), mime_type]
+ _best_match(supported, parsed_header) do |thing, parsed_header|
+ fitness_and_quality_parsed(thing, parsed_header)
   end
+end
 
- weighted_matches.sort!
+def encoding_quality(encoding, parsed_header)
+ best_q = 0
+ fitness = -1
 
- weighted_matches.last[0][1].zero? ? nil : weighted_matches.last[1]
+ parsed_header.each do |e,q|
+ if e == '*' and fitness < 0
+ best_q = q
+ fitness = 1
+ elsif e == encoding
+ best_q = q
+ fitness = 1
+ end
+ end
+
+ [fitness, best_q]
 end
+
+def select_best_encoding(supported, parsed_header)
+ return nil if supported.empty?
+
+ match = _best_match(supported, parsed_header) do |thing, parsed_header|
+ encoding_quality(thing, parsed_header)
+ end
+
+ if match.nil?
+ value = encoding_quality('identity', parsed_header)
+ no_identity = (value[0] != -1) and value[1].zero?
+ f = 'identity' unless no_identity
+ else
+ match
+ end
 end
+end
 
 if __FILE__ == $0
   require "test/unit"
@@ -185,9 +224,9 @@
       # direct match of our second choice with a q parameter
       assert_best_match "application/xml", "application/xml; q=1"
       # match using a subtype wildcard
- assert_best_match "application/xml", "application/*; q=1"
+ assert_best_match "application/xbel+xml", "application/*; q=1"
       # match using a type wildcard
- assert_best_match "application/xml", "*/*"
+ assert_best_match "application/xbel+xml", "*/*"
 
       @supported_mime_types = [ "application/xbel+xml", "text/xml" ]
       # match using a type versus a lower weighted subtype
@@ -209,8 +248,40 @@
       assert_best_match 'image/*', 'image/*'
     end
 
+ def test_best_encoding_match
+ @supported_encodings = %w()
+
+ assert_best_encoding nil, [["x", 1]]
+
+ @supported_encodings = %w(identity)
+
+ assert_best_encoding nil, [["identity", 0.0]]
+ assert_best_encoding nil, [["*", 0.0]]
+ assert_best_encoding 'identity', [["compress", 1.0], ["gzip", 1.0]]
+
+ @supported_encodings = %w(compress gzip identity)
+
+ assert_best_encoding 'compress', [['compress', 1.0], ['gzip', 1.0]]
+ assert_best_encoding 'gzip', [['compress', 0.5], ['gzip', 1.0]]
+
+ @supported_encodings = %w(foo bar identity)
+
+ assert_best_encoding 'identity', []
+ assert_best_encoding 'foo', [['*', 1.0]]
+ assert_best_encoding 'bar', [['*', 1.0], ['foo', 0.9]]
+ assert_best_encoding 'identity', [['foo', 0], ['bar', 0]]
+
+ @supported_encodings = %w(foo bar baz identity)
+
+ assert_best_encoding 'identity', [['*', 0], ['identity', 0.1]]
+ end
+
     def assert_best_match(expected, header)
       assert_equal(expected, best_match(@supported_mime_types, header))
     end
+
+ def assert_best_encoding(expected, header)
+ assert_equal(expected, select_best_encoding(@supported_encodings, header))
+ end
   end
 end