diff --git a/lib/server/MethodCallArgs.d.ts b/lib/server/MethodCallArgs.d.ts
index e4f4b130..f84f40ea 100644
--- a/lib/server/MethodCallArgs.d.ts
+++ b/lib/server/MethodCallArgs.d.ts
@@ -1,6 +1,7 @@
///
import { BasicPrivilege } from '../user/privilege/IPrivilegeManager';
import { IResource, ReturnCallback } from '../resource/IResource';
+import { EventsName, DetailsType } from './webDAVServer/Events';
import { XMLElement } from '../helper/XML';
import { WebDAVServer } from './webDAVServer/WebDAVServer';
import { FSPath } from '../manager/FSManager';
@@ -33,6 +34,8 @@ export declare class MethodCallArgs {
findHeader(name: string, defaultValue?: string): string;
getResource(callback: ReturnCallback): void;
dateISO8601(ticks: number): string;
+ invokeEvent(event: EventsName, subjectResource?: IResource, details?: DetailsType): void;
+ wrapEvent(event: EventsName, subjectResource?: IResource, details?: DetailsType): () => void;
fullUri(uri?: string): string;
prefixUri(): string;
getResourcePath(resource: IResource, callback: ReturnCallback): void;
diff --git a/lib/server/MethodCallArgs.js b/lib/server/MethodCallArgs.js
index 67770d93..d54b1912 100644
--- a/lib/server/MethodCallArgs.js
+++ b/lib/server/MethodCallArgs.js
@@ -139,6 +139,19 @@ var MethodCallArgs = (function () {
result += h + ':' + m;
return result;
};
+ MethodCallArgs.prototype.invokeEvent = function (event, subjectResource, details) {
+ this.server.invoke(event, this, subjectResource, details);
+ };
+ MethodCallArgs.prototype.wrapEvent = function (event, subjectResource, details) {
+ var _this = this;
+ var oldExit = this.exit;
+ this.exit = function () {
+ if (Math.floor(_this.response.statusCode / 100) === 2)
+ _this.invokeEvent(event, subjectResource, details);
+ oldExit();
+ };
+ return this.exit;
+ };
MethodCallArgs.prototype.fullUri = function (uri) {
if (uri === void 0) { uri = null; }
if (!uri)
diff --git a/lib/server/commands/Copy.js b/lib/server/commands/Copy.js
index ae93d247..7dfc2543 100644
--- a/lib/server/commands/Copy.js
+++ b/lib/server/commands/Copy.js
@@ -45,7 +45,9 @@ function copy(arg, source, rDest, destination, callback) {
var dest = rDest.fsManager.newResource(destination.toString(), destination.fileName(), type, rDest);
arg.requirePrivilege(['canCreate', 'canSetProperty', 'canWrite'], dest, function () {
dest.create(function (e) { return _(e, function () {
+ arg.invokeEvent('create', dest);
rDest.addChild(dest, function (e) { return _(e, function () {
+ arg.invokeEvent('addChild', rDest, dest);
copyAllProperties(source, dest, function (e) { return _(e, function () {
if (!type.isFile) {
next();
@@ -53,12 +55,19 @@ function copy(arg, source, rDest, destination, callback) {
}
source.read(true, function (e, rstream) { return _(e, function () {
dest.write(true, function (e, wstream) { return _(e, function () {
- rstream.on('end', next);
+ rstream.on('end', function () {
+ arg.invokeEvent('read', source);
+ next();
+ });
+ wstream.on('finish', function () {
+ arg.invokeEvent('write', dest);
+ });
rstream.pipe(wstream);
}); });
}); });
function next() {
if (!type.isDirectory) {
+ arg.invokeEvent('copy', source, dest);
callback(null);
return;
}
@@ -73,11 +82,14 @@ function copy(arg, source, rDest, destination, callback) {
return;
}
--nb;
- if (nb === 0)
+ if (nb === 0) {
+ arg.invokeEvent('copy', source, dest);
callback(null);
+ }
}
if (nb === 0) {
callback(null);
+ arg.invokeEvent('copy', source, dest);
return;
}
children.forEach(function (child) {
@@ -114,8 +126,11 @@ function default_1(arg, callback) {
callback();
return;
}
- destination = destination.substring(destination.indexOf('://') + '://'.length);
- destination = destination.substring(destination.indexOf('/'));
+ var startIndex = destination.indexOf('://');
+ if (startIndex !== -1) {
+ destination = destination.substring(startIndex + '://'.length);
+ destination = destination.substring(destination.indexOf('/'));
+ }
destination = new FSManager_1.FSPath(destination);
arg.server.getResourceFromPath(destination.getParent(), function (e, rDest) {
if (e) {
@@ -174,6 +189,7 @@ function default_1(arg, callback) {
callback(e);
return;
}
+ arg.invokeEvent('delete', destCollision);
done(true);
}); });
}); });
diff --git a/lib/server/commands/Delete.js b/lib/server/commands/Delete.js
index 16b469d4..c1b862c9 100644
--- a/lib/server/commands/Delete.js
+++ b/lib/server/commands/Delete.js
@@ -14,8 +14,10 @@ function default_1(arg, callback) {
r.delete(function (e) { return process.nextTick(function () {
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
+ arg.invokeEvent('delete', r);
+ }
callback();
}); });
});
diff --git a/lib/server/commands/Get.js b/lib/server/commands/Get.js
index 9d56863a..4c231ef7 100644
--- a/lib/server/commands/Get.js
+++ b/lib/server/commands/Get.js
@@ -61,6 +61,7 @@ function default_1(arg, callback) {
callback();
}
else {
+ arg.invokeEvent('read', r);
var range = arg.findHeader('Range');
if (range) {
var rex = /([0-9]+)/g;
diff --git a/lib/server/commands/Lock.js b/lib/server/commands/Lock.js
index c5458990..85268c00 100644
--- a/lib/server/commands/Lock.js
+++ b/lib/server/commands/Lock.js
@@ -56,12 +56,20 @@ function createLock(arg, callback) {
callback();
return;
}
+ arg.invokeEvent('create', resource);
r.addChild(resource, function (e) {
- if (e)
+ if (e) {
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
- arg.setCode(WebDAVRequest_1.HTTPCodes.Created);
- callback();
+ callback();
+ }
+ else {
+ arg.invokeEvent('addChild', r, resource);
+ writeLock(resource, function () {
+ arg.setCode(WebDAVRequest_1.HTTPCodes.Created);
+ arg.writeXML(createResponse(arg, lock_1));
+ callback();
+ });
+ }
});
}); });
});
@@ -75,7 +83,7 @@ function createLock(arg, callback) {
callback();
return;
}
- arg.checkIfHeader(r, function () {
+ function writeLock(r, cb) {
arg.requirePrivilege(['canSetLock'], r, function () {
r.setLock(lock_1, function (e) { return process.nextTick(function () {
if (e) {
@@ -83,12 +91,18 @@ function createLock(arg, callback) {
callback();
return;
}
+ arg.invokeEvent('lock', r, lock_1);
arg.response.setHeader('Lock-Token', lock_1.uuid);
- arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
- arg.writeXML(createResponse(arg, lock_1));
- callback();
+ cb();
}); });
});
+ }
+ arg.checkIfHeader(r, function () {
+ writeLock(r, function () {
+ arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
+ arg.writeXML(createResponse(arg, lock_1));
+ callback();
+ });
});
});
}
@@ -113,6 +127,7 @@ function refreshLock(arg, lockUUID, callback) {
return;
}
lock.refresh();
+ arg.invokeEvent('refreshLock', r, lock);
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
arg.writeXML(createResponse(arg, lock));
callback();
diff --git a/lib/server/commands/Mkcol.js b/lib/server/commands/Mkcol.js
index 398cb50b..7d1f5dac 100644
--- a/lib/server/commands/Mkcol.js
+++ b/lib/server/commands/Mkcol.js
@@ -33,11 +33,14 @@ function default_1(arg, callback) {
callback();
return;
}
+ arg.invokeEvent('create', resource);
r.addChild(resource, function (e) { return process.nextTick(function () {
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
+ arg.invokeEvent('addChild', r, resource);
arg.setCode(WebDAVRequest_1.HTTPCodes.Created);
+ }
callback();
}); });
}); });
diff --git a/lib/server/commands/Move.js b/lib/server/commands/Move.js
index b7fa713f..9c242301 100644
--- a/lib/server/commands/Move.js
+++ b/lib/server/commands/Move.js
@@ -27,8 +27,10 @@ function default_1(arg, callback) {
r.moveTo(rDest, destination.fileName(), overwrite, function (e) { return process.nextTick(function () {
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
+ arg.invokeEvent('move', r, destination);
arg.setCode(WebDAVRequest_1.HTTPCodes.Created);
+ }
callback();
}); });
});
diff --git a/lib/server/commands/Put.js b/lib/server/commands/Put.js
index a5cc62e1..266fe9fc 100644
--- a/lib/server/commands/Put.js
+++ b/lib/server/commands/Put.js
@@ -25,13 +25,16 @@ function createResource(arg, callback, validCallback) {
callback();
return;
}
+ arg.invokeEvent('create', resource);
r.addChild(resource, function (e) { return process.nextTick(function () {
if (e) {
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
callback();
}
- else
+ else {
+ arg.invokeEvent('addChild', r, resource);
validCallback(resource);
+ }
}); });
}); });
});
@@ -55,8 +58,10 @@ function unchunkedMethod(arg, callback) {
stream.end();
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
+ arg.invokeEvent('write', r);
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
+ }
callback();
}); });
});
@@ -79,8 +84,10 @@ function unchunkedMethod(arg, callback) {
stream.end(arg.data, function (e) {
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
+ arg.invokeEvent('write', r);
arg.setCode(WebDAVRequest_1.HTTPCodes.Created);
+ }
callback();
});
}); });
@@ -108,8 +115,10 @@ function unchunkedMethod(arg, callback) {
stream.end(arg.data, function (e) {
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
+ arg.invokeEvent('write', r);
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
+ }
callback();
});
}); });
@@ -137,8 +146,10 @@ unchunkedMethod.chunked = function (arg, callback) {
stream.end();
if (e)
arg.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
- else
+ else {
+ arg.invokeEvent('write', r);
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
+ }
callback();
}); });
});
@@ -161,6 +172,7 @@ unchunkedMethod.chunked = function (arg, callback) {
arg.request.pipe(stream);
stream.on('finish', function (e) {
arg.setCode(WebDAVRequest_1.HTTPCodes.Created);
+ arg.invokeEvent('write', r);
callback();
});
stream.on('error', function (e) {
@@ -192,6 +204,7 @@ unchunkedMethod.chunked = function (arg, callback) {
arg.request.pipe(stream);
stream.on('finish', function (e) {
arg.setCode(WebDAVRequest_1.HTTPCodes.OK);
+ arg.invokeEvent('write', r);
callback();
});
stream.on('error', function (e) {
diff --git a/lib/server/commands/Unlock.js b/lib/server/commands/Unlock.js
index 7d31bc22..42371416 100644
--- a/lib/server/commands/Unlock.js
+++ b/lib/server/commands/Unlock.js
@@ -38,8 +38,10 @@ function default_1(arg, callback) {
r.removeLock(lock.uuid, function (e, done) {
if (e || !done)
arg.setCode(WebDAVRequest_1.HTTPCodes.Forbidden);
- else
+ else {
+ arg.invokeEvent('unlock', r, lock);
arg.setCode(WebDAVRequest_1.HTTPCodes.NoContent);
+ }
callback();
});
});
diff --git a/lib/server/webDAVServer/Events.d.ts b/lib/server/webDAVServer/Events.d.ts
new file mode 100644
index 00000000..cb4fdb83
--- /dev/null
+++ b/lib/server/webDAVServer/Events.d.ts
@@ -0,0 +1,15 @@
+import { MethodCallArgs } from '../WebDAVRequest';
+import { XMLElement } from '../../helper/XML';
+import { IResource } from '../../resource/IResource';
+import { FSPath } from '../../manager/FSPath';
+import { Lock } from '../../resource/lock/Lock';
+export declare type EventsName = 'create' | 'delete' | 'copy' | 'move' | 'lock' | 'refreshLock' | 'unlock' | 'setProperty' | 'removeProperty' | 'write' | 'read' | 'addChild';
+export declare type DetailsType = IResource | FSPath | Lock | XMLElement;
+export declare type Listener = (arg: MethodCallArgs, subjectResource: IResource, details?: DetailsType) => void;
+export declare function invoke(event: EventsName, arg: MethodCallArgs, subjectResource?: IResource, details?: DetailsType): void;
+export declare function register(event: EventsName, listener: Listener): void;
+export declare function registerWithName(event: EventsName, name: string, listener: Listener): void;
+export declare function clear(event: EventsName): void;
+export declare function clearAll(event: EventsName): void;
+export declare function remove(event: EventsName, listener: Listener): void;
+export declare function removeByName(event: EventsName, name: string): void;
diff --git a/lib/server/webDAVServer/Events.js b/lib/server/webDAVServer/Events.js
new file mode 100644
index 00000000..3a7586fb
--- /dev/null
+++ b/lib/server/webDAVServer/Events.js
@@ -0,0 +1,54 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+function getEventBag(_this, event) {
+ if (!_this.__events)
+ _this.__events = {};
+ if (event && !_this.__events[event]) {
+ _this.__events[event] = {
+ all: [],
+ named: {}
+ };
+ return _this.__events[event];
+ }
+ return event ? _this.__events[event] : _this.__events;
+}
+function invoke(event, arg, subjectResource, details) {
+ var events = getEventBag(this, event);
+ events.all.forEach(function (e) { return process.nextTick(function () { return e(arg, subjectResource, details); }); });
+}
+exports.invoke = invoke;
+function register(event, listener) {
+ var events = getEventBag(this, event);
+ events.all.push(listener);
+}
+exports.register = register;
+function registerWithName(event, name, listener) {
+ var events = getEventBag(this, event);
+ events.all.push(listener);
+ events.named[name] = listener;
+}
+exports.registerWithName = registerWithName;
+function clear(event) {
+ var events = getEventBag(this, event);
+ events.all = [];
+ events.named = {};
+}
+exports.clear = clear;
+function clearAll(event) {
+ this.__events = {};
+}
+exports.clearAll = clearAll;
+function remove(event, listener) {
+ var events = getEventBag(this, event);
+ events.all.indexOf(listener);
+}
+exports.remove = remove;
+function removeByName(event, name) {
+ var events = getEventBag(this, event);
+ var listener = events.named[name];
+ if (listener) {
+ delete events.named[name];
+ events.all.splice(events.all.indexOf(listener), 1);
+ }
+}
+exports.removeByName = removeByName;
diff --git a/lib/server/webDAVServer/WebDAVServer.d.ts b/lib/server/webDAVServer/WebDAVServer.d.ts
index 2eb536b4..2277b249 100644
--- a/lib/server/webDAVServer/WebDAVServer.d.ts
+++ b/lib/server/webDAVServer/WebDAVServer.d.ts
@@ -1,7 +1,7 @@
///
import { WebDAVServerOptions } from '../WebDAVServerOptions';
import { ResourceTreeNode, WebDAVServerStartCallback } from './Types';
-import { WebDAVRequest } from '../WebDAVRequest';
+import { MethodCallArgs, WebDAVRequest } from '../WebDAVRequest';
import { IResource, ReturnCallback } from '../../resource/IResource';
import { HTTPAuthentication } from '../../user/authentication/HTTPAuthentication';
import { IPrivilegeManager } from '../../user/privilege/IPrivilegeManager';
@@ -11,6 +11,7 @@ import * as http from 'http';
import * as persistence from './Persistence';
import * as beforeAfter from './BeforeAfter';
import * as startStop from './StartStop';
+import * as events from './Events';
export { WebDAVServerOptions } from '../WebDAVServerOptions';
export declare class WebDAVServer {
httpAuthentication: HTTPAuthentication;
@@ -42,4 +43,11 @@ export declare class WebDAVServer {
protected invokeBARequest: typeof beforeAfter.invokeBARequest;
protected invokeBeforeRequest: typeof beforeAfter.invokeBeforeRequest;
protected invokeAfterRequest: typeof beforeAfter.invokeAfterRequest;
+ invoke(event: events.EventsName, arg: MethodCallArgs, subjectResource?: IResource | FSPath, details?: events.DetailsType): void;
+ on(event: events.EventsName, listener: events.Listener): any;
+ on(event: events.EventsName, eventName: string, listener: events.Listener): any;
+ clearEvent(event: events.EventsName): void;
+ clearEvents(event: events.EventsName): void;
+ removeEvent(event: events.EventsName, listener: events.Listener): any;
+ removeEvent(event: events.EventsName, eventName: string): any;
}
diff --git a/lib/server/webDAVServer/WebDAVServer.js b/lib/server/webDAVServer/WebDAVServer.js
index 59645d21..99ab3341 100644
--- a/lib/server/webDAVServer/WebDAVServer.js
+++ b/lib/server/webDAVServer/WebDAVServer.js
@@ -6,6 +6,7 @@ var persistence = require("./Persistence");
var beforeAfter = require("./BeforeAfter");
var startStop = require("./StartStop");
var resource = require("./Resource");
+var events = require("./Events");
var WebDAVServerOptions_2 = require("../WebDAVServerOptions");
exports.WebDAVServerOptions = WebDAVServerOptions_2.WebDAVServerOptions;
var WebDAVServer = (function () {
@@ -50,6 +51,27 @@ var WebDAVServer = (function () {
WebDAVServer.prototype.normalizeMethodName = function (method) {
return method.toLowerCase();
};
+ WebDAVServer.prototype.invoke = function (event, arg, subjectResource, details) {
+ events.invoke.bind(this)(event, subjectResource, details);
+ };
+ WebDAVServer.prototype.on = function (event, eName_listener, listener) {
+ if (eName_listener.constructor === Function)
+ events.register.bind(this)(event, eName_listener);
+ else
+ events.registerWithName.bind(this)(event, eName_listener, listener);
+ };
+ WebDAVServer.prototype.clearEvent = function (event) {
+ events.clear.bind(this)(event);
+ };
+ WebDAVServer.prototype.clearEvents = function (event) {
+ events.clearAll.bind(this)();
+ };
+ WebDAVServer.prototype.removeEvent = function (event, eName_listener) {
+ if (eName_listener.constructor === Function)
+ events.remove.bind(this)(event, eName_listener);
+ else
+ events.removeByName.bind(this)(event, eName_listener);
+ };
return WebDAVServer;
}());
exports.WebDAVServer = WebDAVServer;
diff --git a/src/server/MethodCallArgs.ts b/src/server/MethodCallArgs.ts
index f27284ed..97bce761 100644
--- a/src/server/MethodCallArgs.ts
+++ b/src/server/MethodCallArgs.ts
@@ -1,5 +1,6 @@
import { requirePrivilege, BasicPrivilege } from '../user/privilege/IPrivilegeManager'
import { IResource, ReturnCallback } from '../resource/IResource'
+import { EventsName, DetailsType } from './webDAVServer/Events'
import { XML, XMLElement } from '../helper/XML'
import { parseIfHeader } from '../helper/IfParser'
import { WebDAVServer } from './webDAVServer/WebDAVServer'
@@ -206,6 +207,22 @@ export class MethodCallArgs
return result;
}
+ invokeEvent(event : EventsName, subjectResource ?: IResource, details ?: DetailsType)
+ {
+ this.server.invoke(event, this, subjectResource, details);
+ }
+ wrapEvent(event : EventsName, subjectResource ?: IResource, details ?: DetailsType)
+ {
+ const oldExit = this.exit;
+ this.exit = () => {
+ if(Math.floor(this.response.statusCode / 100) === 2)
+ this.invokeEvent(event, subjectResource, details);
+
+ oldExit();
+ }
+ return this.exit;
+ }
+
fullUri(uri : string = null)
{
if(!uri)
diff --git a/src/server/commands/Copy.ts b/src/server/commands/Copy.ts
index 7d87669b..8fb26bd1 100644
--- a/src/server/commands/Copy.ts
+++ b/src/server/commands/Copy.ts
@@ -63,7 +63,11 @@ function copy(arg : MethodCallArgs, source : IResource, rDest : IResource, desti
arg.requirePrivilege([ 'canCreate', 'canSetProperty', 'canWrite' ], dest, () => {
dest.create((e) => _(e, () => {
+ arg.invokeEvent('create', dest);
+
rDest.addChild(dest, (e) => _(e, () => {
+ arg.invokeEvent('addChild', rDest, dest);
+
copyAllProperties(source, dest, (e) => _(e, () => {
if(!type.isFile)
{
@@ -73,7 +77,13 @@ function copy(arg : MethodCallArgs, source : IResource, rDest : IResource, desti
source.read(true, (e, rstream) => _(e, () => {
dest.write(true, (e, wstream) => _(e, () => {
- rstream.on('end', next);
+ rstream.on('end', () => {
+ arg.invokeEvent('read', source);
+ next();
+ });
+ wstream.on('finish', () => {
+ arg.invokeEvent('write', dest);
+ })
rstream.pipe(wstream);
}))
}))
@@ -82,6 +92,7 @@ function copy(arg : MethodCallArgs, source : IResource, rDest : IResource, desti
{
if(!type.isDirectory)
{
+ arg.invokeEvent('copy', source, dest);
callback(null);
return;
}
@@ -101,12 +112,16 @@ function copy(arg : MethodCallArgs, source : IResource, rDest : IResource, desti
--nb;
if(nb === 0)
+ {
+ arg.invokeEvent('copy', source, dest);
callback(null);
+ }
}
if(nb === 0)
{
callback(null);
+ arg.invokeEvent('copy', source, dest);
return;
}
@@ -151,8 +166,12 @@ export default function(arg : MethodCallArgs, callback)
return;
}
- destination = destination.substring(destination.indexOf('://') + '://'.length)
- destination = destination.substring(destination.indexOf('/'))
+ const startIndex = destination.indexOf('://');
+ if(startIndex !== -1)
+ {
+ destination = destination.substring(startIndex + '://'.length)
+ destination = destination.substring(destination.indexOf('/')) // Remove the hostname + port
+ }
destination = new FSPath(destination)
arg.server.getResourceFromPath(destination.getParent(), (e, rDest) => {
@@ -230,6 +249,7 @@ export default function(arg : MethodCallArgs, callback)
return;
}
+ arg.invokeEvent('delete', destCollision);
done(true);
}))
}))
diff --git a/src/server/commands/Delete.ts b/src/server/commands/Delete.ts
index df0a69ea..d0bbdbb7 100644
--- a/src/server/commands/Delete.ts
+++ b/src/server/commands/Delete.ts
@@ -18,7 +18,10 @@ export default function(arg : MethodCallArgs, callback)
if(e)
arg.setCode(HTTPCodes.InternalServerError);
else
+ {
arg.setCode(HTTPCodes.OK);
+ arg.invokeEvent('delete', r);
+ }
callback();
}))
})
diff --git a/src/server/commands/Get.ts b/src/server/commands/Get.ts
index 8cf45e45..f66afd45 100644
--- a/src/server/commands/Get.ts
+++ b/src/server/commands/Get.ts
@@ -64,6 +64,8 @@ export default function(arg : MethodCallArgs, callback)
}
else
{
+ arg.invokeEvent('read', r);
+
const range = arg.findHeader('Range');
if(range)
{
diff --git a/src/server/commands/Lock.ts b/src/server/commands/Lock.ts
index 898df2ee..efdaaccb 100644
--- a/src/server/commands/Lock.ts
+++ b/src/server/commands/Lock.ts
@@ -72,12 +72,22 @@ function createLock(arg : MethodCallArgs, callback)
return;
}
+ arg.invokeEvent('create', resource);
r.addChild(resource, (e) => {
if(e)
+ {
arg.setCode(HTTPCodes.InternalServerError);
+ callback();
+ }
else
- arg.setCode(HTTPCodes.Created);
- callback();
+ {
+ arg.invokeEvent('addChild', r, resource);
+ writeLock(resource, () => {
+ arg.setCode(HTTPCodes.Created);
+ arg.writeXML(createResponse(arg, lock));
+ callback();
+ });
+ }
})
}))
})
@@ -95,7 +105,8 @@ function createLock(arg : MethodCallArgs, callback)
return;
}
- arg.checkIfHeader(r, () => {
+ function writeLock(r : IResource, cb)
+ {
arg.requirePrivilege([ 'canSetLock' ], r, () => {
r.setLock(lock, (e) => process.nextTick(() => {
if(e)
@@ -105,12 +116,19 @@ function createLock(arg : MethodCallArgs, callback)
return;
}
+ arg.invokeEvent('lock', r, lock);
arg.response.setHeader('Lock-Token', lock.uuid);
- arg.setCode(HTTPCodes.OK);
- arg.writeXML(createResponse(arg, lock));
- callback();
+ cb();
}))
})
+ }
+
+ arg.checkIfHeader(r, () => {
+ writeLock(r, () => {
+ arg.setCode(HTTPCodes.OK);
+ arg.writeXML(createResponse(arg, lock));
+ callback();
+ })
})
})
}
@@ -143,6 +161,7 @@ function refreshLock(arg : MethodCallArgs, lockUUID : string, callback)
lock.refresh();
+ arg.invokeEvent('refreshLock', r, lock);
arg.setCode(HTTPCodes.OK);
arg.writeXML(createResponse(arg, lock));
callback();
diff --git a/src/server/commands/Mkcol.ts b/src/server/commands/Mkcol.ts
index 34df9c8a..4a5e773e 100644
--- a/src/server/commands/Mkcol.ts
+++ b/src/server/commands/Mkcol.ts
@@ -42,11 +42,15 @@ export default function(arg : MethodCallArgs, callback)
return;
}
+ arg.invokeEvent('create', resource);
r.addChild(resource, (e) => process.nextTick(() => {
if(e)
arg.setCode(HTTPCodes.InternalServerError)
else
+ {
+ arg.invokeEvent('addChild', r, resource);
arg.setCode(HTTPCodes.Created)
+ }
callback();
}))
}))
diff --git a/src/server/commands/Move.ts b/src/server/commands/Move.ts
index d76c2b33..edb30f0c 100644
--- a/src/server/commands/Move.ts
+++ b/src/server/commands/Move.ts
@@ -35,7 +35,10 @@ export default function(arg : MethodCallArgs, callback)
if(e)
arg.setCode(HTTPCodes.InternalServerError)
else
+ {
+ arg.invokeEvent('move', r, destination);
arg.setCode(HTTPCodes.Created)
+ }
callback()
}))
})
diff --git a/src/server/commands/Put.ts b/src/server/commands/Put.ts
index 83d8b265..8b662acb 100644
--- a/src/server/commands/Put.ts
+++ b/src/server/commands/Put.ts
@@ -31,6 +31,7 @@ function createResource(arg : MethodCallArgs, callback, validCallback : (resourc
return;
}
+ arg.invokeEvent('create', resource);
r.addChild(resource, (e) => process.nextTick(() => {
if(e)
{
@@ -38,7 +39,10 @@ function createResource(arg : MethodCallArgs, callback, validCallback : (resourc
callback();
}
else
+ {
+ arg.invokeEvent('addChild', r, resource);
validCallback(resource);
+ }
}))
}))
})
@@ -71,7 +75,10 @@ export default function unchunkedMethod(arg : MethodCallArgs, callback)
if(e)
arg.setCode(HTTPCodes.InternalServerError)
else
+ {
+ arg.invokeEvent('write', r);
arg.setCode(HTTPCodes.OK)
+ }
callback()
}))
})
@@ -100,7 +107,10 @@ export default function unchunkedMethod(arg : MethodCallArgs, callback)
if(e)
arg.setCode(HTTPCodes.InternalServerError)
else
+ {
+ arg.invokeEvent('write', r);
arg.setCode(HTTPCodes.Created)
+ }
callback();
});
}))
@@ -135,7 +145,10 @@ export default function unchunkedMethod(arg : MethodCallArgs, callback)
if(e)
arg.setCode(HTTPCodes.InternalServerError)
else
+ {
+ arg.invokeEvent('write', r);
arg.setCode(HTTPCodes.OK)
+ }
callback();
});
}))
@@ -171,7 +184,10 @@ export default function unchunkedMethod(arg : MethodCallArgs, callback)
if(e)
arg.setCode(HTTPCodes.InternalServerError)
else
+ {
+ arg.invokeEvent('write', r);
arg.setCode(HTTPCodes.OK)
+ }
callback()
}))
})
@@ -199,6 +215,7 @@ export default function unchunkedMethod(arg : MethodCallArgs, callback)
arg.request.pipe(stream);
stream.on('finish', (e) => {
arg.setCode(HTTPCodes.Created)
+ arg.invokeEvent('write', r);
callback();
});
stream.on('error', (e) => {
@@ -236,6 +253,7 @@ export default function unchunkedMethod(arg : MethodCallArgs, callback)
arg.request.pipe(stream);
stream.on('finish', (e) => {
arg.setCode(HTTPCodes.OK)
+ arg.invokeEvent('write', r);
callback();
});
stream.on('error', (e) => {
diff --git a/src/server/commands/Unlock.ts b/src/server/commands/Unlock.ts
index 6233e7e9..10278efa 100644
--- a/src/server/commands/Unlock.ts
+++ b/src/server/commands/Unlock.ts
@@ -56,7 +56,10 @@ export default function(arg : MethodCallArgs, callback)
if(e || !done)
arg.setCode(HTTPCodes.Forbidden);
else
+ {
+ arg.invokeEvent('unlock', r, lock);
arg.setCode(HTTPCodes.NoContent);
+ }
callback();
})
})
diff --git a/src/server/webDAVServer/Events.ts b/src/server/webDAVServer/Events.ts
new file mode 100644
index 00000000..d29a9de3
--- /dev/null
+++ b/src/server/webDAVServer/Events.ts
@@ -0,0 +1,80 @@
+import { MethodCallArgs } from '../WebDAVRequest'
+import { XMLElement } from '../../helper/XML'
+import { IResource } from '../../resource/IResource'
+import { FSPath } from '../../manager/FSPath'
+import { Lock } from '../../resource/lock/Lock'
+
+export type EventsName = 'create' | 'delete' | 'copy' | 'move'
+ | 'lock' | 'refreshLock' | 'unlock'
+ | 'setProperty' | 'removeProperty'
+ | 'write' | 'read'
+ | 'addChild';
+
+export type DetailsType = IResource | FSPath | Lock | XMLElement;
+export type Listener = (arg : MethodCallArgs, subjectResource : IResource, details ?: DetailsType) => void;
+
+function getEventBag(_this : any, event ?: string)
+{
+ if(!_this.__events)
+ _this.__events = { };
+
+ if(event && !_this.__events[event])
+ {
+ _this.__events[event] = {
+ all: [],
+ named: {}
+ };
+ return _this.__events[event];
+ }
+
+ return event ? _this.__events[event] : _this.__events;
+}
+
+export function invoke(event : EventsName, arg : MethodCallArgs, subjectResource ?: IResource, details ?: DetailsType)
+{
+ const events = getEventBag(this, event);
+ events.all.forEach((e) => process.nextTick(() => e(arg, subjectResource, details)));
+}
+
+export function register(event : EventsName, listener : Listener)
+{
+ const events = getEventBag(this, event);
+ events.all.push(listener)
+}
+
+export function registerWithName(event : EventsName, name : string, listener : Listener)
+{
+ const events = getEventBag(this, event);
+ events.all.push(listener);
+ events.named[name] = listener;
+}
+
+export function clear(event : EventsName)
+{
+ const events = getEventBag(this, event);
+ events.all = [];
+ events.named = {};
+}
+
+export function clearAll(event : EventsName)
+{
+ this.__events = { };
+}
+
+export function remove(event : EventsName, listener : Listener)
+{
+ const events = getEventBag(this, event);
+ events.all.indexOf(listener);
+}
+
+export function removeByName(event : EventsName, name : string)
+{
+ const events = getEventBag(this, event);
+ const listener = events.named[name];
+ if(listener)
+ {
+ delete events.named[name];
+ events.all.splice(events.all.indexOf(listener), 1);
+ }
+}
+
diff --git a/src/server/webDAVServer/WebDAVServer.ts b/src/server/webDAVServer/WebDAVServer.ts
index 65e5e2b1..a61b1439 100644
--- a/src/server/webDAVServer/WebDAVServer.ts
+++ b/src/server/webDAVServer/WebDAVServer.ts
@@ -13,6 +13,7 @@ import * as persistence from './Persistence'
import * as beforeAfter from './BeforeAfter'
import * as startStop from './StartStop'
import * as resource from './Resource'
+import * as events from './Events'
export { WebDAVServerOptions } from '../WebDAVServerOptions'
@@ -101,4 +102,37 @@ export class WebDAVServer
protected invokeBARequest = beforeAfter.invokeBARequest
protected invokeBeforeRequest = beforeAfter.invokeBeforeRequest
protected invokeAfterRequest = beforeAfter.invokeAfterRequest
+
+ // Events
+ invoke(event : events.EventsName, arg : MethodCallArgs, subjectResource ?: IResource | FSPath, details ?: events.DetailsType)
+ {
+ events.invoke.bind(this)(event, subjectResource, details);
+ }
+
+ on(event : events.EventsName, listener : events.Listener)
+ on(event : events.EventsName, eventName : string, listener : events.Listener)
+ on(event : events.EventsName, eName_listener : string | (events.Listener), listener ?: events.Listener)
+ {
+ if(eName_listener.constructor === Function)
+ events.register.bind(this)(event, eName_listener);
+ else
+ events.registerWithName.bind(this)(event, eName_listener, listener);
+ }
+ clearEvent(event : events.EventsName)
+ {
+ events.clear.bind(this)(event);
+ }
+ clearEvents(event : events.EventsName)
+ {
+ events.clearAll.bind(this)();
+ }
+ removeEvent(event : events.EventsName, listener : events.Listener)
+ removeEvent(event : events.EventsName, eventName : string)
+ removeEvent(event : events.EventsName, eName_listener : string | (events.Listener))
+ {
+ if(eName_listener.constructor === Function)
+ events.remove.bind(this)(event, eName_listener);
+ else
+ events.removeByName.bind(this)(event, eName_listener);
+ }
}