Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit d7adafc

Browse files
author
Alan Shaw
committedNov 21, 2019
fix: browser and Node.js configuration
resolves #1103 BREAKING CHANGE: Multi parameter constructor options are no longer supported. To create a new IPFS HTTP client, pass a single parameter to the constructor. The parameter can be one of: * String, formatted as one of: * Multiaddr e.g. /ip4/127.0.0.1/tcp/5001 * URL e.g. http://127.0.0.1:5001 * [Multiaddr](https://www.npmjs.com/package/multiaddr) instance * Object, in format of either: * Address and path e.g. `{ apiAddr: '/ip4/127.0.0.1/tcp/5001': apiPath: '/api/v0' }` (Note: `apiAddr` can also be a string in URL form or a Multiaddr instance) * Node.js style address e.g. `{ host: '127.0.0.1', port: 5001, protocol: 'http' }` License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai>
1 parent 78b430a commit d7adafc

10 files changed

+203
-214
lines changed
 

‎README.md

+126-105
Large diffs are not rendered by default.

‎package.json

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"ky-universal": "^0.3.0",
6969
"merge-options": "^2.0.0",
7070
"multiaddr": "^6.0.6",
71+
"multiaddr-to-uri": "^5.0.0",
7172
"multibase": "~0.6.0",
7273
"multicodec": "~0.5.1",
7374
"multihashes": "~0.4.14",

‎src/get-endpoint-config.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
'use strict'
22

3-
module.exports = (config) => {
3+
const configure = require('./lib/configure')
4+
5+
module.exports = configure(({ apiAddr, apiPath }) => {
6+
const url = new URL(apiAddr)
47
return () => ({
5-
host: config.host,
6-
port: config.port,
7-
protocol: config.protocol,
8-
'api-path': config['api-path']
8+
host: url.hostname,
9+
port: url.port,
10+
protocol: url.protocol.split(':')[0], // remove ":"
11+
'api-path': apiPath
912
})
10-
}
13+
})

