Custom Storage Manager [v2] - OpenMarshal/npm-WebDAV-Server GitHub Wiki
A Storage Manager is an object which will manage the storage allocation of the resources.
If none is provided in the options of the server, a NoStorageManager instance will be used.
Interface
interface IStorageManager
{
reserve(ctx : RequestContext, fs : FileSystem, size : number, callback : (reserved : boolean) => void) : void
evaluateCreate(ctx : RequestContext, fs : FileSystem, path : Path, type : ResourceType, callback : IStorageManagerEvaluateCallback) : void
evaluateContent(ctx : RequestContext, fs : FileSystem, expectedSize : number, callback : IStorageManagerEvaluateCallback) : void
evaluateProperty(ctx : RequestContext, fs : FileSystem, name : string, value : ResourcePropertyValue, attributes : PropertyAttributes, callback : IStorageManagerEvaluateCallback) : void
available(ctx : RequestContext, fs : FileSystem, callback : (available : number) => void) : void
reserved(ctx : RequestContext, fs : FileSystem, callback : (reserved : number) => void) : void
}
type IStorageManagerEvaluateCallback = (size : number) => void;
Methods
reserve
Allocate a chunk of size size bytes. If it is not possible to allocate the requested chunk, the callback must be called with the value false, otherwise it must be called with the value true.
reserve(ctx : RequestContext, fs : FileSystem, size : number, callback : (reserved : boolean) => void) : void
available
Get how many bytes are still available for use for the current request context.
Returning -1 means infinity.
available(ctx : RequestContext, fs : FileSystem, callback : (available : number) => void) : void
reserved
Get how many bytes are already used for the current request context.
reserved(ctx : RequestContext, fs : FileSystem, callback : (reserved : number) => void) : void
evaluateCreate
Evaluates the size of the creation of a new empty resource.
evaluateCreate(ctx : RequestContext, fs : FileSystem, path : Path, type : ResourceType, callback : IStorageManagerEvaluateCallback) : void
evaluateContent
Evaluates the size of the content of a resource based on the actual size of it.
evaluateContent(ctx : RequestContext, fs : FileSystem, expectedSize : number, callback : IStorageManagerEvaluateCallback) : void
evaluateProperty
Evaluates the size of a property.
evaluateProperty(ctx : RequestContext, fs : FileSystem, name : string, value : ResourcePropertyValue, attributes : PropertyAttributes, callback : IStorageManagerEvaluateCallback) : void
Examples
NoStorageManager
class NoStorageManager implements IStorageManager
{
reserve(ctx : RequestContext, fs : FileSystem, size : number, callback : (reserved : boolean) => void) : void
{
callback(true);
}
evaluateCreate(ctx : RequestContext, fs : FileSystem, path : Path, type : ResourceType, callback : IStorageManagerEvaluateCallback) : void
{
callback(0);
}
evaluateContent(ctx : RequestContext, fs : FileSystem, expectedSize : number, callback : IStorageManagerEvaluateCallback) : void
{
callback(0);
}
evaluateProperty(ctx : RequestContext, fs : FileSystem, name : string, value : ResourcePropertyValue, attributes : PropertyAttributes, callback : IStorageManagerEvaluateCallback) : void
{
callback(0);
}
available(ctx : RequestContext, fs : FileSystem, callback : (available : number) => void) : void
{
callback(-1);
}
reserved(ctx : RequestContext, fs : FileSystem, callback : (reserved : number) => void) : void
{
callback(0);
}
}
PerUserStorageManager
class PerUserStorageManager implements IStorageManager
{
storage : {
[UUID : string] : number
}
constructor(public limitPerUser : number)
{
this.storage = {};
}
reserve(ctx : RequestContext, fs : FileSystem, size : number, callback : (reserved : boolean) => void) : void
{
let nb = this.storage[ctx.user.uid];
if(nb === undefined)
nb = 0;
nb += size;
if(nb > this.limitPerUser)
return callback(false);
this.storage[ctx.user.uid] = Math.max(0, nb);
callback(true);
}
evaluateCreate(ctx : RequestContext, fs : FileSystem, path : Path, type : ResourceType, callback : IStorageManagerEvaluateCallback) : void
{
fs.getFullPath(ctx, path, (e, fullPath) => {
callback(fullPath.toString().length);
})
}
evaluateContent(ctx : RequestContext, fs : FileSystem, expectedSize : number, callback : IStorageManagerEvaluateCallback) : void
{
callback(expectedSize);
}
evalPropValue(value : ResourcePropertyValue) : number
{
if(!value)
return 0;
if(value.constructor === String)
return (value as String).length;
if(Array.isArray(value))
return (value as XMLElement[]).map((el) => this.evalPropValue(el)).reduce((p, n) => p + n, 0);
const xml = value as XMLElement;
const attributesLength = Object.keys(xml.attributes).map((at) => at.length + (xml.attributes[at].length as number)).reduce((p, n) => p + n, 0);
return xml.name.length + attributesLength + (xml.elements && xml.elements.length > 0 ? this.evalPropValue(xml.elements) : 0);
}
evaluateProperty(ctx : RequestContext, fs : FileSystem, name : string, value : ResourcePropertyValue, attributes : PropertyAttributes, callback : IStorageManagerEvaluateCallback) : void
{
callback(name.length + Object.keys(attributes).map((ak) => attributes[ak].length + ak.length).reduce((p, n) => p + n, 0) + this.evalPropValue(value));
}
available(ctx : RequestContext, fs : FileSystem, callback : (available : number) => void) : void
{
const nb = this.storage[ctx.user.uid];
callback(nb === undefined ? this.limitPerUser : this.limitPerUser - nb);
}
reserved(ctx : RequestContext, fs : FileSystem, callback : (reserved : number) => void) : void
{
const nb = this.storage[ctx.user.uid];
callback(nb === undefined ? 0 : nb);
}
}