sparoid 2.1.0 → 2.1.2

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: df9de779b1b4fcfd29f3f0ad3ad986001ecc39b61fbe3aeff36c9b3cb5409327
4
- data.tar.gz: 56789005516d3c0c2e3b4799f1cf3d6c9873465ff3516b27edee0649b2f5d373
3
+ metadata.gz: b9b409fe26f6c1e4e114ef772a721c55fe5c33c41ad1e45319cdf391074d084b
4
+ data.tar.gz: 4eaf23fb8ed1afb254bfce4956d68618eb5c31581cd5e36174ef950eaec87320
5
5
  SHA512:
6
- metadata.gz: ce6cca5c5219a9f7f99fb6fa34b16efee1d60acae4e5f6bf639524e8ebfd5d4cc805953e9df48656aae11211b25aa824b28751478691a8a293ad3704bd464416
7
- data.tar.gz: bc288e38f49a5c54f10f338d943169dd662932f516fbdccc6c7d5dc75857da7e0c73dbf2dcb3e5082ee7e769f70552deb12f23a11f8f5cca7f993cc4d6104ad0
6
+ metadata.gz: 8cda0c092e0fcea01748df2a4b5d26f480f6162135aea3b9863e39c8a224f7ed7ca4e105b982f032605b49dd0a7fa467ea92a3776b16592c858f7b38bb1ce2b4
7
+ data.tar.gz: ddb2ac64f0db2115b49712c6d7aebac1e29bed8dbf52354ee806282be72955f6a08a35794965f727221152de360796c82ceb4a79554f2c95283fce4ffc12cb9c
@@ -14,9 +14,9 @@ jobs:
14
14
  ruby: [ 3.2, 3.3, 3.4, 4.0, ruby-head ]
15
15
  runs-on: ubuntu-latest
16
16
  steps:
