UNPKG

@fly/cdn

Version:
78 lines 10.8 kB
/** * @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==