pubnub 6.0.2 → 6.1.1

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: daa6325913f4e4fa3b9a42a89dcb268ec8b9174ca7c30d1b26e0b94bb4e8d3c3
4
- data.tar.gz: e8cdc5e228388108d80cc51daa58e7a0a08d71aa69f51ae206fbcfe020aa7433
3
+ metadata.gz: 2f484475c6f9a486f2f4acb5c1882edb3a5647bd5c3fbfe2a16d521221568488
4
+ data.tar.gz: '09949bfd0ce89c476eb315783549e8fadde4681b3764311cf96576fb566bd79f'
5
5
  SHA512:
6
- metadata.gz: 3a2c68e75729803cd99a560b82b4974929a8e10d8b8c2845c4146655055c9505ea606b58427eb631860fdded94a8df7b16f36b35617ac59e2c5dbb50ed8d46da
7
- data.tar.gz: 8cb3e679e395a59214da0a21233ae080097a4600a6351644a59021e80dff85f9fb86e22a6b784d7c00092ed3944d80d7cbb89276842becc0df998a7e15d8bbf3
6
+ metadata.gz: 25cf31e4588c18a6458c9c2ddeb25862b02cd14339cd50ae59b3e9818adc756a05ba1bdfc9bdbaee5587469334b4633dddf9b5216552974d50d1ddebd116fcfa
7
+ data.tar.gz: f52d1c3fdc09ee349f25639d55844829261d514b4963e42f33b3a402cbc71f05381ea33b65216116ecc36fd6bed645827c3731b866a78c474ed7d9bb8230209f
data/.pubnub.yml CHANGED
@@ -1,6 +1,28 @@
1
1
  ---
2
- version: "6.0.2"
2
+ version: "6.1.1"
3
3
  changelog:
4
+ - date: 2026-07-21
5
+ version: v6.1.1
6
+ changes:
7
+ - type: bug
8
+ text: "`Pubnub::Cbor` now enforces a recursion-depth cap, a per-container length cap, and a total input size cap. Malformed or attacker-crafted tokens reaching `Pubnub::Client#parse_token` raise `Pubnub::Cbor::DecodeError` instead of hanging the caller or triggering `SystemStackError`."
9
+ - type: bug
10
+ text: "`Pubnub::Constants::DEFAULT_SSL` flipped from `false` to `true`. Integrators must now opt out explicitly to send traffic in cleartext."
11
+ - type: bug
12
+ text: "The Requested URI debug entry in `Pubnub::Event#uri` now masks the `signature` and `pnsig` query parameter values."
13
+ - date: 2026-06-15
14
+ version: v6.1.0
15
+ changes:
16
+ - type: feature
17
+ text: "Replace `httpclient` gem with `httpx`, enabling HTTP/2 support."
18
+ - type: feature
19
+ text: "Add `HttpDispatcher` and `HttpResponse` wrapper classes for a consistent internal API ."
20
+ - type: feature
21
+ text: "Update timeout, proxy, and keepalive configuration to use HTTPX equivalents."
22
+ - type: feature
23
+ text: "Update error handling to use `HTTPX::TimeoutError`."
24
+ - type: improvement
25
+ text: "Update specs and test dependencies accordingly."
4
26
  - date: 2026-03-03
5
27
  version: v6.0.2
6
28
  changes:
@@ -634,7 +656,7 @@ sdks:
634
656
  - x86-64
635
657
  - distribution-type: package
636
658
  distribution-repository: RubyGems
637
- package-name: pubnub-6.0.2.gem
659
+ package-name: pubnub-6.1.1.gem
638
660
  location: https://rubygems.org/gems/pubnub
639
661
  requires:
640
662
  - name: addressable
@@ -739,8 +761,8 @@ sdks:
739
761
  - x86-64
740
762
  - distribution-type: library
741
763
  distribution-repository: GitHub release
742
- package-name: pubnub-6.0.2.gem
743
- location: https://github.com/pubnub/ruby/releases/download/v6.0.2/pubnub-6.0.2.gem
764
+ package-name: pubnub-6.1.1.gem
765
+ location: https://github.com/pubnub/ruby/releases/download/v6.1.1/pubnub-6.1.1.gem
744
766
  requires:
745
767
  - name: addressable
746
768
  min-version: 2.0.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ ## v6.1.1
