Skip to content

Commit 5da0bcd

Browse files
lidelAlan Shaw
authored and
Alan Shaw
committed
fix: https multiaddr support in constructor (ipfs#965)
Passing HTTPS multiaddr as a string to constructor did not work, protocol was ignored and unencrypted HTTP was used. This commit improves parsing of multiaddr constructor parameter and adds tests to ensure HTTPS is respected in all scenarios. It also updates iso-stream-http to v0.1.2 which includes fix for "https does not exist" License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
1 parent 21cdcc5 commit 5da0bcd

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"is-ipfs": "~0.6.0",
4141
"is-pull-stream": "0.0.0",
4242
"is-stream": "^1.1.0",
43-
"iso-stream-http": "~0.1.1",
43+
"iso-stream-http": "~0.1.2",
4444
"iso-url": "~0.4.6",
4545
"just-kebab-case": "^1.1.0",
4646
"just-map-keys": "^1.1.0",

src/index.js

+24-13
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,60 @@ const loadCommands = require('./utils/load-commands')
1313
const getConfig = require('./utils/default-config')
1414
const sendRequest = require('./utils/send-request')
1515

16-
function ipfsClient (hostOrMultiaddr, port, opts) {
16+
function ipfsClient (hostOrMultiaddr, port, userOptions) {
1717
// convert all three params to objects that we can merge.
18-
let hostAndPort = {}
18+
let options = {}
1919

2020
if (!hostOrMultiaddr) {
2121
// autoconfigure host and port in browser
2222
if (typeof self !== 'undefined') {
23-
const split = self.location.host.split(':')
24-
hostAndPort.host = split[0]
25-
hostAndPort.port = split[1]
23+
options = urlToOptions(self.location)
2624
}
2725
} else if (multiaddr.isMultiaddr(hostOrMultiaddr)) {
28-
hostAndPort = toHostAndPort(hostOrMultiaddr)
26+
options = maToOptions(hostOrMultiaddr)
2927
} else if (typeof hostOrMultiaddr === 'object') {
30-
hostAndPort = hostOrMultiaddr
28+
options = hostOrMultiaddr
3129
} else if (typeof hostOrMultiaddr === 'string') {
3230
if (hostOrMultiaddr[0] === '/') {
3331
// throws if multiaddr is malformed or can't be converted to a nodeAddress
34-
hostAndPort = toHostAndPort(multiaddr(hostOrMultiaddr))
32+
options = maToOptions(multiaddr(hostOrMultiaddr))
3533
} else {
3634
// hostOrMultiaddr is domain or ip address as a string
37-
hostAndPort.host = hostOrMultiaddr
35+
options.host = hostOrMultiaddr
3836
}
3937
}
4038

4139
if (port && typeof port !== 'object') {
4240
port = { port: port }
4341
}
4442

45-
const config = Object.assign(getConfig(), hostAndPort, port, opts)
43+
const config = Object.assign(getConfig(), options, port, userOptions)
4644
const requestAPI = sendRequest(config)
4745
const cmds = loadCommands(requestAPI, config)
4846
cmds.send = requestAPI
4947

5048
return cmds
5149
}
5250

53-
// throws if multiaddr can't be converted to a nodeAddress
54-
function toHostAndPort (multiaddr) {
51+
function maToOptions (multiaddr) {
52+
// ma.nodeAddress() throws if multiaddr can't be converted to a nodeAddress
5553
const nodeAddr = multiaddr.nodeAddress()
54+
const protos = multiaddr.protos()
55+
// only http and https are allowed as protocol,
56+
// anything else will be replaced with http
57+
const exitProtocol = protos[protos.length - 1].name
5658
return {
5759
host: nodeAddr.address,
58-
port: nodeAddr.port
60+
port: nodeAddr.port,
61+
protocol: exitProtocol.startsWith('http') ? exitProtocol : 'http'
62+
}
63+
}
64+
65+
function urlToOptions (url) {
66+
return {
67+
host: url.hostname,
68+
port: url.port || (url.protocol.startsWith('https') ? 443 : 80),
69+
protocol: url.protocol.startsWith('http') ? url.protocol.split(':')[0] : 'http'
5970
}
6071
}
6172

test/constructor.spec.js

+33-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,25 @@ describe('ipfs-http-client constructor tests', () => {
3030
expectConfig(ipfs, { host, port, protocol })
3131
})
3232

33-
it('mutliaddr dns4 string, opts', () => {
33+
it('multiaddr dns4 string (implicit http)', () => {
34+
const host = 'foo.com'
35+
const port = '1001'
36+
const protocol = 'http' // default to http if not specified in multiaddr
37+
const addr = `/dns4/${host}/tcp/${port}`
38+
const ipfs = ipfsClient(addr)
39+
expectConfig(ipfs, { host, port, protocol })
40+
})
41+
42+
it('multiaddr dns4 string (explicit https)', () => {
43+
const host = 'foo.com'
44+
const port = '1001'
45+
const protocol = 'https'
46+
const addr = `/dns4/${host}/tcp/${port}/${protocol}`
47+
const ipfs = ipfsClient(addr)
48+
expectConfig(ipfs, { host, port, protocol })
49+
})
50+
51+
it('multiaddr dns4 string, explicit https in opts', () => {
3452
const host = 'foo.com'
3553
const port = '1001'
3654
const protocol = 'https'
@@ -39,15 +57,25 @@ describe('ipfs-http-client constructor tests', () => {
3957
expectConfig(ipfs, { host, port, protocol })
4058
})
4159

42-
it('mutliaddr ipv4 string', () => {
60+
it('multiaddr ipv4 string (implicit http)', () => {
4361
const host = '101.101.101.101'
4462
const port = '1001'
63+
const protocol = 'http'
4564
const addr = `/ip4/${host}/tcp/${port}`
4665
const ipfs = ipfsClient(addr)
47-
expectConfig(ipfs, { host, port })
66+
expectConfig(ipfs, { host, port, protocol })
67+
})
68+
69+
it('multiaddr ipv4 string (explicit https)', () => {
70+
const host = '101.101.101.101'
71+
const port = '1001'
72+
const protocol = 'https'
73+
const addr = `/ip4/${host}/tcp/${port}/${protocol}`
74+
const ipfs = ipfsClient(addr)
75+
expectConfig(ipfs, { host, port, protocol })
4876
})
4977

50-
it('mutliaddr instance', () => {
78+
it('multiaddr instance', () => {
5179
const host = 'ace.place'
5280
const port = '1001'
5381
const addr = multiaddr(`/dns4/${host}/tcp/${port}`)
@@ -70,7 +98,7 @@ describe('ipfs-http-client constructor tests', () => {
7098
expectConfig(ipfs, { host, port, apiPath })
7199
})
72100

73-
it('throws on invalid mutliaddr', () => {
101+
it('throws on invalid multiaddr', () => {
74102
expect(() => ipfsClient('/dns4')).to.throw('invalid address')
75103
expect(() => ipfsClient('/hello')).to.throw('no protocol with name')
76104
expect(() => ipfsClient('/dns4/ipfs.io')).to.throw('multiaddr must have a valid format')

0 commit comments

Comments
 (0)