fastify-uws
Version:
A performant HTTP and WebSocket server for Fastify with uWebSockets.
127 lines (126 loc) • 3.41 kB
JavaScript
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
};