2
+ July 21 2026
3
+
4
+ #### Fixed
5
+ - `Pubnub::Cbor` now enforces a recursion-depth cap, a per-container length cap, and a total input size cap. Malformed or attacker-crafted tokens reaching `Pubnub::Client#parse_token` raise `Pubnub::Cbor::DecodeError` instead of hanging the caller or triggering `SystemStackError`.
6
+ - `Pubnub::Constants::DEFAULT_SSL` flipped from `false` to `true`. Integrators must now opt out explicitly to send traffic in cleartext.
7
+ - The Requested URI debug entry in `Pubnub::Event#uri` now masks the `signature` and `pnsig` query parameter values, per the SDK log practices ADR. `auth` and `token` remain visible at DEBUG since they are permitted URL parameters.
8
+
9
+ ## v6.1.0
10
+ June 15 2026
11
+
12
+ #### Added
13
+ - Replace `httpclient` gem with `httpx`, enabling HTTP/2 support.
14
+ - Add `HttpDispatcher` and `HttpResponse` wrapper classes for a consistent internal API .
15
+ - Update timeout, proxy, and keepalive configuration to use HTTPX equivalents.
16
+ - Update error handling to use `HTTPX::TimeoutError`.
17
+
18
+ #### Modified
19
+ - Update specs and test dependencies accordingly.
20
+
1
21
  ## v6.0.2
2
22
  March 03 2026
3
23
 
data/Gemfile CHANGED
@@ -11,8 +11,8 @@ group :test do
11
11
  gem 'rubocop'
12
12
  gem 'standard'
13
13
  gem 'simplecov', '>= 0.21.2', require: false
14
- gem 'vcr'
15
- gem 'webmock'
14
+ gem 'vcr', '>= 6.4'
15
+ gem 'webmock', '>= 3.14'
16
16
  gem 'cucumber'
17
17
  end
18
18
 
data/Gemfile.lock CHANGED
@@ -1,13 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pubnub (6.0.2)
4
+ pubnub (6.1.1)
5
5
  addressable (>= 2.0.0)
6
+ base64
6
7
  concurrent-ruby (~> 1.3.4)
7
8
  concurrent-ruby-edge (~> 0.7.1)
8
9
  dry-validation (~> 1.0)
9
- httpclient (~> 2.8, >= 2.8.3)
10
+ httpx (>= 1.0)
10
11
  json (>= 2.2.0, < 3)
12
+ logger
13
+ ostruct
11
14
  timers (>= 4.3.0)
12
15
 
13
16
  GEM
@@ -17,7 +20,7 @@ GEM
17
20
  public_suffix (>= 2.0.2, < 7.0)
18
21
  ast (2.4.2)
19
22
  awesome_print (1.9.2)
20
- base64 (0.2.0)
23
+ base64 (0.3.0)
21
24
  bigdecimal (3.1.8)
22
25
  binding_of_caller (1.0.1)
23
26
  debug_inspector (>= 1.2.0)
@@ -94,14 +97,18 @@ GEM
94
97
  zeitwerk (~> 2.6)
95
98
  ffi (1.17.0)
96
99
  hashdiff (1.1.1)
97
- httpclient (2.8.3)
100
+ http-2 (1.1.3)
101
+ httpx (1.7.8)
102
+ http-2 (>= 1.1.3)
98
103
  interception (0.5)
99
104
  json (2.7.2)
100
105
  language_server-protocol (3.17.0.3)
101
106
  lint_roller (1.1.0)
107
+ logger (1.7.0)
102
108
  method_source (1.1.0)
103
109
  mini_mime (1.1.5)
104
110
  multi_test (1.1.0)
111
+ ostruct (0.6.3)
105
112
  parallel (1.26.3)
106
113
  parser (3.3.5.0)
107
114
  ast (~> 2.4.1)
@@ -174,8 +181,7 @@ GEM
174
181
  ffi (~> 1.1)
175
182
  timers (4.3.5)
176
183
  unicode-display_width (2.6.0)
177
- vcr (6.3.1)
178
- base64
184
+ vcr (6.4.0)
179
185
  webmock (3.24.0)
180
186
  addressable (>= 2.8.0)
181
187
  crack (>= 0.3.2)
@@ -200,8 +206,8 @@ DEPENDENCIES
200
206
  rubocop
201
207
  simplecov (>= 0.21.2)
202
208
  standard
203
- vcr
204
- webmock
209
+ vcr (>= 6.4)
210
+ webmock (>= 3.14)
205
211
 
206
212
  BUNDLED WITH