17
- - uses: actions/checkout@v4
18
- - uses: ruby/setup-ruby@v1
19
- with:
20
- ruby-version: ${{ matrix.ruby }}
21
- bundler-cache: true
22
- - run: bundle exec rake
17
+ - uses: actions/checkout@v6
18
+ - uses: ruby/setup-ruby@v1
19
+ with:
20
+ ruby-version: ${{ matrix.ruby }}
21
+ bundler-cache: true
22
+ - run: bundle exec rake
@@ -0,0 +1,20 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ release:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+ - uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: '3.4'
19
+ bundler-cache: true
20
+ - uses: rubygems/release-gem@v1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## [2.1.2] - 2026-04-30
2
+
3
+ - Skip addresses that fail synchronous connect in fdpass (#20)
4
+
5
+ ## [2.1.1] - 2026-04-13
6
+
7
+ - Remove the usage of Timeout (#19)
8
+
1
9
  ## [2.1.0] - 2026-03-10
2
10
 
3
11
  - Aligning CLI with Crystal client interface (`send`/`connect` subcommands with flags)
data/README.md CHANGED
@@ -34,7 +34,15 @@ Host *.example.com
34
34
 
35
35
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
36
36
 
37
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
37
+ To install this gem onto your local machine, run `bundle exec rake install`.
38
+
39
+ To release a new version:
40
+
41
+ 1. Bump `Sparoid::VERSION` in `lib/sparoid/version.rb` and add an entry to `CHANGELOG.md`.
42
+ 2. Open a PR with the bump, get it merged into `main`.
43
+ 3. Push a tag matching the new version, e.g. `git tag v2.1.2 && git push origin v2.1.2`.
44
+
45
+ The `Release` GitHub Actions workflow then builds the gem and publishes it to [rubygems.org](https://rubygems.org) via OIDC trusted publishing — no API key required.
38
46
 
39
47
  ## Contributing
40
48
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sparoid
4
- VERSION = "2.1.0"
4
+ VERSION = "2.1.2"
5
5
  end
data/lib/sparoid.rb CHANGED
@@ -4,7 +4,7 @@ require_relative "sparoid/version"
4
4
  require "socket"
5
5
  require "openssl"
6
6
  require "resolv"
7
- require "timeout"
7
+ require "net/http"
8
8
 
9
9
  # Single Packet Authorisation client
10
10
  module Sparoid # rubocop:disable Metrics/ModuleLength
@@ -48,12 +48,18 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
48
48
  end
49
49
 
50
50
  # Connect to a TCP server and pass the FD to the parent
51
- def fdpass(addrs, port, connect_timeout: 10) # rubocop:disable Metrics/AbcSize
52
- # try connect to all IPs
53
- sockets = addrs.map do |addr|
54
- Socket.new(addr.afamily, Socket::SOCK_STREAM).tap do |s|
55
- s.connect_nonblock(Socket.sockaddr_in(port, addr.ip_address), exception: false)
56
- end
51
+ def fdpass(addrs, port, connect_timeout: 10) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
52
+ # try connect to all IPs; skip addrs that fail synchronously (e.g. no route)
53
+ viable_addrs = []
54
+ sockets = addrs.filter_map do |addr|
55
+ s = Socket.new(addr.afamily, Socket::SOCK_STREAM)
56
+ s.connect_nonblock(Socket.sockaddr_in(port, addr.ip_address), exception: false)
57
+ viable_addrs << addr
58
+ s
59
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNREFUSED => e
60
+ warn "Sparoid: skip #{addr.ip_address}: #{e.message}"
61
+ s&.close
62
+ nil
57
63
  end
58
64
  # wait for any socket to be connected
59
65
  until sockets.empty?
@@ -62,7 +68,7 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
62
68
  writeable.each do |s|
63
69
  idx = sockets.index(s)
64
70
  sockets.delete_at(idx) # don't retry this socket again
65
- addr = addrs.delete_at(idx) # find the IP for the socket
71
+ addr = viable_addrs.delete_at(idx) # find the IP for the socket
66
72
  begin
67
73
  s.connect_nonblock(Socket.sockaddr_in(port, addr.ip_address)) # check for errors
68
74
  rescue Errno::EISCONN
@@ -182,25 +188,15 @@ module Sparoid # rubocop:disable Metrics/ModuleLength
182
188
  end
183
189
  end
184
190
 
185
- def public_ips(port = 80) # rubocop:disable Metrics/AbcSize
191
+ def public_ips(port = 80)
186
192
  URLS.map do |host|
187
- Timeout.timeout(5) do
188
- Socket.tcp(host, port, connect_timeout: 3, resolv_timeout: 3) do |sock|
189
- sock.sync = true
190
- sock.print "GET / HTTP/1.1\r\nHost: #{host}\r\nConnection: close\r\n\r\n"
191
- status = sock.readline(chomp: true)
192
- raise(ResolvError, "#{host}:#{port} response: #{status}") unless status.start_with? "HTTP/1.1 200 "
193
-
194
- content_length = 0
195
- until (header = sock.readline(chomp: true)).empty?
196
- if (m = header.match(/^Content-Length: (\d+)/))
197
- content_length = m[1].to_i
198
- end
199
- end
200
- ip = sock.read(content_length).chomp
201
- string_to_ip(ip)
202
- end
203
- end
193
+ http = Net::HTTP.new(host, port)
194
+ http.open_timeout = 3
195
+ http.read_timeout = 5
196
+ response = http.get("/")
197
+ raise(ResolvError, "#{host}:#{port} response: #{response.code}") unless response.is_a?(Net::HTTPSuccess)
198
+
199
+ string_to_ip(response.body.chomp)
204
200
  rescue StandardError
205
201
  nil
206
202
  end.compact
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sparoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carl Hörberg
@@ -17,6 +17,7 @@ extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
19
  - ".github/workflows/main.yml"
20
+ - ".github/workflows/release.yml"
20
21
  - ".gitignore"
21
22
  - ".rubocop.yml"
22
23
  - CHANGELOG.md