diff --git a/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js b/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js index 9ff12312cf1..5cdddf0435e 100644 --- a/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/ProxySettings/index.js @@ -300,6 +300,18 @@ const ProxySettings = ({ collection }) => { /> SOCKS5 +
diff --git a/packages/bruno-app/src/components/Preferences/ProxySettings/index.js b/packages/bruno-app/src/components/Preferences/ProxySettings/index.js index e7931f2d709..b23898685e2 100644 --- a/packages/bruno-app/src/components/Preferences/ProxySettings/index.js +++ b/packages/bruno-app/src/components/Preferences/ProxySettings/index.js @@ -34,7 +34,7 @@ const ProxySettings = ({ close }) => { .nullable() }).optional(), config: Yup.object({ - protocol: Yup.string().required().oneOf(['http', 'https', 'socks4', 'socks5']), + protocol: Yup.string().required().oneOf(['http', 'https', 'socks4', 'socks5', 'socks5h']), hostname: Yup.string().max(1024), port: Yup.number() .min(1) @@ -257,6 +257,17 @@ const ProxySettings = ({ close }) => { /> SOCKS5 +
diff --git a/packages/bruno-electron/src/store/preferences.js b/packages/bruno-electron/src/store/preferences.js index de0bb3a5f6b..1faae83c26e 100644 --- a/packages/bruno-electron/src/store/preferences.js +++ b/packages/bruno-electron/src/store/preferences.js @@ -117,7 +117,7 @@ const preferencesSchema = Yup.object().shape({ source: Yup.string().optional().max(2048).nullable() }).optional(), config: Yup.object({ - protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5']), + protocol: Yup.string().oneOf(['http', 'https', 'socks4', 'socks5', 'socks5h']), hostname: Yup.string().max(1024), port: Yup.number().min(1).max(65535).nullable(), auth: Yup.object({ diff --git a/packages/bruno-electron/test/proxy-util.test.js b/packages/bruno-electron/test/proxy-util.test.js index 55b869cdeb0..4fe674dd7d4 100644 --- a/packages/bruno-electron/test/proxy-util.test.js +++ b/packages/bruno-electron/test/proxy-util.test.js @@ -147,6 +147,37 @@ describe('proxy-util', () => { ); }); + test('setupProxyAgents: manual socks5h proxy routes through socks agent and preserves the socks5h scheme', async () => { + setupMocks(); + const { setupProxyAgents } = require('../src/utils/proxy-util'); + const { SocksProxyAgent } = require('socks-proxy-agent'); + const { getOrCreateHttpsAgent } = require('@usebruno/requests'); + + // https request → only the https agent should be set + const requestConfig = { url: 'https://example.com/resource' }; + const timeline = []; + + await setupProxyAgents({ + requestConfig, + proxyMode: 'on', + proxyConfig: { + protocol: 'socks5h', + hostname: 'socks.example', + port: 1080, + auth: { disabled: true } + }, + httpsAgentRequestFields: {}, + interpolationOptions: {}, + timeline + }); + + // The socks5h scheme must reach socks-proxy-agent verbatim — that scheme is what + // tells the agent to resolve the target hostname on the proxy side (remote DNS). + expect(getOrCreateHttpsAgent).toHaveBeenCalledWith( + expect.objectContaining({ AgentClass: SocksProxyAgent, proxyUri: 'socks5h://socks.example:1080' }) + ); + }); + test('setupProxyAgents: PAC resolution error logs to timeline and falls back to direct agent', async () => { jest.doMock('../src/store/preferences', () => ({ preferencesUtil: { isSslSessionCachingEnabled: () => false }