Skip to content

Commit 7fd11a9

Browse files
authored
refactor(server): replace deprecated url.parse with URL API (#115)
1 parent 61e7a62 commit 7fd11a9

1 file changed

Lines changed: 28 additions & 21 deletions

File tree

src/server.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,29 @@ const encodeOverlaySettings = (
151151

152152
const DEFAULT_ALLOWED_PROTOCOLS = /^(file|.+-extension):/i;
153153

154+
/**
155+
* Extracts and normalizes the hostname from a header, removing brackets for IPv6.
156+
*/
157+
function parseHostnameFromHeader(header: string): string | null {
158+
try {
159+
const parsedUrl = new URL(
160+
// if header doesn't have scheme, add // for parsing.
161+
/^(.+:)?\/\//.test(header) ? header : `//${header}`,
162+
'http://localhost/',
163+
);
164+
let { hostname } = parsedUrl;
165+
166+
// `URL#hostname` keeps IPv6 brackets, but our validation expects bare IPv6.
167+
if (hostname.startsWith('[') && hostname.endsWith(']')) {
168+
hostname = hostname.slice(1, -1);
169+
}
170+
171+
return hostname;
172+
} catch {
173+
return null;
174+
}
175+
}
176+
154177
function isMultiCompiler(
155178
compiler: Compiler | MultiCompiler,
156179
): compiler is MultiCompiler {
@@ -2484,15 +2507,7 @@ class Server<
24842507
return true;
24852508
}
24862509

2487-
// use the node url-parser to retrieve the hostname from the host-header.
2488-
// TODO resolve me in the next major release
2489-
// eslint-disable-next-line n/no-deprecated-api
2490-
const { hostname } = url.parse(
2491-
// if header doesn't have scheme, add // for parsing.
2492-
/^(.+:)?\/\//.test(header) ? header : `//${header}`,
2493-
false,
2494-
true,
2495-
);
2510+
const hostname = parseHostnameFromHeader(header);
24962511

24972512
if (hostname === null) {
24982513
return false;
@@ -2506,8 +2521,8 @@ class Server<
25062521
// A note on IPv6 addresses:
25072522
// header will always contain the brackets denoting
25082523
// an IPv6-address in URLs,
2509-
// these are removed from the hostname in url.parse(),
2510-
// so we have the pure IPv6-address in hostname.
2524+
// these are not removed from `URL#hostname`,
2525+
// so we normalize to a pure IPv6-address when parsing.
25112526
// For convenience, always allow localhost (hostname === 'localhost')
25122527
// and its subdomains (hostname.endsWith(".localhost")).
25132528
// allow hostname of listening address (hostname === this.options.host)
@@ -2537,9 +2552,7 @@ class Server<
25372552
return true;
25382553
}
25392554

2540-
// TODO resolve me in the next major release
2541-
// eslint-disable-next-line n/no-deprecated-api
2542-
const origin = url.parse(originHeader, false, true).hostname;
2555+
const origin = parseHostnameFromHeader(originHeader);
25432556

25442557
if (origin === null) {
25452558
return false;
@@ -2559,13 +2572,7 @@ class Server<
25592572
return true;
25602573
}
25612574

2562-
// eslint-disable-next-line n/no-deprecated-api
2563-
const host = url.parse(
2564-
// if hostHeader doesn't have scheme, add // for parsing.
2565-
/^(.+:)?\/\//.test(hostHeader) ? hostHeader : `//${hostHeader}`,
2566-
false,
2567-
true,
2568-
).hostname;
2575+
const host = parseHostnameFromHeader(hostHeader);
25692576

25702577
if (host === null) {
25712578
return false;

0 commit comments

Comments
 (0)