strelka 0.6.0 → 0.7.0
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.
- checksums.yaml +4 -4
 - checksums.yaml.gz.sig +0 -0
 - data/ChangeLog +156 -9
 - data/History.rdoc +15 -0
 - data/IDEAS.rdoc +17 -1
 - data/MILESTONES.rdoc +1 -1
 - data/Manifest.txt +10 -2
 - data/Plugins.rdoc +4 -4
 - data/README.rdoc +3 -3
 - data/Rakefile +5 -4
 - data/bin/strelka +19 -10
 - data/contrib/hoetemplate/data/project/apps/file_name_app +1 -0
 - data/contrib/hoetemplate/lib/file_name.rb.erb +3 -2
 - data/examples/apps/hello-world +1 -0
 - data/examples/apps/ws-chat +69 -0
 - data/examples/apps/ws-echo +61 -0
 - data/examples/gen-config.rb +6 -5
 - data/lib/strelka/app/auth.rb +2 -2
 - data/lib/strelka/app/errors.rb +1 -1
 - data/lib/strelka/app/filters.rb +3 -2
 - data/lib/strelka/app/negotiation.rb +2 -2
 - data/lib/strelka/app/parameters.rb +1 -2
 - data/lib/strelka/app/restresources.rb +3 -2
 - data/lib/strelka/app/routing.rb +1 -1
 - data/lib/strelka/app/sessions.rb +2 -2
 - data/lib/strelka/app/templating.rb +7 -3
 - data/lib/strelka/app.rb +5 -145
 - data/lib/strelka/behavior/plugin.rb +4 -4
 - data/lib/strelka/discovery.rb +211 -0
 - data/lib/strelka/httprequest.rb +1 -0
 - data/lib/strelka/httpresponse/negotiation.rb +7 -1
 - data/lib/strelka/mixins.rb +4 -1
 - data/lib/strelka/paramvalidator.rb +1 -1
 - data/lib/strelka/plugins.rb +8 -6
 - data/lib/strelka/websocketserver/routing.rb +116 -0
 - data/lib/strelka/websocketserver.rb +147 -0
 - data/lib/strelka.rb +5 -4
 - data/spec/{lib/constants.rb → constants.rb} +3 -2
 - data/spec/{lib/helpers.rb → helpers.rb} +15 -14
 - data/spec/strelka/app/auth_spec.rb +145 -142
 - data/spec/strelka/app/errors_spec.rb +20 -26
 - data/spec/strelka/app/filters_spec.rb +67 -54
 - data/spec/strelka/app/negotiation_spec.rb +8 -14
 - data/spec/strelka/app/parameters_spec.rb +23 -29
 - data/spec/strelka/app/restresources_spec.rb +98 -100
 - data/spec/strelka/app/routing_spec.rb +57 -57
 - data/spec/strelka/app/sessions_spec.rb +11 -17
 - data/spec/strelka/app/templating_spec.rb +36 -40
 - data/spec/strelka/app_spec.rb +48 -147
 - data/spec/strelka/authprovider/basic_spec.rb +5 -11
 - data/spec/strelka/authprovider/hostaccess_spec.rb +9 -15
 - data/spec/strelka/authprovider_spec.rb +3 -9
 - data/spec/strelka/cookie_spec.rb +32 -38
 - data/spec/strelka/cookieset_spec.rb +31 -37
 - data/spec/strelka/discovery_spec.rb +144 -0
 - data/spec/strelka/exceptions_spec.rb +2 -8
 - data/spec/strelka/httprequest/acceptparams_spec.rb +74 -83
 - data/spec/strelka/httprequest/auth_spec.rb +5 -15
 - data/spec/strelka/httprequest/negotiation_spec.rb +93 -103
 - data/spec/strelka/httprequest/session_spec.rb +12 -22
 - data/spec/strelka/httprequest_spec.rb +1 -7
 - data/spec/strelka/httpresponse/negotiation_spec.rb +84 -76
 - data/spec/strelka/httpresponse/session_spec.rb +25 -35
 - data/spec/strelka/httpresponse_spec.rb +20 -26
 - data/spec/strelka/mixins_spec.rb +66 -61
 - data/spec/strelka/multipartparser_spec.rb +31 -37
 - data/spec/strelka/paramvalidator_spec.rb +389 -373
 - data/spec/strelka/plugins_spec.rb +17 -23
 - data/spec/strelka/router/default_spec.rb +32 -38
 - data/spec/strelka/router/exclusive_spec.rb +28 -34
 - data/spec/strelka/router_spec.rb +2 -8
 - data/spec/strelka/session/db_spec.rb +17 -15
 - data/spec/strelka/session/default_spec.rb +22 -28
 - data/spec/strelka/session_spec.rb +3 -9
 - data/spec/strelka/websocketserver/routing_spec.rb +119 -0
 - data/spec/strelka/websocketserver_spec.rb +149 -0
 - data/spec/strelka_spec.rb +11 -13
 - data.tar.gz.sig +3 -3
 - metadata +22 -14
 - metadata.gz.sig +0 -0
 
