Skip to content

Commit

Permalink
Added support for the PROPPATCH method
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienCastex committed May 14, 2017
1 parent 87878cd commit df2be26
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/server/commands/Commands.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var NotImplemented_1 = require("./NotImplemented");
var Proppatch_1 = require("./Proppatch");
var Propfind_1 = require("./Propfind");
var Options_1 = require("./Options");
var Delete_1 = require("./Delete");
Expand All @@ -11,6 +12,7 @@ var Put_1 = require("./Put");
var Get_1 = require("./Get");
exports.default = {
NotImplemented: NotImplemented_1.default,
Proppatch: Proppatch_1.default,
Propfind: Propfind_1.default,
Options: Options_1.default,
Delete: Delete_1.default,
Expand Down
2 changes: 2 additions & 0 deletions lib/server/commands/Proppatch.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { MethodCallArgs } from '../WebDAVRequest';
export default function (arg: MethodCallArgs, callback: any): void;
64 changes: 64 additions & 0 deletions lib/server/commands/Proppatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var WebDAVRequest_1 = require("../WebDAVRequest");
var http_1 = require("http");
var XML_1 = require("../../helper/XML");
function default_1(arg, callback) {
arg.getResource(function (e, r) {
if (e) {
arg.setCode(WebDAVRequest_1.HTTPCodes.NotFound);
callback();
return;
}
var multistatus = XML_1.XML.createElement('D:multistatus', {
'xmlns:D': 'DAV:'
});
var response = multistatus.ele('D:response');
response.ele('D:href').add(arg.fullUri());
var xml = XML_1.XML.parse(arg.data);
var root = xml.find('DAV:propertyupdate');
var finalize = function () {
finalize = function () {
arg.setCode(WebDAVRequest_1.HTTPCodes.MultiStatus);
arg.response.write(XML_1.XML.toXML(multistatus));
callback();
};
};
function notify(el, error) {
var code = error ? WebDAVRequest_1.HTTPCodes.Conflict : WebDAVRequest_1.HTTPCodes.OK;
var propstat = response.ele('D:propstat');
propstat.ele('D:prop').ele(el.name);
propstat.ele('D:status').add('HTTP/1.1 ' + code + ' ' + http_1.STATUS_CODES[code]);
}
execute('DAV:set', function (el, callback) {
r.setProperty(el.name, el.elements, callback);
});
execute('DAV:remove', function (el, callback) {
r.removeProperty(el.name, callback);
});
function execute(name, fnProp) {
var list = root.findMany(name);
if (list.length === 0) {
finalize();
return;
}
list.forEach(function (el) {
var els = el.find('DAV:prop').elements;
if (els.length === 0) {
finalize();
return;
}
var nb = els.length;
els.forEach(function (el) {
fnProp(el, function (e) {
notify(el, e);
--nb;
if (nb === 0)
finalize();
});
});
});
}
});
}
exports.default = default_1;
2 changes: 2 additions & 0 deletions src/server/commands/Commands.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import NotImplemented from './NotImplemented'
import Proppatch from './Proppatch'
import Propfind from './Propfind'
import Options from './Options'
import Delete from './Delete'
Expand All @@ -10,6 +11,7 @@ import Get from './Get'

export default {
NotImplemented,
Proppatch,
Propfind,
Options,
Delete,
Expand Down
79 changes: 79 additions & 0 deletions src/server/commands/Proppatch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { HTTPCodes, MethodCallArgs, WebDAVRequest } from '../WebDAVRequest'
import { STATUS_CODES } from 'http'
import { IResource } from '../../resource/Resource'
import { XML } from '../../helper/XML'

export default function(arg : MethodCallArgs, callback)
{
arg.getResource((e, r) => {
if(e)
{
arg.setCode(HTTPCodes.NotFound)
callback();
return;
}

const multistatus = XML.createElement('D:multistatus', {
'xmlns:D': 'DAV:'
});
const response = multistatus.ele('D:response');
response.ele('D:href').add(arg.fullUri());

const xml = XML.parse(arg.data);
const root = xml.find('DAV:propertyupdate');

let finalize = function()
{
finalize = function()
{
arg.setCode(HTTPCodes.MultiStatus);
arg.response.write(XML.toXML(multistatus));
callback();
}
}

function notify(el : any, error : any)
{
const code = error ? HTTPCodes.Conflict : HTTPCodes.OK;
const propstat = response.ele('D:propstat');
propstat.ele('D:prop').ele(el.name);
propstat.ele('D:status').add('HTTP/1.1 ' + code + ' ' + STATUS_CODES[code]);
}

execute('DAV:set', (el, callback) => {
r.setProperty(el.name, el.elements, callback)
})
execute('DAV:remove', (el, callback) => {
r.removeProperty(el.name, callback)
})

function execute(name, fnProp)
{
const list = root.findMany(name);
if(list.length === 0)
{
finalize();
return;
}

list.forEach(function(el) {
const els = el.find('DAV:prop').elements;
if(els.length === 0)
{
finalize();
return;
}

let nb = els.length;
els.forEach(function(el) {
fnProp(el, (e) => {
notify(el, e);
--nb;
if(nb === 0)
finalize();
})
})
})
}
})
}

0 comments on commit df2be26

Please sign in to comment.