faye-websocket 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of faye-websocket might be problematic. Click here for more details.

@@ -1,21 +1,21 @@
1
1
  module Faye
2
2
  class WebSocket
3
-
3
+
4
4
  module Adapter
5
5
  def websocket?
6
6
  e = defined?(@env) ? @env : env
7
7
  WebSocket.websocket?(e)
8
8
  end
9
-
9
+
10
10
  def eventsource?
11
11
  e = defined?(@env) ? @env : env
12
12
  EventSource.eventsource?(e)
13
13
  end
14
-
15
- def async_connection?
14
+
15
+ def socket_connection?
16
16
  websocket? or eventsource?
17
17
  end
18
18
  end
19
-
19
+
20
20
  end
21
21
  end
@@ -1,6 +1,6 @@
1
1
  module Faye
2
2
  class WebSocket
3
-
3
+
4
4
  module API
5
5
  module ReadyStates
6
6
  CONNECTING = 0
@@ -8,35 +8,35 @@ module Faye
8
8
  CLOSING = 2
9
9
  CLOSED = 3
10
10
  end
11
-
11
+
12
12
  class IllegalStateError < StandardError
13
13
  end
14
-
14
+
15
15
  require File.expand_path('../api/event_target', __FILE__)
16
16
  require File.expand_path('../api/event', __FILE__)
17
17
  include EventTarget
18
18
  include ReadyStates
19
-
19
+
20
20
  attr_reader :url, :ready_state, :buffered_amount
21
-
21
+
22
22
  private
23
-
23
+
24
24
  def open
25
25
  return if @parser and not @parser.open?
26
26
  @ready_state = OPEN
27
-
27
+
28
28
  buffer = @send_buffer || []
29
29
  while message = buffer.shift
30
30
  send(*message)
31
31
  end
32
-
32
+
33
33
  event = Event.new('open')
34
34
  event.init_event('open', false, false)
35
35
  dispatch_event(event)
36
36
  end
37
-
37
+
38
38
  public
39
-
39
+
40
40
  def receive(data)
41
41
  return false unless @ready_state == OPEN
42
42
  event = Event.new('message')
@@ -44,7 +44,7 @@ module Faye
44
44
  event.data = data
45
45
  dispatch_event(event)
46
46
  end
47
-
47
+
48
48
  def send(data, type = nil, error_type = nil)
49
49
  if @ready_state == CONNECTING
50
50
  if @send_buffer
@@ -54,22 +54,21 @@ module Faye
54
54
  raise IllegalStateError, 'Cannot call send(), socket is not open yet'
55
55
  end
56
56
  end
57
-
57
+
58
58
  return false if @ready_state == CLOSED
59
-
59
+
60
60
  data = data.to_s unless Array === data
61
-
61
+
62
62
  data = WebSocket.encode(data) if String === data
63
63
  frame = @parser.frame(data, type, error_type)
64
64
  @stream.write(frame) if frame
65
65
  end
66
-
66
+
67
67
  def close(code = nil, reason = nil, ack = true)
68
- return if [CLOSING, CLOSED].include?(@ready_state)
69
-
70
- @ready_state = CLOSING
71
-
72
- close = lambda do
68
+ return if @ready_state == CLOSED
69
+ return if @ready_state == CLOSING && ack
70
+
71
+ finalize = lambda do
73
72
  @ready_state = CLOSED
74
73
  EventMachine.cancel_timer(@ping_timer) if @ping_timer
75
74
  @stream.close_connection_after_writing
@@ -77,20 +76,24 @@ module Faye
77
76
  event.init_event('close', false, false)
78
77
  dispatch_event(event)
79
78
  end
80
-
79
+
80
+ return finalize.call if @ready_state == CONNECTING
81
+
82
+ @ready_state = CLOSING
83
+
81
84
  if ack
82
85
  if @parser.respond_to?(:close)
83
- @parser.close(code, reason, &close)
86
+ @parser.close(code, reason, &finalize)
84
87
  else
85
- close.call
88
+ finalize.call
86
89
  end
87
90
  else
88
91
  @parser.close(code, reason) if @parser.respond_to?(:close)
89
- close.call
92
+ finalize.call
90
93
  end
91
94
  end
92
95
  end
93
-
96
+
94
97
  end
95
98
  end
96
99
 
@@ -1,13 +1,13 @@
1
1
  module Faye::WebSocket::API
2
2
  class Event
3
-
3
+
4
4
  attr_reader :type, :bubbles, :cancelable
5
5
  attr_accessor :target, :current_target, :event_phase, :data
6
-
6
+
7
7
  CAPTURING_PHASE = 1
8
8
  AT_TARGET = 2
9
9
  BUBBLING_PHASE = 3
10
-
10
+
11
11
  def initialize(event_type, options = {})
12
12
  @type = event_type
13
13
  metaclass = (class << self ; self ; end)
