def fake_send_request(request_type, **kwargs): for arg in ["uid", "gid"]: assert arg in kwargs.keys() assert request_type == HttpFsRequest.OP_READDIR assert kwargs["path"] == fake_path resp = HttpFsResponse() resp._response_data["dir_listing"] = list() return resp
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_CREATE for required_key in ["uid", "gid"]: assert required_key in kwargs.keys() assert kwargs["path"] == fake_path assert kwargs["mode"] == fake_mode resp = HttpFsResponse() resp._response_data["file_descriptor"] = 0 return resp
def fake_send_request(request_type, **kwargs): for arg in ["uid", "gid"]: assert arg in kwargs.keys() assert request_type == HttpFsRequest.OP_WRITE assert kwargs["file_descriptor"] == fake_fd assert kwargs["data"] == base64.standard_b64encode(fake_data).decode("utf-8") assert kwargs["offset"] == fake_offset resp = HttpFsResponse() resp._response_data["bytes_written"] = 10 return resp
def on_invalid_request(self, err_msg): """ Called when invalid JSON has been sent as a request from a client :param err_msg: The error message """ logging.debug("Invalid request received from {}: '{}'".format( self.client_address[0], err_msg)) response_obj = HttpFsResponse(errno.EIO, {"message": err_msg}) self.send_json_response(http.HTTPStatus.BAD_REQUEST, response_obj.as_dict())
def fake_send_request(request_type, **kwargs): for arg in ["uid", "gid"]: assert arg in kwargs.keys() assert request_type == HttpFsRequest.OP_READ assert kwargs["file_descriptor"] == fake_fd assert kwargs["size"] == fake_size assert kwargs["offset"] == fake_offset resp = HttpFsResponse() resp._response_data["bytes_read"] = bytes() return resp
def on_readdir(self, httpfs_request_args): """ Called when HttpFsRequest.OP_READDIR is requested :param httpfs_request_args: The client request args dict """ path = self.get_abs_path(httpfs_request_args["path"]) uid = httpfs_request_args["uid"] gid = httpfs_request_args["gid"] file_stats = os.stat(path) is_owner = file_stats.st_uid == uid is_group = file_stats.st_gid == gid response_obj = HttpFsResponse() if uid == 0: access_ok = True elif is_owner: access_ok = file_stats.st_mode & stat.S_IRUSR elif is_group: access_ok = file_stats.st_mode & stat.S_IRGRP else: access_ok = file_stats.st_mode & stat.S_IROTH if access_ok: dir_listing = os.listdir(path) dir_listing = [".", ".."] + dir_listing response_obj.set_data({"dir_listing": dir_listing}) else: logging.warning("Error during readdir request: Access denied") response_obj.set_err_no(errno.EACCES) response_obj.set_data({"message": "Access denied"}) self.send_json_response(200, response_obj.as_dict())
def on_statfs(self, httpfs_request_args): """ Called when HttpFsRequest.OP_STAT_FS is received from the client :param httpfs_request_args: The client request arg dict """ fs_path = self.get_abs_path(httpfs_request_args["path"]) statfs_os_result = os.statvfs(fs_path) statfs_result = dict() for k in _HttpFsRequestHandler.STAT_FS_KEYS: statfs_result[k] = getattr(statfs_os_result, k) response_obj = HttpFsResponse(response_data=statfs_result) self.send_json_response(200, response_obj.as_dict())
def on_release(self, httpfs_request_args): """ Called when HttpFsRequest.OP_RELEASE is requested :param httpfs_request_args: The client request args dict """ response_obj = HttpFsResponse() try: os.close(httpfs_request_args["file_descriptor"]) except Exception as e: logging.error("Error during release request: {}".format(e)) response_obj.set_err_no(errno.EIO) self.send_json_response(200, response_obj.as_dict())
def fake_send_request(request_type, **kwargs): for arg in ["uid", "gid"]: assert arg in kwargs.keys() assert request_type == HttpFsRequest.OP_RENAME assert kwargs["old_path"] == fake_old_path assert kwargs["new_path"] == fake_new_path return HttpFsResponse()
def on_symlink(self, httpfs_request_args): """ Called when HttpFsRequest.OP_SYMLINK is received from the client :param httpfs_request_args: The client request arg dict """ response_obj = HttpFsResponse() source = self.get_abs_path(httpfs_request_args["source"]) target = self.get_abs_path(httpfs_request_args["target"]) try: os.symlink(source, target) except Exception as e: logging.error("Error during symlink request: {}".format(e)) response_obj.set_err_no(errno.EIO) self.send_json_response(200, response_obj.as_dict())
def fake_send_request(request_type, **kwargs): for arg in ["uid", "gid"]: assert arg in kwargs.keys() assert request_type == HttpFsRequest.OP_UTIMENS assert kwargs["path"] == fake_path assert kwargs["times"] == fake_times return HttpFsResponse()
def fake_send_request(request_type, **kwargs): for arg in ["uid", "gid"]: assert arg in kwargs.keys() assert request_type == HttpFsRequest.OP_OPEN assert kwargs["path"] == fake_path assert kwargs["flags"] == fake_flags return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_CHMOD for required_key in ["uid", "gid"]: assert required_key in kwargs.keys() assert kwargs["path"] == fake_path assert kwargs["mode"] == fake_mode return HttpFsResponse()
def on_rmdir(self, httpfs_request_args): """ Called when HttpFsRequest.OP_RMDIR is requested :param httpfs_request_args: The client request args dict """ response_obj = HttpFsResponse() path = self.get_abs_path(httpfs_request_args["path"]) _error = None _err = None try: os.rmdir(path) except FileNotFoundError as e: logging.error("{} not found".format(path)) err = errno.ENOENT _error = e except OSError as e: err = e.errno _error = e except Exception as e: err = errno.EIO _error = e if _error != None: logging.error("Error during rmdir request: {}".format(_error)) response_obj.set_err_no(_err) response_obj.set_data({"message": str(_error)}) self.send_json_response(200, response_obj.as_dict())
def on_valid_request(self, request_dict): """ Called when a valid JSON request has been sent from a client :param request_dict: JSON request converted to dict object """ cred_store = self.server.get_cred_store() auth_enabled = cred_store is not None has_auth_header = auth_enabled and "Authorization" in self.headers is_authorized = not auth_enabled or ( has_auth_header and cred_store.has_cred(self.headers["Authorization"])) if "User-Agent" not in self.headers or not self.headers[ "User-Agent"].startswith("HttpFsClient"): raise RuntimeError( "Invalid User-Agent header: Client is not an HttpFsClient") if not is_authorized: logging.error("{} is not authorized".format( self.client_address[0])) response = HttpFsResponse(errno.EACCES, {"message": "Invalid API key"}) self.send_json_response(http.HTTPStatus.UNAUTHORIZED, response.as_dict()) else: try: request = HttpFsRequest.from_dict(request_dict) self._delegate_request(request) except Exception as e: response = HttpFsResponse(errno.EIO, {"message": str(e)}) self.send_json_response(http.HTTPStatus.BAD_REQUEST, response.as_dict())
def on_flush(self, httpfs_request_args): """ Called when HttpFsRequest.OP_FLUSH is received from the client :param httpfs_request_args: The client request arg dict """ response_obj = HttpFsResponse() try: os.fsync(httpfs_request_args["file_descriptor"]) except Exception as e: logging.error("Error during flush request: {}".format(e)) response_obj.set_err_no(errno.EIO) response_obj.set_data({"message": str(e)}) self.send_json_response(http.HTTPStatus.OK, response_obj.as_dict())
def on_mkdir(self, httpfs_request_args): """ Called when HttpFsRequest.OP_MKDIR is requested :param httpfs_request_args: The client request args dict """ response_obj = HttpFsResponse() path = self.get_abs_path(httpfs_request_args["path"]) try: os.mkdir(path, mode=httpfs_request_args["mode"]) except Exception as e: logging.error("Error during mkdir request: {}".format(e)) response_obj.set_err_no(errno.EIO) response_obj.set_data({"message": str(e)}) self.send_json_response(http.HTTPStatus.OK, response_obj.as_dict())
def on_truncate(self, httpfs_request_args): """ Called when HttpFsRequest.OP_TRUNCATE is received from the client :param httpfs_request_args: The client request arg dict """ response_obj = HttpFsResponse() path = self.get_abs_path(httpfs_request_args["path"]) length = httpfs_request_args["length"] try: with open(path, 'r+') as f: f.truncate(length) except Exception as e: logging.error("Error during truncate request: {}".format(e)) response_obj.set_err_no(errno.EIO) response_obj.set_data({"message": str(e)}) self.send_json_response(200, response_obj.as_dict())
def on_link(self, httpfs_request_args): """ Called when HttpFsRequest.OP_LINK is requested :param httpfs_request_args: The client request args dict """ target_path = self.get_abs_path(httpfs_request_args["target"]) source_path = self.get_abs_path(httpfs_request_args["source"]) response_obj = HttpFsResponse() try: os.link(source_path, target_path) except Exception as e: logging.error("Error during link request: {}".format(e)) response_obj.set_err_no(errno.EIO) response_obj.set_data({"message": str(e)}) self.send_json_response(http.HTTPStatus.OK, response_obj.as_dict())
def _send_request(self, request_type, **kwargs): """ Sends an HttpFsRequest of the given type with the given kwargs :param request_type: The request type to send :param kwargs: The arguments for the request :return: The HttpFsResponse """ request = HttpFsRequest(request_type, kwargs) try: headers = dict() if self._api_key is not None: headers["Authorization"] = self._api_key response = self._http_keepalive_session.post( self._server_url, json=request.as_dict(), allow_redirects=False, timeout=10, headers=headers, stream=True) response.raise_for_status() # Minimal server response validation is_json = response.headers.get("Content-Type").startswith( "application/json") is_httpfs_server = response.headers.get("Server").startswith( "HttpFs") if not is_json or not is_httpfs_server: logging.error("Server response didn't come from HttpFs") raise FuseOSError(errno.EIO) return HttpFsResponse.from_dict(response.json()) except requests.exceptions.HTTPError as http_error: logging.error(http_error) raise FuseOSError(errno.EACCES) except Exception as exception: logging.error(exception) raise FuseOSError(errno.EIO)
def on_readlink(self, httpfs_request_args): # TODO: This doesn't work """ Called when HttpFsRequest.OP_RELEASE is requested :param httpfs_request_args: The client request args dict """ response_obj = HttpFsResponse() link_path = self.get_abs_path(httpfs_request_args["link_path"]) try: target = os.readlink(link_path) if target.startswith("/"): target = os.path.relpath(target, self.server.get_fs_root()) response_obj.set_data({"target": target}) except Exception as e: logging.error("Error during readlink request: {}".format(e)) response_obj.set_err_no(errno.EIO) self.send_json_response(200, response_obj.as_dict())
def on_getattr(self, httpfs_request_args): """ Called when HttpFsRequest.OP_GET_ATTR is requested :param httpfs_request_args: The client request args dict """ response_obj = HttpFsResponse() path = self.get_abs_path(httpfs_request_args["path"]) try: os_attrs = os.lstat(path) attrs = dict() for k in _HttpFsRequestHandler.GETATTR_KEYS: attrs[k] = getattr(os_attrs, k) response_obj.set_data(attrs) except FileNotFoundError: logging.warning("{} not found".format(path)) response_obj.set_err_no(errno.ENOENT) self.send_json_response(200, response_obj.as_dict())
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_FSYNC assert kwargs["file_descriptor"] == fake_fd assert kwargs["datasync"] == fake_ds return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_TRUNCATE assert kwargs["path"] == fake_path assert kwargs["length"] == fake_len return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_SYMLINK assert kwargs["target"] == fake_target assert kwargs["source"] == fake_source return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_STAT_FS assert kwargs["path"] == fake_path return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_RELEASE assert kwargs["file_descriptor"] == fake_fd return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_READLINK assert kwargs["link_path"] == fake_path resp = HttpFsResponse() resp._response_data["target"] = "" return resp
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_CHOWN assert kwargs["path"] == fake_path assert kwargs["uid"] == 2222 assert kwargs["gid"] == 0 return HttpFsResponse()
def fake_send_request(request_type, **kwargs): assert request_type == HttpFsRequest.OP_MKNOD assert kwargs["path"] == fake_path assert kwargs["mode"] == fake_mode assert kwargs["dev"] == fake_dev return HttpFsResponse()