http-negotiate 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: []