funnel 0.1.6 → 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'funnel'
3
- s.version = '0.1.6'
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/logger.rb',
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/handlers/test_handler.rb',
36
+ 'templates/application/htdocs/test.html',
37
+ 'templates/application/handlers/debug_handler.rb',
37
38
  ]
38
39
  end
@@ -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/logger.rb'
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'
@@ -15,8 +15,8 @@ module Funnel
15
15
  def self.put key, val
16
16
  @@map[key.to_sym] = val
17
17
  end
18
-
19
- def self.parse file
18
+
19
+ def self.load file
20
20
  begin
21
21
  settings = YAML.load_file(File.join(FUNNEL_ROOT, file))
22
22
  settings.each do |key, val|
@@ -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 << "<allow-access-from domain=\"*\" to-ports=\"#{settings.get(:port)}\"/>")
16
+ response << allow_tag("*")
17
17
  else
18
18
  accepted.each do |domain|
19
- response << "<allow-access-from domain=\"#{domain}\" to-ports=\"#{settings.get(:port)}\"/>")
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
@@ -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
- if valid_connection? && valid_origin?
18
- accept_connection
19
- defer_connection
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 = Routes.get_handler(path).send(:new, @signature)
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
- raise_no_default_error unless @routes.key?(:default)
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 : @routes[:default].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
@@ -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
- on_data Frame.decode(data)
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.yaml")
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!
@@ -1,3 +1,3 @@
1
1
  Funnel::Routing::Routes.draw do |map|
2
- map.default :handler => Funnel::Servers::DummyServer
2
+ map.default :handler => Funnel::DebugHandler
3
3
  end
@@ -1,5 +1,2 @@
1
1
  host: 0.0.0.0
2
- port: 4000
3
- accepted_origins:
4
- - localhost
5
- - test.com
2
+ port: 4000
@@ -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
- - 6
9
- version: 0.1.6
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/logger.rb
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/handlers/test_handler.rb
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: []
@@ -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