| 
         @@ -0,0 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- ruby -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            # vim: set nosta noet ts=4 sw=4:
         
     | 
| 
      
 3 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'strelka' unless defined?( Strelka )
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'strelka/websocketserver' unless defined?( Strelka::WebSocketServer )
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'strelka/plugin' unless defined?( Strelka::Plugin )
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # Frame routing logic for Strelka WebSocketServers.
         
     | 
| 
      
 10 
     | 
    
         
            +
            #
         
     | 
| 
      
 11 
     | 
    
         
            +
            # For a protocol that defines its own opcodes:
         
     | 
| 
      
 12 
     | 
    
         
            +
            #
         
     | 
| 
      
 13 
     | 
    
         
            +
            #    class ChatServer
         
     | 
| 
      
 14 
     | 
    
         
            +
            #        plugin :routing
         
     | 
| 
      
 15 
     | 
    
         
            +
            #
         
     | 
| 
      
 16 
     | 
    
         
            +
            #        opcodes :nick => 7,
         
     | 
| 
      
 17 
     | 
    
         
            +
            #                :emote => 8
         
     | 
| 
      
 18 
     | 
    
         
            +
            #
         
     | 
| 
      
 19 
     | 
    
         
            +
            #        on_text do |frame|
         
     | 
| 
      
 20 
     | 
    
         
            +
            #            # ...
         
     | 
| 
      
 21 
     | 
    
         
            +
            #        end
         
     | 
| 
      
 22 
     | 
    
         
            +
            #
         
     | 
| 
      
 23 
     | 
    
         
            +
            #        on_nick do |frame|
         
     | 
| 
      
 24 
     | 
    
         
            +
            #            self.set_nick( frame.socket_id, frame.payload.read )
         
     | 
| 
      
 25 
     | 
    
         
            +
            #        end
         
     | 
| 
      
 26 
     | 
    
         
            +
            #
         
     | 
| 
      
 27 
     | 
    
         
            +
            #
         
     | 
| 
      
 28 
     | 
    
         
            +
            module Strelka::WebSocketServer::Routing
         
     | 
| 
      
 29 
     | 
    
         
            +
            	extend Loggability,
         
     | 
| 
      
 30 
     | 
    
         
            +
            	       Strelka::Plugin
         
     | 
| 
      
 31 
     | 
    
         
            +
            	include Strelka::Constants,
         
     | 
| 
      
 32 
     | 
    
         
            +
            	        Mongrel2::WebSocket::Constants
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            	# Loggability API -- set up logging under the 'strelka' log host
         
     | 
| 
      
 36 
     | 
    
         
            +
            	log_to :strelka
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            	# Plugins API -- set up load order
         
     | 
| 
      
 39 
     | 
    
         
            +
            	# run_inside :templating, :filters, :parameters
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            	# Class methods to add to classes with routing.
         
     | 
| 
      
 43 
     | 
    
         
            +
            	module ClassMethods # :nodoc:
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            		# The list of routes to pass to the Router when the application is created
         
     | 
