handler.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // src/adapter/lambda-edge/handler.ts
  2. import crypto from "node:crypto";
  3. import { decodeBase64, encodeBase64 } from "../../utils/encode.js";
  4. globalThis.crypto ??= crypto;
  5. var convertHeaders = (headers) => {
  6. const cfHeaders = {};
  7. headers.forEach((value, key) => {
  8. cfHeaders[key.toLowerCase()] = [
  9. ...cfHeaders[key.toLowerCase()] || [],
  10. { key: key.toLowerCase(), value }
  11. ];
  12. });
  13. return cfHeaders;
  14. };
  15. var handle = (app) => {
  16. return async (event, ...args) => {
  17. const [context, callback] = args;
  18. const res = await app.fetch(createRequest(event), {
  19. event,
  20. context,
  21. callback: (err, result) => {
  22. callback?.(err, result);
  23. },
  24. config: event.Records[0].cf.config,
  25. request: event.Records[0].cf.request,
  26. response: event.Records[0].cf.response
  27. });
  28. return createResult(res);
  29. };
  30. };
  31. var createResult = async (res) => {
  32. const isBase64Encoded = isContentTypeBinary(res.headers.get("content-type") || "");
  33. const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text();
  34. return {
  35. status: res.status.toString(),
  36. headers: convertHeaders(res.headers),
  37. body,
  38. ...isBase64Encoded && { bodyEncoding: "base64" }
  39. };
  40. };
  41. var createRequest = (event) => {
  42. const queryString = event.Records[0].cf.request.querystring;
  43. const host = event.Records[0].cf.request.headers?.host?.[0]?.value || event.Records[0].cf.config.distributionDomainName;
  44. const urlPath = `https://${host}${event.Records[0].cf.request.uri}`;
  45. const url = queryString ? `${urlPath}?${queryString}` : urlPath;
  46. const headers = new Headers();
  47. Object.entries(event.Records[0].cf.request.headers).forEach(([k, v]) => {
  48. v.forEach((header) => headers.set(k, header.value));
  49. });
  50. const requestBody = event.Records[0].cf.request.body;
  51. const method = event.Records[0].cf.request.method;
  52. const body = createBody(method, requestBody);
  53. return new Request(url, {
  54. headers,
  55. method,
  56. body
  57. });
  58. };
  59. var createBody = (method, requestBody) => {
  60. if (!requestBody || !requestBody.data) {
  61. return void 0;
  62. }
  63. if (method === "GET" || method === "HEAD") {
  64. return void 0;
  65. }
  66. if (requestBody.encoding === "base64") {
  67. return decodeBase64(requestBody.data);
  68. }
  69. return requestBody.data;
  70. };
  71. var isContentTypeBinary = (contentType) => {
  72. return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml.*)$/.test(
  73. contentType
  74. );
  75. };
  76. export {
  77. createBody,
  78. handle,
  79. isContentTypeBinary
  80. };