websocket-driver 0.6.0 → 0.6.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
  SHA1:
3
- metadata.gz: 9bbde50af6076801dfb22819c21ac9faceed294e
4
- data.tar.gz: 191ae0db699002539e938eeb04a06cc4f8cf2dd7
3
+ metadata.gz: 4a069093c87a31c96d30a911bf3855fec2efc384
4
+ data.tar.gz: ea4afb6bcd928bdd6075e68da402875d9470b2f9
5
5
  SHA512:
6
- metadata.gz: 4734fc2fbfb2cf6365c33cc8f545908ea5e643b7c85db5beeade7aee3e96222ec3a3d7cb84ae6972ba01edb2e9ebfafdbe2e41820473ba2a448868ebbf506f00
7
- data.tar.gz: 9c60a203a6e9681f9496182e07792563b6698e1ea3d19c01201c94c996d1a839fa38425677dfd6ad289bbdde246aaf2d8c5cd72d9ac5ceede37dccd9c845b019
6
+ metadata.gz: 01272dedc949458909b2b6dc3acab09a12812ac5de1b0e1d44796d8406678de2445cfe11cdc47e52d447022c0ea5f86acae8aa592ed5c2575073f2c065411e1a
7
+ data.tar.gz: 9bd6c3e39ede403a35a3388b1593a8866e3b3dc851e15f86f1799f9a1abe8887fd4888733c35573faf13dd603487110928fbd91fd0f2de61aac8c43a5dbf8131
@@ -1,3 +1,10 @@
1
+ ### 0.6.1 / 2015-07-13
2
+
3
+ * Fix how events are stored in `EventEmitter` to fix a backward-compatibility
4
+ violation introduced in the last release
5
+ * Use the `Array#pack` and `String#unpack` methods for reading/writing numbers
6
+ to buffers rather than including duplicate logic for this
7
+
1
8
  ### 0.6.0 / 2015-07-08
2
9
 
3
10
  * Use `SecureRandom` to generate the `Sec-WebSocket-Key` header
data/README.md CHANGED
@@ -274,23 +274,23 @@ Note that most of these methods are commands: if they produce data that should
274
274
  be sent over the socket, they will give this to you by calling
275
275
  `socket.write(string)`.
276
276
 
277
- #### `driver.on 'open', -> (event) { }`
277
+ #### `driver.on :open, -> (event) { }`
278
278
 
279
279
  Adds a callback block to execute when the socket becomes open.
280
280
 
281
- #### `driver.on 'message', -> (event) { }`
281
+ #### `driver.on :message, -> (event) { }`
282
282
 
283
283
  Adds a callback block to execute when a message is received. `event` will have a
284
284
  `data` attribute containing either a string in the case of a text message or an
285
285
  array of integers in the case of a binary message.
286
286
 
287
- #### `driver.on 'error', -> (event) { }`
287
+ #### `driver.on :error, -> (event) { }`
288
288
 
289
289
  Adds a callback to execute when a protocol error occurs due to the other peer
290
290
  sending an invalid byte sequence. `event` will have a `message` attribute
291
291
  describing the error.
292
292
 
293
- #### `driver.on 'close', -> (event) { }`
293
+ #### `driver.on :close, -> (event) { }`
294
294
 
295
295
  Adds a callback block to execute when the socket becomes closed. The `event`
296
296
  object has `code` and `reason` attributes.
@@ -21,10 +21,10 @@ module WebSocket
21
21
  path = (uri.path == '') ? '/' : uri.path
22
22
  @pathname = path + (uri.query ? '?' + uri.query : '')
23
23
 
24
- @headers['Host'] = host
25
- @headers['Upgrade'] = 'websocket'
26
- @headers['Connection'] = 'Upgrade'
27
- @headers['Sec-WebSocket-Key'] = @key
24
+ @headers['Host'] = host
25
+ @headers['Upgrade'] = 'websocket'
26
+ @headers['Connection'] = 'Upgrade'
27
+ @headers['Sec-WebSocket-Key'] = @key
28
28
  @headers['Sec-WebSocket-Version'] = '13'
