DNS support (#56)

* feat: dns support
This commit is contained in:
David Dias 2017-03-23 15:09:06 +00:00 committed by GitHub
parent ec467377e6
commit bdfd042ace
6 changed files with 173 additions and 45 deletions

View File

@ -4,25 +4,22 @@ const connect = require('pull-ws/client')
const mafmt = require('mafmt')
const includes = require('lodash.includes')
const Connection = require('interface-connection').Connection
const maToUrl = require('./ma-to-url')
const debug = require('debug')
const log = debug('libp2p:websockets:dialer')
const createListener = require('./listener')
module.exports = class WebSockets {
class WebSockets {
dial (ma, options, callback) {
if (typeof options === 'function') {
callback = options
options = {}
}
if (!callback) {
callback = () => {}
}
callback = callback || function () {}
const maOpts = ma.toOptions()
const url = `ws://${maOpts.host}:${maOpts.port}`
const url = maToUrl(ma)
log('dialing %s', url)
const socket = connect(url, {
binary: true,
@ -30,8 +27,8 @@ module.exports = class WebSockets {
})
const conn = new Connection(socket)
conn.getObservedAddrs = (cb) => cb(null, [ma])
conn.close = (cb) => socket.close(cb)
conn.getObservedAddrs = (callback) => callback(null, [ma])
conn.close = (callback) => socket.close(callback)
return conn
}
@ -54,7 +51,9 @@ module.exports = class WebSockets {
if (includes(ma.protoNames(), 'ipfs')) {
ma = ma.decapsulate('ipfs')
}
return mafmt.WebSockets.matches(ma)
return mafmt.WebSockets.matches(ma) || mafmt.WebSocketsSecure.matches(ma)
})
}
}
module.exports = WebSockets

View File

@ -2,20 +2,14 @@
const Connection = require('interface-connection').Connection
const includes = require('lodash.includes')
// const IPFS_CODE = 421
let createServer = require('pull-ws/server')
if (!createServer) {
createServer = () => {}
}
function noop () {}
const createServer = require('pull-ws/server') || noop
module.exports = (options, handler) => {
const listener = createServer((socket) => {
socket.getObservedAddrs = (cb) => {
socket.getObservedAddrs = (callback) => {
// TODO research if we can reuse the address in anyway
return cb(null, [])
return callback(null, [])
}
handler(new Connection(socket))
@ -24,19 +18,19 @@ module.exports = (options, handler) => {
let listeningMultiaddr
listener._listen = listener.listen
listener.listen = (ma, cb) => {
cb = cb || (() => {})
listener.listen = (ma, callback) => {
callback = callback || noop
listeningMultiaddr = ma
if (includes(ma.protoNames(), 'ipfs')) {
ma = ma.decapsulate('ipfs')
}
listener._listen(ma.toOptions(), cb)
listener._listen(ma.toOptions(), callback)
}
listener.getAddrs = (cb) => {
cb(null, [listeningMultiaddr])
listener.getAddrs = (callback) => {
callback(null, [listeningMultiaddr])
}
return listener

22
src/ma-to-url.js Normal file
View File

@ -0,0 +1,22 @@
'use strict'
const multiaddr = require('multiaddr')
function maToUrl (ma) {
const maStrSplit = ma.toString().split('/')
const proto = ma.protos()[2].name
if (!(proto === 'ws' || proto === 'wss')) {
throw new Error('invalid multiaddr' + ma.toString())
}
let url = ma.protos()[2].name + '://' + maStrSplit[2]
if (!multiaddr.isName(ma)) {
url += ':' + maStrSplit[4]
}
return url
}
module.exports = maToUrl

View File

@ -3,21 +3,22 @@
const tests = require('interface-transport')
const multiaddr = require('multiaddr')
const Ws = require('../src')
const WS = require('../src')
describe('compliance', () => {
tests({
setup (cb) {
let ws = new Ws()
setup (callback) {
let ws = new WS()
const addrs = [
multiaddr('/ip4/127.0.0.1/tcp/9091/ws'),
multiaddr('/ip4/127.0.0.1/tcp/9092/ws'),
multiaddr('/ip4/127.0.0.1/tcp/9093/ws')
multiaddr('/ip4/127.0.0.1/tcp/9092/wss')
// multiaddr('/dns4/awesome-dns-server.com/tcp/9092/ws'),
// multiaddr('/dns4/awesome-dns-server.com/tcp/9092/wss')
]
cb(null, ws, addrs)
callback(null, ws, addrs)
},
teardown (cb) {
cb()
teardown (callback) {
callback()
}
})
})

View File

@ -30,6 +30,7 @@ describe('listen', () => {
it('listen, check for callback', (done) => {
const listener = ws.createListener((conn) => {})
listener.listen(ma, () => {
listener.close(done)
})
@ -37,24 +38,30 @@ describe('listen', () => {
it('listen, check for listening event', (done) => {
const listener = ws.createListener((conn) => {})
listener.on('listening', () => {
listener.close(done)
})
listener.listen(ma)
})
it('listen, check for the close event', (done) => {
const listener = ws.createListener((conn) => {})
listener.on('listening', () => {
listener.on('close', done)
listener.close()
})
listener.listen(ma)
})
it('listen on addr with /ipfs/QmHASH', (done) => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const listener = ws.createListener((conn) => {})
listener.listen(ma, () => {
listener.close(done)
})
@ -77,7 +84,8 @@ describe('listen', () => {
})
it('getAddrs', (done) => {
const listener = ws.createListener((conn) => {})
const listener = ws.createListener((conn) => {
})
listener.listen(ma, () => {
listener.getAddrs((err, addrs) => {
expect(err).to.not.exist()
@ -104,6 +112,7 @@ describe('listen', () => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const listener = ws.createListener((conn) => {})
listener.listen(ma, () => {
listener.getAddrs((err, addrs) => {
expect(err).to.not.exist()
@ -177,17 +186,120 @@ describe('filter addrs', () => {
ws = new WS()
})
it('filter valid addrs for this transport', (done) => {
const mh1 = multiaddr('/ip4/127.0.0.1/tcp/9090')
const mh2 = multiaddr('/ip4/127.0.0.1/udp/9090')
const mh3 = multiaddr('/ip4/127.0.0.1/tcp/9090/ws')
const mh4 = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
describe('filter valid addrs for this transport', function () {
it('should fail invalid WS addresses', function () {
const ma1 = multiaddr('/ip4/127.0.0.1/tcp/9090')
const ma2 = multiaddr('/ip4/127.0.0.1/udp/9090')
const ma3 = multiaddr('/ip6/::1/tcp/80')
const ma4 = multiaddr('/dns/ipfs.io/tcp/80')
const valid = ws.filter([mh1, mh2, mh3, mh4])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(mh3)
expect(valid[1]).to.deep.equal(mh4)
done()
const valid = ws.filter([ma1, ma2, ma3, ma4])
expect(valid.length).to.equal(0)
})
it('should filter correct ipv4 addresses', function () {
const ma1 = multiaddr('/ip4/127.0.0.1/tcp/80/ws')
const ma2 = multiaddr('/ip4/127.0.0.1/tcp/443/wss')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct ipv4 addresses with ipfs id', function () {
const ma1 = multiaddr('/ip4/127.0.0.1/tcp/80/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const ma2 = multiaddr('/ip4/127.0.0.1/tcp/80/wss/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct ipv6 address', function () {
const ma1 = multiaddr('/ip6/::1/tcp/80/ws')
const ma2 = multiaddr('/ip6/::1/tcp/443/wss')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct ipv6 addresses with ipfs id', function () {
const ma1 = multiaddr('/ip6/::1/tcp/80/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const ma2 = multiaddr('/ip6/::1/tcp/443/wss/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct dns address', function () {
const ma1 = multiaddr('/dns/ipfs.io/ws')
const ma2 = multiaddr('/dns/ipfs.io/tcp/80/ws')
const ma3 = multiaddr('/dns/ipfs.io/tcp/80/wss')
const valid = ws.filter([ma1, ma2, ma3])
expect(valid.length).to.equal(3)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
expect(valid[2]).to.deep.equal(ma3)
})
it('should filter correct dns address with ipfs id', function () {
const ma1 = multiaddr('/dns/ipfs.io/tcp/80/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const ma2 = multiaddr('/dns/ipfs.io/tcp/443/wss/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct dns4 address', function () {
const ma1 = multiaddr('/dns4/ipfs.io/tcp/80/ws')
const ma2 = multiaddr('/dns4/ipfs.io/tcp/443/wss')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct dns6 address', function () {
const ma1 = multiaddr('/dns6/ipfs.io/tcp/80/ws')
const ma2 = multiaddr('/dns6/ipfs.io/tcp/443/wss')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter correct dns6 address with ipfs id', function () {
const ma1 = multiaddr('/dns6/ipfs.io/tcp/80/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const ma2 = multiaddr('/dns6/ipfs.io/tcp/443/wss/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const valid = ws.filter([ma1, ma2])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma2)
})
it('should filter mixed addresses', function () {
const ma1 = multiaddr('/dns6/ipfs.io/tcp/80/ws/ipfs/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
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 valid = ws.filter([ma1, ma2, ma3, ma4])
expect(valid.length).to.equal(2)
expect(valid[0]).to.deep.equal(ma1)
expect(valid[1]).to.deep.equal(ma4)
})
})
it('filter a single addr for this transport', (done) => {