internetdata 2.8.5 → 2.8.6
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/lib/internetdata/client.rb +8 -4
- data/lib/internetdata/retries.rb +9 -0
- data/lib/internetdata/transport.rb +17 -2
- data/lib/internetdata/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 60cb6997f887f4ac598e856721bfc16b49d84059390ce32d1c1a13721cf3079a
|
|
4
|
+
data.tar.gz: 129161d2e8eede6fc3aa00ee2daf764f3177dab897b7af0a79d7188241430cce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63b12de438f16533af87d36997d2a66a53b7e5b98330b6a4175c42c6ab481f27ed4bf742646674b51a5eae3567db6fcce25b267cf237bd019369577ebac9f476
|
|
7
|
+
data.tar.gz: c9c6f3cef56834177ea1f5806ebadb0c31aa7ce40817c7e19b3e579f309b64fb68ffaa474f64c503ce8a11c59792e0bb4acf6e678cd4d3fa5f23e044907957d9
|
data/lib/internetdata/client.rb
CHANGED
|
@@ -21,16 +21,20 @@ module InternetData
|
|
|
21
21
|
|
|
22
22
|
# @param api_key [String, nil] a key carrying the `db.download` scope. Omit
|
|
23
23
|
# it and no credential is sent; every database published today answers 401.
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
24
|
+
# The blanks around it are dropped, and blanks alone are no key.
|
|
25
|
+
# @param retries [Integer] extra attempts for a transient failure, from 0. Each
|
|
26
|
+
# waits the server's `Retry-After` when it sent one of at most about 24.8
|
|
27
|
+
# days, and otherwise a backoff of 250 ms that doubles per retry.
|
|
27
28
|
# @param timeout [Numeric] seconds allowed for one API call, 0 for no bound. It
|
|
28
29
|
# also bounds the CONNECT phase of a transfer, which is otherwise unlimited.
|
|
29
30
|
# @raise [ArgumentError] for a `timeout` that is negative, not a finite number,
|
|
30
|
-
# or past 2147483.647 seconds (2**31 - 1 ms), the longest curl holds
|
|
31
|
+
# or past 2147483.647 seconds (2**31 - 1 ms), the longest curl holds; for a
|
|
32
|
+
# `retries` that is not an Integer from 0; and for an `api_key` holding a
|
|
33
|
+
# control character, without the key in the message.
|
|
31
34
|
# @param transport [Transport, nil] override the HTTP layer, mostly for tests.
|
|
32
35
|
def initialize(api_key: nil, base_url: DEFAULT_BASE_URL, retries: DEFAULT_RETRIES,
|
|
33
36
|
timeout: DEFAULT_TIMEOUT, transport: nil)
|
|
37
|
+
retries = Retries.checked_count(retries)
|
|
34
38
|
@transport = transport || Transport.new(
|
|
35
39
|
Transport::Config.new(api_key: api_key, base_url: base_url, timeout: timeout),
|
|
36
40
|
)
|
data/lib/internetdata/retries.rb
CHANGED
|
@@ -15,6 +15,15 @@ module InternetData
|
|
|
15
15
|
|
|
16
16
|
module_function
|
|
17
17
|
|
|
18
|
+
# `retries`, once it is a count. Refused where it is set: unchecked, -1 and
|
|
19
|
+
# NaN read as none, 1.5 as two, Infinity retried a failing call for good, and
|
|
20
|
+
# a String, nil or true raised a raw ArgumentError out of every failing call.
|
|
21
|
+
def checked_count(retries)
|
|
22
|
+
return retries if retries.is_a?(Integer) && retries >= 0
|
|
23
|
+
|
|
24
|
+
raise ArgumentError, "retries must be an Integer from 0, not #{retries.inspect}"
|
|
25
|
+
end
|
|
26
|
+
|
|
18
27
|
# `retry_if`, when given, is asked after each retryable failure, and a false
|
|
19
28
|
# answer ends the attempts there.
|
|
20
29
|
def with_retries(retries, retry_if: nil)
|
|
@@ -24,6 +24,19 @@ module InternetData
|
|
|
24
24
|
"timeout must be a number of seconds from 0 (no bound) to #{LONGEST_TIMEOUT}, not #{timeout.inspect}"
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
# `api_key` without the blanks around it, nil for blanks alone. A control
|
|
28
|
+
# character is refused where it is set, and the key is left out of the
|
|
29
|
+
# message: a CR or LF failed every call with Ethon's raw InvalidValue, whose
|
|
30
|
+
# message quoted the key, and a tab, NUL or DEL went out inside it (2.8.5).
|
|
31
|
+
def self.checked_key(api_key)
|
|
32
|
+
return nil if api_key.nil?
|
|
33
|
+
|
|
34
|
+
key = api_key.to_s.strip
|
|
35
|
+
raise ArgumentError, 'api_key must not contain a control character' if key.match?(/[[:cntrl:]]/)
|
|
36
|
+
|
|
37
|
+
key.empty? ? nil : key
|
|
38
|
+
end
|
|
39
|
+
|
|
27
40
|
# The generated Configuration applies a security scheme whatever it holds, so
|
|
28
41
|
# a keyless client would send `Authorization: Bearer ` - an empty credential,
|
|
29
42
|
# which the API answers 401 to rather than treating as no credential at all.
|
|
@@ -35,7 +48,7 @@ module InternetData
|
|
|
35
48
|
self.scheme = uri.scheme
|
|
36
49
|
self.host = uri.port == uri.default_port ? uri.host : "#{uri.host}:#{uri.port}"
|
|
37
50
|
self.base_path = uri.path
|
|
38
|
-
self.access_token = api_key
|
|
51
|
+
self.access_token = Transport.checked_key(api_key)
|
|
39
52
|
self.timeout = timeout.nil? ? nil : Transport.checked_timeout(timeout)
|
|
40
53
|
end
|
|
41
54
|
|
|
@@ -240,7 +253,9 @@ module InternetData
|
|
|
240
253
|
when 'Integer' then value.is_a?(Integer)
|
|
241
254
|
when 'Float' then value.is_a?(Numeric)
|
|
242
255
|
when 'Boolean' then [true, false].include?(value)
|
|
243
|
-
|
|
256
|
+
# The spec's `type: object`, a sample row: through 2.8.5 a row of 1, "x"
|
|
257
|
+
# or [] came back as the answer.
|
|
258
|
+
when 'Object' then value.is_a?(Hash)
|
|
244
259
|
when /\AArray<(?<inner>.+)>\z/
|
|
245
260
|
inner = Regexp.last_match(:inner)
|
|
246
261
|
value.is_a?(Array) && value.each_with_index.all? { |v, i| check_type!(v, inner, "#{where}[#{i}]") }
|
data/lib/internetdata/version.rb
CHANGED