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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b7a3b9878d6efb8ad25a608fd06548f4be94454406894588e15f856f4451746
4
- data.tar.gz: a5f98cbda60d85887857b75a967ad8d33a41e549781739374865e05a76304e7b
3
+ metadata.gz: 046c514660d2c0dab2cf42bce8314a17e713909377a5da470beaeadf666ff28e
4
+ data.tar.gz: 9830c412394044d102dd6f313346721076ef0f97284d6182aeb06862e1f427b2
5
5
  SHA512:
6
- metadata.gz: fca692d01fb40ad07be65a0050923e03084841e995d53b3580bd84265b74c1a3411b8c4f16f0e319a2a9acb7811e48ad13bc43bc81023d308fb7ea385e150d0d
7
- data.tar.gz: 48e438dea20c9dd8a90224ec32d3d16da1b04f145070e15d9bac741ad39717f04a246631df0475c266f28e495001f41d14f2534c118243075f8abc0921868524
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
@@ -1,4 +1,4 @@
1
- Copyright 2010-2019 James Coglan
1
+ Copyright 2010-2021 James Coglan
2
2
 
3
3
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4
4
  this file except in compliance with the License. You may obtain a copy of the
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # websocket-driver [![Build Status](https://travis-ci.org/faye/websocket-driver-ruby.svg)](https://travis-ci.org/faye/websocket-driver-ruby)
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'] || ''
@@ -56,7 +56,7 @@ module WebSocket
56
56
  when 2 then
57
57
  if octet == 0xFF
58
58
  @stage = 0
59
- emit(:message, MessageEvent.new(Driver.encode(@buffer, UNICODE)))
59
+ emit(:message, MessageEvent.new(Driver.encode(@buffer, Encoding::UTF_8)))
60
60
  else
61
61
  if @length
62
62
  @skipped += 1
@@ -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 = (input ? input.read : String.new('')).force_encoding(BINARY)
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
@@ -14,7 +14,7 @@ module WebSocket
14
14
  @rsv2 = false
15
15
  @rsv3 = false
16
16
  @opcode = nil
17
- @data = String.new('').force_encoding(BINARY)
17
+ @data = String.new('').force_encoding(Encoding::BINARY)
18
18
  end
19
19
 
20
20
  def <<(frame)
@@ -52,7 +52,7 @@ module WebSocket
52
52
  MIN_RESERVED_ERROR = 3000
53
53
  MAX_RESERVED_ERROR = 4999
54
54
 
55
- PACK_FORMATS = {2 => 'n', 8 => 'Q>'}
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 || (is_text ? :text : :binary)]
165
+ message.opcode = OPCODES[type || (String === buffer ? :text : :binary)]
167
166
 
168
- payload = is_text ? buffer.bytes.to_a : buffer
169
- payload = [code].pack(PACK_FORMATS[2]).bytes.to_a + payload if code
170
- message.data = payload.pack('C*')
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
- buffer = []
196
+ values = []
197
+ format = 'C2'
198
198
  masked = frame.masked ? MASK : 0
199
199
 
200
- buffer[0] = (frame.final ? FIN : 0) |
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
- buffer[1] = masked | length
207
+ values[1] = masked | length
208
208
  elsif length <= 65535
209
- buffer[1] = masked | 126
210
- buffer[2..3] = [length].pack(PACK_FORMATS[2]).bytes.to_a
209
+ values[1] = masked | 126
210
+ values[2] = length
211
+ format << 'S>'
211
212
  else
212
- buffer[1] = masked | 127
213
- buffer[2..9] = [length].pack(PACK_FORMATS[8]).bytes.to_a
213
+ values[1] = masked | 127
214
+ values[2] = length
215
+ format << 'Q>'
214
216
  end
215
217
 
216
218
  if frame.masked
217
- buffer.concat(frame.masking_key.bytes.to_a)
218
- buffer.concat(Mask.mask(frame.payload, frame.masking_key).bytes.to_a)
219
+ values << frame.masking_key
220
+ values << Mask.mask(frame.payload, frame.masking_key)
221
+ format << 'a4a*'
219
222
  else
220
- buffer.concat(frame.payload.bytes.to_a)
223
+ values << frame.payload
224
+ format << 'a*'
221
225
  end
222
226
 
223
- @socket.write(buffer.pack('C*'))
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 = (bytesize >= 2) ? payload.unpack(PACK_FORMATS[2]).first : nil
361
- reason = (bytesize > 2) ? Driver.encode(bytes[2..-1] || [], UNICODE) : nil
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 (bytesize > 2 and reason.nil?)
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, UNICODE)
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, UNICODE)
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
@@ -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 = message.encode(UNICODE) unless message.encoding.name == UNICODE
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(string, encoding = nil)
201
- case string
202
- when Array then
203
- string = string.pack('C*')
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
- string.valid_encoding? ? string : nil
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
@@ -4,7 +4,7 @@ module WebSocket
4
4
  class Response
5
5
  include Headers
6
6
 
7
- STATUS_LINE = /^(HTTP\/[0-9]+\.[0-9]+) ([0-9]{3}) ([\x20-\x7e]+)$/
7
+ STATUS_LINE = /^(HTTP\/[0-9]+\.[0-9]+) ([0-9]{3}) ([\x20-\x7e]*)$/
8
8
 
9
9
  attr_reader :code
10
10
 
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.1
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: 2019-06-10 00:00:00.000000000 Z
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.0.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: []