vpndetection 5.11.1 → 5.11.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88c7142499c3369fde5389739ed830b740e54f7afff7349951099c9b81b6723e
4
- data.tar.gz: 1a2aa2f00f36e5c4e419985767ce60c432bba1c465831b69ce33a8ce45957221
3
+ metadata.gz: eb13e51eaae8cf5af6b2eed52cac37486bf9399727527f7afa3884d46b4853ca
4
+ data.tar.gz: 1bfccf0c65a221a3ea8858c29c2b9815378c3a3695ca919cb6df57b5a2613074
5
5
  SHA512:
6
- metadata.gz: 232f1f3a8819dce9f192a40230beec48fd59e4bfcc396b53d1de0a8bc11cc8f62841afe22994cba824af9353054f02905d424e2184d7abadc55f786bbaedb440
7
- data.tar.gz: 964386f4fc6e0a0a47c9209b70cca6d996e6933ac8aaddd1db71b0a050450afeed533898a7da0a4a988dc5e820776229713768c4ebda252a25046e4997ad25aa
6
+ metadata.gz: de0cbd1d51f8f72629daec0959d85384f30aa61567b882e377e9a05120bea4c92b48df6b216e98c24a9bf7dc2bb063fdb589783b3840915318ea272e49c1224a
7
+ data.tar.gz: dbc4652065381fa5d7df6eea1daa5d458047b69a42a015928306a9ddddb8aef81990d719107661cd9a5ac2f5301d01e75e6788e7b9a4fc1a5fef97d4737e5ab2
data/README.md CHANGED
@@ -161,7 +161,7 @@ client = VPNDetection::Client.new(timeout: 10, retries: 4)
161
161
  result = client.lookup('45.83.91.1', timeout: 2, retries: 0)