| 
      
 46 
     | 
    
         
            +
            		attr_reader :op_callbacks
         
     | 
| 
      
 47 
     | 
    
         
            +
            		@op_callbacks = {}
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            		# The Hash of opcodes that can be hooked
         
     | 
| 
      
 50 
     | 
    
         
            +
            		attr_reader :opcode_map
         
     | 
| 
      
 51 
     | 
    
         
            +
            		@opcode_map = {}
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            		### Declare one or more opcodes in the form:
         
     | 
| 
      
 55 
     | 
    
         
            +
            		###
         
     | 
| 
      
 56 
     | 
    
         
            +
            		### {
         
     | 
| 
      
 57 
     | 
    
         
            +
            		###     <bit> => <label>,
         
     | 
| 
      
 58 
     | 
    
         
            +
            		### }
         
     | 
| 
      
 59 
     | 
    
         
            +
            		def opcodes( hash )
         
     | 
| 
      
 60 
     | 
    
         
            +
            			@opcode_map ||= {}
         
     | 
| 
      
 61 
     | 
    
         
            +
            			@opcode_map.merge!( hash )
         
     | 
| 
      
 62 
     | 
    
         
            +
            			@opcode_map.each do |bit, label|
         
     | 
| 
      
 63 
     | 
    
         
            +
            				self.log.debug "Set opcode %p to %#0x" % [ label, bit ]
         
     | 
| 
      
 64 
     | 
    
         
            +
            				declarative = "on_#{label}"
         
     | 
| 
      
 65 
     | 
    
         
            +
            				block = self.make_declarative( label )
         
     | 
| 
      
 66 
     | 
    
         
            +
            				self.log.debug "  declaring method %p on %p" % [ declarative, self ]
         
     | 
| 
      
 67 
     | 
    
         
            +
            				self.class.send( :define_method, declarative, &block )
         
     | 
| 
      
 68 
     | 
    
         
            +
            			end
         
     | 
| 
      
 69 
     | 
    
         
            +
            		end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            		### Make a declarative method for setting the callback for frames with the specified
         
     | 
| 
      
 73 
     | 
    
         
            +
            		### +opcode+ (Symbol).
         
     | 
| 
      
 74 
     | 
    
         
            +
            		def make_declarative( opcode )
         
     | 
| 
      
 75 
     | 
    
         
            +
            			self.log.debug "Making a declarative for %p" % [ opcode ]
         
     | 
| 
      
 76 
     | 
    
         
            +
            			return lambda do |&block|
         
     | 
| 
      
 77 
     | 
    
         
            +
            				self.log.debug "Setting handler for %p frames to %p" % [ opcode, block ]
         
     | 
| 
      
 78 
     | 
    
         
            +
            				methodname = "on_#{opcode}_frame"
         
     | 
| 
      
 79 
     | 
    
         
            +
            				define_method( methodname, &block )
         
     | 
| 
      
 80 
     | 
    
         
            +
            				self.op_callbacks[ opcode ] = self.instance_method( methodname )
         
     | 
| 
      
 81 
     | 
    
         
            +
            			end
         
     | 
| 
      
 82 
     | 
    
         
            +
            		end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            		### Inheritance hook -- inheriting classes inherit their parents' routes table.
         
     | 
| 
      
 86 
     | 
    
         
            +
            		def inherited( subclass )
         
     | 
| 
      
 87 
     | 
    
         
            +
            			super
         
     | 
| 
      
 88 
     | 
    
         
            +
            			subclass.instance_variable_set( :@opcode_map, self.opcode_map.dup )
         
     | 
| 
      
 89 
     | 
    
         
            +
            			subclass.instance_variable_set( :@op_callbacks, self.op_callbacks.dup )
         
     | 
| 
      
 90 
     | 
    
         
            +
            		end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            		### Extension callback -- install default opcode declaratives when the plugin
         
     | 
| 
      
 94 
     | 
    
         
            +
            		### is registered.
         
     | 
