222 lines
7.1 KiB
JavaScript
222 lines
7.1 KiB
JavaScript
"use strict";
|
|
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getProtoOf = Object.getPrototypeOf;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
mod
|
|
));
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
var handler_exports = {};
|
|
__export(handler_exports, {
|
|
getProcessor: () => getProcessor,
|
|
handle: () => handle,
|
|
isContentEncodingBinary: () => isContentEncodingBinary,
|
|
isContentTypeBinary: () => isContentTypeBinary,
|
|
streamHandle: () => streamHandle
|
|
});
|
|
module.exports = __toCommonJS(handler_exports);
|
|
var import_crypto = __toESM(require("crypto"), 1);
|
|
var import_encode = require("../../utils/encode");
|
|
globalThis.crypto ??= import_crypto.default;
|
|
const getRequestContext = (event) => {
|
|
return event.requestContext;
|
|
};
|
|
const streamToNodeStream = async (reader, writer) => {
|
|
let readResult = await reader.read();
|
|
while (!readResult.done) {
|
|
writer.write(readResult.value);
|
|
readResult = await reader.read();
|
|
}
|
|
writer.end();
|
|
};
|
|
const streamHandle = (app) => {
|
|
return awslambda.streamifyResponse(
|
|
async (event, responseStream, context) => {
|
|
const processor = getProcessor(event);
|
|
try {
|
|
const req = processor.createRequest(event);
|
|
const requestContext = getRequestContext(event);
|
|
const res = await app.fetch(req, {
|
|
event,
|
|
requestContext,
|
|
context
|
|
});
|
|
const httpResponseMetadata = {
|
|
statusCode: res.status,
|
|
headers: Object.fromEntries(res.headers.entries())
|
|
};
|
|
responseStream = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata);
|
|
if (res.body) {
|
|
await streamToNodeStream(res.body.getReader(), responseStream);
|
|
} else {
|
|
responseStream.write("");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error processing request:", error);
|
|
responseStream.write("Internal Server Error");
|
|
} finally {
|
|
responseStream.end();
|
|
}
|
|
}
|
|
);
|
|
};
|
|
const handle = (app) => {
|
|
return async (event, lambdaContext) => {
|
|
const processor = getProcessor(event);
|
|
const req = processor.createRequest(event);
|
|
const requestContext = getRequestContext(event);
|
|
const res = await app.fetch(req, {
|
|
event,
|
|
requestContext,
|
|
lambdaContext
|
|
});
|
|
return processor.createResult(event, res);
|
|
};
|
|
};
|
|
class EventProcessor {
|
|
createRequest(event) {
|
|
const queryString = this.getQueryString(event);
|
|
const domainName = event.requestContext && "domainName" in event.requestContext ? event.requestContext.domainName : event.headers?.["host"] ?? event.multiValueHeaders?.["host"]?.[0];
|
|
const path = this.getPath(event);
|
|
const urlPath = `https://${domainName}${path}`;
|
|
const url = queryString ? `${urlPath}?${queryString}` : urlPath;
|
|
const headers = new Headers();
|
|
this.getCookies(event, headers);
|
|
if (event.headers) {
|
|
for (const [k, v] of Object.entries(event.headers)) {
|
|
if (v) {
|
|
headers.set(k, v);
|
|
}
|
|
}
|
|
}
|
|
if (event.multiValueHeaders) {
|
|
for (const [k, values] of Object.entries(event.multiValueHeaders)) {
|
|
if (values) {
|
|
const foundK = headers.get(k);
|
|
values.forEach((v) => (!foundK || !foundK.includes(v)) && headers.append(k, v));
|
|
}
|
|
}
|
|
}
|
|
const method = this.getMethod(event);
|
|
const requestInit = {
|
|
headers,
|
|
method
|
|
};
|
|
if (event.body) {
|
|
requestInit.body = event.isBase64Encoded ? Buffer.from(event.body, "base64") : event.body;
|
|
}
|
|
return new Request(url, requestInit);
|
|
}
|
|
async createResult(event, res) {
|
|
const contentType = res.headers.get("content-type");
|
|
let isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
|
|
if (!isBase64Encoded) {
|
|
const contentEncoding = res.headers.get("content-encoding");
|
|
isBase64Encoded = isContentEncodingBinary(contentEncoding);
|
|
}
|
|
const body = isBase64Encoded ? (0, import_encode.encodeBase64)(await res.arrayBuffer()) : await res.text();
|
|
const result = {
|
|
body,
|
|
headers: {},
|
|
statusCode: res.status,
|
|
isBase64Encoded
|
|
};
|
|
this.setCookies(event, res, result);
|
|
res.headers.forEach((value, key) => {
|
|
result.headers[key] = value;
|
|
});
|
|
return result;
|
|
}
|
|
setCookies = (event, res, result) => {
|
|
if (res.headers.has("set-cookie")) {
|
|
const cookies = res.headers.get("set-cookie")?.split(", ");
|
|
if (Array.isArray(cookies)) {
|
|
this.setCookiesToResult(result, cookies);
|
|
res.headers.delete("set-cookie");
|
|
}
|
|
}
|
|
};
|
|
}
|
|
const v2Processor = new class EventV2Processor extends EventProcessor {
|
|
getPath(event) {
|
|
return event.rawPath;
|
|
}
|
|
getMethod(event) {
|
|
return event.requestContext.http.method;
|
|
}
|
|
getQueryString(event) {
|
|
return event.rawQueryString;
|
|
}
|
|
getCookies(event, headers) {
|
|
if (Array.isArray(event.cookies)) {
|
|
headers.set("Cookie", event.cookies.join("; "));
|
|
}
|
|
}
|
|
setCookiesToResult(result, cookies) {
|
|
result.cookies = cookies;
|
|
}
|
|
}();
|
|
const v1Processor = new class EventV1Processor extends EventProcessor {
|
|
getPath(event) {
|
|
return event.path;
|
|
}
|
|
getMethod(event) {
|
|
return event.httpMethod;
|
|
}
|
|
getQueryString(event) {
|
|
return Object.entries(event.queryStringParameters || {}).filter(([, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
}
|
|
getCookies(event, headers) {
|
|
}
|
|
setCookiesToResult(result, cookies) {
|
|
result.multiValueHeaders = {
|
|
"set-cookie": cookies
|
|
};
|
|
}
|
|
}();
|
|
const getProcessor = (event) => {
|
|
if (isProxyEventV2(event)) {
|
|
return v2Processor;
|
|
} else {
|
|
return v1Processor;
|
|
}
|
|
};
|
|
const isProxyEventV2 = (event) => {
|
|
return Object.prototype.hasOwnProperty.call(event, "rawPath");
|
|
};
|
|
const isContentTypeBinary = (contentType) => {
|
|
return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml.*)$/.test(
|
|
contentType
|
|
);
|
|
};
|
|
const isContentEncodingBinary = (contentEncoding) => {
|
|
if (contentEncoding === null) {
|
|
return false;
|
|
}
|
|
return /^(gzip|deflate|compress|br)/.test(contentEncoding);
|
|
};
|
|
// Annotate the CommonJS export names for ESM import in node:
|
|
0 && (module.exports = {
|
|
getProcessor,
|
|
handle,
|
|
isContentEncodingBinary,
|
|
isContentTypeBinary,
|
|
streamHandle
|
|
});
|