def get_controller(self, req): """ Get the controller to handle a request. :param req: the request :returns: tuple of (controller class, path dictionary) :raises ValueError: (thrown by split_path) if given invalid path """ if req.path == '/info': d = dict(version=None, expose_info=self.expose_info, disallowed_sections=self.disallowed_sections, admin_key=self.admin_key) return InfoController, d #分割请求路径,eg. http://127.0.0.1:8080/auth/v1.0/account/container version, account, container, obj = split_path(req.path, 1, 4, True) d = dict(version=version, account_name=account, container_name=container, object_name=obj) # 如果account为空或者版本号不对,则抛出异常 if account and not valid_api_version(version): raise APIVersionError('Invalid path') # 如果account,container,object都存在,表明对object操作,则返回 object controller if obj and container and account: # info={"status": ..., "sync_key": null, "write_acl": null, "object_count": 1, # "storage_policy": 0, "versions": null, "bytes": ..., "meta": {}, "sharding_state": ..., # "cors": {"allow_origin": null, "expose_headers": null, "max_age": null}, # "sysmeta": {}, "read_acl": null} info = get_container_info(req.environ, self) policy_index = req.headers.get('X-Backend-Storage-Policy-Index', info['storage_policy']) policy = POLICIES.get_by_index(policy_index) if not policy: # This indicates that a new policy has been created, # with rings, deployed, released (i.e. deprecated = # False), used by a client to create a container via # another proxy that was restarted after the policy # was released, and is now cached - all before this # worker was HUPed to stop accepting new # connections. There should never be an "unknown" # index - but when there is - it's probably operator # error and hopefully temporary. raise HTTPServiceUnavailable('Unknown Storage Policy') # obj_controller_router[policy] 等价于调用obj_controller_router类中的 __getitem__(policy) # 根据策略选择返回 ECObjectController 对象 还是 ReplicatedObjectController 对象 return self.obj_controller_router[policy], d # 如果account,container都存在,表明对container操作,则返回 container controller elif container and account: return ContainerController, d # 如果只存在account,表明对account操作,则返回 account controller elif account and not container and not obj: return AccountController, d return None, d
def get_controller(self, req): """ Get the controller to handle a request. :param req: the request :returns: tuple of (controller class, path dictionary) :raises: ValueError (thrown by split_path) if given invalid path """ if req.path == '/info': d = dict(version=None, expose_info=self.expose_info, disallowed_sections=self.disallowed_sections, admin_key=self.admin_key) return InfoController, d #分割路径信息 version, account, container, obj = split_path(req.path, 1, 4, True) #生成包含version、account、container、object的路径字典,用于返回 d = dict(version=version, account_name=account, container_name=container, object_name=obj) if account and not valid_api_version(version): raise APIVersionError('Invalid path') #如果是对象操作 if obj and container and account: #获取container信息 info = get_container_info(req.environ, self) policy_index = req.headers.get('X-Backend-Storage-Policy-Index', info['storage_policy']) #通过index获取存储策略对象 policy = POLICIES.get_by_index(policy_index) if not policy: # This indicates that a new policy has been created, # with rings, deployed, released (i.e. deprecated = # False), used by a client to create a container via # another proxy that was restarted after the policy # was released, and is now cached - all before this # worker was HUPed to stop accepting new # connections. There should never be an "unknown" # index - but when there is - it's probably operator # error and hopefully temporary. raise HTTPServiceUnavailable('Unknown Storage Policy') #返回对象操作的控制器对象,以及路径字典 return self.obj_controller_router[policy], d #如果是container操作,返回container控制器,以及路径字典 elif container and account: return ContainerController, d #如果是account操作,返回account控制器,以及路径字典 elif account and not container and not obj: return AccountController, d return None, d