| 
      
 95 
     | 
    
         
            +
            		def self::extended( mod )
         
     | 
| 
      
 96 
     | 
    
         
            +
            			super
         
     | 
| 
      
 97 
     | 
    
         
            +
            			mod.opcodes( Mongrel2::WebSocket::Constants::OPCODE_NAME )
         
     | 
| 
      
 98 
     | 
    
         
            +
            		end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
            	end # module ClassMethods
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            	### Dispatch the incoming frame to its handler based on its opcode
         
     | 
| 
      
 105 
     | 
    
         
            +
            	def handle_frame( frame )
         
     | 
| 
      
 106 
     | 
    
         
            +
            		self.log.debug "[:routing] Opcode map is: %p" % [ self.class.opcode_map ]
         
     | 
| 
      
 107 
     | 
    
         
            +
            		opname = self.class.opcode_map[ frame.numeric_opcode ]
         
     | 
| 
      
 108 
     | 
    
         
            +
            		self.log.debug "[:routing] Routing frame: %p" % [ opname ]
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            		handler = self.class.op_callbacks[ opname ] or return super
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            		return handler.bind( self ).call( frame )
         
     | 
| 
      
 113 
     | 
    
         
            +
            	end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            end # module Strelka::WebSocketServer::Routing
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,147 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- ruby -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            # vim: set nosta noet ts=4 sw=4:
         
     | 
| 
      
 3 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            require 'mongrel2/handler'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'mongrel2/websocket'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require 'strelka' unless defined?( Strelka )
         
     | 
| 
      
 9 
     | 
    
         
            +
            require 'strelka/mixins'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'strelka/plugins'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'strelka/discovery'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            # WebSocket (RFC 6455) Server base class.
         
     | 
| 
      
 15 
     | 
    
         
            +
            #
         
     | 
| 
      
 16 
     | 
    
         
            +
            #   class ChatServer < Strelka::WebSocketServer
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            #       # Set up a Hash for participating users
         
     | 
| 
      
 19 
     | 
    
         
            +
            #       def initialize( * )
         
     | 
| 
      
 20 
     | 
    
         
            +
            #           super
         
     | 
| 
      
 21 
     | 
    
         
            +
            #           @users = {}
         
     | 
| 
      
 22 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 23 
     | 
    
         
            +
            #
         
     | 
| 
      
 24 
     | 
    
         
            +
            #       # Disconnect clients that don't answer a ping
         
     | 
| 
      
 25 
     | 
    
         
            +
            #       plugin :heartbeat
         
     | 
| 
      
 26 
     | 
    
         
            +
            #       heartbeat_rate 5.0
         
     | 
| 
      
 27 
     | 
    
         
            +
            #       idle_timeout 15.0
         
     | 
| 
      
 28 
     | 
    
         
            +
            #
         
     | 
| 
      
 29 
     | 
    
         
            +
            #       # When a websocket is set up, add a new user to the table, but without a nick.
         
     | 
| 
      
 30 
     | 
    
         
            +
            #       on_handshake do |frame|
         
     | 
| 
      
 31 
     | 
    
         
            +
            #           @users[ frame.socket_id ] = nil
         
     | 
| 
      
 32 
     | 
    
         
            +
            #           return frame.response # accept the connection
         
     | 
| 
      
 33 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 34 
     | 
    
         
            +
            #
         
     | 
| 
      
 35 
     | 
    
         
            +
            #       # Handle incoming commands, which should be text frames
         
     | 
| 
      
 36 
     | 
    
         
            +
            #       on_text do |frame|
         
     | 
| 
      
 37 
     | 
    
         
            +
            #           senderid = frame.socket_id
         
     | 
| 
      
 38 
     | 
    
         
            +
            #           data = frame.payload.read
         
     | 
| 
      
 39 
     | 
    
         
            +
            #
         
     | 
| 
      
 40 
     | 
    
         
            +
            #           # If the input starts with '/', it's a command (e.g., /quit, /nick, etc.)
         
     | 