29
29
 
30
30
  if @protocols.size > 0
@@ -52,11 +52,11 @@ module WebSocket
52
52
  true
53
53
  end
54
54
 
55
- def parse(buffer)
55
+ def parse(chunk)
56
56
  return if @ready_state == 3
57
57
  return super if @ready_state > 0
58
58
 
59
- @http.parse(buffer)
59
+ @http.parse(chunk)
60
60
  return fail_handshake('Invalid HTTP response') if @http.error?
61
61
  return unless @http.complete?
62
62
 
@@ -6,9 +6,9 @@ module WebSocket
6
6
  super
7
7
  @stage = 0
8
8
 
9
- @headers['Upgrade'] = 'WebSocket'
10
- @headers['Connection'] = 'Upgrade'
11
- @headers['WebSocket-Origin'] = @socket.env['HTTP_ORIGIN']
9
+ @headers['Upgrade'] = 'WebSocket'
10
+ @headers['Connection'] = 'Upgrade'
11
+ @headers['WebSocket-Origin'] = @socket.env['HTTP_ORIGIN']
12
12
  @headers['WebSocket-Location'] = @socket.url
13
13
  end
14
14
 
@@ -23,37 +23,36 @@ module WebSocket
23
23
  true
24
24
  end
25
25
 
26
- def parse(buffer)
26
+ def parse(chunk)
27
27
  return if @ready_state > 1
28
28
 
29
- @reader.put(buffer)
29
+ @reader.put(chunk)
30
30
 
31
- @reader.each_byte do |data|
31
+ @reader.each_byte do |octet|
32
32
  case @stage
33
33
  when -1 then
34
- @body << data
34
+ @body << octet
35
35
  send_handshake_body
36
36
 
37
37
  when 0 then
38
- parse_leading_byte(data)
38
+ parse_leading_byte(octet)
39
39
 
40
40
  when 1 then
41
- value = (data & 0x7F)
42
- @length = value + 128 * @length
41
+ @length = (octet & 0x7F) + 128 * @length
43
42
 
44
43
  if @closing and @length.zero?
45
44
  return close
46
- elsif (0x80 & data) != 0x80
45
+ elsif (octet & 0x80) != 0x80
47
46
  if @length.zero?
48
47
  @stage = 0
49
48
  else
50
49
  @skipped = 0
51
- @stage = 2
50
+ @stage = 2
52
51
  end
53
52
  end
54
53
 
55
54
  when 2 then
56
- if data == 0xFF
55
+ if octet == 0xFF
57
56
  @stage = 0
58
57
  emit(:message, MessageEvent.new(Driver.encode(@buffer, :utf8)))
59
58
  else
@@ -61,7 +60,7 @@ module WebSocket
61
60
  @skipped += 1
62
61
  @stage = 0 if @skipped == @length
63
62
  else
64
- @buffer << data
63
+ @buffer << octet
65
64
  return close if @buffer.size > @max_length
66
65
  end
67
66
  end
@@ -69,10 +68,10 @@ module WebSocket
69
68
  end
70
69
  end
71
70
 
72
- def frame(data, type = nil, error_type = nil)
73
- return queue([data, type, error_type]) if @ready_state == 0
74
- frame = ["\x00", data, "\xFF"].map { |s| Driver.encode(s, :binary) } * ''
75
- @socket.write(Driver.encode(frame, :binary))
71
+ def frame(buffer, type = nil, error_type = nil)
72
+ return queue([buffer, type, error_type]) if @ready_state == 0
73
+ frame = [0x00, buffer, 0xFF].pack('CA*C')
74
+ @socket.write(frame)
76
75
  true
77
76
  end
78
77
 
@@ -84,8 +83,8 @@ module WebSocket
84
83
  headers.join("\r\n")
85
84
  end
86
85
 
