Skip to content

Instantly share code, notes, and snippets.

@greg-hellings
Created January 11, 2012 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greg-hellings/1596892 to your computer and use it in GitHub Desktop.
Save greg-hellings/1596892 to your computer and use it in GitHub Desktop.
class PostHandler(web.RequestHandler):
"""
only authorized parties can post messages
"""
def post(self):
if hmac_key and not 'signature' in self.request.arguments: return 'false'
if 'message' in self.request.arguments:
message = self.request.arguments['message'][0]
group = self.request.arguments.get('group',['default'])[0]
print '%s:MESSAGE to %s:%s' % (time.time(), group, message)
if hmac_key:
signature = self.request.arguments['signature'][0]
if not hmac.new(hmac_key,message).hexdigest()==signature: return 'false'
for client in listeners.get(group,[]): client.send(message)
return 'true'
return 'false'
class TokenHandler(web.RequestHandler):
"""
if running with -t post a token to allow a client to join using the token
the message here is the token (any uuid)
allows only authorized parties to joins, for example, a chat
"""
def post(self):
if hmac_key and not 'message' in self.request.arguments: return 'false'
if 'message' in self.request.arguments:
message = self.request.arguments['message'][0]
if hmac_key:
signature = self.request.arguments['signature'][0]
if not hmac.new(hmac_key,message).hexdigest()==signature: return 'false'
tokens[message] = None
return 'true'
return 'false'
class DistributeHandler(SocketConnection):
def on_open(self, conn):
# only authorized parties can join
self.group = 'default'
print '%s:CONNECT to %s' % (time.time(), self.group)
def on_message(self, message):
pass
def on_close(self):
if self.group in listeners: listeners[self.group].remove(self)
# notify clients that a member has left the groups
for client in listeners.get(self.group,[]): client.send('-'+self.name)
print '%s:DISCONNECT from %s' % (time.time(), self.group)
class BaseRouter(SocketConnection):
__endpoints__ = {
'/realtime/' : DistributeHandler
}
def on_open(self, *args):
print "Connection received: %s" % (repr(args),)
@event
def join(self, *args):
print "Joining!!"
class TornadioHandler(object):
"""This should be the only class you need to worry about if you are trying to extend or
customize the behavior of this file."""
def __init__(self, *points, **kargs):
"""Instantiate a new handler for SocketIO 0.7+ which will operate as a distribution center for web2py
applications on this site.
Positional arguments are tuples of the form ('/chat', MyHandler) where the first argument is the URL path
that should be picked up by the handler and the second argument is a class which extends tornadio2.SocketConnection.
Optional keyword arguments are regarded as follows:
port : The port that SocketIO connections should listen on (defaults 8888)
flash_port : The port that the Flash policy file should be served on (defaults 843)
flash_policy_file : An absolute path to the flash policy file on the file system
hmac_key : An authorization key (string) which must be passed when making a broadcast post from the localhost
tokens : A boolean value which requires the client files to possess identifier tokens in order to be allowed
to join a channel (default False)
debug : A boolean value which enables or disables debugging output (default True)"""
# First, construct the endpoints that need to be available
endpoints = self.make_endpoints(points)
# Next, parse the options
self.port = 'port' in kargs.keys() and kargs['port'] or 8888
self.flash_port = 'flash_port' in kargs.keys() and kargs['flash_port'] or 843
self.flash_policy_file = 'flash_policy_file' in kargs.keys() and kargs['flash_policy_file'] or op.join(ROOT, 'tornadio2', 'examples', 'multiplexed', 'flashpolicy.xml')
self.hmac_key = 'hmac_key' in kargs.keys() and kargs['hmac_key'] or False
self.tokens = 'tokens' in kargs.keys() and kargs['tokens'] or False
self.debug = 'debug' in kargs.keys() and kargs['debug'] or True
# A few of these need to be globalized
global hmac_key
hmac_key = self.hmac_key
DistributeHandler.tokens = self.tokens
# Now, construct the router class
my_router = TornadioRouter(BaseRouter)
# Create the application
self.application = web.Application(
my_router.apply_routes([(r'/', PostHandler),
(r'/token', TokenHandler)]),
flash_policy_port = self.flash_port,
flash_policy_file = self.flash_policy_file,
socket_io_port = self.port
)
SocketServer(self.application)
def make_endpoints(self, points):
"""Constructs the endpoints that are necessary for this distribution handler."""
for point in points:
BaseRouter.__endpoints__[point[0]] = point[1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment