protocol-websocket 0.8.0 → 0.9.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
- checksums.yaml.gz.sig +0 -0
- data/lib/.DS_Store +0 -0
- data/lib/protocol/.DS_Store +0 -0
- data/lib/protocol/websocket/binary_frame.rb +2 -1
- data/lib/protocol/websocket/connection.rb +50 -50
- data/lib/protocol/websocket/extension/compression/constants.rb +34 -0
- data/lib/protocol/websocket/extension/compression/deflate.rb +25 -13
- data/lib/protocol/websocket/extension/compression/inflate.rb +18 -12
- data/lib/protocol/websocket/extension/compression.rb +21 -15
- data/lib/protocol/websocket/extensions.rb +5 -3
- data/lib/protocol/websocket/message.rb +61 -0
- data/lib/protocol/websocket/text_frame.rb +2 -1
- data/lib/protocol/websocket/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +9 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c466ba64c434d16b197dacfb48341ab14eca48ba5aefde4cf06df4f10be84fc
|
4
|
+
data.tar.gz: 3d470e57b3c94936ec31adce97e829550344e6345de423f0d3c51915d951d782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 271a7a12c932857ea8887e67d7303a008852cc700e2d3bea0cbf96a6f30c53b8cae442f62877f4ad89c215dfb5bae81c0948da6b3cd5c267304dc368d795e542
|
7
|
+
data.tar.gz: 826444b74fd01885c66389a1c08b8b2cb99617662c3e364453d4d1572fa0237447d70d196fc867bde6231bc11efd6b47c874619bafe1efa800bcc1304a055329
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/.DS_Store
ADDED
Binary file
|
Binary file
|
@@ -19,6 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require_relative 'frame'
|
22
|
+
require_relative 'message'
|
22
23
|
|
23
24
|
module Protocol
|
24
25
|
module WebSocket
|
@@ -30,7 +31,7 @@ module Protocol
|
|
30
31
|
end
|
31
32
|
|
32
33
|
def read_message(buffer)
|
33
|
-
buffer
|
34
|
+
return BinaryMessage.new(buffer)
|
34
35
|
end
|
35
36
|
|
36
37
|
def apply(connection)
|
@@ -131,39 +131,7 @@ module Protocol
|
|
131
131
|
raise ProtocolError, "Received unexpected continuation!"
|
132
132
|
end
|
133
133
|
end
|
134
|
-
|
135
|
-
def text_message(buffer, **options)
|
136
|
-
frame = TextFrame.new(mask: @mask)
|
137
|
-
frame.pack(buffer)
|
138
|
-
|
139
|
-
return frame
|
140
|
-
end
|
141
|
-
|
142
|
-
def send_text(buffer, **options)
|
143
|
-
write_frame(@writer.text_message(buffer, **options))
|
144
|
-
end
|
145
|
-
|
146
|
-
def binary_message(buffer, **options)
|
147
|
-
frame = BinaryFrame.new(mask: @mask)
|
148
|
-
frame.pack(buffer)
|
149
|
-
|
150
|
-
return frame
|
151
|
-
end
|
152
|
-
|
153
|
-
def send_binary(buffer, **options)
|
154
|
-
write_frame(@writer.binary_message(buffer, **options))
|
155
|
-
end
|
156
|
-
|
157
|
-
def send_close(code = Error::NO_ERROR, reason = "")
|
158
|
-
frame = CloseFrame.new(mask: @mask)
|
159
|
-
frame.pack(code, reason)
|
160
|
-
|
161
|
-
self.write_frame(frame)
|
162
|
-
self.flush
|
163
|
-
|
164
|
-
@state = :closed
|
165
|
-
end
|
166
|
-
|
134
|
+
|
167
135
|
def receive_close(frame)
|
168
136
|
@state = :closed
|
169
137
|
|
@@ -209,23 +177,59 @@ module Protocol
|
|
209
177
|
warn "Unhandled frame #{frame.inspect}"
|
210
178
|
end
|
211
179
|
|
212
|
-
def
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
send_binary(buffer, **options)
|
218
|
-
end
|
180
|
+
def pack_text_frame(buffer, **options)
|
181
|
+
frame = TextFrame.new(mask: @mask)
|
182
|
+
frame.pack(buffer)
|
183
|
+
|
184
|
+
return frame
|
219
185
|
end
|
220
186
|
|
221
|
-
|
222
|
-
|
223
|
-
|
187
|
+
def send_text(buffer, **options)
|
188
|
+
write_frame(@writer.pack_text_frame(buffer, **options))
|
189
|
+
end
|
190
|
+
|
191
|
+
def pack_binary_frame(buffer, **options)
|
192
|
+
frame = BinaryFrame.new(mask: @mask)
|
193
|
+
frame.pack(buffer)
|
224
194
|
|
225
|
-
|
195
|
+
return frame
|
226
196
|
end
|
227
197
|
|
228
|
-
|
198
|
+
def send_binary(buffer, **options)
|
199
|
+
write_frame(@writer.pack_binary_frame(buffer, **options))
|
200
|
+
end
|
201
|
+
|
202
|
+
def send_close(code = Error::NO_ERROR, reason = "")
|
203
|
+
frame = CloseFrame.new(mask: @mask)
|
204
|
+
frame.pack(code, reason)
|
205
|
+
|
206
|
+
self.write_frame(frame)
|
207
|
+
self.flush
|
208
|
+
|
209
|
+
@state = :closed
|
210
|
+
end
|
211
|
+
|
212
|
+
# Write a message to the connection.
|
213
|
+
# @parameter message [Message] The message to send.
|
214
|
+
def write(message, **options)
|
215
|
+
if message.is_a?(String)
|
216
|
+
if message.encoding == Encoding::UTF_8
|
217
|
+
return send_text(message, **options)
|
218
|
+
else
|
219
|
+
return send_binary(message, **options)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
message.send(self, **options)
|
224
|
+
end
|
225
|
+
|
226
|
+
# The default implementation for reading a message buffer.
|
227
|
+
def unpack_frames(frames)
|
228
|
+
frames.map(&:unpack).join("")
|
229
|
+
end
|
230
|
+
|
231
|
+
# Read a message from the connection.
|
232
|
+
# @returns message [Message] The received message.
|
229
233
|
def read(**options)
|
230
234
|
@framer.flush
|
231
235
|
|
@@ -234,7 +238,7 @@ module Protocol
|
|
234
238
|
frames = @frames
|
235
239
|
@frames = []
|
236
240
|
|
237
|
-
buffer = @reader.
|
241
|
+
buffer = @reader.unpack_frames(frames, **options)
|
238
242
|
return frames.first.read_message(buffer)
|
239
243
|
end
|
240
244
|
end
|
@@ -243,10 +247,6 @@ module Protocol
|
|
243
247
|
|
244
248
|
raise
|
245
249
|
end
|
246
|
-
|
247
|
-
def read_message(frames, **options)
|
248
|
-
frames.map(&:unpack).join("")
|
249
|
-
end
|
250
250
|
end
|
251
251
|
end
|
252
252
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'zlib'
|
22
|
+
|
23
|
+
module Protocol
|
24
|
+
module WebSocket
|
25
|
+
module Extension
|
26
|
+
module Compression
|
27
|
+
NAME = 'permessage-deflate'
|
28
|
+
|
29
|
+
# Zlib is not capable of handling < 9 window bits.
|
30
|
+
MINIMUM_WINDOW_BITS = 9
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -18,24 +18,26 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
require_relative 'constants'
|
22
22
|
|
23
23
|
module Protocol
|
24
24
|
module WebSocket
|
25
25
|
module Extension
|
26
26
|
module Compression
|
27
27
|
class Deflate
|
28
|
-
|
28
|
+
# Client writing to server.
|
29
|
+
def self.client(parent, client_max_window_bits: 15, client_no_context_takeover: false, **options)
|
29
30
|
self.new(parent,
|
30
|
-
window_bits:
|
31
|
+
window_bits: client_max_window_bits,
|
31
32
|
context_takeover: !client_no_context_takeover,
|
32
33
|
**options
|
33
34
|
)
|
34
35
|
end
|
35
36
|
|
36
|
-
|
37
|
+
# Server writing to client.
|
38
|
+
def self.server(parent, server_max_window_bits: 15, server_no_context_takeover: false, **options)
|
37
39
|
self.new(parent,
|
38
|
-
window_bits:
|
40
|
+
window_bits: server_max_window_bits,
|
39
41
|
context_takeover: !server_no_context_takeover,
|
40
42
|
**options
|
41
43
|
)
|
@@ -46,28 +48,39 @@ module Protocol
|
|
46
48
|
|
47
49
|
@deflate = nil
|
48
50
|
|
49
|
-
@
|
51
|
+
@level = level
|
50
52
|
@memory_level = memory_level
|
51
53
|
@strategy = strategy
|
52
54
|
|
55
|
+
if window_bits < MINIMUM_WINDOW_BITS
|
56
|
+
window_bits = MINIMUM_WINDOW_BITS
|
57
|
+
end
|
58
|
+
|
53
59
|
@window_bits = window_bits
|
54
60
|
@context_takeover = context_takeover
|
55
61
|
end
|
56
62
|
|
57
|
-
def
|
63
|
+
def inspect
|
64
|
+
"#<#{self.class} window_bits=#{@window_bits} context_takeover=#{@context_takeover}>"
|
65
|
+
end
|
66
|
+
|
67
|
+
attr :window_bits
|
68
|
+
attr :context_takeover
|
69
|
+
|
70
|
+
def pack_text_frame(buffer, compress: true, **options)
|
58
71
|
buffer = self.deflate(buffer)
|
59
72
|
|
60
|
-
frame = @parent.
|
73
|
+
frame = @parent.pack_text_frame(buffer, **options)
|
61
74
|
|
62
75
|
frame.flags |= Frame::RSV1
|
63
76
|
|
64
77
|
return frame
|
65
78
|
end
|
66
79
|
|
67
|
-
def
|
68
|
-
|
80
|
+
def pack_binary_frame(buffer, compress: false, **options)
|
81
|
+
buffer = self.deflate(buffer)
|
69
82
|
|
70
|
-
frame = parent.
|
83
|
+
frame = @parent.pack_binary_frame(buffer, **options)
|
71
84
|
|
72
85
|
frame.flags |= Frame::RSV1
|
73
86
|
|
@@ -77,14 +90,13 @@ module Protocol
|
|
77
90
|
private
|
78
91
|
|
79
92
|
def deflate(buffer)
|
80
|
-
Console.logger.info(self, "Deflating #{buffer.size} bytes")
|
81
93
|
deflate = @deflate || Zlib::Deflate.new(@level, -@window_bits, @memory_level, @strategy)
|
82
94
|
|
83
95
|
if @context_takeover
|
84
96
|
@deflate = deflate
|
85
97
|
end
|
86
98
|
|
87
|
-
return
|
99
|
+
return deflate.deflate(buffer, Zlib::SYNC_FLUSH)[0...-4]
|
88
100
|
end
|
89
101
|
end
|
90
102
|
end
|
@@ -18,26 +18,26 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
require_relative 'constants'
|
22
22
|
|
23
23
|
module Protocol
|
24
24
|
module WebSocket
|
25
25
|
module Extension
|
26
26
|
module Compression
|
27
27
|
class Inflate
|
28
|
-
|
28
|
+
# Client reading from server.
|
29
|
+
def self.client(parent, server_max_window_bits: 15, server_no_context_takeover: false, **options)
|
29
30
|
self.new(parent,
|
30
|
-
window_bits:
|
31
|
-
context_takeover: !
|
32
|
-
**options
|
31
|
+
window_bits: server_max_window_bits,
|
32
|
+
context_takeover: !server_no_context_takeover,
|
33
33
|
)
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
# Server reading from client.
|
37
|
+
def self.server(parent, client_max_window_bits: 15, client_no_context_takeover: false, **options)
|
37
38
|
self.new(parent,
|
38
|
-
window_bits:
|
39
|
-
context_takeover: !
|
40
|
-
**options
|
39
|
+
window_bits: client_max_window_bits,
|
40
|
+
context_takeover: !client_no_context_takeover,
|
41
41
|
)
|
42
42
|
end
|
43
43
|
|
@@ -48,12 +48,19 @@ module Protocol
|
|
48
48
|
|
49
49
|
@inflate = nil
|
50
50
|
|
51
|
+
if window_bits < MINIMUM_WINDOW_BITS
|
52
|
+
window_bits = MINIMUM_WINDOW_BITS
|
53
|
+
end
|
54
|
+
|
51
55
|
@window_bits = window_bits
|
52
56
|
@context_takeover = context_takeover
|
53
57
|
end
|
54
58
|
|
55
|
-
|
56
|
-
|
59
|
+
attr :window_bits
|
60
|
+
attr :context_takeover
|
61
|
+
|
62
|
+
def unpack_frames(frames, **options)
|
63
|
+
buffer = @parent.unpack_frames(frames, **options)
|
57
64
|
|
58
65
|
frame = frames.first
|
59
66
|
|
@@ -69,7 +76,6 @@ module Protocol
|
|
69
76
|
private
|
70
77
|
|
71
78
|
def inflate(buffer)
|
72
|
-
Console.logger.info(self, "Inflating #{buffer.bytesize} bytes")
|
73
79
|
inflate = @inflate || Zlib::Inflate.new(-@window_bits)
|
74
80
|
|
75
81
|
if @context_takeover
|
@@ -18,7 +18,7 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
|
-
|
21
|
+
require_relative 'compression/constants'
|
22
22
|
require_relative 'compression/inflate'
|
23
23
|
require_relative 'compression/deflate'
|
24
24
|
|
@@ -26,17 +26,15 @@ module Protocol
|
|
26
26
|
module WebSocket
|
27
27
|
module Extension
|
28
28
|
module Compression
|
29
|
-
NAME = 'permessage-deflate'
|
30
|
-
|
31
29
|
# Client offer to server, construct a list of requested compression parameters suitable for the `Sec-WebSocket-Extensions` header.
|
32
30
|
# @returns [Array(String)] a list of compression parameters suitable to send to the server.
|
33
|
-
def self.offer(
|
31
|
+
def self.offer(client_max_window_bits: true, server_max_window_bits: true, client_no_context_takeover: false, server_no_context_takeover: false)
|
34
32
|
|
35
33
|
header = [NAME]
|
36
34
|
|
37
|
-
case
|
35
|
+
case client_max_window_bits
|
38
36
|
when 8..15
|
39
|
-
header << "client_max_window_bits=#{
|
37
|
+
header << "client_max_window_bits=#{client_max_window_bits}"
|
40
38
|
when true
|
41
39
|
header << 'client_max_window_bits'
|
42
40
|
else
|
@@ -47,9 +45,9 @@ module Protocol
|
|
47
45
|
header << 'client_no_context_takeover'
|
48
46
|
end
|
49
47
|
|
50
|
-
case
|
48
|
+
case server_max_window_bits
|
51
49
|
when 8..15
|
52
|
-
header << "server_max_window_bits=#{
|
50
|
+
header << "server_max_window_bits=#{server_max_window_bits}"
|
53
51
|
when true
|
54
52
|
# Default (unspecified) to the server maximum window bits.
|
55
53
|
else
|
@@ -72,22 +70,28 @@ module Protocol
|
|
72
70
|
arguments.each do |key, value|
|
73
71
|
case key
|
74
72
|
when "server_no_context_takeover"
|
75
|
-
options[:server_no_context_takeover] =
|
73
|
+
options[:server_no_context_takeover] = true
|
76
74
|
header << key
|
77
75
|
when "client_no_context_takeover"
|
78
|
-
options[:client_no_context_takeover] =
|
76
|
+
options[:client_no_context_takeover] = true
|
79
77
|
header << key
|
80
78
|
when "server_max_window_bits"
|
81
|
-
|
79
|
+
value = Integer(value || 15)
|
80
|
+
value = MINIMUM_WINDOW_BITS if value < MINIMUM_WINDOW_BITS
|
81
|
+
options[:server_max_window_bits] = value
|
82
|
+
header << "server_max_window_bits=#{value}"
|
82
83
|
when "client_max_window_bits"
|
83
|
-
|
84
|
+
value = Integer(value || 15)
|
85
|
+
value = MINIMUM_WINDOW_BITS if value < MINIMUM_WINDOW_BITS
|
86
|
+
options[:client_max_window_bits] = value
|
87
|
+
header << "client_max_window_bits=#{value}"
|
84
88
|
else
|
85
89
|
raise ArgumentError, "Unknown option #{key}!"
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
89
93
|
# The header which represents the final accepted/negotiated configuration.
|
90
|
-
return header
|
94
|
+
return header, options
|
91
95
|
end
|
92
96
|
|
93
97
|
# @parameter options [Hash] a hash of options which are accepted by the server.
|
@@ -105,9 +109,9 @@ module Protocol
|
|
105
109
|
arguments.each do |key, value|
|
106
110
|
case key
|
107
111
|
when "server_no_context_takeover"
|
108
|
-
options[:server_no_context_takeover] =
|
112
|
+
options[:server_no_context_takeover] = true
|
109
113
|
when "client_no_context_takeover"
|
110
|
-
options[:client_no_context_takeover] =
|
114
|
+
options[:client_no_context_takeover] = true
|
111
115
|
when "server_max_window_bits"
|
112
116
|
options[:server_max_window_bits] = Integer(value || 15)
|
113
117
|
when "client_max_window_bits"
|
@@ -116,6 +120,8 @@ module Protocol
|
|
116
120
|
raise ArgumentError, "Unknown option #{key}!"
|
117
121
|
end
|
118
122
|
end
|
123
|
+
|
124
|
+
return options
|
119
125
|
end
|
120
126
|
|
121
127
|
# @parameter options [Hash] a hash of options which are accepted by the client.
|
@@ -75,7 +75,7 @@ module Protocol
|
|
75
75
|
if extension = named.delete(name)
|
76
76
|
klass, options = extension
|
77
77
|
|
78
|
-
klass.accept(arguments, **options)
|
78
|
+
options = klass.accept(arguments, **options)
|
79
79
|
|
80
80
|
@accepted << [klass, options]
|
81
81
|
end
|
@@ -84,7 +84,7 @@ module Protocol
|
|
84
84
|
|
85
85
|
def apply(connection)
|
86
86
|
@accepted.each do |(klass, options)|
|
87
|
-
klass.
|
87
|
+
klass.client(connection, **options)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -121,7 +121,9 @@ module Protocol
|
|
121
121
|
if extension = named[name]
|
122
122
|
klass, options = extension
|
123
123
|
|
124
|
-
if
|
124
|
+
if result = klass.negotiate(arguments, **options)
|
125
|
+
header, options = result
|
126
|
+
|
125
127
|
# The extension is accepted and no further offers will be considered:
|
126
128
|
named.delete(name)
|
127
129
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Copyright, 2022, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative 'frame'
|
22
|
+
|
23
|
+
module Protocol
|
24
|
+
module WebSocket
|
25
|
+
class Message
|
26
|
+
def initialize(buffer)
|
27
|
+
@buffer = buffer
|
28
|
+
end
|
29
|
+
|
30
|
+
attr :buffer
|
31
|
+
|
32
|
+
def size
|
33
|
+
@buffer.bytesize
|
34
|
+
end
|
35
|
+
|
36
|
+
def == other
|
37
|
+
@buffer == other
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_str
|
41
|
+
@buffer
|
42
|
+
end
|
43
|
+
|
44
|
+
def encoding
|
45
|
+
@buffer.encoding
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class TextMessage < Message
|
50
|
+
def send(connection, **options)
|
51
|
+
connection.send_text(@buffer, **options)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class BinaryMessage < Message
|
56
|
+
def send(connection, **options)
|
57
|
+
connection.send_binary(@buffer, **options)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -19,6 +19,7 @@
|
|
19
19
|
# THE SOFTWARE.
|
20
20
|
|
21
21
|
require_relative 'frame'
|
22
|
+
require_relative 'message'
|
22
23
|
|
23
24
|
module Protocol
|
24
25
|
module WebSocket
|
@@ -39,7 +40,7 @@ module Protocol
|
|
39
40
|
raise ProtocolError, "invalid UTF-8 in text frame!"
|
40
41
|
end
|
41
42
|
|
42
|
-
buffer
|
43
|
+
return TextMessage.new(buffer)
|
43
44
|
end
|
44
45
|
|
45
46
|
# Apply this frame to the specified connection.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protocol-websocket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -41,7 +41,7 @@ cert_chain:
|
|
41
41
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
42
42
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
43
43
|
-----END CERTIFICATE-----
|
44
|
-
date: 2022-08-
|
44
|
+
date: 2022-08-22 00:00:00.000000000 Z
|
45
45
|
dependencies:
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: protocol-http
|
@@ -100,25 +100,27 @@ dependencies:
|
|
100
100
|
- !ruby/object:Gem::Version
|
101
101
|
version: '0'
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
|
-
name:
|
103
|
+
name: sus
|
104
104
|
requirement: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - "~>"
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
108
|
+
version: 0.9.1
|
109
109
|
type: :development
|
110
110
|
prerelease: false
|
111
111
|
version_requirements: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
115
|
+
version: 0.9.1
|
116
116
|
description:
|
117
117
|
email:
|
118
118
|
executables: []
|
119
119
|
extensions: []
|
120
120
|
extra_rdoc_files: []
|
121
121
|
files:
|
122
|
+
- lib/.DS_Store
|
123
|
+
- lib/protocol/.DS_Store
|
122
124
|
- lib/protocol/websocket.rb
|
123
125
|
- lib/protocol/websocket/binary_frame.rb
|
124
126
|
- lib/protocol/websocket/close_frame.rb
|
@@ -126,6 +128,7 @@ files:
|
|
126
128
|
- lib/protocol/websocket/continuation_frame.rb
|
127
129
|
- lib/protocol/websocket/error.rb
|
128
130
|
- lib/protocol/websocket/extension/compression.rb
|
131
|
+
- lib/protocol/websocket/extension/compression/constants.rb
|
129
132
|
- lib/protocol/websocket/extension/compression/deflate.rb
|
130
133
|
- lib/protocol/websocket/extension/compression/inflate.rb
|
131
134
|
- lib/protocol/websocket/extensions.md
|
@@ -133,6 +136,7 @@ files:
|
|
133
136
|
- lib/protocol/websocket/frame.rb
|
134
137
|
- lib/protocol/websocket/framer.rb
|
135
138
|
- lib/protocol/websocket/headers.rb
|
139
|
+
- lib/protocol/websocket/message.rb
|
136
140
|
- lib/protocol/websocket/ping_frame.rb
|
137
141
|
- lib/protocol/websocket/pong_frame.rb
|
138
142
|
- lib/protocol/websocket/text_frame.rb
|
metadata.gz.sig
CHANGED
Binary file
|