87
- def parse_leading_byte(data)
88
- if (0x80 & data) == 0x80
86
+ def parse_leading_byte(octet)
87
+ if (octet & 0x80) == 0x80
89
88
  @length = 0
90
89
  @stage = 1
91
90
  else
@@ -29,7 +29,7 @@ module WebSocket
29
29
 
30
30
  def close(reason = nil, code = nil)
31
31
  return false if @ready_state == 3
32
- @socket.write(Driver.encode("\xFF\x00", :binary))
32
+ @socket.write([0xFF, 0x00].pack('C*'))
33
33
  @ready_state = 3
34
34
  emit(:close, CloseEvent.new(nil, nil))
35
35
  true
@@ -53,9 +53,7 @@ module WebSocket
53
53
  key2 = env['HTTP_SEC_WEBSOCKET_KEY2']
54
54
  value2 = number_from_key(key2) / spaces_in_key(key2)
55
55
 
56
- Digest::MD5.digest(big_endian(value1) +
57
- big_endian(value2) +
58
- head)
56
+ Digest::MD5.digest([value1, value2, head].pack('N2A*'))
59
57
  end
60
58
 
61
59
  def send_handshake_body
@@ -66,11 +64,11 @@ module WebSocket
66
64
  parse(@body[BODY_SIZE..-1]) if @body.bytesize > BODY_SIZE
67
65
  end
68
66
 
69
- def parse_leading_byte(data)
70
- return super unless data == 0xFF
67
+ def parse_leading_byte(octet)
68
+ return super unless octet == 0xFF
71
69
  @closing = true
72
- @length = 0
73
- @stage = 1
70
+ @length = 0
71
+ @stage = 1
74
72
  end
75
73
 
76
74
  def number_from_key(key)
@@ -80,14 +78,6 @@ module WebSocket
80
78
  def spaces_in_key(key)
81
79
  key.scan(/ /).size
82
80
  end
83
-
84
- def big_endian(number)
85
- string = Driver.encode('', :binary)
86
- [24, 16, 8, 0].each do |offset|
87
- string << (number >> offset & 0xFF).chr
88
- end
89
- string
90
- end
91
81
  end
92
82
 
93
83
  end
@@ -13,7 +13,11 @@ module WebSocket
13
13
  end
14
14
 
15
15
  def on(event, callable = nil, &block)
16
- add_listener(event, callable, &block)
16
+ if callable
17
+ add_listener(event, callable)
18
+ else
19
+ add_listener(event, &block)
20
+ end
17
21
  end
18
22
 
19
23
  def remove_listener(event, callable = nil, &block)
@@ -5,7 +5,7 @@ module WebSocket
5
5
  ALLOWED_DUPLICATES = %w[set-cookie set-cookie2 warning www-authenticate]
6
6
 
7
7
  def initialize(received = {})
8
- @raw = received
8
+ @raw = received
9
9
  clear
10
10
 
11
11
  @received = {}
@@ -50,6 +50,8 @@ module WebSocket
50
50
  MIN_RESERVED_ERROR = 3000
51
51
  MAX_RESERVED_ERROR = 4999
52
52
 
53
+ PACK_FORMATS = {2 => 'n', 8 => 'Q>'}
54
+
53
55
  def initialize(socket, options = {})
54
56
  super
55
57
 
@@ -66,8 +68,8 @@ module WebSocket
66
68
  sec_key = @socket.env['HTTP_SEC_WEBSOCKET_KEY']
67
69
  protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL']
68
70
 
69
- @headers['Upgrade'] = 'websocket'
70
- @headers['Connection'] = 'Upgrade'
71
+ @headers['Upgrade'] = 'websocket'
72
+ @headers['Connection'] = 'Upgrade'
71
73
  @headers['Sec-WebSocket-Accept'] = Hybi.generate_accept(sec_key)
72
74
 
73
75
  if protos = @socket.env['HTTP_SEC_WEBSOCKET_PROTOCOL']
@@ -86,8 +88,8 @@ module WebSocket
86
88
  true
87
89
  end
88
90
 
