2025-10-01 19:55:38 +02:00

435 lines
17 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var RequestContext_1 = require("../RequestContext");
var WebDAVServerOptions_1 = require("../WebDAVServerOptions");
var JSCompatibility_1 = require("../../../helper/JSCompatibility");
var Path_1 = require("../../../manager/v2/Path");
var Commands_1 = require("../commands/Commands");
var persistence = require("./Persistence");
var beforeAfter = require("./BeforeAfter");
var startStop = require("./StartStop");
var promise_1 = require("../../../helper/v2/promise");
var WebDAVServer = /** @class */ (function () {
function WebDAVServer(options) {
/**
* Stop the WebDAV server.
*/
this.stop = startStop.stop;
/**
* Execute a request as if the HTTP server received it.
*/
this.executeRequest = startStop.executeRequest.bind(this);
/**
* Load the previous save made by the 'autoSave' system.
*/
this.autoLoad = persistence.autoLoad;
/**
* Load a state of the resource tree.
*/
this.load = persistence.load;
/**
* Save the state of the resource tree.
*/
this.save = persistence.save;
this.beforeManagers = [];
this.afterManagers = [];
this.methods = {};
this.options = WebDAVServerOptions_1.setDefaultServerOptions(options);
this.events = {};
this.httpAuthentication = this.options.httpAuthentication;
this.privilegeManager = this.options.privilegeManager;
this.fileSystems = {
'/': this.options.rootFileSystem
};
// Implement all methods in commands/Commands.ts
var commands = Commands_1.default;
for (var k in commands)
if (k === 'NotImplemented')
this.onUnknownMethod(new commands[k]());
else
this.method(k, new commands[k]());
}
WebDAVServer.prototype.isSameFileSystem = function (fs, path, checkByReference) {
return checkByReference && this.fileSystems[path] === fs || !checkByReference && this.fileSystems[path].serializer().uid() === fs.serializer().uid();
};
WebDAVServer.prototype.createExternalContext = function (_options, _callback) {
return RequestContext_1.ExternalRequestContext.create(this, _options, _callback);
};
/**
* Get the root file system.
*
* @returns The root file system
*/
WebDAVServer.prototype.rootFileSystem = function () {
return this.fileSystems['/'];
};
/**
* Get a resource object to manage a resource from its path.
*
* @param ctx Context of the request
* @param path Path of the resource
*/
WebDAVServer.prototype.getResourceAsync = function (ctx, path) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.getResource(ctx, path, cb); });
};
/**
* Get a resource object to manage a resource from its path.
*
* @param ctx Context of the request
* @param path Path of the resource
* @param callback Callback containing the requested resource
*/
WebDAVServer.prototype.getResource = function (ctx, path, callback) {
path = new Path_1.Path(path);
this.getFileSystem(path, function (fs, _, subPath) {
callback(null, fs.resource(ctx, subPath));
});
};
/**
* Synchronously get a resource object to manage a resource from its path.
*
* @param ctx Context of the request
* @param path Path of the resource
* @returns The requested resource
*/
WebDAVServer.prototype.getResourceSync = function (ctx, path) {
path = new Path_1.Path(path);
var info = this.getFileSystemSync(path);
return info.fs.resource(ctx, info.subPath);
};
WebDAVServer.prototype.setFileSystemAsync = function (path, fs, override) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.setFileSystem(path, fs, override, function (successed) { return cb(undefined, successed); }); });
};
WebDAVServer.prototype.setFileSystem = function (path, fs, _override, _callback) {
var override = _callback ? _override : undefined;
var callback = _callback ? _callback : _override;
var result = this.setFileSystemSync(path, fs, override);
if (callback)
callback(result);
};
/**
* Synchronously map/mount a file system to a path.
*
* @param path Path where to mount the file system
* @param fs File system to mount
* @param override Define if the mounting can override a previous mounted file system
* @returns The status of the mounting
*/
WebDAVServer.prototype.setFileSystemSync = function (path, fs, override) {
if (override === void 0) { override = true; }
var sPath = new Path_1.Path(path).toString();
if (!override && this.fileSystems[sPath])
return false;
this.fileSystems[sPath] = fs;
return true;
};
WebDAVServer.prototype.removeFileSystem = function (fs_path, _checkByReference, _callback) {
var checkByReference = _callback ? _checkByReference : true;
var callback = _callback ? _callback : _checkByReference;
var result = this.removeFileSystemSync(fs_path, checkByReference);
if (callback)
callback(result);
};
WebDAVServer.prototype.removeFileSystemSync = function (fs_path, checkByReference) {
if (checkByReference === void 0) { checkByReference = true; }
var nb = 0;
if (fs_path.constructor === Path_1.Path || fs_path.constructor === String) {
var path = new Path_1.Path(fs_path).toString();
if (this.fileSystems[path] !== undefined) {
delete this.fileSystems[path];
nb = 1;
}
}
else {
var fs = fs_path;
for (var name_1 in this.fileSystems) {
if (this.isSameFileSystem(fs, name_1, checkByReference)) {
delete this.fileSystems[name_1];
++nb;
}
}
}
return nb;
};
WebDAVServer.prototype.getFileSystemPath = function (fs, _checkByReference, _callback) {
var checkByReference = _callback ? _checkByReference : undefined;
var callback = _callback ? _callback : _checkByReference;
callback(this.getFileSystemPathSync(fs, checkByReference));
};
/**
* Synchronously get the mount path of a file system.
*
* @param fs File system
* @param checkByReference Define if the file system must be matched by reference or by its serializer's UID
* @returns The mount path of the file system
*/
WebDAVServer.prototype.getFileSystemPathSync = function (fs, checkByReference) {
checkByReference = checkByReference === null || checkByReference === undefined ? true : checkByReference;
for (var path in this.fileSystems)
if (this.isSameFileSystem(fs, path, checkByReference))
return new Path_1.Path(path);
return null;
};
/**
* Get the list of file systems mounted on or under the parentPath.
*
* @param parentPath Path from which list sub file systems
* @param callback Callback containing the list of file systems found and their mount path
*/
WebDAVServer.prototype.getChildFileSystems = function (parentPath, callback) {
var result = this.getChildFileSystemsSync(parentPath);
callback(result);
};
/**
* Synchronously get the list of file systems mounted on or under the parentPath.
*
* @param parentPath Path from which list sub file systems
* @returns Object containing the list of file systems found and their mount path
*/
WebDAVServer.prototype.getChildFileSystemsSync = function (parentPath) {
var results = [];
var seekPath = parentPath.toString(true);
for (var fsPath in this.fileSystems) {
var pfsPath = new Path_1.Path(fsPath);
if (pfsPath.paths.length === parentPath.paths.length + 1 && JSCompatibility_1.startsWith(fsPath, seekPath)) {
results.push({
fs: this.fileSystems[fsPath],
path: pfsPath
});
}
}
return results;
};
/**
* Get the file system managing the provided path.
*
* @param path Requested path
*/
WebDAVServer.prototype.getFileSystemAsync = function (path) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.getFileSystem(path, function (fs, rootPath, subPath) { return cb(undefined, { fs: fs, rootPath: rootPath, subPath: subPath }); }); });
};
/**
* Get the file system managing the provided path.
*
* @param path Requested path
* @param callback Callback containing the file system, the mount path of the file system and the sub path from the mount path to the requested path
*/
WebDAVServer.prototype.getFileSystem = function (path, callback) {
var result = this.getFileSystemSync(path);
callback(result.fs, result.rootPath, result.subPath);
};
/**
* Get synchronously the file system managing the provided path.
*
* @param path Requested path
* @returns Object containing the file system, the mount path of the file system and the sub path from the mount path to the requested path
*/
WebDAVServer.prototype.getFileSystemSync = function (path) {
var best = {
index: 0,
rootPath: new Path_1.Path('/')
};
for (var fsPath in this.fileSystems) {
var pfsPath = new Path_1.Path(fsPath);
if (path.paths.length < pfsPath.paths.length)
continue;
var value = 0;
for (; value < pfsPath.paths.length; ++value)
if (pfsPath.paths[value] !== path.paths[value]) {
value = -1;
break;
}
if (best.index < value)
best = {
index: value,
rootPath: pfsPath
};
if (value === path.paths.length)
break; // Found the best value possible.
}
var subPath = path.clone();
for (var _i = 0, _a = best.rootPath.paths; _i < _a.length; _i++) {
var _ = _a[_i];
subPath.removeRoot();
}
return {
fs: this.fileSystems[best.rootPath.toString()],
rootPath: best.rootPath,
subPath: subPath
};
};
/**
* Action to execute when the requested method is unknown.
*
* @param unknownMethod Action to execute
*/
WebDAVServer.prototype.onUnknownMethod = function (unknownMethod) {
this.unknownMethod = unknownMethod;
};
WebDAVServer.prototype.listResourcesAsync = function (root) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.listResources(root, function (paths) { return cb(undefined, paths); }); });
};
WebDAVServer.prototype.listResources = function (_root, _callback) {
var _this = this;
var root = new Path_1.Path(Path_1.Path.isPath(_root) ? _root : '/');
var callback = _callback ? _callback : _root;
var output = [];
output.push(root.toString());
this.getResource(this.createExternalContext(), root, function (e, resource) {
resource.readDir(true, function (e, files) {
if (e || files.length === 0)
return callback(output);
var nb = files.length;
files.forEach(function (fileName) {
var childPath = root.getChildPath(fileName);
_this.listResources(childPath, function (outputs) {
outputs.forEach(function (o) { return output.push(o); });
if (--nb === 0)
callback(output);
});
});
});
});
};
WebDAVServer.prototype.startAsync = function (port) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.start(port, function (server) { return cb(undefined, server); }); });
};
WebDAVServer.prototype.start = function (port, callback) {
startStop.start.bind(this)(port, callback);
};
/**
* Stop the WebDAV server.
*/
WebDAVServer.prototype.stopAsync = function () {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.stop(cb); });
};
WebDAVServer.prototype.autoSave = function (options) {
var fn = persistence.autoSave.bind(this);
if (options)
fn(options);
else if (this.options.autoSave)
fn(this.options.autoSave);
};
/**
* Force the autoSave system to save when available.
*/
WebDAVServer.prototype.forceAutoSave = function () {
this.autoSavePool.save();
};
/**
* Load the previous save made by the 'autoSave' system.
*/
WebDAVServer.prototype.autoLoadAsync = function () {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.autoLoad(cb); });
};
/**
* Load a state of the resource tree.
*/
WebDAVServer.prototype.loadAsync = function (data, serializers) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.load(data, serializers, cb); });
};
/**
* Save the state of the resource tree.
*/
WebDAVServer.prototype.saveAsync = function () {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.save(cb); });
};
/**
* Define an action to execute when a HTTP method is requested.
*
* @param name Name of the method to bind to
* @param manager Action to execute when the method is requested
*/
WebDAVServer.prototype.method = function (name, manager) {
this.methods[this.normalizeMethodName(name)] = manager;
};
WebDAVServer.prototype.on = function (event, listener) {
if (!this.events[event])
this.events[event] = [];
this.events[event].push(listener);
return this;
};
WebDAVServer.prototype.removeEvent = function (event, listener) {
if (listener) {
if (this.events[event]) {
var eventList = this.events[event];
for (var index = 0; index < eventList.length; ++index) {
if (eventList[index] === listener) {
eventList.splice(index, 1);
--index;
}
}
}
}
else {
delete this.events[event];
}
return this;
};
/**
* Trigger an event.
*
* @param event Name of the event.
* @param ctx Context of the event.
* @param fs File system on which the event happened.
* @param path Path of the resource on which the event happened.
*/
WebDAVServer.prototype.emit = function (event, ctx, fs, path, data) {
if (!this.events[event])
return;
this.events[event].forEach(function (l) { return process.nextTick(function () { return l(ctx, fs, path.constructor === String ? new Path_1.Path(path) : path, data); }); });
};
/**
* Normalize the name of the method.
*/
WebDAVServer.prototype.normalizeMethodName = function (method) {
return method.toLowerCase();
};
// Before / After execution
/**
* Invoke the BeforeRequest events.
*
* @param base Context of the request
* @param callback Callback to execute when all BeforeRequest events have been executed
*/
WebDAVServer.prototype.invokeBeforeRequest = function (base, callback) {
beforeAfter.invokeBeforeRequest.bind(this)(base, callback);
};
/**
* Invoke the AfterRequest events.
*
* @param base Context of the request
* @param callback Callback to execute when all AfterRequest events have been executed
*/
WebDAVServer.prototype.invokeAfterRequest = function (base, callback) {
beforeAfter.invokeAfterRequest.bind(this)(base, callback);
};
/**
* Action to execute before an operation is executed when a HTTP request is received.
*
* @param manager Action to execute
*/
WebDAVServer.prototype.beforeRequest = function (manager) {
this.beforeManagers.push(manager);
};
/**
* Action to execute after an operation is executed when a HTTP request is received.
*
* @param manager Action to execute
*/
WebDAVServer.prototype.afterRequest = function (manager) {
this.afterManagers.push(manager);
};
return WebDAVServer;
}());
exports.WebDAVServer = WebDAVServer;