Skip to content

Commit 0a16a9c

Browse files
committed
Fix path segments containing colons being misidentified as absolute URLs
Fixes #2424
1 parent ff46eae commit 0a16a9c

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

source/core/options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1757,7 +1757,7 @@ export default class Options {
17571757

17581758
// Detect if URL is already absolute (has a protocol/scheme)
17591759
const valueString = value.toString();
1760-
const isAbsolute = is.urlInstance(value) || /^[a-z][a-z\d+.-]*:/i.test(valueString);
1760+
const isAbsolute = is.urlInstance(value) || /^[a-z][a-z\d+.-]*:\/\//i.test(valueString);
17611761

17621762
// Only concatenate prefixUrl if the URL is relative
17631763
const urlString = isAbsolute ? valueString : `${this.prefixUrl as string}${valueString}`;

test/hooks.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,58 @@ test('setting absolute URL in hook does not concatenate with prefixUrl', withSer
664664
t.is(body, 'changed');
665665
});
666666

667+
test('allows colon in path segment with prefixUrl (CouchDB user URLs)', withServer, async (t, server, serverGot) => {
668+
server.get('/_users/org.couchdb.user:[email protected]', (_request, response) => {
669+
response.end('user document');
670+
});
671+
672+
const client = serverGot.extend({
673+
prefixUrl: `${server.url}/_users/`,
674+
});
675+
676+
const {body} = await client.get('org.couchdb.user:[email protected]');
677+
t.is(body, 'user document');
678+
});
679+
680+
test('allows multiple colons in path with prefixUrl', withServer, async (t, server, serverGot) => {
681+
server.get('/api/ns:type:id', (_request, response) => {
682+
response.end('namespaced');
683+
});
684+
685+
const client = serverGot.extend({
686+
prefixUrl: `${server.url}/api/`,
687+
});
688+
689+
const {body} = await client.get('ns:type:id');
690+
t.is(body, 'namespaced');
691+
});
692+
693+
test('allows mailto-like patterns in path with prefixUrl', withServer, async (t, server, serverGot) => {
694+
server.get('/users/mailto:[email protected]', (_request, response) => {
695+
response.end('email user');
696+
});
697+
698+
const client = serverGot.extend({
699+
prefixUrl: `${server.url}/users/`,
700+
});
701+
702+
const {body} = await client.get('mailto:[email protected]');
703+
t.is(body, 'email user');
704+
});
705+
706+
test('allows URN-like patterns in path with prefixUrl', withServer, async (t, server, serverGot) => {
707+
server.get('/resources/urn:isbn:123', (_request, response) => {
708+
response.end('book');
709+
});
710+
711+
const client = serverGot.extend({
712+
prefixUrl: `${server.url}/resources/`,
713+
});
714+
715+
const {body} = await client.get('urn:isbn:123');
716+
t.is(body, 'book');
717+
});
718+
667719
test('afterResponse is called with response', withServer, async (t, server, got) => {
668720
server.get('/', echoHeaders);
669721

0 commit comments

Comments
 (0)