dewy
Version:
Dewy(dǝw-y) is a minimalist HTTP server framework with a small codebase, utilizing built-in URLPattern for efficient routing.
115 lines (114 loc) • 3.98 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.cors = void 0;
require("../_dnt.polyfills.js");
const DEFAULT_METHODS = new Set([
"GET",
"HEAD",
"PUT",
"PATCH",
"POST",
"DELETE",
]);
function cors(options = {}) {
const allowOrigin = options.allowOrigin ? new Set(options.allowOrigin) : null;
const allowMethods = options.allowMethods
? new Set(options.allowMethods)
: DEFAULT_METHODS;
return async ({ request }, next) => {
const requestMethod = request.method.toUpperCase();
const requestOrigin = request.headers.get("Origin") ?? "";
if (requestMethod === "OPTIONS") {
// not preflight
if (!request.headers.get("Access-Control-Request-Method")) {
return next();
}
const response = options.preflightContinue
? await next()
: new Response(null, {
status: 204,
headers: { "Content-Length": "0" },
});
applyOrigin(response, allowOrigin, requestOrigin);
applyCredentials(response, options, requestOrigin);
applyMethods(response, allowMethods);
applyHeaders(response, options, request);
applyMaxAge(response, options);
applyExposeHeaders(response, options);
applyAllowPrivateNetwork(response, options, request);
return response;
}
const response = await next();
applyOrigin(response, allowOrigin, requestOrigin);
applyCredentials(response, options, requestOrigin);
applyExposeHeaders(response, options);
return response;
};
}
exports.cors = cors;
/** @internal */
function applyOrigin(res, allowOrigin, origin) {
if (!allowOrigin) {
res.headers.set("Access-Control-Allow-Origin", "*");
return;
}
if (allowOrigin.has(origin)) {
res.headers.set("Access-Control-Allow-Origin", origin);
// ref. https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#access-control-allow-origin
applyVaryAppend(res, "Origin");
}
}
/** @internal */
function applyCredentials(res, options, requestOrigin) {
if (options.allowCredentials) {
if (res.headers.get("Access-Control-Allow-Origin") === "*") {
res.headers.set("Access-Control-Allow-Origin", requestOrigin);
}
res.headers.set("Access-Control-Allow-Credentials", "true");
}
}
function applyMethods(res, allowMethods) {
res.headers.set("Access-Control-Allow-Methods", Array.from(allowMethods).join(","));
}
/** @internal */
function applyHeaders(res, options, req) {
const requestHeaders = req.headers.get("Access-Control-Request-Headers");
if (!requestHeaders) {
return;
}
if (!options.allowHeaders) {
applyVaryAppend(res, "Access-Control-Request-Headers");
res.headers.set("Access-Control-Allow-Headers", requestHeaders);
return;
}
res.headers.set("Access-Control-Allow-Headers", options.allowHeaders.join(","));
}
/** @internal */
function applyExposeHeaders(res, options) {
if (options.exposeHeaders) {
res.headers.set("Access-Control-Expose-Headers", options.exposeHeaders.join(","));
}
}
/** @internal */
function applyMaxAge(res, options) {
if (options.maxAge) {
res.headers.set("Access-Control-Max-Age", `${options.maxAge}`);
}
}
/** @internal */
function applyAllowPrivateNetwork(res, options, req) {
if (options.allowPrivateNetwork &&
req.headers.get("Access-Control-Request-Private-Network")) {
res.headers.set("Access-Control-Allow-Private-Network", "true");
}
}
/** @internal */
function applyVaryAppend(res, value) {
const existsVary = res.headers.get("Vary");
if (existsVary) {
res.headers.set("Vary", `${existsVary}, ${value}`);
}
else {
res.headers.set("Vary", value);
}
}