Prevent session_id collisions

Keep a registry of open sessions, and refuse to open duplicates.
Min RK 10 years ago
parent e110914495
commit 4fe10b8142

@ -16,7 +16,7 @@ from jupyter_client.jsonutil import date_default
from ipython_genutils.py3compat import cast_unicode
from notebook.utils import url_path_join, url_escape
from ...base.handlers import IPythonHandler, APIHandler, json_errors
from ...base.handlers import APIHandler, json_errors
from ...base.zmqhandlers import AuthenticatedZMQStreamHandler, deserialize_binary_message
from jupyter_client import protocol_version as client_protocol_version
@ -96,6 +96,12 @@ class KernelActionHandler(APIHandler):
class ZMQChannelsHandler(AuthenticatedZMQStreamHandler):
# class-level registry of open sessions
# allows checking for conflict on session-id,
# which is used as a zmq identity and must be unique.
session_key = ''
_open_sessions = {}
@property
def kernel_info_timeout(self):
@ -209,6 +215,8 @@ class ZMQChannelsHandler(AuthenticatedZMQStreamHandler):
def pre_get(self):
# authenticate first
super(ZMQChannelsHandler, self).pre_get()
# check session collision:
self._register_session()
# then request kernel info, waiting up to a certain time before giving up.
# We don't want to wait forever, because browsers don't take it well when
# servers never respond to websocket connection requests.
@ -232,6 +240,13 @@ class ZMQChannelsHandler(AuthenticatedZMQStreamHandler):
self.kernel_id = cast_unicode(kernel_id, 'ascii')
yield super(ZMQChannelsHandler, self).get(kernel_id=kernel_id)
def _register_session(self):
"""Ensure we aren't creating a duplicate session"""
self.session_key = '%s:%s' % (self.kernel_id, self.session.session)
if self.session_key in self._open_sessions:
raise web.HTTPError(400, "Session %s already open." % self.session_key)
self._open_sessions[self.session_key] = self
def open(self, kernel_id):
super(ZMQChannelsHandler, self).open()
try:
@ -350,6 +365,10 @@ class ZMQChannelsHandler(AuthenticatedZMQStreamHandler):
def on_close(self):
self.log.debug("Websocket closed %s", self.session_key)
# unregister myself as an open session (only if it's really me)
if self._open_sessions.get(self.session_key) is self:
self._open_sessions.pop(self.session_key)
km = self.kernel_manager
if self.kernel_id in km:
km.remove_restart_callback(

Loading…
Cancel
Save