http-negotiate 0.1.0 → 0.1.1

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: bd99cf36cd404c834530adbd738b22a485280105cc5e1bc868515f70f08d9549
4
- data.tar.gz: aad680c6a7a7f9d627232317b0ef880d801bc65a9dbbf73ff0a9ab2b40c7a005
3
+ metadata.gz: 37db2775817222cbcb2d1d27845d37011cfec405d7b8ddc9f0030383bc53264c
4
+ data.tar.gz: 84e031f85bc9d04b8f1ed52213a0c681e5be4bb638e0ab13881f5320a0ad511a
5
5
  SHA512:
6
- metadata.gz: 7dad74af3b4900b212d17519fc517d54e4d1b8c3b26d7fe527e35c4296a4c27ac1dc4e5776fdde817922e250190bcec1c0f59db9c3ece17fbee58d29686cc4e0
7
- data.tar.gz: e628966125eba4f566a151bf91d77d637097977c71e46f9b0fc7d5c734ebdf70b6b39954e354bbfadd1ab7e5854e4464e54586c4d00bd3b4daa6f2d09219db26
6
+ metadata.gz: bde399e1e18835553bd15b72c9062c98d6560b7ae8e705739f4e4ea3fc96caa70b2db000b93897c5470a71f9f8cdc0a7674fc1afb2952d841a43c652c5a447fe
7
+ data.tar.gz: 6575f6321b5beac495967b5e42fca6e2c238a4e7171588ef3e653efa925397cf8a8e2d3563ee7ba395e5cb012d4bd12edf06277b0468dc4189c90398a2d9939a
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", "~> 12.0"
6
+ gem "rake", "~> 13.0"
7
7
  gem "rspec", "~> 3.0"
@@ -1,5 +1,5 @@
1
1
  module HTTP
2
2
  module Negotiate
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
4
  end
5
5
  end
@@ -8,18 +8,23 @@ module HTTP::Negotiate
8
8
  HEADERS = { type: '' }.merge(
9
9
  %i[charset language encoding].map { |k| [k, ?_ + k.to_s.upcase] }.to_h)
10
10
 
11
+ # these are for the hash representation of variant metadata
12
+ KEYS = %i[weight type encoding charset language size].freeze
13
+
11
14
  public
12
15
 
13
16
  # The variant mapping takes the following form:
14
17
  # { variant => [weight, type, encoding, charset, language, size] }
15
18
  #
19
+ # (Alternatively this array can be a hash with the same keys as symbols.)
20
+ #
16
21
  # * the variant can be anything, including the actual variant
17
22
  # * the weight is a number between 0 and 1 denoting the initial
18
23
  # preference for the variant
19
24
  # * type, encoding, charset, language are all strings containing
20
25
  # their respective standardized tokens (note "encoding" is like
21
26
  # `gzip`, not like `utf-8`: that's "charset")
22
- # * size is the number of bytes
27
+ # * size is the number of bytes, an integer
23
28
  #
24
29
  # Returns either the winning variant or all variants if requested,
25
30
  # sorted by the algorithm, or nil or the empty array if none are
@@ -27,19 +32,17 @@ module HTTP::Negotiate
27
32
  #
28
33
  # @param request [Hash,Rack::Request,#env] Anything roughly a hash of headers
29
34
  # @param variants [Hash] the variants, described above
30
- # @param all [false, true] whether to return
35
+ # @param all [false, true] whether to return a sorted list or not
36
+ # @param cmp [Proc] a secondary comparison of variants as a tiebreaker
31
37
  #
32
- def negotiate request, variants, all: false
38
+ def negotiate request, variants, all: false, cmp: nil
33
39
  # pull accept headers
34
40
  request = request.env if request.respond_to? :env
35
41
  # this will ensure that the keys will match irrespective of
36
42
  # whether it's passed in as actual http headers or a cgi-like env
37
43
  request = request.transform_keys do |k|
38
- if /^Accept(-.+)?$/i.match? k.to_s
39
- 'HTTP_' + k.to_s.upcase.tr(?-, ?_)
40
- else
41
- k
42
- end
44
+ k = k.to_s.strip
45
+ /^Accept(-.*)?$/i.match?(k) ? "HTTP_#{k.upcase.tr ?-, ?_}" : k
43
46
  end
44
47
 
45
48
  # the working set
@@ -48,7 +51,10 @@ module HTTP::Negotiate
48
51
  HEADERS.each do |k, h|
49
52
  if hdr = request["HTTP_ACCEPT#{h}"]
50
53
  defq = 1.0
51
- # theoretically you can have quoted-string parameters but we don't care
54
+ # strip out all the whitespace from the header value;
55
+ # theoretically you can have quoted-string parameter values
56
+ # but we don't care (although interestingly according to rfc7231,
57
+ # accept-language only affords q= and not arbitrary parameters)
52
58
  hdr = hdr.dup.gsub(/\s+/, '')
53
59
  accept[k] = hdr.split(/,+/).map do |c|
54
60
  val, *params = c.split(/;+/)
@@ -71,9 +77,14 @@ module HTTP::Negotiate
71
77
  end
72
78
  end
73
79
 
80
+ # convert variants to array
81
+ variants = variants.transform_values do |v|
82
+ v.is_a?(Hash) ? v.values_at(*KEYS) : v
83
+ end
84
+
74
85
  # check if any of the variants specify a language, since this will
75
86
  # affect the scoring
76
- any_lang = variants.values.any? { |v| v[5] }
87
+ any_lang = variants.values.any? { |v| v[4] }
77
88
 
78
89
  # chosen will be { variant => value }
79
90
  scores = {}
@@ -172,10 +183,16 @@ module HTTP::Negotiate
172
183
  scores[var] = qs * qe * qc * ql * qt
173
184
  end
174
185
 
175
- chosen = scores.sort { |a, b| b.last <=> a.last }.map(&:first)
186
+ # XXX do something smarter here for secondary comparison
187
+ cmp ||= -> a, b { 0 }
188
+
189
+ chosen = scores.sort do |a, b|
190
+ c = b.last <=> a.last
191
+ c == 0 ? cmp.call(a.first, b.first) : c
192
+ end.map(&:first)
176
193
  all ? chosen : chosen.first
177
194
  end
178
195
 
179
196
  extend self
180
197
  end
181
-
198
+ 3
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http-negotiate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dorian Taylor
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-07 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.9'
55
- description:
55
+ description:
56
56
  email:
57
57
  - code@doriantaylor.com
58
58
  executables: []
@@ -78,7 +78,7 @@ licenses:
78
78
  metadata:
79
79
  homepage_uri: https://github.com/doriantaylor/rb-http-negotiate
80
80
  source_code_uri: https://github.com/doriantaylor/rb-http-negotiate
81
- post_install_message:
81
+ post_install_message:
82
82
  rdoc_options: []
83
83
  require_paths:
84
84
  - lib
@@ -93,8 +93,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  requirements: []
96
- rubygems_version: 3.1.2
97
- signing_key:
96
+ rubygems_version: 3.2.22
97
+ signing_key:
98
98
  specification_version: 4
99
99
  summary: An implementation of Gisle Aas's HTTP::Negotiate
100
100
  test_files: []