mirror of
https://github.com/fluencelabs/js-multiaddr-to-uri
synced 2024-12-04 20:40:20 +00:00
feat: assume HTTP when multiaddr ends with /tcp (#7)
This makes multiaddrs ending with `/tcp/8080` to default to HTTP unless an explicit assumeHttp: false is passed. We also skip default ports for HTTP and HTTPS in the URL. Motivation: https://github.com/ipfs/js-ipfs/pull/2358#issue-307463029 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
This commit is contained in:
parent
ad08d43abb
commit
adda9366c1
@ -18,10 +18,19 @@ const toUri = require('multiaddr-to-uri')
|
||||
|
||||
console.log(toUri('/dnsaddr/protocol.ai/https'))
|
||||
// -> https://protocol.ai
|
||||
|
||||
console.log(toUri('/ip4/127.0.0.1/tcp/8080'))
|
||||
// -> http://127.0.0.1:8080
|
||||
|
||||
console.log(toUri('/ip4/127.0.0.1/tcp/8080', { assumeHttp: false }))
|
||||
// -> tcp://127.0.0.1:8080
|
||||
```
|
||||
|
||||
Note:
|
||||
|
||||
* When `/tcp` is the last (terminating) protocol HTTP is assumed by default (implicit `assumeHttp: true`)
|
||||
* this means produced URIs will start with `http://` instead of `tcp://`
|
||||
* passing `{ assumeHttp: false }` disables this behavior
|
||||
* Might be lossy - e.g. a DNSv6 multiaddr
|
||||
* Can throw if the passed multiaddr:
|
||||
* is not a valid multiaddr
|
||||
|
23
index.js
23
index.js
@ -1,5 +1,20 @@
|
||||
const Multiaddr = require('multiaddr')
|
||||
|
||||
const reduceValue = (_, v) => v
|
||||
const tcpUri = (str, port, parts, opts) => {
|
||||
// return tcp when explicitly requested
|
||||
if (opts && opts.assumeHttp === false) return `tcp://${str}:${port}`
|
||||
// check if tcp is the last protocol in multiaddr
|
||||
let protocol = 'tcp'
|
||||
let explicitPort = `:${port}`
|
||||
const last = parts[parts.length - 1]
|
||||
if (last.protocol === 'tcp') {
|
||||
// assume http and produce clean urls
|
||||
protocol = port === 443 ? 'https' : 'http'
|
||||
explicitPort = port === 443 || port === 80 ? '' : explicitPort
|
||||
}
|
||||
return `${protocol}://${str}${explicitPort}`
|
||||
}
|
||||
|
||||
const Reducers = {
|
||||
ip4: reduceValue,
|
||||
@ -8,10 +23,10 @@ const Reducers = {
|
||||
? content
|
||||
: `[${content}]`
|
||||
),
|
||||
tcp: (str, content, i, parts) => (
|
||||
tcp: (str, content, i, parts, opts) => (
|
||||
parts.some(p => ['http', 'https', 'ws', 'wss'].includes(p.protocol))
|
||||
? `${str}:${content}`
|
||||
: `tcp://${str}:${content}`
|
||||
: tcpUri(str, content, parts, opts)
|
||||
),
|
||||
udp: (str, content) => `udp://${str}:${content}`,
|
||||
dnsaddr: reduceValue,
|
||||
@ -28,7 +43,7 @@ const Reducers = {
|
||||
'p2p-webrtc-direct': str => `${str}/p2p-webrtc-direct`
|
||||
}
|
||||
|
||||
module.exports = (multiaddr) => (
|
||||
module.exports = (multiaddr, opts) => (
|
||||
Multiaddr(multiaddr)
|
||||
.stringTuples()
|
||||
.map(tuple => ({
|
||||
@ -38,6 +53,6 @@ module.exports = (multiaddr) => (
|
||||
.reduce((str, part, i, parts) => {
|
||||
const reduce = Reducers[part.protocol]
|
||||
if (!reduce) throw new Error(`Unsupported protocol ${part.protocol}`)
|
||||
return reduce(str, part.content, i, parts)
|
||||
return reduce(str, part.content, i, parts, opts)
|
||||
}, '')
|
||||
)
|
||||
|
39
test.js
39
test.js
@ -7,19 +7,14 @@ test('should convert multiaddr to URI', (t) => {
|
||||
['/ip4/127.0.0.1/http', 'http://127.0.0.1'],
|
||||
['/ip6/fc00::', 'fc00::'],
|
||||
['/ip6/fc00::/http', 'http://[fc00::]'],
|
||||
['/ip4/0.0.7.6/tcp/1234', 'tcp://0.0.7.6:1234'],
|
||||
['/ip4/0.0.7.6/tcp/1234/http', 'http://0.0.7.6:1234'],
|
||||
['/ip4/0.0.7.6/tcp/1234/https', 'https://0.0.7.6:1234'],
|
||||
['/ip6/::/tcp/0', 'tcp://[::]:0'],
|
||||
['/ip4/0.0.7.6/udp/1234', 'udp://0.0.7.6:1234'],
|
||||
['/ip6/::/udp/0', 'udp://[::]:0'],
|
||||
['/dnsaddr/ipfs.io', 'ipfs.io'],
|
||||
['/dns4/ipfs.io', 'ipfs.io'],
|
||||
['/dns4/libp2p.io', 'libp2p.io'],
|
||||
['/dns6/protocol.ai', 'protocol.ai'],
|
||||
['/dns4/protocol.ai/tcp/80', 'tcp://protocol.ai:80'],
|
||||
['/dns6/protocol.ai/tcp/80', 'tcp://protocol.ai:80'],
|
||||
['/dnsaddr/protocol.ai/tcp/80', 'tcp://protocol.ai:80'],
|
||||
['/dnsaddr/protocol.ai/tcp/80/http', 'http://protocol.ai:80'],
|
||||
['/dnsaddr/protocol.ai/tcp/80/https', 'https://protocol.ai:80'],
|
||||
['/dnsaddr/ipfs.io/ws', 'ws://ipfs.io'],
|
||||
@ -83,6 +78,40 @@ test('should convert multiaddr to URI', (t) => {
|
||||
data.forEach(d => t.is(toUri(d[0]), d[1]))
|
||||
})
|
||||
|
||||
test('should convert multiaddr to http(s):// URI when implicit { assumeHttp: true }', (t) => {
|
||||
const data = [
|
||||
['/ip4/0.0.7.6/tcp/1234', 'http://0.0.7.6:1234'],
|
||||
['/ip6/::/tcp/0', 'http://[::]:0'],
|
||||
['/dns4/protocol.ai/tcp/80', 'http://protocol.ai'],
|
||||
['/dns6/protocol.ai/tcp/80', 'http://protocol.ai'],
|
||||
['/dns4/protocol.ai/tcp/8080', 'http://protocol.ai:8080'],
|
||||
['/dns6/protocol.ai/tcp/8080', 'http://protocol.ai:8080'],
|
||||
['/dns4/protocol.ai/tcp/443', 'https://protocol.ai'],
|
||||
['/dns6/protocol.ai/tcp/443', 'https://protocol.ai'],
|
||||
['/dnsaddr/protocol.ai/tcp/80', 'http://protocol.ai'],
|
||||
['/dnsaddr/protocol.ai/tcp/443', 'https://protocol.ai'],
|
||||
['/dnsaddr/protocol.ai/tcp/8080', 'http://protocol.ai:8080']
|
||||
]
|
||||
data.forEach(d => t.is(toUri(d[0]), d[1]))
|
||||
})
|
||||
|
||||
test('should convert multiaddr to tcp:// URI when explicit { assumeHttp: false }', (t) => {
|
||||
const data = [
|
||||
['/ip4/0.0.7.6/tcp/1234', 'tcp://0.0.7.6:1234'],
|
||||
['/ip6/::/tcp/0', 'tcp://[::]:0'],
|
||||
['/dns4/protocol.ai/tcp/80', 'tcp://protocol.ai:80'],
|
||||
['/dns6/protocol.ai/tcp/80', 'tcp://protocol.ai:80'],
|
||||
['/dns4/protocol.ai/tcp/8080', 'tcp://protocol.ai:8080'],
|
||||
['/dns6/protocol.ai/tcp/8080', 'tcp://protocol.ai:8080'],
|
||||
['/dns4/protocol.ai/tcp/443', 'tcp://protocol.ai:443'],
|
||||
['/dns6/protocol.ai/tcp/443', 'tcp://protocol.ai:443'],
|
||||
['/dnsaddr/protocol.ai/tcp/80', 'tcp://protocol.ai:80'],
|
||||
['/dnsaddr/protocol.ai/tcp/443', 'tcp://protocol.ai:443'],
|
||||
['/dnsaddr/protocol.ai/tcp/8080', 'tcp://protocol.ai:8080']
|
||||
]
|
||||
data.forEach(d => t.is(toUri(d[0], { assumeHttp: false }), d[1]))
|
||||
})
|
||||
|
||||
test('should throw for unsupported protocol', (t) => {
|
||||
t.throws(() => toUri('/quic'))
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user