funnel 0.1.6 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/funnel.gemspec +4 -3
- data/lib/funnel.rb +1 -2
- data/lib/funnel/configuration.rb +2 -2
- data/lib/funnel/flash/policy.rb +8 -2
- data/lib/funnel/log.rb +49 -0
- data/lib/funnel/routing/router.rb +22 -10
- data/lib/funnel/routing/routes.rb +9 -19
- data/lib/funnel/server.rb +4 -0
- data/lib/funnel/web_socket/connection.rb +14 -17
- data/templates/application/config/boot.rb +4 -2
- data/templates/application/config/routes.rb +1 -1
- data/templates/application/config/settings.yml +1 -4
- data/templates/application/handlers/debug_handler.rb +25 -0
- data/templates/application/htdocs/test.html +33 -0
- metadata +5 -4
- data/lib/funnel/logger.rb +0 -24
- data/templates/application/handlers/test_handler.rb +0 -21
data/funnel.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
spec = Gem::Specification.new do |s|
|
2
2
|
s.name = 'funnel'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.8'
|
4
4
|
s.date = '2009-12-30'
|
5
5
|
s.summary = 'A realtime resource-centric application framework'
|
6
6
|
s.email = 'dan.simpson@gmail.com'
|
@@ -18,7 +18,7 @@ spec = Gem::Specification.new do |s|
|
|
18
18
|
'README.markdown',
|
19
19
|
'funnel.gemspec',
|
20
20
|
'lib/funnel.rb',
|
21
|
-
'lib/funnel/
|
21
|
+
'lib/funnel/log.rb',
|
22
22
|
'lib/funnel/configuration.rb',
|
23
23
|
'lib/funnel/flash/policy.rb',
|
24
24
|
'lib/funnel/web_socket/frame.rb',
|
@@ -33,6 +33,7 @@ spec = Gem::Specification.new do |s|
|
|
33
33
|
'templates/application/config/settings.yml',
|
34
34
|
'templates/application/config/routes.rb',
|
35
35
|
'templates/application/script/server',
|
36
|
-
'templates/application/
|
36
|
+
'templates/application/htdocs/test.html',
|
37
|
+
'templates/application/handlers/debug_handler.rb',
|
37
38
|
]
|
38
39
|
end
|
data/lib/funnel.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'eventmachine'
|
3
|
-
require 'pp'
|
4
3
|
|
5
4
|
module Funnel
|
6
5
|
module WebSocket
|
@@ -8,7 +7,7 @@ module Funnel
|
|
8
7
|
end
|
9
8
|
|
10
9
|
require 'funnel/configuration.rb'
|
11
|
-
require 'funnel/
|
10
|
+
require 'funnel/log.rb'
|
12
11
|
require 'funnel/flash/policy.rb'
|
13
12
|
require 'funnel/generators/application.rb'
|
14
13
|
require 'funnel/web_socket/frame.rb'
|
data/lib/funnel/configuration.rb
CHANGED
data/lib/funnel/flash/policy.rb
CHANGED
@@ -13,10 +13,10 @@ module Funnel
|
|
13
13
|
# use the configuration settings to determine who
|
14
14
|
# can connect via the flash socket
|
15
15
|
if accepted.empty?
|
16
|
-
response <<
|
16
|
+
response << allow_tag("*")
|
17
17
|
else
|
18
18
|
accepted.each do |domain|
|
19
|
-
response <<
|
19
|
+
response << allow_tag(domain)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -24,6 +24,12 @@ module Funnel
|
|
24
24
|
response
|
25
25
|
end
|
26
26
|
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.allow_tag domain
|
30
|
+
"<allow-access-from domain=\"#{domain}\" to-ports=\"#{settings.get(:port)}\"/>"
|
31
|
+
end
|
32
|
+
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
data/lib/funnel/log.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Funnel
|
2
|
+
class Log
|
3
|
+
|
4
|
+
@@threshhold = 1
|
5
|
+
|
6
|
+
# TODO (Maybe): all this can be made way more
|
7
|
+
# meta... at the cost of readibility
|
8
|
+
@@descriptor = {
|
9
|
+
1 => "DBUG",
|
10
|
+
2 => "WARN",
|
11
|
+
3 => "INFO"
|
12
|
+
}
|
13
|
+
|
14
|
+
def self.debug msg
|
15
|
+
log(msg,1) if @@threshhold <= 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.warning msg
|
19
|
+
log(msg,2) if @@threshhold <= 2
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.info msg
|
23
|
+
log(msg,3) if @@threshhold <= 3
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.debug!
|
27
|
+
@@threshhold = 1
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.warn!
|
31
|
+
@@threshhold = 2
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.info!
|
35
|
+
@@threshhold = 3
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.shutthefuckup!
|
39
|
+
@@threshhold = 4
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def self.log msg, level
|
45
|
+
puts "[#{@@descriptor[level]}] #{Time.now} - #{msg}"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -11,18 +11,24 @@ module Funnel
|
|
11
11
|
send_data Funnel::Flash::Policy.response
|
12
12
|
close_connection and return
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
@headers = WebSocket::Headers.parse(data)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
else
|
21
|
-
close_connection
|
16
|
+
|
17
|
+
unless valid_connection?
|
18
|
+
Log.info("Invalid WebSocket Connection")
|
19
|
+
close_connection and return
|
22
20
|
end
|
23
|
-
|
21
|
+
|
22
|
+
unless valid_origin?
|
23
|
+
Log.info("Invalid WebSocket Origin")
|
24
|
+
close_connection and return
|
25
|
+
end
|
26
|
+
|
27
|
+
accept_connection
|
28
|
+
defer_connection
|
29
|
+
|
24
30
|
end
|
25
|
-
|
31
|
+
|
26
32
|
# is this a websocket connection?
|
27
33
|
def valid_connection?
|
28
34
|
@headers[:connection] =~ /upgrade/i && @headers[:upgrade] =~ /websocket/i
|
@@ -49,8 +55,14 @@ module Funnel
|
|
49
55
|
# change the handler from this instance, to a new instance
|
50
56
|
# of the type defined by the routing map
|
51
57
|
def defer_connection
|
58
|
+
handler = Routes.get_handler(path)
|
59
|
+
|
60
|
+
unless handler
|
61
|
+
Log.info "No route matches #{path}"
|
62
|
+
close_connection and return
|
63
|
+
end
|
52
64
|
|
53
|
-
conn =
|
65
|
+
conn = handler.send(:new, @signature)
|
54
66
|
conn.headers = @headers
|
55
67
|
|
56
68
|
EM.instance_variable_get("@conns")[@signature] = conn
|
@@ -8,42 +8,32 @@ module Funnel
|
|
8
8
|
def self.get_handler path
|
9
9
|
@@instance.get_handler(path)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def self.draw
|
13
13
|
@@instance = Routes.new unless @@instance
|
14
14
|
yield @@instance
|
15
15
|
end
|
16
|
-
|
17
|
-
|
16
|
+
|
18
17
|
def initialize
|
19
18
|
@routes = {}
|
20
19
|
end
|
21
|
-
|
20
|
+
|
22
21
|
def connect path, opts
|
23
22
|
@routes[path] = Route.new(path, opts)
|
24
23
|
end
|
25
|
-
|
24
|
+
|
26
25
|
def default opts
|
27
26
|
@routes[:default] = Route.new(:default, opts)
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
def get_default
|
31
|
-
|
32
|
-
|
33
|
-
@routes[:default].handler
|
30
|
+
@routes.key?(:default) ? @routes[:default].handler : nil
|
34
31
|
end
|
35
|
-
|
32
|
+
|
36
33
|
def get_handler path
|
37
|
-
@routes.key?(path) ? @routes[path].handler :
|
34
|
+
@routes.key?(path) ? @routes[path].handler : get_default
|
38
35
|
end
|
39
|
-
|
40
|
-
def raise_no_default_error
|
41
|
-
str = "No default route detected. Please supply a"
|
42
|
-
str << " default route in your config/routes.rb file. "
|
43
|
-
str << " Eg: map.default :handler => TestHandler"
|
44
|
-
raise str
|
45
|
-
end
|
46
|
-
|
36
|
+
|
47
37
|
end
|
48
38
|
end
|
49
39
|
end
|
data/lib/funnel/server.rb
CHANGED
@@ -8,6 +8,8 @@ module Funnel
|
|
8
8
|
EM.epoll if EM.epoll?
|
9
9
|
EM.kqueue if EM.kqueue?
|
10
10
|
|
11
|
+
Log.info "Starting Funnel Server..."
|
12
|
+
|
11
13
|
EM.run do
|
12
14
|
|
13
15
|
trap("TERM") { stop }
|
@@ -15,10 +17,12 @@ module Funnel
|
|
15
17
|
|
16
18
|
EM.start_server(host, port, Routing::Router)
|
17
19
|
|
20
|
+
Log.info "Server Listening on #{host}:#{port}"
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
24
|
def self.stop
|
25
|
+
Log.info "Funnel Server Shutting Down"
|
22
26
|
EM.stop
|
23
27
|
end
|
24
28
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Funnel
|
2
2
|
module WebSocket
|
3
|
-
|
3
|
+
|
4
4
|
class Connection < EM::Connection
|
5
5
|
|
6
6
|
attr_accessor :headers
|
@@ -8,44 +8,39 @@ module Funnel
|
|
8
8
|
###
|
9
9
|
# helper methods
|
10
10
|
###
|
11
|
-
|
11
|
+
|
12
12
|
def cookies
|
13
13
|
@headers[:cookies]
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def host
|
17
17
|
@headers[:host]
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def origin
|
21
21
|
@headers[:origin]
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def path
|
25
25
|
@headers[:path]
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def protocol
|
29
29
|
@headers[:websocket_protocol]
|
30
30
|
end
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
|
34
32
|
#override this
|
35
33
|
def on_ready
|
36
|
-
puts "Connect"
|
37
34
|
end
|
38
|
-
|
35
|
+
|
39
36
|
#override this
|
40
37
|
def on_disconnect
|
41
|
-
puts "Disconnect"
|
42
38
|
end
|
43
|
-
|
39
|
+
|
44
40
|
#override this
|
45
41
|
def on_data data
|
46
|
-
puts "Data"
|
47
42
|
end
|
48
|
-
|
43
|
+
|
49
44
|
#called from EM
|
50
45
|
def unbind
|
51
46
|
on_disconnect
|
@@ -59,13 +54,15 @@ module Funnel
|
|
59
54
|
|
60
55
|
#called from EM
|
61
56
|
def receive_data data
|
62
|
-
|
57
|
+
while msg = data.slice!(/\000([^\377]*)\377/)
|
58
|
+
on_data Frame.decode(msg)
|
59
|
+
end
|
63
60
|
end
|
64
61
|
|
65
62
|
def send_message msg
|
66
63
|
send_data Frame.encode(msg)
|
67
64
|
end
|
68
|
-
|
65
|
+
|
69
66
|
end
|
70
67
|
end
|
71
68
|
end
|
@@ -4,7 +4,7 @@ FUNNEL_ROOT = File.expand_path("../../", __FILE__)
|
|
4
4
|
require "rubygems"
|
5
5
|
require "funnel"
|
6
6
|
|
7
|
-
Funnel::Configuration.load("config/settings.
|
7
|
+
Funnel::Configuration.load("config/settings.yml")
|
8
8
|
|
9
9
|
#load handlers defined by user
|
10
10
|
handlers = Dir.entries(FUNNEL_ROOT + "/handlers").select { |n| not n =~ /^\.+$/ }
|
@@ -20,4 +20,6 @@ require "routes"
|
|
20
20
|
Funnel::Server.start(
|
21
21
|
Funnel::Configuration.get(:host),
|
22
22
|
Funnel::Configuration.get(:port)
|
23
|
-
)
|
23
|
+
)
|
24
|
+
|
25
|
+
Funnel::Log.debug!
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Funnel
|
2
|
+
|
3
|
+
class DebugHandler < Funnel::WebSocket::Connection
|
4
|
+
|
5
|
+
#called when the connection is ready to send
|
6
|
+
#and receive data
|
7
|
+
def on_ready
|
8
|
+
Log.info "A connection has been established"
|
9
|
+
end
|
10
|
+
|
11
|
+
#called on disconnect
|
12
|
+
def on_disconnect
|
13
|
+
Log.info "A connection has been closed"
|
14
|
+
end
|
15
|
+
|
16
|
+
#right back at you
|
17
|
+
def on_data msg
|
18
|
+
Log.info "A message was received #{msg}"
|
19
|
+
send_message msg
|
20
|
+
Log.info "A message was sent #{msg}"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Funnel Test</title>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
|
8
|
+
|
9
|
+
<h1>Funnel Test</h1>
|
10
|
+
<div id="info">Connecting....</div>
|
11
|
+
|
12
|
+
<script>
|
13
|
+
|
14
|
+
var webSocket = new WebSocket("ws://localhost:4000/");
|
15
|
+
|
16
|
+
webSocket.onopen = function(event){
|
17
|
+
document.getElementById("info").innerHTML += "<br/>Connection Open";
|
18
|
+
};
|
19
|
+
|
20
|
+
webSocket.onmessage = function(event){
|
21
|
+
document.getElementById("info").innerHTML += "<br/>" + event.data;
|
22
|
+
};
|
23
|
+
|
24
|
+
webSocket.onclose = function(event){
|
25
|
+
document.getElementById("info").innerHTML += "<br/>Connection Closed";
|
26
|
+
};
|
27
|
+
|
28
|
+
</script>
|
29
|
+
|
30
|
+
<a href="#" onclick="webSocket.send("test")">Send Test Message</a>
|
31
|
+
|
32
|
+
</body>
|
33
|
+
</html>
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 8
|
9
|
+
version: 0.1.8
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Dan Simpson
|
@@ -43,7 +43,7 @@ files:
|
|
43
43
|
- README.markdown
|
44
44
|
- funnel.gemspec
|
45
45
|
- lib/funnel.rb
|
46
|
-
- lib/funnel/
|
46
|
+
- lib/funnel/log.rb
|
47
47
|
- lib/funnel/configuration.rb
|
48
48
|
- lib/funnel/flash/policy.rb
|
49
49
|
- lib/funnel/web_socket/frame.rb
|
@@ -58,7 +58,8 @@ files:
|
|
58
58
|
- templates/application/config/settings.yml
|
59
59
|
- templates/application/config/routes.rb
|
60
60
|
- templates/application/script/server
|
61
|
-
- templates/application/
|
61
|
+
- templates/application/htdocs/test.html
|
62
|
+
- templates/application/handlers/debug_handler.rb
|
62
63
|
has_rdoc: true
|
63
64
|
homepage: http://github.com/dansimpson/funnel
|
64
65
|
licenses: []
|
data/lib/funnel/logger.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
class Logger
|
2
|
-
|
3
|
-
@@threshhold = 3
|
4
|
-
|
5
|
-
def self.info msg
|
6
|
-
log msg if @@threshhold <= 3
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.debug msf
|
10
|
-
log msg if @@threshhold <= 1
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.warning msg
|
14
|
-
log msg if @@threshhold <= 2
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def self.log msg
|
20
|
-
p "#{Time.now} - #{msg}"
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class TestHandler < Funnel::WebSocket::Connection
|
2
|
-
|
3
|
-
#called when the connection is ready to send
|
4
|
-
#and receive data
|
5
|
-
def on_ready
|
6
|
-
puts "A connection has been established"
|
7
|
-
end
|
8
|
-
|
9
|
-
#called on disconnect
|
10
|
-
def on_disconnect
|
11
|
-
puts "A connection has been closed"
|
12
|
-
end
|
13
|
-
|
14
|
-
#right back at you
|
15
|
-
def on_data msg
|
16
|
-
puts "A message was received #{msg}"
|
17
|
-
send_message msg
|
18
|
-
puts "A message was sent #{msg}"
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|