Skip to content

Commit

Permalink
Moved redirect interceptor to makeAxiosInstance
Browse files Browse the repository at this point in the history
  • Loading branch information
naman-bruno committed Jan 22, 2025
1 parent 51ab121 commit 7f2b06b
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 67 deletions.
90 changes: 89 additions & 1 deletion packages/bruno-electron/src/ipc/network/axios-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ const Socket = require('net').Socket;
const axios = require('axios');
const connectionCache = new Map(); // Cache to store checkConnection() results
const electronApp = require("electron");
const { get } = require('lodash');
const { preferencesUtil } = require('../../store/preferences');
const { getCookieStringForUrl, addCookieToJar } = require('../../utils/cookies');

const LOCAL_IPV6 = '::1';
const LOCAL_IPV4 = '127.0.0.1';
Expand Down Expand Up @@ -43,13 +46,29 @@ const checkConnection = (host, port) =>
}
});

const saveCookies = (url, headers) => {
if (preferencesUtil.shouldStoreCookies()) {
let setCookieHeaders = [];
if (headers['set-cookie']) {
setCookieHeaders = Array.isArray(headers['set-cookie'])
? headers['set-cookie']
: [headers['set-cookie']];
for (let setCookieHeader of setCookieHeaders) {
if (typeof setCookieHeader === 'string' && setCookieHeader.length) {
addCookieToJar(setCookieHeader, url);
}
}
}
}
}

