UNPKG

fastify-uws

Version:

A performant HTTP and WebSocket server for Fastify with uWebSockets.

127 lines (126 loc) 3.41 kB
import { STATUS_CODES as u } from "node:http"; import { Writable as a } from "streamx"; import { ERR_HEAD_SET as n, ERR_STREAM_DESTROYED as o } from "./errors.js"; import { kHeaders as r, kHead as c } from "./symbols.js"; class f { isMultiValue; name; value; constructor(t, e) { this.isMultiValue = Array.isArray(e), this.name = t, this.value = this.isMultiValue ? e : String(e); } } const l = Buffer.alloc(0); class d { chunk; end; byteLength; constructor(t, e = !1) { this.chunk = t || l, this.empty = !t, this.end = e, this.byteLength = this.empty ? 1 : Buffer.byteLength(this.chunk); } } function w() { this.emit("aborted"); } const b = () => { }, y = { byteLength(i) { return i.byteLength; } }; class L extends a { socket; statusCode; statusMessage; headersSent; chunked; contentLength; writableEnded; firstChunk; [r]; constructor(t) { super(y), this.socket = t, this.statusCode = 200, this.headersSent = !1, this.chunked = !1, this.contentLength = null, this.writableEnded = !1, this.firstChunk = !0, this[r] = /* @__PURE__ */ new Map(); const e = this.destroy.bind(this); this.once("error", b), t.once("error", e), t.once("close", e), t.once("aborted", w.bind(this)); } get aborted() { return this.socket.aborted; } get finished() { return this.socket.writableEnded && !this.socket.aborted; } get status() { return `${this.statusCode} ${this.statusMessage || u[this.statusCode]}`; } get bytesWritten() { return this.socket.bytesWritten; } hasHeader(t) { return this[r].has(t.toLowerCase()); } getHeader(t) { return this[r].get(t.toLowerCase())?.value; } getHeaders() { const t = {}; return this[r].forEach((e, s) => { t[s] = e.value; }), t; } setHeader(t, e) { if (this.headersSent) throw new n(); const s = t.toLowerCase(); if (s === "content-length") { this.contentLength = Number(e); return; } if (s === "transfer-encoding") { this.chunked = e.includes("chunked"); return; } this[r].set(s, new f(t, e)); } removeHeader(t) { if (this.headersSent) throw new n(); this[r].delete(t.toLowerCase()); } writeHead(t, e, s) { if (this.headersSent) throw new n(); if (this.statusCode = t, typeof e == "object" ? s = e : e && (this.statusMessage = e), s) for (const h of Object.keys(s)) this.setHeader(h, s[h]); } end(t) { if (!this.aborted) { if (this.destroyed) throw new o(); return this.writableEnded = !0, super.end(new d(t, !0)); } } destroy(t) { this.destroyed || this.destroying || this.aborted || this.socket.destroy(t); } write(t) { if (!this.aborted) { if (this.destroyed) throw new o(); return t = new d(t), this.firstChunk && this.contentLength !== null && this.contentLength === t.byteLength ? (t.end = !0, this.writableEnded = !0, super.end(t), !0) : (this.firstChunk = !1, super.write(t)); } } _write(t, e) { if (this.aborted) return e(); if (this.headersSent || (this.headersSent = !0, this.socket[c] = { headers: this[r], status: this.status }), t.end) { this.socket.end(t, null, e); return; } this.socket.write(t, null, e); } _destroy(t) { if (this.socket.destroyed) return t(); this.socket.once("close", t); } } export { L as Response };