# HG changeset patch # User souliane # Date 1411301399 -7200 # Node ID 471b6babe96007d0653e539254622d12a2ae8abd # Parent 8492c2bb463b7e633316b02d6b9dd7a27e89e698 server_side: set a timeout to reset the waiting connection requests after 5 minutes diff -r 8492c2bb463b -r 471b6babe960 src/server/constants.py --- a/src/server/constants.py Fri Sep 19 15:39:12 2014 +0200 +++ b/src/server/constants.py Sun Sep 21 14:09:59 2014 +0200 @@ -30,7 +30,7 @@ APP_NAME_FILE = "libervia" SERVICE_PROFILE = 'libervia' # the SàT profile that is used for exporting the service - TIMEOUT = 300 # Session's time out, after that the user will be disconnected + TIMEOUT = 300 # Session's time out, after that the user will be disconnected or a waiting connection request will be reset HTML_DIR = "html/" SERVER_CSS_DIR = "server_css/" MEDIA_DIR = "media/" diff -r 8492c2bb463b -r 471b6babe960 src/server/server.py --- a/src/server/server.py Fri Sep 19 15:39:12 2014 +0200 +++ b/src/server/server.py Sun Sep 21 14:09:59 2014 +0200 @@ -564,6 +564,39 @@ return self.sat_host.bridge.skipOTR(profile) +class WaitingRequests(dict): + + def setRequest(self, request, profile): + """Add the given profile to the waiting list. + + @param request (server.Request): the connection request + @param profile (str): %(doc_profile)s + """ + dc = reactor.callLater(C.TIMEOUT, self.purgeRequest, profile) + self[profile] = (request, dc) + + def purgeRequest(self, profile): + """Remove the given profile from the waiting list. + + @param profile (str): %(doc_profile)s + """ + try: + dc = self[profile][1] + except KeyError: + return + if dc.active(): + dc.cancel() + del self[profile] + + def getRequest(self, profile): + """Get the waiting request for the given profile. + + @param profile (str): %(doc_profile)s + @return: the waiting request or None + """ + return self[profile][0] if profile in self else None + + class Register(JSONRPCMethodManager): """This class manage the registration procedure with SàT It provide an api for the browser, check password and setup the web server""" @@ -572,13 +605,7 @@ JSONRPCMethodManager.__init__(self, sat_host) self.profiles_waiting = {} self.request = None - - def getWaitingRequest(self, profile): - """Tell if a profile is trying to log in""" - if profile in self.profiles_waiting: - return self.profiles_waiting[profile] - else: - return None + self.waiting_profiles = WaitingRequests() def render(self, request): """ @@ -647,12 +674,12 @@ return C.PROFILE_AUTH_ERROR # profiles with empty passwords are restricted to local frontends - if login_ in self.profiles_waiting: + if self.waiting_profiles.getRequest(login_): return C.ALREADY_WAITING def auth_eb(failure): fault = failure.value.faultString - self.__cleanWaiting(login_) + self.waiting_profiles.purgeRequest(login_) if fault == 'PasswordError': log.info("Profile %s doesn't exist or the submitted password is wrong" % login_) request.write(C.PROFILE_AUTH_ERROR) @@ -667,12 +694,13 @@ request.write(C.UNKNOWN_ERROR % fault) request.finish() - self.profiles_waiting[login_] = request + self.waiting_profiles.setRequest(request, login_) d = self.asyncBridgeCall("asyncConnect", login_, password_) d.addCallbacks(lambda connected: self._logged(login_, request) if connected else None, auth_eb) return server.NOT_DONE_YET + def _registerNewAccount(self, request): """Create a new account, or return error @param request: request of the register form @@ -716,13 +744,6 @@ d.addErrback(registeringError) return server.NOT_DONE_YET - def __cleanWaiting(self, login): - """Remove login from waiting queue""" - try: - del self.profiles_waiting[login] - except KeyError: - pass - def _logged(self, profile, request): """Set everything when a user just logged in @@ -732,7 +753,7 @@ - C.PROFILE_LOGGED - C.SESSION_ACTIVE """ - self.__cleanWaiting(profile) + self.waiting_profiles.purgeRequest(profile) _session = request.getSession() sat_session = ISATSession(_session) if sat_session.profile: @@ -766,9 +787,9 @@ def jsonrpc_asyncConnect(self): _session = self.request.getSession() profile = ISATSession(_session).profile - if profile in self.profiles_waiting: + if self.waiting_profiles.getRequest(profile): raise jsonrpclib.Fault(1, C.ALREADY_WAITING) # FIXME: define some standard error codes for libervia - self.profiles_waiting[profile] = self.request + self.waiting_profiles.setRequest(self.request, profile) self.sat_host.bridge.asyncConnect(profile) return server.NOT_DONE_YET @@ -877,7 +898,7 @@ def connected(self, profile): assert(self.register) # register must be plugged - request = self.register.getWaitingRequest(profile) + request = self.register.waiting_profiles.getRequest(profile) if request: self.register._logged(profile, request)