faye-tls1-websocket 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,53 @@
1
+ require 'faye/websocket'
2
+ require 'rack'
3
+
4
+ static = Rack::File.new(File.dirname(__FILE__))
5
+
6
+ App = lambda do |env|
7
+ if Faye::WebSocket.websocket?(env)
8
+ ws = Faye::WebSocket.new(env, ['irc', 'xmpp'], :ping => 5)
9
+ p [:open, ws.url, ws.version, ws.protocol]
10
+
11
+ ws.onmessage = lambda do |event|
12
+ ws.send(event.data)
13
+ end
14
+
15
+ ws.onclose = lambda do |event|
16
+ p [:close, event.code, event.reason]
17
+ ws = nil
18
+ end
19
+
20
+ ws.rack_response
21
+
22
+ elsif Faye::EventSource.eventsource?(env)
23
+ es = Faye::EventSource.new(env)
24
+ time = es.last_event_id.to_i
25
+
26
+ p [:open, es.url, es.last_event_id]
27
+
28
+ loop = EM.add_periodic_timer(2) do
29
+ time += 1
30
+ es.send("Time: #{time}")
31
+ EM.add_timer(1) do
32
+ es.send('Update!!', :event => 'update', :id => time) if es
33
+ end
34
+ end
35
+
36
+ es.send("Welcome!\n\nThis is an EventSource server.")
37
+
38
+ es.onclose = lambda do |event|
39
+ EM.cancel_timer(loop)
40
+ p [:close, es.url]
41
+ es = nil
42
+ end
43
+
44
+ es.rack_response
45
+
46
+ else
47
+ static.call(env)
48
+ end
49
+ end
50
+
51
+ def App.log(message)
52
+ end
53
+
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'faye/websocket'
4
+ require 'cgi'
5
+ require 'progressbar'
6
+
7
+ EM.run {
8
+ host = 'ws://localhost:9001'
9
+ ruby = RUBY_PLATFORM =~ /java/ ? 'JRuby' : 'MRI'
10
+ agent = "#{ruby} #{RUBY_VERSION}"
11
+ cases = 0
12
+ skip = []
13
+
14
+ socket = Faye::WebSocket::Client.new("#{host}/getCaseCount")
15
+ progress = nil
16
+
17
+ socket.onmessage = lambda do |event|
18
+ puts "Total cases to run: #{event.data}"
19
+ cases = event.data.to_i
20
+ progress = ProgressBar.new('Autobahn', cases)
21
+ end
22
+
23
+ socket.onclose = lambda do |event|
24
+ run_case = lambda do |n|
25
+ progress.inc
26
+
27
+ if n > cases
28
+ socket = Faye::WebSocket::Client.new("#{host}/updateReports?agent=#{CGI.escape agent}")
29
+ progress.finish
30
+ socket.onclose = lambda { |e| EM.stop }
31
+
32
+ elsif skip.include?(n)
33
+ EM.next_tick { run_case.call(n+1) }
34
+
35
+ else
36
+ socket = Faye::WebSocket::Client.new("#{host}/runCase?case=#{n}&agent=#{CGI.escape agent}")
37
+
38
+ socket.onmessage = lambda do |event|
39
+ socket.send(event.data)
40
+ end
41
+
42
+ socket.on :close do |event|
43
+ run_case.call(n + 1)
44
+ end
45
+ end
46
+ end
47
+
48
+ run_case.call(1)
49
+ end
50
+ }
51
+
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'faye/websocket'
4
+ require 'eventmachine'
5
+
6
+ port = ARGV[0] || 7000
7
+ secure = ARGV[1] == 'ssl'
8
+
9
+ EM.run {
10
+ scheme = secure ? 'wss' : 'ws'
11
+ url = "#{scheme}://localhost:#{port}/"
12
+ headers = {'Origin' => 'http://faye.jcoglan.com'}
13
+ ws = Faye::WebSocket::Client.new(url, nil, :headers => headers)
14
+
15
+ puts "Connecting to #{ws.url}"
16
+
17
+ ws.onopen = lambda do |event|
18
+ p [:open]
19
+ ws.send("Hello, WebSocket!")
20
+ end
21
+
22
+ ws.onmessage = lambda do |event|
23
+ p [:message, event.data]
24
+ # ws.close 1002, 'Going away'
25
+ end
26
+
27
+ ws.onclose = lambda do |event|
28
+ p [:close, event.code, event.reason]
29
+ EM.stop
30
+ end
31
+ }
32
+
@@ -0,0 +1,14 @@
1
+ # Run using your favourite server:
2
+ #
3
+ # thin start -R examples/config.ru -p 7000
4
+ # rainbows -c examples/rainbows.conf -E production examples/config.ru -p 7000
5
+
6
+ require 'rubygems'
7
+ require 'bundler/setup'
8
+ require File.expand_path('../app', __FILE__)
9
+
10
+ Faye::WebSocket.load_adapter('thin')
11
+ Faye::WebSocket.load_adapter('rainbows')
12
+
13
+ run App
14
+
@@ -0,0 +1,21 @@
1
+ defaults
2
+ mode http
3
+ timeout client 5s
4
+ timeout connect 5s
5
+ timeout server 5s
6
+
7
+ frontend all 0.0.0.0:3000
8
+ mode http
9
+ timeout client 120s
10
+
11
+ option forwardfor
12
+ option http-server-close
13
+ option http-pretend-keepalive
14
+
15
+ default_backend sockets
16
+
17
+ backend sockets
18
+ balance uri depth 2
19
+ timeout server 120s
20
+ server socket1 127.0.0.1:7000
21
+
@@ -0,0 +1,3 @@
1
+ Rainbows! do
2
+ use :EventMachine
3
+ end
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rack/content_length'
4
+ require 'rack/chunked'
5
+
6
+ port = ARGV[0] || 7000
7
+ secure = ARGV[1] == 'ssl'
8
+ engine = ARGV[2] || 'thin'
9
+ spec = File.expand_path('../../spec', __FILE__)
10
+
11
+ require File.expand_path('../app', __FILE__)
12
+ Faye::WebSocket.load_adapter(engine)
13
+
14
+ case engine
15
+
16
+ when 'goliath'
17
+ class WebSocketServer < Goliath::API
18
+ def response(env)
19
+ App.call(env)
20
+ end
21
+ end
22
+
23
+ when 'puma'
24
+ events = Puma::Events.new($stdout, $stderr)
25
+ binder = Puma::Binder.new(events)
26
+ binder.parse(["tcp://0.0.0.0:#{port}"], App)
27
+ server = Puma::Server.new(App, events)
28
+ server.binder = binder
29
+ server.run.join
30
+
31
+ when 'rainbows'
32
+ rackup = Unicorn::Configurator::RACKUP
33
+ rackup[:port] = port
34
+ rackup[:set_listener] = true
35
+ options = rackup[:options]
36
+ options[:config_file] = File.expand_path('../rainbows.conf', __FILE__)
37
+ Rainbows::HttpServer.new(App, options).start.join
38
+
39
+ when 'thin'
40
+ EM.run {
41
+ thin = Rack::Handler.get('thin')
42
+ thin.run(App, :Port => port) do |server|
43
+ if secure
44
+ server.ssl_options = {
45
+ :private_key_file => spec + '/server.key',
46
+ :cert_chain_file => spec + '/server.crt'
47
+ }
48
+ server.ssl = true
49
+ end
50
+ end
51
+ }
52
+ end
53
+
@@ -0,0 +1,39 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
5
+ <title>EventSource test</title>
6
+ </head>
7
+ <body>
8
+
9
+ <h1>EventSource test</h1>
10
+ <ul></ul>
11
+
12
+ <script type="text/javascript">
13
+ var logger = document.getElementsByTagName('ul')[0],
14
+ socket = new EventSource('/');
15
+
16
+ var log = function(text) {
17
+ logger.innerHTML += '<li>' + text + '</li>';
18
+ };
19
+
20
+ socket.onopen = function() {
21
+ log('OPEN');
22
+ };
23
+
24
+ socket.onmessage = function(event) {
25
+ log('MESSAGE: ' + event.data);
26
+ };
27
+
28
+ socket.addEventListener('update', function(event) {
29
+ log('UPDATE(' + event.lastEventId + '): ' + event.data);
30
+ });
31
+
32
+ socket.onerror = function(event) {
33
+ log('ERROR: ' + event.message);
34
+ };
35
+ </script>
36
+
37
+ </body>
38
+ </html>
39
+
@@ -0,0 +1,44 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8">
5
+ <title>WebSocket test</title>
6
+ </head>
7
+ <body>
8
+
9
+ <h1>WebSocket test</h1>
10
+ <ul></ul>
11
+
12
+ <script type="text/javascript">
13
+ var logger = document.getElementsByTagName('ul')[0],
14
+ Socket = window.MozWebSocket || window.WebSocket,
15
+ protos = ['foo', 'bar', 'xmpp'],
16
+ socket = new Socket('ws://' + location.hostname + ':' + location.port + '/', protos),
17
+ index = 0;
18
+
19
+ var log = function(text) {
20
+ logger.innerHTML += '<li>' + text + '</li>';
21
+ };
22
+
23
+ socket.addEventListener('open', function() {
24
+ log('OPEN: ' + socket.protocol);
25
+ socket.send('Hello, world');
26
+ });
27
+
28
+ socket.onerror = function(event) {
29
+ log('ERROR: ' + event.message);
30
+ };
31
+
32
+ socket.onmessage = function(event) {
33
+ log('MESSAGE: ' + event.data);
34
+ setTimeout(function() { socket.send(++index + ' ' + event.data) }, 2000);
35
+ };
36
+
37
+ socket.onclose = function(event) {
38
+ log('CLOSE: ' + event.code + ', ' + event.reason);
39
+ };
40
+ </script>
41
+
42
+ </body>
43
+ </html>
44
+
@@ -0,0 +1,47 @@
1
+ class Goliath::Connection
2
+ attr_accessor :socket_stream
3
+ alias :goliath_receive_data :receive_data
4
+
5
+ def receive_data(data)
6
+ if @serving == :websocket
7
+ socket_stream.receive(data) if socket_stream
8
+ else
9
+ goliath_receive_data(data)
10
+ socket_stream.receive(@parser.upgrade_data) if socket_stream
11
+ @serving = :websocket if @api.websocket?
12
+ end
13
+ end
14
+
15
+ def unbind
16
+ super
17
+ ensure
18
+ socket_stream.fail if socket_stream
19
+ end
20
+ end
21
+
22
+ class Goliath::API
23
+ include Faye::WebSocket::Adapter
24
+ end
25
+
26
+ class Goliath::Request
27
+ alias :goliath_process :process
28
+
29
+ def process
30
+ env['em.connection'] = conn
31
+ goliath_process
32
+ end
33
+ end
34
+
35
+ class Goliath::Response
36
+ alias :goliath_head :head
37
+ alias :goliath_headers_output :headers_output
38
+
39
+ def head
40
+ (status == 101) ? '' : goliath_head
41
+ end
42
+
43
+ def headers_output
44
+ (status == 101) ? '' : goliath_headers_output
45
+ end
46
+ end
47
+
@@ -0,0 +1,31 @@
1
+ # WebSocket extensions for Rainbows
2
+ # Based on code from the Cramp project
3
+ # http://github.com/lifo/cramp
4
+
5
+ # Copyright (c) 2009-2011 Pratik Naik
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ module Faye
26
+ class WebSocket
27
+ autoload :RainbowsClient, File.expand_path('../rainbows_client', __FILE__)
28
+ end
29
+ end
30
+
31
+ Rainbows::O[:em_client_class] = "Faye::WebSocket::RainbowsClient"
@@ -0,0 +1,69 @@
1
+ # WebSocket extensions for Rainbows
2
+ # Based on code from the Cramp project
3
+ # http://github.com/lifo/cramp
4
+
5
+ # Copyright (c) 2009-2011 Pratik Naik
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ # SOFTWARE.
24
+
25
+ module Faye
26
+ class WebSocket
27
+
28
+ class RainbowsClient < Rainbows::EventMachine::Client
29
+ include Faye::WebSocket::Adapter
30
+ attr_accessor :socket_stream
31
+
32
+ def receive_data(data)
33
+ return super unless @state == :websocket
34
+ socket_stream.receive(data) if socket_stream
35
+ end
36
+
37
+ def app_call(*args)
38
+ @env['em.connection'] = self
39
+ if args.first == NULL_IO and @hp.content_length == 0 and websocket?
40
+ prepare_request_body
41
+ else
42
+ super
43
+ end
44
+ end
45
+
46
+ def on_read(data)
47
+ if @state == :body and websocket? and @hp.body_eof?
48
+ @state = :websocket
49
+ @input.rewind
50
+ app_call StringIO.new(@buf)
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def unbind
57
+ super
58
+ ensure
59
+ socket_stream.fail if socket_stream
60
+ end
61
+
62
+ def write_headers(status, headers, *args)
63
+ super unless socket_connection? and status == 101
64
+ end
65
+ end
66
+
67
+ end
68
+ end
69
+