Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
test: add tests for different types of connection config (#3388)
Browse files Browse the repository at this point in the history
We claim to support URLs, MultiAddrs, strings and individual URL components
so add tests for them.

Also, add code to actually support the above permutations..

Co-authored-by: Vasco Santos <[email protected]>
  • Loading branch information
achingbrain and vasco-santos authored Nov 13, 2020
1 parent 583503b commit b554002
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 41 deletions.
2 changes: 2 additions & 0 deletions packages/ipfs-core-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"it-all": "^1.0.4",
"it-map": "^1.0.4",
"it-peekable": "^1.0.1",
"multiaddr": "^8.0.0",
"multiaddr-to-uri": "^6.0.0",
"uint8arrays": "^1.1.0"
},
"devDependencies": {
Expand Down
23 changes: 23 additions & 0 deletions packages/ipfs-core-utils/src/to-url-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict'

const multiaddr = require('multiaddr')
const multiAddrToUri = require('multiaddr-to-uri')

/**
* @param {string|Multiaddr|URL} url - A string, multiaddr or URL to convert to a url string
* @returns {string}
*/
module.exports = (url) => {
try {
// @ts-expect-error
url = multiAddrToUri(multiaddr(url))
} catch (err) { }

url = url.toString()

return url
}

/**
* @typedef {import('multiaddr')} Multiaddr
*/
2 changes: 0 additions & 2 deletions packages/ipfs-http-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,13 @@
"ipld-dag-cbor": "^0.17.0",
"ipld-dag-pb": "^0.20.0",
"ipld-raw": "^6.0.0",
"iso-url": "^1.0.0",
"it-last": "^1.0.4",
"it-map": "^1.0.4",
"it-tar": "^1.2.2",
"it-to-buffer": "^1.0.2",
"it-to-stream": "^0.1.2",
"merge-options": "^2.0.0",
"multiaddr": "^8.0.0",
"multiaddr-to-uri": "^6.0.0",
"multibase": "^3.0.0",
"multicodec": "^2.0.1",
"multihashes": "^3.0.1",
Expand Down
77 changes: 39 additions & 38 deletions packages/ipfs-http-client/src/lib/core.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
'use strict'
/* eslint-env browser */
const Multiaddr = require('multiaddr')
const toUri = require('multiaddr-to-uri')
const { isBrowser, isWebWorker } = require('ipfs-utils/src/env')
const { URL } = require('iso-url')
const parseDuration = require('parse-duration').default
const log = require('debug')('ipfs-http-client:lib:error-handler')
const HTTP = require('ipfs-utils/src/http')
const merge = require('merge-options')
const toUrlString = require('ipfs-core-utils/src/to-url-string')

/**
* @param {any} input
* @returns {input is Multiaddr}
*/
const isMultiaddr = (input) => {
try {
Multiaddr(input) // eslint-disable-line no-new
return true
} catch (e) {
return false
}
}
const DEFAULT_PROTOCOL = isBrowser || isWebWorker ? location.protocol : 'http'
const DEFAULT_HOST = isBrowser || isWebWorker ? location.hostname : 'localhost'
const DEFAULT_PORT = isBrowser || isWebWorker ? location.port : '5001'

/**
* @param {any} options
* @param {ClientOptions|URL|Multiaddr|string} [options]
* @returns {ClientOptions}
*/
const normalizeInput = (options = {}) => {
if (isMultiaddr(options)) {
options = { url: toUri(options) }
} else if (typeof options === 'string') {
options = { url: options }
const normalizeOptions = (options = {}) => {
let url
let opts = {}

if (typeof options === 'string' || Multiaddr.isMultiaddr(options)) {
url = new URL(toUrlString(options))
} else if (options instanceof URL) {
url = options
} else if (typeof options.url === 'string' || Multiaddr.isMultiaddr(options.url)) {
url = new URL(toUrlString(options.url))
opts = options
} else if (options.url instanceof URL) {
url = options.url
opts = options
} else {
opts = options || {}

const protocol = (opts.protocol || DEFAULT_PROTOCOL).replace(':', '')
const host = (opts.host || DEFAULT_HOST).split(':')[0]
const port = (opts.port || DEFAULT_PORT)

url = new URL(`${protocol}://${host}:${port}`)
}

const url = new URL(options.url)
if (options.apiPath) {
url.pathname = options.apiPath
if (opts.apiPath) {
url.pathname = opts.apiPath
} else if (url.pathname === '/' || url.pathname === undefined) {
url.pathname = 'api/v0'
}
if (!options.url) {
if (isBrowser || isWebWorker) {
url.protocol = options.protocol || location.protocol
url.hostname = options.host || location.hostname
url.port = options.port || location.port
} else {
url.hostname = options.host || 'localhost'
url.port = options.port || '5001'
url.protocol = options.protocol || 'http'
}
}
options.url = url

return options
return {
...opts,
host: url.host,
protocol: url.protocol.replace(':', ''),
port: Number(url.port),
apiPath: url.pathname,
url
}
}

const errorHandler = async (response) => {
Expand Down Expand Up @@ -111,7 +112,7 @@ const parseTimeout = (value) => {
* @property {Headers|Record<string, string>} [headers] - Request headers.
* @property {number|string} [timeout] - Amount of time until request should timeout in ms or humand readable. https://www.npmjs.com/package/parse-duration for valid string values.
* @property {string} [apiPath] - Path to the API.
* @property {URL|string} [url] - Full API URL.
* @property {URL|string|Multiaddr} [url] - Full API URL.
* @property {object} [ipld]
* @property {any[]} [ipld.formats] - An array of additional [IPLD formats](https://github.com/ipld/interface-ipld-format) to support
* @property {(format: string) => Promise<any>} [ipld.loadFormat] - an async function that takes the name of an [IPLD format](https://github.com/ipld/interface-ipld-format) as a string and should return the implementation of that codec
Expand All @@ -121,7 +122,7 @@ class Client extends HTTP {
* @param {ClientOptions|URL|Multiaddr|string} [options]
*/
constructor (options = {}) {
const opts = normalizeInput(options)
const opts = normalizeOptions(options)

super({
timeout: parseTimeout(opts.timeout) || 60000 * 20,
Expand Down
71 changes: 70 additions & 1 deletion packages/ipfs-http-client/test/constructor.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ describe('ipfs-http-client constructor tests', () => {
expectConfig(ipfs, { host, port, protocol })
})

it('opts with URL components from URL', () => {
const host = 'wizard.world'
const port = '999'
const protocol = 'https'
const url = new URL(`${protocol}://${host}:${port}`)
const ipfs = ipfsClient({ host: url.host, port: url.port, protocol: url.protocol })
expectConfig(ipfs, { host, port, protocol })
})

it('multiaddr dns4 string (implicit http)', () => {
const host = 'foo.com'
const port = '1001'
Expand Down Expand Up @@ -79,6 +88,22 @@ describe('ipfs-http-client constructor tests', () => {
expectConfig(ipfs, { host, port })
})

it('URL as string', () => {
const host = '10.100.100.255'
const port = '9999'
const apiPath = '/future/api/v1/'
const ipfs = ipfsClient(`http://${host}:${port}${apiPath}`)
expectConfig(ipfs, { host, port, apiPath })
})

it('URL as URL', () => {
const host = '10.100.100.255'
const port = '9999'
const apiPath = '/future/api/v1/'
const ipfs = ipfsClient(new URL(`http://${host}:${port}${apiPath}`))
expectConfig(ipfs, { host, port, apiPath })
})

it('host, port and api path', () => {
const host = '10.100.100.255'
const port = '9999'
Expand All @@ -87,13 +112,57 @@ describe('ipfs-http-client constructor tests', () => {
expectConfig(ipfs, { host, port, apiPath })
})

it('url', () => {
it('options.url as URL string', () => {
const host = '10.100.100.255'
const port = '9999'
const apiPath = '/future/api/v1/'
const ipfs = ipfsClient({ url: `http://${host}:${port}${apiPath}` })
expectConfig(ipfs, { host, port, apiPath })
})

it('options.url as URL', () => {
const host = '10.100.100.255'
const port = '9999'
const apiPath = '/future/api/v1/'
const ipfs = ipfsClient({ url: new URL(`http://${host}:${port}${apiPath}`) })
expectConfig(ipfs, { host, port, apiPath })
})

it('options.url as multiaddr (implicit http)', () => {
const host = 'foo.com'
const port = '1001'
const protocol = 'http' // default to http if not specified in multiaddr
const addr = `/dns4/${host}/tcp/${port}`
const ipfs = ipfsClient({ url: multiaddr(addr) })
expectConfig(ipfs, { host, port, protocol })
})

it('options.url as multiaddr (explicit https)', () => {
const host = 'foo.com'
const port = '1001'
const protocol = 'https'
const addr = `/dns4/${host}/tcp/${port}/https`
const ipfs = ipfsClient({ url: multiaddr(addr) })
expectConfig(ipfs, { host, port, protocol })
})

it('options.url as multiaddr string (implicit http)', () => {
const host = 'foo.com'
const port = '1001'
const protocol = 'http' // default to http if not specified in multiaddr
const addr = `/dns4/${host}/tcp/${port}`
const ipfs = ipfsClient({ url: addr })
expectConfig(ipfs, { host, port, protocol })
})

it('options.url as multiaddr string (explicit https)', () => {
const host = 'foo.com'
const port = '1001'
const protocol = 'https'
const addr = `/dns4/${host}/tcp/${port}/https`
const ipfs = ipfsClient({ url: addr })
expectConfig(ipfs, { host, port, protocol })
})
})

describe('integration', () => {
Expand Down

0 comments on commit b554002

Please sign in to comment.