github-webhook-filter/main.ts

85 lines
2.4 KiB
TypeScript
Raw Normal View History

import { httpErrors, log } from "./deps.ts";
2022-09-02 20:24:33 +00:00
import config from "./lib/config.ts";
import handler from "./lib/handler.ts";
import { requestLog } from "./lib/util.ts";
2022-09-02 20:24:33 +00:00
function setupLogs() {
log.setup({
handlers: {
console: new log.ConsoleHandler("DEBUG", {
formatter: (rec) => `${rec.datetime.toISOString()} [${rec.levelName}] ${rec.msg}`,
}),
2022-09-02 20:24:33 +00:00
},
loggers: {
default: {
level: config.debug ? "DEBUG" : "INFO",
handlers: ["console"],
},
},
});
}
2022-09-02 20:24:33 +00:00
async function handleRequest(req: Request, info: Deno.ServeHandlerInfo): Promise<Response> {
const reqLog = requestLog(req.headers);
2022-09-06 02:00:52 +00:00
let res: Response;
let meta: Record<string, string> | null = null;
2022-09-02 20:24:33 +00:00
try {
const webhookResult = await handler(req);
if (webhookResult instanceof Response) {
res = webhookResult;
} else {
[res, meta] = webhookResult;
}
2022-09-02 20:24:33 +00:00
} catch (err) {
if (err instanceof httpErrors.HttpError && err.expose) {
reqLog.warn(`http error: ${err.message}`);
2022-09-06 02:00:52 +00:00
res = new Response(err.message, { status: err.status });
2022-09-02 20:24:33 +00:00
} else {
reqLog.critical(err);
2022-09-06 02:00:52 +00:00
res = new Response("Internal Server Error", { status: 500 });
2022-09-02 20:24:33 +00:00
}
}
// clone response to make headers mutable
res = new Response(res.body, res);
// set metadata headers
meta = {
"deploy": config.deployId,
...meta,
};
for (const [key, value] of Object.entries(meta)) {
res.headers.set(`x-webhook-filter-${key}`, value);
}
// remove other headers that don't make sense here
for (const header of ["set-cookie", "alt-svc"]) {
res.headers.delete(header);
}
// log request
2022-09-06 02:00:52 +00:00
const respLen = res.headers.get("content-length") || 0;
const addr = info.remoteAddr;
reqLog.info(
2022-09-06 02:00:52 +00:00
`http: ${addr.hostname}:${addr.port} - ${req.method} ${req.url} ${res.status} ${respLen}`,
2022-09-02 20:24:33 +00:00
);
2022-09-06 02:00:52 +00:00
return res;
2022-09-02 20:24:33 +00:00
}
if (import.meta.main) {
setupLogs();
if (config.signKey) {
log.info("url signing enabled");
2022-09-04 12:39:03 +00:00
}
log.info(`starting webserver on ${config.hostname}:${config.port}`);
Deno.serve({
hostname: config.hostname,
port: config.port,
onListen: () => log.info(`listening on ${config.hostname}:${config.port}`),
}, handleRequest);
}