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.
@@ -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