diff --git a/.aegir.js b/.aegir.js index 9953ffa..f43cfb2 100644 --- a/.aegir.js +++ b/.aegir.js @@ -1,3 +1,5 @@ +'use strict' + const multiaddr = require('multiaddr') const pull = require('pull-stream') @@ -5,18 +7,22 @@ const WS = require('./src') let listener +function boot (done) { + const ws = new WS() + const ma = multiaddr('/ip4/127.0.0.1/tcp/9095/ws') + listener = ws.createListener((conn) => pull(conn, conn)) + listener.listen(ma, done) +} + +function shutdown (done) { + listener.close(done) +} + module.exports = { hooks: { browser: { - pre (callback) { - const ws = new WS() - const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws') - listener = ws.createListener((conn) => pull(conn, conn)) - listener.listen(ma, callback) - }, - post (callback) { - listener.close(callback) - } + pre: boot, + post: shutdown } } } diff --git a/.travis.yml b/.travis.yml index 8c39794..584f308 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,21 +4,17 @@ language: node_js matrix: include: - node_js: 6 - env: - - SAUCE=true - - CXX=g++-4.8 - - node_js: "stable" - env: - - CXX=g++-4.8 - -# Make sure we have new NPM. -before_install: - - npm install -g npm + env: CXX=g++-4.8 + - node_js: 8 + env: CXX=g++-4.8 + # - node_js: stable + # env: CXX=g++-4.8 script: - npm run lint - - npm test + - npm run test - npm run coverage + - make test before_script: - export DISPLAY=:99.0 @@ -28,7 +24,7 @@ after_success: - npm run coverage-publish addons: - firefox: latest + firefox: 'latest' apt: sources: - ubuntu-toolchain-r-test diff --git a/circle.yml b/circle.yml index 56f7efb..a0da9bc 100644 --- a/circle.yml +++ b/circle.yml @@ -6,8 +6,12 @@ dependencies: pre: - google-chrome --version - curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb + - for v in $(curl http://archive.ubuntu.com/ubuntu/pool/main/n/nss/ | grep "href=" | grep "libnss3.*deb\"" -o | grep -o "libnss3.*deb" | grep "3.28" | grep "14.04"); do curl -L -o $v http://archive.ubuntu.com/ubuntu/pool/main/n/nss/$v; done && rm libnss3-tools*_i386.deb libnss3-dev*_i386.deb - sudo dpkg -i google-chrome.deb || true + - sudo dpkg -i libnss3*.deb || true - sudo apt-get update + - sudo apt-get install -f || true + - sudo dpkg -i libnss3*.deb - sudo apt-get install -f - sudo apt-get install --only-upgrade lsb-base - sudo dpkg -i google-chrome.deb diff --git a/package.json b/package.json index 27b7817..1dc8afa 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,15 @@ "main": "src/index.js", "scripts": { "lint": "aegir lint", - "test": "aegir test", - "test:node": "aegir test --target=node", - "test:browser": "aegir test --target=browser", "build": "aegir build", - "release": "aegir release", - "release-minor": "aegir release --type minor", - "release-major": "aegir release --type major", + "test": "aegir test --target node --target browser --no-parallel", + "test:node": "aegir test --target node", + "test:browser": "aegir test --target browser --no-parallel", + "release": "aegir test release --target node --target browser --no-parallel", + "release-minor": "aegir release --type minor --target node --target browser", + "release-major": "aegir release --type major --target node --target browser", "coverage": "aegir coverage", - "coverage-publish": "aegir coverage --upload" + "coverage-publish": "aegir coverage --provider coveralls" }, "browser": { "pull-ws/server": false @@ -39,10 +39,10 @@ "interface-connection": "~0.3.2", "lodash.includes": "^4.3.0", "mafmt": "^3.0.1", - "pull-ws": "^3.2.9" + "pull-ws": "^3.3.0" }, "devDependencies": { - "aegir": "github:ipfs/aegir", + "aegir": "^12.0.8", "chai": "^4.1.1", "dirty-chai": "^2.0.1", "gulp": "^3.9.1", @@ -50,8 +50,7 @@ "multiaddr": "^3.0.1", "pre-commit": "^1.2.2", "pull-goodbye": "0.0.2", - "pull-stream": "^3.6.0", - "safe-buffer": "^5.1.1" + "pull-stream": "^3.6.1" }, "contributors": [ "Chris Campbell ", diff --git a/src/index.js b/src/index.js index ba6394a..4dd95fa 100644 --- a/src/index.js +++ b/src/index.js @@ -51,10 +51,16 @@ class WebSockets { } return multiaddrs.filter((ma) => { + if (includes(ma.protoNames(), 'p2p-circuit')) { + return false + } + if (includes(ma.protoNames(), 'ipfs')) { ma = ma.decapsulate('ipfs') } - return mafmt.WebSockets.matches(ma) || mafmt.WebSocketsSecure.matches(ma) + + return mafmt.WebSockets.matches(ma) || + mafmt.WebSocketsSecure.matches(ma) }) } } diff --git a/src/listener.js b/src/listener.js index e2cf9aa..924a8f2 100644 --- a/src/listener.js +++ b/src/listener.js @@ -2,7 +2,11 @@ const Connection = require('interface-connection').Connection const includes = require('lodash.includes') +const multiaddr = require('multiaddr') +const os = require('os') + function noop () {} + const createServer = require('pull-ws/server') || noop module.exports = (options, handler) => { @@ -30,7 +34,39 @@ module.exports = (options, handler) => { } listener.getAddrs = (callback) => { - callback(null, [listeningMultiaddr]) + const multiaddrs = [] + const address = listener.address() + + if (!address) { + return callback(new Error('Listener is not ready yet')) + } + + let ipfsId = listeningMultiaddr.getPeerId() + + // Because TCP will only return the IPv6 version + // we need to capture from the passed multiaddr + if (listeningMultiaddr.toString().indexOf('ip4') !== -1) { + let m = listeningMultiaddr.decapsulate('tcp') + m = m.encapsulate('/tcp/' + address.port + '/ws') + if (listeningMultiaddr.getPeerId()) { + m = m.encapsulate('/ipfs/' + ipfsId) + } + + if (m.toString().indexOf('0.0.0.0') !== -1) { + const netInterfaces = os.networkInterfaces() + Object.keys(netInterfaces).forEach((niKey) => { + netInterfaces[niKey].forEach((ni) => { + if (ni.family === 'IPv4') { + multiaddrs.push(multiaddr(m.toString().replace('0.0.0.0', ni.address))) + } + }) + }) + } else { + multiaddrs.push(m) + } + } + + callback(null, multiaddrs) } return listener diff --git a/test/browser.js b/test/browser.js index c210f3c..7deecf6 100644 --- a/test/browser.js +++ b/test/browser.js @@ -13,7 +13,7 @@ const goodbye = require('pull-goodbye') const WS = require('../src') describe('libp2p-websockets', () => { - const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws') + const ma = multiaddr('/ip4/127.0.0.1/tcp/9095/ws') let ws let conn @@ -56,7 +56,8 @@ describe('libp2p-websockets', () => { pull(s, conn, s) }) - it('many writes', (done) => { + it('many writes', function (done) { + this.timeout(10000) const s = goodbye({ source: pull( pull.infinite(), diff --git a/test/node.js b/test/node.js index 19875fb..5222382 100644 --- a/test/node.js +++ b/test/node.js @@ -1,4 +1,5 @@ /* eslint-env mocha */ +/* eslint max-nested-callbacks: ["error", 5] */ 'use strict' const chai = require('chai') @@ -97,16 +98,45 @@ describe('listen', () => { }) }) - it.skip('getAddrs on port 0 listen', (done) => { - // TODO port 0 not supported yet + it('getAddrs on port 0 listen', (done) => { + const addr = multiaddr(`/ip4/127.0.0.1/tcp/0/ws`) + const listener = ws.createListener((conn) => { + }) + listener.listen(addr, () => { + listener.getAddrs((err, addrs) => { + expect(err).to.not.exist() + expect(addrs.length).to.equal(1) + expect(addrs.map((a) => a.toOptions().port)).to.not.include('0') + listener.close(done) + }) + }) }) - it.skip('getAddrs from listening on 0.0.0.0', (done) => { - // TODO 0.0.0.0 not supported yet + it('getAddrs from listening on 0.0.0.0', (done) => { + const addr = multiaddr(`/ip4/0.0.0.0/tcp/9003/ws`) + const listener = ws.createListener((conn) => { + }) + listener.listen(addr, () => { + listener.getAddrs((err, addrs) => { + expect(err).to.not.exist() + expect(addrs.map((a) => a.toOptions().host)).to.not.include('0.0.0.0') + listener.close(done) + }) + }) }) - it.skip('getAddrs from listening on 0.0.0.0 and port 0', (done) => { - // TODO 0.0.0.0 or port 0 not supported yet + it('getAddrs from listening on 0.0.0.0 and port 0', (done) => { + const addr = multiaddr(`/ip4/0.0.0.0/tcp/0/ws`) + const listener = ws.createListener((conn) => { + }) + listener.listen(addr, () => { + listener.getAddrs((err, addrs) => { + expect(err).to.not.exist() + expect(addrs.map((a) => a.toOptions().host)).to.not.include('0.0.0.0') + expect(addrs.map((a) => a.toOptions().port)).to.not.include('0') + listener.close(done) + }) + }) }) it('getAddrs preserves IPFS Id', (done) => { @@ -128,7 +158,7 @@ describe('listen', () => { describe('dial', () => { let ws let listener - const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws') + const ma = multiaddr('/ip4/127.0.0.1/tcp/9091/ws') beforeEach((done) => { ws = new WS() @@ -163,7 +193,7 @@ describe('dial', () => { }) it('dial on IPv4 with IPFS Id', (done) => { - const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw') + const ma = multiaddr('/ip4/127.0.0.1/tcp/9091/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw') const conn = ws.dial(ma) const s = goodbye({ @@ -295,8 +325,10 @@ describe('filter addrs', () => { const ma2 = multiaddr('/ip4/127.0.0.1/tcp/9090') const ma3 = multiaddr('/ip4/127.0.0.1/udp/9090') const ma4 = multiaddr('/dns6/ipfs.io/ws') + const mh5 = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw' + + '/p2p-circuit/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw') - const valid = ws.filter([ma1, ma2, ma3, ma4]) + const valid = ws.filter([ma1, ma2, ma3, ma4, mh5]) expect(valid.length).to.equal(2) expect(valid[0]).to.deep.equal(ma1) expect(valid[1]).to.deep.equal(ma4) @@ -314,7 +346,7 @@ describe('filter addrs', () => { }) describe('valid Connection', () => { - const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws') + const ma = multiaddr('/ip4/127.0.0.1/tcp/9092/ws') it('get observed addrs', (done) => { let dialerObsAddrs @@ -348,6 +380,7 @@ describe('valid Connection', () => { listenerObsAddrs = addrs listener.close(onClose) + function onClose () { expect(listenerObsAddrs[0]).to.deep.equal(ma) expect(dialerObsAddrs.length).to.equal(0) @@ -405,6 +438,7 @@ describe('valid Connection', () => { }) listener.listen(ma, onListen) + function onListen () { const conn = ws.dial(ma) conn.setPeerInfo('b')