From 9a91f9f1755ac656d272d043ff23dfaba8457495 Mon Sep 17 00:00:00 2001 From: Hugvey Central Command Date: Mon, 13 May 2019 12:08:31 +0200 Subject: [PATCH] Header for websocket connection on non-localhost --- hugvey/panopticon.py | 64 +++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/hugvey/panopticon.py b/hugvey/panopticon.py index 4ef79be..c904e36 100644 --- a/hugvey/panopticon.py +++ b/hugvey/panopticon.py @@ -30,7 +30,7 @@ def getWebSocketHandler(central_command): class WebSocketHandler(tornado.websocket.WebSocketHandler): CORS_ORIGINS = ['localhost'] connections = set() - + def check_origin(self, origin): parsed_origin = urlparse(origin) # parsed_origin.netloc.lower() gives localhost:3333 @@ -79,7 +79,7 @@ def getWebSocketHandler(central_command): logger.exception(e) def send(self, message): - # Possible useless method: use self.write_message() + # Possible useless method: use self.write_message() j = json.dumps(message) self.write_message(j) @@ -100,40 +100,40 @@ def getWebSocketHandler(central_command): def msgInit(self): msg = self.getStatusMsg() self.send(msg) - + def msgBlock(self, hv_id): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'block'}) - + def msgUnblock(self, hv_id): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'unblock'}) - + def msgResume(self, hv_id): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'resume'}) - + def msgPause(self, hv_id): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'pause'}) - + def msgRestart(self, hv_id): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'restart'}) - + def msgFinish(self, hv_id): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'finish'}) - + def msgChangeLanguage(self, hv_id, lang_code): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'change_language', 'lang_code': lang_code}) - + def msgChangeLightId(self, hv_id, lightId): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'change_light', 'light_id': lightId}) - + def msgPlayMsg(self, hv_id, msg_id, reloadStory): central_command.hugveys[hv_id].eventQueue.put_nowait({'event': 'play_msg', 'msg_id': msg_id, 'reloadStory':bool(reloadStory)}) - + @classmethod def write_to_clients(wsHandlerClass, msg): if msg is None: logger.critical("Tried to send 'none' to Panopticon") return - + for client in wsHandlerClass.connections: client.write_message(msg) @@ -143,7 +143,7 @@ class NonCachingStaticFileHandler(tornado.web.StaticFileHandler): def set_extra_headers(self, path): # Disable cache self.set_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0') - + def getUploadHandler(central_command): class UploadHandler(tornado.web.RequestHandler): def set_default_headers(self): @@ -160,12 +160,12 @@ def getUploadHandler(central_command): logger.info('upload') langCode = self.get_argument("language") langFile = os.path.join(central_command.config['web']['files_dir'] , central_command.languageFiles[langCode]) - + storyData = json.loads(self.request.files['json'][0]['body']) # print(json.dumps(storyData)) # self.finish() # return - + if 'audio' in self.request.files: msgId = self.get_argument("message_id") audioFile = self.request.files['audio'][0] @@ -179,7 +179,7 @@ def getUploadHandler(central_command): if 'audio' in storyData[i] and storyData[i]['audio'] is not None and os.path.exists(storyData[i]['audio']['file']): logger.info(f"Remove previous file {storyData[i]['audio']['file']} ({storyData[i]['audio']['original_name']})") os.unlink(storyData[i]['audio']['file']) - + storyData[i]['audio'] = { 'file': audioFilename, 'original_name': original_fname @@ -188,17 +188,17 @@ def getUploadHandler(central_command): logger.info(f'Save {original_fname} to {audioFilename}') fp.write(audioFile['body']) break - + # logger.info(os.path.abspath(langFile)) langFile = os.path.abspath(langFile) with open(langFile, 'w') as json_fp: logger.info(f'Save story to {langFile} {json_fp}') json.dump(storyData, json_fp, indent=2) - + # Reload language files for new instances central_command.loadLanguages() self.finish() - + return UploadHandler def getVoiceHandler(voiceStorage): @@ -212,7 +212,7 @@ def getVoiceHandler(voiceStorage): fn = await voiceStorage.requestFile(lang_code, text, isVariable) if not fn: raise Exception(f"No Filename for text: {text}") - + if int(self.get_argument('filename')) == 1: self.set_header("Content-Type","text/plain") self.write(fn) @@ -221,25 +221,30 @@ def getVoiceHandler(voiceStorage): with open(fn, 'rb') as fp: self.write(fp.read()) self.finish() - return VoiceHandler + return VoiceHandler +class StaticFileWithHeaderHandler(tornado.web.StaticFileHandler): + def set_extra_headers(self, path): + """For subclass to add extra headers to the response""" + if path[-5:] == '.html': + self.set_header("Access-Control-Allow-Origin", "*") class Panopticon(object): def __init__(self, central_command, config, voiceStorage): self.command = central_command self.config = config - + self.voiceStorage = voiceStorage - + self.wsHandler = getWebSocketHandler(self.command) - + self.application = tornado.web.Application([ (r"/ws(.*)", self.wsHandler), (r"/local/(.*)", NonCachingStaticFileHandler, {"path": config['web']['files_dir']}), (r"/upload", getUploadHandler(self.command)), (r"/voice", getVoiceHandler(self.voiceStorage)), - (r"/(.*)", tornado.web.StaticFileHandler, + (r"/(.*)", StaticFileWithHeaderHandler, {"path": web_dir, "default_filename": 'index.html'}), ], debug=True) @@ -251,17 +256,17 @@ class Panopticon(object): asyncio.set_event_loop(evt_loop) self.loop = tornado.ioloop.IOLoop.current() - + thread = threading.Thread( target=self.broadcastLoggingQueueToWs, kwargs={'wsHandler': self.wsHandler, 'q': self.command.logQueue}, name=f"panopticon/logws") thread.start() - + logger.info(f"Start Panopticon on http://localhost:{self.config['web']['port']}") self.loop.start() def stop(self): self.loop.stop() - + def broadcastLoggingQueueToWs(self, wsHandler, q: Queue): while True: record = q.get() @@ -278,4 +283,3 @@ class Panopticon(object): j = json.dumps(msg) logger.debug(j) self.loop.add_callback(wsHandler.write_to_clients, j) - \ No newline at end of file