💾 Archived View for iich.space › src › modules › gemini › response.ts captured on 2021-12-17 at 13:26:06.

View Raw

More Information

⬅️ Previous capture (2021-12-03)

-=-=-=-=-=-=-

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();
  }
}