websocket-driver 0.6.0 → 0.6.1

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
  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