| 
      
 41 
     | 
    
         
            +
            #           output = nil
         
     | 
| 
      
 42 
     | 
    
         
            +
            #           if data.start_with?( '/' )
         
     | 
| 
      
 43 
     | 
    
         
            +
            #               output = self.command( senderid, data[1..-1] )
         
     | 
| 
      
 44 
     | 
    
         
            +
            #           else
         
     | 
| 
      
 45 
     | 
    
         
            +
            #               output = self.say( senderid, data )
         
     | 
| 
      
 46 
     | 
    
         
            +
            #           end
         
     | 
| 
      
 47 
     | 
    
         
            +
            #
         
     | 
| 
      
 48 
     | 
    
         
            +
            #           response = frame.response
         
     | 
| 
      
 49 
     | 
    
         
            +
            #           response.puts( output )
         
     | 
| 
      
 50 
     | 
    
         
            +
            #           return response
         
     | 
| 
      
 51 
     | 
    
         
            +
            #       end
         
     | 
| 
      
 52 
     | 
    
         
            +
            #
         
     | 
| 
      
 53 
     | 
    
         
            +
            #   end # class ChatServer
         
     | 
| 
      
 54 
     | 
    
         
            +
            #
         
     | 
| 
      
 55 
     | 
    
         
            +
            class Strelka::WebSocketServer < Mongrel2::Handler
         
     | 
| 
      
 56 
     | 
    
         
            +
            	extend Strelka::MethodUtilities,
         
     | 
| 
      
 57 
     | 
    
         
            +
            	       Strelka::PluginLoader,
         
     | 
| 
      
 58 
     | 
    
         
            +
            		   Strelka::Discovery
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            	# Loggability API -- log to the Strelka logger
         
     | 
| 
      
 62 
     | 
    
         
            +
            	log_to :strelka
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            	### Handle a WebSocket frame in +request+. If not overridden, WebSocket connections are
         
     | 
| 
      
 66 
     | 
    
         
            +
            	### closed with a policy error status.
         
     | 
| 
      
 67 
     | 
    
         
            +
            	def handle_websocket( frame )
         
     | 
| 
      
 68 
     | 
    
         
            +
            		response = nil
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            		# Dispatch the frame
         
     | 
| 
      
 71 
     | 
    
         
            +
            		response = catch( :close_websocket ) do
         
     | 
| 
      
 72 
     | 
    
         
            +
            			self.log.debug "Incoming WEBSOCKET frame (%p):%s" % [ frame, frame.headers.path ]
         
     | 
| 
      
 73 
     | 
    
         
            +
            			self.handle_frame( frame )
         
     | 
| 
      
 74 
     | 
    
         
            +
            		end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            		return response
         
     | 
| 
      
 77 
     | 
    
         
            +
            	end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            	### Handle a WebSocket handshake HTTP +request+.
         
     | 
| 
      
 81 
     | 
    
         
            +
            	def handle_websocket_handshake( handshake )
         
     | 
| 
      
 82 
     | 
    
         
            +
            		self.log.warn "Incoming WEBSOCKET_HANDSHAKE request (%p)" % [ request.headers.path ]
         
     | 
| 
      
 83 
     | 
    
         
            +
            		return handshake.response( handshake.protocols.first )
         
     | 
| 
      
 84 
     | 
    
         
            +
            	end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            	### Handle a disconnect notice from Mongrel2 via the given +request+. Its return value
         
     | 
| 
      
 88 
     | 
    
         
            +
            	### is ignored.
         
     | 
| 
      
 89 
     | 
    
         
            +
            	def handle_disconnect( request )
         
     | 
| 
      
 90 
     | 
    
         
            +
            		self.log.info "Unhandled disconnect notice."
         
     | 
| 
      
 91 
     | 
    
         
            +
            		return nil
         
     | 
| 
      
 92 
     | 
    
         
            +
            	end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            	#########
         
     | 
| 
      
 96 
     | 
    
         
            +
            	protected
         
     | 
| 
      
 97 
     | 
    
         
            +
            	#########
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            	### Default frame handler.
         
     | 
