Header for websocket connection on non-localhost

This commit is contained in:
Hugvey Central Command 2019-05-13 12:08:31 +02:00
parent b8b912a10a
commit 9a91f9f175

View file

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