@@ -15,19 +15,19 @@ module Faye::WebSocket::API
15
15
  metaclass.__send__(:define_method, key) { value }
16
16
  end
17
17
  end
18
-
18
+
19
19
  def init_event(event_type, can_bubble, cancelable)
20
20
  @type = event_type
21
21
  @bubbles = can_bubble
22
22
  @cancelable = cancelable
23
23
  end
24
-
24
+
25
25
  def stop_propagation
26
26
  end
27
-
27
+
28
28
  def prevent_default
29
29
  end
30
-
30
+
31
31
  end
32
32
  end
33
33
 
@@ -1,34 +1,34 @@
1
1
  module Faye::WebSocket::API
2
2
  module EventTarget
3
-
3
+
4
4
  attr_accessor :onopen, :onmessage, :onerror, :onclose
5
-
5
+
6
6
  def add_event_listener(event_type, listener, use_capture = false)
7
7
  @listeners ||= {}
8
8
  list = @listeners[event_type] ||= []
9
9
  list << listener
10
10
  end
11
-
11
+
12
12
  def remove_event_listener(event_type, listener, use_capture = false)
13
13
  return unless @listeners and @listeners[event_type]
14
14
  return @listeners.delete(event_type) unless listener
15
-
15
+
16
16
  @listeners[event_type].delete_if(&listener.method(:==))
17
17
  end
18
-
18
+
19
19
  def dispatch_event(event)
20
20
  event.target = event.current_target = self
21
21
  event.event_phase = Event::AT_TARGET
22
-
22
+
23
23
  callback = __send__("on#{ event.type }")
24
24
  callback.call(event) if callback
25
-
25
+
26
26
  return unless @listeners and @listeners[event.type]
27
27
  @listeners[event.type].each do |listener|
28
28
  listener.call(event)
29
29
  end
30
30
  end
31
-
31
+
32
32
  end
33
33
  end
34
34
 
@@ -1,51 +1,51 @@
1
1
  module Faye
2
2
  class WebSocket
3
-
3
+
4
4
  class Client
5
5
  include API
6
6
  attr_reader :protocol, :uri
7
-
7
+
8
8
  def initialize(url, protocols = nil)
9
9
  @parser = HybiParser.new(self, :masking => true, :protocols => protocols)
10
10
  @url = url
11
11
  @uri = URI.parse(url)
12
-
12
+
13
13
  @protocol = ''
14
14
  @ready_state = CONNECTING
15
15
  @buffered_amount = 0
16
-
16
+
17
17
  port = @uri.port || (@uri.scheme == 'wss' ? 443 : 80)
18
-
18
+
19
19
  EventMachine.connect(@uri.host, port, Connection) do |conn|
20
20
  @stream = conn
21
21
  conn.parent = self
22
22
  end
23
23
  end
24
-
24
+
25
25
  private
26
-
26
+
27
27
  def on_connect
28
28
  @stream.start_tls if @uri.scheme == 'wss'
29
29
  @handshake = @parser.create_handshake
30
30
  @message = []
31
31
  @stream.write(@handshake.request_data)
32
32
  end
33
-
33
+
34
34
  def receive_data(data)
35
35
  data = WebSocket.encode(data)
36
-
36
+
37
37
  case @ready_state
38
38
  when CONNECTING then
39
39
  @message += @handshake.parse(data)
40
40
  return unless @handshake.complete?
41
-
41
+
42
42
  if @handshake.valid?
43
43
  @protocol = @handshake.protocol || ''
44
44
  @ready_state = OPEN
45
45
  event = Event.new('open')
46
46
  event.init_event('open', false, false)
47
47
  dispatch_event(event)
48
-
48
+
49
49
  receive_data(@message)
50
50
  else
51
51
  @ready_state = CLOSED
@@ -53,32 +53,32 @@ module Faye
53
53
  event.init_event('close', false, false)
54
54
  dispatch_event(event)
55
55
  end
56
-
56
+
57
57
  when OPEN, CLOSING then
58
58
  @parser.parse(data)
59
59
  end
60
60
  end
61
-
61
+
62
62
  module Connection
63
63
  attr_accessor :parent
64
-
64
+
65
65
  def connection_completed
66
66
  parent.__send__(:on_connect)
67
67
  end
68
-
68
+
69
69
  def receive_data(data)
70
70
  parent.__send__(:receive_data, data)
71
71
  end
72
-
72
+
73
73
  def unbind
74
74
  parent.close(1006, '', false)
75
75
  end
76
-
76
+
77
77
  def write(data)
78
78
  send_data(data) rescue nil
79
79
  end
80
80
  end
81
81
  end
82
-
82
+
83
83
  end
84
84
  end
@@ -1,18 +1,18 @@
1
1
  module Faye
2
2
  class WebSocket
3
-
3
+
4
4
  class Draft75Parser
5
5
  attr_reader :protocol
