Skip to content

Commit

Permalink
fix(brave): no port collisions
Browse files Browse the repository at this point in the history
Before starting embedded js-ipfs we now check if API and Gateway ports are free.
If not, we find available ones and update the config.

This way user does not need to deal with "port taken" errors and
embedded node provides seamless experience without surprises.
  • Loading branch information
lidel committed Jul 16, 2019
1 parent b9a4c37 commit b48e643
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
36 changes: 28 additions & 8 deletions add-on/src/lib/ipfs-client/embedded-chromesockets.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,16 @@ const Ipfs = require('ipfs')
const HttpApi = require('ipfs/src/http')
const multiaddr = require('multiaddr')
const maToUri = require('multiaddr-to-uri')
const getPort = require('get-port')

const { optionDefaults } = require('../options')

// js-ipfs with embedded hapi HTTP server
let node = null
let nodeHttpApi = null

exports.init = function init (opts) {
log('init embedded:chromesockets')

async function buildConfig (opts) {
const defaultOpts = JSON.parse(optionDefaults.ipfsNodeConfig)

defaultOpts.libp2p = {
config: {
dht: {
Expand All @@ -36,9 +34,31 @@ exports.init = function init (opts) {
}
}
}

const userOpts = JSON.parse(opts.ipfsNodeConfig)
const ipfsOpts = mergeOptions.call({ concatArrays: true }, defaultOpts, userOpts, { start: false })
const ipfsNodeConfig = mergeOptions.call({ concatArrays: true }, defaultOpts, userOpts, { start: false })

// Detect when API or Gateway port is not available (taken by something else)
// We find the next free port and update configuration to use it instead
const multiaddr2port = (ma) => parseInt(new URL(multiaddr2httpUrl(ma)).port, 10)
const gatewayPort = multiaddr2port(ipfsNodeConfig.config.Addresses.Gateway)
const apiPort = multiaddr2port(ipfsNodeConfig.config.Addresses.API)
log(`checking if ports are available: api: ${apiPort}, gateway: ${gatewayPort}`)
const freeGatewayPort = await getPort({ port: getPort.makeRange(gatewayPort, gatewayPort + 100) })
const freeApiPort = await getPort({ port: getPort.makeRange(apiPort, apiPort + 100) })
if (gatewayPort !== freeGatewayPort || apiPort !== freeApiPort) {
log(`updating config to available ports: api: ${freeApiPort}, gateway: ${freeGatewayPort}`)
const addrs = ipfsNodeConfig.config.Addresses
addrs.Gateway = addrs.Gateway.replace(gatewayPort.toString(), freeGatewayPort.toString())
addrs.API = addrs.API.replace(apiPort.toString(), freeApiPort.toString())
}

return ipfsNodeConfig
}

exports.init = async function init (opts) {
log('init embedded:chromesockets')

const ipfsOpts = await buildConfig(opts)
log('creating js-ipfs with opts: ', ipfsOpts)
node = new Ipfs(ipfsOpts)

Expand Down Expand Up @@ -90,9 +110,9 @@ async function updateConfigWithHttpEndpoints (ipfs, opts) {
ipfsApiUrl: httpApi,
ipfsNodeConfig: JSON.stringify(ipfsNodeConfig, null, 2)
}
// update current runtime config (in place, effective without restart)
// update current runtime config (in place)
Object.assign(opts, configChanges)
// update user config in storage (effective on next run)
// update user config in storage (triggers async client restart if ports changed)
log(`synchronizing ipfsNodeConfig with customGatewayUrl (${configChanges.customGatewayUrl}) and ipfsApiUrl (${configChanges.ipfsApiUrl})`)
await browser.storage.local.set(configChanges)
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
"drag-and-drop-files": "0.0.1",
"file-type": "12.0.1",
"filesize": "4.1.2",
"get-port": "5.0.0",
"http-dns": "3.0.1",
"http-node": "1.2.0",
"ipfs": "https://github.com/ipfs/js-ipfs/tarball/2ae6b672c222555b1a068141f2acfe4b5f39b709/js-ipfs.tar.gz",
Expand Down
7 changes: 7 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5786,6 +5786,13 @@ get-iterator@^1.0.2:
resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-1.0.2.tgz#cd747c02b4c084461fac14f48f6b45a80ed25c82"
integrity sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==

get-port@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.0.0.tgz#aa22b6b86fd926dd7884de3e23332c9f70c031a6"
integrity sha512-imzMU0FjsZqNa6BqOjbbW6w5BivHIuQKopjpPqcnx0AVHJQKCxK1O+Ab3OrVXhrekqfVMjwA9ZYu062R+KcIsQ==
dependencies:
type-fest "^0.3.0"

get-port@^4.0.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119"
Expand Down

0 comments on commit b48e643

Please sign in to comment.