faye-websocket 0.4.6-java → 0.4.7-java

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.

Potentially problematic release.


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

@@ -15,14 +15,14 @@ void Init_faye_websocket_mask() {
15
15
  VALUE method_faye_websocket_mask(VALUE self, VALUE payload, VALUE mask) {
16
16
  int n = RARRAY_LEN(payload), i, p, m;
17
17
  VALUE unmasked = rb_ary_new2(n);
18
-
18
+
19
19
  int mask_array[] = {
20
20
  NUM2INT(rb_ary_entry(mask, 0)),
21
21
  NUM2INT(rb_ary_entry(mask, 1)),
22
22
  NUM2INT(rb_ary_entry(mask, 2)),
23
23
  NUM2INT(rb_ary_entry(mask, 3))
24
24
  };
25
-
25
+
26
26
  for (i = 0; i < n; i++) {
27
27
  p = NUM2INT(rb_ary_entry(payload, i));
28
28
  m = mask_array[i % 4];
@@ -1,7 +1,7 @@
1
1
  class Goliath::Connection
2
2
  attr_accessor :socket_stream
3
3
  alias :goliath_receive_data :receive_data
4
-
4
+
5
5
  def receive_data(data)
6
6
  if @serving == :websocket
7
7
  socket_stream.receive(data) if socket_stream
@@ -11,7 +11,7 @@ class Goliath::Connection
11
11
  @serving = :websocket if @api.websocket?
12
12
  end
13
13
  end
14
-
14
+
15
15
  def unbind
16
16
  super
17
17
  ensure
@@ -25,7 +25,7 @@ end
25
25
 
26
26
  class Goliath::Request
27
27
  alias :goliath_process :process
28
-
28
+
29
29
  def process
30
30
  env['em.connection'] = conn
31
31
  goliath_process
@@ -35,11 +35,11 @@ end
35
35
  class Goliath::Response
36
36
  alias :goliath_head :head
37
37
  alias :goliath_headers_output :headers_output
38
-
38
+
39
39
  def head
40
40
  (status == 101) ? '' : goliath_head
41
41
  end
42
-
42
+
43
43
  def headers_output
44
44
  (status == 101) ? '' : goliath_headers_output
45
45
  end
@@ -3,7 +3,7 @@
3
3
  # http://github.com/lifo/cramp
4
4
 
5
5
  # Copyright (c) 2009-2011 Pratik Naik
6
- #
6
+ #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining
8
8
  # a copy of this software and associated documentation files (the
9
9
  # "Software"), to deal in the Software without restriction, including
@@ -11,10 +11,10 @@
11
11
  # distribute, sublicense, and/or sell copies of the Software, and to
12
12
  # permit persons to whom the Software is furnished to do so, subject to
13
13
  # the following conditions:
14
- #
14
+ #
15
15
  # The above copyright notice and this permission notice shall be
16
16
  # included in all copies or substantial portions of the Software.
17
- #
17
+ #
18
18
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
19
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
20
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -3,7 +3,7 @@
3
3
  # http://github.com/lifo/cramp
4
4
 
5
5
  # Copyright (c) 2009-2011 Pratik Naik
6
- #
6
+ #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining
8
8
  # a copy of this software and associated documentation files (the
9
9
  # "Software"), to deal in the Software without restriction, including
@@ -11,10 +11,10 @@
11
11
  # distribute, sublicense, and/or sell copies of the Software, and to
12
12
  # permit persons to whom the Software is furnished to do so, subject to
13
13
  # the following conditions:
14
- #
14
+ #
15
15
  # The above copyright notice and this permission notice shall be
16
16
  # included in all copies or substantial portions of the Software.
17
- #
17
+ #
18
18
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
19
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
20
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -25,16 +25,16 @@
25
25
 
26
26
  module Faye
27
27
  class WebSocket
28
-
28
+
29
29
  class RainbowsClient < Rainbows::EventMachine::Client
30
30
  include Faye::WebSocket::Adapter
31
31
  attr_accessor :socket_stream
32
-
32
+
33
33
  def receive_data(data)
34
34
  return super unless @state == :websocket
35
35
  socket_stream.receive(data) if socket_stream
36
36
  end
37
-
37
+
38
38
  def app_call(*args)
39
39
  @env['em.connection'] = self
40
40
  if args.first == NULL_IO and @hp.content_length == 0 and websocket?
@@ -43,7 +43,7 @@ module Faye
43
43
  super
44
44
  end
45
45
  end
46
-
46
+
47
47
  def on_read(data)
48
48
  if @state == :body and websocket? and @hp.body_eof?
49
49
  @state = :websocket
@@ -53,18 +53,18 @@ module Faye
53
53
  super
54
54
  end
55
55
  end
56
-
56
+
57
57
  def unbind
58
58
  super
59
59
  ensure
60
60
  socket_stream.fail if socket_stream
61
61
  end
62
-
63
- def write_headers(*args)
64
- super unless async_connection?
62
+
63
+ def write_headers(status, headers, *args)
64
+ super unless socket_connection? and status == 101
65
65
  end
66
66
  end
67
-
67
+
68
68
  end
69
69
  end
70
70
 
@@ -3,7 +3,7 @@
3
3
  # http://github.com/lifo/cramp
4
4
 
5
5
  # Copyright (c) 2009-2011 Pratik Naik
6
- #
6
+ #
7
7
  # Permission is hereby granted, free of charge, to any person obtaining
8
8
  # a copy of this software and associated documentation files (the
9
9
  # "Software"), to deal in the Software without restriction, including
@@ -11,10 +11,10 @@
11
11
  # distribute, sublicense, and/or sell copies of the Software, and to
12
12
  # permit persons to whom the Software is furnished to do so, subject to
13
13
  # the following conditions:
14
- #
14
+ #
15
15
  # The above copyright notice and this permission notice shall be
16
16
  # included in all copies or substantial portions of the Software.
17
- #
17
+ #
18
18
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
19
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
20
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -25,22 +25,22 @@
25
25
 
26
26
  class Thin::Connection
27
27
  attr_accessor :socket_stream
28
-
28
+
29
29
  alias :thin_process :process
30
30
  alias :thin_receive_data :receive_data
31
-
31
+
32
32
  def process
33
33
  if @serving != :websocket and @request.websocket?
34
34
  @serving = :websocket
35
35
  end
36
- if @request.async_connection?
36
+ if @request.socket_connection?
37
37
  @request.env['em.connection'] = self
38
38
  @response.persistent!
39
39
  @response.async = true
40
40
  end
41
41
  thin_process
42
42
  end
43
-
43
+
44
44
  def receive_data(data)
45
45
  return thin_receive_data(data) unless @serving == :websocket
46
46
  socket_stream.receive(data) if socket_stream
@@ -54,9 +54,10 @@ end
54
54
  class Thin::Response
55
55
  attr_accessor :async
56
56
  alias :thin_head :head
57
-
57
+
58
58
  def head
59
- async ? '' : thin_head
59
+ return '' if async and status == 101
60
+ thin_head
60
61
  end
61
62
  end
62
63
 
@@ -3,82 +3,82 @@ require File.expand_path('../websocket', __FILE__) unless defined?(Faye::WebSock
3
3
  module Faye
4
4
  class EventSource
5
5
  DEFAULT_RETRY = 5
6
-
6
+
7
7
  include WebSocket::API
8
8
  attr_reader :env, :url, :ready_state
9
-
9
+
10
10
  def self.eventsource?(env)
11
11
  accept = (env['HTTP_ACCEPT'] || '').split(/\s*,\s*/)
12
12
  accept.include?('text/event-stream')
13
13
  end
14
-
14
+
15
15
  def self.determine_url(env)
16
16
  secure = if env.has_key?('HTTP_X_FORWARDED_PROTO')
17
17
  env['HTTP_X_FORWARDED_PROTO'] == 'https'
18
18
  else
19
19
  env['HTTP_ORIGIN'] =~ /^https:/i
20
20
  end
21
-
21
+
22
22
  scheme = secure ? 'https:' : 'http:'
23
23
  "#{ scheme }//#{ env['HTTP_HOST'] }#{ env['REQUEST_URI'] }"
24
24
  end
25
-
25
+
26
26
  def initialize(env, options = {})
27
27
  @env = env
28
28
  @ping = options[:ping]
29
29
  @retry = (options[:retry] || DEFAULT_RETRY).to_f
30
30
  @url = EventSource.determine_url(env)
31
31
  @stream = Stream.new(self)
32
-
32
+
33
33
  @ready_state = CONNECTING
34
34
  @send_buffer = []
35
35
  EventMachine.next_tick { open }
36
-
36
+
37
37
  callback = @env['async.callback']
38
38
  callback.call([101, {}, @stream])
39
-
39
+
40
40
  @stream.write("HTTP/1.1 200 OK\r\n" +
41
41
  "Content-Type: text/event-stream\r\n" +
42
42
  "Cache-Control: no-cache, no-store\r\n" +
43
43
  "Connection: close\r\n" +
44
44
  "\r\n\r\n" +
45
45
  "retry: #{ (@retry * 1000).floor }\r\n\r\n")
46
-
46
+
47
47
  @ready_state = OPEN
48
-
48
+
49
49
  if @ping
50
50
  @ping_timer = EventMachine.add_periodic_timer(@ping) { ping }
51
51
  end
52
52
  end
53
-
53
+
54
54
  def last_event_id
55
55
  @env['HTTP_LAST_EVENT_ID'] || ''
56
56
  end
57
-
57
+
58
58
  def rack_response
59
59
  [ -1, {}, [] ]
60
60
  end
61
-
61
+
62
62
  def send(message, options = {})
63
63
  return false unless @ready_state == OPEN
64
-
64
+
65
65
  message = WebSocket.encode(message.to_s).
66
66
  gsub(/(\r\n|\r|\n)/, '\1data: ')
67
-
67
+
68
68
  frame = ""
69
69
  frame << "event: #{options[:event]}\r\n" if options[:event]
70
70
  frame << "id: #{options[:id]}\r\n" if options[:id]
71
71
  frame << "data: #{message}\r\n\r\n"
72
-
72
+
73
73
  @stream.write(frame)
74
74
  true
75
75
  end
76
-
76
+
77
77
  def ping(message = nil)
78
78
  @stream.write(":\r\n\r\n")
79
79
  true
80
80
  end
81
-
81
+
82
82
  def close
83
83
  return if [CLOSING, CLOSED].include?(@ready_state)
84
84
  @ready_state = CLOSED
@@ -89,32 +89,32 @@ module Faye
89
89
  dispatch_event(event)
90
90
  end
91
91
  end
92
-
92
+
93
93
  class EventSource::Stream
94
94
  include EventMachine::Deferrable
95
-
95
+
96
96
  extend Forwardable
97
97
  def_delegators :@connection, :close_connection, :close_connection_after_writing
98
-
98
+
99
99
  def initialize(event_source)
100
100
  @event_source = event_source
101
101
  @connection = event_source.env['em.connection']
102
102
  @stream_send = event_source.env['stream.send']
103
-
103
+
104
104
  @connection.socket_stream = self if @connection.respond_to?(:socket_stream)
105
105
  end
106
-
106
+
107
107
  def each(&callback)
108
108
  @stream_send ||= callback
109
109
  end
110
-
110
+
111
111
  def fail
112
112
  @event_source.close
113
113
  end
114
-
114
+
115
115
  def receive(data)
116
116
  end
117
-
117
+
118
118
  def write(data)
119
119
  return unless @stream_send
120
120
  @stream_send.call(data) rescue nil
@@ -1,5 +1,5 @@
1
1
  # API and protocol references:
2
- #
2
+ #
3
3
  # * http://dev.w3.org/html5/websockets/
4
4
  # * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget
5
5
  # * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-event
@@ -18,61 +18,61 @@ require 'eventmachine'
18
18
 
19
19
  module Faye
20
20
  autoload :EventSource, File.expand_path('../eventsource', __FILE__)
21
-
21
+
22
22
  class WebSocket
23
23
  root = File.expand_path('../websocket', __FILE__)
24
24
  require root + '/../../faye_websocket_mask'
25
-
25
+
26
26
  def self.jruby?
27
27
  defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
28
28
  end
29
-
29
+
30
30
  def self.rbx?
31
31
  defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
32
32
  end
33
-
33
+
34
34
  if jruby?
35
35
  require 'jruby'
36
36
  com.jcoglan.faye.FayeWebsocketMaskService.new.basicLoad(JRuby.runtime)
37
37
  end
38
-
38
+
39
39
  unless WebSocketMask.respond_to?(:mask)
40
40
  def WebSocketMask.mask(payload, mask)
41
41
  @instance ||= new
42
42
  @instance.mask(payload, mask)
43
43
  end
44
44
  end
45
-
45
+
46
46
  unless String.instance_methods.include?(:force_encoding)
47
47
  require root + '/utf8_match'
48
48
  end
49
-
49
+
50
50
  autoload :Adapter, root + '/adapter'
51
51
  autoload :API, root + '/api'
52
52
  autoload :Client, root + '/client'
53
53
  autoload :Draft75Parser, root + '/draft75_parser'
54
54
  autoload :Draft76Parser, root + '/draft76_parser'
55
55
  autoload :HybiParser, root + '/hybi_parser'
56
-
56
+
57
57
  ADAPTERS = {
58
58
  'thin' => :Thin,
59
59
  'rainbows' => :Rainbows,
60
60
  'goliath' => :Goliath
61
61
  }
62
-
62
+
63
63
  def self.load_adapter(backend)
64
64
  const = Kernel.const_get(ADAPTERS[backend]) rescue nil
65
65
  require(backend) unless const
66
66
  require File.expand_path("../adapters/#{backend}", __FILE__)
67
67
  end
68
-
68
+
69
69
  def self.utf8_string(string)
70
70
  string = string.pack('C*') if Array === string
71
71
  string.respond_to?(:force_encoding) ?
72
72
  string.force_encoding('UTF-8') :
73
73
  string
74
74
  end
75
-
75
+
76
76
  def self.encode(string, validate_encoding = false)
77
77
  if Array === string
78
78
  string = utf8_string(string)
@@ -80,7 +80,7 @@ module Faye
80
80
  end
81
81
  utf8_string(string)
82
82
  end
83
-
83
+
84
84
  def self.valid_utf8?(byte_array)
85
85
  string = utf8_string(byte_array)
86
86
  if defined?(UTF8_MATCH)
@@ -89,14 +89,14 @@ module Faye
89
89
  string.valid_encoding?
90
90
  end
91
91
  end
92
-
92
+
93
93
  def self.websocket?(env)
94
94
  env['REQUEST_METHOD'] == 'GET' and
95
95
  env['HTTP_CONNECTION'] and
96
96
  env['HTTP_CONNECTION'].split(/\s*,\s*/).include?('Upgrade') and
97
- ['WebSocket', 'websocket'].include?(env['HTTP_UPGRADE'])
97
+ env['HTTP_UPGRADE'].downcase == 'websocket'
98
98
  end
99
-
99
+
100
100
  def self.parser(env)
101
101
  if env['HTTP_SEC_WEBSOCKET_VERSION']
102
102
  HybiParser
@@ -106,45 +106,45 @@ module Faye
106
106
  Draft75Parser
107
107
  end
108
108
  end
109
-
109
+
110
110
  def self.determine_url(env)
111
111
  secure = if env.has_key?('HTTP_X_FORWARDED_PROTO')
112
112
  env['HTTP_X_FORWARDED_PROTO'] == 'https'
113
113
  else
114
114
  env['HTTP_ORIGIN'] =~ /^https:/i
115
115
  end
116
-
116
+
117
117
  scheme = secure ? 'wss:' : 'ws:'
118
118
  "#{ scheme }//#{ env['HTTP_HOST'] }#{ env['REQUEST_URI'] }"
119
119
  end
120
-
120
+
121
121
  extend Forwardable
122
122
  def_delegators :@parser, :version
123
-
123
+
124
124
  attr_reader :env
125
125
  include API
126
-
126
+
127
127
  def initialize(env, supported_protos = nil, options = {})
128
128
  @env = env
129
129
  @stream = Stream.new(self)
130
130
  @ping = options[:ping]
131
131
  @ping_id = 0
132
-
132
+
133
133
  @url = WebSocket.determine_url(@env)
134
134
  @ready_state = CONNECTING
135
135
  @buffered_amount = 0
136
-
136
+
137
137
  @parser = WebSocket.parser(@env).new(self, :protocols => supported_protos)
138
-
138
+
139
139
  @send_buffer = []
140
140
  EventMachine.next_tick { open }
141
-
141
+
142
142
  @callback = @env['async.callback']
143
143
  @callback.call([101, {}, @stream])
144
144
  @stream.write(@parser.handshake_response)
145
-
145
+
146
146
  @ready_state = OPEN if @parser.open?
147
-
147
+
148
148
  if @ping
149
149
  @ping_timer = EventMachine.add_periodic_timer(@ping) do
150
150
  @ping_id += 1
@@ -152,22 +152,22 @@ module Faye
152
152
  end
153
153
  end
154
154
  end
155
-
155
+
156
156
  def ping(message = '', &callback)
157
157
  return false unless @parser.respond_to?(:ping)
158
158
  @parser.ping(message, &callback)
159
159
  end
160
-
160
+
161
161
  def protocol
162
162
  @parser.protocol || ''
163
163
  end
164
-
164
+
165
165
  def rack_response
166
166
  [ -1, {}, [] ]
167
167
  end
168
-
168
+
169
169
  private
170
-
170
+
171
171
  def parse(data)
172
172
  response = @parser.parse(data)
173
173
  return unless response
@@ -175,33 +175,33 @@ module Faye
175
175
  open
176
176
  end
177
177
  end
178
-
178
+
179
179
  class WebSocket::Stream
180
180
  include EventMachine::Deferrable
181
-
181
+
182
182
  extend Forwardable
183
183
  def_delegators :@connection, :close_connection, :close_connection_after_writing
184
-
184
+
185
185
  def initialize(web_socket)
186
186
  @web_socket = web_socket
187
187
  @connection = web_socket.env['em.connection']
188
188
  @stream_send = web_socket.env['stream.send']
189
-
189
+
190
190
  @connection.socket_stream = self if @connection.respond_to?(:socket_stream)
191
191
  end
192
-
192
+
193
193
  def each(&callback)
194
194
  @stream_send ||= callback
195
195
  end
196
-
196
+
197
197
  def fail
198
198
  @web_socket.close(1006, '', false)
199
199
  end
200
-
200
+
201
201
  def receive(data)
202
202
  @web_socket.__send__(:parse, data)
203
203
  end
204
-
204
+
205
205
  def write(data)
206
206
  return unless @stream_send
207
207
  @stream_send.call(data) rescue nil