‎src/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ function ipfsClient (config) {
101101
yield file
102102
}
103103
})()),
104-
getPullStream: toPullStream((path, options) => (async function * () {
104+
getPullStream: pullify.source((path, options) => (async function * () {
105105
for await (const file of get(path, options)) {
106106
if (file.content) {
107107
const { content } = file

‎src/lib/configure.js

+22-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
const ky = require('ky-universal').default
55
const { isBrowser, isWebWorker } = require('ipfs-utils/src/env')
6-
const { toUri } = require('./multiaddr')
6+
const toUri = require('multiaddr-to-uri')
77
const errorHandler = require('./error-handler')
88
const mergeOptions = require('merge-options').bind({ ignoreUndefined: true })
99
const parseDuration = require('parse-duration')
@@ -22,7 +22,16 @@ module.exports = create => config => {
2222

2323
config.apiAddr = (config.apiAddr || getDefaultApiAddr(config)).toString()
2424
config.apiAddr = config.apiAddr.startsWith('/') ? toUri(config.apiAddr) : config.apiAddr
25-
config.apiPath = config.apiPath || config['api-path'] || '/api/v0'
25+
config.apiAddr = trimEnd(config.apiAddr, '/')
26+
27+
const apiAddrPath = getNonRootPath(config.apiAddr)
28+
29+
// Use configured apiPath, or path on the end of apiAddr (if there is one) or default to /api/v0
30+
config.apiPath = config.apiPath || config['api-path'] || apiAddrPath || '/api/v0'
31+
config.apiPath = trimEnd(config.apiPath, '/')
32+
33+
// If user passed apiAddr with a path, trim it from the end (it is now apiPath)
34+
config.apiAddr = apiAddrPath ? trimEnd(config.apiAddr, apiAddrPath) : config.apiAddr
2635

2736
const defaults = {
2837
prefixUrl: config.apiAddr + config.apiPath,
@@ -48,13 +57,9 @@ module.exports = create => config => {
4857

4958
function getDefaultApiAddr ({ protocol, host, port }) {
5059
if (isBrowser || isWebWorker) {
51-
if (!protocol && !host && !port) { // Use current origin
52-
return ''
53-
}
54-
5560
if (!protocol) {
5661
protocol = location.protocol.startsWith('http')
57-
? location.protocol.split(':')[0]
62+
? trimEnd(location.protocol, ':')
5863
: 'http'
5964
}
6065

@@ -79,3 +84,13 @@ function wrap (fn, defaults) {
7984
function parseTimeout (value) {
8085
return typeof value === 'string' ? parseDuration(value) : value
8186
}
87+
88+
const trimEnd = (str, end) => str.endsWith(end) ? str.slice(0, -end.length) : str
89+
90+
// Get the path from a URL is it is not /
91+
function getNonRootPath (url) {
92+
if (url) {
93+
const { pathname } = new URL(url)
94+
return pathname === '/' ? null : pathname
95+
}
96+
}

‎src/lib/multiaddr.js

-18
This file was deleted.

‎test/constructor.spec.js

+6-15
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,6 @@ describe('ipfs-http-client constructor tests', () => {
4444
expectConfig(ipfs, { host, port, protocol })
4545
})
4646

47-
it('multiaddr dns4 string, explicit https in opts', () => {
48-
const host = 'foo.com'
49-
const port = '1001'
50-
const protocol = 'https'
51-
const addr = `/dns4/${host}/tcp/${port}`
52-
const ipfs = ipfsClient(addr, { protocol })
53-
expectConfig(ipfs, { host, port, protocol })
54-
})
55-
5647
it('multiaddr ipv4 string (implicit http)', () => {
5748
const host = '101.101.101.101'
5849
const port = '1001'
@@ -82,22 +73,22 @@ describe('ipfs-http-client constructor tests', () => {
8273
it('host and port strings', () => {
8374
const host = '1.1.1.1'
8475
const port = '9999'
85-
const ipfs = ipfsClient(host, port)
76+
const ipfs = ipfsClient({ host, port })
8677
expectConfig(ipfs, { host, port })
8778
})
8879

8980
it('host, port and api path', () => {
9081
const host = '10.100.100.255'
9182
const port = '9999'
9283
const apiPath = '/future/api/v1/'
93-
const ipfs = ipfsClient(host, port, { 'api-path': apiPath })
94-
expectConfig(ipfs, { host, port, apiPath })
84+
const ipfs = ipfsClient({ host, port, apiPath })
85+
expectConfig(ipfs, { host, port, apiPath: apiPath.slice(0, -1) })
9586
})
9687

9788
it('throws on invalid multiaddr', () => {
9889
expect(() => ipfsClient('/dns4')).to.throw('invalid address')
9990
expect(() => ipfsClient('/hello')).to.throw('no protocol with name')
100-
expect(() => ipfsClient('/dns4/ipfs.io')).to.throw('multiaddr must have a valid format')
91+
expect(() => ipfsClient('/dns4/ipfs.io')).to.throw(/Invalid URL/)
10192
})
10293
})
10394

@@ -134,7 +125,7 @@ async function clientWorks (client) {
134125
function expectConfig (ipfs, { host, port, protocol, apiPath }) {
135126
const conf = ipfs.getEndpointConfig()
136127
expect(conf.host).to.be.oneOf([host, 'localhost', ''])
137-
expect(conf.port).to.be.oneOf([port, '5001', 80])
128+
expect(conf.port).to.be.oneOf([port, '5001', '80'])
138129
expect(conf.protocol).to.equal(protocol || 'http')
139-
expect(conf['api-path']).to.equal(apiPath || '/api/v0/')
130+
expect(conf['api-path']).to.equal(apiPath || '/api/v0')
140131
}

‎test/endpoint-config.spec.js

+4-31
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,16 @@
33
'use strict'
44

55
const { expect } = require('interface-ipfs-core/src/utils/mocha')
6-
const isNode = require('detect-node')
76
const ipfsClient = require('../src')
8-
const f = require('./utils/factory')
97

108
describe('.getEndpointConfig', () => {
11-
if (!isNode) { return }
12-
13-
let ipfsd
14-
let ipfs
15-
16-
before(async function () {
17-
this.timeout(20 * 1000) // slow CI
18-
19-
ipfsd = await f.spawn({
20-
initOptions: {
21-
bits: 1024,
22-
profile: 'test'
23-
}
24-
})
25-
ipfs = ipfsClient(ipfsd.apiAddr)
26-
})
27-
28-
after(async function () {
29-
this.timeout(10 * 1000)
30-
31-
if (ipfsd) {
32-
await ipfsd.stop()
33-
}
34-
})
35-
369
it('should return the endpoint configuration', function () {
10+
const ipfs = ipfsClient('https://127.0.0.1:5501/ipfs/api/')
3711
const endpoint = ipfs.getEndpointConfig()
3812

3913
expect(endpoint.host).to.equal('127.0.0.1')
40-
expect(endpoint.protocol).to.equal('http')
41-
expect(endpoint['api-path']).to.equal('/api/v0/')
42-
// changes per test run so we just assert it exists.
43-
expect(endpoint).to.have.property('port')
14+
expect(endpoint.protocol).to.equal('https')
15+
expect(endpoint['api-path']).to.equal('/ipfs/api')
16+
expect(endpoint.port).to.equal('5501')
4417
})
4518
})

‎test/lib.configure.spec.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ describe('lib/configure', () => {
1010
it('should accept no config', () => {
1111
configure(config => {
1212
if (isBrowser || isWebWorker) {
13-
expect(config.apiAddr).to.eql('')
13+
expect(config.apiAddr).to.eql(location.origin)
1414
} else {
1515
expect(config.apiAddr).to.eql('http://localhost:5001')
1616
}
@@ -24,10 +24,17 @@ describe('lib/configure', () => {
2424
})(input)
2525
})
2626

27+
it('should accept string url', () => {
28+
const input = 'http://127.0.0.1:5001'
29+
configure(config => {
30+
expect(config.apiAddr).to.eql('http://127.0.0.1:5001')
31+
})(input)
32+
})
33+
2734
it('should accept multiaddr instance', () => {
28-
const input = Multiaddr('/ip4/127.0.0.1')
35+
const input = Multiaddr('/ip4/127.0.0.1/tcp/5001')
2936
configure(config => {
30-
expect(config.apiAddr).to.eql('http://127.0.0.1')
37+
expect(config.apiAddr).to.eql('http://127.0.0.1:5001')
3138
})(input)
3239
})
3340

0 commit comments

Comments
 (0)