import { TLSSocket } from 'tls'; import { TextEncoder } from 'util'; import { createLogger } from '@/log'; import { Status } from './status'; const log = createLogger(); export class Response { socket: TLSSocket; isStatusSent = false; isClosed = false; encoder = new TextEncoder(); static fromSocket(socket: TLSSocket): Response { return new Response(socket); } constructor(socket: TLSSocket) { this.socket = socket; } private write(data: string | Buffer): void { let buffer: Uint8Array; if (data instanceof Buffer) { buffer = data; } else { buffer = this.encoder.encode(data); } try { this.socket.write(buffer); } catch (error: unknown) { log.error(error); } } sendStatus(code: Status, meta = ''): void { if (this.isStatusSent === true) { throw new Error('status already sent'); } else { this.write(`${code} ${meta}\r\n`); this.isStatusSent = true; } } send(data: string | Buffer): void { if (this.isStatusSent === false) { this.sendStatus(Status.SUCCESS, 'text/gemini'); } this.write(data); } end(): void { try { this.socket.end(); } catch (error) { log.error(error); } this.isClosed = true; } redirect(path = ''): void { this.sendStatus(Status.REDIRECT_TEMPORARY, path); this.end(); } }