207
213
  2.4.20
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.2
1
+ 6.1.1
@@ -12,7 +12,7 @@ Before do |scenario|
12
12
  expect(ENV['SERVER_PORT']).not_to be_nil
13
13
  @pn_configuration = {
14
14
  origin: ENV['SERVER_HOST'] + ":" + ENV['SERVER_PORT'],
15
- isSecure: false,
15
+ ssl: false,
16
16
  }
17
17
  }
18
18
 
data/lib/pubnub/cbor.rb CHANGED
@@ -1,5 +1,10 @@
1
1
  module Pubnub
2
2
  class Cbor
3
+ class DecodeError < StandardError; end
4
+
5
+ MAX_DEPTH = 32
6
+ MAX_CONTAINER_LENGTH = 65_536
7
+ MAX_INPUT_SIZE = 1_048_576
3
8
 
4
9
  private
5
10
 
@@ -43,9 +48,14 @@ module Pubnub
43
48
  end
44
49
  end
45
50
 
51
+ def take_bytes(data, count)
52
+ raise DecodeError, "Truncated CBOR input" if data.size < count
53
+ data.shift(count)
54
+ end
55
+
46
56
  def decode_integer(data, additional)
47
57
  if ADDITIONAL_LENGTH_BYTES.member?(additional)
48
- bytearray_to_i(data.shift(ADDITIONAL_LENGTH_BYTES[additional]))
58
+ bytearray_to_i(take_bytes(data, ADDITIONAL_LENGTH_BYTES[additional]))
49
59
  else
50
60
  additional
51
61
  end
@@ -55,7 +65,10 @@ module Pubnub
55
65
  if additional <= 23
56
66
  additional
57
67
  else
58
- bytes = bytearray_to_i(data.shift(ADDITIONAL_LENGTH_BYTES[additional]))
68
+ raise DecodeError, "Invalid float additional value" unless ADDITIONAL_LENGTH_BYTES.member?(additional)
69
+
70
+ bytes = bytearray_to_i(take_bytes(data, ADDITIONAL_LENGTH_BYTES[additional]))
71
+
59
72
  case (additional)
60
73
  when ADDITIONAL_LENGTH_1B
61
74
  bytes
@@ -98,44 +111,57 @@ module Pubnub
98
111
  result = []
99
112
 
100
113
  loop do
114
+ raise DecodeError, "Truncated CBOR input" if data.empty?
101
115
  byte = data.shift
102
116
  break if byte == INDEFINITE_BREAK
103
117
  result.append(byte)
104
- break if data.empty?
105
118
  end
106
119
  result
107
120
  end
108
121
 
109
- def compute_length(data, additional)
110
- if ADDITIONAL_LENGTH_BYTES.member?(additional)
111
- bytearray_to_i(data.shift(ADDITIONAL_LENGTH_BYTES[additional]))
112
- else
113
- additional
122
+ def compute_container_length(data, additional, min_element_bytes)
123
+ length = if ADDITIONAL_LENGTH_BYTES.member?(additional)
124
+ bytearray_to_i(take_bytes(data, ADDITIONAL_LENGTH_BYTES[additional]))
125
+ else
126
+ additional
127
+ end
128
+
129
+ if length > MAX_CONTAINER_LENGTH
130
+ raise DecodeError, "CBOR container length #{length} exceeds maximum #{MAX_CONTAINER_LENGTH}"
131
+ end
132
+
133
+ if length * min_element_bytes > data.size
134
+ raise DecodeError, "CBOR container length #{length} exceeds remaining input"
114
135
  end
136
+
137
+ length
115
138
  end
116
139
 
117
140
  def decode_string(data, additional)
118
141
  if additional == ADDITIONAL_TYPE_INDEFINITE
119
142
  indefinite_data(data).pack('C*').force_encoding('UTF-8')
120
143
  else
121
- length = compute_length(data, additional)
122
- data.shift(length).pack('C*').force_encoding('UTF-8')
144
+ length = compute_container_length(data, additional, 1)
145
+ take_bytes(data, length).pack('C*').force_encoding('UTF-8')
123
146
  end
124
147
  end
125
148
 
126
- def decode_map(data, additional)
127
- length = compute_length(data, additional)
149
+ def decode_map(data, additional, depth)
150
+ length = compute_container_length(data, additional, 2)
128
151
  result = Hash.new
129
- (1..length).each { result.store(parse_data(data), parse_data(data)) }
152
+ length.times { result.store(parse_data(data, depth), parse_data(data, depth)) }
130
153
  result
