websocket-driver 0.7.1 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
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: []