protocol-websocket 0.16.0 → 0.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/protocol/websocket/binary_frame.rb +2 -2
- data/lib/protocol/websocket/close_frame.rb +9 -1
- data/lib/protocol/websocket/coder/json.rb +1 -1
- data/lib/protocol/websocket/coder.rb +1 -1
- data/lib/protocol/websocket/connection.rb +24 -4
- data/lib/protocol/websocket/continuation_frame.rb +1 -1
- data/lib/protocol/websocket/error.rb +17 -3
- data/lib/protocol/websocket/extension/compression/constants.rb +3 -3
- data/lib/protocol/websocket/extension/compression/deflate.rb +2 -2
- data/lib/protocol/websocket/extension/compression/inflate.rb +3 -3
- data/lib/protocol/websocket/extension/compression.rb +6 -6
- data/lib/protocol/websocket/extensions.rb +3 -3
- data/lib/protocol/websocket/frame.rb +6 -6
- data/lib/protocol/websocket/framer.rb +7 -7
- data/lib/protocol/websocket/headers.rb +9 -9
- data/lib/protocol/websocket/message.rb +9 -2
- data/lib/protocol/websocket/ping_frame.rb +2 -2
- data/lib/protocol/websocket/pong_frame.rb +1 -1
- data/lib/protocol/websocket/text_frame.rb +2 -2
- data/lib/protocol/websocket/version.rb +1 -1
- data/lib/protocol/websocket.rb +4 -4
- data.tar.gz.sig +0 -0
- metadata +2 -3
- metadata.gz.sig +0 -0
- data/lib/protocol/websocket/json_message.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef7b32c9de28a9b7486a004d8ae53739fbe34de345e32b7a5e4ff056df5c755c
|
4
|
+
data.tar.gz: 2b8d07f45527f32e5a4b2cf0bb5d22707083a6fea94bedb1e93413aece140ee1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfef8b28cadd857f4d7430cb35e668f14789ce9d70fed4fa2c24c945ff9848ef9d35000e143b0344489c8120b4d940168a07e717a8da22738d1972f1f373bb8d
|
7
|
+
data.tar.gz: b3df54c2b5fa01963ffa5f26f15ddd16f3d983b20aeac9d1ee39fb60d052bfb720ee7963c2588708aebb6a9d649c29af81518f3af2bd1dc67c147b9fc6983673
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -4,7 +4,7 @@
|
|
4
4
|
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
# Copyright, 2021, by Aurora Nockert.
|
6
6
|
|
7
|
-
require_relative
|
7
|
+
require_relative "frame"
|
8
8
|
|
9
9
|
module Protocol
|
10
10
|
module WebSocket
|
@@ -59,6 +59,14 @@ module Protocol
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
# Generate a suitable reply.
|
63
|
+
# @returns [CloseFrame]
|
64
|
+
def reply(code = Error::NO_ERROR, reason = "")
|
65
|
+
frame = CloseFrame.new
|
66
|
+
frame.pack(code, reason)
|
67
|
+
return frame
|
68
|
+
end
|
69
|
+
|
62
70
|
# Apply this frame to the specified connection.
|
63
71
|
def apply(connection)
|
64
72
|
connection.receive_close(self)
|
@@ -5,8 +5,7 @@
|
|
5
5
|
# Copyright, 2019, by William T. Nelson.
|
6
6
|
# Copyright, 2021, by Aurora Nockert.
|
7
7
|
|
8
|
-
require_relative
|
9
|
-
require 'securerandom'
|
8
|
+
require_relative "framer"
|
10
9
|
|
11
10
|
module Protocol
|
12
11
|
module WebSocket
|
@@ -89,13 +88,34 @@ module Protocol
|
|
89
88
|
@state == :closed
|
90
89
|
end
|
91
90
|
|
92
|
-
# Immediately transition the connection to the closed state *and* close the underlying connection.
|
91
|
+
# Immediately transition the connection to the closed state *and* close the underlying connection. Any data not yet read will be lost.
|
93
92
|
def close(...)
|
94
93
|
close!(...)
|
95
94
|
|
96
95
|
@framer.close
|
97
96
|
end
|
98
97
|
|
98
|
+
# Close the connection gracefully, sending a close frame with the specified error code and reason. If an error occurs while sending the close frame, the connection will be closed immediately. You may continue to read data from the connection after calling this method, but you should not write any more data.
|
99
|
+
#
|
100
|
+
# @parameter error [Error | Nil] The error that occurred, if any.
|
101
|
+
def close_write(error = nil)
|
102
|
+
if error
|
103
|
+
send_close(Error::INTERNAL_ERROR, error.message)
|
104
|
+
else
|
105
|
+
send_close
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Close the connection gracefully. This will send a close frame and wait for the remote end to respond with a close frame. Any data received after the close frame is sent will be ignored. If you want to process this data, use {#close_write} instead, and read the data before calling {#close}.
|
110
|
+
def shutdown
|
111
|
+
send_close unless @state == :closed
|
112
|
+
|
113
|
+
# `read_frame` will return nil after receiving a close frame:
|
114
|
+
while read_frame
|
115
|
+
# Drain the connection.
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
99
119
|
# Read a frame from the framer, and apply it to the connection.
|
100
120
|
def read_frame
|
101
121
|
return nil if closed?
|
@@ -246,7 +266,7 @@ module Protocol
|
|
246
266
|
def write(message, **options)
|
247
267
|
case message
|
248
268
|
when String
|
249
|
-
|
269
|
+
# This is a compatibility shim for the previous implementation. We may want to eventually deprecate this use case... or maybe it's convenient enough to leave it around.
|
250
270
|
if message.encoding == Encoding::UTF_8
|
251
271
|
return send_text(message, **options)
|
252
272
|
else
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "protocol/http/error"
|
7
7
|
|
8
8
|
module Protocol
|
9
9
|
module WebSocket
|
@@ -19,10 +19,24 @@ module Protocol
|
|
19
19
|
# Indicates that an endpoint is terminating the connection due to a protocol error.
|
20
20
|
PROTOCOL_ERROR = 1002
|
21
21
|
|
22
|
-
# Indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept.
|
22
|
+
# Indicates that an endpoint is terminating the connection because it has received a type of data it cannot accept. (e.g., an endpoint that understands only text data MAY send this if it receives a binary message).
|
23
23
|
INVALID_DATA = 1003
|
24
24
|
|
25
|
-
|
25
|
+
|
26
|
+
# Indicates that an endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message (e.g., non-UTF-8 data within a text message).
|
27
|
+
INVALID_PAYLOAD = 1007
|
28
|
+
|
29
|
+
# Indicates that an endpoint is terminating the connection because it has received a message that violates its policy. This is a generic status code that can be returned when there is no other more suitable status code (e.g., 1003 or 1009) or if there is a need to hide specific details about the policy.
|
30
|
+
POLICY_VIOLATION = 1008
|
31
|
+
|
32
|
+
# Indicates that an endpoint is terminating the connection because it has received a message that is too big for it to process.
|
33
|
+
MESSAGE_TOO_LARGE = 1009
|
34
|
+
|
35
|
+
# Indicates that an endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the server didn't return them in the response message of the WebSocket handshake. The list of extensions that are needed should appear in the /reason/ part of the Close frame. Note that this status code is not used by the server, because it can fail the WebSocket handshake instead.
|
36
|
+
MISSING_EXTENSION = 1010
|
37
|
+
|
38
|
+
# Indicates that a server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.
|
39
|
+
INTERNAL_ERROR = 1011
|
26
40
|
end
|
27
41
|
|
28
42
|
# Raised by stream or connection handlers, results in GOAWAY frame which signals termination of the current connection. You *cannot* recover from this exception, or any exceptions subclassed from it.
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2022-
|
4
|
+
# Copyright, 2022-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
6
|
+
require "zlib"
|
7
7
|
|
8
8
|
module Protocol
|
9
9
|
module WebSocket
|
10
10
|
module Extension
|
11
11
|
module Compression
|
12
|
-
NAME =
|
12
|
+
NAME = "permessage-deflate"
|
13
13
|
|
14
14
|
# Zlib is not capable of handling < 9 window bits.
|
15
15
|
MINIMUM_WINDOW_BITS = 9
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2022-
|
4
|
+
# Copyright, 2022-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "constants"
|
7
7
|
|
8
8
|
module Protocol
|
9
9
|
module WebSocket
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2022-
|
4
|
+
# Copyright, 2022-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "constants"
|
7
7
|
|
8
8
|
module Protocol
|
9
9
|
module WebSocket
|
@@ -26,7 +26,7 @@ module Protocol
|
|
26
26
|
)
|
27
27
|
end
|
28
28
|
|
29
|
-
TRAILER = [0x00, 0x00, 0xff, 0xff].pack(
|
29
|
+
TRAILER = [0x00, 0x00, 0xff, 0xff].pack("C*")
|
30
30
|
|
31
31
|
def initialize(parent, context_takeover: true, window_bits: 15)
|
32
32
|
@parent = parent
|
@@ -3,9 +3,9 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2022-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
6
|
+
require_relative "compression/constants"
|
7
|
+
require_relative "compression/inflate"
|
8
|
+
require_relative "compression/deflate"
|
9
9
|
|
10
10
|
module Protocol
|
11
11
|
module WebSocket
|
@@ -22,13 +22,13 @@ module Protocol
|
|
22
22
|
when 8..15
|
23
23
|
header << "client_max_window_bits=#{client_max_window_bits}"
|
24
24
|
when true
|
25
|
-
header <<
|
25
|
+
header << "client_max_window_bits"
|
26
26
|
else
|
27
27
|
raise ArgumentError, "Invalid local maximum window bits!"
|
28
28
|
end
|
29
29
|
|
30
30
|
if client_no_context_takeover
|
31
|
-
header <<
|
31
|
+
header << "client_no_context_takeover"
|
32
32
|
end
|
33
33
|
|
34
34
|
case server_max_window_bits
|
@@ -41,7 +41,7 @@ module Protocol
|
|
41
41
|
end
|
42
42
|
|
43
43
|
if server_no_context_takeover
|
44
|
-
header <<
|
44
|
+
header << "server_no_context_takeover"
|
45
45
|
end
|
46
46
|
|
47
47
|
return header
|
@@ -3,8 +3,8 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2022-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
6
|
+
require_relative "extension/compression"
|
7
|
+
require_relative "headers"
|
8
8
|
|
9
9
|
module Protocol
|
10
10
|
module WebSocket
|
@@ -16,7 +16,7 @@ module Protocol
|
|
16
16
|
name, *arguments = header.split(/\s*;\s*/)
|
17
17
|
|
18
18
|
arguments = arguments.map do |argument|
|
19
|
-
argument.split(
|
19
|
+
argument.split("=", 2)
|
20
20
|
end
|
21
21
|
|
22
22
|
yield name, arguments
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# Copyright, 2019, by Soumya.
|
6
6
|
# Copyright, 2021, by Aurora Nockert.
|
7
7
|
|
8
|
-
require_relative
|
8
|
+
require_relative "error"
|
9
9
|
|
10
10
|
module Protocol
|
11
11
|
module WebSocket
|
@@ -178,10 +178,10 @@ module Protocol
|
|
178
178
|
|
179
179
|
if length == 126
|
180
180
|
buffer = stream.read(2) or raise EOFError, "Could not read length!"
|
181
|
-
length = buffer.unpack(
|
181
|
+
length = buffer.unpack("n").first
|
182
182
|
elsif length == 127
|
183
183
|
buffer = stream.read(8) or raise EOFError, "Could not read length!"
|
184
|
-
length = buffer.unpack(
|
184
|
+
length = buffer.unpack("Q>").first
|
185
185
|
end
|
186
186
|
|
187
187
|
if length > maximum_frame_size
|
@@ -223,12 +223,12 @@ module Protocol
|
|
223
223
|
buffer << [
|
224
224
|
(@finished ? 0b1000_0000 : 0) | (@flags << 4) | @opcode,
|
225
225
|
(@mask ? 0b1000_0000 : 0) | short_length,
|
226
|
-
].pack(
|
226
|
+
].pack("CC")
|
227
227
|
|
228
228
|
if short_length == 126
|
229
|
-
buffer << [@length].pack(
|
229
|
+
buffer << [@length].pack("n")
|
230
230
|
elsif short_length == 127
|
231
|
-
buffer << [@length].pack(
|
231
|
+
buffer << [@length].pack("Q>")
|
232
232
|
end
|
233
233
|
|
234
234
|
buffer << @mask if @mask
|
@@ -3,14 +3,14 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
6
|
+
require_relative "frame"
|
7
7
|
|
8
|
-
require_relative
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
8
|
+
require_relative "continuation_frame"
|
9
|
+
require_relative "text_frame"
|
10
|
+
require_relative "binary_frame"
|
11
|
+
require_relative "close_frame"
|
12
|
+
require_relative "ping_frame"
|
13
|
+
require_relative "pong_frame"
|
14
14
|
|
15
15
|
module Protocol
|
16
16
|
module WebSocket
|
@@ -1,27 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2019-
|
4
|
+
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
6
|
+
require "digest/sha1"
|
7
|
+
require "securerandom"
|
8
8
|
|
9
9
|
module Protocol
|
10
10
|
module WebSocket
|
11
11
|
module Headers
|
12
12
|
# The protocol string used for the `upgrade:` header (HTTP/1) and `:protocol` pseudo-header (HTTP/2).
|
13
|
-
PROTOCOL = "websocket"
|
13
|
+
PROTOCOL = "websocket"
|
14
14
|
|
15
15
|
# The WebSocket protocol header, used for application level protocol negotiation.
|
16
|
-
SEC_WEBSOCKET_PROTOCOL =
|
16
|
+
SEC_WEBSOCKET_PROTOCOL = "sec-websocket-protocol"
|
17
17
|
|
18
18
|
# The WebSocket version header. Used for negotiating binary protocol version.
|
19
|
-
SEC_WEBSOCKET_VERSION =
|
19
|
+
SEC_WEBSOCKET_VERSION = "sec-websocket-version"
|
20
20
|
|
21
|
-
SEC_WEBSOCKET_KEY =
|
22
|
-
SEC_WEBSOCKET_ACCEPT =
|
21
|
+
SEC_WEBSOCKET_KEY = "sec-websocket-key"
|
22
|
+
SEC_WEBSOCKET_ACCEPT = "sec-websocket-accept"
|
23
23
|
|
24
|
-
SEC_WEBSOCKET_EXTENSIONS =
|
24
|
+
SEC_WEBSOCKET_EXTENSIONS = "sec-websocket-extensions"
|
25
25
|
|
26
26
|
module Nounce
|
27
27
|
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
|
@@ -3,8 +3,8 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2022-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
6
|
+
require_relative "frame"
|
7
|
+
require_relative "coder"
|
8
8
|
|
9
9
|
module Protocol
|
10
10
|
module WebSocket
|
@@ -72,5 +72,12 @@ module Protocol
|
|
72
72
|
connection.send_binary(@buffer, **options)
|
73
73
|
end
|
74
74
|
end
|
75
|
+
|
76
|
+
# Represents a ping message that can be sent over a WebSocket connection.
|
77
|
+
class PingMessage < Message
|
78
|
+
def send(connection)
|
79
|
+
connection.send_ping(@buffer)
|
80
|
+
end
|
81
|
+
end
|
75
82
|
end
|
76
83
|
end
|
data/lib/protocol/websocket.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2019-2024, by Samuel Williams.
|
5
5
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
6
|
+
require_relative "websocket/version"
|
7
|
+
require_relative "websocket/framer"
|
8
|
+
require_relative "websocket/connection"
|
9
|
+
require_relative "websocket/message"
|
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.18.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: 2024-09-
|
44
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
45
45
|
dependencies:
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: protocol-http
|
@@ -79,7 +79,6 @@ files:
|
|
79
79
|
- lib/protocol/websocket/frame.rb
|
80
80
|
- lib/protocol/websocket/framer.rb
|
81
81
|
- lib/protocol/websocket/headers.rb
|
82
|
-
- lib/protocol/websocket/json_message.rb
|
83
82
|
- lib/protocol/websocket/message.rb
|
84
83
|
- lib/protocol/websocket/ping_frame.rb
|
85
84
|
- lib/protocol/websocket/pong_frame.rb
|
metadata.gz.sig
CHANGED
Binary file
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Released under the MIT License.
|
4
|
-
# Copyright, 2022-2024, by Samuel Williams.
|
5
|
-
|
6
|
-
require_relative 'message'
|
7
|
-
|
8
|
-
warn "Protocol::WebSocket::JSONMessage is deprecated. Use Protocol::WebSocket::TextMessage instead."
|
9
|
-
|
10
|
-
module Protocol
|
11
|
-
module WebSocket
|
12
|
-
# @deprecated Use {TextMessage} instead.
|
13
|
-
class JSONMessage < TextMessage
|
14
|
-
def self.wrap(message)
|
15
|
-
message
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.generate(object)
|
19
|
-
self.new(JSON.generate(object))
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|