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 +4 -4
- data/Gemfile +1 -1
- data/lib/http/negotiate/version.rb +1 -1
- data/lib/http/negotiate.rb +29 -12
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37db2775817222cbcb2d1d27845d37011cfec405d7b8ddc9f0030383bc53264c
|
4
|
+
data.tar.gz: 84e031f85bc9d04b8f1ed52213a0c681e5be4bb638e0ab13881f5320a0ad511a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bde399e1e18835553bd15b72c9062c98d6560b7ae8e705739f4e4ea3fc96caa70b2db000b93897c5470a71f9f8cdc0a7674fc1afb2952d841a43c652c5a447fe
|
7
|
+
data.tar.gz: 6575f6321b5beac495967b5e42fca6e2c238a4e7171588ef3e653efa925397cf8a8e2d3563ee7ba395e5cb012d4bd12edf06277b0468dc4189c90398a2d9939a
|
data/Gemfile
CHANGED
data/lib/http/negotiate.rb
CHANGED
@@ -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
|
-
|
39
|
-
|
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
|
-
#
|
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[
|
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
|
-
|
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.
|
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:
|
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.
|
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: []
|