Skip to content

Commit

Permalink
perf: prevent calling new URL() on absolute paths
Browse files Browse the repository at this point in the history
  • Loading branch information
stas-nc committed Feb 4, 2025
1 parent 3ae708b commit b8ed63a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
8 changes: 4 additions & 4 deletions src/app/utils/localizeUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ export function localizeUrl(config: IntlAdapterConfig, url: string, configOverri
return url;
}

const { uri, origin } = parseAsFullyQualifiedURI(url);
const { path, origin } = parseAsFullyQualifiedURI(url);

if (!uri.startsWith('/')) {
if (!path.startsWith('/')) {
throw new Error(`Localization of relative URLs is not supported. Received: "${url}"`);
}

const { cleanUrl } = parseUrl(config, uri);
const { cleanUrl } = parseUrl(config, path);

const receivedLocale = configOverride.locale || config.default.locale;
const receivedLocale = configOverride.locale ?? config.default.locale;

const locale = getCanonicalLocale(receivedLocale, config.supported.locale);

Expand Down
24 changes: 16 additions & 8 deletions src/app/utils/parseAsFullyQualifiedURI.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
type ParsedUri = {
origin: string;
uri: string;
path: string;
};

export function parseAsFullyQualifiedURI(uri: string): ParsedUri {
let origin = '';
try {
// Normalize multiple slashes to a single slash, but don't affect the initial "http://" or "https://"
uri = uri.replace(/([^:])\/{2,}/g, '$1/');
const normalizedUri = uri.replace(/([^:])\/{2,}/g, '$1/');

const urlObj = new URL(uri);
origin = urlObj.origin;
if (normalizedUri.startsWith('/')) {
return { origin: '', path: normalizedUri };
}

uri = urlObj.pathname + urlObj.search + urlObj.hash;
} catch {}
const { origin, pathname, search, hash } = new URL(normalizedUri);

return { origin, uri };
return {
origin,
path: pathname + search + hash,
};
} catch {
return {
origin: '',
path: uri,
};
}
}
12 changes: 6 additions & 6 deletions src/app/utils/parseUrl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ export function parseUrl(config: IntlAdapterConfig, url: string): ParsedUrl {
};
}

const { uri, origin } = parseAsFullyQualifiedURI(url);
const { path, origin } = parseAsFullyQualifiedURI(url);

if (!uri.startsWith('/')) {
throw new Error(`Localization of relative URLs is not supported. Received: "${uri}"`);
if (!path.startsWith('/')) {
throw new Error(`Localization of relative URLs is not supported. Received: "${url}"`);
}

const [, langPart, ...path] = uri.split('/');
const [, langPart, ...unlocalizedPath] = path.split('/');
const locale = getCanonicalLocale(langPart, config.supported.locale);

if (locale !== null && config.supported.locale.indexOf(locale) !== -1) {
return { cleanUrl: `${origin}/${path.join('/')}`, locale };
return { cleanUrl: `${origin}/${unlocalizedPath.join('/')}`, locale };
}

return { cleanUrl: origin + uri, locale: config.default.locale };
return { cleanUrl: origin + path, locale: config.default.locale };
}

0 comments on commit b8ed63a

Please sign in to comment.