def delete(self, trans): """ Deletes the item permanently. @param trans: A valid transaction handle @return: None """ user = currentThread().context.user self = _db.get_item(self._id, trans) user_role = permsresolver.get_access(self, user) can_delete = (user_role > permsresolver.AUTHOR) or \ (user_role == permsresolver.AUTHOR and self._owner == user._id) if (not(self._isSystem) and can_delete): # delete item physically self._delete(trans) # update container parent = _db.get_item(self._parentid, trans) parent.modified = time.time() _db.put_item(parent, trans) else: raise exceptions.PermissionDenied, \ 'The object was not deleted.\n' + \ 'The user has insufficient permissions.'
def _fetch_session(self, session_id, cookies_enabled): session = None if session_id: session = SessionManager.fetch_session(session_id) if session is not None: context.session = session context.user = _db.get_item(context.session.userid) context.request.serverVariables["AUTH_USER"] = \ context.user.displayName.value if not cookies_enabled: if not session.sessionid in context.request.SCRIPT_NAME: context.request.serverVariables['SCRIPT_NAME'] += \ '/{%s}' % session.sessionid else: lstScript = context.request.SCRIPT_NAME.split('/') context.request.serverVariables['SCRIPT_NAME'] = \ '/%s/{%s}' % (lstScript[1], session.sessionid) else: # create guest session guest_id = settings['sessionmanager']['guest'] context.user = _db.get_item(guest_id) new_session = SessionManager.create(guest_id) session_id = new_session.sessionid if 'PMB' in context.request.serverVariables['HTTP_USER_AGENT']: # if is a mobile client # add session id in special header context.response.set_header('Porcupine-Session', session_id) else: # add cookie with sessionid context.response.cookies['_sid'] = session_id context.response.cookies['_sid']['path'] = \ context.request.SCRIPT_NAME + '/' context.session = new_session
def update(self, trans): """ Updates the item. @param trans: A valid transaction handle @return: None """ old_item = _db.get_item(self._id, trans) parent = _db.get_item(self._parentid, trans) user = currentThread().context.user user_role = permsresolver.get_access(old_item, user) if user_role > permsresolver.READER: # set security if user_role == permsresolver.COORDINATOR: # user is COORDINATOR if (self.inheritRoles != old_item.inheritRoles) or \ (not self.inheritRoles and \ self.security != old_item.security): self._applySecurity(parent, trans) else: # restore previous ACL self.security = old_item.security self.inheritRoles = old_item.inheritRoles _db.handle_update(self, old_item, trans) self.modifiedBy = user.displayName.value self.modified = time.time() parent.modified = self.modified _db.put_item(self, trans) _db.put_item(parent, trans) else: raise exceptions.PermissionDenied, \ 'The user does not have update permissions.'
def move_to(self, target_id, trans): """ Moves the item to the designated target. @param target_id: The ID of the destination container @type target_id: str @param trans: A valid transaction handle @return: None @raise L{porcupine.exceptions.ObjectNotFound}: If the target container does not exist. """ user = currentThread().context.user user_role = permsresolver.get_access(self, user) can_move = (user_role > permsresolver.AUTHOR) ## or (user_role == permsresolver.AUTHOR and oItem.owner == user.id) parent_id = self._parentid target = _db.get_item(target_id, trans) if target == None or target._isDeleted: raise exceptions.ObjectNotFound, ( 'The target container "%s" does not exist.' % target_id , False) if isinstance(self, Shortcut): contentclass = self.get_target_contentclass(trans) else: contentclass = self.get_contentclass() user_role2 = permsresolver.get_access(target, user) if self.isCollection and target.is_contained_in(self._id, trans): raise exceptions.ContainmentError, \ 'Cannot move item to destination.\n' + \ 'The destination is contained in the source.' if (not(self._isSystem) and can_move and user_role2 > permsresolver.READER): if not(contentclass in target.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type\n"%s".' % contentclass self._parentid = target._id self.inheritRoles = False self.modified = time.time() _db.check_unique(self, None, trans) _db.put_item(self, trans) # update target target.modified = time.time() _db.put_item(target, trans) # update parent parent = _db.get_item(parent_id, trans) parent.modified = time.time() _db.put_item(parent, trans) else: raise exceptions.PermissionDenied, \ 'The object was not moved.\n' + \ 'The user has insufficient permissions.'
def on_delete(item, attr, trans, bPermanent): if bPermanent: [CompositionEventHandler._removeComposite(_db.get_item(id, trans), trans) for id in attr.value] else: for sID in attr.value: composite = _db.get_item(sID, trans) _db.handle_delete(composite, trans, False) composite._isDeleted = 1 _db.put_item(composite, trans)
def on_update(item, new_attr, old_attr, trans): from porcupine.systemObjects import Composite # load objects dctObjects = {} for i, obj in enumerate(new_attr.value): if isinstance(obj, Composite): obj._containerid = item._id elif isinstance(obj, str): obj = _db.get_item(obj, trans) new_attr.value[i] = obj else: raise exceptions.ContainmentError, \ 'Invalid object type "%s" in composition.' % \ obj.__class__.__name__ dctObjects[obj._id] = obj # check containment composite_type = misc.get_rto_by_name(new_attr.compositeClass) if [obj for obj in dctObjects.values() if not isinstance(obj, composite_type)]: raise exceptions.ContainmentError, \ 'Invalid content class "%s" in composition.' % \ obj.get_contentclass() # get previous value if old_attr != None: old_ids = set(old_attr.value) else: old_ids = set() new_ids = set([obj._id for obj in new_attr.value]) # calculate added composites lstAdded = list(new_ids - old_ids) for obj_id in lstAdded: _db.handle_update(dctObjects[obj_id], None, trans) _db.put_item(dctObjects[obj_id], trans) # calculate constant composites lstConstant = list(new_ids & old_ids) for obj_id in lstConstant: _db.handle_update(dctObjects[obj_id], _db.get_item(obj_id, trans), trans) _db.put_item(dctObjects[obj_id], trans) # calculate removed composites lstRemoved = list(old_ids - new_ids) [CompositionEventHandler._removeComposite(_db.get_item(id, trans), trans) for id in lstRemoved] new_attr.value = list(new_ids)
def get_handle(**kwargs): if _db._db_handle is None or not _db._db_handle.is_open(): # open database kwargs.setdefault('maintain', False) kwargs.setdefault('recover', 0) _db.open(**kwargs) identity = kwargs.get('identity', _db.get_item('system')) if isinstance(identity, basestring): identity = _db.get_item(identity) context.user = identity return _db
def get_target_contentclass(self, trans=None): """Returns the content class of the target item. @param trans: A valid transaction handle @return: the fully qualified name of the target's content class @rtype: str """ if self.target.value: target = _db.get_item(self.target.value, trans) while isinstance(target, Shortcut): target = _db.get_item(target.target.value, trans) return target.get_contentclass()
def on_delete(item, attr, trans, bPermanent): if not item._isDeleted: if attr.value and attr.respectsReferences: raise exceptions.ReferentialIntegrityError, ( 'Cannot delete object "%s" ' % item.displayName.value + 'because it is referenced by other objects.') if attr.cascadeDelete: _db.get_item(attr.value, trans)._recycle(trans) if bPermanent and attr.value: if attr.cascadeDelete: _db.get_item(attr.value, trans)._delete(trans) else: # remove reference Relator1EventHandler._remove_reference(attr, item._id, trans)
def recycle(self, rb_id, trans): """ Moves the item to the specified recycle bin. The item then becomes inaccessible. @param rb_id: The id of the destination container, which must be a L{RecycleBin} instance @type rb_id: str @param trans: A valid transaction handle @return: None """ user = currentThread().context.user self = _db.get_item(self._id, trans) user_role = permsresolver.get_access(self, user) can_delete = (user_role > permsresolver.AUTHOR) or \ (user_role == permsresolver.AUTHOR and self._owner == user._id) if (not(self._isSystem) and can_delete): deleted = DeletedItem(self, trans) deleted._owner = user._id deleted._created = time.time() deleted.modifiedBy = user.displayName.value deleted.modified = time.time() deleted._parentid = rb_id # check recycle bin's containment recycle_bin = _db.get_item(rb_id, trans) if not(deleted.get_contentclass() in recycle_bin.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type\n"%s".' % deleted.get_contentclass() _db.handle_update(deleted, None, trans) _db.put_item(deleted, trans) # delete item logically self._recycle(trans) # update container parent = _db.get_item(self._parentid, trans) parent.modified = time.time() _db.put_item(parent, trans) else: raise exceptions.PermissionDenied, \ 'The object was not deleted.\n' + \ 'The user has insufficient permissions.'
def getHandle(identity=None, recover=0): # open database _db.open(recover=recover, maintain=False) if identity == None: identity = _db.get_item('system') currentThread().context = SecurityContext(identity) return _db
def _fetch_session(self): path_info = self.request.serverVariables['PATH_INFO'] or '/' # get session session = None cookiesEnabled = True if self.request.cookies.has_key('_sid'): session = SessionManager.fetch_session( self.request.cookies['_sid'].value) else: cookiesEnabled = False session_match = re.match(self.sid_pattern, path_info) if session_match: path_info = path_info.replace(session_match.group(), '', 1) or '/' self.request.serverVariables['PATH_INFO'] = path_info session = SessionManager.fetch_session(session_match.group(1)) if session != None: self.session = session self.user = _db.get_item(self.session.userid) self.request.serverVariables["AUTH_USER"] = \ self.user.displayName.value if not cookiesEnabled: if not session.sessionid in self.request.serverVariables["SCRIPT_NAME"]: self.request.serverVariables["SCRIPT_NAME"] += \ '/{%s}' % session.sessionid else: lstScript = self.request.serverVariables["SCRIPT_NAME"].split('/') self.request.serverVariables["SCRIPT_NAME"] = \ "/%s/{%s}" %(lstScript[1], session.sessionid) else: self.session = self.__create_guest_session()
def get_deleted_item(self): """ Use this method to get the item that was logically deleted. @return: the deleted item @rtype: L{GenericItem} """ return _db.get_item(self._deletedId)
def get_handle(**kwargs): if _db._db_handle is None or not _db._db_handle.is_open(): # open database kwargs.setdefault("maintain", False) kwargs.setdefault("recover", 0) _db.open(**kwargs) identity = kwargs.get("identity", _db.get_item("system")) context.user = identity return _db
def thread_loop(self): # run as system context.user = _db.get_item('system') while self.running: time.sleep(self.interval) try: self.execute() except: e = exceptions.InternalServerError() e.emit()
def restore_to(self, parent_id, trans): """ Restores the deleted object to the specified container. @param parent_id: The ID of the container in which the item will be restored @type parent_id: str @param trans: A valid transaction handle @return: None @raise L{porcupine.exceptions.ObjectNotFound}: If the original location or the original item no longer exists. """ deleted = _db.get_item(self._deletedId, trans) if deleted == None: raise exceptions.ObjectNotFound, ( 'Cannot locate original item.\n' + 'It seems that this item resided in a container\n' + 'that has been permanently deleted or it is shortcut\n' + 'having its target permanently deleted.', False) parent = _db.get_item(parent_id or deleted._parentid, trans) if parent == None or parent._isDeleted: raise exceptions.ObjectNotFound, ( 'Cannot locate target container.\n' + 'It seems that this container is deleted.', False) if isinstance(deleted, Shortcut): contentclass = deleted.get_target_contentclass(trans) else: contentclass = deleted.get_contentclass() if contentclass and not(contentclass in parent.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type\n"%s".' % contentclass # try to restore original item self._restore(deleted, parent, trans) # update parent parent.modified = time.time() _db.put_item(parent, trans) # delete self self.delete(trans, _removeDeleted=False)
def thread_loop(self): # run as system time_to_run = int(time.time()) + self.interval context.user = _db.get_item('system') while self.running: time.sleep(1) if int(time.time()) >= time_to_run: time_to_run = int(time.time()) + self.interval try: self.execute() except: e = exceptions.InternalServerError() e.emit()
def _remove_reference(attr, oid, trans): from porcupine.datatypes import Relator1, RelatorN ref_item = _db.get_item(attr.value, trans) ref_attr = getattr(ref_item, attr.relAttr) if isinstance(ref_attr, RelatorN): try: ref_attr.value.remove(oid) except ValueError: pass elif isinstance(ref_attr, Relator1): ref_attr.value = None ref_attr.validate() _db.put_item(ref_item, trans)
def delete(self, trans, _removeDeleted=True): """ Deletes the deleted object permanently. @param trans: A valid transaction handle @param _removeDeleted: Leave as is @return: None """ Removable.delete(self, trans) if _removeDeleted: # we got a direct call. remove deleted item deleted = _db.get_item(self._deletedId, trans) if deleted != None: deleted._delete(trans)
def create(target, trans=None): """Helper method for creating shortcuts of items. @param target: The id of the item or the item object itself @type parent: str OR L{Item} @param trans: A valid transaction handle @return: L{Shortcut} """ if type(target) == str: target = _db.get_item(target, trans) shortcut = Shortcut() shortcut.displayName.value = target.displayName.value shortcut.target.value = target._id return shortcut
def _get_item(self, s): item = persist.loads(s) if not self.enforce_permissions: if self.resolve_shortcuts: while item is not None and isinstance(item, Shortcut): item = _db.get_item(item.target.value) else: # check read permissions access = permsresolver.get_access(item, context.user) if item._isDeleted or access == 0: item = None elif self.resolve_shortcuts and isinstance(item, Shortcut): item = item.get_target() return item
def _get_item(self, s): item = persist.loads(s) if self.fetch_all: if self.resolve_shortcuts: while item != None and isinstance(item, Shortcut): item = _db.get_item(item.target.value, self._txn) else: # check read permissions access = permsresolver.get_access(item, self._thread.context.user) if item._isDeleted or access == 0: item = None elif self.resolve_shortcuts and isinstance(item, Shortcut): item = item.get_target(self._txn) return item
def is_contained_in(self, item_id, trans=None): """ Checks if the item is contained in the specified container. @param item_id: The id of the container @type item_id: str @rtype: bool """ item = self while item._id != '': if item._id == item_id: return True item = _db.get_item(item.parentid, trans) return False
def _add_reference(attr, oid, trans): from porcupine.datatypes import Relator1, RelatorN ref_item = _db.get_item(attr.value, trans) if ref_item != None and isinstance(ref_item, tuple([misc.get_rto_by_name(cc) for cc in attr.relCc])): ref_attr = getattr(ref_item, attr.relAttr) if isinstance(ref_attr, RelatorN): ref_attr.value.append(oid) elif isinstance(ref_attr, Relator1): ref_attr.value = oid ref_attr.validate() _db.put_item(ref_item, trans) else: attr.value = None
def _remove_references(attr, ids, oid, trans): # remove references from porcupine.datatypes import Relator1, RelatorN for id in ids: ref_item = _db.get_item(id, trans) ref_attr = getattr(ref_item, attr.relAttr) if isinstance(ref_attr, RelatorN): try: ref_attr.value.remove(oid) except ValueError: pass elif isinstance(ref_attr, Relator1): ref_attr.value = '' ref_attr.validate() _db.put_item(ref_item, trans)
def _get_size(self): try: if self._value is not None: # equality size = self._cursor.count() else: # range cursor - approximate sizing # assuming even distribution of keys # get scope's range first_value = str_long( self._cursor.set_range(self._scope + b'_')[0]) last = self._cursor.set_range(self._scope + b'a') if last is not None: last_value = str_long(self._cursor.get(db.DB_PREV)[0]) else: last_value = str_long(self._cursor.last()[0]) scope_range = float(last_value - first_value) if self._range._lower_value is not None: start_value = str_long(self._scope + b'_' + self._range._lower_value) if start_value < first_value: start_value = first_value else: start_value = first_value if self._range._upper_value is not None: end_value = str_long(self._scope + b'_' + self._range._upper_value) if end_value > last_value: end_value = last_value else: end_value = last_value if scope_range == 0: size = 0 else: children_count = _db.get_item(self._scope).children_count size = int(((end_value - start_value) / scope_range) * children_count) except (db.DBLockDeadlockError, db.DBLockNotGrantedError): if context._trans is not None: context._trans.abort() raise exceptions.DBRetryTransaction return size
def append_to(self, parent, trans): """ Adds the item to the specified container. @param parent: The id of the destination container or the container itself @type parent: str OR L{Container} @param trans: A valid transaction handle @return: None """ if type(parent) == str: parent = _db.get_item(parent, trans) if isinstance(self, Shortcut): contentclass = self.get_target_contentclass(trans) else: contentclass = self.get_contentclass() user = currentThread().context.user user_role = permsresolver.get_access(parent, user) if user_role == permsresolver.READER: raise exceptions.PermissionDenied, \ 'The user does not have write permissions ' + \ 'on the parent folder.' if not(contentclass in parent.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type\n"%s".' % contentclass # set security to new item if user_role == permsresolver.COORDINATOR: # user is COORDINATOR self._applySecurity(parent, trans) else: # user is not COORDINATOR self.inheritRoles = True self.security = parent.security self._owner = user._id self._created = time.time() self.modifiedBy = user.displayName.value self.modified = time.time() self._parentid = parent._id _db.handle_update(self, None, trans) parent.modified = self.modified _db.put_item(self, trans) _db.put_item(parent, trans)
def copy_to(self, target_id, trans): """ Copies the item to the designated target. @param target_id: The ID of the destination container @type target_id: str @param trans: A valid transaction handle @return: None @raise L{porcupine.exceptions.ObjectNotFound}: If the target container does not exist. """ target = _db.get_item(target_id, trans) if target == None or target._isDeleted: raise exceptions.ObjectNotFound, ( 'The target container "%s" does not exist.' % target_id , False) if isinstance(self, Shortcut): contentclass = self.get_target_contentclass(trans) else: contentclass = self.get_contentclass() if self.isCollection and target.is_contained_in(self._id, trans): raise exceptions.ContainmentError, \ 'Cannot copy item to destination.\n' + \ 'The destination is contained in the source.' # check permissions on target folder user = currentThread().context.user user_role = permsresolver.get_access(target, user) if not(self._isSystem) and user_role > permsresolver.READER: if not(contentclass in target.containment): raise exceptions.ContainmentError, \ 'The target container does not accept ' + \ 'objects of type\n"%s".' % contentclass self._copy(target, trans, clear_inherited=True) # update parent target.modified = time.time() _db.put_item(target, trans) else: raise exceptions.PermissionDenied, \ 'The object was not copied.\n' + \ 'The user has insufficient permissions.'
def __create_guest_session(self): # create new session with the specified guest user self.user = _db.get_item(settings['sessionmanager']['guest']) new_session = SessionManager.create(settings['sessionmanager']['guest']) session_id = new_session.sessionid query_string = self.request.getQueryString() if '_nojavascript' in query_string: root_url = self.request.getRootUrl() path = self.request.serverVariables['PATH_INFO'] self.response.redirect( '%(root_url)s/{%(session_id)s}%(path)s' % locals() ) # add cookie with sessionid self.response.cookies['_sid'] = session_id self.response.cookies['_sid']['path'] = \ self.request.serverVariables['SCRIPT_NAME'] return new_session
def apply(context, item, registration, **kwargs): policyid = kwargs['policyid'] policy = _db.get_item(policyid) user = context.user policyGrantedTo = policy.policyGranted.value userID = user._id if userID in policyGrantedTo or user.is_admin(): return memberOf = ['everyone'] memberOf.extend(user.memberof.value) if hasattr(user, 'authenticate'): memberOf.append('authusers') for groupid in memberOf: if groupid in policyGrantedTo: return raise exceptions.PermissionDenied( "This action is restricted due to policy '%s'" % policy.displayName.value)
def execute_command(self, cmd, request): try: # DB maintenance commands if cmd == 'DB_BACKUP': output_file = request.data if not os.path.isdir(os.path.dirname(output_file)): raise IOError services.lock_db() try: _db.backup(output_file) finally: services.unlock_db() return (0, 'Database backup completed successfully.') elif cmd == 'DB_RESTORE': backup_set = request.data if not os.path.exists(backup_set): raise IOError services.lock_db() services.close_db() try: _db.restore(backup_set) finally: services.open_db() services.unlock_db() return (0, 'Database restore completed successfully.') elif cmd == 'DB_SHRINK': iLogs = _db.shrink() if iLogs: return (0, 'Successfully removed %d log files.' % iLogs) else: return (0, 'No log files removed.') # package management commands elif cmd == 'PACKAGE': ini_file = request.data my_pkg = None try: my_pkg = Package(ini_file=ini_file) my_pkg.create() finally: if my_pkg is not None: my_pkg.close() return (0, 'The package "%s-%s.ppf" was created succefully.' % (my_pkg.name, my_pkg.version)) elif cmd == 'INSTALL': # some scripts might require a security context from porcupine import context ppf_file = request.data my_pkg = None try: my_pkg = Package(package_file=ppf_file) # install as system context.user = _db.get_item('system') my_pkg.install() finally: if my_pkg is not None: my_pkg.close() context.user = None return (0, 'The package "%s" was installed succefully.' % ppf_file) elif cmd == 'UNINSTALL': # some scripts might require a security context from porcupine import context ppf_file = request.data my_pkg = None try: my_pkg = Package(package_file=ppf_file) # uninstall as system context.user = _db.get_item('system') my_pkg.uninstall() finally: if my_pkg is not None: my_pkg.close() context.user = None return (0, 'The package "%s" was uninstalled succefully.' % ppf_file) # replication commands elif cmd == 'SITE_INFO': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: site_list = list(rep_mgr.get_site_list().values()) site_list.append( rep_mgr.local_site.address + (1,)) #print site_list info = [str.format('{0:25}{1:10}{2:6}', 'SITE', 'STATUS', 'MASTER'), '-' * 41] for site in site_list: site_address = site[:2] if site[2] == 1: s = 'ONLINE' else: s = 'OFFLINE' if rep_mgr.master and \ rep_mgr.master.address == site_address: m = 'X' else: m = '' info.append(str.format('{0:25}{1:10}{2:6}', site_address, s, m)) info.append('') info.append('Total sites: %d' % len(site_list)) return (0, '\n'.join(info)) else: raise NotImplementedError elif cmd == 'REP_JOIN_SITE': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: site = request.data #print('adding remote site %s' % (site.address, )) site_list = rep_mgr.sites.values() + [rep_mgr.local_site] rep_mgr.broadcast(MgtMessage('REP_ADD_REMOTE_SITE', site)) rep_mgr.add_remote_site(site) return (0, [rep_mgr.master, site_list]) else: raise NotImplementedError elif cmd == 'REP_ADD_REMOTE_SITE': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: site = request.data #print('adding remote site %s' % (site.address, )) rep_mgr.add_remote_site(site) return (0, None) else: raise NotImplementedError elif cmd == 'REP_NEW_MASTER': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: master = request.data #print('new master is %s' % (master.address, )) rep_mgr.master = master services.notify(('NEW_MASTER', master)) return (0, None) else: raise NotImplementedError # other elif cmd == 'RELOAD': mod = misc.get_rto_by_name(request.data) misc.reload_module_tree(mod) services.notify(('RELOAD_PACKAGE', request.data)) return (0, 'Reloaded module tree "%s"' % request.data) # unknown command else: logger.warning( 'Management service received unknown command: %s' % cmd) return (-1, 'Unknown command.') except IOError: return (-1, 'Invalid file path.') except NotImplementedError: return (-1, 'Unsupported command.')
def apply(context, item, registration, **kwargs): user = _db.get_item(kwargs['userid']) context.original_user = context.user context.user = user
def handle_request(self, rh, raw_request=None): if raw_request is None: raw_request = loads(rh.input_buffer) response = context.response = HttpResponse() request = context.request = HttpRequest(raw_request) item = None registration = None # get sessionid session_id = None cookies_enabled = True path_info = request.serverVariables['PATH_INFO'] #print(path_info) # detect if sessionid is injected in the URL session_match = re.match(self._sid_pattern, path_info) if session_match: path_info = path_info.replace(session_match.group(), '', 1) or '/' request.serverVariables['PATH_INFO'] = path_info session_id = session_match.group(1) cookies_enabled = False # otherwise check cookie elif '_sid' in request.cookies: session_id = request.cookies['_sid'].value cookies_enabled = True try: try: path_tokens = path_info.split('/') if len(path_tokens) > 1: dir_name = path_tokens[1] web_app = pubdirs.dirs.get(dir_name, None) else: web_app = None if web_app is None: # create snapshot txn for reads context._trans = _db.get_transaction(snapshot=True) # try to get the requested object from the db item = _db.get_item(path_info) if item is not None and not item._isDeleted: self._fetch_session(session_id, cookies_enabled) self._dispatch_method(item) else: raise exceptions.NotFound( 'The resource "%s" does not exist' % path_info) else: # request to a published directory self._fetch_session(session_id, cookies_enabled) # remove blank entry & app name to get the requested path dir_path = '/'.join(path_tokens[2:]) registration = web_app.get_registration( dir_path, request.serverVariables['REQUEST_METHOD'], request.serverVariables['HTTP_USER_AGENT'], request.get_lang()) if not registration: raise exceptions.NotFound( 'The resource "%s" does not exist' % path_info) # apply pre-processing filters [filter[0].apply(context, item, registration, **filter[1]) for filter in registration.filters if filter[0].type == 'pre'] rtype = registration.type if rtype == 1: # psp page # create snapshot txn for reads context._trans = _db.get_transaction(snapshot=True) ServerPage.execute(context, registration.context) elif rtype == 0: # static file f_name = registration.context if_none_match = request.HTTP_IF_NONE_MATCH if if_none_match is not None and if_none_match == \ '"%s"' % misc.generate_file_etag(f_name): response._code = 304 else: response.load_from_file(f_name) if not any([f[0].mutates_output for f in registration.filters if f[0].type == 'post']): response.set_header( 'ETag', '"%s"' % misc.generate_file_etag(f_name)) if registration.encoding: response.charset = registration.encoding except exceptions.ResponseEnd as e: pass if registration is not None and response._code == 200: # do we have caching directive? if registration.max_age: response.set_expiration(registration.max_age) # apply post-processing filters [filter[0].apply(context, item, registration, **filter[1]) for filter in registration.filters if filter[0].type == 'post'] except exceptions.InternalRedirect as e: lstPathInfo = e.args[0].split('?') raw_request['env']['PATH_INFO'] = lstPathInfo[0] if len(lstPathInfo) == 2: raw_request['env']['QUERY_STRING'] = lstPathInfo[1] else: raw_request['env']['QUERY_STRING'] = '' self.handle_request(rh, raw_request) except exceptions.DBReadOnly: context._teardown() # proxy request to master rep_mgr = _db.get_replication_manager() if rep_mgr.master is not None: master_addr = rep_mgr.master.req_address master_request = BaseRequest(rh.input_buffer) try: master_response = master_request.get_response(master_addr) except: pass else: rh.write_buffer(master_response) return e = exceptions.InternalServerError('Database is in read-only mode') e.output_traceback = False e.emit(context, item) except exceptions.PorcupineException as e: e.emit(context, item) except: e = exceptions.InternalServerError() e.emit(context, item) context._teardown() settings['requestinterfaces'][request.interface](rh, response)