ld-eventsource 2.2.6 → 2.3.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 +4 -4
- data/lib/ld-eventsource/client.rb +47 -8
- data/lib/ld-eventsource/impl/event_parser.rb +7 -2
- data/lib/ld-eventsource/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56eca88c610f3aa1f572426034422f66f343ce30553c9d2e281462c4f3efe831
|
4
|
+
data.tar.gz: a9719f1e29695c0468c8b745239feb71041d5735e32f071fd77873866518bad5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2daad080ae032ab394dd4700e6bc22d20d167aca0e0a7ba9f74b41544ff0c5232cb0d34b6803fdc09342d95608732bea6c9ee7cef87bc912fef9a8ab10ccfb26
|
7
|
+
data.tar.gz: 520224cf097791d2942ed0662dc29d94bff02c979fdebde479186efb21dbfa052aa80eee62779be723db2c918a9dd34a19ab4eea343453b7e114524a3dc23eb5
|
@@ -49,6 +49,9 @@ module SSE
|
|
49
49
|
# The default value for `reconnect_reset_interval` in {#initialize}.
|
50
50
|
DEFAULT_RECONNECT_RESET_INTERVAL = 60
|
51
51
|
|
52
|
+
# The default HTTP method for requests.
|
53
|
+
DEFAULT_HTTP_METHOD = "GET"
|
54
|
+
|
52
55
|
#
|
53
56
|
# Creates a new SSE client.
|
54
57
|
#
|
@@ -84,6 +87,16 @@ module SSE
|
|
84
87
|
# @param socket_factory [#open] (nil) an optional factory object for creating sockets,
|
85
88
|
# if you want to use something other than the default `TCPSocket`; it must implement
|
86
89
|
# `open(uri, timeout)` to return a connected `Socket`
|
90
|
+
# @param method [String] ("GET") the HTTP method to use for requests
|
91
|
+
# @param payload [String, Hash, Array, #call] (nil) optional request payload. If payload is a Hash or
|
92
|
+
# an Array, it will be converted to JSON and sent as the request body. A string will be sent as a non-JSON
|
93
|
+
# request body. If payload responds to #call, it will be invoked on each
|
94
|
+
# request to generate the payload dynamically.
|
95
|
+
# @param retry_enabled [Boolean] (true) whether to retry connections after failures. If false, the client
|
96
|
+
# will exit after the first connection failure instead of attempting to reconnect.
|
97
|
+
# @param http_client_options [Hash] (nil) additional options to pass to
|
98
|
+
# the HTTP client, such as `socket_factory` or `proxy`. These settings will override
|
99
|
+
# the socket factory and proxy settings.
|
87
100
|
# @yieldparam [Client] client the new client instance, before opening the connection
|
88
101
|
#
|
89
102
|
def initialize(uri,
|
@@ -95,17 +108,25 @@ module SSE
|
|
95
108
|
last_event_id: nil,
|
96
109
|
proxy: nil,
|
97
110
|
logger: nil,
|
98
|
-
socket_factory: nil
|
111
|
+
socket_factory: nil,
|
112
|
+
method: DEFAULT_HTTP_METHOD,
|
113
|
+
payload: nil,
|
114
|
+
retry_enabled: true,
|
115
|
+
http_client_options: nil)
|
99
116
|
@uri = URI(uri)
|
100
117
|
@stopped = Concurrent::AtomicBoolean.new(false)
|
118
|
+
@retry_enabled = retry_enabled
|
101
119
|
|
102
120
|
@headers = headers.clone
|
103
121
|
@connect_timeout = connect_timeout
|
104
122
|
@read_timeout = read_timeout
|
123
|
+
@method = method.to_s.upcase
|
124
|
+
@payload = payload
|
105
125
|
@logger = logger || default_logger
|
106
|
-
|
126
|
+
|
127
|
+
base_http_client_options = {}
|
107
128
|
if socket_factory
|
108
|
-
|
129
|
+
base_http_client_options["socket_class"] = socket_factory
|
109
130
|
end
|
110
131
|
|
111
132
|
if proxy
|
@@ -118,13 +139,18 @@ module SSE
|
|
118
139
|
end
|
119
140
|
|
120
141
|
if @proxy
|
121
|
-
|
142
|
+
base_http_client_options["proxy"] = {
|
122
143
|
:proxy_address => @proxy.host,
|
123
144
|
:proxy_port => @proxy.port,
|
124
145
|
}
|
146
|
+
base_http_client_options["proxy"][:proxy_username] = @proxy.user unless @proxy.user.nil?
|
147
|
+
base_http_client_options["proxy"][:proxy_password] = @proxy.password unless @proxy.password.nil?
|
125
148
|
end
|
126
149
|
|
127
|
-
|
150
|
+
options = http_client_options.is_a?(Hash) ? base_http_client_options.merge(http_client_options) : base_http_client_options
|
151
|
+
|
152
|
+
@http_client = HTTP::Client.new(options)
|
153
|
+
.follow
|
128
154
|
.timeout({
|
129
155
|
read: read_timeout,
|
130
156
|
connect: connect_timeout,
|
@@ -246,6 +272,8 @@ module SSE
|
|
246
272
|
rescue StandardError => e
|
247
273
|
log_and_dispatch_error(e, "Unexpected error while closing stream")
|
248
274
|
end
|
275
|
+
|
276
|
+
return close unless @retry_enabled
|
249
277
|
end
|
250
278
|
end
|
251
279
|
|
@@ -262,9 +290,7 @@ module SSE
|
|
262
290
|
cxn = nil
|
263
291
|
begin
|
264
292
|
@logger.info { "Connecting to event stream at #{@uri}" }
|
265
|
-
cxn = @http_client.request(
|
266
|
-
headers: build_headers,
|
267
|
-
})
|
293
|
+
cxn = @http_client.request(@method, @uri, build_opts)
|
268
294
|
if cxn.status.code == 200
|
269
295
|
content_type = cxn.content_type.mime_type
|
270
296
|
if content_type && content_type.start_with?("text/event-stream")
|
@@ -358,5 +384,18 @@ module SSE
|
|
358
384
|
h['Last-Event-Id'] = @last_id if !@last_id.nil? && @last_id != ""
|
359
385
|
h.merge(@headers)
|
360
386
|
end
|
387
|
+
|
388
|
+
def build_opts
|
389
|
+
return {headers: build_headers} if @payload.nil?
|
390
|
+
|
391
|
+
# Resolve payload if it's callable
|
392
|
+
resolved_payload = @payload.respond_to?(:call) ? @payload.call : @payload
|
393
|
+
|
394
|
+
if resolved_payload.is_a?(Hash) || resolved_payload.is_a?(Array)
|
395
|
+
{headers: build_headers, json: resolved_payload}
|
396
|
+
else
|
397
|
+
{headers: build_headers, body: resolved_payload.to_s}
|
398
|
+
end
|
399
|
+
end
|
361
400
|
end
|
362
401
|
end
|
@@ -42,9 +42,14 @@ module SSE
|
|
42
42
|
|
43
43
|
pos += 1 # skip colon
|
44
44
|
pos += 1 if pos < line.length && line[pos] == ' ' # skip optional single space, per SSE spec
|
45
|
-
|
45
|
+
value = line.slice(pos..-1)
|
46
46
|
|
47
|
-
item = process_field(name,
|
47
|
+
item = process_field(name, value)
|
48
|
+
gen.yield item unless item.nil?
|
49
|
+
else
|
50
|
+
# Handle field with no colon - treat as having empty value
|
51
|
+
# According to SSE spec, a line like "data" should be treated as "data:"
|
52
|
+
item = process_field(line, "")
|
48
53
|
gen.yield item unless item.nil?
|
49
54
|
end
|
50
55
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ld-eventsource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-09-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logger
|