162
162
  ```
163
163
 
164
- `timeout` is in seconds and bounds each attempt, body included, so a call that is retried can take longer in total. It defaults to 30 seconds, and 0 means no bound; before 5.2.0 the default was 10, so pass `timeout: 10` to keep that bound. The client's values are defaults: `lookup`, `lookup_batch`, `my_ip` and `my_entitlement` each take `timeout:` and `retries:` for that call alone, and every `client.oauth` method and every `client.database` call that is not a transfer takes `timeout:` (from 5.3.0). A database download bounds only its connection with it, because a whole transfer can take minutes. A negative value, anything that isn't a number, and anything past 2147483.647 seconds (the longest curl holds) raise `ArgumentError` where you pass them, before any request.
164
+ `timeout` is in seconds and bounds each attempt, body included, so a call that is retried can take longer in total. It defaults to 30 seconds, and 0 means no bound; before 5.2.0 the default was 10, so pass `timeout: 10` to keep that bound. The client's values are defaults: `lookup`, `lookup_batch`, `my_ip` and `my_entitlement` each take `timeout:` and `retries:` for that call alone, and every `client.oauth` method and every `client.database` call that is not a transfer takes `timeout:` (from 5.3.0). A database download bounds only its connection with it, because a whole transfer can take minutes. A negative value, anything that isn't a number, and anything past 2147483.647 seconds (the longest curl holds) raise `ArgumentError` where you pass them, before any request. So does a `retries` that isn't an Integer from 0 (from 5.11.3).
165
165
 
166
166
  ### Database downloads
167
167
 
@@ -29,9 +29,9 @@ module VPNDetection
29
29
  # @param cache [Boolean] pass false to disable caching.
30
30
  # @param cache_ttl [Numeric] how long an answer stays fresh, in seconds.
31
31
  # @param concurrency [Integer] batch requests - chunks of up to 1000 addresses - in flight during a batch.
32
- # @param retries [Integer] extra attempts for a transient failure. Each waits
33
- # the server's `Retry-After` when it sent one of at most about 24.8 days,
34
- # and otherwise a backoff of 250 ms that doubles per retry.
32
+ # @param retries [Integer] extra attempts for a transient failure, from 0. Each
33
+ # waits the server's `Retry-After` when it sent one of at most about 24.8
34
+ # days, and otherwise a backoff of 250 ms that doubles per retry.
35
35
  # @param timeout [Numeric] seconds one request may take before it is
36
36
  # abandoned, 0 for no bound. Applies per ATTEMPT, so a retried call may take
37
37
  # longer in total, and every call that takes `retries:` also takes
@@ -40,12 +40,14 @@ module VPNDetection
40
40
  # @raise [ArgumentError] for an `api_key` with a control character in it.
41
41
  # @raise [ArgumentError] for a `timeout`, here or on any call, that is
42
42
  # negative, not a finite number, or past 2147483.647 seconds (2**31 - 1 ms),
43
- # the longest curl holds.
43
+ # the longest curl holds, and for a `retries`, here or on any call, that is
44
+ # not an Integer from 0.
44
45
  # @param transport [Transport, nil] override the HTTP layer, mostly for tests.
45
46
  def initialize(api_key: nil, base_url: DEFAULT_BASE_URL, cache: true,
46
47
  cache_max_size: DEFAULT_CACHE_MAX_SIZE, cache_ttl: DEFAULT_CACHE_TTL,
47
48
  concurrency: DEFAULT_CONCURRENCY, retries: DEFAULT_RETRIES,
48
49
  timeout: DEFAULT_TIMEOUT, transport: nil)
50
+ retries = Retries.checked_count(retries)
49
51
  @transport = transport || Transport.new(
50
52
  Transport::Config.new(api_key: api_key, base_url: base_url, timeout: timeout),
51
53
  )
@@ -80,6 +82,7 @@ module VPNDetection
80
82
  def lookup(ip, retries: nil, timeout: nil)
81
83
  # Here as well as in the transport: a bogon or a cached answer returns before any request.
82
84
  Transport.checked_timeout(timeout) unless timeout.nil?
85
+ Retries.checked_count(retries) unless retries.nil?
83
86
  # Judged, cached and sent as the IPv4 address it carries, if it is mapped.
84
87
  ip = Bogon.unmapped(ip)
85
88
  return Bogon.result(ip) if Bogon.bogon?(ip)
@@ -117,6 +120,7 @@ module VPNDetection
117
120
  # this is IS the question: a machine that moves between networks would
118
121
  # otherwise be told where it used to be.
119
122
  def my_ip(retries: nil, timeout: nil)
123
+ Retries.checked_count(retries) unless retries.nil?
120
124
  Retries.with_retries(retries || @retries) do
121
125
  Transport.lookup_result(@transport.myip_request(timeout: timeout).run)
122
126
  end
@@ -142,6 +146,7 @@ module VPNDetection
142
146
  #
143
147
  # @return [Entitlement]
144
148
  def my_entitlement(retries: nil, timeout: nil)
149
+ Retries.checked_count(retries) unless retries.nil?
145
150
  Retries.with_retries(retries || @retries) do
146
151
  Transport.entitlement_result(@transport.entitlement_request(timeout: timeout).run)
147
152
  end
@@ -169,6 +174,7 @@ module VPNDetection
169
174
  raise Error.new(:bad_request, "concurrency must be at least 1, not #{limit.inspect}")
170
175
  end
171
176
  Transport.checked_timeout(timeout) unless timeout.nil?
177
+ Retries.checked_count(retries) unless retries.nil?
172
178
 
173
179
  # An IPv4-mapped address is sent as the address it carries, once however
174
180
  # many of its spellings were asked, and answered under each one asked.
@@ -40,6 +40,7 @@ module VPNDetection
40
40
  @skip = options[:skip]
41
41
  @on_warn = options[:on_warn]
42
42
  @retries = options.fetch(:retries, DEFAULT_RETRIES)
43
+ Retries.checked_count(@retries) unless @retries.nil?
43
44
  @warned = {}
44
45
  @client = options[:client] || Client.new(
45
46
  api_key: options[:api_key],
@@ -15,6 +15,15 @@ module VPNDetection
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 or nil 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)
@@ -335,12 +335,13 @@ module VPNDetection
335
335
  }.freeze
336
336
 
337
337
  # RFC 3339's full-date, the spec's `date`, and its date-time, the spec's
338
- # `date-time`, in the upper case the API sends. Anything else reached the
338
+ # `date-time`, its `T` and `Z` in either case, as RFC 3339 allows: through
339
+ # 5.11.1 a lowercase one failed the call. Anything else reached the
339
340
  # generated reader's Date.parse or Time.parse, which read "monday" as this
340
341
  # week's, "10:00" as today in the process's zone and 30 February as 2 March,
341
342
  # or a lookup's detail handed it back as served (5.10.0, measured 2026-10-21).
342
343
  RFC3339_DATE = /\A(\d{4})-(\d{2})-(\d{2})\z/
343
- RFC3339_DATE_TIME = /\A(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|[+-](\d{2}):(\d{2}))\z/
344
+ RFC3339_DATE_TIME = /\A(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:[Zz]|[+-](\d{2}):(\d{2}))\z/
344
345
 
345
346
  # A date in the form its type names, on a day and at a time that exist: an
346
347
  # hour of 24 rolls over the way a missing day does.
@@ -366,7 +367,9 @@ module VPNDetection
366
367
  when 'Integer' then value.is_a?(Integer)
367
368
  when 'Float' then value.is_a?(Numeric)
368
369
  when 'Boolean' then [true, false].include?(value)
369
- when 'Object' then true
370
+ # The spec's `type: object`, a sample row: through 5.11.2 a row of 1, "x"
371
+ # or [] came back as the answer.
372
+ when 'Object' then value.is_a?(Hash)
370
373
  when /\AArray<(?<inner>.+)>\z/
371
374
  inner = Regexp.last_match(:inner)
372
375
  value.is_a?(Array) && value.each_with_index.all? { |v, i| check_type!(v, inner, "#{where}[#{i}]") }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module VPNDetection
4
- VERSION = '5.11.1'
4
+ VERSION = '5.11.3'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vpndetection
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.11.1
4
+ version: 5.11.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mslm Dev