131
154
  end
132
155
 
133
- def decode_array(data, additional)
134
- length = compute_length(data, additional)
135
- (1..length).map { parse_data(data) }
156
+ def decode_array(data, additional, depth)
157
+ length = compute_container_length(data, additional, 1)
158
+ Array.new(length) { parse_data(data, depth) }
136
159
  end
137
160
 
138
- def parse_data(data)
161
+ def parse_data(data, depth = 0)
162
+ raise DecodeError, "CBOR nesting depth exceeds #{MAX_DEPTH}" if depth > MAX_DEPTH
163
+ raise DecodeError, "Truncated CBOR input" if data.empty?
164
+
139
165
  byte = data.shift
140
166
 
141
167
  case (byte)
@@ -163,9 +189,9 @@ module Pubnub
163
189
  when TYPE_TEXT_STRING
164
190
  decode_string(data, additional)
165
191
  when TYPE_ARRAY
166
- decode_array(data, additional)
192
+ decode_array(data, additional, depth + 1)
167
193
  when TYPE_HASHMAP
168
- decode_map(data, additional)
194
+ decode_map(data, additional, depth + 1)
169
195
  else
170
196
  nil
171
197
  end
@@ -175,7 +201,11 @@ module Pubnub
175
201
  public
176
202
 
177
203
  def decode(value)
178
- parse_data(value)
204
+ if value.size > MAX_INPUT_SIZE
205
+ raise DecodeError, "CBOR input size #{value.size} exceeds maximum #{MAX_INPUT_SIZE}"
206
+ end
207
+
208
+ parse_data(value.dup)
179
209
  end
180
210
  end
181
211
 
data/lib/pubnub/client.rb CHANGED
@@ -268,11 +268,11 @@ module Pubnub
268
268
  if sync
269
269
  @env[:req_dispatchers_pool][:sync][origin] ||= {}
270
270
  @env[:req_dispatchers_pool][:sync][origin][event_type] ||=
271
- setup_httpclient(event_type)
271
+ setup_httpx_session(event_type)
272
272
  else
273
273
  @env[:req_dispatchers_pool][:async][origin] ||= {}
274
274
  @env[:req_dispatchers_pool][:async][origin][event_type] ||=
275
- setup_httpclient(event_type)
275
+ setup_httpx_session(event_type)
276
276
  end
277
277
  end
278
278
 
@@ -359,33 +359,43 @@ module Pubnub
359
359
  @env[:state][event.origin] ||= {}
360
360
  end
361
361
 
362
- def setup_httpclient(event_type)
363
- hc = if ENV["HTTP_PROXY"]
364
- HTTPClient.new(ENV["HTTP_PROXY"])
365
- else
366
- HTTPClient.new
367
- end
368
-
369
- case event_type
370
- when :subscribe_event
371
- hc.connect_timeout = @env[:s_open_timeout]
372
- hc.send_timeout = @env[:s_send_timeout]
373
- hc.receive_timeout = @env[:s_read_timeout]
374
- unless @env[:disable_keepalive] || @env[:disable_subscribe_keepalive]
375
- hc.keep_alive_timeout = @env[:idle_timeout]
376
- hc.tcp_keepalive = true
362
+ def setup_httpx_session(event_type)
363
+ timeout_opts = case event_type
364
+ when :subscribe_event
365
+ {
366
+ connect_timeout: @env[:s_open_timeout],
367
+ write_timeout: @env[:s_send_timeout] || @env[:s_open_timeout],
368
+ read_timeout: @env[:s_read_timeout]
369
+ }
370
+ when :single_event
371
+ {
372
+ connect_timeout: @env[:open_timeout],
373
+ write_timeout: @env[:send_timeout] || @env[:open_timeout],
374
+ read_timeout: @env[:read_timeout]
375
+ }
377
376
  end
378
- when :single_event
379
- hc.connect_timeout = @env[:open_timeout]
380
- hc.send_timeout = @env[:send_timeout]
381
- hc.receive_timeout = @env[:read_timeout]
382
- unless @env[:disable_keepalive] || @env[:disable_non_subscribe_keepalive]
383
- hc.keep_alive_timeout = @env[:idle_timeout]
384
- hc.tcp_keepalive = true
377
+
378
+ keepalive_enabled = case event_type
379
+ when :subscribe_event
380
+ !(@env[:disable_keepalive] || @env[:disable_subscribe_keepalive])
381
+ when :single_event
382
+ !(@env[:disable_keepalive] || @env[:disable_non_subscribe_keepalive])
385
383
  end
