UNPKG

fastify-uws

Version:

A performant HTTP and WebSocket server for Fastify with uWebSockets.

2 lines (1 loc) 2.98 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("uWebSockets.js"),S=require("node:dns/promises"),E=require("node:http"),L=require("eventemitter3"),_=require("ipaddr.js"),l=require("./errors.cjs"),g=require("./http-socket.cjs"),R=require("./request.cjs"),w=require("./response.cjs"),s=require("./symbols.cjs");function T(n){return n.http2&&n.https?c.SSLApp({key_file_name:n.https.key.toString("utf-8"),cert_file_name:n.https.cert.toString("utf-8")}):c.App()}const v=new Map(E.METHODS.map(n=>[n.toLowerCase(),n])),d={};class q extends L.EventEmitter{[s.kHandler];timeout;[s.kHttps];[s.kWs];[s.kAddress];[s.kListenSocket];[s.kApp];[s.kClosed];[s.kListenAll];[s.kListening];constructor(e,t={}){super();const{http2:r=!1,https:h=null,connectionTimeout:u=0}=t;this[s.kHandler]=e,this.timeout=u,this[s.kHttps]=h,this[s.kWs]=null,this[s.kAddress]=null,this[s.kListenSocket]=null,this[s.kApp]=T({http2:r,https:h}),this[s.kClosed]=!1}get encrypted(){return!!this[s.kHttps]}get listening(){return this[s.kListening]}setTimeout(e){this.timeout=e}address(){return this[s.kAddress]}listen(e,t){e?.signal&&e.signal.addEventListener("abort",()=>{this.close()}),this[s.kListen](e).then(()=>{t?.(),this[s.kListening]=!0,this.emit("listening")}).catch(r=>{this[s.kAddress]=null,process.nextTick(()=>this.emit("error",r))})}closeIdleConnections(){this.close()}close(e=()=>{}){if(this[s.kAddress]=null,this[s.kListening]=!1,this[s.kClosed])return e();const t=this[s.kAddress]?.port;if(t!==void 0&&d[t]===this&&delete d[t],this[s.kAddress]=null,this[s.kClosed]=!0,this[s.kListenSocket]&&(c.us_listen_socket_close(this[s.kListenSocket]),this[s.kListenSocket]=null),this[s.kWs])for(const r of this[s.kWs].connections)r.close();process.nextTick(()=>{this.emit("close"),e()})}ref(){}unref(){}async[s.kListen]({port:e,host:t}){if(this[s.kClosed])throw new l.ERR_SERVER_DESTROYED;if(e!=null&&Number.isNaN(Number(e)))throw new l.ERR_SOCKET_BAD_PORT(e);e=e==null?0:Number(e);const r=await S.lookup(t);if(this[s.kAddress]={...r,port:e},this[s.kAddress].address.startsWith("["))throw new l.ERR_ENOTFOUND(this[s.kAddress].address);const h=_.parse(this[s.kAddress].address);this[s.kAddress].family=h.kind()==="ipv6"?"IPv6":"IPv4";const u=h.toNormalizedString(),a=this[s.kApp],p=(A,k)=>{const o=v.get(k.getMethod()),i=new g.HTTPSocket(this,A,o==="GET"||o==="HEAD");if(!o){i[s.kClientError]=!0,this.emit("clientError",new l.ERR_INVALID_METHOD,i);return}const f=new R.Request(k,i,o),m=new w.Response(i);f.headers.upgrade&&this.emit("upgrade",f,i),this[s.kHandler](f,m)};return a.any("/*",p),e!==0&&d[e]&&(this[s.kWs]=d[e][s.kWs]),this[s.kWs]&&this[s.kWs].addServer(this),new Promise((A,k)=>{const o=i=>{if(!i)return k(new l.ERR_ADDRINUSE(this[s.kAddress].address,e));this[s.kListenSocket]=i,e=this[s.kAddress].port=c.us_socket_local_port(i),d[e]||(d[e]=this),A()};this[s.kListenAll]=t==="localhost",this[s.kListenAll]?a.listen(e,o):a.listen(u,e,o)})}}exports.Server=q;