funnel 0.1.6 → 0.1.8
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.
- 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
|