Skip to content

Commit 211e828

Browse files
authored
complete node:url implementation (#2967)
1 parent 966eee4 commit 211e828

10 files changed

+3432
-4
lines changed

src/node/internal/internal_querystring.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { ERR_INVALID_URI } from 'node-internal:internal_errors';
99
type EncodeFunction = (value: string) => string;
1010
type DecodeFunction = (value: string) => string;
1111

12-
const hexTable = new Array(256) as string[];
12+
export const hexTable = new Array(256) as string[];
1313
for (let i = 0; i < 256; ++i) {
1414
hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
1515
}
@@ -35,7 +35,7 @@ const isHexTable = new Int8Array([
3535
]);
3636

3737
/* eslint-disable */
38-
function encodeStr(
38+
export function encodeStr(
3939
str: string,
4040
noEscapeTable: Int8Array,
4141
hexTable: string[]
@@ -339,8 +339,8 @@ function addKeyVal(
339339

340340
export function parse(
341341
qs: string,
342-
sep: string,
343-
eq: string,
342+
sep?: string,
343+
eq?: string,
344344
options?: {
345345
maxKeys?: number;
346346
decodeURIComponent?: DecodeFunction;

src/node/internal/internal_url.ts

+51
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,54 @@ export function toPathIfFileURL(fileURLOrPath: URL | string): string {
258258
if (!isURL(fileURLOrPath)) return fileURLOrPath;
259259
return fileURLToPath(fileURLOrPath);
260260
}
261+
262+
/**
263+
* Utility function that converts a URL object into an ordinary options object
264+
* as expected by the `http.request` and `https.request` APIs.
265+
* @param {URL} url
266+
* @returns {Record<string, unknown>}
267+
*/
268+
export function urlToHttpOptions(url: URL): Record<string, unknown> {
269+
const { hostname, pathname, port, username, password, search } = url;
270+
const options: Record<string, unknown> = {
271+
__proto__: null,
272+
...url, // In case the url object was extended by the user.
273+
protocol: url.protocol,
274+
hostname:
275+
hostname && hostname[0] === '[' ? hostname.slice(1, -1) : hostname,
276+
hash: url.hash,
277+
search: search,
278+
pathname: pathname,
279+
path: `${pathname || ''}${search || ''}`,
280+
href: url.href,
281+
};
282+
if (port !== '') {
283+
options.port = Number(port);
284+
}
285+
if (username || password) {
286+
options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(password)}`;
287+
}
288+
return options;
289+
}
290+
291+
// Protocols that can allow "unsafe" and "unwise" chars.
292+
export const unsafeProtocol = new Set<string>(['javascript', 'javascript:']);
293+
// Protocols that never have a hostname.
294+
export const hostlessProtocol = new Set<string>(['javascript', 'javascript:']);
295+
// Protocols that always contain a // bit.
296+
export const slashedProtocol = new Set<string>([
297+
'http',
298+
'http:',
299+
'https',
300+
'https:',
301+
'ftp',
302+
'ftp:',
303+
'gopher',
304+
'gopher:',
305+
'file',
306+
'file:',
307+
'ws',
308+
'ws:',
309+
'wss',
310+
'wss:',
311+
]);

0 commit comments

Comments
 (0)