@stacksjs/whois
Version:
Easily get whois info.
8 lines (7 loc) • 14.2 kB
JavaScript
// @bun
import E from"net";import{log as q}from"@stacksjs/logging";var Y="https://www.iana.org/whois?q=",Z={"whois.denic.de":"-T dn,ace","whois.nic.fr":"-V Md5.2"},K={"br.com":"whois.centralnic.net","cn.com":"whois.centralnic.net","de.com":"whois.centralnic.net","eu.com":"whois.centralnic.net","gb.com":"whois.centralnic.net","gb.net":"whois.centralnic.net","gr.com":"whois.centralnic.net","hu.com":"whois.centralnic.net","in.net":"whois.centralnic.net","no.com":"whois.centralnic.net","qc.com":"whois.centralnic.net","ru.com":"whois.centralnic.net","sa.com":"whois.centralnic.net","se.com":"whois.centralnic.net","se.net":"whois.centralnic.net","uk.com":"whois.centralnic.net","uk.net":"whois.centralnic.net","us.com":"whois.centralnic.net","uy.com":"whois.centralnic.net","za.com":"whois.centralnic.net","jpn.com":"whois.centralnic.ne","web.com":"whois.centralnic.ne",com:"whois.verisign-grs.com","za.net":"whois.za.net",net:"whois.verisign-grs.com","eu.org":"whois.eu.org","za.org":"whois.za.org",org:"whois.pir.org","llyw.cymru":"whois.nic.llyw.cymru","gov.scot":"whois.nic.gov.scot","gov.wales":"whois.nic.gov.wales",edu:"whois.educause.edu",gov:"whois.dotgov.gov",int:"whois.iana.org","e164.arpa":"whois.ripe.net",arpa:"whois.iana.org",aero:"whois.aero",asia:"whois.nic.asia",biz:"whois.nic.biz",cat:"whois.nic.cat",coop:"whois.nic.coop",info:"whois.afilias.net",jobs:"whois.nic.jobs",mobi:"whois.afilias.net",museum:"whois.nic.museum",name:"whois.nic.name",post:"whois.dotpostregistry.net",pro:"whois.nic.pro",tel:"whois.nic.tel",travel:"whois.nic.travel",xxx:"whois.nic.xxx",ac:"whois.nic.ac",ae:"whois.aeda.net.ae",af:"whois.nic.af",ag:"whois.nic.ag",ai:"whois.nic.ai",am:"whois.amnic.net",ar:"whois.nic.ar",as:"whois.nic.as","priv.at":"whois.nic.priv.at",at:"whois.nic.at",au:"whois.auda.org.au",aw:"whois.nic.aw",ax:"whois.ax",be:"whois.dns.be",bf:"whois.registre.bf",bg:"whois.register.bg",bh:"whois.nic.bh",bi:"whois1.nic.bi",bj:"whois.nic.bj",bm:"whois.afilias-srs.net",bn:"whois.bnnic.bn",bo:"whois.nic.bo",br:"whois.registro.br",by:"whois.cctld.by",bw:"whois.nic.net.bw",bz:"whois.afilias-grs.info","co.ca":"whois.co.ca",ca:"whois.cira.ca",cc:"ccwhois.verisign-grs.com",cd:"whois.nic.cd",ch:"whois.nic.ch",ci:"whois.nic.ci",cl:"whois.nic.cl",cm:"whois.netcom.cm","edu.cn":"whois.edu.cn",cn:"whois.cnnic.cn","uk.co":"whois.uk.co",co:"whois.nic.co",cr:"whois.nic.cr",cx:"whois.nic.cx",cz:"whois.nic.cz",de:"whois.denic.de",dk:"whois.dk-hostmaster.dk",dm:"whois.dmdomains.dm",do:"whois.nic.do",dz:"whois.nic.dz",ec:"whois.nic.ec",ee:"whois.tld.ee",eu:"whois.eu",fi:"whois.fi",fj:"www.whois.fj",fm:"whois.nic.fm",fo:"whois.nic.fo",fr:"whois.nic.fr",gd:"whois.nic.gd",ge:"whois.nic.ge",gf:"whois.mediaserv.net",gg:"whois.gg",gh:"whois.nic.gh",gi:"whois2.afilias-grs.net",gl:"whois.nic.gl",gp:"whois.nic.gp",gq:"whois.dominio.gq",gs:"whois.nic.gs",gy:"whois.registry.gy",hk:"whois.hkirc.hk",hm:"whois.registry.hm",hn:"whois.nic.hn",hr:"whois.dns.hr",ht:"whois.nic.ht",hu:"whois.nic.hu",id:"whois.id",ie:"whois.weare.ie",il:"whois.isoc.org.il",im:"whois.nic.im",in:"whois.registry.in",io:"whois.nic.io",iq:"whois.cmc.iq",ir:"whois.nic.ir",is:"whois.isnic.is",it:"whois.nic.it",je:"whois.je",jp:"whois.jprs.jp",ke:"whois.kenic.or.ke",kg:"whois.kg",ki:"whois.nic.ki",kn:"whois.nic.kn",kr:"whois.kr",kw:"whois.nic.kw",ky:"whois.kyregistry.ky",kz:"whois.nic.kz",la:"whois.nic.la",lb:"whois.lbdr.org.lb",lc:"whois2.afilias-grs.net",li:"whois.nic.li",lk:"whois.nic.lk",ls:"whois.nic.ls",lt:"whois.domreg.lt",lu:"whois.dns.lu",lv:"whois.nic.lv",ly:"whois.nic.ly",ma:"whois.registre.ma",md:"whois.nic.md",me:"whois.nic.me",mg:"whois.nic.mg",mk:"whois.marnet.mk",ml:"whois.dot.ml",mm:"whois.registry.gov.mm",mn:"whois.nic.mn",mq:"whois.mediaserv.net",mr:"whois.nic.mr",ms:"whois.nic.ms",mt:"whois.nic.org.mt",mu:"whois.nic.mu",mw:"whois.nic.mw",mx:"whois.mx",my:"whois.mynic.my",mz:"whois.nic.mz",na:"whois.na-nic.com.na",nc:"whois.nc",nf:"whois.nic.nf",ng:"whois.nic.net.ng",nl:"whois.domain-registry.nl",no:"whois.norid.no",nu:"whois.iis.nu",nz:"whois.irs.net.nz",om:"whois.registry.om",pe:"kero.yachay.pe",pf:"whois.registry.pf",pk:"whois.pknic.net.pk","co.pl":"whois.co.pl",pl:"whois.dns.pl",pm:"whois.nic.pm",pr:"whois.afilias-srs.net",ps:"whois.pnina.ps",pt:"whois.dns.pt",pw:"whois.nic.pw",qa:"whois.registry.qa",re:"whois.nic.re",ro:"whois.rotld.ro",rs:"whois.rnids.rs","ac.ru":"whois.free.net","edu.ru":"whois.informika.ru","com.ru":"whois.flexireg.net","msk.ru":"whois.flexireg.net","net.ru":"whois.nic.net.ru","nov.ru":"whois.flexireg.net","org.ru":"whois.nic.net.ru","pp.ru":"whois.nic.net.ru","spb.ru":"whois.flexireg.net",ru:"whois.tcinet.ru",rw:"whois.ricta.org.rw",sa:"whois.nic.net.sa",sb:"whois.nic.net.sb",sc:"whois2.afilias-grs.net",sd:"whois.sdnic.sd",se:"whois.iis.se",sg:"whois.sgnic.sg",sh:"whois.nic.sh",si:"whois.register.si",sk:"whois.sk-nic.sk",sl:"whois.nic.sl",sm:"whois.nic.sm",sn:"whois.nic.sn",so:"whois.nic.so",ss:"whois.nic.ss",st:"whois.nic.st","msk.su":"whois.flexireg.net","nov.su":"whois.flexireg.net","spb.su":"whois.flexireg.net",su:"whois.tcinet.ru",sx:"whois.sx",sy:"whois.tld.sy",tc:"whois.nic.tc",td:"whois.nic.td",tf:"whois.nic.tf",tg:"whois.nic.tg",th:"whois.thnic.co.th",tk:"whois.dot.tk",tl:"whois.nic.tl",tm:"whois.nic.tm",tn:"whois.ati.tn",to:"whois.tonic.to",tr:"whois.trabis.gov.tr",tv:"whois.nic.tv",tw:"whois.twnic.net.tw",tz:"whois.tznic.or.tz","biz.ua":"whois.biz.ua","co.ua":"whois.co.ua","pp.ua":"whois.pp.ua",ua:"whois.ua",ug:"whois.co.ug","ac.uk":"whois.nic.ac.uk","gov.uk":"whois.gov.uk",uk:"whois.nic.uk","fed.us":"whois.nic.gov",us:"whois.nic.us",uy:"whois.nic.org.uy",uz:"whois.cctld.uz",vc:"whois2.afilias-grs.net",ve:"whois.nic.ve",vg:"whois.nic.vg",vu:"whois.dnrs.vu",wf:"whois.nic.wf",ws:"whois.website.ws",yt:"whois.nic.yt","ac.za":"whois.ac.za","co.za":"whois.registry.net.za","gov.za":"whois.gov.za","net.za":"net-whois.registry.net.za","org.za":"org-whois.registry.net.za","web.za":"web-whois.registry.net.za",zm:"whois.zicta.zm","xn--2scrj9c":"whois.registry.in","xn--3e0b707e":"whois.kr","xn--3hcrj9c":"whois.registry.in","xn--45br5cyl":"whois.registry.in","xn--45brj9c":"whois.registry.in","xn--4dbrk0ce":"whois.isoc.org.il","xn--80ao21a":"whois.nic.kz","xn--90a3ac":"whois.rnids.rs","xn--90ae":"whois.imena.bg","xn--90ais":"whois.cctld.by","xn--clchc0ea0b2g2a9gcd":"whois.sgnic.sg","xn--d1alf":"whois.marnet.mk","xn--e1a4c":"whois.eu","xn--fiqs8s":"cwhois.cnnic.cn","xn--fiqz9s":"cwhois.cnnic.cn","xn--fpcrj9c3d":"whois.registry.in","xn--fzc2c9e2c":"whois.nic.lk","xn--gecrj9c":"whois.registry.in","xn--h2breg3eve":"whois.registry.in","xn--h2brj9c8c":"whois.registry.in","xn--h2brj9c":"whois.registry.in","xn--j1amh":"whois.dotukr.com","xn--j6w193g":"whois.hkirc.hk","xn--kprw13d":"whois.twnic.net.tw","xn--kpry57d":"whois.twnic.net.tw","xn--lgbbat1ad8j":"whois.nic.dz","xn--mgb9awbf":"whois.registry.om","xn--mgba3a4f16a":"whois.nic.ir","xn--mgbaam7a8h":"whois.aeda.net.ae","xn--mgbah1a3hjkrd":"whois.nic.mr","xn--mgbbh1a71e":"whois.registry.in","xn--mgbbh1a":"whois.registry.in","xn--mgberp4a5d4ar":"whois.nic.net.sa","xn--mgbgu82a":"whois.registry.in","xn--mgbtx2b":"whois.cmc.iq","xn--mgbx4cd0ab":"whois.mynic.my","xn--node":"whois.itdc.ge","xn--o3cw4h":"whois.thnic.co.th","xn--ogbpf8fl":"whois.tld.sy","xn--p1ai":"whois.tcinet.ru","xn--pgbs0dh":"whois.ati.tn","xn--q7ce6a":"whois.nic.la","xn--qxa6a":"whois.eu","xn--rvc1e0am3e":"whois.registry.in","xn--s9brj9c":"whois.registry.in","xn--wgbh1c":"whois.dotmasr.eg","xn--wgbl6a":"whois.registry.qa","xn--xkc2al3hye2a":"whois.nic.lk","xn--xkc2dl3a5ee0h":"whois.registry.in","xn--y9a3aq":"whois.amnic.net","xn--yfro4i67o":"whois.sgnic.sg","xn--ygbi2ammx":"whois.pnina.ps"};import U from"net";class G{options;constructor(i){this.options=i}static createConnection(i,h){new G(i).connect(h)}connect(i){let h=new U.Socket,{proxy:w,destination:n}=this.options;h.connect({port:w.port,host:w.host},()=>{if(w.type===5)this.connectSocks5(h,i);else this.connectSocks4(h,i)}),h.on("error",(g)=>{i(g)})}connectSocks4(i,h){let{destination:w,proxy:n}=this.options,g=w.port,c=n.userId||"",s;if(this.isIPv4(w.host)){let m=w.host.split(".").map(Number);s=Buffer.from(m)}else s=Buffer.from([0,0,0,1]);let o=Buffer.concat([Buffer.from([4]),Buffer.from([1]),Buffer.from([g>>8&255,g&255]),s,Buffer.from(c),Buffer.from([0])]);if(!this.isIPv4(w.host)){let m=Buffer.concat([o,Buffer.from(w.host),Buffer.from([0])]);i.write(m)}else i.write(o);i.once("data",(m)=>{if(m.length<8){h(Error("Invalid SOCKS4 response"));return}let x=m[1];if(x!==90){h(Error(`SOCKS4 connection failed with status: ${x}`));return}h(null,{socket:i})})}connectSocks5(i,h){let{destination:w,proxy:n}=this.options,g;if(n.userId&&n.password)g=[0,2];else g=[0];let c=Buffer.from([5,g.length,...g]);i.write(c),i.once("data",(s)=>{if(s.length<2||s[0]!==5){h(Error("Invalid SOCKS5 greeting response"));return}let o=s[1];if(o===255){h(Error("No acceptable authentication methods"));return}if(o===2)this.authenticateSocks5(i,h);else this.sendConnectRequest(i,h)})}authenticateSocks5(i,h){let{proxy:w}=this.options,n=w.userId||"",g=w.password||"",c=Buffer.concat([Buffer.from([1]),Buffer.from([n.length]),Buffer.from(n),Buffer.from([g.length]),Buffer.from(g)]);i.write(c),i.once("data",(s)=>{if(s.length<2||s[0]!==1){h(Error("Invalid SOCKS5 auth response"));return}if(s[1]!==0){h(Error("SOCKS5 authentication failed"));return}this.sendConnectRequest(i,h)})}sendConnectRequest(i,h){let{destination:w}=this.options,n=w.port,g,c;if(this.isIPv4(w.host)){c=1;let o=w.host.split(".").map(Number);g=Buffer.from(o)}else if(this.isIPv6(w.host)){c=4;let o=w.host.split(":"),m=[];for(let x of o){let z=Number.parseInt(x,16);m.push(z>>8&255,z&255)}g=Buffer.from(m)}else c=3,g=Buffer.concat([Buffer.from([w.host.length]),Buffer.from(w.host)]);let s=Buffer.concat([Buffer.from([5,1,0,c]),g,Buffer.from([n>>8&255,n&255])]);i.write(s),i.once("data",(o)=>{if(o.length<10||o[0]!==5){h(Error("Invalid SOCKS5 connect response"));return}let m=o[1];if(m!==0){let z=m===void 0?"No SOCKS5 status returned":{1:"General SOCKS server failure",2:"Connection not allowed by ruleset",3:"Network unreachable",4:"Host unreachable",5:"Connection refused",6:"TTL expired",7:"Command not supported",8:"Address type not supported"}[m]||`Unknown error (${m})`;h(Error(`SOCKS5 connection failed: ${z}`));return}h(null,{socket:i})})}isIPv4(i){if(!/^(?:\d{1,3}\.){3}\d{1,3}$/.test(i))return!1;return i.split(".").map(Number).every((n)=>n>=0&&n<=255)}isIPv6(i){return i.includes(":")&&i.split(":").length>=3}}var _;((w)=>{w[w.SOCKS4=0]="SOCKS4";w[w.SOCKS5=1]="SOCKS5"})(_||={});function Q(i){if(Array.isArray(i))return i.slice();if(typeof i==="object"&&i!==null){let h={};for(let w in i)if(Object.prototype.hasOwnProperty.call(i,w))h[w]=Q(i[w]);return h}return i}async function A(i){let h=Y+i;try{let w=await fetch(h);if(w.ok){let g=(await w.text()).match(/whois:\s+(\S+)/);if(g?.[1])return g[1]}}catch(w){console.error("Error in getting WhoIs server data from IANA",w)}return""}function N(i){if(i==="com")return"whois.verisign-grs.com";return K[i]}function $(i){let h=i.split(".");for(let w=h.length-1;w>0;w--){let n=h.slice(w).join(".");if(K[n])return n}return h[h.length-1]}function y(i){return Z[i]}class J{static iterParse(i,h){let w="",n=null,g="";for(let c=0;c<i.length;c++){let s=i[c];if(s===`
`||g===":"&&s===" "){if(w.trim()in h)n=w.trim();else if(n!==null){let o=w.trim();if(o!==""){let m=h[n];if(Array.isArray(m))m.push(o);else h[n]=o;n=null}}w=""}else if(s!==":")w=w+s;if(g=s,w==="Record maintained by"||w===">>>")break}return h}static parseData(i,h){if(!h)h={"Domain Name":"","Creation Date":"","Updated Date":"","Registry Expiry Date":"","Domain Status":[],Registrar:""};return h=J.iterParse(i,h),h}}async function R(i,h,w,n,g,c){let s=new TextDecoder(g),o=new TextEncoder;if(!c){let x=new E.Socket;return x.setTimeout(30000),new Promise((z,f)=>{try{x.connect({port:n,host:w},()=>{if(h!=="")x.write(o.encode(`${h} ${i}\r
`));else x.write(o.encode(`${i}\r
`))}),x.on("data",(b)=>{z(s.decode(b))}),x.on("error",(b)=>{f(b)}),x.on("timeout",()=>{x.destroy(),f(Error(`WHOIS request to ${w}:${n} timed out after 30s`))})}catch(b){f(b)}})}let m={proxy:{host:c.ip,port:c.port,type:c.type===1?5:4},command:"connect",destination:{host:w,port:n}};if(c.username&&c.password)m.proxy.userId=c.username,m.proxy.password=c.password;return new Promise((x,z)=>{G.createConnection(m,(f,b)=>{if(f)z(f);else{if(!b)z(Error("No socket info received!"));if(h!=="")b?.socket.write(o.encode(`${h} ${i}\r
`));else b?.socket.write(o.encode(`${i}\r
`));b?.socket.on("data",(H)=>{x(s.decode(H))}),b?.socket.resume()}})})}async function X(i,h=!1,w=null){let n,g=43,c="",s,o="utf-8";if(!w)n=$(i),s=null;else n=w.tld?w.tld:$(i),o=w.encoding?w.encoding:"utf-8",s=w.proxy?w.proxy:null,c=w.server?w.server:"",g=w.serverPort?w.serverPort:43;if(c===""){let z=N(n);if(!z){if(q.debug(`No WhoIs server found for TLD: ${n}! Attempting IANA WhoIs database for server!`),z=await A(n),!z)return q.debug("WhoIs server could not be found!"),{_raw:"",parsedData:null};q.debug(`WhoIs sever found for ${n}: ${c}`)}c=z}let x=y(c)||"";try{q.debug(`Attempting WHOIS lookup for ${i} on server ${c}`);let z=await R(i,x,c,g,o,s);if(q.debug("Raw WHOIS data received:",z),!h){let b=J.parseData(z,null);return{_raw:z,parsedData:b}}let f=null;if(w?.parseData)f=Q(w.parseData);try{let b=J.parseData(z,f);return{_raw:z,parsedData:b}}catch(b){return console.error("Error in parsing WhoIs data!",b),{_raw:z,parsedData:null}}}catch(z){return q.debug(`Error in WHOIS lookup for ${i} on server ${c}`,z),{_raw:"",parsedData:null}}}function T(i,h=null){return q.debug(`Lookup called for ${i}`),X(i,!0,h)}async function W(i,h=!1,w=1,n=!1,g=null){let c=[];if(h){if(w>i.length)w=i.length;for(let s=0;s<i.length;s+=w){let o=i.slice(s,s+w),m=await Promise.all(o.map(async(x)=>{return await X(x,n,g)}));c.push(...m)}}else for(let s=0;s<i.length;s++){let o=await X(i[s],n,g);c.push(o)}return c}export{X as whois,R as tcpWhois,T as lookup,N as getWhoIsServer,$ as getTLD,y as getParameters,A as findWhoIsServer,W as batchWhois,J as WhoIsParser,G as SocksClient,K as SERVERS,_ as ProxyType,Z as PARAMETERS,Y as IANA_CHK_URL};