ld-eventsource 2.1.1 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/ld-eventsource/client.rb +6 -3
- data/lib/ld-eventsource/events.rb +5 -1
- data/lib/ld-eventsource/impl/backoff.rb +5 -1
- data/lib/ld-eventsource/impl/buffered_line_reader.rb +13 -4
- data/lib/ld-eventsource/impl/event_parser.rb +7 -3
- data/lib/ld-eventsource/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76ed80d3fefe60b6a147769dc1b44b0dfd7fe5b6841ff84655ae86764def70b9
|
4
|
+
data.tar.gz: cf24cff61716e4487d74023e09be18a516232a198aabcda2742fb8ec8de9de72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 329c044114376d9d618e37a138b7c99dc5c4f00baa3d22ea72ce88309deec8bd22a62c0513a362223542f9ddfa5aaae0413e14bbf336ef943a90e0374d2d9c89
|
7
|
+
data.tar.gz: 9110b5daa08a3c7fb04bb432527feaf4bee5e67d02b215621c89546ffd0a4da98c14a9618cdf4040474afe1649db777996547bfb502512930a3b364f05dd57c1
|
@@ -306,6 +306,9 @@ module SSE
|
|
306
306
|
else
|
307
307
|
begin
|
308
308
|
data = cxn.readpartial
|
309
|
+
# readpartial gives us a string, which may not be a valid UTF-8 string because a
|
310
|
+
# multi-byte character might not yet have been fully read, but BufferedLineReader
|
311
|
+
# will handle that.
|
309
312
|
rescue HTTP::TimeoutError
|
310
313
|
# For historical reasons, we rethrow this as our own type
|
311
314
|
raise Errors::ReadTimeoutError.new(@read_timeout)
|
@@ -315,7 +318,7 @@ module SSE
|
|
315
318
|
end
|
316
319
|
end
|
317
320
|
end
|
318
|
-
event_parser = Impl::EventParser.new(Impl::BufferedLineReader.lines_from(chunks))
|
321
|
+
event_parser = Impl::EventParser.new(Impl::BufferedLineReader.lines_from(chunks), @last_id)
|
319
322
|
|
320
323
|
event_parser.items.each do |item|
|
321
324
|
return if @stopped.value
|
@@ -331,7 +334,7 @@ module SSE
|
|
331
334
|
|
332
335
|
def dispatch_event(event)
|
333
336
|
@logger.debug { "Received event: #{event}" }
|
334
|
-
@last_id = event.id
|
337
|
+
@last_id = event.id if !event.id.nil?
|
335
338
|
|
336
339
|
# Pass the event to the caller
|
337
340
|
@on[:event].call(event)
|
@@ -354,7 +357,7 @@ module SSE
|
|
354
357
|
'Cache-Control' => 'no-cache',
|
355
358
|
'User-Agent' => 'ruby-eventsource'
|
356
359
|
}
|
357
|
-
h['Last-Event-Id'] = @last_id if !@last_id.nil?
|
360
|
+
h['Last-Event-Id'] = @last_id if !@last_id.nil? && @last_id != ""
|
358
361
|
h.merge(@headers)
|
359
362
|
end
|
360
363
|
end
|
@@ -11,6 +11,10 @@ module SSE
|
|
11
11
|
# if there were multiple `data:` lines, they are concatenated with newlines
|
12
12
|
# @!attribute id
|
13
13
|
# @return [String] the string that appeared after `id:` in the stream if any, or nil
|
14
|
+
# @!attribute last_event_id
|
15
|
+
# @return [String] the `id:` value that was most recently seen in an event from
|
16
|
+
# this stream; this differs from the `id` property in that it retains the same value
|
17
|
+
# in subsequent events if they do not provide their own `id:`
|
14
18
|
#
|
15
|
-
StreamEvent = Struct.new(:type, :data, :id)
|
19
|
+
StreamEvent = Struct.new(:type, :data, :id, :last_event_id)
|
16
20
|
end
|
@@ -41,7 +41,11 @@ module SSE
|
|
41
41
|
@last_good_time = nil
|
42
42
|
target = ([@base_interval * (2 ** @attempts), @max_interval].min).to_f
|
43
43
|
@attempts += 1
|
44
|
-
|
44
|
+
if target == 0
|
45
|
+
0 # in some Ruby versions it's illegal to call rand(0)
|
46
|
+
else
|
47
|
+
(target / 2) + @jitter_rand.rand(target / 2)
|
48
|
+
end
|
45
49
|
end
|
46
50
|
|
47
51
|
#
|
@@ -9,17 +9,21 @@ module SSE
|
|
9
9
|
# input data runs out, the output enumerator ends and does not include any partially
|
10
10
|
# completed line.
|
11
11
|
#
|
12
|
-
# @param [Enumerator] chunks an enumerator that will yield strings from a stream
|
13
|
-
#
|
12
|
+
# @param [Enumerator] chunks an enumerator that will yield strings from a stream -
|
13
|
+
# these are treated as raw UTF-8 bytes, regardless of the string's declared encoding
|
14
|
+
# (so it is OK if a multi-byte character is split across chunks); if the declared
|
15
|
+
# encoding of the chunk is not ASCII-8BIT, it will be changed to ASCII-8BIT in place
|
16
|
+
# @return [Enumerator] an enumerator that will yield one line at a time in UTF-8
|
14
17
|
#
|
15
18
|
def self.lines_from(chunks)
|
16
|
-
buffer = ""
|
19
|
+
buffer = "".b
|
17
20
|
position = 0
|
18
21
|
line_start = 0
|
19
22
|
last_char_was_cr = false
|
20
23
|
|
21
24
|
Enumerator.new do |gen|
|
22
25
|
chunks.each do |chunk|
|
26
|
+
chunk.force_encoding("ASCII-8BIT")
|
23
27
|
buffer << chunk
|
24
28
|
|
25
29
|
loop do
|
@@ -47,7 +51,12 @@ module SSE
|
|
47
51
|
next
|
48
52
|
end
|
49
53
|
|
50
|
-
line = buffer[line_start, i - line_start]
|
54
|
+
line = buffer[line_start, i - line_start].force_encoding("UTF-8")
|
55
|
+
# Calling force_encoding just declares that we believe the encoding of this string to be
|
56
|
+
# UTF-8 (which is the only encoding allowed in the SSE protocol); it doesn't cause any
|
57
|
+
# re-decoding of the string. The previous line-parsing steps were done on raw 8-bit
|
58
|
+
# strings so that it won't try to do any UTF-8 decoding on intermediate slices.
|
59
|
+
|
51
60
|
last_char_was_cr = false
|
52
61
|
i += 1
|
53
62
|
if ch == "\r"
|
@@ -23,8 +23,9 @@ module SSE
|
|
23
23
|
# @param [Enumerator] lines an enumerator that will yield one line of text at a time;
|
24
24
|
# the lines should not include line terminators
|
25
25
|
#
|
26
|
-
def initialize(lines)
|
26
|
+
def initialize(lines, last_event_id = nil)
|
27
27
|
@lines = lines
|
28
|
+
@last_event_id = last_event_id
|
28
29
|
reset_buffers
|
29
30
|
end
|
30
31
|
|
@@ -65,7 +66,10 @@ module SSE
|
|
65
66
|
@data << value
|
66
67
|
@have_data = true
|
67
68
|
when "id"
|
68
|
-
|
69
|
+
if !value.include?("\x00")
|
70
|
+
@id = value
|
71
|
+
@last_event_id = value
|
72
|
+
end
|
69
73
|
when "retry"
|
70
74
|
if /^(?<num>\d+)$/ =~ value
|
71
75
|
return SetRetryInterval.new(num.to_i)
|
@@ -76,7 +80,7 @@ module SSE
|
|
76
80
|
|
77
81
|
def maybe_create_event
|
78
82
|
return nil if !@have_data
|
79
|
-
StreamEvent.new(@type || :message, @data, @id)
|
83
|
+
StreamEvent.new(@type || :message, @data, @id, @last_event_id)
|
80
84
|
end
|
81
85
|
end
|
82
86
|
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.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LaunchDarkly
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.3.4
|
140
140
|
signing_key:
|
141
141
|
specification_version: 4
|
142
142
|
summary: LaunchDarkly SSE client
|