hfs
Version:
HTTP File Server
58 lines (57 loc) • 3.41 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.rootsMiddleware = exports.roots = void 0;
const config_1 = require("./config");
const misc_1 = require("./misc");
const connections_1 = require("./connections");
const listen_1 = require("./listen");
const lodash_1 = __importDefault(require("lodash"));
exports.roots = (0, config_1.defineConfig)(misc_1.CFG.roots, {}, map => {
const list = Object.keys(map);
const matchers = list.map(hostMask => (0, misc_1.makeMatcher)(hostMask));
const values = Object.values(map).map(x => (0, misc_1.enforceFinal)('/', (0, misc_1.enforceStarting)('/', x)));
return (host) => values[matchers.findIndex(m => m(host))];
});
const forceAddress = (0, config_1.defineConfig)(misc_1.CFG.force_address, false);
forceAddress.sub((v, { version }) => {
if (version === null || version === void 0 ? void 0 : version.olderThan('0.53.0-alpha2'))
forceAddress.set((0, config_1.getConfig)('force_base_url') || (0, config_1.getConfig)('roots_mandatory') || false);
});
const rootsMiddleware = (ctx, next) => (() => {
var _a;
if (!ctx.path) // it was once reported "Cannot read properties of null (reading 'startsWith')" but I can't reproduce it, and it shouldn't happen anyway
return (0, connections_1.disconnect)(ctx, 'no path'); // let's assume that such requests can't be served anyway. This will leave a trace with an ip, anyway
ctx.state.originalPath = ctx.path;
let params; // undefined if we are not going to work on api parameters
if (ctx.path.startsWith(misc_1.SPECIAL_URI)) { // special uris should be excluded...
if (!ctx.path.startsWith(misc_1.API_URI))
return; // ...unless it's an api
params = ctx.state.params || ctx.query; // for api we'll translate params
changeUriParams(v => (0, misc_1.removeStarting)(ctx.state.revProxyPath, v)); // this removal must be done before adding the root; this operation doesn't conceptually belong to "roots", and it may be placed in different middleware, but it's convenient to do it here
const { referer } = ctx.headers;
if (referer && (0, misc_1.try_)(() => new URL(referer).pathname.startsWith(ctx.state.revProxyPath + misc_1.ADMIN_URI)))
return; // exclude apis for admin-panel
}
if (lodash_1.default.isEmpty(exports.roots.get()))
return;
const root = ctx.state.root = (_a = exports.roots.compiled()) === null || _a === void 0 ? void 0 : _a(ctx.host);
if (!ctx.state.skipFilters && forceAddress.get()
&& root === undefined && !(0, misc_1.isLocalHost)(ctx) && ctx.host !== listen_1.baseUrl.compiled())
return (0, connections_1.disconnect)(ctx, forceAddress.key()); // returning truthy will not call next
if (!root || root === '/')
return; // no transformation is required
changeUriParams(v => (0, misc_1.join)(root, v));
if (!params)
ctx.path = (0, misc_1.join)(root, ctx.path);
function changeUriParams(cb) {
if (!params)
return;
for (const [k, v] of Object.entries(params))
if (k.startsWith('uri'))
params[k] = Array.isArray(v) ? v.map(cb) : cb(v);
}
})() || next();
exports.rootsMiddleware = rootsMiddleware;
;