aws-eventstream 1.0.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 +7 -0
- data/lib/aws-eventstream.rb +8 -0
- data/lib/aws-eventstream/bytes_buffer.rb +66 -0
- data/lib/aws-eventstream/decoder.rb +247 -0
- data/lib/aws-eventstream/encoder.rb +136 -0
- data/lib/aws-eventstream/errors.rb +35 -0
- data/lib/aws-eventstream/header_value.rb +46 -0
- data/lib/aws-eventstream/message.rb +20 -0
- data/lib/aws-eventstream/types.rb +40 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0bd89e470bb670750b5db3fa159c05c47f6ae848
|
4
|
+
data.tar.gz: 0e6a31068166775645f803c36f2aa27c7b7341ce
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 475cdba6288c5ba3224a65d18f9b3d16feba99d2b9868043af4c01194adeeb55f686200cac511e3067465ffe8b7cfa93dbe306751f31f6ce93966d5b052f4b6c
|
7
|
+
data.tar.gz: b96b77164bc0e6e1f9095de872400f9a589f912d450f6cdb0c40c3b769888f38f90be9b572b09f2715f1358ba43b71d06842d95c628108e57bdd1c5201aba3be
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require_relative 'aws-eventstream/decoder'
|
2
|
+
require_relative 'aws-eventstream/encoder'
|
3
|
+
|
4
|
+
require_relative 'aws-eventstream/bytes_buffer'
|
5
|
+
require_relative 'aws-eventstream/message'
|
6
|
+
require_relative 'aws-eventstream/header_value'
|
7
|
+
require_relative 'aws-eventstream/types'
|
8
|
+
require_relative 'aws-eventstream/errors'
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Aws
|
2
|
+
module EventStream
|
3
|
+
|
4
|
+
# @api private
|
5
|
+
class BytesBuffer
|
6
|
+
|
7
|
+
# This Util class is for Decoder/Encoder usage only
|
8
|
+
# Not for public common bytes buffer usage
|
9
|
+
def initialize(data)
|
10
|
+
@data = data
|
11
|
+
@pos = 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(len = nil, offset = 0)
|
15
|
+
return '' if len == 0 || bytesize == 0
|
16
|
+
unless eof?
|
17
|
+
start_byte = @pos + offset
|
18
|
+
end_byte = len ?
|
19
|
+
start_byte + len - 1 :
|
20
|
+
bytesize - 1
|
21
|
+
|
22
|
+
error = Errors::ReadBytesExceedLengthError.new(end_byte, bytesize)
|
23
|
+
raise error if end_byte >= bytesize
|
24
|
+
|
25
|
+
@pos = end_byte + 1
|
26
|
+
@data[start_byte..end_byte]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def readbyte
|
31
|
+
unless eof?
|
32
|
+
@pos += 1
|
33
|
+
@data[@pos - 1]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def write(bytes)
|
38
|
+
@data <<= bytes
|
39
|
+
bytes.bytesize
|
40
|
+
end
|
41
|
+
alias_method :<<, :write
|
42
|
+
|
43
|
+
def rewind
|
44
|
+
@pos = 0
|
45
|
+
end
|
46
|
+
|
47
|
+
def eof?
|
48
|
+
@pos == bytesize
|
49
|
+
end
|
50
|
+
|
51
|
+
def bytesize
|
52
|
+
@data.bytesize
|
53
|
+
end
|
54
|
+
|
55
|
+
def tell
|
56
|
+
@pos
|
57
|
+
end
|
58
|
+
|
59
|
+
def clear!
|
60
|
+
@data = ''
|
61
|
+
@pos = 0
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'zlib'
|
4
|
+
|
5
|
+
module Aws
|
6
|
+
module EventStream
|
7
|
+
|
8
|
+
# This class provides method for decoding binary inputs into
|
9
|
+
# single or multiple messages (Aws::EventStream::Message).
|
10
|
+
#
|
11
|
+
# * {#decode} - decodes messages from an IO like object responds
|
12
|
+
# to #read that containing binary data, returning decoded
|
13
|
+
# Aws::EventStream::Message along the way or wrapped in an enumerator
|
14
|
+
#
|
15
|
+
# ## Examples
|
16
|
+
#
|
17
|
+
# decoder = Aws::EventStream::Decoder.new
|
18
|
+
#
|
19
|
+
# # decoding from IO
|
20
|
+
# decoder.decode(io) do |message|
|
21
|
+
# message.headers
|
22
|
+
# # => { ... }
|
23
|
+
# message.payload
|
24
|
+
# # => StringIO / Tempfile
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # alternatively
|
28
|
+
# message_pool = decoder.decode(io)
|
29
|
+
# message_pool.next
|
30
|
+
# # => Aws::EventStream::Message
|
31
|
+
#
|
32
|
+
# * {#decode_chunk} - decodes a single message from a chunk of data,
|
33
|
+
# returning message object followed by boolean(indicating eof status
|
34
|
+
# of data) in an array object
|
35
|
+
#
|
36
|
+
# ## Examples
|
37
|
+
#
|
38
|
+
# # chunk containing exactly one message data
|
39
|
+
# message, chunk_eof = decoder.decode_chunk(chunk_str)
|
40
|
+
# message
|
41
|
+
# # => Aws::EventStream::Message
|
42
|
+
# chunk_eof
|
43
|
+
# # => true
|
44
|
+
#
|
45
|
+
# # chunk containing a partial message
|
46
|
+
# message, chunk_eof = decoder.decode_chunk(chunk_str)
|
47
|
+
# message
|
48
|
+
# # => nil
|
49
|
+
# chunk_eof
|
50
|
+
# # => true
|
51
|
+
# # chunk data is saved at decoder's message_buffer
|
52
|
+
#
|
53
|
+
# # chunk containing more that one data message
|
54
|
+
# message, chunk_eof = decoder.decode_chunk(chunk_str)
|
55
|
+
# message
|
56
|
+
# # => Aws::EventStream::Message
|
57
|
+
# chunk_eof
|
58
|
+
# # => false
|
59
|
+
# # extra chunk data is saved at message_buffer of the decoder
|
60
|
+
#
|
61
|
+
class Decoder
|
62
|
+
|
63
|
+
include Enumerable
|
64
|
+
|
65
|
+
ONE_MEGABYTE = 1024 * 1024
|
66
|
+
|
67
|
+
# bytes of prelude part, including 4 bytes of
|
68
|
+
# total message length, headers length and crc checksum of prelude
|
69
|
+
PRELUDE_LENGTH = 12
|
70
|
+
|
71
|
+
# bytes of total overhead in a message, including prelude
|
72
|
+
# and 4 bytes total message crc checksum
|
73
|
+
OVERHEAD_LENGTH = 16
|
74
|
+
|
75
|
+
# @options options [Boolean] format (true) When `false`
|
76
|
+
# disable user-friendly formatting for message header values
|
77
|
+
# including timestamp and uuid etc.
|
78
|
+
#
|
79
|
+
def initialize(options = {})
|
80
|
+
@format = options.fetch(:format, true)
|
81
|
+
@message_buffer = BytesBuffer.new('')
|
82
|
+
end
|
83
|
+
|
84
|
+
# @returns [BytesBuffer]
|
85
|
+
attr_reader :message_buffer
|
86
|
+
|
87
|
+
# Decodes messages from a binary stream
|
88
|
+
#
|
89
|
+
# @param [IO#read] io An IO-like object
|
90
|
+
# that responds to `#read`
|
91
|
+
#
|
92
|
+
# @yieldparam [Message] message
|
93
|
+
# @return [Enumerable<Message>, nil] Returns a new Enumerable
|
94
|
+
# containing decoded messages if no block is given
|
95
|
+
def decode(io, &block)
|
96
|
+
io = BytesBuffer.new(io.read)
|
97
|
+
return decode_io(io) unless block_given?
|
98
|
+
until io.eof?
|
99
|
+
# fetch message only
|
100
|
+
yield(decode_message(io).first)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Decodes a single message from a chunk of string
|
105
|
+
#
|
106
|
+
# @param [String] chunk A chunk of string to be decoded,
|
107
|
+
# chunk can contain partial event message to multiple event messages
|
108
|
+
# When not provided, decode data from #message_buffer
|
109
|
+
#
|
110
|
+
# @return [Array<Message|nil, Boolean>] Returns single decoded message
|
111
|
+
# and boolean pair, the boolean flag indicates whether this chunk
|
112
|
+
# has been fully consumed, unused data is tracked at #message_buffer
|
113
|
+
def decode_chunk(chunk = nil)
|
114
|
+
@message_buffer.write(chunk) if chunk
|
115
|
+
@message_buffer.rewind
|
116
|
+
decode_message(@message_buffer)
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def decode_io(io)
|
122
|
+
::Enumerator.new {|e| e << decode_message(io) unless io.eof? }
|
123
|
+
end
|
124
|
+
|
125
|
+
def decode_message(io)
|
126
|
+
# decode prelude
|
127
|
+
total_len, headers_len, prelude_buffer = prelude(io)
|
128
|
+
|
129
|
+
# incomplete message received, leave it in the buffer
|
130
|
+
return [nil, true] if io.bytesize < total_len
|
131
|
+
|
132
|
+
# decode headers and payload
|
133
|
+
headers, payload = context(io, total_len, headers_len, prelude_buffer)
|
134
|
+
|
135
|
+
# track extra message data in the buffer if exists
|
136
|
+
# for #decode_chunk, io is @message_buffer
|
137
|
+
if eof = io.eof?
|
138
|
+
@message_buffer.clear!
|
139
|
+
else
|
140
|
+
@message_buffer = BytesBuffer.new(@message_buffer.read)
|
141
|
+
end
|
142
|
+
|
143
|
+
[Message.new(headers: headers, payload: payload), eof]
|
144
|
+
end
|
145
|
+
|
146
|
+
def prelude(io)
|
147
|
+
# buffer prelude into bytes buffer
|
148
|
+
# prelude contains length of message and headers,
|
149
|
+
# followed with CRC checksum of itself
|
150
|
+
buffer = BytesBuffer.new(io.read(PRELUDE_LENGTH))
|
151
|
+
|
152
|
+
# prelude checksum takes last 4 bytes
|
153
|
+
checksum = Zlib.crc32(buffer.read(PRELUDE_LENGTH - 4))
|
154
|
+
unless checksum == unpack_uint32(buffer)
|
155
|
+
raise Errors::PreludeChecksumError
|
156
|
+
end
|
157
|
+
|
158
|
+
buffer.rewind
|
159
|
+
total_len, headers_len, _ = buffer.read.unpack("N*")
|
160
|
+
[total_len, headers_len, buffer]
|
161
|
+
end
|
162
|
+
|
163
|
+
def context(io, total_len, headers_len, prelude_buffer)
|
164
|
+
# buffer rest of the message except prelude length
|
165
|
+
# including context and total message checksum
|
166
|
+
buffer = BytesBuffer.new(io.read(total_len - PRELUDE_LENGTH))
|
167
|
+
context_len = total_len - OVERHEAD_LENGTH
|
168
|
+
|
169
|
+
prelude_buffer.rewind
|
170
|
+
checksum = Zlib.crc32(prelude_buffer.read << buffer.read(context_len))
|
171
|
+
unless checksum == unpack_uint32(buffer)
|
172
|
+
raise Errors::MessageChecksumError
|
173
|
+
end
|
174
|
+
|
175
|
+
buffer.rewind
|
176
|
+
[
|
177
|
+
extract_headers(BytesBuffer.new(buffer.read(headers_len))),
|
178
|
+
extract_payload(BytesBuffer.new(buffer.read(context_len - headers_len)))
|
179
|
+
]
|
180
|
+
end
|
181
|
+
|
182
|
+
def extract_headers(buffer)
|
183
|
+
headers = {}
|
184
|
+
until buffer.eof?
|
185
|
+
# header key
|
186
|
+
key_len = unpack_uint8(buffer)
|
187
|
+
key = buffer.read(key_len)
|
188
|
+
|
189
|
+
# header value
|
190
|
+
value_type = Types.types[unpack_uint8(buffer)]
|
191
|
+
unpack_pattern, value_len, _ = Types.pattern[value_type]
|
192
|
+
if !!unpack_pattern == unpack_pattern
|
193
|
+
# boolean types won't have value specified
|
194
|
+
value = unpack_pattern
|
195
|
+
else
|
196
|
+
value_len = unpack_uint16(buffer) unless value_len
|
197
|
+
value = unpack_pattern ?
|
198
|
+
buffer.read(value_len).unpack(unpack_pattern)[0] :
|
199
|
+
buffer.read(value_len)
|
200
|
+
end
|
201
|
+
|
202
|
+
headers[key] = HeaderValue.new(
|
203
|
+
format: @format,
|
204
|
+
value: value,
|
205
|
+
type: value_type
|
206
|
+
)
|
207
|
+
end
|
208
|
+
headers
|
209
|
+
end
|
210
|
+
|
211
|
+
def extract_payload(buffer)
|
212
|
+
buffer.bytesize <= ONE_MEGABYTE ?
|
213
|
+
payload_stringio(buffer) :
|
214
|
+
payload_tempfile(buffer)
|
215
|
+
end
|
216
|
+
|
217
|
+
def payload_stringio(buffer)
|
218
|
+
StringIO.new(buffer.read)
|
219
|
+
end
|
220
|
+
|
221
|
+
def payload_tempfile(buffer)
|
222
|
+
payload = Tempfile.new
|
223
|
+
payload.binmode
|
224
|
+
until buffer.eof?
|
225
|
+
payload.write(buffer.read(ONE_MEGABYTE))
|
226
|
+
end
|
227
|
+
payload.rewind
|
228
|
+
payload
|
229
|
+
end
|
230
|
+
|
231
|
+
# overhead decode helpers
|
232
|
+
|
233
|
+
def unpack_uint32(buffer)
|
234
|
+
buffer.read(4).unpack("N")[0]
|
235
|
+
end
|
236
|
+
|
237
|
+
def unpack_uint16(buffer)
|
238
|
+
buffer.read(2).unpack("S>")[0]
|
239
|
+
end
|
240
|
+
|
241
|
+
def unpack_uint8(buffer)
|
242
|
+
buffer.readbyte.unpack("C")[0]
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module EventStream
|
5
|
+
|
6
|
+
# This class provides #encode method for encoding
|
7
|
+
# Aws::EventStream::Message into binary.
|
8
|
+
#
|
9
|
+
# * {#encode} - encode Aws::EventStream::Message into binary
|
10
|
+
# when output IO-like object is provided, binary string
|
11
|
+
# would be written to IO. If not, the encoded binary string
|
12
|
+
# would be returned directly
|
13
|
+
#
|
14
|
+
# ## Examples
|
15
|
+
#
|
16
|
+
# message = Aws::EventStream::Message.new(
|
17
|
+
# headers: {
|
18
|
+
# "foo" => Aws::EventStream::HeaderValue.new(
|
19
|
+
# value: "bar", type: "string"
|
20
|
+
# )
|
21
|
+
# },
|
22
|
+
# payload: "payload"
|
23
|
+
# )
|
24
|
+
# encoder = Aws::EventsStream::Encoder.new
|
25
|
+
# file = Tempfile.new
|
26
|
+
#
|
27
|
+
# # encode into IO ouput
|
28
|
+
# encoder.encode(message, file)
|
29
|
+
#
|
30
|
+
# # get encoded binary string
|
31
|
+
# encoded_message = encoder.encode(message)
|
32
|
+
#
|
33
|
+
# file.read == encoded_message
|
34
|
+
# # => true
|
35
|
+
#
|
36
|
+
class Encoder
|
37
|
+
|
38
|
+
# bytes of total overhead in a message, including prelude
|
39
|
+
# and 4 bytes total message crc checksum
|
40
|
+
OVERHEAD_LENGTH = 16
|
41
|
+
|
42
|
+
# Encodes Aws::EventStream::Message to output IO when
|
43
|
+
# provided, else return the encoded binary string
|
44
|
+
#
|
45
|
+
# @param [Aws::EventStream::Message] message
|
46
|
+
#
|
47
|
+
# @param [IO#write, nil] io An IO-like object that
|
48
|
+
# responds to `#write`, encoded message will be
|
49
|
+
# written to this IO when provided
|
50
|
+
#
|
51
|
+
# @return [nil, String] when output IO is provided,
|
52
|
+
# encoded message will be written to that IO, nil
|
53
|
+
# will be returned. Else, encoded binary string is
|
54
|
+
# returned.
|
55
|
+
def encode(message, io = nil)
|
56
|
+
encoded = encode_message(message).read
|
57
|
+
if io
|
58
|
+
io.write(encoded)
|
59
|
+
io.close
|
60
|
+
else
|
61
|
+
encoded
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def encode_message(message)
|
68
|
+
# create context buffer with encode headers
|
69
|
+
ctx_buffer = encode_headers(message)
|
70
|
+
headers_len = ctx_buffer.bytesize
|
71
|
+
# encode payload
|
72
|
+
ctx_buffer << message.payload.read
|
73
|
+
total_len = ctx_buffer.bytesize + OVERHEAD_LENGTH
|
74
|
+
|
75
|
+
# create message buffer with prelude section
|
76
|
+
buffer = prelude(total_len, headers_len)
|
77
|
+
|
78
|
+
# append message context (headers, payload)
|
79
|
+
buffer << ctx_buffer.read
|
80
|
+
# append message checksum
|
81
|
+
buffer << pack_uint32(Zlib.crc32(buffer.read))
|
82
|
+
|
83
|
+
# write buffered message to io
|
84
|
+
buffer.rewind
|
85
|
+
buffer
|
86
|
+
end
|
87
|
+
|
88
|
+
def encode_headers(msg)
|
89
|
+
buffer = BytesBuffer.new('')
|
90
|
+
msg.headers.each do |k, v|
|
91
|
+
# header key
|
92
|
+
buffer << pack_uint8(k.bytesize)
|
93
|
+
buffer << k
|
94
|
+
|
95
|
+
# header value
|
96
|
+
pattern, val_len, idx = Types.pattern[v.type]
|
97
|
+
buffer << pack_uint8(idx)
|
98
|
+
# boolean types doesn't need to specify value
|
99
|
+
next if !!pattern == pattern
|
100
|
+
buffer << pack_uint16(v.value.bytesize) unless val_len
|
101
|
+
pattern ? buffer << [v.value].pack(pattern) :
|
102
|
+
buffer << v.value
|
103
|
+
end
|
104
|
+
buffer
|
105
|
+
end
|
106
|
+
|
107
|
+
def prelude(total_len, headers_len)
|
108
|
+
BytesBuffer.new(pack_uint32([
|
109
|
+
total_len,
|
110
|
+
headers_len,
|
111
|
+
Zlib.crc32(pack_uint32([total_len, headers_len]))
|
112
|
+
]))
|
113
|
+
end
|
114
|
+
|
115
|
+
# overhead encode helpers
|
116
|
+
|
117
|
+
def pack_uint8(val)
|
118
|
+
[val].pack("C")
|
119
|
+
end
|
120
|
+
|
121
|
+
def pack_uint16(val)
|
122
|
+
[val].pack("S>")
|
123
|
+
end
|
124
|
+
|
125
|
+
def pack_uint32(val)
|
126
|
+
if val.respond_to?(:each)
|
127
|
+
val.pack("N*")
|
128
|
+
else
|
129
|
+
[val].pack("N")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Aws
|
2
|
+
module EventStream
|
3
|
+
module Errors
|
4
|
+
|
5
|
+
# Raised when reading bytes exceed buffer total bytes
|
6
|
+
class ReadBytesExceedLengthError < RuntimeError
|
7
|
+
def initialize(target_byte, total_len)
|
8
|
+
msg = "Attempting reading bytes to offset #{target_byte} exceeds"\
|
9
|
+
" buffer length of #{total_len}"
|
10
|
+
super(msg)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Raise when insufficient bytes of a message is received
|
15
|
+
class IncompleteMessageError < RuntimeError
|
16
|
+
def initialize(*args)
|
17
|
+
super("Not enough bytes for event message")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class PreludeChecksumError < RuntimeError
|
22
|
+
def initialize(*args)
|
23
|
+
super("Prelude checksum mismatch")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class MessageChecksumError < RuntimeError
|
28
|
+
def initialize(*args)
|
29
|
+
super("Message checksum mismatch")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Aws
|
2
|
+
module EventStream
|
3
|
+
|
4
|
+
class HeaderValue
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@type = options.fetch(:type)
|
8
|
+
@value = options[:format] ?
|
9
|
+
format_value(options.fetch(:value)) :
|
10
|
+
options.fetch(:value)
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :value
|
14
|
+
|
15
|
+
# @return [String] type of the header value
|
16
|
+
# complete type list see Aws::EventStream::Types
|
17
|
+
attr_reader :type
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def format_value(value)
|
22
|
+
case @type
|
23
|
+
when "timestamp" then format_timestamp(value)
|
24
|
+
when "uuid" then format_uuid(value)
|
25
|
+
else
|
26
|
+
value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def format_uuid(value)
|
31
|
+
bytes = value.bytes
|
32
|
+
# For user-friendly uuid representation,
|
33
|
+
# format binary bytes into uuid string format
|
34
|
+
uuid_pattern = [ [ 3, 2, 1, 0 ], [ 5, 4 ], [ 7, 6 ], [ 8, 9 ], 10..15 ]
|
35
|
+
uuid_pattern.map {|p| p.map {|n| "%02x" % bytes.to_a[n] }.join }.join("-")
|
36
|
+
end
|
37
|
+
|
38
|
+
def format_timestamp(value)
|
39
|
+
# millis_since_epoch to sec_since_epoch
|
40
|
+
Time.at(value / 1000.0)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Aws
|
2
|
+
module EventStream
|
3
|
+
class Message
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@headers = options[:headers] || {}
|
7
|
+
@payload = options[:payload] || StringIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Hash] headers of a message
|
11
|
+
attr_reader :headers
|
12
|
+
|
13
|
+
# @return [IO] payload of a message, size not exceed 16MB.
|
14
|
+
# StringIO is returned for <= 1MB payload
|
15
|
+
# Tempfile is returned for > 1MB payload
|
16
|
+
attr_reader :payload
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Aws
|
2
|
+
module EventStream
|
3
|
+
|
4
|
+
# Message Header Value Types
|
5
|
+
module Types
|
6
|
+
|
7
|
+
def self.types
|
8
|
+
[
|
9
|
+
"bool_true",
|
10
|
+
"bool_false",
|
11
|
+
"byte",
|
12
|
+
"short",
|
13
|
+
"integer",
|
14
|
+
"long",
|
15
|
+
"bytes",
|
16
|
+
"string",
|
17
|
+
"timestamp",
|
18
|
+
"uuid"
|
19
|
+
]
|
20
|
+
end
|
21
|
+
|
22
|
+
# pack/unpack pattern, byte size, type idx
|
23
|
+
def self.pattern
|
24
|
+
{
|
25
|
+
"bool_true" => [true, 0, 0],
|
26
|
+
"bool_false" => [false, 0, 1],
|
27
|
+
"byte" => ["c", 1, 2],
|
28
|
+
"short" => ["s>", 2, 3],
|
29
|
+
"integer" => ["l>", 4, 4],
|
30
|
+
"long" => ["q>", 8, 5],
|
31
|
+
"bytes" => [nil, nil, 6],
|
32
|
+
"string" => [nil, nil, 7],
|
33
|
+
"timestamp" => ["q>", 8, 8],
|
34
|
+
"uuid" => [nil, 16, 9]
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws-eventstream
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Amazon Web Services
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-05-10 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Amazon Web Services event stream library. Decodes and encodes binary
|
14
|
+
stream under `vnd.amazon.event-stream` content-type
|
15
|
+
email:
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/aws-eventstream.rb
|
21
|
+
- lib/aws-eventstream/bytes_buffer.rb
|
22
|
+
- lib/aws-eventstream/decoder.rb
|
23
|
+
- lib/aws-eventstream/encoder.rb
|
24
|
+
- lib/aws-eventstream/errors.rb
|
25
|
+
- lib/aws-eventstream/header_value.rb
|
26
|
+
- lib/aws-eventstream/message.rb
|
27
|
+
- lib/aws-eventstream/types.rb
|
28
|
+
homepage: http://github.com/aws/aws-sdk-ruby
|
29
|
+
licenses:
|
30
|
+
- Apache-2.0
|
31
|
+
metadata:
|
32
|
+
source_code_uri: https://github.com/aws/aws-sdk-ruby/tree/master/gems/aws-eventstream
|
33
|
+
changelog_uri: https://github.com/aws/aws-sdk-ruby/tree/master/gems/aws-eventstream/CHANGELOG.md
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 2.5.2.3
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: AWS Event Stream Library
|
54
|
+
test_files: []
|