| 
      
 100 
     | 
    
         
            +
            	def handle_frame( frame )
         
     | 
| 
      
 101 
     | 
    
         
            +
            		if frame.control?
         
     | 
| 
      
 102 
     | 
    
         
            +
            			self.handle_control_frame( frame )
         
     | 
| 
      
 103 
     | 
    
         
            +
            		else
         
     | 
| 
      
 104 
     | 
    
         
            +
            			self.handle_content_frame( frame )
         
     | 
| 
      
 105 
     | 
    
         
            +
            		end
         
     | 
| 
      
 106 
     | 
    
         
            +
            	end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            	### Throw a :close_websocket frame that will close the current connection.
         
     | 
| 
      
 110 
     | 
    
         
            +
            	def close_with( frame, reason )
         
     | 
| 
      
 111 
     | 
    
         
            +
            		self.log.debug "Closing the connection: %p" % [ reason ]
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            		# Make a CLOSE frame
         
     | 
| 
      
 114 
     | 
    
         
            +
            		frame = frame.response( :close )
         
     | 
| 
      
 115 
     | 
    
         
            +
            		frame.set_status( reason )
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            		throw :close_websocket, frame
         
     | 
| 
      
 118 
     | 
    
         
            +
            	end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            	### Handle an incoming control frame.
         
     | 
| 
      
 122 
     | 
    
         
            +
            	def handle_control_frame( frame )
         
     | 
| 
      
 123 
     | 
    
         
            +
            		self.log.debug "Handling control frame: %p" % [ frame ]
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            		case frame.opcode
         
     | 
| 
      
 126 
     | 
    
         
            +
            		when :ping
         
     | 
| 
      
 127 
     | 
    
         
            +
            			return frame.response
         
     | 
| 
      
 128 
     | 
    
         
            +
            		when :pong
         
     | 
| 
      
 129 
     | 
    
         
            +
            			return nil
         
     | 
| 
      
 130 
     | 
    
         
            +
            		when :close
         
     | 
| 
      
 131 
     | 
    
         
            +
            			self.conn.reply_close( frame )
         
     | 
| 
      
 132 
     | 
    
         
            +
            			return nil
         
     | 
| 
      
 133 
     | 
    
         
            +
            		else
         
     | 
| 
      
 134 
     | 
    
         
            +
            			self.close_with( frame, CLOSE_BAD_DATA_TYPE )
         
     | 
| 
      
 135 
     | 
    
         
            +
            		end
         
     | 
| 
      
 136 
     | 
    
         
            +
            	end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            	### Handle an incoming content frame.
         
     | 
| 
      
 140 
     | 
    
         
            +
            	def handle_content_frame( frame )
         
     | 
| 
      
 141 
     | 
    
         
            +
            		self.log.warn "Unhandled frame type %p" % [ frame.opcode ]
         
     | 
| 
      
 142 
     | 
    
         
            +
            		self.close_with( frame, CLOSE_BAD_DATA_TYPE )
         
     | 
| 
      
 143 
     | 
    
         
            +
            	end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            end # class Strelka::WebSocketServer
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
    
        data/lib/strelka.rb
    CHANGED
    
    | 
         @@ -24,10 +24,10 @@ module Strelka 
     | 
|
| 
       24 
24 
     | 
    
         
             
            	log_as :strelka
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            	# Library version constant
         
     | 
| 
       27 
     | 
    
         
            -
            	VERSION = '0. 
     | 
| 
      
 27 
     | 
    
         
            +
            	VERSION = '0.7.0'
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
            	# Version-control revision constant
         
     | 
| 
       30 
     | 
    
         
            -
            	REVISION = %q$Revision:  
     | 
| 
      
 30 
     | 
    
         
            +
            	REVISION = %q$Revision: 2caa91898658 $
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
            	require 'strelka/constants'
         
     | 
| 
       33 
33 
     | 
    
         
             
            	require 'strelka/exceptions'
         
     | 
| 
         @@ -36,6 +36,7 @@ module Strelka 
     | 
