Add support for ipv6 localhost & refactor *.localhost handling

This commit is contained in:
Brandon Gillis 2023-12-02 02:50:44 +01:00
parent 96d50ebd93
commit 06d62175bf
2 changed files with 43 additions and 19 deletions

View File

@ -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;
});

View File

@ -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) {