omq-cli 0.11.1 → 0.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: 82458438956c6684df34eb15fa145d933baf3f37c3a253fba05ed88776d20e5a
4
- data.tar.gz: f828a6b492e7c6b5b220cf666d3f125a5b740d5e4188a363d480aab62acb3ea9
3
+ metadata.gz: bf0669b8fdbac0b56ba21e536417f14203d32449ebd2edd208c3656a5627ad50
4
+ data.tar.gz: 82d522de8b51a202734d66102faf20e1f563276f6492c5acfadafc9d88acd108
5
5
  SHA512:
6
- metadata.gz: 650397c0f746a3cd13e11759ec3fc20126e1f014ab664eced6d4372d2fae9564966db5d3b2293c9ee2f58530cdbd641af9b9b26d6c4ecc44dd1ed3365e7b6872
7
- data.tar.gz: 4840b079b19bde1e7e9b3b702afa3cb87cbdb4203967e1f540b1916def46f46fb39ca6955ae2ed0a47534d2f3495f140cdb542fd2e2d5818003413568fc60afd
6
+ metadata.gz: d45d60e485bdb41a8829ccf7aa0dee9f700e47bb75467f17d3487c61dfdb3afbef767a578db9afdbabc4d7635e8fe13b282dc03ae5e2dda0915a73bdd6d0a82c
7
+ data.tar.gz: 16f717242084209df1ee1e83320ea382490951514fa753674a90797d1ff480921a75a2c63c3c38c567299e85f5594a5d5114981d0404c0ad6942764b45df208d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.2 — 2026-04-10
4
+
5
+ ### Fixed
6
+
7
+ - **Endpoint normalization for `tcp://:PORT`.** Connects now normalize
8
+ to `tcp://localhost:PORT` (preserving Happy Eyeballs) instead of
9
+ `tcp://127.0.0.1:PORT`. Binds normalize to the loopback address
10
+ (`[::1]` on IPv6-capable hosts, `127.0.0.1` otherwise) instead of
11
+ `0.0.0.0` (all interfaces). `tcp://*:PORT` binds still expand to
12
+ `0.0.0.0`. Explicit addresses (`0.0.0.0`, `[::]`, `127.0.0.1`) pass
13
+ through unchanged. The macOS hang (IPv6 `connect(2)` stalling via
14
+ kqueue) is fixed by the connect timeout in omq v0.17.3.
15
+
3
16
  ## 0.11.0 — 2026-04-10
4
17
 
5
18
  ### Added
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "socket"
4
+
3
5
  module OMQ
4
6
  module CLI
5
7
  # Parses and validates command-line arguments for the omq CLI.
@@ -436,10 +438,23 @@ module OMQ
436
438
  opts[:type_name] = type_name.downcase
437
439
  end
438
440
 
439
- normalize = ->(url) { url.sub(%r{\Atcp://\*:}, "tcp://0.0.0.0:").sub(%r{\Atcp://:}, "tcp://localhost:") }
440
- normalize_ep = ->(ep) { Endpoint.new(normalize.call(ep.url), ep.bind?) }
441
- opts[:binds].map!(&normalize)
442
- opts[:connects].map!(&normalize)
441
+ # Normalize shorthand hostnames to concrete addresses.
442
+ #
443
+ # Binds: tcp://:PORT → loopback (::1 if IPv6 available, else 127.0.0.1)
444
+ # tcp://*:PORT → 0.0.0.0 (all interfaces, IPv4)
445
+ # tcp://0.0.0.0:PORT, tcp://[::]:PORT → pass through
446
+ #
447
+ # Connects: tcp://:PORT → localhost (Happy Eyeballs)
448
+ # tcp://*:PORT → localhost
449
+ #
450
+ # The hang on macOS (IPv6 connect(2) not getting ECONNREFUSED via
451
+ # kqueue) is fixed by the connect timeout in Engine::Reconnect.
452
+ loopback = self.class.loopback_bind_host
453
+ normalize_bind = ->(url) { url.sub(%r{\Atcp://\*:}, "tcp://0.0.0.0:").sub(%r{\Atcp://:}, "tcp://#{loopback}:") }
454
+ normalize_connect = ->(url) { url.sub(%r{\Atcp://(\*|):}, "tcp://localhost:") }
455
+ normalize_ep = ->(ep) { Endpoint.new(ep.bind? ? normalize_bind.call(ep.url) : normalize_connect.call(ep.url), ep.bind?) }
456
+ opts[:binds].map!(&normalize_bind)
457
+ opts[:connects].map!(&normalize_connect)
443
458
  opts[:endpoints].map!(&normalize_ep)
444
459
  opts[:in_endpoints].map!(&normalize_ep)
445
460
  opts[:out_endpoints].map!(&normalize_ep)
@@ -526,6 +541,21 @@ module OMQ
526
541
  dups = all_urls.tally.select { |_, n| n > 1 }.keys
527
542
  abort "duplicate endpoint: #{dups.first}" if dups.any?
528
543
  end
544
+
545
+
546
+ # Returns the loopback address for bind normalization.
547
+ # Prefers IPv6 loopback ([::1]) when the host has at least one
548
+ # non-loopback, non-link-local IPv6 address, otherwise 127.0.0.1.
549
+ #
550
+ def self.loopback_bind_host
551
+ @loopback_bind_host ||= begin
552
+ has_ipv6 = ::Socket.getifaddrs.any? { |ifa|
553
+ addr = ifa.addr
554
+ addr&.ipv6? && !addr.ipv6_loopback? && !addr.ipv6_linklocal?
555
+ }
556
+ has_ipv6 ? "[::1]" : "127.0.0.1"
557
+ end
558
+ end
529
559
  end
530
560
  end
531
561
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OMQ
4
4
  module CLI
5
- VERSION = "0.11.1"
5
+ VERSION = "0.11.3"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omq-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.1
4
+ version: 0.11.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrik Wenger
@@ -16,6 +16,9 @@ dependencies:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
18
  version: '0.17'
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: 0.17.3
19
22
  type: :runtime
20
23
  prerelease: false
21
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -23,6 +26,9 @@ dependencies:
23
26
  - - "~>"
24
27
  - !ruby/object:Gem::Version
25
28
  version: '0.17'
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 0.17.3
26
32
  - !ruby/object:Gem::Dependency
27
33
  name: omq-ffi
28
34
  requirement: !ruby/object:Gem::Requirement