377 lines
17 KiB
JavaScript
377 lines
17 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
var WebDAVRequest_1 = require("../WebDAVRequest");
|
|
var xml_js_builder_1 = require("xml-js-builder");
|
|
var Workflow_1 = require("../../../helper/Workflow");
|
|
var Errors_1 = require("../../../Errors");
|
|
var http = require("http");
|
|
function dateISO8601(ticks) {
|
|
// Adding date
|
|
var date = new Date(ticks);
|
|
var result = date.toISOString().substring(0, '0000-00-00T00:00:00'.length);
|
|
// Adding timezone offset
|
|
var offset = date.getTimezoneOffset();
|
|
result += offset < 0 ? '-' : '+';
|
|
offset = Math.abs(offset);
|
|
var h = Math.floor(offset / 60).toString(10);
|
|
while (h.length < 2)
|
|
h = '0' + h;
|
|
var m = (offset % 60).toString(10);
|
|
while (m.length < 2)
|
|
m = '0' + m;
|
|
result += h + ':' + m;
|
|
return result;
|
|
}
|
|
function parseRequestBody(ctx, data) {
|
|
var allTrue = {
|
|
leftElements: [],
|
|
mustDisplay: function () { return true; },
|
|
mustDisplayValue: function () { return true; }
|
|
};
|
|
var onlyName = {
|
|
leftElements: [],
|
|
mustDisplay: function () { return true; },
|
|
mustDisplayValue: function () { return false; }
|
|
};
|
|
if (ctx.headers.contentLength <= 0)
|
|
return allTrue;
|
|
try {
|
|
var xml = xml_js_builder_1.XML.parse(data);
|
|
var propfind = xml.find('DAV:propfind');
|
|
if (propfind.findIndex('DAV:propname') !== -1)
|
|
return onlyName;
|
|
if (propfind.findIndex('DAV:allprop') !== -1)
|
|
return allTrue;
|
|
var prop_1 = propfind.find('DAV:prop');
|
|
var fn = function (name) {
|
|
var index = prop_1.findIndex(name);
|
|
if (index === -1)
|
|
return false;
|
|
prop_1.elements.splice(index, 1);
|
|
return true;
|
|
};
|
|
return {
|
|
leftElements: prop_1.elements,
|
|
mustDisplay: fn,
|
|
mustDisplayValue: function () { return true; }
|
|
};
|
|
}
|
|
catch (ex) {
|
|
return allTrue;
|
|
}
|
|
}
|
|
function propstatStatus(status) {
|
|
return "HTTP/1.1 " + status + " " + http.STATUS_CODES[status];
|
|
}
|
|
var default_1 = /** @class */ (function () {
|
|
function default_1() {
|
|
}
|
|
default_1.prototype.addXMLInfo = function (ctx, data, resource, multistatus, _callback) {
|
|
var reqBody = parseRequestBody(ctx, data);
|
|
var response = new xml_js_builder_1.XMLElementBuilder('D:response');
|
|
var callback = function (e) {
|
|
if (e === Errors_1.Errors.MustIgnore || e === Errors_1.Errors.ResourceNotFound)
|
|
e = null;
|
|
else if (!e)
|
|
multistatus.add(response);
|
|
else {
|
|
var errorNumber = WebDAVRequest_1.HTTPRequestContext.defaultStatusCode(e);
|
|
if (errorNumber !== null) {
|
|
var response_1 = new xml_js_builder_1.XMLElementBuilder('D:response');
|
|
response_1.ele('D:propstat').ele('D:status').add("HTTP/1.1 " + errorNumber + " " + http.STATUS_CODES[errorNumber]);
|
|
resource.fs.getFullPath(ctx, resource.path, function (e, path) {
|
|
if (e)
|
|
return nbOut(e);
|
|
var p = WebDAVRequest_1.HTTPRequestContext.encodeURL(ctx.fullUri(path.toString()));
|
|
response_1.ele('D:href', undefined, true).add(p);
|
|
if (ctx.server.options.enableLocationTag)
|
|
response_1.ele('D:location').ele('D:href', undefined, true).add(p);
|
|
});
|
|
multistatus.add(response_1);
|
|
}
|
|
}
|
|
_callback(e);
|
|
};
|
|
var propstat = response.ele('D:propstat');
|
|
propstat.ele('D:status').add('HTTP/1.1 200 OK');
|
|
var prop = propstat.ele('D:prop');
|
|
var nb = 1;
|
|
function nbOut(error) {
|
|
if (nb > 0 && error) {
|
|
nb = -1000;
|
|
return callback(error);
|
|
}
|
|
--nb;
|
|
if (nb === 0) {
|
|
if (reqBody.leftElements.length > 0) {
|
|
var propstatError = response.ele('D:propstat');
|
|
var prop_2 = propstatError.ele('D:prop');
|
|
propstatError.ele('D:status').add(propstatStatus(WebDAVRequest_1.HTTPCodes.NotFound));
|
|
for (var _i = 0, _a = reqBody.leftElements; _i < _a.length; _i++) {
|
|
var el = _a[_i];
|
|
if (el) {
|
|
prop_2.add(el);
|
|
}
|
|
}
|
|
}
|
|
callback();
|
|
}
|
|
}
|
|
var tags = {};
|
|
function mustDisplayTag(name) {
|
|
if (reqBody.mustDisplay('DAV:' + name))
|
|
tags[name] = {
|
|
el: prop.ele('D:' + name),
|
|
value: reqBody.mustDisplayValue('DAV:' + name)
|
|
};
|
|
else
|
|
tags[name] = {
|
|
value: false
|
|
};
|
|
}
|
|
mustDisplayTag('getlastmodified');
|
|
mustDisplayTag('lockdiscovery');
|
|
mustDisplayTag('supportedlock');
|
|
mustDisplayTag('creationdate');
|
|
mustDisplayTag('resourcetype');
|
|
mustDisplayTag('displayname');
|
|
mustDisplayTag('getetag');
|
|
function displayValue(values, fn) {
|
|
if (values.constructor === String ? tags[values].value : values.some(function (n) { return tags[n].value; })) {
|
|
++nb;
|
|
process.nextTick(fn);
|
|
}
|
|
}
|
|
displayValue('creationdate', function () {
|
|
resource.creationDate(function (e, ticks) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.creationdate.el.add(dateISO8601(ticks));
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
displayValue('lockdiscovery', function () {
|
|
resource.listDeepLocks(function (e, locks) {
|
|
if (e)
|
|
return nbOut(e);
|
|
for (var path in locks) {
|
|
for (var _i = 0, _a = locks[path]; _i < _a.length; _i++) {
|
|
var _lock = _a[_i];
|
|
var lock = _lock;
|
|
var activelock = tags.lockdiscovery.el.ele('D:activelock');
|
|
activelock.ele('D:lockscope').ele('D:' + lock.lockKind.scope.value.toLowerCase());
|
|
activelock.ele('D:locktype').ele('D:' + lock.lockKind.type.value.toLowerCase());
|
|
activelock.ele('D:depth').add('Infinity');
|
|
if (lock.owner)
|
|
activelock.ele('D:owner').add(lock.owner);
|
|
activelock.ele('D:timeout').add("Second-" + (lock.expirationDate - Date.now()));
|
|
activelock.ele('D:locktoken').ele('D:href', undefined, true).add(lock.uuid);
|
|
activelock.ele('D:lockroot').ele('D:href', undefined, true).add(WebDAVRequest_1.HTTPRequestContext.encodeURL(ctx.fullUri(path)));
|
|
}
|
|
}
|
|
nbOut(null);
|
|
});
|
|
});
|
|
++nb;
|
|
resource.type(function (e, type) { return process.nextTick(function () {
|
|
if (e)
|
|
return nbOut(e);
|
|
resource.fs.getFullPath(ctx, resource.path, function (e, path) {
|
|
if (e)
|
|
return nbOut(e);
|
|
var p = WebDAVRequest_1.HTTPRequestContext.encodeURL(ctx.fullUri(path.toString()));
|
|
var href = p.lastIndexOf('/') !== p.length - 1 && type.isDirectory ? p + '/' : p;
|
|
response.ele('D:href', undefined, true).add(href);
|
|
if (ctx.server.options.enableLocationTag)
|
|
response.ele('D:location').ele('D:href', undefined, true).add(p);
|
|
if (tags.resourcetype.value && type.isDirectory)
|
|
tags.resourcetype.el.ele('D:collection');
|
|
if (type.isFile) {
|
|
mustDisplayTag('getcontentlength');
|
|
mustDisplayTag('getcontenttype');
|
|
if (tags.getcontenttype.value) {
|
|
++nb;
|
|
resource.mimeType(ctx.headers.isSource, function (e, mimeType) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.getcontenttype.el.add(mimeType);
|
|
nbOut(e);
|
|
}); });
|
|
}
|
|
if (tags.getcontentlength.value) {
|
|
++nb;
|
|
resource.size(ctx.headers.isSource, function (e, size) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.getcontentlength.el.add(size === undefined || size === null || size.constructor !== Number ? 0 : size);
|
|
nbOut(e);
|
|
}); });
|
|
}
|
|
}
|
|
nbOut();
|
|
});
|
|
}); });
|
|
displayValue('displayname', function () {
|
|
var methodDisplayName = resource.webName;
|
|
if (resource.displayName)
|
|
methodDisplayName = resource.displayName;
|
|
methodDisplayName.bind(resource)(function (e, name) { return process.nextTick(function () {
|
|
if (!e)
|
|
tags.displayname.el.add(name || '');
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
displayValue('supportedlock', function () {
|
|
resource.availableLocks(function (e, lockKinds) { return process.nextTick(function () {
|
|
if (e) {
|
|
nbOut(e);
|
|
return;
|
|
}
|
|
lockKinds.forEach(function (lockKind) {
|
|
var lockentry = tags.supportedlock.el.ele('D:lockentry');
|
|
var lockscope = lockentry.ele('D:lockscope');
|
|
lockscope.ele('D:' + lockKind.scope.value.toLowerCase());
|
|
var locktype = lockentry.ele('D:locktype');
|
|
locktype.ele('D:' + lockKind.type.value.toLowerCase());
|
|
});
|
|
nbOut();
|
|
}); });
|
|
});
|
|
displayValue('getlastmodified', function () {
|
|
resource.lastModifiedDate(function (e, lastModifiedDate) { return process.nextTick(function () {
|
|
if (!e && tags.getlastmodified.value)
|
|
tags.getlastmodified.el.add(new Date(lastModifiedDate).toUTCString());
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
displayValue('getetag', function () {
|
|
resource.etag(function (e, etag) { return process.nextTick(function () {
|
|
if (!e && tags.getetag.value)
|
|
tags.getetag.el.add(etag);
|
|
nbOut(e);
|
|
}); });
|
|
});
|
|
++nb;
|
|
process.nextTick(function () {
|
|
resource.propertyManager(function (e, pm) {
|
|
if (e)
|
|
return nbOut(e);
|
|
pm.getProperties(function (e, properties) {
|
|
if (e)
|
|
return nbOut(e);
|
|
for (var name_1 in properties) {
|
|
if (reqBody.mustDisplay(name_1)) {
|
|
var tag = prop.ele(name_1);
|
|
if (reqBody.mustDisplayValue(name_1)) {
|
|
var property = properties[name_1];
|
|
if (tag.attributes)
|
|
for (var attName in property.attributes)
|
|
tag.attributes[attName] = property.attributes[attName];
|
|
else
|
|
tag.attributes = property.attributes;
|
|
tag.add(property.value);
|
|
}
|
|
}
|
|
}
|
|
nbOut();
|
|
});
|
|
});
|
|
});
|
|
nbOut();
|
|
};
|
|
default_1.prototype.unchunked = function (ctx, data, callback) {
|
|
var _this = this;
|
|
if (ctx.server.options.maxRequestDepth < ctx.headers.depth || ctx.headers.depth < 0 && (ctx.server.options.maxRequestDepth !== Infinity && ctx.server.options.maxRequestDepth >= 0)) {
|
|
ctx.setCode(WebDAVRequest_1.HTTPCodes.Forbidden);
|
|
callback();
|
|
return;
|
|
}
|
|
ctx.getResource(function (e, resource) {
|
|
ctx.checkIfHeader(resource, function () {
|
|
var multistatus = new xml_js_builder_1.XMLElementBuilder('D:multistatus', {
|
|
'xmlns:D': 'DAV:'
|
|
});
|
|
var done = function (multistatus) {
|
|
ctx.setCode(WebDAVRequest_1.HTTPCodes.MultiStatus);
|
|
ctx.writeBody(multistatus);
|
|
callback();
|
|
};
|
|
resource.type(function (e, type) { return process.nextTick(function () {
|
|
if (e) {
|
|
if (!ctx.setCodeFromError(e))
|
|
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
|
|
return callback();
|
|
}
|
|
if (!type.isDirectory || ctx.headers.depth === 0) {
|
|
_this.addXMLInfo(ctx, data, resource, multistatus, function (e) {
|
|
if (!e)
|
|
done(multistatus);
|
|
else {
|
|
if (!ctx.setCodeFromError(e))
|
|
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
|
|
callback();
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
var injectResourcePropfind = function (resource, depth, callback) {
|
|
--depth;
|
|
resource.readDir(true, function (e, children) { return process.nextTick(function () {
|
|
function err(e) {
|
|
if (!ctx.setCodeFromError(e))
|
|
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
|
|
callback();
|
|
}
|
|
if (e)
|
|
return err(e);
|
|
resource.fs.getFullPath(ctx, resource.path, function (e, rsPath) {
|
|
new Workflow_1.Workflow()
|
|
.each(children, function (childName, cb) {
|
|
ctx.server.getResource(ctx, rsPath.getChildPath(childName), function (e, r) {
|
|
if (e)
|
|
return cb(e);
|
|
_this.addXMLInfo(ctx, data, r, multistatus, function (e) {
|
|
if (e)
|
|
return cb(e);
|
|
if (depth !== 0) {
|
|
r.type(function (e, type) {
|
|
if (e || !type.isDirectory)
|
|
return cb(e);
|
|
injectResourcePropfind(r, depth, function () {
|
|
cb();
|
|
});
|
|
});
|
|
}
|
|
else {
|
|
cb();
|
|
}
|
|
});
|
|
});
|
|
})
|
|
.error(err)
|
|
.done(function () {
|
|
callback();
|
|
});
|
|
});
|
|
}); });
|
|
};
|
|
_this.addXMLInfo(ctx, data, resource, multistatus, function (e) {
|
|
if (!e) {
|
|
injectResourcePropfind(resource, ctx.headers.depth, function () {
|
|
done(multistatus);
|
|
});
|
|
}
|
|
else {
|
|
if (!ctx.setCodeFromError(e))
|
|
ctx.setCode(WebDAVRequest_1.HTTPCodes.InternalServerError);
|
|
callback();
|
|
}
|
|
});
|
|
}); });
|
|
});
|
|
});
|
|
};
|
|
default_1.prototype.isValidFor = function (ctx, type) {
|
|
return !!type;
|
|
};
|
|
return default_1;
|
|
}());
|
|
exports.default = default_1;
|