|
| 
       36 
36 
     | 
    
         
             
            	require 'strelka/app'
         
     | 
| 
       37 
37 
     | 
    
         
             
            	require 'strelka/httprequest'
         
     | 
| 
       38 
38 
     | 
    
         
             
            	require 'strelka/httpresponse'
         
     | 
| 
      
 39 
     | 
    
         
            +
            	require 'strelka/discovery'
         
     | 
| 
       39 
40 
     | 
    
         | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
42 
     | 
    
         
             
            	### Get the library version. If +include_buildnum+ is true, the version string will
         
     | 
| 
         @@ -67,10 +68,10 @@ module Strelka 
     | 
|
| 
       67 
68 
     | 
    
         
             
            	### named +gemname+. Returns the first matching class, or raises an exception if no
         
     | 
| 
       68 
69 
     | 
    
         
             
            	### app class was found.
         
     | 
| 
       69 
70 
     | 
    
         
             
            	def self::App( appname, gemname=nil )
         
     | 
| 
       70 
     | 
    
         
            -
            		path, _ = Strelka:: 
     | 
| 
      
 71 
     | 
    
         
            +
            		path, _ = Strelka::Discovery.find( appname, gemname )
         
     | 
| 
       71 
72 
     | 
    
         
             
            		raise LoadError, "Can't find the %s app." % [ appname ] unless path
         
     | 
| 
       72 
73 
     | 
    
         | 
| 
       73 
     | 
    
         
            -
            		apps = Strelka:: 
     | 
| 
      
 74 
     | 
    
         
            +
            		apps = Strelka::Discovery.load( path ) or
         
     | 
| 
       74 
75 
     | 
    
         
             
            			raise ScriptError "Loading %s didn't define a Strelka::App class." % [ path ]
         
     | 
| 
       75 
76 
     | 
    
         | 
| 
       76 
77 
     | 
    
         
             
            		return apps.first
         
     | 
| 
         @@ -8,7 +8,8 @@ require 'strelka' unless defined?( Strelka ) 
     | 
|
| 
       8 
8 
     | 
    
         
             
            ### A collection of constants used in testing
         
     | 
| 
       9 
9 
     | 
    
         
             
            module Strelka::TestConstants # :nodoc:all
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            	include Strelka::Constants
         
     | 
| 
      
 11 
     | 
    
         
            +
            	include Strelka::Constants,
         
     | 
| 
      
 12 
     | 
    
         
            +
            	        Mongrel2::WebSocket::Constants
         
     | 
| 
       12 
13 
     | 
    
         | 
| 
       13 
14 
     | 
    
         
             
            	unless defined?( TEST_HOST )
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
         @@ -24,7 +25,7 @@ module Strelka::TestConstants # :nodoc:all 
     | 
|
| 
       24 
25 
     | 
    
         | 
| 
       25 
26 
     | 
    
         
             
            		# Freeze all testing constants
         
     | 
| 
       26 
27 
     | 
    
         
             
            		constants.each do |cname|
         
     | 
| 
       27 
     | 
    
         
            -
            			const_get(cname).freeze
         
     | 
| 
      
 28 
     | 
    
         
            +
            			const_get(cname).freeze if cname.to_s.start_with?( 'TEST_' )
         
     | 
| 
       28 
29 
     | 
    
         
             
            		end
         
     | 
| 
       29 
30 
     | 
    
         
             
            	end
         
     | 
| 
       30 
31 
     | 
    
         | 
