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 +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: []
|