89
- def parse(data)
90
- @reader.put(data)
91
+ def parse(chunk)
92
+ @reader.put(chunk)
91
93
  buffer = true
92
94
  while buffer
93
95
  case @stage
@@ -158,21 +160,19 @@ module WebSocket
158
160
  end
159
161
  end
160
162
 
161
- def frame(data, type = nil, code = nil)
162
- return queue([data, type, code]) if @ready_state <= 0
163
+ def frame(buffer, type = nil, code = nil)
164
+ return queue([buffer, type, code]) if @ready_state <= 0
163
165
  return false unless @ready_state == 1
164
166
 
165
167
  message = Message.new
166
168
  frame = Frame.new
167
- is_text = String === data
169
+ is_text = String === buffer
168
170
 
169
171
  message.rsv1 = message.rsv2 = message.rsv3 = false
170
172
  message.opcode = OPCODES[type || (is_text ? :text : :binary)]
171
173
 
172
- payload = is_text ? data.bytes.to_a : data
173
- if code
174
- payload = [(code >> 8) & BYTE, code & BYTE, *payload]
175
- end
174
+ payload = is_text ? buffer.bytes.to_a : buffer
175
+ payload = [code].pack(PACK_FORMATS[2]).bytes.to_a + payload if code
176
176
  message.data = payload.pack('C*')
177
177
 
178
178
  if MESSAGE_OPCODES.include?(message.opcode)
@@ -215,18 +215,10 @@ module WebSocket
215
215
  buffer[1] = masked | length
216
216
  elsif length <= 65535
217
217
  buffer[1] = masked | 126
218
- buffer[2] = (length >> 8) & BYTE
219
- buffer[3] = length & BYTE
218
+ buffer[2..3] = [length].pack(PACK_FORMATS[2]).bytes.to_a
220
219
  else
221
220
  buffer[1] = masked | 127
222
- buffer[2] = (length >> 56) & BYTE
223
- buffer[3] = (length >> 48) & BYTE
224
- buffer[4] = (length >> 40) & BYTE
225
- buffer[5] = (length >> 32) & BYTE
226
- buffer[6] = (length >> 24) & BYTE
227
- buffer[7] = (length >> 16) & BYTE
228
- buffer[8] = (length >> 8) & BYTE
229
- buffer[9] = length & BYTE
221
+ buffer[2..9] = [length].pack(PACK_FORMATS[8]).bytes.to_a
230
222
  end
231
223
 
232
224
  if frame.masked
@@ -271,16 +263,16 @@ module WebSocket
271
263
  shutdown(ERRORS[type], message, true)
272
264
  end
273
265
 
274
- def parse_opcode(data)
275
- rsvs = [RSV1, RSV2, RSV3].map { |rsv| (data & rsv) == rsv }
266
+ def parse_opcode(octet)
267
+ rsvs = [RSV1, RSV2, RSV3].map { |rsv| (octet & rsv) == rsv }
276
268
 
277
269
  @frame = Frame.new
278
270
 
279
- @frame.final = (data & FIN) == FIN
271
+ @frame.final = (octet & FIN) == FIN
280
272
  @frame.rsv1 = rsvs[0]
281
273
  @frame.rsv2 = rsvs[1]
282
274
  @frame.rsv3 = rsvs[2]
283
- @frame.opcode = (data & OPCODE)
275
+ @frame.opcode = (octet & OPCODE)
284
276
 
285
277
  @stage = 1
286
278
 
@@ -304,9 +296,9 @@ module WebSocket
304
296
  end
305
297
  end
306
298
 
307
- def parse_length(data)
308
- @frame.masked = (data & MASK) == MASK
309
- @frame.length = (data & LENGTH)
299
+ def parse_length(octet)
300
+ @frame.masked = (octet & MASK) == MASK
301
+ @frame.length = (octet & LENGTH)
310
302
 
311
303
  if @frame.length >= 0 and @frame.length <= 125
312
304
  @stage = @frame.masked ? 3 : 4
