http-negotiate 0.1.3 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +5 -0
- data/http-negotiate.gemspec +1 -1
- data/lib/http/negotiate/version.rb +1 -1
- data/lib/http/negotiate.rb +55 -26
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e27b1c078a2a7afaf0787772a0c48086fc5b6a108f04a87e64ed247f26e7f3d
|
4
|
+
data.tar.gz: a26e38a5eece61435947e558db362d706299a5c48ac64bad54012a52dc0850c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6234e7a39672c501cdfb69fbbdd620c9ca7ca4c9978a714f2b0e2425d80a2dd67c111837e30a72c375a8d308ae7dae02a60ddd2d6981ed342f70ec8db8a0ba27
|
7
|
+
data.tar.gz: a2e8a89a8a226dc0ec9a15ceca62055705bd7903a4939907b17f4b6f23f1d3dda5bf5801308dda797348410bed6481961139462e87c535de7559efaf393f779f
|
data/.yardopts
ADDED
data/http-negotiate.gemspec
CHANGED
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
|
|
31
31
|
# dev/test dependencies
|
32
32
|
spec.add_development_dependency 'bundler', '~> 2.2'
|
33
33
|
spec.add_development_dependency 'rake', '~> 13.0'
|
34
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.12'
|
35
35
|
end
|
data/lib/http/negotiate.rb
CHANGED
@@ -13,32 +13,31 @@ module HTTP::Negotiate
|
|
13
13
|
|
14
14
|
public
|
15
15
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# `gzip`, not like `utf-8`: that's "charset")
|
27
|
-
# * size is the number of bytes, an integer
|
16
|
+
# Return a parsed representation of the relevant header
|
17
|
+
# set. Translates `Accept-*` (`HTTP_ACCEPT_*`) into lower-case
|
18
|
+
# symbols, so `Accept-Language` or `HTTP_ACCEPT_LANGUAGE` becomes
|
19
|
+
# `:language`. Same for `:charset`, and `:encoding`, etc., save for
|
20
|
+
# plain `Accept` which is translated to `:type`. The parameter
|
21
|
+
# `:add_langs` will supplement `Accept-Language` assertions of
|
22
|
+
# specific languages with their more generic counterparts, if not
|
23
|
+
# already present in the header, with a slightly lower quality
|
24
|
+
# score, e.g. `en-us` adds `en;q=0.999`, `zh-cn;q=0.8` adds
|
25
|
+
# `zh;q=0.799`.
|
28
26
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
27
|
+
# @param request [Hash, Rack::Request, #env] Anything roughly a hash
|
28
|
+
# of headers
|
29
|
+
# @param add_langs [false, true] whether to supplement language tags
|
32
30
|
#
|
33
|
-
# @
|
34
|
-
# @param variants [Hash] the variants, described above
|
35
|
-
# @param add_langs [false, true] whether to supplant language tags
|
36
|
-
# @param all [false, true] whether to return a sorted list or not
|
37
|
-
# @param cmp [Proc] a secondary comparison of variants as a tiebreaker
|
31
|
+
# @return [Hash] the parsed `Accept*` headers
|
38
32
|
#
|
39
|
-
def
|
33
|
+
def parse_headers request, add_langs: false
|
40
34
|
# pull accept headers
|
41
35
|
request = request.env if request.respond_to? :env
|
36
|
+
|
37
|
+
# no-op if this is already parsed
|
38
|
+
return request if request.is_a? Hash and
|
39
|
+
request.all? { |k, v| k.is_a? Symbol and v.is_a? Hash }
|
40
|
+
|
42
41
|
# this will ensure that the keys will match irrespective of
|
43
42
|
# whether it's passed in as actual http headers or a cgi-like env
|
44
43
|
request = request.transform_keys do |k|
|
@@ -56,18 +55,19 @@ module HTTP::Negotiate
|
|
56
55
|
# theoretically you can have quoted-string parameter values
|
57
56
|
# but we don't care (although interestingly according to rfc7231,
|
58
57
|
# accept-language only affords q= and not arbitrary parameters)
|
59
|
-
hdr = hdr.dup.
|
58
|
+
hdr = hdr.respond_to?(:to_a) ? hdr.to_a.dup : hdr.to_s.split(/\s*,+\s*/)
|
59
|
+
hdr = hdr.map { |h| h.to_s.gsub(/\s+/, '') }.reject(&:empty?)
|
60
60
|
|
61
61
|
# don't add the test group if it's an empty string, because
|
62
62
|
# postel's law is a thing
|
63
63
|
next if hdr.empty?
|
64
64
|
|
65
|
-
accept[k] = hdr.
|
65
|
+
accept[k] = hdr.map do |c|
|
66
66
|
val, *params = c.split(/;+/)
|
67
67
|
params = params.map do |p|
|
68
|
-
k, v = p.split(
|
68
|
+
k, v = p.split(/\s*=+\s*/, 2)
|
69
69
|
k = k.downcase.to_sym
|
70
|
-
v = v.to_f if v and k == :q
|
70
|
+
v = v.to_f if v and k == :q # note garbage will return 0
|
71
71
|
[k, v]
|
72
72
|
end.to_h
|
73
73
|
if params[:q]
|
@@ -100,6 +100,35 @@ module HTTP::Negotiate
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
accept
|
104
|
+
end
|
105
|
+
|
106
|
+
# The variant mapping takes the following form:
|
107
|
+
# { variant => [weight, type, encoding, charset, language, size] }
|
108
|
+
#
|
109
|
+
# (Alternatively this array can be a hash with the same keys as symbols.)
|
110
|
+
#
|
111
|
+
# * the variant can be anything, including the actual variant
|
112
|
+
# * the weight is a number between 0 and 1 denoting the initial
|
113
|
+
# preference for the variant
|
114
|
+
# * type, encoding, charset, language are all strings containing
|
115
|
+
# their respective standardized tokens (note "encoding" is like
|
116
|
+
# `gzip`, not like `utf-8`: that's "charset")
|
117
|
+
# * size is the number of bytes, an integer
|
118
|
+
#
|
119
|
+
# Returns either the winning variant or all variants if requested,
|
120
|
+
# sorted by the algorithm, or nil or the empty array if none are
|
121
|
+
# selected.
|
122
|
+
#
|
123
|
+
# @param request [Hash,Rack::Request,#env] Anything roughly a hash of headers
|
124
|
+
# @param variants [Hash] the variants, described above
|
125
|
+
# @param add_langs [false, true] whether to supplement language tags
|
126
|
+
# @param all [false, true] whether to return a sorted list or not
|
127
|
+
# @param cmp [Proc] a secondary comparison of variants as a tiebreaker
|
128
|
+
#
|
129
|
+
def negotiate request, variants, add_langs: false, all: false, cmp: nil
|
130
|
+
accept = parse_headers request, add_langs: add_langs
|
131
|
+
|
103
132
|
# convert variants to array
|
104
133
|
variants = variants.transform_values do |v|
|
105
134
|
v.is_a?(Hash) ? v.values_at(*KEYS) : v
|
@@ -155,7 +184,7 @@ module HTTP::Negotiate
|
|
155
184
|
test = i > 0 ? lang.slice(0, i).join(?-) : ?*
|
156
185
|
if accept[:language][test]
|
157
186
|
al = accept[:language][test][:q]
|
158
|
-
# *;q=0 will override
|
187
|
+
# *;q=0 will override
|
159
188
|
if al == 0 and test != ?*
|
160
189
|
ql = 0
|
161
190
|
break
|
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.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dorian Taylor
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.12'
|
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.
|
54
|
+
version: '3.12'
|
55
55
|
description:
|
56
56
|
email:
|
57
57
|
- code@doriantaylor.com
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- ".gitignore"
|
63
63
|
- ".rspec"
|
64
64
|
- ".travis.yml"
|
65
|
+
- ".yardopts"
|
65
66
|
- Gemfile
|
66
67
|
- LICENSE
|
67
68
|
- README.md
|
@@ -93,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
94
|
- !ruby/object:Gem::Version
|
94
95
|
version: '0'
|
95
96
|
requirements: []
|
96
|
-
rubygems_version: 3.
|
97
|
+
rubygems_version: 3.3.15
|
97
98
|
signing_key:
|
98
99
|
specification_version: 4
|
99
100
|
summary: An implementation of Gisle Aas's HTTP::Negotiate
|