protect websocket handling from any exceptions

This commit is contained in:
Jakob Ketterl 2019-10-21 21:51:31 +02:00
parent 6cdec05cde
commit eb29d0ac99
2 changed files with 21 additions and 17 deletions

View File

@ -152,4 +152,4 @@ class WebSocketController(Controller):
def handle_request(self): def handle_request(self):
conn = WebSocketConnection(self.handler, WebSocketMessageHandler()) conn = WebSocketConnection(self.handler, WebSocketMessageHandler())
# enter read loop # enter read loop
conn.read_loop() conn.handle()

View File

@ -149,6 +149,26 @@ class WebSocketConnection(object):
def interrupt(self): def interrupt(self):
self.interruptPipeSend.send(bytes(0x00)) self.interruptPipeSend.send(bytes(0x00))
def handle(self):
WebSocketConnection.connections.append(self)
try:
self.read_loop()
finally:
logger.debug("websocket loop ended; shutting down")
self.messageHandler.handleClose()
self.cancelPing()
logger.debug("websocket loop ended; sending close frame")
header = self.get_header(0, OPCODE_CLOSE)
self._sendBytes(header)
try:
WebSocketConnection.connections.remove(self)
except ValueError:
pass
def read_loop(self): def read_loop(self):
def protected_read(num): def protected_read(num):
data = self.handler.rfile.read(num) data = self.handler.rfile.read(num)
@ -158,7 +178,6 @@ class WebSocketConnection(object):
raise IncompleteRead() raise IncompleteRead()
return data return data
WebSocketConnection.connections.append(self)
self.open = True self.open = True
while self.open: while self.open:
(read, _, _) = select.select([self.interruptPipeRecv, self.handler.rfile], [], [], 15) (read, _, _) = select.select([self.interruptPipeRecv, self.handler.rfile], [], [], 15)
@ -203,21 +222,6 @@ class WebSocketConnection(object):
logger.exception("OSError while reading data; closing connection") logger.exception("OSError while reading data; closing connection")
self.open = False self.open = False
logger.debug("websocket loop ended; shutting down")
self.messageHandler.handleClose()
self.cancelPing()
logger.debug("websocket loop ended; sending close frame")
header = self.get_header(0, OPCODE_CLOSE)
self._sendBytes(header)
try:
WebSocketConnection.connections.remove(self)
except ValueError:
pass
def close(self): def close(self):
self.open = False self.open = False
self.interrupt() self.interrupt()