/**
* Function that configures axios with timing interceptors
* Important to note here that the timings are not completely accurate.
* @see https://github.com/axios/axios/issues/695
* @returns {axios.AxiosInstance}
*/
function makeAxiosInstance() {
function makeAxiosInstance({ brunoConfig, MAX_REDIRECTS, httpsAgentRequestFields, interpolationOptions, setupProxyAgents }) {
/** @type {axios.AxiosInstance} */
const instance = axios.create({
transformRequest: function transformRequest(data, headers) {
Expand Down Expand Up @@ -94,18 +113,87 @@ function makeAxiosInstance() {
return config;
});

let redirectCount = 0

instance.interceptors.response.use(
(response) => {
const end = Date.now();
const start = response.config.headers['request-start-time'];
response.headers['request-duration'] = end - start;
redirectCount = 0;
return response;
},
(error) => {
if (error.response) {
const end = Date.now();
const start = error.config.headers['request-start-time'];
error.response.headers['request-duration'] = end - start;

if (error.response && [301, 302, 303, 307, 308].includes(error.response.status)) {
if (redirectCount >= MAX_REDIRECTS) {
const dataBuffer = Buffer.from(error.response.data);

return {
status: error.response.status,
statusText: error.response.statusText,
headers: error.response.headers,
data: error.response.data,
dataBuffer: dataBuffer.toString('base64'),
size: Buffer.byteLength(dataBuffer),
duration: error.response.headers.get('request-duration') ?? 0
};
}

let proxyMode = 'off';
let proxyConfig = {};

const collectionProxyConfig = get(brunoConfig, 'proxy', {});
const collectionProxyEnabled = get(collectionProxyConfig, 'enabled', 'global');
if (collectionProxyEnabled === true) {
proxyConfig = collectionProxyConfig;
proxyMode = 'on';
} else if (collectionProxyEnabled === 'global') {
proxyConfig = preferencesUtil.getGlobalProxyConfig();
proxyMode = get(proxyConfig, 'mode', 'off');
}

// Increase redirect count
redirectCount++;

const redirectUrl = error.response.headers.location;

if (preferencesUtil.shouldStoreCookies()) {
saveCookies(redirectUrl, error.response.headers);
}

// Create a new request config for the redirect
const requestConfig = {
...error.config,
url: redirectUrl,
headers: {
...error.config.headers,
},
};

if (preferencesUtil.shouldSendCookies()) {
const cookieString = getCookieStringForUrl(error.response.headers.location);
if (cookieString && typeof cookieString === 'string' && cookieString.length) {
requestConfig.headers['cookie'] = cookieString;
}
}


setupProxyAgents({
requestConfig,
proxyMode,
proxyConfig,
httpsAgentRequestFields,
interpolationOptions
});

// Make the redirected request
return instance(requestConfig);
}
}
return Promise.reject(error);
}
Expand Down
94 changes: 28 additions & 66 deletions packages/bruno-electron/src/ipc/network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,15 @@ const saveCookies = (url, headers) => {
}
}

function setupProxyAgents(requestConfig, url, proxyMode, proxyConfig, httpsAgentRequestFields, interpolationOptions) {
function setupProxyAgents({
requestConfig,
proxyMode,
proxyConfig,
httpsAgentRequestFields,
interpolationOptions
}) {
if (proxyMode === 'on') {
const shouldProxy = shouldUseProxy(url, get(proxyConfig, 'bypassProxy', ''));
const shouldProxy = shouldUseProxy(requestConfig.url, get(proxyConfig, 'bypassProxy', ''));
if (shouldProxy) {
const proxyProtocol = interpolateString(get(proxyConfig, 'protocol'), interpolationOptions);
const proxyHostname = interpolateString(get(proxyConfig, 'hostname'), interpolationOptions);
Expand Down Expand Up @@ -269,14 +275,25 @@ const configureRequest = async (
proxyMode = get(proxyConfig, 'mode', 'off');
}

setupProxyAgents(request, request.url, proxyMode, proxyConfig, httpsAgentRequestFields, interpolationOptions);
setupProxyAgents({
requestConfig: request,
proxyMode,
proxyConfig,
httpsAgentRequestFields,
interpolationOptions
});

let redirectCount = 0
let MAX_REDIRECTS
let axiosInstance = makeAxiosInstance();
MAX_REDIRECTS = request.maxRedirects
let MAX_REDIRECTS = request.maxRedirects
request.maxRedirects = 0


let axiosInstance = makeAxiosInstance({
brunoConfig,
MAX_REDIRECTS,
httpsAgentRequestFields,
interpolationOptions,
setupProxyAgents
});

if (request.ntlmConfig) {
axiosInstance=NtlmClient(request.ntlmConfig,axiosInstance.defaults)
delete request.ntlmConfig;
Expand Down Expand Up @@ -317,61 +334,6 @@ const configureRequest = async (
}
}

axiosInstance.interceptors.response.use(
response => {
redirectCount = 0;
return response;
},
async error => {
if (error.response && [301, 302, 303, 307, 308].includes(error.response.status)) {
if (redirectCount >= MAX_REDIRECTS) {
const dataBuffer = Buffer.from(error.response.data);

return {
status: error.response.status,
statusText: error.response.statusText,
headers: error.response.headers,
data: error.response.data,
dataBuffer: dataBuffer.toString('base64'),
size: Buffer.byteLength(dataBuffer),
duration: error.response.headers.get('request-duration') ?? 0
};
}

// Increase redirect count
redirectCount++;

const redirectUrl = error.response.headers.location;

if (preferencesUtil.shouldStoreCookies()) {
saveCookies(redirectUrl, error.response.headers);
}

// Create a new request config for the redirect
const requestConfig = {
...error.config,
url: redirectUrl,
headers: {
...error.config.headers,
},
};

if (preferencesUtil.shouldSendCookies()) {
const cookieString = getCookieStringForUrl(request.url);
if (cookieString && typeof cookieString === 'string' && cookieString.length) {
requestConfig.headers['cookie'] = cookieString;
}
}

setupProxyAgents(requestConfig, redirectUrl, proxyMode, proxyConfig, httpsAgentRequestFields, interpolationOptions);

// Make the redirected request
return axiosInstance(requestConfig);
}
return Promise.reject(error);
},
);



if (request.awsv4config) {
Expand Down Expand Up @@ -438,9 +400,9 @@ const parseDataFromResponse = (response, disableParsingResponseJson = false) =>
if ( !disableParsingResponseJson && ! (typeof data === 'string' && data.startsWith("\"") && data.endsWith("\""))) {
data = JSON.parse(data);
}
} catch {
} catch {
console.log('Failed to parse response data as JSON');
}
}

return { data, dataBuffer };
};
Expand Down Expand Up @@ -1090,7 +1052,7 @@ const registerNetworkIpc = (mainWindow) => {

const request = prepareRequest(item, collection);
request.__bruno__executionMode = 'runner';

const requestUid = uuid();
const processEnvVars = getProcessEnvVars(collectionUid);

Expand Down

0 comments on commit 7f2b06b

Please sign in to comment.