333 lines
14 KiB
JavaScript
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;
|