protocol-websocket 0.11.1 → 0.12.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17a6b7e17274fe574b07bc2ad242cbe383671f7f05c84fd784ec474fbde5e28a
4
- data.tar.gz: f1098660970a0cf6069d5037dd736b52b18b7da51727c9968a96970ecd1015b0
3
+ metadata.gz: 48ab5e17dd31fff02afee7770e13982923252d35c0e78f0f8b12f35d6d34ff2a
4
+ data.tar.gz: 5cfe56a5875410c6190f65928ea4b0897abccb66981581b46271e9bd8b2d72a1
5
5
  SHA512:
6
- metadata.gz: 1720e16bd8d32258b7583d9cde912229d64af57428ad3bb8644832c5b6f4e5c1588a798c9368a9638c5801f320e9b8489094d40ca5ffe45634b6d582d3f12170
7
- data.tar.gz: 17ac4461055d2de24188f365a85e5fb80c907ab041fc62bdc2f376e24bec1178f950ef8ff4388d39c6c144e056e63d8fc8e28ab53dcd537a4f92af73c02a5dd2
6
+ metadata.gz: 7f558e9e5b5f4a1d83cc1cfa298b5a4edef48a0fc256b4ba949ce8d10db66a9c7df9db1b68cf083e46b340984f7c1575b745b8f0a81c45a66a63405ff703d11e
7
+ data.tar.gz: 9e3f2863933129185d723c256ac2d1ad1086e357ae4028f05dc2b1d746b9e8e29d5e57ee98148e2f045997eb1acfbfe1c7e1ff325d2815a3ad75b145fe2590c1
checksums.yaml.gz.sig CHANGED
Binary file
@@ -61,8 +61,17 @@ module Protocol
61
61
  return self
62
62
  end
63
63
 
64
+ # If not already closed, transition the connection to the closed state and send a close frame.
64
65
  def close!(...)
65
- @state = :closed
66
+ unless @state == :closed
67
+ @state = :closed
68
+
69
+ begin
70
+ send_close(...)
71
+ rescue
72
+ # Ignore errors.
73
+ end
74
+ end
66
75
 
67
76
  return self
68
77
  end
@@ -71,16 +80,9 @@ module Protocol
71
80
  @state == :closed
72
81
  end
73
82
 
83
+ # Immediately transition the connection to the closed state and close the underlying connection.
74
84
  def close(...)
75
- unless @state == :closed
76
- close!
77
-
78
- begin
79
- send_close(...)
80
- rescue
81
- # Ignore.
82
- end
83
- end
85
+ close!(...)
84
86
 
85
87
  @framer.close
86
88
  end
@@ -101,11 +103,9 @@ module Protocol
101
103
  return frame
102
104
  rescue ProtocolError => error
103
105
  close(error.code, error.message)
104
-
105
106
  raise
106
- rescue
107
- close(Error::PROTOCOL_ERROR, $!.message)
108
-
107
+ rescue => error
108
+ close(Error::PROTOCOL_ERROR, error.message)
109
109
  raise
110
110
  end
111
111
 
@@ -142,11 +142,8 @@ module Protocol
142
142
  def receive_close(frame)
143
143
  code, reason = frame.unpack
144
144
 
145
- # If we're already closed, then we don't need to send a close frame. Otherwise, according to the RFC, we should echo the close frame. However, it's possible it will fail to send if the connection is already closed.
146
- unless @state == :closed
147
- close!
148
- send_close(code, reason)
149
- end
145
+ # On receiving a close frame, we must enter the closed state:
146
+ close!(code, reason)
150
147
 
151
148
  if code and code != Error::NO_ERROR
152
149
  raise ClosedError.new reason, code
@@ -202,6 +199,7 @@ module Protocol
202
199
  write_frame(@writer.pack_binary_frame(buffer, **options))
203
200
  end
204
201
 
202
+ # Send a control frame with data containing a specified control sequence to begin the closing handshake. Does not close the connection, until the remote end responds with a close frame.
205
203
  def send_close(code = Error::NO_ERROR, reason = "")
206
204
  frame = CloseFrame.new(mask: @mask)
207
205
  frame.pack(code, reason)
@@ -246,7 +244,6 @@ module Protocol
246
244
  end
247
245
  rescue ProtocolError => error
248
246
  close(error.code, error.message)
249
-
250
247
  raise
251
248
  end
252
249
  end
@@ -54,21 +54,29 @@ module Protocol
54
54
  attr :context_takeover
55
55
 
56
56
  def pack_text_frame(buffer, compress: true, **options)
57
- buffer = self.deflate(buffer)
57
+ if compress
58
+ buffer = self.deflate(buffer)
59
+ end
58
60
 
59
61
  frame = @parent.pack_text_frame(buffer, **options)
60
62
 
61
- frame.flags |= Frame::RSV1
63
+ if compress
64
+ frame.flags |= Frame::RSV1
65
+ end
62
66
 
63
67
  return frame
64
68
  end
65
69
 
66
70
  def pack_binary_frame(buffer, compress: false, **options)
67
- buffer = self.deflate(buffer)
71
+ if compress
72
+ buffer = self.deflate(buffer)
73
+ end
68
74
 
69
75
  frame = @parent.pack_binary_frame(buffer, **options)
70
76
 
71
- frame.flags |= Frame::RSV1
77
+ if compress
78
+ frame.flags |= Frame::RSV1
79
+ end
72
80
 
73
81
  return frame
74
82
  end
@@ -54,12 +54,11 @@ module Protocol
54
54
 
55
55
  frame = frames.first
56
56
 
57
- if frame.flags & Frame::RSV1
57
+ if frame.flag?(Frame::RSV1)
58
58
  buffer = self.inflate(buffer)
