From e40937bd8b7eafd57328b717dcc885a98c04deb5 Mon Sep 17 00:00:00 2001 From: Diogo Date: Thu, 25 Sep 2014 09:51:38 -0300 Subject: [PATCH 1/4] added https option for tornado now tornado can be called by https --- gluon/contrib/websocket_messaging.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/gluon/contrib/websocket_messaging.py b/gluon/contrib/websocket_messaging.py index dcd4a35e..72d53b35 100644 --- a/gluon/contrib/websocket_messaging.py +++ b/gluon/contrib/websocket_messaging.py @@ -65,6 +65,11 @@ Here is a complete sample web2py action: 'http://127.0.0.1:8888',form.vars.message,'mykey','mygroup') return form +https is possible too using 'https://127.0.0.1:8888' instead of 'http://127.0.0.1:8888', but need to +be started with + + python gluon/contrib/websocket_messaging.py -k mykey -p 8888 -s keyfile.pem -c certfile.pem + Acknowledgements: Tornado code inspired by http://thomas.pelletier.im/2010/08/websocket-tornado-redis/ @@ -194,6 +199,16 @@ if __name__ == "__main__": default=False, dest='tokens', help='require tockens to join') + parser.add_option('-s', + '--sslkey', + default=False, + dest='keyfile', + help='require ssl keyfile full path') + parser.add_option('-c', + '--sslcert', + default=False, + dest='certfile', + help='require ssl certfile full path') (options, args) = parser.parse_args() hmac_key = options.hmac_key DistributeHandler.tokens = options.tokens @@ -202,6 +217,10 @@ if __name__ == "__main__": (r'/token', TokenHandler), (r'/realtime/(.*)', DistributeHandler)] application = tornado.web.Application(urls, auto_reload=True) - http_server = tornado.httpserver.HTTPServer(application) + if options.keyfile and options.certfile: + ssl_options = dict(certfile=options.certfile, keyfile=options.keyfile) + else: + ssl_options = None + http_server = tornado.httpserver.HTTPServer(application, ssl_options=ssl_options) http_server.listen(int(options.port), address=options.address) tornado.ioloop.IOLoop.instance().start() From 11082987ea6b6849795a064f69c238d1f6b56962 Mon Sep 17 00:00:00 2001 From: Diogo Date: Sat, 27 Sep 2014 23:03:24 -0300 Subject: [PATCH 2/4] removing bug with return true in post Error with get replicate in post: http://stackoverflow.com/questions/19563093 --- gluon/contrib/websocket_messaging.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gluon/contrib/websocket_messaging.py b/gluon/contrib/websocket_messaging.py index 72d53b35..81705620 100644 --- a/gluon/contrib/websocket_messaging.py +++ b/gluon/contrib/websocket_messaging.py @@ -117,7 +117,7 @@ class PostHandler(tornado.web.RequestHandler): return 'false' for client in listeners.get(group, []): client.write_message(message) - return 'true' + return None return 'false' @@ -137,7 +137,7 @@ class TokenHandler(tornado.web.RequestHandler): if not hmac.new(hmac_key, message).hexdigest() == signature: return 'false' tokens[message] = None - return 'true' + return None return 'false' From ae5069d9b17ba26dc280abb32e3a26f35949dfb0 Mon Sep 17 00:00:00 2001 From: Diogo Date: Tue, 30 Sep 2014 08:47:31 -0300 Subject: [PATCH 3/4] add example for websocket wss --- gluon/contrib/websocket_messaging.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gluon/contrib/websocket_messaging.py b/gluon/contrib/websocket_messaging.py index 81705620..1cd7e13f 100644 --- a/gluon/contrib/websocket_messaging.py +++ b/gluon/contrib/websocket_messaging.py @@ -68,7 +68,11 @@ Here is a complete sample web2py action: https is possible too using 'https://127.0.0.1:8888' instead of 'http://127.0.0.1:8888', but need to be started with - python gluon/contrib/websocket_messaging.py -k mykey -p 8888 -s keyfile.pem -c certfile.pem + python gluon/contrib/websocket_messaging.py -k mykey -p 8888 -s keyfile.pem -c certfile.pem + +for secure websocket do: + + web2py_websocket('wss://127.0.0.1:8888/realtime/mygroup',callback) Acknowledgements: Tornado code inspired by http://thomas.pelletier.im/2010/08/websocket-tornado-redis/ From 16da2edc6d3879159a82210ad7e1bca6df75a5f3 Mon Sep 17 00:00:00 2001 From: Diogo Date: Wed, 1 Oct 2014 08:17:12 -0300 Subject: [PATCH 4/4] removing returns and added 401 error send to user --- gluon/contrib/websocket_messaging.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/gluon/contrib/websocket_messaging.py b/gluon/contrib/websocket_messaging.py index 1cd7e13f..72c6f186 100644 --- a/gluon/contrib/websocket_messaging.py +++ b/gluon/contrib/websocket_messaging.py @@ -110,7 +110,7 @@ class PostHandler(tornado.web.RequestHandler): """ def post(self): if hmac_key and not 'signature' in self.request.arguments: - return 'false' + self.send_error(401) if 'message' in self.request.arguments: message = self.request.arguments['message'][0] group = self.request.arguments.get('group', ['default'])[0] @@ -118,11 +118,9 @@ class PostHandler(tornado.web.RequestHandler): if hmac_key: signature = self.request.arguments['signature'][0] if not hmac.new(hmac_key, message).hexdigest() == signature: - return 'false' + self.send_error(401) for client in listeners.get(group, []): client.write_message(message) - return None - return 'false' class TokenHandler(tornado.web.RequestHandler): @@ -133,16 +131,14 @@ class TokenHandler(tornado.web.RequestHandler): """ def post(self): if hmac_key and not 'message' in self.request.arguments: - return 'false' + self.send_error(401) 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' + self.send_error(401) tokens[message] = None - return None - return 'false' class DistributeHandler(tornado.websocket.WebSocketHandler): @@ -178,6 +174,13 @@ class DistributeHandler(tornado.websocket.WebSocketHandler): client.write_message('-' + self.name) print '%s:DISCONNECT from %s' % (time.time(), self.group) + #if your webserver is different from tornado server uncomment this + #or override using something more restrictive: + #http://tornado.readthedocs.org/en/latest/websocket.html#tornado.websocket.WebSocketHandler.check_origin + #def check_origin(self, origin): + # return True + + if __name__ == "__main__": usage = __doc__ version = ""