384
+
385
+ if keepalive_enabled
386
+ timeout_opts[:keep_alive_timeout] = @env[:idle_timeout]
387
+ end
388
+
389
+ options = { timeout: timeout_opts }
390
+ httpx = HTTPX.plugin(:persistent)
391
+
392
+ if ENV["HTTP_PROXY"]
393
+ options[:proxy] = { uri: ENV["HTTP_PROXY"] }
394
+ httpx = httpx.plugin(:proxy)
386
395
  end
387
396
 
388
- hc
397
+ session = httpx.with(**options)
398
+ HttpDispatcher.new(session, keepalive_enabled: keepalive_enabled)
389
399
  end
390
400
 
391
401
  def validate!(env)
@@ -20,7 +20,7 @@ module Pubnub
20
20
  DEFAULT_TTL = 1440
21
21
  DEFAULT_REGION = '0'.freeze
22
22
  DEFAULT_USE_RANDOM_IV = true
23
- DEFAULT_SSL = false
23
+ DEFAULT_SSL = true
24
24
  REQUEST_MESSAGE_COUNT_THRESHOLD = 0
25
25
  MAXIMUM_HERE_NOW_COUNT = 1000
26
26
 
@@ -5,7 +5,7 @@ module Pubnub
5
5
  # Module that holds formatters for events
6
6
  module EFormatter
7
7
  def format_envelopes(response, request)
8
- if response.is_a?(HTTPClient::TimeoutError) || response.is_a?(OpenSSL::SSL::SSLError)
8
+ if response.is_a?(HTTPX::TimeoutError) || response.is_a?(OpenSSL::SSL::SSLError)
9
9
  return error_envelope(nil,
10
10
  response,
11
11
  request: request,
data/lib/pubnub/event.rb CHANGED
@@ -88,7 +88,7 @@ module Pubnub
88
88
  uri += path
89
89
  uri += '?' + Formatter.params_hash_to_url_params(parameters)
90
90
  uri += "&signature=#{sa_signature}" if sa_signature
91
- Pubnub.logger.debug('Pubnub::Event') { "Requested URI: #{uri}" }
91
+ Pubnub.logger.debug('Pubnub::Event') { "Requested URI: #{uri.gsub(/([?&](?:signature|pnsig)=)[^&#]*/i, '\1***')}" }
92
92
  URI uri
93
93
  end
94
94
 
@@ -251,7 +251,7 @@ module Pubnub
251
251
  when JSON::ParserError
252
252
  error_category = Pubnub::Constants::STATUS_NON_JSON_RESPONSE
253
253
  code = req_res_objects[:response].code
254
- when HTTPClient::TimeoutError
254
+ when HTTPX::TimeoutError
255
255
  error_category = Pubnub::Constants::STATUS_TIMEOUT
256
256
  code = 408
257
257
  when OpenSSL::SSL::SSLError
@@ -0,0 +1,40 @@
1
+ module Pubnub
2
+ class HttpDispatcher
3
+ attr_reader :tcp_keepalive
4
+
5
+ def initialize(httpx_session, keepalive_enabled: true)
6
+ @session = httpx_session
7
+ @tcp_keepalive = keepalive_enabled
8
+ end
9
+
10
+ def get(url, header: {})
11
+ execute { @session.get(url, headers: header) }
12
+ end
13
+
14
+ def post(url, body: '', header: {})
15
+ execute { @session.post(url, headers: header, body: body) }
16
+ end
17
+
18
+ def patch(url, body: '', header: {})
19
+ execute { @session.patch(url, headers: header, body: body) }
20
+ end
21
+
22
+ def delete(url, header: {})
23
+ execute { @session.delete(url, headers: header) }
24
+ end
25
+
26
+ def reset_all
27
+ @session.close
28
+ end
29
+
30
+ private
31
+
32
+ def execute
33
+ response = yield
34
+ if response.is_a?(HTTPX::ErrorResponse)
35
+ raise response.error
36
+ end
37
+ Pubnub::HttpResponse.new(response)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,12 @@
1
+ module Pubnub
2
+ class HttpResponse
3
+ attr_reader :body, :code, :http_version
4
+ alias status_code code
5
+
6
+ def initialize(httpx_response)
7
+ @code = httpx_response.status
8
+ @body = httpx_response.body.to_s
9
+ @http_version = httpx_response.version
10
+ end
11
+ end
12
+ end
data/lib/pubnub/pam.rb CHANGED
@@ -77,7 +77,7 @@ module Pubnub
77
77
  when JSON::ParserError
78
78
  error_category = Pubnub::Constants::STATUS_NON_JSON_RESPONSE
79
79
  code = req_res_objects[:response].code
80
- when HTTPClient::TimeoutError
80
+ when HTTPX::TimeoutError
81
81
  error_category = Pubnub::Constants::STATUS_TIMEOUT
82
82
  code = 408
83
83
  else
@@ -69,6 +69,7 @@ module Pubnub
69
69
 
70
70
  begin
71
71
  req = request_dispatcher.get(uri.to_s)
72
+
72
73
  if retries > 0
73
74
  @app.subscriber.announce_status(announcement_type: Pubnub::Constants::RECONNECTED_ANNOUNCEMENT,
74
75
  event: @event,
@@ -1,4 +1,4 @@
1
1
  # Toplevel Pubnub module.
2
2
  module Pubnub
3
- VERSION = '6.0.2'.freeze
3
+ VERSION = '6.1.1'.freeze
4
4
  end
data/lib/pubnub.rb CHANGED
@@ -5,7 +5,9 @@ require 'open-uri'
5
5
  require 'openssl'
6
6
 
7
7
  require 'timers'
8
- require 'httpclient'
8
+ require 'httpx'
9
+ require 'pubnub/http_response'
10
+ require 'pubnub/http_dispatcher'
9
11
  require 'logger'
10
12
  require 'dry-validation'
11
13
  require 'cgi'
data/pubnub.gemspec CHANGED
@@ -19,10 +19,13 @@ Gem::Specification.new do |spec|
19
19
  spec.required_ruby_version = '>= 3.0.0'
20
20
 
21
21
  spec.add_dependency 'addressable', '>= 2.0.0'
22
+ spec.add_dependency 'base64'
23
+ spec.add_dependency 'logger'
24
+ spec.add_dependency 'ostruct'
22
25
  spec.add_dependency 'concurrent-ruby', '~> 1.3.4'
23
26
  spec.add_dependency 'concurrent-ruby-edge', '~> 0.7.1'
24
27
  spec.add_dependency 'dry-validation', '~> 1.0'
25
- spec.add_dependency 'httpclient', '~> 2.8', '>= 2.8.3'
28
+ spec.add_dependency 'httpx', '>= 1.0'
26
29
  spec.add_dependency 'json', '>= 2.2.0', '< 3'
27
30
  spec.add_dependency 'timers', '>= 4.3.0'
28
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pubnub
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.2
4
+ version: 6.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - PubNub
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-03 00:00:00.000000000 Z
11
+ date: 2026-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -24,6 +24,48 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: logger
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ostruct
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
27
69
  - !ruby/object:Gem::Dependency
28
70
  name: concurrent-ruby
29
71
  requirement: !ruby/object:Gem::Requirement
@@ -67,25 +109,19 @@ dependencies:
67
109
  - !ruby/object:Gem::Version
68
110
  version: '1.0'
69
111
  - !ruby/object:Gem::Dependency
70
- name: httpclient
112
+ name: httpx
71
113
  requirement: !ruby/object:Gem::Requirement
72
114
  requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '2.8'
76
115
  - - ">="
77
116
  - !ruby/object:Gem::Version
78
- version: 2.8.3
117
+ version: '1.0'
79
118
  type: :runtime
80
119
  prerelease: false
81
120
  version_requirements: !ruby/object:Gem::Requirement
82
121
  requirements:
83
- - - "~>"
84
- - !ruby/object:Gem::Version
85
- version: '2.8'
86
122
  - - ">="
87
123
  - !ruby/object:Gem::Version
88
- version: 2.8.3
124
+ version: '1.0'
89
125
  - !ruby/object:Gem::Dependency
90
126
  name: json
91
127
  requirement: !ruby/object:Gem::Requirement
@@ -224,6 +260,8 @@ files:
224
260
  - lib/pubnub/format.rb
225
261
  - lib/pubnub/formatter.rb
226
262
  - lib/pubnub/heart.rb
263
+ - lib/pubnub/http_dispatcher.rb
264
+ - lib/pubnub/http_response.rb
227
265
  - lib/pubnub/modules/crypto/crypto_module.rb
228
266
  - lib/pubnub/modules/crypto/crypto_provider.rb
229
267
  - lib/pubnub/modules/crypto/cryptor.rb