mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-24 21:25:45 +00:00
fix: improve URL parsing in getParsedWsUrlObject (#5822)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import ws from 'ws';
|
||||
import { hexy as hexdump } from 'hexy';
|
||||
import { getParsedWsUrlObject } from './ws-url';
|
||||
|
||||
/**
|
||||
* Safely parse JSON string with error handling
|
||||
@@ -21,45 +22,6 @@ const safeParseJSON = (jsonString, context = 'JSON string') => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get parsed WebSocket URL object
|
||||
* @param {string} url - The WebSocket URL
|
||||
* @returns {Object} Parsed URL object with protocol, host, path
|
||||
*/
|
||||
const getParsedWsUrlObject = (url) => {
|
||||
const addProtocolIfMissing = (str) => {
|
||||
if (str.includes('://')) return str;
|
||||
|
||||
// For localhost, default to insecure (grpc://) for local development
|
||||
if (str.includes('localhost') || str.includes('127.0.0.1')) {
|
||||
return `ws://${str}`;
|
||||
}
|
||||
|
||||
// For other hosts, default to secure
|
||||
return `wss://${str}`;
|
||||
};
|
||||
|
||||
const removeTrailingSlash = (str) => (str.endsWith('/') ? str.slice(0, -1) : str);
|
||||
|
||||
if (!url) return { host: '', path: '' };
|
||||
|
||||
try {
|
||||
const urlObj = new URL(addProtocolIfMissing(url.toLowerCase()));
|
||||
return {
|
||||
protocol: urlObj.protocol,
|
||||
host: urlObj.host,
|
||||
path: removeTrailingSlash(urlObj.pathname),
|
||||
search: urlObj.search,
|
||||
fullUrl: urlObj.href
|
||||
};
|
||||
} catch (err) {
|
||||
console.error({ err });
|
||||
return {
|
||||
host: '',
|
||||
path: ''
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
class WsClient {
|
||||
messageQueues = {};
|
||||
|
||||
39
packages/bruno-requests/src/ws/ws-url.js
Normal file
39
packages/bruno-requests/src/ws/ws-url.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Get parsed WebSocket URL object
|
||||
* @param {string} url - The WebSocket URL
|
||||
* @returns {Object} Parsed URL object with protocol, host, path
|
||||
*/
|
||||
export const getParsedWsUrlObject = (url) => {
|
||||
const addProtocolIfMissing = (str) => {
|
||||
if (str.includes('://')) return str;
|
||||
|
||||
// For localhost, default to insecure (grpc://) for local development
|
||||
if (str.includes('localhost') || str.includes('127.0.0.1')) {
|
||||
return `ws://${str}`;
|
||||
}
|
||||
|
||||
// For other hosts, default to secure
|
||||
return `wss://${str}`;
|
||||
};
|
||||
|
||||
const removeTrailingSlash = (str) => (str.endsWith('/') ? str.slice(0, -1) : str);
|
||||
|
||||
if (!url) return { host: '', path: '' };
|
||||
|
||||
try {
|
||||
const urlObj = new URL(addProtocolIfMissing(url));
|
||||
return {
|
||||
protocol: urlObj.protocol,
|
||||
host: urlObj.host,
|
||||
path: removeTrailingSlash(urlObj.pathname),
|
||||
search: urlObj.search,
|
||||
fullUrl: urlObj.href
|
||||
};
|
||||
} catch (err) {
|
||||
console.error({ err });
|
||||
return {
|
||||
host: '',
|
||||
path: ''
|
||||
};
|
||||
}
|
||||
};
|
||||
36
packages/bruno-requests/src/ws/ws-url.spec.ts
Normal file
36
packages/bruno-requests/src/ws/ws-url.spec.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { getParsedWsUrlObject } from './ws-url';
|
||||
|
||||
describe('getParsedWsUrlObject', () => {
|
||||
it('returns empty host and path for empty input', () => {
|
||||
expect(getParsedWsUrlObject('')).toEqual({ host: '', path: '' });
|
||||
});
|
||||
|
||||
it('defaults to ws:// for localhost without protocol', () => {
|
||||
const parsed: any = getParsedWsUrlObject('localhost:8080/some/path');
|
||||
expect(parsed.protocol).toBe('ws:');
|
||||
expect(parsed.host).toBe('localhost:8080');
|
||||
expect(parsed.path).toBe('/some/path');
|
||||
expect(parsed.fullUrl.startsWith('ws://')).toBe(true);
|
||||
});
|
||||
|
||||
it('defaults to wss:// for external hosts without protocol', () => {
|
||||
const parsed: any = getParsedWsUrlObject('example.com/s');
|
||||
expect(parsed.protocol).toBe('wss:');
|
||||
expect(parsed.host).toBe('example.com');
|
||||
expect(parsed.path).toBe('/s');
|
||||
expect(parsed.fullUrl.startsWith('wss://')).toBe(true);
|
||||
});
|
||||
|
||||
it('preserves provided protocol and parses query/search', () => {
|
||||
const parsed: any = getParsedWsUrlObject('wss://example.com/path/With/cAses/?a=1&b=2');
|
||||
expect(parsed.protocol).toBe('wss:');
|
||||
expect(parsed.host).toBe('example.com');
|
||||
expect(parsed.path).toBe('/path/With/cAses');
|
||||
expect(parsed.search).toBe('?a=1&b=2');
|
||||
});
|
||||
|
||||
it('removes trailing slash from path', () => {
|
||||
const parsed: any = getParsedWsUrlObject('ws://127.0.0.1:9000/endpoint/');
|
||||
expect(parsed.path).toBe('/endpoint');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user