@fly/cdn
Version:
Fly's TypeScript CDN
78 lines • 10.8 kB
JavaScript
/**
* @module Backends
*/
import aws from '../aws';
const allowedMethods = ["GET", "HEAD"];
/**
* Creates a fetch-like proxy function for making requests to AWS S3.
*
* Example:
*
* ```typescript
* import { awsS3 } from "./src/backends";
* const backend = awsS3({
* bucket: "flyio-test-website",
* // region: "us-east-1"
* // credentials: { // for private S3 buckets
* // accessKeyId: app.config.aws_access_key_id,
* // secretAccessKey: app.config.aws_secret_access_key, // store this as a secret
* // }
* });
* ```
* @param options AWS S3 bucket to proxy to
* @module Backends
*/
export function awsS3(options) {
const opts = normalizeOptions(options);
const fn = async function awsS3Fetch(req, init) {
if (typeof req === "string")
req = new Request(req, init);
if (!allowedMethods.includes(req.method))
return new Response(`HTTP Method not allowed, only ${allowedMethods.join(", ")} are allowed.`, { status: 405 });
const url = new URL(req.url);
if (url.pathname.endsWith("/"))
url.pathname += "index.html";
let res;
if (typeof opts.credentials !== 'object')
res = await fetch(buildS3Url(opts, url.pathname), { method: req.method, headers: req.headers });
else
res = await aws.fetch({
path: `/${opts.bucket}${url.pathname}`,
service: 's3',
region: opts.region,
method: req.method,
}, opts.credentials);
if (res.status >= 500) {
console.error(`AWS S3 returned a server error, status code: ${res.status}, body:`, await res.text());
return new Response(req.method === "GET" ? "Something went wrong." : null, { status: 500 });
}
if (res.status === 404)
return new Response(req.method === "GET" ? "Not found." : null, { status: 404 });
if (res.status >= 400) {
console.error(`AWS S3 returned a client error, status code: ${res.status}, body:`, await res.text());
return new Response(req.method === "GET" ? "Something went wrong." : null, { status: 500 });
}
for (let h in res.headers)
if (h.startsWith("x-amz-"))
res.headers.delete(h);
return res;
};
return Object.assign(fn, { proxyConfig: opts });
}
function normalizeOptions(options) {
if (typeof options === 'string')
options = { bucket: options };
return options;
}
function buildS3Url(opts, path) {
const region = opts.region || 'us-east-1';
let host;
if (region === 'us-east-1') {
host = "s3.amazonaws.com";
}
else {
host = `s3-${opts.region}.amazonaws.com`;
}
return `http://${host}/${opts.bucket}${path}`;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzX3MzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2JhY2tlbmRzL2F3c19zMy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE9BQU8sR0FBb0IsTUFBTSxRQUFRLENBQUE7QUFZekMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUE7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILE1BQU0sVUFBVSxLQUFLLENBQUMsT0FBOEI7SUFDaEQsTUFBTSxJQUFJLEdBQUcsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFdkMsTUFBTSxFQUFFLEdBQUcsS0FBSyxVQUFVLFVBQVUsQ0FBQyxHQUFnQixFQUFFLElBQWtCO1FBQ3JFLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUTtZQUFFLEdBQUcsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUNwQyxPQUFPLElBQUksUUFBUSxDQUFDLGlDQUFpQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQTtRQUVuSCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0IsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7WUFDMUIsR0FBRyxDQUFDLFFBQVEsSUFBSSxZQUFZLENBQUE7UUFFaEMsSUFBSSxHQUFhLENBQUM7UUFFbEIsSUFBSSxPQUFPLElBQUksQ0FBQyxXQUFXLEtBQUssUUFBUTtZQUNwQyxHQUFHLEdBQUcsTUFBTSxLQUFLLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7O1lBRS9GLEdBQUcsR0FBRyxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUM7Z0JBQ2xCLElBQUksRUFBRSxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLFFBQVEsRUFBRTtnQkFDdEMsT0FBTyxFQUFFLElBQUk7Z0JBQ2IsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO2dCQUNuQixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07YUFDckIsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFekIsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLEdBQUcsRUFBRTtZQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLGdEQUFnRCxHQUFHLENBQUMsTUFBTSxTQUFTLEVBQUUsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNyRyxPQUFPLElBQUksUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7U0FDOUY7UUFFRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssR0FBRztZQUNsQixPQUFPLElBQUksUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFBO1FBRXBGLElBQUksR0FBRyxDQUFDLE1BQU0sSUFBSSxHQUFHLEVBQUU7WUFDbkIsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsR0FBRyxDQUFDLE1BQU0sU0FBUyxFQUFFLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFDckcsT0FBTyxJQUFJLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFBO1NBQzlGO1FBRUQsS0FBSyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsT0FBTztZQUNyQixJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDO2dCQUN0QixHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUU3QixPQUFPLEdBQUcsQ0FBQTtJQUNkLENBQUMsQ0FBQTtJQUVELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtBQUNuRCxDQUFDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxPQUE4QjtJQUNwRCxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVE7UUFDM0IsT0FBTyxHQUFHLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFBO0lBQ2pDLE9BQU8sT0FBTyxDQUFBO0FBQ2xCLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxJQUFrQixFQUFFLElBQVk7SUFDaEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxXQUFXLENBQUM7SUFDMUMsSUFBSSxJQUFZLENBQUM7SUFDakIsSUFBSSxNQUFNLEtBQUssV0FBVyxFQUFFO1FBQ3hCLElBQUksR0FBRyxrQkFBa0IsQ0FBQTtLQUM1QjtTQUFNO1FBQ0gsSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLE1BQU0sZ0JBQWdCLENBQUE7S0FDM0M7SUFFRCxPQUFPLFVBQVUsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxFQUFFLENBQUE7QUFDakQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG1vZHVsZSBCYWNrZW5kc1xuICovXG5pbXBvcnQgYXdzLCB7IENyZWRlbnRpYWxzIH0gZnJvbSAnLi4vYXdzJ1xuaW1wb3J0IHsgUHJveHlGdW5jdGlvbiB9IGZyb20gJ3NyYy9wcm94eSc7XG5cbi8qKlxuICogQVdTIFMzIGJ1Y2tldCBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXdzUzNPcHRpb25zIHtcbiAgICBidWNrZXQ6IHN0cmluZyxcbiAgICByZWdpb24/OiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM/OiBDcmVkZW50aWFsc1xufVxuXG5jb25zdCBhbGxvd2VkTWV0aG9kcyA9IFtcIkdFVFwiLCBcIkhFQURcIl1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZmV0Y2gtbGlrZSBwcm94eSBmdW5jdGlvbiBmb3IgbWFraW5nIHJlcXVlc3RzIHRvIEFXUyBTMy5cbiAqIFxuICogRXhhbXBsZTpcbiAqIFxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgYXdzUzMgfSBmcm9tIFwiLi9zcmMvYmFja2VuZHNcIjtcbiAqIGNvbnN0IGJhY2tlbmQgPSBhd3NTMyh7XG4gKiAgYnVja2V0OiBcImZseWlvLXRlc3Qtd2Vic2l0ZVwiLFxuICogIC8vIHJlZ2lvbjogXCJ1cy1lYXN0LTFcIlxuICogIC8vIGNyZWRlbnRpYWxzOiB7IC8vIGZvciBwcml2YXRlIFMzIGJ1Y2tldHNcbiAqICAvLyAgIGFjY2Vzc0tleUlkOiBhcHAuY29uZmlnLmF3c19hY2Nlc3Nfa2V5X2lkLFxuICogIC8vICAgc2VjcmV0QWNjZXNzS2V5OiBhcHAuY29uZmlnLmF3c19zZWNyZXRfYWNjZXNzX2tleSwgLy8gc3RvcmUgdGhpcyBhcyBhIHNlY3JldFxuICogIC8vIH1cbiAqIH0pO1xuICogYGBgXG4gKiBAcGFyYW0gb3B0aW9ucyBBV1MgUzMgYnVja2V0IHRvIHByb3h5IHRvXG4gKiBAbW9kdWxlIEJhY2tlbmRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhd3NTMyhvcHRpb25zOiBBd3NTM09wdGlvbnMgfCBzdHJpbmcpOiBQcm94eUZ1bmN0aW9uPEF3c1MzT3B0aW9ucz4ge1xuICAgIGNvbnN0IG9wdHMgPSBub3JtYWxpemVPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgY29uc3QgZm4gPSBhc3luYyBmdW5jdGlvbiBhd3NTM0ZldGNoKHJlcTogUmVxdWVzdEluZm8sIGluaXQ/OiBSZXF1ZXN0SW5pdCk6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXEgPT09IFwic3RyaW5nXCIpIHJlcSA9IG5ldyBSZXF1ZXN0KHJlcSwgaW5pdCk7XG5cbiAgICAgICAgaWYgKCFhbGxvd2VkTWV0aG9kcy5pbmNsdWRlcyhyZXEubWV0aG9kKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoYEhUVFAgTWV0aG9kIG5vdCBhbGxvd2VkLCBvbmx5ICR7YWxsb3dlZE1ldGhvZHMuam9pbihcIiwgXCIpfSBhcmUgYWxsb3dlZC5gLCB7IHN0YXR1czogNDA1IH0pXG5cbiAgICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKTtcbiAgICAgICAgaWYgKHVybC5wYXRobmFtZS5lbmRzV2l0aChcIi9cIikpXG4gICAgICAgICAgICB1cmwucGF0aG5hbWUgKz0gXCJpbmRleC5odG1sXCJcblxuICAgICAgICBsZXQgcmVzOiBSZXNwb25zZTtcblxuICAgICAgICBpZiAodHlwZW9mIG9wdHMuY3JlZGVudGlhbHMgIT09ICdvYmplY3QnKVxuICAgICAgICAgICAgcmVzID0gYXdhaXQgZmV0Y2goYnVpbGRTM1VybChvcHRzLCB1cmwucGF0aG5hbWUpLCB7IG1ldGhvZDogcmVxLm1ldGhvZCwgaGVhZGVyczogcmVxLmhlYWRlcnMgfSlcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmVzID0gYXdhaXQgYXdzLmZldGNoKHtcbiAgICAgICAgICAgICAgICBwYXRoOiBgLyR7b3B0cy5idWNrZXR9JHt1cmwucGF0aG5hbWV9YCxcbiAgICAgICAgICAgICAgICBzZXJ2aWNlOiAnczMnLFxuICAgICAgICAgICAgICAgIHJlZ2lvbjogb3B0cy5yZWdpb24sXG4gICAgICAgICAgICAgICAgbWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICAgICAgfSwgb3B0cy5jcmVkZW50aWFscyk7XG5cbiAgICAgICAgaWYgKHJlcy5zdGF0dXMgPj0gNTAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBBV1MgUzMgcmV0dXJuZWQgYSBzZXJ2ZXIgZXJyb3IsIHN0YXR1cyBjb2RlOiAke3Jlcy5zdGF0dXN9LCBib2R5OmAsIGF3YWl0IHJlcy50ZXh0KCkpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShyZXEubWV0aG9kID09PSBcIkdFVFwiID8gXCJTb21ldGhpbmcgd2VudCB3cm9uZy5cIiA6IG51bGwsIHsgc3RhdHVzOiA1MDAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXMuc3RhdHVzID09PSA0MDQpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKHJlcS5tZXRob2QgPT09IFwiR0VUXCIgPyBcIk5vdCBmb3VuZC5cIiA6IG51bGwsIHsgc3RhdHVzOiA0MDQgfSlcblxuICAgICAgICBpZiAocmVzLnN0YXR1cyA+PSA0MDApIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEFXUyBTMyByZXR1cm5lZCBhIGNsaWVudCBlcnJvciwgc3RhdHVzIGNvZGU6ICR7cmVzLnN0YXR1c30sIGJvZHk6YCwgYXdhaXQgcmVzLnRleHQoKSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKHJlcS5tZXRob2QgPT09IFwiR0VUXCIgPyBcIlNvbWV0aGluZyB3ZW50IHdyb25nLlwiIDogbnVsbCwgeyBzdGF0dXM6IDUwMCB9KVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaCBpbiByZXMuaGVhZGVycylcbiAgICAgICAgICAgIGlmIChoLnN0YXJ0c1dpdGgoXCJ4LWFtei1cIikpXG4gICAgICAgICAgICAgICAgcmVzLmhlYWRlcnMuZGVsZXRlKGgpXG5cbiAgICAgICAgcmV0dXJuIHJlc1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKGZuLCB7IHByb3h5Q29uZmlnOiBvcHRzIH0pXG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZU9wdGlvbnMob3B0aW9uczogQXdzUzNPcHRpb25zIHwgc3RyaW5nKTogQXdzUzNPcHRpb25zIHtcbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnKVxuICAgICAgICBvcHRpb25zID0geyBidWNrZXQ6IG9wdGlvbnMgfVxuICAgIHJldHVybiBvcHRpb25zXG59XG5cbmZ1bmN0aW9uIGJ1aWxkUzNVcmwob3B0czogQXdzUzNPcHRpb25zLCBwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHJlZ2lvbiA9IG9wdHMucmVnaW9uIHx8ICd1cy1lYXN0LTEnO1xuICAgIGxldCBob3N0OiBzdHJpbmc7XG4gICAgaWYgKHJlZ2lvbiA9PT0gJ3VzLWVhc3QtMScpIHtcbiAgICAgICAgaG9zdCA9IFwiczMuYW1hem9uYXdzLmNvbVwiXG4gICAgfSBlbHNlIHtcbiAgICAgICAgaG9zdCA9IGBzMy0ke29wdHMucmVnaW9ufS5hbWF6b25hd3MuY29tYFxuICAgIH1cblxuICAgIHJldHVybiBgaHR0cDovLyR7aG9zdH0vJHtvcHRzLmJ1Y2tldH0ke3BhdGh9YFxufSJdfQ==