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

333 lines
14 KiB
JavaScript

"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var xml_js_builder_1 = require("xml-js-builder");
var IfParser_1 = require("../../helper/v2/IfParser");
var HTTPCodes_1 = require("../HTTPCodes");
var Path_1 = require("../../manager/v2/Path");
var Errors_1 = require("../../Errors");
var http = require("http");
var url = require("url");
var promise_1 = require("../../helper/v2/promise");
var RequestContextHeaders = /** @class */ (function () {
function RequestContextHeaders(headers) {
this.headers = headers;
this.isSource = this.find('source', 'F').toUpperCase() === 'T' || this.find('translate', 'T').toUpperCase() === 'F';
this.host = this.find('Host', 'localhost');
var depth = this.find('Depth');
try {
if (depth.toLowerCase() === 'infinity')
this.depth = -1;
else
this.depth = Math.max(-1, parseInt(depth, 10));
}
catch (_) {
this.depth = undefined;
}
try {
this.contentLength = Math.max(0, parseInt(this.find('Content-length', '0'), 10));
}
catch (_) {
this.contentLength = 0;
}
}
RequestContextHeaders.prototype.find = function (name, defaultValue) {
if (defaultValue === void 0) { defaultValue = null; }
name = name.replace(/(-| )/g, '').toLowerCase();
for (var k in this.headers)
if (k.replace(/(-| )/g, '').toLowerCase() === name) {
var value = this.headers[k].toString().trim();
if (value.length !== 0)
return value;
}
return defaultValue;
};
RequestContextHeaders.prototype.findBestAccept = function (defaultType) {
if (defaultType === void 0) { defaultType = 'xml'; }
var accepts = this.find('Accept', 'text/xml').split(',');
var regex = {
'xml': /[^a-z0-9A-Z]xml$/,
'json': /[^a-z0-9A-Z]json$/
};
for (var _i = 0, accepts_1 = accepts; _i < accepts_1.length; _i++) {
var value = accepts_1[_i];
for (var name_1 in regex)
if (regex[name_1].test(value))
return name_1;
}
return defaultType;
};
return RequestContextHeaders;
}());
exports.RequestContextHeaders = RequestContextHeaders;
var DefaultRequestContextExternalOptions = /** @class */ (function () {
function DefaultRequestContextExternalOptions() {
this.headers = {
host: 'localhost'
};
this.url = '/';
this.user = {
isAdministrator: true,
isDefaultUser: false,
password: null,
uid: '-1',
username: '_default_super_admin_'
};
}
return DefaultRequestContextExternalOptions;
}());
exports.DefaultRequestContextExternalOptions = DefaultRequestContextExternalOptions;
var RequestContext = /** @class */ (function () {
function RequestContext(server, uri, headers, rootPath) {
this.overridePrivileges = false;
this.rootPath = rootPath;
this.headers = new RequestContextHeaders(headers);
this.server = server;
uri = url.parse(uri).pathname;
uri = uri ? uri : '';
this.requested = {
uri: uri,
path: new Path_1.Path(uri)
};
this.requested.path.decode();
if (this.rootPath) {
this.rootPath = new Path_1.Path(this.rootPath).toString(false);
if (this.rootPath === '/')
this.rootPath = undefined;
}
}
RequestContext.prototype.getResourceAsync = function (path) {
var _this = this;
return promise_1.promisifyCall(function (cb) { return _this.getResource(path, cb); });
};
RequestContext.prototype.getResource = function (_path, _callback) {
var path = Path_1.Path.isPath(_path) ? new Path_1.Path(_path) : this.requested.path;
var callback = _callback ? _callback : _path;
this.server.getResource(this, path, callback);
};
RequestContext.prototype.getResourceSync = function (path) {
path = path ? path : this.requested.path;
return this.server.getResourceSync(this, path);
};
RequestContext.prototype.fullUri = function (uri) {
if (uri === void 0) { uri = null; }
if (!uri)
uri = this.requested.uri;
if (this.server.options.respondWithPaths)
return this.rootPath ? this.rootPath + uri : uri;
else
return (this.prefixUri() + uri).replace(/([^:])\/\//g, '$1/');
};
RequestContext.prototype.prefixUri = function () {
return 'http://' + this.headers.host.replace('/', '') + (this.rootPath ? this.rootPath : '');
};
return RequestContext;
}());
exports.RequestContext = RequestContext;
var ExternalRequestContext = /** @class */ (function (_super) {
__extends(ExternalRequestContext, _super);
function ExternalRequestContext() {
return _super !== null && _super.apply(this, arguments) || this;
}
ExternalRequestContext.create = function (server, _options, _callback) {
var defaultValues = new DefaultRequestContextExternalOptions();
var options = _options && _options.constructor !== Function ? _options : defaultValues;
var callback = _callback ? _callback : _options && _options.constructor === Function ? _options : function () { };
if (defaultValues !== options) {
for (var name_2 in defaultValues)
if (options[name_2] === undefined)
options[name_2] = defaultValues[name_2];
}
var ctx = new ExternalRequestContext(server, options.url, options.headers);
if (options.user) {
ctx.user = options.user;
process.nextTick(function () { return callback(null, ctx); });
}
return ctx;
};
return ExternalRequestContext;
}(RequestContext));
exports.ExternalRequestContext = ExternalRequestContext;
var HTTPRequestContext = /** @class */ (function (_super) {
__extends(HTTPRequestContext, _super);
function HTTPRequestContext(server, request, response, exit, rootPath) {
var _this = _super.call(this, server, request.url, request.headers, rootPath) || this;
_this.responseBody = undefined;
_this.response = response;
_this.request = request;
_this.exit = exit;
if (_this.response) {
_this.response.on('error', function (e) {
console.error(e);
});
}
return _this;
}
HTTPRequestContext.create = function (server, request, response, _rootPath, _callback) {
var rootPath = _callback ? _rootPath : undefined;
var callback = _callback ? _callback : _rootPath;
var ctx = new HTTPRequestContext(server, request, response, null, rootPath);
response.setHeader('DAV', '1,2');
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Credentials', 'true');
response.setHeader('Access-Control-Expose-Headers', 'DAV, content-length, Allow');
response.setHeader('MS-Author-Via', 'DAV');
response.setHeader('Server', server.options.serverName + '/' + server.options.version);
if (server.options.headers) {
for (var headerName in server.options.headers)
response.setHeader(headerName, server.options.headers[headerName]);
}
var setAllowHeader = function (type) {
var allowedMethods = [];
for (var name_3 in server.methods) {
var method = server.methods[name_3];
if (!method.isValidFor || method.isValidFor(ctx, type))
allowedMethods.push(name_3.toUpperCase());
}
response.setHeader('Allow', allowedMethods.join(','));
callback(null, ctx);
};
ctx.askForAuthentication(false, function (e) {
if (e) {
callback(e, ctx);
return;
}
server.httpAuthentication.getUser(ctx, function (e, user) {
ctx.user = user;
if (e && e !== Errors_1.Errors.UserNotFound) {
if (server.options.requireAuthentification || e !== Errors_1.Errors.MissingAuthorisationHeader)
return callback(e, ctx);
}
if (server.options.requireAuthentification && (!user || user.isDefaultUser || e === Errors_1.Errors.UserNotFound))
return callback(Errors_1.Errors.MissingAuthorisationHeader, ctx);
server.getFileSystem(ctx.requested.path, function (fs, _, subPath) {
fs.type(ctx.requested.path.isRoot() ? server.createExternalContext() : ctx, subPath, function (e, type) {
if (e)
type = undefined;
setAllowHeader(type);
});
});
});
});
};
HTTPRequestContext.encodeURL = function (url) {
return encodeURI(url);
};
HTTPRequestContext.prototype.noBodyExpected = function (callback) {
if (this.server.options.strictMode && this.headers.contentLength !== 0) {
this.setCode(HTTPCodes_1.HTTPCodes.UnsupportedMediaType);
this.exit();
}
else
callback();
};
HTTPRequestContext.prototype.checkIfHeader = function (_fs, _path, _callback) {
var _this = this;
var fs = _callback ? _fs : null;
var path = _callback ? _path : null;
var resource = _callback ? null : _fs;
var callback = _callback ? _callback : _path;
var ifHeader = this.headers.find('If');
if (!ifHeader) {
callback();
return;
}
if (!resource) {
resource = fs.resource(this, path);
}
IfParser_1.parseIfHeader(ifHeader)(this, resource, function (e, passed) {
if (e) {
_this.setCode(HTTPCodes_1.HTTPCodes.InternalServerError);
_this.exit();
}
else if (!passed) {
_this.setCode(HTTPCodes_1.HTTPCodes.PreconditionFailed);
_this.exit();
}
else
callback();
});
};
HTTPRequestContext.prototype.askForAuthentication = function (checkForUser, callback) {
if (checkForUser && this.user !== null && !this.user.isDefaultUser) {
callback(Errors_1.Errors.AlreadyAuthenticated);
return;
}
var auth = this.server.httpAuthentication.askForAuthentication(this);
for (var name_4 in auth)
this.response.setHeader(name_4, auth[name_4]);
callback(null);
};
HTTPRequestContext.prototype.writeBody = function (xmlObject) {
var content = xml_js_builder_1.XML.toXML(xmlObject);
switch (this.headers.findBestAccept()) {
default:
case 'xml':
this.response.setHeader('Content-Type', 'application/xml;charset=utf-8');
this.response.setHeader('Content-Length', Buffer.from(content).length.toString());
this.response.write(content, 'UTF-8');
break;
case 'json':
content = xml_js_builder_1.XML.toJSON(content);
this.response.setHeader('Content-Type', 'application/json;charset=utf-8');
this.response.setHeader('Content-Length', Buffer.from(content).length.toString());
this.response.write(content, 'UTF-8');
break;
}
this.responseBody = content;
};
HTTPRequestContext.prototype.setCode = function (code, message) {
if (!message)
message = http.STATUS_CODES[code];
if (!message) {
this.response.statusCode = code;
}
else {
this.response.statusCode = code;
this.response.statusMessage = message;
}
};
HTTPRequestContext.defaultStatusCode = function (error) {
var code = null;
for (var _i = 0, _a = this.defaultErrorStatusCodes; _i < _a.length; _i++) {
var errorCode = _a[_i];
if (errorCode.error === error) {
code = errorCode.code;
break;
}
}
return code;
};
HTTPRequestContext.prototype.setCodeFromError = function (error) {
var code = HTTPRequestContext.defaultStatusCode(error);
if (code)
this.setCode(code);
return !!code;
};
HTTPRequestContext.defaultErrorStatusCodes = [
{ error: Errors_1.Errors.ResourceNotFound, code: HTTPCodes_1.HTTPCodes.NotFound },
{ error: Errors_1.Errors.Locked, code: HTTPCodes_1.HTTPCodes.Locked },
{ error: Errors_1.Errors.BadAuthentication, code: HTTPCodes_1.HTTPCodes.Unauthorized },
{ error: Errors_1.Errors.NotEnoughPrivilege, code: HTTPCodes_1.HTTPCodes.Unauthorized },
{ error: Errors_1.Errors.ResourceAlreadyExists, code: HTTPCodes_1.HTTPCodes.Conflict },
{ error: Errors_1.Errors.IntermediateResourceMissing, code: HTTPCodes_1.HTTPCodes.Conflict },
{ error: Errors_1.Errors.WrongParentTypeForCreation, code: HTTPCodes_1.HTTPCodes.Conflict },
{ error: Errors_1.Errors.InsufficientStorage, code: HTTPCodes_1.HTTPCodes.InsufficientStorage },
{ error: Errors_1.Errors.Forbidden, code: HTTPCodes_1.HTTPCodes.Forbidden }
];
return HTTPRequestContext;
}(RequestContext));
exports.HTTPRequestContext = HTTPRequestContext;