bunny 3.3.0 → 3.5.0

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: 1a2354707d0c6f725a8992baaff54c129113312407166c6c7275b6aef9c6d10b
4
- data.tar.gz: 5e0bfc1d60c0ccd0c0718fea83b537a4be5cca88c1c17795a7340d5fa39df168
3
+ metadata.gz: 0c409adf026a09b52061cdbca1d1ea72e6312f11085712f3ba586111fc62fd91
4
+ data.tar.gz: c90db5d9e534fb527899221f0a13fb91e13ef18cc178f064f077a7984da692d5
5
5
  SHA512:
6
- metadata.gz: 85cda03336b6f4130335f39d5641054e8be776e2cb6a14291075954fa5364c62f631044c0a5364fd9473634e9680ed5a46331c1e8ec588470ea9281d0b5943bc
7
- data.tar.gz: 58f094229752eb2718345c078cb6ed2baa7f5642b59f37e211dd8f963e8543960ec0423fb3a7c4b0e7cb3c1a4daf6be1a747d14eb5b3a625b4abd8873d33b9fd
6
+ metadata.gz: 9fadf7743831aef18668dc5394c3a888b89f39f2afeb71c73f99a0553722ed365ed26fa571cd1a0d0ed27240c5b35b2c0fa4b330b9b2acfe25339bebf5e49fca
7
+ data.tar.gz: 465c8430c93d6895c510f4fc8d66493f0c2a17493ce1685175305f8ed6a704017e85098972c074c8bca67fb12611c01e9820d33da21120b3cbdfa37a226a17d9
data/ChangeLog.md CHANGED
@@ -1,3 +1,62 @@
1
+ ## Changes between Bunny 3.5.0 and 3.6.0
2
+
3
+ No changes yet.
4
+
5
+
6
+ ## Changes between Bunny 3.4.0 and 3.5.0 (Oct 25, 2026)
7
+
8
+ ### `no_declare: true` Is Respected by Topology Recovery
9
+
10
+ Queues and exchanges instantiated with `no_declare: true` are no longer redeclared during recovery.
11
+
12
+ GitHub issue: [#751](https://github.com/ruby-amqp/bunny/issues/751)
13
+
14
+ ### `basic.cancel-ok` for Server-Initiated Consumer Cancellations
15
+
16
+ For RabbitMQ versions that declare a corresponding capability, Bunny now responds to a
17
+ server-sent `basic.cancel` with a `basic.cancel-ok`.
18
+
19
+ See [rabbitmq/rabbitmq-server#17734](https://github.com/rabbitmq/rabbitmq-server/issues/17734) and [rabbitmq/rabbitmq-java-client#2113](https://github.com/rabbitmq/rabbitmq-java-client/issues/2113) for context.
20
+
21
+ ### `Bunny::Session#server_has_capability?`
22
+
23
+ New `Bunny::Session#server_has_capability?` takes a capability name as a symbol.
24
+
25
+ ### `Bunny::DeliveryInfo#to_s` and `#inspect` Use Channel and Consumer Identifiers
26
+
27
+ `Bunny::DeliveryInfo#to_s` and `#inspect` now include the channel number and consumer tag
28
+ but avoid printing the actual data structures.
29
+
30
+ See [ruby-amqp/kicks#48](https://github.com/ruby-amqp/kicks/pull/48) for background.
31
+
32
+
33
+ ## Changes between Bunny 3.3.0 and 3.4.0 (Sep 18, 2026)
34
+
35
+ ### Ruby 3.2 or Later Is Now Required
36
+
37
+ `required_ruby_version` was raised from `3.0` to `3.2`.
38
+
39
+
40
+ ### Client Certificate Chains
41
+
42
+ If `tls_cert` points at a certificate bundle (chain), the entire chain will now be sent.
43
+
44
+ Previously only the first (leaf) certificate was sent, unintentionally.
45
+
46
+ Contributed by @eglitobias.
47
+
48
+ GitHub issues: [#749](https://github.com/ruby-amqp/bunny/issues/749), [#750](https://github.com/ruby-amqp/bunny/pull/750)
49
+
50
+
51
+ ### TLS Handshake Now Respects `connect_timeout`
52
+
53
+ A peer that accepted the TCP connection but never completed the TLS handshake
54
+ could block `Bunny::Session#start` indefinitely. The handshake now gives up after
55
+ `connect_timeout` and the connection fails over to the next endpoint.
56
+
57
+ This requires the `openssl` gem `3.3.0` or later.
58
+
59
+
1
60
  ## Changes between Bunny 3.2.0 and 3.3.0 (Aug 29, 2026)
2
61
 
3
62
  ### Passive Declarations No Longer Affect Topology Recovery
data/lib/bunny/channel.rb CHANGED
@@ -523,7 +523,6 @@ module Bunny
523
523
 
524
524
  q = find_queue(name) || Bunny::Queue.new(self, name, opts)
525
525
 
526
- record_queue(q) unless opts[:passive]
527
526
  register_queue(q)
528
527
  end
529
528
 
@@ -652,7 +651,6 @@ module Bunny
652
651
  )
653
652
  q = find_queue(name) || Bunny::Queue.new(self, name, final_opts)
654
653
 
655
- record_queue(q)
656
654
  register_queue(q)
657
655
  end
658
656
 
@@ -2130,6 +2128,13 @@ module Bunny
2130
2128
  pending_server_named_queue_declaration?
2131
2129
  end
2132
2130
 
2131
+ # @private
2132
+ def send_basic_cancel_ok(consumer_tag)
2133
+ tag = consumer_tag.to_s
2134
+ payload = [AMQ::Protocol::Basic::CancelOk.index, tag.bytesize, tag].pack("NCa*")
2135
+ @connection.send_frame(AMQ::Protocol::MethodFrame.new(payload, @id))
2136
+ end
2137
+
2133
2138
  # @private
2134
2139
  def handle_method(method)
2135
2140
  @logger.debug { "Channel#handle_frame on channel #{@id}: #{method.inspect}" }
@@ -2171,6 +2176,8 @@ module Bunny
2171
2176
  when AMQ::Protocol::Basic::ConsumeOk then
2172
2177
  @continuations.push(method)
2173
2178
  when AMQ::Protocol::Basic::Cancel then
2179
+ send_basic_cancel_ok(method.consumer_tag) if @connection.server_has_capability?(:accept_consumer_cancel_ok)
2180
+
2174
2181
  if consumer = @consumers[method.consumer_tag]
2175
2182
  @work_pool.submit do
2176
2183
  begin
@@ -64,12 +64,12 @@ module Bunny
64
64
 
65
65
  # @private
66
66
  def to_s
67
- to_hash.to_s
67
+ printable_hash.to_s
68
68
  end
69
69
 
70
70
  # @private
71
71
  def inspect
72
- to_hash.inspect
72
+ printable_hash.inspect
73
73
  end
74
74
 
75
75
  # @return [String] Consumer tag this delivery is for
@@ -97,5 +97,11 @@ module Bunny
97
97
  def routing_key
98
98
  @basic_deliver.routing_key
99
99
  end
100
+
101
+ private
102
+
103
+ def printable_hash
104
+ to_hash.merge(consumer: @consumer&.consumer_tag, channel: @channel&.number)
105
+ end
100
106
  end
101
107
  end
@@ -108,9 +108,6 @@ module Bunny
108
108
 
109
109
  # for basic.return dispatch and such
110
110
  @channel.register_exchange(self)
111
- # for topology recovery. A passive declaration does not own the exchange,
112
- # so it must not overwrite what was recorded for it earlier
113
- @channel.record_exchange(self) unless @options[:passive]
114
111
  end
115
112
 
116
113
  # @return [Boolean] true if this exchange was declared as durable (will survive broker restart).
data/lib/bunny/queue.rb CHANGED
@@ -91,9 +91,6 @@ module Bunny
91
91
 
92
92
  # for basic.deliver dispatch and such
93
93
  @channel.register_queue(self)
94
- # for topology recovery. A passive declaration does not own the queue,
95
- # so it must not overwrite what was recorded for it earlier
96
- @channel.record_queue(self) unless @options[:passive]
97
94
  end
98
95
 
99
96
  # @return [Boolean] true if this queue was declared as durable (will survive broker restart).
data/lib/bunny/session.rb CHANGED
@@ -1593,6 +1593,12 @@ module Bunny
1593
1593
  to_s
1594
1594
  end
1595
1595
 
1596
+ # @param [Symbol] capability a server capability name
1597
+ # @return [Boolean] true if the server advertises the capability as supported
1598
+ def server_has_capability?(capability)
1599
+ (@server_capabilities || {})[capability.to_s] == true
1600
+ end
1601
+
1596
1602
  protected
1597
1603
 
1598
1604
  # @private
@@ -108,7 +108,12 @@ module Bunny
108
108
  def connect
109
109
  if uses_tls?
110
110
  begin
111
- @socket.connect
111
+ tls_handshake
112
+ rescue ClientTimeout => e
113
+ @logger.error { "TLS connection failed: #{e.message}" }
114
+ close
115
+ @status = :not_connected
116
+ raise Bunny::TCPConnectionFailed.new(e, self.hostname, self.port)
112
117
  rescue OpenSSL::SSL::SSLError => e
113
118
  @logger.error { "TLS connection failed: #{e.message}" }
114
119
  raise e
@@ -335,6 +340,17 @@ module Bunny
335
340
  @socket
336
341
  end
337
342
 
343
+ # Needs the openssl gem >= 3.3, which added SSLSocket#timeout= and made #connect honour it
344
+ def tls_handshake
345
+ previous_timeout = @socket.timeout
346
+ @socket.timeout = @connect_timeout if @connect_timeout
347
+ @socket.connect
348
+ rescue IO::TimeoutError
349
+ raise ClientTimeout, "TLS handshake timed out after #{@connect_timeout} seconds"
350
+ ensure
351
+ @socket.timeout = previous_timeout
352
+ end
353
+
338
354
  def maybe_initialize_socket
339
355
  initialize_socket if !@socket || closed?
340
356
  end
@@ -481,7 +497,12 @@ module Bunny
481
497
  end
482
498
 
483
499
  def initialize_tls_context(ctx, opts = {})
484
- ctx.cert = OpenSSL::X509::Certificate.new(@tls_certificate) if @tls_certificate
500
+ if @tls_certificate
501
+ leaf, *chain = OpenSSL::X509::Certificate.load(@tls_certificate)
502
+
503
+ ctx.cert = leaf
504
+ ctx.extra_chain_cert = chain unless chain.empty?
505
+ end
485
506
  ctx.key = OpenSSL::PKey.read(@tls_key) if @tls_key
486
507
  ctx.cert_store = if @tls_certificate_store
487
508
  @tls_certificate_store
data/lib/bunny/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "3.3.0"
5
+ VERSION = "3.5.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bunny
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Duncan
@@ -47,6 +47,20 @@ dependencies:
47
47
  - - ">="
48
48
  - !ruby/object:Gem::Version
49
49
  version: '1.7'
50
+ - !ruby/object:Gem::Dependency
51
+ name: openssl
52
+ requirement: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '3.3'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '3.3'
50
64
  - !ruby/object:Gem::Dependency
51
65
  name: sorted_set
52
66
  requirement: !ruby/object:Gem::Requirement
@@ -129,14 +143,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
129
143
  requirements:
130
144
  - - ">="
131
145
  - !ruby/object:Gem::Version
132
- version: '3.0'
146
+ version: '3.2'
133
147
  required_rubygems_version: !ruby/object:Gem::Requirement
134
148
  requirements:
135
149
  - - ">="
136
150
  - !ruby/object:Gem::Version
137
151
  version: '0'
138
152
  requirements: []
139
- rubygems_version: 4.0.16
153
+ rubygems_version: 3.6.9
140
154
  specification_version: 4
141
155
  summary: Popular easy to use Ruby client for RabbitMQ
142
156
  test_files: []