UNPKG

fastify-uws

Version:

A performant HTTP and WebSocket server for Fastify with uWebSockets.

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