Skip to content

Commit

Permalink
fix: allow port parameter matching
Browse files Browse the repository at this point in the history
  • Loading branch information
joeynenni committed Feb 1, 2025
1 parent 44bf2d1 commit c24d902
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
16 changes: 16 additions & 0 deletions src/utils/__tests__/matchAndRewriteRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,22 @@ describe('matchAndRewriteURL', () => {
expect(url4.toString()).toEqual('https://localhost/googleapis/foo/v1/test:url?key=abc123');
});

it('Matches port parameters and remaps them properly', () => {
const url = attemptRemap({
url: new URL('https://foo.domain.com:4567/'),
mappings: [{prefix: '/domain/{subdomain}/{port}', target: '{subdomain}.domain.com:{port}'}],
});
expect(url.toString()).toEqual('https://localhost/domain/foo/4567/');
});

it('Does not remove port when url is not matched', () => {
const url = attemptRemap({
url: new URL('https://foo.domain.com:4567/'),
mappings: [],
});
expect(url.toString()).toEqual('https://foo.domain.com:4567/');
});

it('Applies the /.proxy/ mapping without any mappings', () => {
const url = attemptRemap({
url: new URL('https://1234567890.discordsays.com/api/token'),
Expand Down
12 changes: 9 additions & 3 deletions src/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ function regexFromTarget(target: string): RegExp {
return new RegExp(`${regexString}(/|$)`);
}

function removePortParameterFromTarget(url: string): string {
return url.replace(/:\{[^}]+\}/g, '');
}

export interface MatchAndRewriteURLInputs {
originalURL: URL;
prefixHost: string;
Expand All @@ -32,15 +36,17 @@ export interface MatchAndRewriteURLInputs {
* @returns null if URL doesn't match prefix, otherwise return rewritten URL
*/
export function matchAndRewriteURL({originalURL, prefix, prefixHost, target}: MatchAndRewriteURLInputs): URL | null {
// coerce url with filler https protocol so we can retrieve host and pathname from target
const targetURL = new URL(`https://${target}`);
// Remove port parameter from target and coerce url with filler https protocol so we can retrieve host and pathname from target
const targetURL = new URL(`https://${removePortParameterFromTarget(target)}`);
// Depending on the environment, the URL constructor may turn `{` and `}` into `%7B` and `%7D`, respectively
const targetRegEx = regexFromTarget(targetURL.host.replace(/%7B/g, '{').replace(/%7D/g, '}'));
const targetRegEx = regexFromTarget(target.replace(/%7B/g, '{').replace(/%7D/g, '}'));
const match = originalURL.toString().match(targetRegEx);
// Null match indicates that this target is not relevant
if (match == null) return originalURL;
const newURL = new URL(originalURL.toString());
newURL.host = prefixHost;
// Remove port from new url (discord activities proxy doesn't listen on custom ports)
newURL.port = '';
newURL.pathname = prefix.replace(SUBSTITUTION_REGEX, (_, matchName) => {
const replaceValue = match.groups?.[matchName];
if (replaceValue == null) throw new Error('Misconfigured route.');
Expand Down

0 comments on commit c24d902

Please sign in to comment.