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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37db2775817222cbcb2d1d27845d37011cfec405d7b8ddc9f0030383bc53264c
4
- data.tar.gz: 84e031f85bc9d04b8f1ed52213a0c681e5be4bb638e0ab13881f5320a0ad511a
3
+ metadata.gz: 97e8bcc59dec991c82e9e253b34ab3643ee7b62441b2d890c1988bcd2bd6a941
4
+ data.tar.gz: 66a3825c19b6ab786a4b1fdca2cd5fff90d03b91d72aea495576f2e3312c2bb1
5
5
  SHA512:
6
- metadata.gz: bde399e1e18835553bd15b72c9062c98d6560b7ae8e705739f4e4ea3fc96caa70b2db000b93897c5470a71f9f8cdc0a7674fc1afb2952d841a43c652c5a447fe
7
- data.tar.gz: 6575f6321b5beac495967b5e42fca6e2c238a4e7171588ef3e653efa925397cf8a8e2d3563ee7ba395e5cb012d4bd12edf06277b0468dc4189c90398a2d9939a
6
+ metadata.gz: 89807147d59bfeadcfa20e4228bbd6de119c2bcadcfcf76c204516e20a47c049c8c0a7d736e05265f5f737d10ce8b1c4a49ee7da4719a0c30abe7e62dba57c2c
7
+ data.tar.gz: 8f83584309e4a1fb37b46c53b3618bba9a470030414e20d30c8f96bbf09deecc003674fd265262193ea4fecf3053de20927f35fd676a547c46586941e77e8381
data/Gemfile CHANGED
@@ -3,5 +3,5 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in http-negotiate.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 13.0"
7
- gem "rspec", "~> 3.0"
6
+ #gem "rake", "~> 13.0"
7
+ #gem "rspec", "~> 3.0"
@@ -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.1'
32
+ spec.add_development_dependency 'bundler', '~> 2.2'
33
33
  spec.add_development_dependency 'rake', '~> 13.0'
34
- spec.add_development_dependency 'rspec', '~> 3.9'
34
+ spec.add_development_dependency 'rspec', '~> 3.10'
35
35
  end
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  module Negotiate
3
- VERSION = '0.1.1'
3
+ VERSION = '0.1.2'
4
4
  end
5
5
  end
@@ -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[maj]
166
- if at[maj][min]
167
- qt = at[maj][min][:q]
168
- elsif at[maj][?*]
169
- qt = at[maj][?*][:q]
170
- else
171
- qt = 0.1
172
- end
173
- elsif at[?*]
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 == 0 ? cmp.call(a.first, b.first) : 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.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.1'
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.1'
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.9'
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.9'
54
+ version: '3.10'
55
55
  description:
56
56
  email:
57
57
  - code@doriantaylor.com