Path: blob/main/plugins/default-browser-emulator/lib/helpers/lookupPublicIp.ts
1030 views
import * as http from 'http';1import { RequestOptions } from 'http';2import IHttpSocketAgent from '@secret-agent/interfaces/IHttpSocketAgent';3import * as https from 'https';4import * as url from 'url';5import IHttpSocketWrapper from '@secret-agent/interfaces/IHttpSocketWrapper';67export default async function lookupPublicIp(8ipLookupServiceUrl: string = IpLookupServices.ipify,9agent?: IHttpSocketAgent,10proxyUrl?: string,11): Promise<string> {12if (!ipLookupServiceUrl.startsWith('http')) ipLookupServiceUrl = `https://${ipLookupServiceUrl}`;13if (proxyUrl && proxyUrl.startsWith('http')) {14// require https for lookup services over http proxies15ipLookupServiceUrl.replace('http://', 'https://');16}17const lookupService = parse(ipLookupServiceUrl);18const port = lookupService.port ?? lookupService.protocol === 'https:' ? 443 : 80;1920const requestOptions: http.RequestOptions = {21method: 'GET',22};2324let socketWrapper: IHttpSocketWrapper;25if (agent) {26socketWrapper = await agent.createSocketConnection({27host: lookupService.host,28port: String(port),29servername: lookupService.host,30keepAlive: false,31isSsl: ipLookupServiceUrl.startsWith('https'),32proxyUrl,33});3435requestOptions.createConnection = () => socketWrapper.socket;36requestOptions.agent = null;37}3839try {40return await httpGet(ipLookupServiceUrl, requestOptions);41} finally {42if (socketWrapper) socketWrapper.close();43}44}4546export function httpGet(requestUrl: string, requestOptions: RequestOptions): Promise<string> {47const httpModule = requestUrl.startsWith('https') ? https : http;4849return new Promise<string>((resolve, reject) => {50const request = httpModule.request(requestUrl, requestOptions, async res => {51if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {52resolve(httpGet(res.headers.location, requestOptions));53return;54}5556res.on('error', reject);57res.setEncoding('utf8');58let result = '';59for await (const chunk of res) {60result += chunk;61}62resolve(result);63});64request.on('error', reject);65request.end();66});67}6869const parsedLookupServicesByUrl = new Map<string, RequestOptions>();70function parse(requestUrl: string): RequestOptions {71if (!parsedLookupServicesByUrl.has(requestUrl)) {72const options = url.parse(requestUrl);73options.port ||= requestUrl.startsWith('https') ? '443' : '80';7475parsedLookupServicesByUrl.set(requestUrl, options);76}77return parsedLookupServicesByUrl.get(requestUrl);78}7980export const IpLookupServices = {81ipify: 'api.ipify.org',82icanhazip: 'icanhazip.com', // warn: using cloudflare as of 11/19/2183aws: 'checkip.amazonaws.com',84identMe: 'ident.me',85ifconfigMe: 'ifconfig.me/ip',86ipecho: 'ipecho.net/plain',87ipinfo: 'ipinfo.io/ip',88opendns: 'diagnostic.opendns.com/myip',89};909192