diff --git a/src/index.ts b/src/index.ts index fb01a8a..5df544a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,6 +36,14 @@ export interface MultiaddrToUriOpts { assumeHttp?: boolean } +const ASSUME_HTTP_CODES = [ + protocols('tcp').code, + protocols('dns').code, + protocols('dnsaddr').code, + protocols('dns4').code, + protocols('dns6').code +] + interface Interpreter { (value: string, ma: StringTuple[]): string } function extractSNI (ma: StringTuple[]): string | null { @@ -219,15 +227,25 @@ export function multiaddrToUri (input: Multiaddr | string | Uint8Array, opts?: M } let uri = interpreter(head[1] ?? '', parts) - if (opts?.assumeHttp !== false && head[0] === protocols('tcp').code) { - // If rightmost proto is tcp, we assume http here - uri = uri.replace('tcp://', 'http://') - if (head[1] === '443' || head[1] === '80') { - if (head[1] === '443') { - uri = uri.replace('http://', 'https://') - } - // Drop the port - uri = uri.substring(0, uri.lastIndexOf(':')) + + if (opts?.assumeHttp !== false && ASSUME_HTTP_CODES.includes(head[0])) { + // strip any declared protocol + uri = uri.replace(/^.*:\/\//, '') + + if (head[1] === '443') { + uri = `https://${uri}` + } else { + uri = `http://${uri}` + } + } + + if (uri.startsWith('http://') || uri.startsWith('https://')) { + // this will strip default ports while keeping paths intact + uri = new URL(uri).toString() + + // strip trailing slash, e.g. http://127.0.0.1/ -> http://127.0.0.1 + if (uri.endsWith('/')) { + uri = uri.substring(0, uri.length - 1) } } diff --git a/test/test.spec.ts b/test/test.spec.ts index 5a53227..172c252 100644 --- a/test/test.spec.ts +++ b/test/test.spec.ts @@ -16,12 +16,16 @@ describe('multiaddr-to-uri', () => { ['/ip4/0.0.7.6/udp/1234', 'udp://0.0.7.6:1234'], ['/ip6/::/udp/0', 'udp://[::]:0'], ['/dns/a.com/tcp/1234', 'http://a.com:1234'], - ['/dns/a.com', 'a.com'], - ['/dnsaddr/ipfs.io', 'ipfs.io'], - ['/dns4/ipfs.io', 'ipfs.io'], - ['/dns4/libp2p.io', 'libp2p.io'], - ['/dns6/protocol.ai', 'protocol.ai'], - ['/dnsaddr/protocol.ai/tcp/80/http', 'http://protocol.ai:80'], + ['/dns/a.com/tcp/1234/https', 'https://a.com:1234'], + ['/dns/a.com/tcp/1234/tls/http', 'https://a.com:1234'], + ['/dns/a.com/tcp/80', 'http://a.com'], + ['/dns/a.com/tcp/443', 'https://a.com'], + ['/dns/a.com', 'http://a.com'], + ['/dnsaddr/ipfs.io', 'http://ipfs.io'], + ['/dns4/ipfs.io', 'http://ipfs.io'], + ['/dns4/libp2p.io', 'http://libp2p.io'], + ['/dns6/protocol.ai', 'http://protocol.ai'], + ['/dnsaddr/protocol.ai/tcp/80/http', 'http://protocol.ai'], ['/dnsaddr/protocol.ai/tcp/80/https', 'https://protocol.ai:80'], ['/dnsaddr/ipfs.io/ws', 'ws://ipfs.io'], ['/dnsaddr/ipfs.io/http', 'http://ipfs.io'],