websocket-driver 0.7.1 → 0.7.5
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
- data/CHANGELOG.md +20 -0
- data/LICENSE.md +1 -1
- data/README.md +17 -8
- data/lib/websocket/driver/client.rb +7 -7
- data/lib/websocket/driver/draft75.rb +1 -1
- data/lib/websocket/driver/draft76.rb +3 -2
- data/lib/websocket/driver/headers.rb +1 -1
- data/lib/websocket/driver/hybi/message.rb +1 -1
- data/lib/websocket/driver/hybi.rb +35 -31
- data/lib/websocket/driver/proxy.rb +4 -4
- data/lib/websocket/driver/server.rb +3 -3
- data/lib/websocket/driver/stream_reader.rb +3 -3
- data/lib/websocket/driver.rb +14 -17
- data/lib/websocket/http/request.rb +2 -2
- data/lib/websocket/http/response.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 046c514660d2c0dab2cf42bce8314a17e713909377a5da470beaeadf666ff28e
|
4
|
+
data.tar.gz: 9830c412394044d102dd6f313346721076ef0f97284d6182aeb06862e1f427b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cea4027f342f51a688c8004a92ca29b68af9a9395b5e7f8d2462b8742067862718d23f4be9ca6162f761774490e4cdf33111bb746f9221d5acace6546a749b35
|
7
|
+
data.tar.gz: d124aa6acf1cbfa498b44d02d6aa659c99e97e177441e8cbd43958db38c6cf03d703d26ae73998a09719c0612f538554049d58b58aa8cc8ab5f0bb458e27c988
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
### 0.7.5 / 2021-06-12
|
2
|
+
|
3
|
+
- Do not change the encoding of strings passed to `Driver#text`
|
4
|
+
|
5
|
+
### 0.7.4 / 2021-05-24
|
6
|
+
|
7
|
+
- Optimise conversions between strings and byte arrays and related encoding
|
8
|
+
operations, to reduce amount of allocation and copying
|
9
|
+
|
10
|
+
### 0.7.3 / 2020-07-09
|
11
|
+
|
12
|
+
- Let the client accept HTTP responses that have an empty reason phrase
|
13
|
+
following the `101` status code
|
14
|
+
|
15
|
+
### 0.7.2 / 2020-05-22
|
16
|
+
|
17
|
+
- Emit `ping` and `pong` events from the `Server` driver
|
18
|
+
- Handle draft-76 handshakes correctly if the request's body is a frozen string
|
19
|
+
|
1
20
|
### 0.7.1 / 2019-06-10
|
2
21
|
|
3
22
|
- Catch any exceptions produced while generating a handshake response and send a
|
@@ -5,6 +24,7 @@
|
|
5
24
|
- Pick the RFC-6455 protocol version if the request contains any of the headers
|
6
25
|
used by that version
|
7
26
|
- Handle errors encountered while handling malformed draft-76 requests
|
27
|
+
- Change license from MIT to Apache 2.0
|
8
28
|
|
9
29
|
### 0.7.0 / 2017-09-11
|
10
30
|
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# websocket-driver
|
1
|
+
# websocket-driver
|
2
2
|
|
3
3
|
This module provides a complete implementation of the WebSocket protocols that
|
4
4
|
can be hooked up to any TCP library. It aims to simplify things by decoupling
|
@@ -150,7 +150,16 @@ module Connection
|
|
150
150
|
if WebSocket::Driver.websocket?(@driver.env)
|
151
151
|
@driver.start
|
152
152
|
else
|
153
|
-
# handle other HTTP requests
|
153
|
+
# handle other HTTP requests, for example
|
154
|
+
body = '<h1>hello</h1>'
|
155
|
+
response = [
|
156
|
+
'HTTP/1.1 200 OK',
|
157
|
+
'Content-Type: text/plain',
|
158
|
+
"Content-Length: #{body.bytesize}",
|
159
|
+
'',
|
160
|
+
body
|
161
|
+
]
|
162
|
+
send_data response.join("\r\n")
|
154
163
|
end
|
155
164
|
end
|
156
165
|
|
@@ -274,33 +283,33 @@ Note that most of these methods are commands: if they produce data that should
|
|
274
283
|
be sent over the socket, they will give this to you by calling
|
275
284
|
`socket.write(string)`.
|
276
285
|
|
277
|
-
#### `driver.on :open, -> (event) {
|
286
|
+
#### `driver.on :open, -> (event) {}`
|
278
287
|
|
279
288
|
Adds a callback block to execute when the socket becomes open.
|
280
289
|
|
281
|
-
#### `driver.on :message, -> (event) {
|
290
|
+
#### `driver.on :message, -> (event) {}`
|
282
291
|
|
283
292
|
Adds a callback block to execute when a message is received. `event` will have a
|
284
293
|
`data` attribute containing either a string in the case of a text message or an
|
285
294
|
array of integers in the case of a binary message.
|
286
295
|
|
287
|
-
#### `driver.on :error, -> (event) {
|
296
|
+
#### `driver.on :error, -> (event) {}`
|
288
297
|
|
289
298
|
Adds a callback to execute when a protocol error occurs due to the other peer
|
290
299
|
sending an invalid byte sequence. `event` will have a `message` attribute
|
291
300
|
describing the error.
|
292
301
|
|
293
|
-
#### `driver.on :close, -> (event) {
|
302
|
+
#### `driver.on :close, -> (event) {}`
|
294
303
|
|
295
304
|
Adds a callback block to execute when the socket becomes closed. The `event`
|
296
305
|
object has `code` and `reason` attributes.
|
297
306
|
|
298
|
-
#### `driver.on :ping, -> (event) {
|
307
|
+
#### `driver.on :ping, -> (event) {}`
|
299
308
|
|
300
309
|
Adds a callback block to execute when a ping is received. You do not need to
|
301
310
|
handle this by sending a pong frame yourself; the driver handles this for you.
|
302
311
|
|
303
|
-
#### `driver.on :pong, -> (event) {
|
312
|
+
#### `driver.on :pong, -> (event) {}`
|
304
313
|
|
305
314
|
Adds a callback block to execute when a pong is received. If this was in
|
306
315
|
response to a ping you sent, you can also handle this event via the
|
@@ -20,10 +20,10 @@ module WebSocket
|
|
20
20
|
|
21
21
|
uri = URI.parse(@socket.url)
|
22
22
|
unless VALID_SCHEMES.include?(uri.scheme)
|
23
|
-
raise URIError, "#{socket.url} is not a valid WebSocket URL"
|
23
|
+
raise URIError, "#{ socket.url } is not a valid WebSocket URL"
|
24
24
|
end
|
25
25
|
|
26
|
-
host = uri.host + (uri.port ? ":#{uri.port}" : '')
|
26
|
+
host = uri.host + (uri.port ? ":#{ uri.port }" : '')
|
27
27
|
path = (uri.path == '') ? '/' : uri.path
|
28
28
|
@pathname = path + (uri.query ? '?' + uri.query : '')
|
29
29
|
|
@@ -44,7 +44,7 @@ module WebSocket
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def version
|
47
|
-
"hybi-#{VERSION}"
|
47
|
+
"hybi-#{ VERSION }"
|
48
48
|
end
|
49
49
|
|
50
50
|
def proxy(origin, options = {})
|
@@ -73,19 +73,19 @@ module WebSocket
|
|
73
73
|
parse(@http.body)
|
74
74
|
end
|
75
75
|
|
76
|
-
private
|
76
|
+
private
|
77
77
|
|
78
78
|
def handshake_request
|
79
79
|
extensions = @extensions.generate_offer
|
80
80
|
@headers['Sec-WebSocket-Extensions'] = extensions if extensions
|
81
81
|
|
82
|
-
start = "GET #{@pathname} HTTP/1.1"
|
82
|
+
start = "GET #{ @pathname } HTTP/1.1"
|
83
83
|
headers = [start, @headers.to_s, '']
|
84
84
|
headers.join("\r\n")
|
85
85
|
end
|
86
86
|
|
87
87
|
def fail_handshake(message)
|
88
|
-
message = "Error during WebSocket handshake: #{message}"
|
88
|
+
message = "Error during WebSocket handshake: #{ message }"
|
89
89
|
@ready_state = 3
|
90
90
|
emit(:error, ProtocolError.new(message))
|
91
91
|
emit(:close, CloseEvent.new(ERRORS[:protocol_error], message))
|
@@ -96,7 +96,7 @@ module WebSocket
|
|
96
96
|
@headers = Headers.new(@http.headers)
|
97
97
|
|
98
98
|
unless @http.code == 101
|
99
|
-
return fail_handshake("Unexpected response code: #{@http.code}")
|
99
|
+
return fail_handshake("Unexpected response code: #{ @http.code }")
|
100
100
|
end
|
101
101
|
|
102
102
|
upgrade = @http['Upgrade'] || ''
|
@@ -6,9 +6,10 @@ module WebSocket
|
|
6
6
|
|
7
7
|
def initialize(socket, options = {})
|
8
8
|
super
|
9
|
-
input = @socket.env['rack.input']
|
9
|
+
input = (@socket.env['rack.input'] || StringIO.new('')).read
|
10
|
+
input = input.dup if input.frozen?
|
10
11
|
@stage = -1
|
11
|
-
@body =
|
12
|
+
@body = input.force_encoding(Encoding::BINARY)
|
12
13
|
|
13
14
|
@headers.clear
|
14
15
|
@headers['Upgrade'] = 'WebSocket'
|
@@ -25,7 +25,7 @@ module WebSocket
|
|
25
25
|
return if value.nil?
|
26
26
|
key = HTTP.normalize_header(name)
|
27
27
|
return unless @sent.add?(key) or ALLOWED_DUPLICATES.include?(key)
|
28
|
-
@lines << "#{name.strip}: #{value.to_s.strip}\r\n"
|
28
|
+
@lines << "#{ name.strip }: #{ value.to_s.strip }\r\n"
|
29
29
|
end
|
30
30
|
|
31
31
|
def inspect
|
@@ -52,7 +52,7 @@ module WebSocket
|
|
52
52
|
MIN_RESERVED_ERROR = 3000
|
53
53
|
MAX_RESERVED_ERROR = 4999
|
54
54
|
|
55
|
-
PACK_FORMATS = {2 => '
|
55
|
+
PACK_FORMATS = { 2 => 'S>', 8 => 'Q>' }
|
56
56
|
|
57
57
|
def initialize(socket, options = {})
|
58
58
|
super
|
@@ -78,7 +78,7 @@ module WebSocket
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def version
|
81
|
-
"hybi-#{VERSION}"
|
81
|
+
"hybi-#{ VERSION }"
|
82
82
|
end
|
83
83
|
|
84
84
|
def add_extension(extension)
|
@@ -160,14 +160,13 @@ module WebSocket
|
|
160
160
|
|
161
161
|
message = Message.new
|
162
162
|
frame = Frame.new
|
163
|
-
is_text = String === buffer
|
164
163
|
|
165
164
|
message.rsv1 = message.rsv2 = message.rsv3 = false
|
166
|
-
message.opcode = OPCODES[type || (
|
165
|
+
message.opcode = OPCODES[type || (String === buffer ? :text : :binary)]
|
167
166
|
|
168
|
-
payload =
|
169
|
-
payload = [code].pack(
|
170
|
-
message.data = payload
|
167
|
+
payload = Driver.encode(buffer)
|
168
|
+
payload = [code, payload].pack('S>a*') if code
|
169
|
+
message.data = payload
|
171
170
|
|
172
171
|
if MESSAGE_OPCODES.include?(message.opcode)
|
173
172
|
message = @extensions.process_outgoing_message(message)
|
@@ -194,33 +193,38 @@ module WebSocket
|
|
194
193
|
|
195
194
|
def send_frame(frame)
|
196
195
|
length = frame.length
|
197
|
-
|
196
|
+
values = []
|
197
|
+
format = 'C2'
|
198
198
|
masked = frame.masked ? MASK : 0
|
199
199
|
|
200
|
-
|
200
|
+
values[0] = (frame.final ? FIN : 0) |
|
201
201
|
(frame.rsv1 ? RSV1 : 0) |
|
202
202
|
(frame.rsv2 ? RSV2 : 0) |
|
203
203
|
(frame.rsv3 ? RSV3 : 0) |
|
204
204
|
frame.opcode
|
205
205
|
|
206
206
|
if length <= 125
|
207
|
-
|
207
|
+
values[1] = masked | length
|
208
208
|
elsif length <= 65535
|
209
|
-
|
210
|
-
|
209
|
+
values[1] = masked | 126
|
210
|
+
values[2] = length
|
211
|
+
format << 'S>'
|
211
212
|
else
|
212
|
-
|
213
|
-
|
213
|
+
values[1] = masked | 127
|
214
|
+
values[2] = length
|
215
|
+
format << 'Q>'
|
214
216
|
end
|
215
217
|
|
216
218
|
if frame.masked
|
217
|
-
|
218
|
-
|
219
|
+
values << frame.masking_key
|
220
|
+
values << Mask.mask(frame.payload, frame.masking_key)
|
221
|
+
format << 'a4a*'
|
219
222
|
else
|
220
|
-
|
223
|
+
values << frame.payload
|
224
|
+
format << 'a*'
|
221
225
|
end
|
222
226
|
|
223
|
-
@socket.write(
|
227
|
+
@socket.write(values.pack(format))
|
224
228
|
end
|
225
229
|
|
226
230
|
def handshake_response
|
@@ -228,7 +232,7 @@ module WebSocket
|
|
228
232
|
version = @socket.env['HTTP_SEC_WEBSOCKET_VERSION']
|
229
233
|
|
230
234
|
unless version == VERSION
|
231
|
-
raise ProtocolError.new("Unsupported WebSocket version: #{VERSION}")
|
235
|
+
raise ProtocolError.new("Unsupported WebSocket version: #{ VERSION }")
|
232
236
|
end
|
233
237
|
|
234
238
|
unless sec_key
|
@@ -281,17 +285,17 @@ module WebSocket
|
|
281
285
|
|
282
286
|
unless @extensions.valid_frame_rsv?(@frame)
|
283
287
|
return fail(:protocol_error,
|
284
|
-
"One or more reserved bits are on: reserved1 = #{@frame.rsv1 ? 1 : 0}" +
|
285
|
-
", reserved2 = #{@frame.rsv2 ? 1 : 0 }" +
|
286
|
-
", reserved3 = #{@frame.rsv3 ? 1 : 0 }")
|
288
|
+
"One or more reserved bits are on: reserved1 = #{ @frame.rsv1 ? 1 : 0 }" +
|
289
|
+
", reserved2 = #{ @frame.rsv2 ? 1 : 0 }" +
|
290
|
+
", reserved3 = #{ @frame.rsv3 ? 1 : 0 }")
|
287
291
|
end
|
288
292
|
|
289
293
|
unless OPCODES.values.include?(@frame.opcode)
|
290
|
-
return fail(:protocol_error, "Unrecognized frame opcode: #{@frame.opcode}")
|
294
|
+
return fail(:protocol_error, "Unrecognized frame opcode: #{ @frame.opcode }")
|
291
295
|
end
|
292
296
|
|
293
297
|
unless MESSAGE_OPCODES.include?(@frame.opcode) or @frame.final
|
294
|
-
return fail(:protocol_error, "Received fragmented control frame: opcode = #{@frame.opcode}")
|
298
|
+
return fail(:protocol_error, "Received fragmented control frame: opcode = #{ @frame.opcode }")
|
295
299
|
end
|
296
300
|
|
297
301
|
if @message and OPENING_OPCODES.include?(@frame.opcode)
|
@@ -321,7 +325,7 @@ module WebSocket
|
|
321
325
|
@stage = @frame.masked ? 3 : 4
|
322
326
|
|
323
327
|
unless MESSAGE_OPCODES.include?(@frame.opcode) or @frame.length <= 125
|
324
|
-
return fail(:protocol_error, "Received control frame having too long payload: #{@frame.length}")
|
328
|
+
return fail(:protocol_error, "Received control frame having too long payload: #{ @frame.length }")
|
325
329
|
end
|
326
330
|
|
327
331
|
return unless check_frame_length
|
@@ -343,7 +347,6 @@ module WebSocket
|
|
343
347
|
opcode = frame.opcode
|
344
348
|
payload = frame.payload = Mask.mask(buffer, @frame.masking_key)
|
345
349
|
bytesize = payload.bytesize
|
346
|
-
bytes = payload.bytes.to_a
|
347
350
|
|
348
351
|
@frame = nil
|
349
352
|
|
@@ -357,8 +360,8 @@ module WebSocket
|
|
357
360
|
@message << frame
|
358
361
|
|
359
362
|
when OPCODES[:close] then
|
360
|
-
code
|
361
|
-
reason =
|
363
|
+
code, reason = payload.unpack('S>a*') if bytesize >= 2
|
364
|
+
reason = Driver.encode(reason || '', Encoding::UTF_8)
|
362
365
|
|
363
366
|
unless (bytesize == 0) or
|
364
367
|
(code && code >= MIN_RESERVED_ERROR && code <= MAX_RESERVED_ERROR) or
|
@@ -366,7 +369,7 @@ module WebSocket
|
|
366
369
|
code = ERRORS[:protocol_error]
|
367
370
|
end
|
368
371
|
|
369
|
-
if bytesize > 125 or
|
372
|
+
if bytesize > 125 or !reason.valid_encoding?
|
370
373
|
code = ERRORS[:protocol_error]
|
371
374
|
end
|
372
375
|
|
@@ -377,7 +380,7 @@ module WebSocket
|
|
377
380
|
emit(:ping, PingEvent.new(payload))
|
378
381
|
|
379
382
|
when OPCODES[:pong] then
|
380
|
-
message = Driver.encode(payload,
|
383
|
+
message = Driver.encode(payload, Encoding::UTF_8)
|
381
384
|
callback = @ping_callbacks[message]
|
382
385
|
@ping_callbacks.delete(message)
|
383
386
|
callback.call if callback
|
@@ -395,7 +398,8 @@ module WebSocket
|
|
395
398
|
|
396
399
|
case message.opcode
|
397
400
|
when OPCODES[:text] then
|
398
|
-
payload = Driver.encode(payload,
|
401
|
+
payload = Driver.encode(payload, Encoding::UTF_8)
|
402
|
+
payload = nil unless payload.valid_encoding?
|
399
403
|
when OPCODES[:binary]
|
400
404
|
payload = payload.bytes.to_a
|
401
405
|
end
|
@@ -4,7 +4,7 @@ module WebSocket
|
|
4
4
|
class Proxy
|
5
5
|
include EventEmitter
|
6
6
|
|
7
|
-
PORTS = {'ws' => 80, 'wss' => 443}
|
7
|
+
PORTS = { 'ws' => 80, 'wss' => 443 }
|
8
8
|
|
9
9
|
attr_reader :status, :headers
|
10
10
|
|
@@ -20,7 +20,7 @@ module WebSocket
|
|
20
20
|
@state = 0
|
21
21
|
|
22
22
|
@headers = Headers.new
|
23
|
-
@headers['Host'] = @origin.host + (@origin.port ? ":#{@origin.port}" : '')
|
23
|
+
@headers['Host'] = @origin.host + (@origin.port ? ":#{ @origin.port }" : '')
|
24
24
|
@headers['Connection'] = 'keep-alive'
|
25
25
|
@headers['Proxy-Connection'] = 'keep-alive'
|
26
26
|
|
@@ -41,7 +41,7 @@ module WebSocket
|
|
41
41
|
@state = 1
|
42
42
|
|
43
43
|
port = @origin.port || PORTS[@origin.scheme]
|
44
|
-
start = "CONNECT #{@origin.host}:#{port} HTTP/1.1"
|
44
|
+
start = "CONNECT #{ @origin.host }:#{ port } HTTP/1.1"
|
45
45
|
headers = [start, @headers.to_s, '']
|
46
46
|
|
47
47
|
@socket.write(headers.join("\r\n"))
|
@@ -58,7 +58,7 @@ module WebSocket
|
|
58
58
|
if @status == 200
|
59
59
|
emit(:connect, ConnectEvent.new)
|
60
60
|
else
|
61
|
-
message = "Can't establish a connection to the server at #{@socket.url}"
|
61
|
+
message = "Can't establish a connection to the server at #{ @socket.url }"
|
62
62
|
emit(:error, ProtocolError.new(message))
|
63
63
|
end
|
64
64
|
end
|
@@ -2,7 +2,7 @@ module WebSocket
|
|
2
2
|
class Driver
|
3
3
|
|
4
4
|
class Server < Driver
|
5
|
-
EVENTS = %w[open message error close]
|
5
|
+
EVENTS = %w[open message error close ping pong]
|
6
6
|
|
7
7
|
def initialize(socket, options = {})
|
8
8
|
super
|
@@ -17,9 +17,9 @@ module WebSocket
|
|
17
17
|
def url
|
18
18
|
return nil unless e = env
|
19
19
|
|
20
|
-
url = "ws://#{e['HTTP_HOST']}"
|
20
|
+
url = "ws://#{ e['HTTP_HOST'] }"
|
21
21
|
url << e['PATH_INFO']
|
22
|
-
url << "?#{e['QUERY_STRING']}" unless e['QUERY_STRING'] == ''
|
22
|
+
url << "?#{ e['QUERY_STRING'] }" unless e['QUERY_STRING'] == ''
|
23
23
|
url
|
24
24
|
end
|
25
25
|
|
@@ -6,13 +6,13 @@ module WebSocket
|
|
6
6
|
MINIMUM_AUTOMATIC_PRUNE_OFFSET = 128
|
7
7
|
|
8
8
|
def initialize
|
9
|
-
@buffer = String.new('').force_encoding(BINARY)
|
9
|
+
@buffer = String.new('').force_encoding(Encoding::BINARY)
|
10
10
|
@offset = 0
|
11
11
|
end
|
12
12
|
|
13
13
|
def put(chunk)
|
14
14
|
return unless chunk and chunk.bytesize > 0
|
15
|
-
@buffer << chunk.force_encoding(BINARY)
|
15
|
+
@buffer << chunk.force_encoding(Encoding::BINARY)
|
16
16
|
end
|
17
17
|
|
18
18
|
# Read bytes from the data:
|
@@ -42,7 +42,7 @@ module WebSocket
|
|
42
42
|
buffer_size = @buffer.bytesize
|
43
43
|
|
44
44
|
if @offset > buffer_size
|
45
|
-
@buffer = String.new('').force_encoding(BINARY)
|
45
|
+
@buffer = String.new('').force_encoding(Encoding::BINARY)
|
46
46
|
else
|
47
47
|
@buffer = @buffer.byteslice(@offset, buffer_size - @offset)
|
48
48
|
end
|
data/lib/websocket/driver.rb
CHANGED
@@ -44,9 +44,6 @@ module WebSocket
|
|
44
44
|
MAX_LENGTH = 0x3ffffff
|
45
45
|
STATES = [:connecting, :open, :closing, :closed]
|
46
46
|
|
47
|
-
BINARY = 'ASCII-8BIT'
|
48
|
-
UNICODE = 'UTF-8'
|
49
|
-
|
50
47
|
ConnectEvent = Struct.new(nil)
|
51
48
|
OpenEvent = Struct.new(nil)
|
52
49
|
MessageEvent = Struct.new(:data)
|
@@ -118,7 +115,7 @@ module WebSocket
|
|
118
115
|
end
|
119
116
|
|
120
117
|
def text(message)
|
121
|
-
message =
|
118
|
+
message = Driver.encode(message, Encoding::UTF_8)
|
122
119
|
frame(message, :text)
|
123
120
|
end
|
124
121
|
|
@@ -197,25 +194,25 @@ module WebSocket
|
|
197
194
|
end
|
198
195
|
end
|
199
196
|
|
200
|
-
def self.encode(
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
encoding ||= BINARY
|
205
|
-
when String then
|
206
|
-
encoding ||= UNICODE
|
207
|
-
end
|
208
|
-
unless string.encoding.name == encoding
|
209
|
-
string = string.dup if string.frozen?
|
210
|
-
string.force_encoding(encoding)
|
197
|
+
def self.encode(data, encoding = nil)
|
198
|
+
if Array === data
|
199
|
+
encoding ||= Encoding::BINARY
|
200
|
+
return data.pack('C*').force_encoding(encoding)
|
211
201
|
end
|
212
|
-
|
202
|
+
|
203
|
+
encoding ||= Encoding::UTF_8
|
204
|
+
|
205
|
+
return data if data.encoding == encoding
|
206
|
+
return data.encode(encoding) unless data.encoding == Encoding::BINARY
|
207
|
+
|
208
|
+
data = data.dup if data.frozen?
|
209
|
+
data.force_encoding(encoding)
|
213
210
|
end
|
214
211
|
|
215
212
|
def self.validate_options(options, valid_keys)
|
216
213
|
options.keys.each do |key|
|
217
214
|
unless valid_keys.include?(key)
|
218
|
-
raise ConfigurationError, "Unrecognized option: #{key.inspect}"
|
215
|
+
raise ConfigurationError, "Unrecognized option: #{ key.inspect }"
|
219
216
|
end
|
220
217
|
end
|
221
218
|
end
|
@@ -30,11 +30,11 @@ module WebSocket
|
|
30
30
|
super
|
31
31
|
@headers.each do |name, value|
|
32
32
|
rack_name = name.upcase.gsub(/-/, '_')
|
33
|
-
rack_name = "HTTP_#{rack_name}" unless RESERVED_HEADERS.include?(name)
|
33
|
+
rack_name = "HTTP_#{ rack_name }" unless RESERVED_HEADERS.include?(name)
|
34
34
|
@env[rack_name] = value
|
35
35
|
end
|
36
36
|
if host = @env['HTTP_HOST']
|
37
|
-
uri = URI.parse("http://#{host}")
|
37
|
+
uri = URI.parse("http://#{ host }")
|
38
38
|
@env['SERVER_NAME'] = uri.host
|
39
39
|
@env['SERVER_PORT'] = uri.port.to_s
|
40
40
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: websocket-driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Coglan
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: websocket-extensions
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
description:
|
83
|
+
description:
|
84
84
|
email: jcoglan@gmail.com
|
85
85
|
executables: []
|
86
86
|
extensions:
|
@@ -116,7 +116,7 @@ homepage: https://github.com/faye/websocket-driver-ruby
|
|
116
116
|
licenses:
|
117
117
|
- Apache-2.0
|
118
118
|
metadata: {}
|
119
|
-
post_install_message:
|
119
|
+
post_install_message:
|
120
120
|
rdoc_options:
|
121
121
|
- "--main"
|
122
122
|
- README.md
|
@@ -135,8 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
135
|
- !ruby/object:Gem::Version
|
136
136
|
version: '0'
|
137
137
|
requirements: []
|
138
|
-
rubygems_version: 3.
|
139
|
-
signing_key:
|
138
|
+
rubygems_version: 3.1.6
|
139
|
+
signing_key:
|
140
140
|
specification_version: 4
|
141
141
|
summary: WebSocket protocol handler with pluggable I/O
|
142
142
|
test_files: []
|