59
+ frame.flags &= ~Frame::RSV1
59
60
  end
60
61
 
61
- frame.flags &= ~Frame::RSV1
62
-
63
62
  return buffer
64
63
  end
65
64
 
@@ -34,6 +34,10 @@ module Protocol
34
34
  @payload = payload
35
35
  end
36
36
 
37
+ def flag?(value)
38
+ @flags & value != 0
39
+ end
40
+
37
41
  def <=> other
38
42
  to_ary <=> other.to_ary
39
43
  end
@@ -86,6 +90,30 @@ module Protocol
86
90
  attr_accessor :length
87
91
  attr_accessor :payload
88
92
 
93
+ if IO.const_defined?(:Buffer) && IO::Buffer.respond_to?(:for) && IO::Buffer.method_defined?(:xor!)
94
+ private def mask_xor(data, mask)
95
+ buffer = data.dup
96
+ mask_buffer = IO::Buffer.for(mask)
97
+
98
+ IO::Buffer.for(buffer) do |buffer|
99
+ buffer.xor!(mask_buffer)
100
+ end
101
+
102
+ return buffer
103
+ end
104
+ else
105
+ warn "IO::Buffer not available, falling back to slow implementation of mask_xor!"
106
+ private def mask_xor(data, mask)
107
+ result = String.new(encoding: Encoding::BINARY)
108
+
109
+ for i in 0...data.bytesize do
110
+ result << (data.getbyte(i) ^ mask.getbyte(i % 4))
111
+ end
112
+
113
+ return result
114
+ end
115
+ end
116
+
89
117
  def pack(data = "")
90
118
  length = data.bytesize
91
119
 
@@ -94,12 +122,7 @@ module Protocol
94
122
  end
95
123
 
96
124
  if @mask
97
- @payload = String.new(encoding: Encoding::BINARY)
98
-
99
- for i in 0...data.bytesize do
100
- @payload << (data.getbyte(i) ^ mask.getbyte(i % 4))
101
- end
102
-
125
+ @payload = mask_xor(data, mask)
103
126
  @length = length
104
127
  else
105
128
  @payload = data
@@ -111,13 +134,7 @@ module Protocol
111
134
 
112
135
  def unpack
113
136
  if @mask and !@payload.empty?
114
- data = String.new(encoding: Encoding::BINARY)
115
-
116
- for i in 0...@payload.bytesize do
117
- data << (@payload.getbyte(i) ^ @mask.getbyte(i % 4))
118
- end
119
-
120
- return data
137
+ return mask_xor(@payload, @mask)
121
138
  else
122
139
  return @payload
123
140
  end
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Protocol
7
7
  module WebSocket
8
- VERSION = "0.11.1"
8
+ VERSION = "0.12.1"
9
9
  end
10
10
  end
data/readme.md CHANGED
@@ -17,3 +17,11 @@ We welcome contributions to this project.
17
17
  3. Commit your changes (`git commit -am 'Add some feature'`).
18
18
  4. Push to the branch (`git push origin my-new-feature`).
19
19
  5. Create new Pull Request.
20
+
21
+ ### Developer Certificate of Origin
22
+
23
+ This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
24
+
25
+ ### Contributor Covenant
26
+
27
+ This project is governed by [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
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.11.1
4
+ version: 0.12.1
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: 2023-06-01 00:00:00.000000000 Z
44
+ date: 2023-10-05 00:00:00.000000000 Z
45
45
  dependencies:
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: protocol-http
@@ -57,62 +57,6 @@ dependencies:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
59
  version: '0.2'
60
- - !ruby/object:Gem::Dependency
61
- name: protocol-http1
62
- requirement: !ruby/object:Gem::Requirement
63
- requirements:
64
- - - "~>"
65
- - !ruby/object:Gem::Version
66
- version: '0.2'
67
- type: :runtime
68
- prerelease: false
69
- version_requirements: !ruby/object:Gem::Requirement
70
- requirements:
71
- - - "~>"
72
- - !ruby/object:Gem::Version
73
- version: '0.2'
74
- - !ruby/object:Gem::Dependency
75
- name: bundler
76
- requirement: !ruby/object:Gem::Requirement
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: '0'
81
- type: :development
82
- prerelease: false
83
- version_requirements: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- version: '0'
88
- - !ruby/object:Gem::Dependency
89
- name: covered
90
- requirement: !ruby/object:Gem::Requirement
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- version: '0'
95
- type: :development
96
- prerelease: false
97
- version_requirements: !ruby/object:Gem::Requirement
98
- requirements:
99
- - - ">="
100
- - !ruby/object:Gem::Version
101
- version: '0'
102
- - !ruby/object:Gem::Dependency
103
- name: sus
104
- requirement: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - "~>"
107
- - !ruby/object:Gem::Version
108
- version: '0.16'
109
- type: :development
110
- prerelease: false
111
- version_requirements: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - "~>"
114
- - !ruby/object:Gem::Version
115
- version: '0.16'
116
60
  description:
117
61
  email:
118
62
  executables: []
@@ -154,14 +98,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
154
98
  requirements:
155
99
  - - ">="
156
100
  - !ruby/object:Gem::Version
157
- version: 2.7.6
101
+ version: '3.0'
158
102
  required_rubygems_version: !ruby/object:Gem::Requirement
159
103
  requirements:
160
104
  - - ">="
161
105
  - !ruby/object:Gem::Version
162
106
  version: '0'
163
107
  requirements: []
164
- rubygems_version: 3.4.7
108
+ rubygems_version: 3.4.19
165
109
  signing_key:
166
110
  specification_version: 4
167
111
  summary: A low level implementation of the WebSocket protocol.
metadata.gz.sig CHANGED
Binary file