fastify-uws
Version:
A performant HTTP and WebSocket server for Fastify with uWebSockets.
5 lines (4 loc) • 4.12 kB
JavaScript
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const T=require("eventemitter3"),l=require("./errors.cjs"),t=require("./symbols.cjs"),A=Buffer.from([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1]),o=(i,e,r)=>i.subarray(e,r).toString("hex"),u=()=>{};function E(){this.aborted=!0,this.emit("aborted"),this.errored&&this.emit("error",this.errored),this.emit("close")}function S(i){return this.emit("drain",i),!0}function v(){this.destroyed||(this.emit("timeout"),this.abort())}function H(i,e){i.writableNeedDrain=!0;let r=!1;const n=()=>{i.removeListener("drain",s),!r&&(r=!0,e())},s=()=>{r||(i.writableNeedDrain=!1,i.removeListener("close",n),i.removeListener("drain",s),e())};i.on("drain",s),i.once("close",n)}function f(i,e){if(e.status&&i.writeStatus(e.status),e.headers)for(const r of e.headers.values())if(r.isMultiValue)for(const n of r.value)i.writeHeader(r.name,n);else i.writeHeader(r.name,r.value)}function a(i){return i!=null&&i.empty?0:(i==null?void 0:i.byteLength)!==void 0?i.byteLength:Buffer.byteLength(i)}function m(i){return i!=null&&i.chunk?i.chunk:i}class p extends T.EventEmitter{constructor(e,r,n){super(),this.aborted=!1,this.writableNeedDrain=!1,this.bytesRead=0,this.bytesWritten=0,this.writableEnded=!1,this.errored=null,this[t.kServer]=e,this[t.kRes]=r,this[t.kWriteOnly]=n,this[t.kReadyState]={read:!1,write:!1},this[t.kEncoding]=null,this[t.kRemoteAdress]=null,this[t.kUwsRemoteAddress]=null,this[t.kHead]=null,this[t.kClientError]=!1,this.once("error",u),r.onAborted(E.bind(this)),r.onWritable(S.bind(this)),e.timeout&&(this[t.kTimeoutRef]=setTimeout(v.bind(this),e.timeout))}get readyState(){const e=this[t.kReadyState];return e.read&&!e.write?"readOnly":!e.read&&e.write?"writeOnly":e.read?"open":"opening"}get writable(){return!0}get readable(){return!0}get encrypted(){return!!this[t.kServer][t.kHttps]}get remoteAddress(){let e=this[t.kRemoteAdress];if(e)return e;let r=this[t.kUwsRemoteAddress];return r||(r=this[t.kUwsRemoteAddress]=Buffer.from(this[t.kRes].getRemoteAddress())),r.length===4?e=`${r.readUInt8(0)}.${r.readUInt8(1)}.${r.readUInt8(2)}.${r.readUInt8(3)}`:r.equals(A)?e="::1":e=`${o(r,0,2)}:${o(r,2,4)}:${o(r,4,6)}:${o(r,6,8)}:${o(r,8,10)}:${o(r,10,12)}:${o(r,12,14)}:${o(r,14)}`,this[t.kRemoteAdress]=e,e}get remoteFamily(){return this[t.kUwsRemoteAddress]||(this[t.kUwsRemoteAddress]=Buffer.from(this[t.kRes].getRemoteAddress())),this[t.kUwsRemoteAddress].length===4?"IPv4":"IPv6"}get destroyed(){return this.writableEnded||this.aborted}address(){return{...this[t.kServer][t.kAddress]}}abort(){this.aborted||(this.aborted=!0,!this[t.kWs]&&!this.writableEnded&&this[t.kRes].close())}setEncoding(e){this[t.kEncoding]=e}destroy(e){this.aborted||(this._clearTimeout(),this.errored=e,this.abort())}onRead(e){if(this[t.kWriteOnly]||this.aborted)return e(null,null);let r=!1;this[t.kReadyState].read=!0;const n=this[t.kEncoding];try{this[t.kRes].onData((s,h)=>{r||(this.bytesRead+=s.byteLength,n?s=Buffer.from(s).toString(n):s=Buffer.copyBytesFrom(new Uint8Array(s)),this.emit("data",s),e(null,s),h&&(r=!0,e(null,null)))})}catch(s){r=!0,this.destroy(s),e(s)}}end(e,r,n=u){if(this.aborted)throw new l.ERR_STREAM_DESTROYED;if(!e)return this.abort();this.writableEnded=!0,this._clearTimeout();const s=this[t.kRes];s.cork(()=>{this[t.kHead]&&(f(s,this[t.kHead]),this[t.kHead]=null),s.end(m(e)),this.bytesWritten+=a(e),this.emit("close"),this.emit("finish"),n()})}write(e,r,n=u){if(this.destroyed)throw new l.ERR_STREAM_DESTROYED;if(this[t.kClientError]&&e.startsWith("HTTP/")){const[h,c]=e.split(`\r
\r
`),[b,...k]=h.split(`\r
`),[,y,R]=b.split(" ");return this[t.kHead]={headers:k.map(d=>{const[w,...g]=d.split(": ");return{name:w,value:g.join(": ").trim()}}).filter(d=>d.name.toLowerCase()!=="content-length"),status:`${y} ${R}`},e=c,this.end(e,r,n)}const s=this[t.kRes];return this[t.kReadyState].write=!0,s.cork(()=>{this[t.kHead]&&(f(s,this[t.kHead]),this[t.kHead]=null);const h=s.write(m(e));if(this.bytesWritten+=a(e),h)return n();H(this,n)}),!this.writableNeedDrain}_clearTimeout(){this[t.kTimeoutRef]&&clearTimeout(this[t.kTimeoutRef])}}exports.HTTPSocket=p;