@@ -322,7 +314,7 @@ module WebSocket
322
314
  end
323
315
 
324
316
  def parse_extended_length(buffer)
325
- @frame.length = integer(buffer)
317
+ @frame.length = buffer.unpack(PACK_FORMATS[buffer.bytesize]).first
326
318
  @stage = @frame.masked ? 3 : 4
327
319
 
328
320
  unless MESSAGE_OPCODES.include?(@frame.opcode) or @frame.length <= 125
@@ -411,14 +403,6 @@ module WebSocket
411
403
  rescue ::WebSocket::Extensions::ExtensionError => error
412
404
  fail(:extension_error, error.message)
413
405
  end
414
-
415
- def integer(buffer)
416
- number = 0
417
- buffer.each_byte.with_index do |data, i|
418
- number += data << (8 * (buffer.bytesize - 1 - i))
419
- end
420
- number
421
- end
422
406
  end
423
407
 
424
408
  end
@@ -48,11 +48,11 @@ module WebSocket
48
48
  true
49
49
  end
50
50
 
51
- def parse(buffer)
52
- @http.parse(buffer)
51
+ def parse(chunk)
52
+ @http.parse(chunk)
53
53
  return unless @http.complete?
54
54
 
55
- @status = @http.code
55
+ @status = @http.code
56
56
  @headers = Headers.new(@http.headers)
57
57
 
58
58
  if @status == 200
@@ -39,10 +39,10 @@ module WebSocket
39
39
  end
40
40
  end
41
41
 
42
- def parse(buffer)
43
- return @delegate.parse(buffer) if @delegate
42
+ def parse(chunk)
43
+ return @delegate.parse(chunk) if @delegate
44
44
 
45
- @http.parse(buffer)
45
+ @http.parse(chunk)
46
46
  return fail_request('Invalid HTTP request') if @http.error?
47
47
  return unless @http.complete?
48
48
 
@@ -56,8 +56,8 @@ module WebSocket
56
56
  emit(:connect, ConnectEvent.new)
57
57
  end
58
58
 
59
- def write(data)
60
- @socket.write(Driver.encode(data, :binary))
59
+ def write(buffer)
60
+ @socket.write(Driver.encode(buffer, :binary))
61
61
  end
62
62
 
63
63
  private
@@ -10,9 +10,9 @@ module WebSocket
10
10
  @offset = 0
11
11
  end
12
12
 
13
- def put(buffer)
14
- return unless buffer and buffer.bytesize > 0
15
- @buffer << Driver.encode(buffer, :binary)
13
+ def put(chunk)
14
+ return unless chunk and chunk.bytesize > 0
15
+ @buffer << Driver.encode(chunk, :binary)
16
16
  end
17
17
 
18
18
  # Read bytes from the data:
@@ -30,9 +30,9 @@ module WebSocket
30
30
  def each_byte
31
31
  prune
32
32
 
33
- @buffer.each_byte do |value|
33
+ @buffer.each_byte do |octet|
34
34
  @offset += 1
35
- yield value
35
+ yield octet
36
36
  end
37
37
  end
38
38
 
@@ -51,9 +51,9 @@ module WebSocket
51
51
  @stage == -1
52
52
  end
53
53
 
54
- def parse(data)
55
- data.each_byte do |byte|
56
- if byte == LF and @stage < 2
54
+ def parse(chunk)
55
+ chunk.each_byte do |octet|
56
+ if octet == LF and @stage < 2
57
57
  @buffer.pop if @buffer.last == CR
58
58
  if @buffer.empty?
59
59
  complete if @stage == 1
@@ -71,7 +71,7 @@ module WebSocket
71
71
  end
72
72
  @buffer = []
73
73
  else
74
- @buffer << byte if @stage >= 0
74
+ @buffer << octet if @stage >= 0
75
75
  error if @stage < 2 and @buffer.size > MAX_LINE_LENGTH
76
76
  end
77
77
  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.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Coglan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-08 00:00:00.000000000 Z
11
+ date: 2015-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: websocket-extensions