file_manager: simplify directory registration
Now that the file_manager directly handles DELETE file requests, it is not necessary have the HTTP file handler perform any checks. Thus it is no longer required to pass a "can_delete" parameter. Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
2a967303cb
commit
36c82d0c7f
|
@ -9,6 +9,7 @@ import mimetypes
|
||||||
import logging
|
import logging
|
||||||
import tornado
|
import tornado
|
||||||
from inspect import isclass
|
from inspect import isclass
|
||||||
|
from tornado.escape import url_unescape
|
||||||
from tornado.routing import Rule, PathMatches, AnyMatches
|
from tornado.routing import Rule, PathMatches, AnyMatches
|
||||||
from utils import ServerError
|
from utils import ServerError
|
||||||
from websockets import WebsocketManager, WebSocket
|
from websockets import WebsocketManager, WebSocket
|
||||||
|
@ -186,8 +187,7 @@ class MoonrakerApp:
|
||||||
self.wsm.register_local_handler(api_def, callback)
|
self.wsm.register_local_handler(api_def, callback)
|
||||||
logging.info(msg)
|
logging.info(msg)
|
||||||
|
|
||||||
def register_static_file_handler(self, pattern, file_path,
|
def register_static_file_handler(self, pattern, file_path):
|
||||||
can_delete=False):
|
|
||||||
if pattern[0] != "/":
|
if pattern[0] != "/":
|
||||||
pattern = "/server/files/" + pattern
|
pattern = "/server/files/" + pattern
|
||||||
if os.path.isfile(file_path):
|
if os.path.isfile(file_path):
|
||||||
|
@ -200,12 +200,7 @@ class MoonrakerApp:
|
||||||
logging.info(f"Invalid file path: {file_path}")
|
logging.info(f"Invalid file path: {file_path}")
|
||||||
return
|
return
|
||||||
logging.debug(f"Registering static file: ({pattern}) {file_path}")
|
logging.debug(f"Registering static file: ({pattern}) {file_path}")
|
||||||
methods = ['GET']
|
params = {'server': self.server, 'auth': self.auth, 'path': file_path}
|
||||||
if can_delete:
|
|
||||||
methods.append('DELETE')
|
|
||||||
params = {
|
|
||||||
'server': self.server, 'auth': self.auth,
|
|
||||||
'path': file_path, 'methods': methods}
|
|
||||||
self.mutable_router.add_handler(pattern, FileRequestHandler, params)
|
self.mutable_router.add_handler(pattern, FileRequestHandler, params)
|
||||||
|
|
||||||
def register_upload_handler(self, pattern):
|
def register_upload_handler(self, pattern):
|
||||||
|
@ -321,12 +316,6 @@ class LocalRequestHandler(AuthorizedRequestHandler):
|
||||||
|
|
||||||
|
|
||||||
class FileRequestHandler(AuthorizedFileHandler):
|
class FileRequestHandler(AuthorizedFileHandler):
|
||||||
def initialize(self, server, auth, path, methods,
|
|
||||||
default_filename=None):
|
|
||||||
super(FileRequestHandler, self).initialize(
|
|
||||||
server, auth, path, default_filename)
|
|
||||||
self.methods = methods
|
|
||||||
|
|
||||||
def set_extra_headers(self, path):
|
def set_extra_headers(self, path):
|
||||||
# The call below shold never return an empty string,
|
# The call below shold never return an empty string,
|
||||||
# as the path should have already been validated to be
|
# as the path should have already been validated to be
|
||||||
|
@ -336,10 +325,8 @@ class FileRequestHandler(AuthorizedFileHandler):
|
||||||
"Content-Disposition", f"attachment; filename={basename}")
|
"Content-Disposition", f"attachment; filename={basename}")
|
||||||
|
|
||||||
async def delete(self, path):
|
async def delete(self, path):
|
||||||
if 'DELETE' not in self.methods:
|
|
||||||
raise tornado.web.HTTPError(405)
|
|
||||||
|
|
||||||
path = self.request.path.lstrip("/").split("/", 2)[-1]
|
path = self.request.path.lstrip("/").split("/", 2)[-1]
|
||||||
|
path = url_unescape(path)
|
||||||
file_manager = self.server.lookup_plugin('file_manager')
|
file_manager = self.server.lookup_plugin('file_manager')
|
||||||
try:
|
try:
|
||||||
filename = await file_manager.delete_file(path)
|
filename = await file_manager.delete_file(path)
|
||||||
|
@ -348,7 +335,7 @@ class FileRequestHandler(AuthorizedFileHandler):
|
||||||
raise tornado.web.HTTPError(
|
raise tornado.web.HTTPError(
|
||||||
403, "File is loaded, DELETE not permitted")
|
403, "File is loaded, DELETE not permitted")
|
||||||
else:
|
else:
|
||||||
raise tornado.web.HTTPError(400, str(e))
|
raise tornado.web.HTTPError(e.status_code, str(e))
|
||||||
self.finish({'result': filename})
|
self.finish({'result': filename})
|
||||||
|
|
||||||
class FileUploadHandler(AuthorizedRequestHandler):
|
class FileUploadHandler(AuthorizedRequestHandler):
|
||||||
|
|
|
@ -297,8 +297,7 @@ class Server:
|
||||||
vsd_path = vsd_config.get('path', None)
|
vsd_path = vsd_config.get('path', None)
|
||||||
if vsd_path is not None:
|
if vsd_path is not None:
|
||||||
file_manager = self.lookup_plugin('file_manager')
|
file_manager = self.lookup_plugin('file_manager')
|
||||||
file_manager.register_directory(
|
file_manager.register_directory('gcodes', vsd_path)
|
||||||
'gcodes', vsd_path, can_delete=True)
|
|
||||||
else:
|
else:
|
||||||
logging.info(
|
logging.info(
|
||||||
"Configuration for [virtual_sdcard] not found,"
|
"Configuration for [virtual_sdcard] not found,"
|
||||||
|
|
|
@ -22,7 +22,6 @@ class FileManager:
|
||||||
self.server = config.get_server()
|
self.server = config.get_server()
|
||||||
self.file_paths = {}
|
self.file_paths = {}
|
||||||
self.file_lists = {}
|
self.file_lists = {}
|
||||||
self.mutable_paths = set()
|
|
||||||
self.gcode_metadata = MetadataStorage(self.server)
|
self.gcode_metadata = MetadataStorage(self.server)
|
||||||
self.fixed_path_args = {}
|
self.fixed_path_args = {}
|
||||||
|
|
||||||
|
@ -48,8 +47,7 @@ class FileManager:
|
||||||
# Register Klippy Configuration Path
|
# Register Klippy Configuration Path
|
||||||
config_path = config.get('config_path', None)
|
config_path = config.get('config_path', None)
|
||||||
if config_path is not None:
|
if config_path is not None:
|
||||||
ret = self.register_directory(
|
ret = self.register_directory('config', config_path)
|
||||||
'config', config_path, can_delete=True)
|
|
||||||
if not ret:
|
if not ret:
|
||||||
raise config.error(
|
raise config.error(
|
||||||
"Option 'config_path' is not a valid directory")
|
"Option 'config_path' is not a valid directory")
|
||||||
|
@ -73,7 +71,7 @@ class FileManager:
|
||||||
log_path = os.path.normpath(os.path.expanduser(log_file))
|
log_path = os.path.normpath(os.path.expanduser(log_file))
|
||||||
self.server.register_static_file_handler("klippy.log", log_path)
|
self.server.register_static_file_handler("klippy.log", log_path)
|
||||||
|
|
||||||
def register_directory(self, base, path, can_delete=False):
|
def register_directory(self, base, path):
|
||||||
if path is None:
|
if path is None:
|
||||||
return False
|
return False
|
||||||
home = os.path.expanduser('~')
|
home = os.path.expanduser('~')
|
||||||
|
@ -87,10 +85,7 @@ class FileManager:
|
||||||
return False
|
return False
|
||||||
if path != self.file_paths.get(base, ""):
|
if path != self.file_paths.get(base, ""):
|
||||||
self.file_paths[base] = path
|
self.file_paths[base] = path
|
||||||
if can_delete:
|
self.server.register_static_file_handler(base, path)
|
||||||
self.mutable_paths.add(base)
|
|
||||||
self.server.register_static_file_handler(
|
|
||||||
base, path, can_delete=can_delete)
|
|
||||||
try:
|
try:
|
||||||
self._update_file_list(base=base)
|
self._update_file_list(base=base)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -449,14 +444,15 @@ class FileManager:
|
||||||
return await self.delete_file(file_path)
|
return await self.delete_file(file_path)
|
||||||
|
|
||||||
async def delete_file(self, path):
|
async def delete_file(self, path):
|
||||||
parts = path.split("/", 1)
|
parts = path.lstrip("/").split("/", 1)
|
||||||
|
if len(parts) != 2:
|
||||||
|
raise self.server.error(
|
||||||
|
f"Path not available for DELETE: {path}", 405)
|
||||||
root = parts[0]
|
root = parts[0]
|
||||||
filename = parts[1]
|
filename = parts[1]
|
||||||
if root not in self.file_paths or len(parts) != 2:
|
if root not in self.file_paths or root not in FULL_ACCESS_ROOTS:
|
||||||
raise self.server.error(f"Invalid file path: {path}")
|
|
||||||
if root not in self.mutable_paths:
|
|
||||||
raise self.server.error(
|
raise self.server.error(
|
||||||
f"Path not mutable, Cannot delete file: {path}")
|
f"Path not available for DELETE: {path}", 405)
|
||||||
root_path = self.file_paths[root]
|
root_path = self.file_paths[root]
|
||||||
full_path = os.path.join(root_path, filename)
|
full_path = os.path.join(root_path, filename)
|
||||||
if not os.path.isfile(full_path):
|
if not os.path.isfile(full_path):
|
||||||
|
|
Loading…
Reference in New Issue