http-negotiate 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/http-negotiate.gemspec +2 -2
- data/lib/http/negotiate/version.rb +1 -1
- data/lib/http/negotiate.rb +38 -20
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97e8bcc59dec991c82e9e253b34ab3643ee7b62441b2d890c1988bcd2bd6a941
|
4
|
+
data.tar.gz: 66a3825c19b6ab786a4b1fdca2cd5fff90d03b91d72aea495576f2e3312c2bb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89807147d59bfeadcfa20e4228bbd6de119c2bcadcfcf76c204516e20a47c049c8c0a7d736e05265f5f737d10ce8b1c4a49ee7da4719a0c30abe7e62dba57c2c
|
7
|
+
data.tar.gz: 8f83584309e4a1fb37b46c53b3618bba9a470030414e20d30c8f96bbf09deecc003674fd265262193ea4fecf3053de20927f35fd676a547c46586941e77e8381
|
data/Gemfile
CHANGED
data/http-negotiate.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
30
30
|
|
31
31
|
# dev/test dependencies
|
32
|
-
spec.add_development_dependency 'bundler', '~> 2.
|
32
|
+
spec.add_development_dependency 'bundler', '~> 2.2'
|
33
33
|
spec.add_development_dependency 'rake', '~> 13.0'
|
34
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.10'
|
35
35
|
end
|
data/lib/http/negotiate.rb
CHANGED
@@ -32,10 +32,11 @@ module HTTP::Negotiate
|
|
32
32
|
#
|
33
33
|
# @param request [Hash,Rack::Request,#env] Anything roughly a hash of headers
|
34
34
|
# @param variants [Hash] the variants, described above
|
35
|
+
# @param add_langs [false, true] whether to supplant language tags
|
35
36
|
# @param all [false, true] whether to return a sorted list or not
|
36
37
|
# @param cmp [Proc] a secondary comparison of variants as a tiebreaker
|
37
38
|
#
|
38
|
-
def negotiate request, variants, all: false, cmp: nil
|
39
|
+
def negotiate request, variants, add_langs: false, all: false, cmp: nil
|
39
40
|
# pull accept headers
|
40
41
|
request = request.env if request.respond_to? :env
|
41
42
|
# this will ensure that the keys will match irrespective of
|
@@ -56,6 +57,11 @@ module HTTP::Negotiate
|
|
56
57
|
# but we don't care (although interestingly according to rfc7231,
|
57
58
|
# accept-language only affords q= and not arbitrary parameters)
|
58
59
|
hdr = hdr.dup.gsub(/\s+/, '')
|
60
|
+
|
61
|
+
# don't add the test group if it's an empty string, because
|
62
|
+
# postel's law is a thing
|
63
|
+
next if hdr.empty?
|
64
|
+
|
59
65
|
accept[k] = hdr.split(/,+/).map do |c|
|
60
66
|
val, *params = c.split(/;+/)
|
61
67
|
params = params.map do |p|
|
@@ -77,6 +83,23 @@ module HTTP::Negotiate
|
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
86
|
+
# sneakily supplant shorter language tags at 99% q
|
87
|
+
if accept[:language]
|
88
|
+
langs = accept[:language]
|
89
|
+
langs.transform_keys! { |k| k.tr(?_, ?-).tr_s(?-, ?-).downcase }
|
90
|
+
if add_langs
|
91
|
+
langs.keys.select { |k| k.include? ?- }.each do |k|
|
92
|
+
# a tag with q=0 has to be explicitly set in the header
|
93
|
+
next if (q = langs[k][:q]) == 0
|
94
|
+
lang = k.split ?-
|
95
|
+
(1..lang.length).to_a.reverse.each do |i|
|
96
|
+
# each shorter language tag will have a slightly lower score
|
97
|
+
langs[lang.slice(0, i).join ?-] ||= { q: q *= 0.999 }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
80
103
|
# convert variants to array
|
81
104
|
variants = variants.transform_values do |v|
|
82
105
|
v.is_a?(Hash) ? v.values_at(*KEYS) : v
|
@@ -162,37 +185,32 @@ module HTTP::Negotiate
|
|
162
185
|
# warn maj.inspect, min.inspect
|
163
186
|
|
164
187
|
# XXX match params at some point
|
165
|
-
if at[
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
# ???
|
175
|
-
qt = at[?*].fetch(?*, { q: 0.1 })[:q]
|
176
|
-
else
|
177
|
-
# ???
|
178
|
-
qt = 0.1
|
179
|
-
end
|
188
|
+
qt = if at.fetch(maj, {})[min]
|
189
|
+
at[maj][min][:q]
|
190
|
+
elsif at.fetch(maj, {})[?*]
|
191
|
+
at[maj][?*][:q]
|
192
|
+
elsif at.fetch(?*, {})[?*]
|
193
|
+
at[?*][?*][:q]
|
194
|
+
else
|
195
|
+
0.1
|
196
|
+
end
|
180
197
|
|
181
198
|
end
|
182
199
|
|
183
|
-
scores[var] = qs * qe * qc * ql * qt
|
200
|
+
scores[var] = [qs * qe * qc * ql * qt, size]
|
184
201
|
end
|
185
202
|
|
186
203
|
# XXX do something smarter here for secondary comparison
|
187
204
|
cmp ||= -> a, b { 0 }
|
188
205
|
|
189
206
|
chosen = scores.sort do |a, b|
|
190
|
-
c = b.last <=> a.last
|
191
|
-
c
|
207
|
+
c = b.last.first <=> a.last.first # first compare scores
|
208
|
+
c = cmp.call(a.first, b.first) if c == 0 # then secondary cmp
|
209
|
+
c == 0 ? a.last.last <=> b.last.last : c # then finally by size
|
192
210
|
end.map(&:first)
|
211
|
+
|
193
212
|
all ? chosen : chosen.first
|
194
213
|
end
|
195
214
|
|
196
215
|
extend self
|
197
216
|
end
|
198
|
-
3
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: http-negotiate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dorian Taylor
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '2.
|
19
|
+
version: '2.2'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '2.
|
26
|
+
version: '2.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.10'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.10'
|
55
55
|
description:
|
56
56
|
email:
|
57
57
|
- code@doriantaylor.com
|