Mercurial > libervia-web
diff libervia/server/pages.py @ 1203:251eba911d4d
server (websockets): fixed websocket handling on HTTPS connections:
Original request used to retrieve a page was stored on dynamic pages, but after the end of
it, the channel was deleted, resulting in a isSecure() always returning False, and
troubles in chain leading to the the use of the wrong session object. This patch fixes
this by reworking the way original request is used, and creating a new wrapping class
allowing to keep an API similar to iweb.IRequest, with data coming from both the original
request and the websocket request.
fix 327
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 14 Jul 2019 14:45:51 +0200 |
parents | 1211dbc3cca7 |
children | 92d0a2b785fd |
line wrap: on
line diff
--- a/libervia/server/pages.py Fri Jul 12 14:58:11 2019 +0200 +++ b/libervia/server/pages.py Sun Jul 14 14:45:51 2019 +0200 @@ -470,6 +470,16 @@ .format( *uri_tuple)) self.uri_callbacks[uri_tuple] = (self, get_uri_cb) + def getSignalId(self, request): + """Retrieve signal_id for a request + + signal_id is used for dynamic page, to associate a initial request with a + signal handler. For WebsocketRequest, signal_id attribute is used (which must + be orginal request's id) + For server.Request it's id(request) + """ + return getattr(request, 'signal_id', id(request)) + def registerSignal(self, request, signal, check_profile=True): r"""register a signal handler @@ -491,11 +501,12 @@ if not self.dynamic: log.error(_(u"You can't register signal if page is not dynamic")) return - LiberviaPage.signals_handlers.setdefault(signal, {})[id(request)] = ( + signal_id = self.getSignalId(request) + LiberviaPage.signals_handlers.setdefault(signal, {})[signal_id] = [ self, request, check_profile, - ) + ] request._signals_registered.append(signal) def getConfig(self, key, default=None, value_type=None): @@ -1025,6 +1036,13 @@ we send all cached signals """ assert request._signals_cache is not None + # we need to replace corresponding original requests by this websocket request + # in signals_handlers + signal_id = request.signal_id + for signal_handlers_map in self.__class__.signals_handlers.itervalues(): + if signal_id in signal_handlers_map: + signal_handlers_map[signal_id][1] = request + cache = request._signals_cache request._signals_cache = None for request, signal, args in cache: @@ -1036,8 +1054,9 @@ we remove signal handler """ for signal in request._signals_registered: + signal_id = self.getSignalId(request) try: - del LiberviaPage.signals_handlers[signal][id(request)] + del LiberviaPage.signals_handlers[signal][signal_id] except KeyError: log.error(_(u"Can't find signal handler for [{signal}], this should not " u"happen").format(signal=signal)) @@ -1208,11 +1227,11 @@ request.template_data["websocket"] = WebsocketMeta( socket_url, socket_token, socket_debug ) - self.host.registerWSToken(socket_token, self, request) # we will keep track of handlers to remove request._signals_registered = [] # we will cache registered signals until socket is opened request._signals_cache = [] + self.host.registerWSToken(socket_token, self, request) def _prepare_render(self, __, request): return defer.maybeDeferred(self.prepare_render, self, request)