Univention Bugzilla – Attachment 10536 Details for
Bug 52272
UMC-Web-Server: cleanup sessions with one timer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch (git:fbest/52272-web-server-session-timeout)
52272.patch (text/plain), 5.97 KB, created by
Florian Best
on 2020-10-28 11:32:07 CET
(
hide
)
Description:
patch (git:fbest/52272-web-server-session-timeout)
Filename:
MIME Type:
Creator:
Florian Best
Created:
2020-10-28 11:32:07 CET
Size:
5.97 KB
patch
obsolete
>commit 7dc382926020187e03c6495f4b5fd68fd56f1f8c >Author: Florian Best <best@univention.de> >Date: Wed Oct 28 11:30:56 2020 +0100 > > Bug #52272: cleanup sessions in one timer > > The UMC-Web-Server creates a timer which counts down the session second wise for each session to check if it can be destroyed. > > When 1000 uses are logged in currently, every seconds 1000 timer-callbacks are called. > We should register one timer which iterates over all sessions instead. > >diff --git management/univention-management-console/univention-management-console-web-server management/univention-management-console/univention-management-console-web-server >index 6142305e74..cc70e0eb22 100755 >--- management/univention-management-console/univention-management-console-web-server >+++ management/univention-management-console/univention-management-console-web-server >@@ -299,6 +299,16 @@ class UMCP_Dispatcher(object): > except KeyError: > CORE.info('Session %r not found' % (sessionid,)) > >+ @classmethod >+ def clean_sessions(cls): >+ now = time.time() >+ for sessionid, user in list(Ressource.sessions.items()): >+ session = UMCP_Dispatcher.sessions.get(sessionid) >+ if (not session or not session._requestid2response_queue) and user.timed_out(now): >+ CORE.info('session %r timed out' % (sessionid,)) >+ Ressource.sessions.pop(user.sessionid, None) >+ return True # execute again! >+ > > class UploadManager(dict): > >@@ -357,29 +367,20 @@ class User(object): > self.username = username > self.password = password > self.saml = saml >- self._time_remaining = _session_timeout > self.reset_timeout() > self.data = data or {} > > def reset_timeout(self): >- self._time_remaining = self.session_validity >+ self._timeout = time.time() + _session_timeout > >- @property >- def session_validity(self): >- if self.saml is not None: >- return self.time_remaining >- return _session_timeout >+ def timed_out(self, now): >+ return self.session_end_time < now > > @property >- def time_remaining(self): >- remaining = [] >- if self.saml is not None: >- remaining.append(self.saml.time_remaining) >- remaining.append(self._time_remaining) >- try: >- return min(remaining) >- except ValueError: # no SAML, no client >- return 0 >+ def session_end_time(self): >+ if self.is_saml_user() and self.saml.response.not_on_or_after: >+ return self.saml.response.not_on_or_after >+ return self._timeout > > def is_saml_user(self): > # self.saml indicates that it was originally a >@@ -400,9 +401,6 @@ class User(object): > else: > return None > >- def timed_out(self): >- return self.saml.timed_out() >- > def __repr__(self): > return '<User(%s, %s, %s)>' % (self.username, self.sessionid, self.saml is not None) > >@@ -415,17 +413,6 @@ class SAMLUser(object): > self.data = response.ava > self.username = u''.join(self.data['uid']) > >- @property >- def time_remaining(self): >- if self.response.not_on_or_after == 0: >- return 0 >- return int(self.response.not_on_or_after - time.time()) >- >- def timed_out(self): >- if self.response.not_on_or_after == 0: >- return False >- return self.time_remaining < 0 >- > > traceback_pattern = re.compile(r'(Traceback.*most recent call|File.*line.*in.*\d)') > >@@ -654,7 +641,7 @@ class Ressource(object): > > def check_saml_session_validity(self): > user = self.get_user() >- if user and user.saml is not None and user.time_remaining < 1: >+ if user and user.saml is not None and user.timed_out(time.time()): > raise UMC_HTTPError(UNAUTHORIZED) > > def set_cookies(self, *cookies, **kwargs): >@@ -681,8 +668,6 @@ class Ressource(object): > olduser = self.get_user() > > user = User(sessionid, username, password, saml or olduser and olduser.saml, kwargs) >- self._session_timeout_timer(user) >- > self.sessions[sessionid] = user > self.set_cookies(('UMCSessionId', sessionid), ('UMCUsername', username)) > return user >@@ -699,28 +684,10 @@ class Ressource(object): > if not value or value not in self.sessions: > return > user = self.sessions[value] >- if user.time_remaining <= 0: >+ if user.timed_out(time.time()): > return > return user > >- def _session_timeout_timer(self, user): >- """In order to avoid problems when the system time is changed (e.g., >- via rdate), we register a timer event that counts down the session >- timeout second-wise.""" >- >- # count down the remaining time >- user._time_remaining -= 1 >- >- session = UMCP_Dispatcher.sessions.get(user.sessionid) >- if user._time_remaining <= 0 and (not session or not session._requestid2response_queue): >- self._log('info', 'session timed out') >- self.sessions.pop(user.sessionid, None) >- return >- >- # count down the timer second-wise (in order to avoid problems when >- # changing the system time, e.g. via rdate) >- notifier.timer_add(1000, lambda: self._session_timeout_timer(user)) >- > > class CPgeneric(Ressource): > >@@ -884,8 +851,7 @@ class CPGet(CPgeneric): > raise UMC_HTTPError(UNAUTHORIZED) > info['username'] = user.username > info['auth_type'] = user.saml and 'SAML' >- info['remaining'] = user.time_remaining >- info['validity'] = user.session_validity >+ info['remaining'] = user.session_end_time - time.time() > return json.dumps({"status": 200, "result": info, "message": ""}).encode('ASCII') > > @cherrypy.expose >@@ -1017,7 +983,7 @@ class CPAuth(CPgeneric): > CORE.info('CPAuth/auth/sso: got new auth request (%s:%s <=> %s)' % (get_ip_address(), remote.port, remote.name)) > > user = self.get_user() >- if not user or not user.saml or user.timed_out(): >+ if not user or not user.saml or user.timed_out(time.time()): > # redirect user to login page in case he's not authenticated or his session timed out > raise HTTPRedirect('/univention/saml/') > >@@ -1619,6 +1585,7 @@ class UMC_HTTP_Daemon(DaemonRunner): > notifier.init(notifier.GENERIC) > notifier.dispatch.MIN_TIMER = get_int('umc/http/dispatch-interval', notifier.dispatch.MIN_TIMER) > notifier.dispatcher_add(UMCP_Dispatcher.check_queue) >+ notifier.timer_add(1000, UMCP_Dispatcher.clean_sessions) > notifier.loop() > except (SystemExit, KeyboardInterrupt) as exc: > # stop the web server
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 52272
:
10536
|
10571