Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: respect rejectUnauthorized and ca opts when proxying https #725

Merged
merged 2 commits into from
Oct 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/bruno-cli/src/runner/run-single-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ const { ScriptRuntime, TestRuntime, VarsRuntime, AssertRuntime } = require('@use
const { stripExtension } = require('../utils/filesystem');
const { getOptions } = require('../utils/bru');
const https = require('https');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { HttpProxyAgent } = require('http-proxy-agent');
const { SocksProxyAgent } = require('socks-proxy-agent');
const { makeAxiosInstance } = require('../utils/axios-instance');
const { shouldUseProxy } = require('../utils/proxy-util');
const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../utils/proxy-util');

const runSingleRequest = async function (
filename,
Expand Down Expand Up @@ -152,7 +151,7 @@ const runSingleRequest = async function (
request.httpsAgent = socksProxyAgent;
request.httpAgent = socksProxyAgent;
} else {
request.httpsAgent = new HttpsProxyAgent(
request.httpsAgent = new PatchedHttpsProxyAgent(
proxyUri,
Object.keys(httpsAgentRequestFields).length > 0 ? { ...httpsAgentRequestFields } : undefined
);
Expand Down
25 changes: 22 additions & 3 deletions packages/bruno-cli/src/utils/proxy-util.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const parseUrl = require('url').parse;
const { isEmpty } = require('lodash');
const { HttpsProxyAgent } = require('https-proxy-agent');

const DEFAULT_PORTS = {
ftp: 21,
Expand All @@ -9,7 +11,7 @@ const DEFAULT_PORTS = {
wss: 443
};
/**
* check for proxy bypass, Copied form 'proxy-from-env'
* check for proxy bypass, copied form 'proxy-from-env'
*/
const shouldUseProxy = (url, proxyBypass) => {
if (proxyBypass === '*') {
Expand Down Expand Up @@ -39,7 +41,6 @@ const shouldUseProxy = (url, proxyBypass) => {
if (!dontProxyFor) {
return true; // Skip zero-length hosts.
}

const parsedProxy = dontProxyFor.match(/^(.+):(\d+)$/);
let parsedProxyHostname = parsedProxy ? parsedProxy[1] : dontProxyFor;
const parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
Expand All @@ -61,6 +62,24 @@ const shouldUseProxy = (url, proxyBypass) => {
});
};

/**
* Patched version of HttpsProxyAgent to get around a bug that ignores
* options like ca and rejectUnauthorized when upgrading the socket to TLS:
* https://github.com/TooTallNate/proxy-agents/issues/194
*/
class PatchedHttpsProxyAgent extends HttpsProxyAgent {
constructor(proxy, opts) {
super(proxy, opts);
this.constructorOpts = opts;
}

async connect(req, opts) {
const combinedOpts = { ...this.constructorOpts, ...opts };
return super.connect(req, combinedOpts);
}
}

module.exports = {
shouldUseProxy
shouldUseProxy,
PatchedHttpsProxyAgent
};
5 changes: 2 additions & 3 deletions packages/bruno-electron/src/ipc/network/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ const { sortFolder, getAllRequestsInFolderRecursively } = require('./helper');
const { preferencesUtil } = require('../../store/preferences');
const { getProcessEnvVars } = require('../../store/process-env');
const { getBrunoConfig } = require('../../store/bruno-config');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { HttpProxyAgent } = require('http-proxy-agent');
const { SocksProxyAgent } = require('socks-proxy-agent');
const { makeAxiosInstance } = require('./axios-instance');
const { addAwsV4Interceptor, resolveAwsV4Credentials } = require('./awsv4auth-helper');
const { shouldUseProxy } = require('../../utils/proxy-util');
const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../../utils/proxy-util');

// override the default escape function to prevent escaping
Mustache.escape = function (value) {
Expand Down Expand Up @@ -149,7 +148,7 @@ const configureRequest = async (collectionUid, request, envVars, collectionVaria
request.httpsAgent = socksProxyAgent;
request.httpAgent = socksProxyAgent;
} else {
request.httpsAgent = new HttpsProxyAgent(
request.httpsAgent = new PatchedHttpsProxyAgent(
proxyUri,
Object.keys(httpsAgentRequestFields).length > 0 ? { ...httpsAgentRequestFields } : undefined
);
Expand Down
21 changes: 20 additions & 1 deletion packages/bruno-electron/src/utils/proxy-util.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const parseUrl = require('url').parse;
const { isEmpty } = require('lodash');
const { HttpsProxyAgent } = require('https-proxy-agent');

const DEFAULT_PORTS = {
ftp: 21,
Expand Down Expand Up @@ -61,6 +62,24 @@ const shouldUseProxy = (url, proxyBypass) => {
});
};

/**
* Patched version of HttpsProxyAgent to get around a bug that ignores options
* such as ca and rejectUnauthorized when upgrading the proxied socket to TLS:
* https://github.com/TooTallNate/proxy-agents/issues/194
*/
class PatchedHttpsProxyAgent extends HttpsProxyAgent {
constructor(proxy, opts) {
super(proxy, opts);
this.constructorOpts = opts;
}

async connect(req, opts) {
const combinedOpts = { ...this.constructorOpts, ...opts };
return super.connect(req, combinedOpts);
}
}

module.exports = {
shouldUseProxy
shouldUseProxy,
PatchedHttpsProxyAgent
};