From 96d50ebd9334debcc47edf02ca3e8ca0fe913f20 Mon Sep 17 00:00:00 2001 From: Brandon Gillis Date: Fri, 1 Dec 2023 23:24:16 +0100 Subject: [PATCH 1/2] fix(#124): resolve all *.localhost to localhost --- .../bruno-electron/src/ipc/network/index.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index b119558237..8e0fbe21cf 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -1,6 +1,7 @@ const os = require('os'); const fs = require('fs'); const qs = require('qs'); +const parseUrl = require('url').parse; const https = require('https'); const axios = require('axios'); const path = require('path'); @@ -74,6 +75,14 @@ const getEnvVars = (environment = {}) => { const protocolRegex = /([a-zA-Z]{2,20}:\/\/)(.*)/; +const getTld = (hostname) => { + if (!hostname) { + return ''; + } + + return hostname.substring(hostname.lastIndexOf('.') + 1); +}; + const configureRequest = async ( collectionUid, request, @@ -174,6 +183,15 @@ const configureRequest = async ( }); } + // resolve all *.localhost to localhost + // RFC: 6761 section 6.3 (https://tools.ietf.org/html/rfc6761#section-6.3) + // @see https://github.com/usebruno/bruno/issues/124 + let parsedUrl = parseUrl(request.url); + if (getTld(parsedUrl.hostname) === 'localhost') { + request.headers['Host'] = parsedUrl.hostname; + request.url = request.url.replace(parsedUrl.hostname, 'localhost'); + } + const axiosInstance = makeAxiosInstance(); if (request.awsv4config) { From 06d62175bfa288ff01216f8fc9cbe1883dc2313a Mon Sep 17 00:00:00 2001 From: Brandon Gillis Date: Sat, 2 Dec 2023 02:50:44 +0100 Subject: [PATCH 2/2] Add support for ipv6 localhost & refactor *.localhost handling --- .../src/ipc/network/axios-instance.js | 44 ++++++++++++++++++- .../bruno-electron/src/ipc/network/index.js | 18 -------- 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/packages/bruno-electron/src/ipc/network/axios-instance.js b/packages/bruno-electron/src/ipc/network/axios-instance.js index 2251564840..2627859902 100644 --- a/packages/bruno-electron/src/ipc/network/axios-instance.js +++ b/packages/bruno-electron/src/ipc/network/axios-instance.js @@ -1,5 +1,32 @@ +const URL = require('url'); +const Socket = require('net').Socket; const axios = require('axios'); +const getTld = (hostname) => { + if (!hostname) { + return ''; + } + + return hostname.substring(hostname.lastIndexOf('.') + 1); +}; + +const checkConnection = (host, port) => + new Promise((resolve) => { + const socket = new Socket(); + + socket.once('connect', () => { + socket.end(); + resolve(true); + }); + + socket.once('error', () => { + resolve(false); + }); + + // Try to connect to the host and port + socket.connect(port, host); + }); + /** * Function that configures axios with timing interceptors * Important to note here that the timings are not completely accurate. @@ -10,7 +37,22 @@ function makeAxiosInstance() { /** @type {axios.AxiosInstance} */ const instance = axios.create(); - instance.interceptors.request.use((config) => { + instance.interceptors.request.use(async (config) => { + const url = URL.parse(config.url); + + // Resolve all *.localhost to localhost and check if it should use IPv6 or IPv4 + // RFC: 6761 section 6.3 (https://tools.ietf.org/html/rfc6761#section-6.3) + // @see https://github.com/usebruno/bruno/issues/124 + if (getTld(url.hostname) === 'localhost') { + config.headers.Host = url.hostname; // Put original hostname in Host + + const portNumber = Number(url.port) || (url.protocol.includes('https') ? 443 : 80); + const useIpv6 = await checkConnection('::1', portNumber); + url.hostname = useIpv6 ? '::1' : '127.0.0.1'; + delete url.host; // Clear hostname cache + config.url = URL.format(url); + } + config.headers['request-start-time'] = Date.now(); return config; }); diff --git a/packages/bruno-electron/src/ipc/network/index.js b/packages/bruno-electron/src/ipc/network/index.js index 8e0fbe21cf..b119558237 100644 --- a/packages/bruno-electron/src/ipc/network/index.js +++ b/packages/bruno-electron/src/ipc/network/index.js @@ -1,7 +1,6 @@ const os = require('os'); const fs = require('fs'); const qs = require('qs'); -const parseUrl = require('url').parse; const https = require('https'); const axios = require('axios'); const path = require('path'); @@ -75,14 +74,6 @@ const getEnvVars = (environment = {}) => { const protocolRegex = /([a-zA-Z]{2,20}:\/\/)(.*)/; -const getTld = (hostname) => { - if (!hostname) { - return ''; - } - - return hostname.substring(hostname.lastIndexOf('.') + 1); -}; - const configureRequest = async ( collectionUid, request, @@ -183,15 +174,6 @@ const configureRequest = async ( }); } - // resolve all *.localhost to localhost - // RFC: 6761 section 6.3 (https://tools.ietf.org/html/rfc6761#section-6.3) - // @see https://github.com/usebruno/bruno/issues/124 - let parsedUrl = parseUrl(request.url); - if (getTld(parsedUrl.hostname) === 'localhost') { - request.headers['Host'] = parsedUrl.hostname; - request.url = request.url.replace(parsedUrl.hostname, 'localhost'); - } - const axiosInstance = makeAxiosInstance(); if (request.awsv4config) {