helpers.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import type { IncomingMessage, ServerResponse } from 'node:http';
  2. export function sendJson(
  3. response: ServerResponse,
  4. status: number,
  5. value: unknown,
  6. ): void {
  7. response.statusCode = status;
  8. response.setHeader('content-type', 'application/json; charset=utf-8');
  9. response.end(`${JSON.stringify(value)}\n`);
  10. }
  11. export function sendHtml(response: ServerResponse, html: string): void {
  12. response.statusCode = 200;
  13. response.setHeader('content-type', 'text/html; charset=utf-8');
  14. response.end(html);
  15. }
  16. export function isValidId(id: string): boolean {
  17. return /^[a-zA-Z0-9_-]+$/.test(id) && id.length <= 256;
  18. }
  19. export function extractResumeSlug(interviewId: string): string {
  20. if (interviewId.startsWith('recovered-')) {
  21. return interviewId.replace('recovered-', '');
  22. }
  23. const parts = interviewId.split('-');
  24. return parts.slice(2).join('-') || interviewId;
  25. }
  26. const MAX_BODY_SIZE = 64 * 1024; // 64KB
  27. /**
  28. * Read and parse JSON body from an HTTP request with size limit.
  29. * Destroys the request if the body exceeds MAX_BODY_SIZE.
  30. */
  31. export async function readJsonBody(request: IncomingMessage): Promise<unknown> {
  32. const chunks: Buffer[] = [];
  33. let size = 0;
  34. for await (const chunk of request) {
  35. const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
  36. size += buffer.length;
  37. if (size > MAX_BODY_SIZE) {
  38. request.destroy();
  39. throw new Error('Request body too large');
  40. }
  41. chunks.push(buffer);
  42. }
  43. const raw = Buffer.concat(chunks).toString('utf8').trim();
  44. return raw ? JSON.parse(raw) : {};
  45. }