accept_headers 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/Gemfile +2 -2
- data/README.md +86 -31
- data/accept_headers.gemspec +2 -2
- data/lib/accept_headers.rb +4 -0
- data/lib/accept_headers/acceptable.rb +4 -28
- data/lib/accept_headers/charset.rb +7 -15
- data/lib/accept_headers/charset/negotiator.rb +27 -0
- data/lib/accept_headers/encoding.rb +7 -15
- data/lib/accept_headers/encoding/negotiator.rb +27 -0
- data/lib/accept_headers/language.rb +9 -25
- data/lib/accept_headers/language/negotiator.rb +37 -0
- data/lib/accept_headers/media_type.rb +9 -38
- data/lib/accept_headers/media_type/negotiator.rb +50 -0
- data/lib/accept_headers/negotiatable.rb +54 -0
- data/lib/accept_headers/version.rb +1 -1
- data/spec/charset/negotiator_spec.rb +73 -0
- data/spec/charset_spec.rb +4 -58
- data/spec/encoding/negotiator_spec.rb +73 -0
- data/spec/encoding_spec.rb +4 -58
- data/spec/language/negotiator_spec.rb +78 -0
- data/spec/language_spec.rb +4 -63
- data/spec/media_type/negotiator_spec.rb +92 -0
- data/spec/media_type_spec.rb +4 -78
- data/spec/spec_helper.rb +10 -12
- metadata +19 -5
@@ -0,0 +1,37 @@
|
|
1
|
+
require "accept_headers/language"
|
2
|
+
require "accept_headers/negotiatable"
|
3
|
+
|
4
|
+
module AcceptHeaders
|
5
|
+
class Language
|
6
|
+
class Negotiator
|
7
|
+
include Negotiatable
|
8
|
+
|
9
|
+
LANGUAGE_PATTERN = /^\s*(?<primary_tag>[\w]{1,8}|\*)(?:\s*\-\s*(?<subtag>[\w]{1,8}|\*))?\s*$/
|
10
|
+
|
11
|
+
private
|
12
|
+
def parse(original_header)
|
13
|
+
header = original_header.dup
|
14
|
+
header.sub!(/\AAccept-Language:\s*/, '')
|
15
|
+
header.strip!
|
16
|
+
return [Language.new] if header.empty?
|
17
|
+
languages = []
|
18
|
+
header.split(',').each do |entry|
|
19
|
+
language_arr = entry.split(';', 2)
|
20
|
+
next if language_arr[0].nil?
|
21
|
+
language_range = LANGUAGE_PATTERN.match(language_arr[0])
|
22
|
+
next if language_range.nil?
|
23
|
+
begin
|
24
|
+
languages << Language.new(
|
25
|
+
language_range[:primary_tag],
|
26
|
+
language_range[:subtag],
|
27
|
+
q: parse_q(language_arr[1])
|
28
|
+
)
|
29
|
+
rescue Error
|
30
|
+
next
|
31
|
+
end
|
32
|
+
end
|
33
|
+
languages.sort! { |x,y| y <=> x }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -70,45 +70,16 @@ module AcceptHeaders
|
|
70
70
|
string
|
71
71
|
end
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
header.split(',').each do |entry|
|
83
|
-
accept_media_range, accept_params = entry.split(';', 2)
|
84
|
-
next if accept_media_range.nil?
|
85
|
-
media_range = MEDIA_TYPE_PATTERN.match(accept_media_range)
|
86
|
-
next if media_range.nil?
|
87
|
-
begin
|
88
|
-
media_types << MediaType.new(
|
89
|
-
media_range[:type],
|
90
|
-
media_range[:subtype],
|
91
|
-
q: parse_q(accept_params),
|
92
|
-
params: parse_params(accept_params)
|
93
|
-
)
|
94
|
-
rescue Error
|
95
|
-
next
|
96
|
-
end
|
97
|
-
end
|
98
|
-
media_types.sort! { |x,y| y <=> x }
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
|
103
|
-
def self.parse_params(params_string)
|
104
|
-
params = {}
|
105
|
-
return params if !params_string || params_string.empty?
|
106
|
-
params_string.split(';').each do |part|
|
107
|
-
param = PARAM_PATTERN.match(part)
|
108
|
-
params[param[:attribute]] = param[:value] if param
|
73
|
+
def match(other)
|
74
|
+
if type == other.type && subtype == other.subtype
|
75
|
+
true
|
76
|
+
elsif type == other.type && subtype == '*'
|
77
|
+
true
|
78
|
+
elsif other.type == '*' && other.subtype == '*'
|
79
|
+
true
|
80
|
+
else
|
81
|
+
false
|
109
82
|
end
|
110
|
-
params.delete('q')
|
111
|
-
params
|
112
83
|
end
|
113
84
|
end
|
114
85
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "accept_headers/media_type"
|
2
|
+
require "accept_headers/negotiatable"
|
3
|
+
|
4
|
+
module AcceptHeaders
|
5
|
+
class MediaType
|
6
|
+
class Negotiator
|
7
|
+
include Negotiatable
|
8
|
+
|
9
|
+
private
|
10
|
+
MEDIA_TYPE_PATTERN = /^\s*(?<type>[\w!#$%^&*\-\+{}\\|'.`~]+)(?:\s*\/\s*(?<subtype>[\w!#$%^&*\-\+{}\\|'.`~]+))?\s*$/
|
11
|
+
PARAM_PATTERN = /(?<attribute>[\w!#$%^&*\-\+{}\\|'.`~]+)\s*\=\s*(?:\"(?<value>[^"]*)\"|\'(?<value>[^']*)\'|(?<value>[\w!#$%^&*\-\+{}\\|\'.`~]*))/
|
12
|
+
|
13
|
+
def parse(original_header)
|
14
|
+
header = original_header.dup
|
15
|
+
header.sub!(/\AAccept:\s*/, '')
|
16
|
+
header.strip!
|
17
|
+
return [MediaType.new] if header.empty?
|
18
|
+
media_types = []
|
19
|
+
header.split(',').each do |entry|
|
20
|
+
accept_media_range, accept_params = entry.split(';', 2)
|
21
|
+
next if accept_media_range.nil?
|
22
|
+
media_range = MEDIA_TYPE_PATTERN.match(accept_media_range)
|
23
|
+
next if media_range.nil?
|
24
|
+
begin
|
25
|
+
media_types << MediaType.new(
|
26
|
+
media_range[:type],
|
27
|
+
media_range[:subtype],
|
28
|
+
q: parse_q(accept_params),
|
29
|
+
params: parse_params(accept_params)
|
30
|
+
)
|
31
|
+
rescue Error
|
32
|
+
next
|
33
|
+
end
|
34
|
+
end
|
35
|
+
media_types.sort! { |x,y| y <=> x }
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_params(params_string)
|
39
|
+
params = {}
|
40
|
+
return params if !params_string || params_string.empty?
|
41
|
+
params_string.split(';').each do |part|
|
42
|
+
param = PARAM_PATTERN.match(part)
|
43
|
+
params[param[:attribute]] = param[:value] if param
|
44
|
+
end
|
45
|
+
params.delete('q')
|
46
|
+
params
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module AcceptHeaders
|
2
|
+
module Negotiatable
|
3
|
+
class Error < StandardError; end
|
4
|
+
class ParseError < Error; end
|
5
|
+
|
6
|
+
TOKEN_PATTERN = /^\s*(?<token>[\w!#$%^&*\-\+{}\\|'.`~]+)\s*$/
|
7
|
+
Q_PATTERN = /(?:\A|;)\s*(?<exists>qs*\=)\s*(?:(?<q>0\.\d{1,3}|[01])|(?:[^;]*))\s*(?:\z|;)/
|
8
|
+
|
9
|
+
attr_reader :list
|
10
|
+
|
11
|
+
def initialize(header)
|
12
|
+
@list = parse(header)
|
13
|
+
end
|
14
|
+
|
15
|
+
def negotiate(supported_string)
|
16
|
+
supported = parse(supported_string)
|
17
|
+
return nil if @list.empty?
|
18
|
+
rejects, acceptable = @list.partition { |m| m.q == 0.0 }
|
19
|
+
rejects.each do |reject|
|
20
|
+
supported.each do |support|
|
21
|
+
if support.match(reject)
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
acceptable.sort { |x,y| y <=> x }.each do |accepted|
|
27
|
+
supported.each do |support|
|
28
|
+
if support.match(accepted)
|
29
|
+
return accepted
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def parse(header)
|
37
|
+
raise NotImplementedError.new("#parse(header) is not implemented")
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse_q(header)
|
41
|
+
q = 1
|
42
|
+
return q unless header
|
43
|
+
q_match = Q_PATTERN.match(header)
|
44
|
+
if q_match && q_match[:exists]
|
45
|
+
if q_match[:q]
|
46
|
+
q = q_match[:q]
|
47
|
+
else
|
48
|
+
q = 0.001
|
49
|
+
end
|
50
|
+
end
|
51
|
+
q
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative "../spec_helper"
|
2
|
+
|
3
|
+
module AcceptHeaders
|
4
|
+
class Charset
|
5
|
+
describe Negotiator do
|
6
|
+
subject do
|
7
|
+
AcceptHeaders::Charset::Negotiator
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "parsing an accept header" do
|
11
|
+
it "returns a sorted array of charsets" do
|
12
|
+
subject.new("*; q=0.2, unicode-1-1").list.must_equal [
|
13
|
+
Charset.new('unicode-1-1'),
|
14
|
+
Charset.new('*', q: 0.2)
|
15
|
+
]
|
16
|
+
|
17
|
+
subject.new("us-ascii; q=0.5, iso-8859-1, utf-8; q=0.8, macintosh").list.must_equal [
|
18
|
+
Charset.new('iso-8859-1'),
|
19
|
+
Charset.new('macintosh'),
|
20
|
+
Charset.new('utf-8', q: 0.8),
|
21
|
+
Charset.new('us-ascii', q: 0.5)
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "sets charset to * when the accept-charset header is empty" do
|
26
|
+
subject.new('').list.must_equal [
|
27
|
+
Charset.new('*')
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "defaults q to 1 if it's not explicitly specified" do
|
32
|
+
subject.new("iso-8859-1").list.must_equal [
|
33
|
+
Charset.new('iso-8859-1', q: 1.0)
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "strips whitespace from between charsets" do
|
38
|
+
subject.new("\tunicode-1-1\r,\niso-8859-1\s").list.must_equal [
|
39
|
+
Charset.new('unicode-1-1'),
|
40
|
+
Charset.new('iso-8859-1')
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "strips whitespace around q" do
|
45
|
+
subject.new("iso-8859-1;\tq\r=\n1, unicode-1-1;q=0.8\n").list.must_equal [
|
46
|
+
Charset.new('iso-8859-1'),
|
47
|
+
Charset.new('unicode-1-1', q: 0.8)
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has a q value of 0.001 when parsed q is invalid" do
|
52
|
+
subject.new("iso-8859-1;q=x").list.must_equal [
|
53
|
+
Charset.new('iso-8859-1', q: 0.001)
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "skips invalid character sets" do
|
58
|
+
subject.new("iso-8859-1, @unicode-1-1").list.must_equal [
|
59
|
+
Charset.new('iso-8859-1', q: 1)
|
60
|
+
]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "negotiate supported charsets" do
|
65
|
+
it "returns a best matching charset" do
|
66
|
+
match = Charset.new('iso-8859-1')
|
67
|
+
n = subject.new('us-ascii; q=0.5, iso-8859-1, utf-8; q=0.8, macintosh')
|
68
|
+
n.negotiate('iso-8859-1').must_equal match
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/charset_spec.rb
CHANGED
@@ -34,11 +34,11 @@ module AcceptHeaders
|
|
34
34
|
subject.new('iso-8859-1', q: '1')
|
35
35
|
end
|
36
36
|
|
37
|
-
it "raises an
|
37
|
+
it "raises an InvalidQError unless q value is between 0 and 1" do
|
38
38
|
[-1.0, -0.1, 1.1].each do |q|
|
39
39
|
e = -> do
|
40
40
|
subject.new('iso-8859-1', q: q)
|
41
|
-
end.must_raise Charset::
|
41
|
+
end.must_raise Charset::InvalidQError
|
42
42
|
|
43
43
|
e.message.must_equal "q must be between 0 and 1"
|
44
44
|
end
|
@@ -47,10 +47,10 @@ module AcceptHeaders
|
|
47
47
|
subject.new('unicode-1-1', q: 0)
|
48
48
|
end
|
49
49
|
|
50
|
-
it "raises an
|
50
|
+
it "raises an InvalidQError if q has more than a precision of 3" do
|
51
51
|
e = -> do
|
52
52
|
subject.new('iso-8859-1', q: 0.1234)
|
53
|
-
end.must_raise Charset::
|
53
|
+
end.must_raise Charset::InvalidQError
|
54
54
|
|
55
55
|
e.message.must_equal "q must be at most 3 decimal places"
|
56
56
|
|
@@ -68,59 +68,5 @@ module AcceptHeaders
|
|
68
68
|
s = subject.new('iso-8859-1', q: 0.9).to_s
|
69
69
|
s.must_equal "iso-8859-1;q=0.9"
|
70
70
|
end
|
71
|
-
|
72
|
-
describe "parsing an accept header" do
|
73
|
-
it "returns a sorted array of charsets" do
|
74
|
-
subject.parse("*; q=0.2, unicode-1-1").must_equal [
|
75
|
-
Charset.new('unicode-1-1'),
|
76
|
-
Charset.new('*', q: 0.2)
|
77
|
-
]
|
78
|
-
|
79
|
-
subject.parse("us-ascii; q=0.5, iso-8859-1, utf-8; q=0.8, macintosh").must_equal [
|
80
|
-
Charset.new('iso-8859-1'),
|
81
|
-
Charset.new('macintosh'),
|
82
|
-
Charset.new('utf-8', q: 0.8),
|
83
|
-
Charset.new('us-ascii', q: 0.5)
|
84
|
-
]
|
85
|
-
end
|
86
|
-
|
87
|
-
it "sets charset to * when the accept-charset header is empty" do
|
88
|
-
subject.parse('').must_equal [
|
89
|
-
Charset.new('*')
|
90
|
-
]
|
91
|
-
end
|
92
|
-
|
93
|
-
it "defaults q to 1 if it's not explicitly specified" do
|
94
|
-
subject.parse("iso-8859-1").must_equal [
|
95
|
-
Charset.new('iso-8859-1', q: 1.0)
|
96
|
-
]
|
97
|
-
end
|
98
|
-
|
99
|
-
it "strips whitespace from between charsets" do
|
100
|
-
subject.parse("\tunicode-1-1\r,\niso-8859-1\s").must_equal [
|
101
|
-
Charset.new('unicode-1-1'),
|
102
|
-
Charset.new('iso-8859-1')
|
103
|
-
]
|
104
|
-
end
|
105
|
-
|
106
|
-
it "strips whitespace around q" do
|
107
|
-
subject.parse("iso-8859-1;\tq\r=\n1, unicode-1-1;q=0.8\n").must_equal [
|
108
|
-
Charset.new('iso-8859-1'),
|
109
|
-
Charset.new('unicode-1-1', q: 0.8)
|
110
|
-
]
|
111
|
-
end
|
112
|
-
|
113
|
-
it "has a q value of 0.001 when parsed q is invalid" do
|
114
|
-
subject.parse("iso-8859-1;q=x").must_equal [
|
115
|
-
Charset.new('iso-8859-1', q: 0.001)
|
116
|
-
]
|
117
|
-
end
|
118
|
-
|
119
|
-
it "skips invalid character sets" do
|
120
|
-
subject.parse("iso-8859-1, @unicode-1-1").must_equal [
|
121
|
-
Charset.new('iso-8859-1', q: 1)
|
122
|
-
]
|
123
|
-
end
|
124
|
-
end
|
125
71
|
end
|
126
72
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative "../spec_helper"
|
2
|
+
|
3
|
+
module AcceptHeaders
|
4
|
+
class Encoding
|
5
|
+
describe Negotiator do
|
6
|
+
subject do
|
7
|
+
AcceptHeaders::Encoding::Negotiator
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "parsing an accept header" do
|
11
|
+
it "returns a sorted array of encodings" do
|
12
|
+
subject.new("*; q=0.2, compress").list.must_equal [
|
13
|
+
Encoding.new('compress'),
|
14
|
+
Encoding.new('*', q: 0.2)
|
15
|
+
]
|
16
|
+
|
17
|
+
subject.new("deflate; q=0.5, gzip, compress; q=0.8, identity").list.must_equal [
|
18
|
+
Encoding.new('gzip'),
|
19
|
+
Encoding.new('identity'),
|
20
|
+
Encoding.new('compress', q: 0.8),
|
21
|
+
Encoding.new('deflate', q: 0.5)
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "sets encoding to * when the accept-encoding header is empty" do
|
26
|
+
subject.new('').list.must_equal [
|
27
|
+
Encoding.new('*')
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "defaults q to 1 if it's not explicitly specified" do
|
32
|
+
subject.new("gzip").list.must_equal [
|
33
|
+
Encoding.new('gzip', q: 1.0)
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
it "strips whitespace from between encodings" do
|
38
|
+
subject.new("\tcompress\r,\ngzip\s").list.must_equal [
|
39
|
+
Encoding.new('compress'),
|
40
|
+
Encoding.new('gzip')
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "strips whitespace around q" do
|
45
|
+
subject.new("gzip;\tq\r=\n1, compress;q=0.8\n").list.must_equal [
|
46
|
+
Encoding.new('gzip'),
|
47
|
+
Encoding.new('compress', q: 0.8)
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "has a q value of 0.001 when parsed q is invalid" do
|
52
|
+
subject.new("gzip;q=x").list.must_equal [
|
53
|
+
Encoding.new('gzip', q: 0.001)
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "skips invalid encodings" do
|
58
|
+
subject.new("gzip, @blah").list.must_equal [
|
59
|
+
Encoding.new('gzip', q: 1.0)
|
60
|
+
]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "negotiate supported encodings" do
|
65
|
+
it "returns a best matching encoding" do
|
66
|
+
match =
|
67
|
+
n = subject.new("deflate; q=0.5, gzip, compress; q=0.8, identity")
|
68
|
+
n.negotiate("identity").must_equal Encoding.new('identity')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/encoding_spec.rb
CHANGED
@@ -34,11 +34,11 @@ module AcceptHeaders
|
|
34
34
|
subject.new('gzip', q: '1')
|
35
35
|
end
|
36
36
|
|
37
|
-
it "raises an
|
37
|
+
it "raises an InvalidQError unless q value is between 0 and 1" do
|
38
38
|
[-1.0, -0.1, 1.1].each do |q|
|
39
39
|
e = -> do
|
40
40
|
subject.new('gzip', q: q)
|
41
|
-
end.must_raise Encoding::
|
41
|
+
end.must_raise Encoding::InvalidQError
|
42
42
|
|
43
43
|
e.message.must_equal "q must be between 0 and 1"
|
44
44
|
end
|
@@ -47,10 +47,10 @@ module AcceptHeaders
|
|
47
47
|
subject.new('compress', q: 0)
|
48
48
|
end
|
49
49
|
|
50
|
-
it "raises an
|
50
|
+
it "raises an InvalidQError if q has more than a precision of 3" do
|
51
51
|
e = -> do
|
52
52
|
subject.new('gzip', q: 0.1234)
|
53
|
-
end.must_raise Encoding::
|
53
|
+
end.must_raise Encoding::InvalidQError
|
54
54
|
|
55
55
|
e.message.must_equal "q must be at most 3 decimal places"
|
56
56
|
|
@@ -68,59 +68,5 @@ module AcceptHeaders
|
|
68
68
|
s = subject.new('gzip', q: 0.9).to_s
|
69
69
|
s.must_equal "gzip;q=0.9"
|
70
70
|
end
|
71
|
-
|
72
|
-
describe "parsing an accept header" do
|
73
|
-
it "returns a sorted array of encodings" do
|
74
|
-
subject.parse("*; q=0.2, compress").must_equal [
|
75
|
-
Encoding.new('compress'),
|
76
|
-
Encoding.new('*', q: 0.2)
|
77
|
-
]
|
78
|
-
|
79
|
-
subject.parse("deflate; q=0.5, gzip, compress; q=0.8, identity").must_equal [
|
80
|
-
Encoding.new('gzip'),
|
81
|
-
Encoding.new('identity'),
|
82
|
-
Encoding.new('compress', q: 0.8),
|
83
|
-
Encoding.new('deflate', q: 0.5)
|
84
|
-
]
|
85
|
-
end
|
86
|
-
|
87
|
-
it "sets encoding to * when the accept-encoding header is empty" do
|
88
|
-
subject.parse('').must_equal [
|
89
|
-
Encoding.new('*')
|
90
|
-
]
|
91
|
-
end
|
92
|
-
|
93
|
-
it "defaults q to 1 if it's not explicitly specified" do
|
94
|
-
subject.parse("gzip").must_equal [
|
95
|
-
Encoding.new('gzip', q: 1.0)
|
96
|
-
]
|
97
|
-
end
|
98
|
-
|
99
|
-
it "strips whitespace from between encodings" do
|
100
|
-
subject.parse("\tcompress\r,\ngzip\s").must_equal [
|
101
|
-
Encoding.new('compress'),
|
102
|
-
Encoding.new('gzip')
|
103
|
-
]
|
104
|
-
end
|
105
|
-
|
106
|
-
it "strips whitespace around q" do
|
107
|
-
subject.parse("gzip;\tq\r=\n1, compress;q=0.8\n").must_equal [
|
108
|
-
Encoding.new('gzip'),
|
109
|
-
Encoding.new('compress', q: 0.8)
|
110
|
-
]
|
111
|
-
end
|
112
|
-
|
113
|
-
it "has a q value of 0.001 when parsed q is invalid" do
|
114
|
-
subject.parse("gzip;q=x").must_equal [
|
115
|
-
Encoding.new('gzip', q: 0.001)
|
116
|
-
]
|
117
|
-
end
|
118
|
-
|
119
|
-
it "skips invalid encodings" do
|
120
|
-
subject.parse("gzip, @blah").must_equal [
|
121
|
-
Encoding.new('gzip', q: 1.0)
|
122
|
-
]
|
123
|
-
end
|
124
|
-
end
|
125
71
|
end
|
126
72
|
end
|