@fly/cdn
Version:
Fly's TypeScript CDN
106 lines • 15.9 kB
JavaScript
/**
* @module Config
* @ignore
* */
import { applyReplacements } from "../text-replacements";
export function validateRule(r) {
if (typeof r !== "object") {
throw new Error("must be an object");
}
if (!r.actionType) {
throw new Error("actionType must be defined");
}
if (r.actionType !== "redirect" && r.actionType !== "rewrite") {
throw new Error("actionType must be either `redirect` or `rewrite`");
}
if (r.actionType === "rewrite" && !r.backendKey) {
throw new Error("must inclue `backendKey` when actionType is set to `rewrite`");
}
return true;
}
export function buildRules(backends, rules) {
const compiled = rules.map(compileRule);
return async function ruleFetch(req, init) {
if (typeof req === "string") {
req = new Request(req, init);
}
const match = compiled.find((r) => r(req));
if (!match) {
return new Response("no routing rule found", { status: 404 });
}
const rule = match.rule;
// do the redirect
if (rule.actionType === "redirect") {
let original = new URL(req.url);
let url = undefined;
if (match.pathPattern && rule.redirectURLPattern) {
url = original.pathname.replace(match.pathPattern, rule.redirectURLPattern);
}
if (!url || original.toString() === url) {
return new Response("Can't redirect to a bad URL", { status: 500 });
}
const status = rule.redirectStatus || 302;
return new Response("Redirect", { status: status, headers: { location: url.toString() } });
}
if (rule.actionType !== "rewrite") {
return new Response("Invalid rule action", { status: 500 });
}
const backend = rule.backendKey && backends ? backends.get(rule.backendKey) : undefined;
if (!backend) {
return new Response("No backend for rule", { status: 502 });
}
// rewrite request if necessary
if (match.pathPattern && rule.pathReplacementPattern) {
let url = new URL(req.url);
url = new URL(url.pathname.replace(match.pathPattern, rule.pathReplacementPattern), url);
req = new Request(url.toString(), req);
}
if (!rule.responseReplacements || rule.responseReplacements.length === 0) {
return await backend(req, init);
}
req.headers.delete("accept-encoding");
let resp = await backend(req, init);
return applyReplacements(resp, rule.responseReplacements);
};
}
function compileRule(rule) {
const pathPattern = ensureRegExp(rule.pathPattern);
const httpHeaderValue = ensureRegExp(rule.httpHeaderValue);
const fn = function compiledRule(req) {
const url = new URL(req.url);
if (rule.matchScheme === "http" || rule.matchScheme === "https") {
const scheme = url.protocol.substring(0, -1);
if (scheme != rule.matchScheme || app.env === "development")
return false;
}
if (rule.hostname && rule.hostname != "") {
if (url.hostname != rule.hostname || app.env !== "development") {
return false;
}
}
if (rule.httpHeaderKey && rule.httpHeaderKey != "" && httpHeaderValue) {
const header = req.headers.get(rule.httpHeaderKey);
if (!header || !header.match(httpHeaderValue)) {
return false;
}
}
if (pathPattern) {
if (!url.pathname.match(pathPattern)) {
return false;
}
}
return true;
};
return Object.assign(fn, { rule: rule, pathPattern: pathPattern });
}
function ensureRegExp(pattern) {
if (!pattern || pattern == "")
return null;
if (typeof pattern === "string")
return new RegExp(pattern);
if (typeof pattern != "object" || !(pattern instanceof RegExp)) {
throw new Error("Pattern must be a string or RegExp: " + typeof pattern);
}
return pattern;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL3J1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7S0FHSztBQUNMLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBb0J6RCxNQUFNLFVBQVUsWUFBWSxDQUFDLENBQU07SUFDakMsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLEVBQUU7UUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0tBQ3JDO0lBQ0QsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUU7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFBO0tBQzlDO0lBQ0QsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFVBQVUsSUFBSSxDQUFDLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRTtRQUM3RCxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUE7S0FDckU7SUFDRCxJQUFJLENBQUMsQ0FBQyxVQUFVLEtBQUssU0FBUyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsRUFBRTtRQUMvQyxNQUFNLElBQUksS0FBSyxDQUFDLDhEQUE4RCxDQUFDLENBQUE7S0FDaEY7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUFDLFFBQXdCLEVBQUUsS0FBaUI7SUFDcEUsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQTtJQUN2QyxPQUFPLEtBQUssVUFBVSxTQUFTLENBQUMsR0FBZ0IsRUFBRSxJQUFrQjtRQUNsRSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtZQUMzQixHQUFHLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFBO1NBQzdCO1FBQ0QsTUFBTSxLQUFLLEdBQUcsUUFBUSxD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QWUsQ0FBQyxFQUFFO2dCQUM3QyxPQUFPLEtBQUssQ0FBQTthQUNiO1NBQ0Y7UUFFRCxJQUFJLFdBQVcsRUFBRTtZQUNmLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFBRTtnQkFDcEMsT0FBTyxLQUFLLENBQUE7YUFDYjtTQUNGO1FBQ0QsT0FBTyxJQUFJLENBQUE7SUFDYixDQUFDLENBQUE7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQTtBQUNwRSxDQUFDO0FBRUQsU0FBUyxZQUFZLENBQUMsT0FBeUI7SUFDN0MsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLElBQUksRUFBRTtRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQzFDLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtRQUFFLE9BQU8sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDM0QsSUFBSSxPQUFPLE9BQU8sSUFBSSxRQUFRLElBQUksQ0FBQyxDQUFDLE9BQU8sWUFBWSxNQUFNLENBQUMsRUFBRTtRQUM5RCxNQUFNLElBQUksS0FBSyxDQUFDLHNDQUFzQyxHQUFHLE9BQU8sT0FBTyxDQUFDLENBQUE7S0FDekU7SUFDRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIENvbmZpZ1xuICogQGlnbm9yZVxuICogKi9cbmltcG9ydCB7IGFwcGx5UmVwbGFjZW1lbnRzIH0gZnJvbSBcIi4uL3RleHQtcmVwbGFjZW1lbnRzXCI7XG5pbXBvcnQgeyBCYWNrZW5kUHJveGllcyB9IGZyb20gXCIuL2luZGV4XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZUluZm8ge1xuICBhY3Rpb25UeXBlOiBcInJlZGlyZWN0XCIgfCBcInJld3JpdGVcIixcbiAgYmFja2VuZEtleT86IHN0cmluZyxcbiAgbWF0Y2hTY2hlbWU/OiBzdHJpbmcsXG4gIGhvc3RuYW1lPzogc3RyaW5nLFxuICBwYXRoTWF0Y2hNb2RlPzogXCJwcmVmaXhcIiB8IFwiZnVsbFwiLFxuICBodHRwSGVhZGVyS2V5Pzogc3RyaW5nLFxuICBodHRwSGVhZGVyVmFsdWU/OiBSZWdFeHAgfCBzdHJpbmcsXG4gIHBhdGhQYXR0ZXJuPzogUmVnRXhwIHwgc3RyaW5nLFxuICBwYXRoUmVwbGFjZW1lbnRQYXR0ZXJuPzogc3RyaW5nLFxuICByZWRpcmVjdFVSTFBhdHRlcm4/OiBzdHJpbmcsXG4gIHJlZGlyZWN0U3RhdHVzPzogbnVtYmVyLFxuICByZXNwb25zZVJlcGxhY2VtZW50cz86IFtzdHJpbmcsIHN0cmluZ11bXSxcbn1cblxuZGVjbGFyZSB2YXIgYXBwOiBhbnlcblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUnVsZShyOiBhbnkpOiByIGlzIFJ1bGVJbmZvIHtcbiAgaWYgKHR5cGVvZiByICE9PSBcIm9iamVjdFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwibXVzdCBiZSBhbiBvYmplY3RcIilcbiAgfVxuICBpZiAoIXIuYWN0aW9uVHlwZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcImFjdGlvblR5cGUgbXVzdCBiZSBkZWZpbmVkXCIpXG4gIH1cbiAgaWYgKHIuYWN0aW9uVHlwZSAhPT0gXCJyZWRpcmVjdFwiICYmIHIuYWN0aW9uVHlwZSAhPT0gXCJyZXdyaXRlXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJhY3Rpb25UeXBlIG11c3QgYmUgZWl0aGVyIGByZWRpcmVjdGAgb3IgYHJld3JpdGVgXCIpXG4gIH1cbiAgaWYgKHIuYWN0aW9uVHlwZSA9PT0gXCJyZXdyaXRlXCIgJiYgIXIuYmFja2VuZEtleSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIm11c3QgaW5jbHVlIGBiYWNrZW5kS2V5YCB3aGVuIGFjdGlvblR5cGUgaXMgc2V0IHRvIGByZXdyaXRlYFwiKVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJ1bGVzKGJhY2tlbmRzOiBCYWNrZW5kUHJveGllcywgcnVsZXM6IFJ1bGVJbmZvW10pIHtcbiAgY29uc3QgY29tcGlsZWQgPSBydWxlcy5tYXAoY29tcGlsZVJ1bGUpXG4gIHJldHVybiBhc3luYyBmdW5jdGlvbiBydWxlRmV0Y2gocmVxOiBSZXF1ZXN0SW5mbywgaW5pdD86IFJlcXVlc3RJbml0KSB7XG4gICAgaWYgKHR5cGVvZiByZXEgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJlcSA9IG5ldyBSZXF1ZXN0KHJlcSwgaW5pdClcbiAgICB9XG4gICAgY29uc3QgbWF0Y2ggPSBjb21waWxlZC5maW5kKChyKSA9PiByKDxSZXF1ZXN0PnJlcSkpXG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcIm5vIHJvdXRpbmcgcnVsZSBmb3VuZFwiLCB7IHN0YXR1czogNDA0IH0pXG4gICAgfVxuICAgIGNvbnN0IHJ1bGUgPSBtYXRjaC5ydWxlXG4gICAgLy8gZG8gdGhlIHJlZGlyZWN0XG4gICAgaWYgKHJ1bGUuYWN0aW9uVHlwZSA9PT0gXCJyZWRpcmVjdFwiKSB7XG4gICAgICBsZXQgb3JpZ2luYWwgPSBuZXcgVVJMKHJlcS51cmwpXG4gICAgICBsZXQgdXJsOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWRcbiAgICAgIGlmIChtYXRjaC5wYXRoUGF0dGVybiAmJiBydWxlLnJlZGlyZWN0VVJMUGF0dGVybikge1xuICAgICAgICB1cmwgPSBvcmlnaW5hbC5wYXRobmFtZS5yZXBsYWNlKG1hdGNoLnBhdGhQYXR0ZXJuLCBydWxlLnJlZGlyZWN0VVJMUGF0dGVybilcbiAgICAgIH1cbiAgICAgIGlmICghdXJsIHx8IG9yaWdpbmFsLnRvU3RyaW5nKCkgPT09IHVybCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKFwiQ2FuJ3QgcmVkaXJlY3QgdG8gYSBiYWQgVVJMXCIsIHsgc3RhdHVzOiA1MDAgfSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXR1cyA9IHJ1bGUucmVkaXJlY3RTdGF0dXMgfHwgMzAyXG4gICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKFwiUmVkaXJlY3RcIiwgeyBzdGF0dXM6IHN0YXR1cywgaGVhZGVyczogeyBsb2NhdGlvbjogdXJsLnRvU3RyaW5nKCkgfSB9KVxuICAgIH1cbiAgICBpZiAocnVsZS5hY3Rpb25UeXBlICE9PSBcInJld3JpdGVcIikge1xuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShcIkludmFsaWQgcnVsZSBhY3Rpb25cIiwgeyBzdGF0dXM6IDUwMCB9KVxuICAgIH1cbiAgICBjb25zdCBiYWNrZW5kID0gcnVsZS5iYWNrZW5kS2V5ICYmIGJhY2tlbmRzID8gYmFja2VuZHMuZ2V0KHJ1bGUuYmFja2VuZEtleSkgOiB1bmRlZmluZWRcbiAgICBpZiAoIWJhY2tlbmQpIHtcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJObyBiYWNrZW5kIGZvciBydWxlXCIsIHsgc3RhdHVzOiA1MDIgfSlcbiAgICB9XG4gICAgLy8gcmV3cml0ZSByZXF1ZXN0IGlmIG5lY2Vzc2FyeVxuICAgIGlmIChtYXRjaC5wYXRoUGF0dGVybiAmJiBydWxlLnBhdGhSZXBsYWNlbWVudFBhdHRlcm4pIHtcbiAgICAgIGxldCB1cmwgPSBuZXcgVVJMKHJlcS51cmwpXG4gICAgICB1cmwgPSBuZXcgVVJMKHVybC5wYXRobmFtZS5yZXBsYWNlKG1hdGNoLnBhdGhQYXR0ZXJuLCBydWxlLnBhdGhSZXBsYWNlbWVudFBhdHRlcm4pLCB1cmwpXG4gICAgICByZXEgPSBuZXcgUmVxdWVzdCh1cmwudG9TdHJpbmcoKSwgPFJlcXVlc3RJbml0PnJlcSlcbiAgICB9XG4gICAgaWYgKCFydWxlLnJlc3BvbnNlUmVwbGFjZW1lbnRzIHx8IHJ1bGUucmVzcG9uc2VSZXBsYWNlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gYXdhaXQgYmFja2VuZChyZXEsIGluaXQpXG4gICAgfVxuXG4gICAgcmVxLmhlYWRlcnMuZGVsZXRlKFwiYWNjZXB0LWVuY29kaW5nXCIpXG4gICAgbGV0IHJlc3AgPSBhd2FpdCBiYWNrZW5kKHJlcSwgaW5pdClcbiAgICByZXR1cm4gYXBwbHlSZXBsYWNlbWVudHMocmVzcCwgcnVsZS5yZXNwb25zZVJlcGxhY2VtZW50cylcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21waWxlUnVsZShydWxlOiBSdWxlSW5mbykge1xuICBjb25zdCBwYXRoUGF0dGVybiA9IGVuc3VyZVJlZ0V4cChydWxlLnBhdGhQYXR0ZXJuKVxuICBjb25zdCBodHRwSGVhZGVyVmFsdWUgPSBlbnN1cmVSZWdFeHAocnVsZS5odHRwSGVhZGVyVmFsdWUpXG4gIGNvbnN0IGZuID0gZnVuY3Rpb24gY29tcGlsZWRSdWxlKHJlcTogUmVxdWVzdCkge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybClcbiAgICBpZiAocnVsZS5tYXRjaFNjaGVtZSA9PT0gXCJodHRwXCIgfHwgcnVsZS5tYXRjaFNjaGVtZSA9PT0gXCJodHRwc1wiKSB7XG4gICAgICBjb25zdCBzY2hlbWUgPSB1cmwucHJvdG9jb2wuc3Vic3RyaW5nKDAsIC0xKVxuICAgICAgaWYgKHNjaGVtZSAhPSBydWxlLm1hdGNoU2NoZW1lIHx8IGFwcC5lbnYgPT09IFwiZGV2ZWxvcG1lbnRcIikgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGlmIChydWxlLmhvc3RuYW1lICYmIHJ1bGUuaG9zdG5hbWUgIT0gXCJcIikge1xuICAgICAgaWYgKHVybC5ob3N0bmFtZSAhPSBydWxlLmhvc3RuYW1lIHx8IGFwcC5lbnYgIT09IFwiZGV2ZWxvcG1lbnRcIikge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHJ1bGUuaHR0cEhlYWRlcktleSAmJiBydWxlLmh0dHBIZWFkZXJLZXkgIT0gXCJcIiAmJiBodHRwSGVhZGVyVmFsdWUpIHtcbiAgICAgIGNvbnN0IGhlYWRlciA9IHJlcS5oZWFkZXJzLmdldChydWxlLmh0dHBIZWFkZXJLZXkpXG4gICAgICBpZiAoIWhlYWRlciB8fCAhaGVhZGVyLm1hdGNoKGh0dHBIZWFkZXJWYWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHBhdGhQYXR0ZXJuKSB7XG4gICAgICBpZiAoIXVybC5wYXRobmFtZS5tYXRjaChwYXRoUGF0dGVybikpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oZm4sIHsgcnVsZTogcnVsZSwgcGF0aFBhdHRlcm46IHBhdGhQYXR0ZXJuIH0pXG59XG5cbmZ1bmN0aW9uIGVuc3VyZVJlZ0V4cChwYXR0ZXJuPzogc3RyaW5nIHwgUmVnRXhwKSB7XG4gIGlmICghcGF0dGVybiB8fCBwYXR0ZXJuID09IFwiXCIpIHJldHVybiBudWxsXG4gIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG5ldyBSZWdFeHAocGF0dGVybilcbiAgaWYgKHR5cGVvZiBwYXR0ZXJuICE9IFwib2JqZWN0XCIgfHwgIShwYXR0ZXJuIGluc3RhbmNlb2YgUmVnRXhwKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlBhdHRlcm4gbXVzdCBiZSBhIHN0cmluZyBvciBSZWdFeHA6IFwiICsgdHlwZW9mIHBhdHRlcm4pXG4gIH1cbiAgcmV0dXJuIHBhdHRlcm5cbn0iXX0=