6
-
6
+
7
7
  def initialize(web_socket, options = {})
8
8
  @socket = web_socket
9
9
  @stage = 0
10
10
  end
11
-
11
+
12
12
  def version
13
13
  'hixie-75'
14
14
  end
15
-
15
+
16
16
  def handshake_response
17
17
  upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
18
18
  upgrade << "Upgrade: WebSocket\r\n"
@@ -22,21 +22,21 @@ module Faye
22
22
  upgrade << "\r\n"
23
23
  upgrade
24
24
  end
25
-
25
+
26
26
  def open?
27
27
  true
28
28
  end
29
-
29
+
30
30
  def parse(buffer)
31
31
  buffer.each_byte do |data|
32
32
  case @stage
33
33
  when 0 then
34
34
  parse_leading_byte(data)
35
-
35
+
36
36
  when 1 then
37
37
  value = (data & 0x7F)
38
38
  @length = value + 128 * @length
39
-
39
+
40
40
  if @closing and @length.zero?
41
41
  @socket.close(nil, nil, false)
42
42
  elsif (0x80 & data) != 0x80
@@ -48,7 +48,7 @@ module Faye
48
48
  @stage = 2
49
49
  end
50
50
  end
51
-
51
+
52
52
  when 2 then
53
53
  if data == 0xFF
54
54
  @socket.receive(WebSocket.encode(@buffer))
@@ -61,10 +61,10 @@ module Faye
61
61
  end
62
62
  end
63
63
  end
64
-
64
+
65
65
  nil
66
66
  end
67
-
67
+
68
68
  def parse_leading_byte(data)
69
69
  if (0x80 & data) == 0x80
70
70
  @length = 0
@@ -75,13 +75,13 @@ module Faye
75
75
  @stage = 2
76
76
  end
77
77
  end
78
-
78
+
79
79
  def frame(data, type = nil, error_type = nil)
80
80
  return WebSocket.encode(data) if Array === data
81
81
  ["\x00", data, "\xFF"].map(&WebSocket.method(:encode)) * ''
82
82
  end
83
83
  end
84
-
84
+
85
85
  end
86
86
  end
87
87
 
@@ -1,15 +1,15 @@
1
1
  module Faye
2
2
  class WebSocket
3
-
3
+
4
4
  class Draft76Parser < Draft75Parser
5
5
  def version
6
6
  'hixie-76'
7
7
  end
8
-
8
+
9
9
  def handshake_response
10
10
  env = @socket.env
11
11
  signature = handshake_signature(env['rack.input'].read)
12
-
12
+
13
13
  upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
14
14
  upgrade << "Upgrade: WebSocket\r\n"
15
15
  upgrade << "Connection: Upgrade\r\n"
@@ -19,57 +19,57 @@ module Faye
19
19
  upgrade << signature if signature
20
20
  upgrade
21
21
  end
22
-
22
+
23
23
  def handshake_signature(head)
24
24
  return nil if head.empty?
25
25
  env = @socket.env
26
-
26
+
27
27
  key1 = env['HTTP_SEC_WEBSOCKET_KEY1']
28
28
  value1 = number_from_key(key1) / spaces_in_key(key1)
29
-
29
+
30
30
  key2 = env['HTTP_SEC_WEBSOCKET_KEY2']
31
31
  value2 = number_from_key(key2) / spaces_in_key(key2)
32
-
32
+
33
33
  @handshake_complete = true
34
-
34
+
35
35
  Digest::MD5.digest(big_endian(value1) +
36
36
  big_endian(value2) +
37
37
  head)
38
38
  end
39
-
39
+
40
40
  def open?
41
41
  !!@handshake_complete
42
42
  end
43
-
43
+
44
44
  def parse(data)
45
45
  return super if @handshake_complete
46
46
  handshake_signature(data)
47
47
  end
48
-
48
+
49
49
  def close(code = nil, reason = nil, &callback)
50
50
  return if @closed
51
51
  @socket.send([0xFF, 0x00]) if @closing
52
52
  @closed = true
53
53
  callback.call if callback
54
54
  end
55
-
55
+
56
56
  private
57
-
57
+
58
58
  def parse_leading_byte(data)
59
59
  return super unless data == 0xFF
60
60
  @closing = true
61
61
  @length = 0
62
62
  @stage = 1
63
63
  end
64
-
64
+
65
65
  def number_from_key(key)
66
66
  key.scan(/[0-9]/).join('').to_i(10)
67
67
  end
68
-
68
+
69
69
  def spaces_in_key(key)
70
70
  key.scan(/ /).size
71
71
  end
72
-
72
+
73
73
  def big_endian(number)
74
74
  string = ''
75
75
  [24,16,8,0].each do |offset|
@@ -78,7 +78,7 @@ module Faye
78
78
  string
79
79
  end
80
80
  end
81
-
81
+
82
82
  end
83
83
  end
84
84