| 
         @@ -8,11 +8,8 @@ BEGIN { 
     | 
|
| 
       8 
8 
     | 
    
         
             
            	srcdir = basedir.parent
         
     | 
| 
       9 
9 
     | 
    
         
             
            	mongrel2dir = srcdir + 'Mongrel2/lib'
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            	 
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            	$LOAD_PATH.unshift( mongrel2dir.to_s ) unless $LOAD_PATH.include?( mongrel2dir.to_s )
         
     | 
| 
       14 
     | 
    
         
            -
            	$LOAD_PATH.unshift( basedir.to_s ) unless $LOAD_PATH.include?( basedir.to_s )
         
     | 
| 
       15 
     | 
    
         
            -
            	$LOAD_PATH.unshift( libdir.to_s ) unless $LOAD_PATH.include?( libdir.to_s )
         
     | 
| 
      
 11 
     | 
    
         
            +
            	$LOAD_PATH.unshift( mongrel2dir.to_s ) unless
         
     | 
| 
      
 12 
     | 
    
         
            +
            		!mongrel2dir.directory? || $LOAD_PATH.include?( mongrel2dir.to_s )
         
     | 
| 
       16 
13 
     | 
    
         
             
            }
         
     | 
| 
       17 
14 
     | 
    
         | 
| 
       18 
15 
     | 
    
         
             
            # SimpleCov test coverage reporting; enable this using the :coverage rake task
         
     | 
| 
         @@ -40,7 +37,7 @@ require 'mongrel2/testing' 
     | 
|
| 
       40 
37 
     | 
    
         
             
            require 'strelka'
         
     | 
| 
       41 
38 
     | 
    
         
             
            require 'strelka/testing'
         
     | 
| 
       42 
39 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
            require_relative 'constants'
         
     | 
| 
       44 
41 
     | 
    
         | 
| 
       45 
42 
     | 
    
         
             
            Loggability.format_with( :color ) if $stdout.tty?
         
     | 
| 
       46 
43 
     | 
    
         | 
| 
         @@ -103,19 +100,23 @@ module Strelka::SpecHelpers 
     | 
|
| 
       103 
100 
     | 
    
         
             
            end
         
     | 
| 
       104 
101 
     | 
    
         | 
| 
       105 
102 
     | 
    
         | 
| 
       106 
     | 
    
         
            -
            abort "You need a version of RSpec >= 2.6.0" unless defined?( RSpec )
         
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
103 
     | 
    
         
             
            ### Mock with RSpec
         
     | 
| 
       109 
     | 
    
         
            -
            RSpec.configure do | 
     | 
| 
      
 104 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
       110 
105 
     | 
    
         
             
            	include Strelka::TestConstants
         
     | 
| 
       111 
106 
     | 
    
         | 
| 
       112 
     | 
    
         
            -
            	 
     | 
| 
      
 107 
     | 
    
         
            +
            	config.treat_symbols_as_metadata_keys_with_true_values = true
         
     | 
| 
      
 108 
     | 
    
         
            +
            	config.run_all_when_everything_filtered = true
         
     | 
| 
      
 109 
     | 
    
         
            +
            	config.filter_run :focus
         
     | 
| 
      
 110 
     | 
    
         
            +
            	config.order = 'random'
         
     | 
| 
      
 111 
     | 
    
         
            +
            	config.mock_with( :rspec ) do |mock|
         
     | 
| 
      
 112 
     | 
    
         
            +
            		mock.syntax = :expect
         
     | 
| 
      
 113 
     | 
    
         
            +
            	end
         
     | 
| 
       113 
114 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
            	 
     | 
| 
      
 115 
     | 
    
         
            +
            	config.extend( Strelka::TestConstants )
         
     | 
| 
       115 
116 
     | 
    
         | 
| 
       116 
     | 
    
         
            -
            	 
     | 
| 
       117 
     | 
    
         
            -
            	 
     | 
| 
       118 
     | 
    
         
            -
            	 
     | 
| 
      
 117 
     | 
    
         
            +
            	config.include( Loggability::SpecHelpers )
         
     | 
| 
      
 118 
     | 
    
         
            +
            	config.include( Mongrel2::SpecHelpers )
         
     | 
| 
      
 119 
     | 
    
         
            +
            	config.include( Strelka::SpecHelpers )
         
     | 
| 
       119 
120 
     | 
    
         
             
            end
         
     | 
| 
       120 
121 
     | 
    
         | 
| 
       121 
122 
     | 
    
         
             
            # vim: set nosta noet ts=4 sw=4:
         
     |