| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- import { HTTPStatus } from 'deps';
- import { isSuccessfulStatus } from 'deps';
- import { logger } from 'infra/logger.ts';
- interface Options {
- status?: HTTPStatus;
- json?: boolean;
- }
- export default class Controller {
- constructor(
- public handlers: Record<
- string,
- (
- req: Request,
- error?: string,
- headers?: Record<string, string>,
- ) => Response | Promise<Response>
- >,
- ) {}
- public static response = (
- req: Request,
- body: string,
- options: Options = {},
- ) => {
- const url = new URL(req.url);
- const output = new TextEncoder().encode(body);
- const response = new Response(output, {
- status: options.status ?? HTTPStatus.OK,
- });
- const userName = this.getUser(req);
- if (options.json) {
- response.headers.set('Content-Type', 'application/json');
- }
- const userAgent = req.headers.get('User-Agent') ?? '-';
- const logMessage = this.getLogMessage(
- req.method,
- url.pathname,
- response.status,
- output.byteLength,
- userAgent,
- userName,
- );
- if (isSuccessfulStatus(response.status)) {
- if (this.isHealthCheck(userAgent)) {
- logger.debug(logMessage);
- } else {
- logger.info(logMessage);
- }
- } else {
- logger.error(logMessage);
- }
- return response;
- };
- public static responseJSON = (
- req: Request,
- body: unknown,
- options: Options = {},
- ) => {
- options.json = true;
- return this.response(req, JSON.stringify(body), options);
- };
- private static getUser = (req: Request): string | undefined => {
- const authHeader = req.headers.get('Authorization');
- if (authHeader && authHeader.startsWith('Basic ')) {
- const base64Credentials = authHeader.slice(6);
- const credentials = atob(base64Credentials);
- const [userName] = credentials.split(':');
- return userName;
- }
- return;
- };
- private static getLogMessage(
- method: string,
- path: string,
- status: number,
- length: number,
- userAgent: string,
- userName?: string,
- ) {
- const user = userName ? userName + ' ' : '';
- return `${method} ${path} ${user}${status} ${length} (${userAgent})`;
- }
- private static isHealthCheck(userAgent: string): boolean {
- return userAgent === Deno.env.get('DOCKER_USER_AGENT');
- }
- }
|