0.2.0 - Mid migration

This commit is contained in:
Daniel Mason 2022-04-25 14:47:15 +12:00
parent 139e6a915e
commit 7e38fdbd7d
42393 changed files with 5358157 additions and 62 deletions

1
web/node_modules/bonjour/.npmignore generated vendored Normal file
View file

@ -0,0 +1 @@
node_modules

10
web/node_modules/bonjour/.travis.yml generated vendored Normal file
View file

@ -0,0 +1,10 @@
language: node_js
os:
- linux
- osx
node_js:
- '6'
- '5'
- '4'
- '0.12'
- '0.10'

21
web/node_modules/bonjour/LICENSE generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015-2016 Thomas Watson Steen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

181
web/node_modules/bonjour/README.md generated vendored Normal file
View file

@ -0,0 +1,181 @@
# bonjour
A Bonjour/Zeroconf protocol implementation in pure JavaScript. Publish
services on the local network or discover existing services using
multicast DNS.
[![Build status](https://travis-ci.org/watson/bonjour.svg?branch=master)](https://travis-ci.org/watson/bonjour)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)
## Installation
```
npm install bonjour
```
## Usage
```js
var bonjour = require('bonjour')()
// advertise an HTTP server on port 3000
bonjour.publish({ name: 'My Web Server', type: 'http', port: 3000 })
// browse for all http services
bonjour.find({ type: 'http' }, function (service) {
console.log('Found an HTTP server:', service)
})
```
## API
### Initializing
```js
var bonjour = require('bonjour')([options])
```
The `options` are optional and will be used when initializing the
underlying multicast-dns server. For details see [the multicast-dns
documentation](https://github.com/mafintosh/multicast-dns#mdns--multicastdnsoptions).
### Publishing
#### `var service = bonjour.publish(options)`
Publishes a new service.
Options are:
- `name` (string)
- `host` (string, optional) - defaults to local hostname
- `port` (number)
- `type` (string)
- `subtypes` (array of strings, optional)
- `protocol` (string, optional) - `udp` or `tcp` (default)
- `txt` (object, optional) - a key/value object to broadcast as the TXT
record
IANA maintains a [list of official service types and port
numbers](http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml).
#### `bonjour.unpublishAll([callback])`
Unpublish all services. The optional `callback` will be called when the
services have been unpublished.
#### `bonjour.destroy()`
Destroy the mdns instance. Closes the udp socket.
### Browser
#### `var browser = bonjour.find(options[, onup])`
Listen for services advertised on the network. An optional callback can
be provided as the 2nd argument and will be added as an event listener
for the `up` event.
Options (all optional):
- `type` (string)
- `subtypes` (array of strings)
- `protocol` (string) - defaults to `tcp`
- `txt` (object) - passed into [dns-txt
module](https://github.com/watson/dns-txt) contructor. Set to `{
binary: true }` if you want to keep the TXT records in binary
#### `var browser = bonjour.findOne(options[, callback])`
Listen for and call the `callback` with the first instance of a service
matching the `options`. If no `callback` is given, it's expected that
you listen for the `up` event. The returned `browser` will automatically
stop it self after the first matching service.
Options are the same as given in the `browser.find` function.
#### `Event: up`
Emitted every time a new service is found that matches the browser.
#### `Event: down`
Emitted every time an existing service emmits a goodbye message.
#### `browser.services`
An array of services known by the browser to be online.
#### `browser.start()`
Start looking for matching services.
#### `browser.stop()`
Stop looking for matching services.
#### `browser.update()`
Broadcast the query again.
### Service
#### `Event: up`
Emitted when the service is up.
#### `Event: error`
Emitted if an error occurrs while publishing the service.
#### `service.stop([callback])`
Unpublish the service. The optional `callback` will be called when the
service have been unpublished.
#### `service.start()`
Publish the service.
#### `service.name`
The name of the service, e.g. `Apple TV`.
#### `service.type`
The type of the service, e.g. `http`.
#### `service.subtypes`
An array of subtypes. Note that this property might be `null`.
#### `service.protocol`
The protocol used by the service, e.g. `tcp`.
#### `service.host`
The hostname or ip address where the service resides.
#### `service.port`
The port on which the service listens, e.g. `5000`.
#### `service.fqdn`
The fully qualified domain name of the service. E.g. if given the name
`Foo Bar`, the type `http` and the protocol `tcp`, the `service.fqdn`
property will be `Foo Bar._http._tcp.local`.
#### `service.txt`
The TXT record advertised by the service (a key/value object). Note that
this property might be `null`.
#### `service.published`
A boolean indicating if the service is currently published.
## License
MIT

39
web/node_modules/bonjour/index.js generated vendored Normal file
View file

@ -0,0 +1,39 @@
'use strict'
var Registry = require('./lib/registry')
var Server = require('./lib/mdns-server')
var Browser = require('./lib/browser')
module.exports = Bonjour
function Bonjour (opts) {
if (!(this instanceof Bonjour)) return new Bonjour(opts)
this._server = new Server(opts)
this._registry = new Registry(this._server)
}
Bonjour.prototype.publish = function (opts) {
return this._registry.publish(opts)
}
Bonjour.prototype.unpublishAll = function (cb) {
this._registry.unpublishAll(cb)
}
Bonjour.prototype.find = function (opts, onup) {
return new Browser(this._server.mdns, opts, onup)
}
Bonjour.prototype.findOne = function (opts, cb) {
var browser = new Browser(this._server.mdns, opts)
browser.once('up', function (service) {
browser.stop()
if (cb) cb(service)
})
return browser
}
Bonjour.prototype.destroy = function () {
this._registry.destroy()
this._server.mdns.destroy()
}

198
web/node_modules/bonjour/lib/browser.js generated vendored Normal file
View file

@ -0,0 +1,198 @@
'use strict'
var util = require('util')
var EventEmitter = require('events').EventEmitter
var serviceName = require('multicast-dns-service-types')
var dnsEqual = require('dns-equal')
var dnsTxt = require('dns-txt')
var TLD = '.local'
var WILDCARD = '_services._dns-sd._udp' + TLD
module.exports = Browser
util.inherits(Browser, EventEmitter)
/**
* Start a browser
*
* The browser listens for services by querying for PTR records of a given
* type, protocol and domain, e.g. _http._tcp.local.
*
* If no type is given, a wild card search is performed.
*
* An internal list of online services is kept which starts out empty. When
* ever a new service is discovered, it's added to the list and an "up" event
* is emitted with that service. When it's discovered that the service is no
* longer available, it is removed from the list and a "down" event is emitted
* with that service.
*/
function Browser (mdns, opts, onup) {
if (typeof opts === 'function') return new Browser(mdns, null, opts)
EventEmitter.call(this)
this._mdns = mdns
this._onresponse = null
this._serviceMap = {}
this._txt = dnsTxt(opts.txt)
if (!opts || !opts.type) {
this._name = WILDCARD
this._wildcard = true
} else {
this._name = serviceName.stringify(opts.type, opts.protocol || 'tcp') + TLD
if (opts.name) this._name = opts.name + '.' + this._name
this._wildcard = false
}
this.services = []
if (onup) this.on('up', onup)
this.start()
}
Browser.prototype.start = function () {
if (this._onresponse) return
var self = this
// List of names for the browser to listen for. In a normal search this will
// be the primary name stored on the browser. In case of a wildcard search
// the names will be determined at runtime as responses come in.
var nameMap = {}
if (!this._wildcard) nameMap[this._name] = true
this._onresponse = function (packet, rinfo) {
if (self._wildcard) {
packet.answers.forEach(function (answer) {
if (answer.type !== 'PTR' || answer.name !== self._name || answer.name in nameMap) return
nameMap[answer.data] = true
self._mdns.query(answer.data, 'PTR')
})
}
Object.keys(nameMap).forEach(function (name) {
// unregister all services shutting down
goodbyes(name, packet).forEach(self._removeService.bind(self))
// register all new services
var matches = buildServicesFor(name, packet, self._txt, rinfo)
if (matches.length === 0) return
matches.forEach(function (service) {
if (self._serviceMap[service.fqdn]) return // ignore already registered services
self._addService(service)
})
})
}
this._mdns.on('response', this._onresponse)
this.update()
}
Browser.prototype.stop = function () {
if (!this._onresponse) return
this._mdns.removeListener('response', this._onresponse)
this._onresponse = null
}
Browser.prototype.update = function () {
this._mdns.query(this._name, 'PTR')
}
Browser.prototype._addService = function (service) {
this.services.push(service)
this._serviceMap[service.fqdn] = true
this.emit('up', service)
}
Browser.prototype._removeService = function (fqdn) {
var service, index
this.services.some(function (s, i) {
if (dnsEqual(s.fqdn, fqdn)) {
service = s
index = i
return true
}
})
if (!service) return
this.services.splice(index, 1)
delete this._serviceMap[fqdn]
this.emit('down', service)
}
// PTR records with a TTL of 0 is considered a "goodbye" announcement. I.e. a
// DNS response broadcasted when a service shuts down in order to let the
// network know that the service is no longer going to be available.
//
// For more info see:
// https://tools.ietf.org/html/rfc6762#section-8.4
//
// This function returns an array of all resource records considered a goodbye
// record
function goodbyes (name, packet) {
return packet.answers.concat(packet.additionals)
.filter(function (rr) {
return rr.type === 'PTR' && rr.ttl === 0 && dnsEqual(rr.name, name)
})
.map(function (rr) {
return rr.data
})
}
function buildServicesFor (name, packet, txt, referer) {
var records = packet.answers.concat(packet.additionals).filter(function (rr) {
return rr.ttl > 0 // ignore goodbye messages
})
return records
.filter(function (rr) {
return rr.type === 'PTR' && dnsEqual(rr.name, name)
})
.map(function (ptr) {
var service = {
addresses: []
}
records
.filter(function (rr) {
return (rr.type === 'SRV' || rr.type === 'TXT') && dnsEqual(rr.name, ptr.data)
})
.forEach(function (rr) {
if (rr.type === 'SRV') {
var parts = rr.name.split('.')
var name = parts[0]
var types = serviceName.parse(parts.slice(1, -1).join('.'))
service.name = name
service.fqdn = rr.name
service.host = rr.data.target
service.referer = referer
service.port = rr.data.port
service.type = types.name
service.protocol = types.protocol
service.subtypes = types.subtypes
} else if (rr.type === 'TXT') {
service.rawTxt = rr.data
service.txt = txt.decode(rr.data)
}
})
if (!service.name) return
records
.filter(function (rr) {
return (rr.type === 'A' || rr.type === 'AAAA') && dnsEqual(rr.name, service.host)
})
.forEach(function (rr) {
service.addresses.push(rr.data)
})
return service
})
.filter(function (rr) {
return !!rr
})
}

116
web/node_modules/bonjour/lib/mdns-server.js generated vendored Normal file
View file

@ -0,0 +1,116 @@
'use strict'
var multicastdns = require('multicast-dns')
var dnsEqual = require('dns-equal')
var flatten = require('array-flatten')
var deepEqual = require('deep-equal')
module.exports = Server
function Server (opts) {
this.mdns = multicastdns(opts)
this.mdns.setMaxListeners(0)
this.registry = {}
this.mdns.on('query', this._respondToQuery.bind(this))
}
Server.prototype.register = function (records) {
var self = this
if (Array.isArray(records)) records.forEach(register)
else register(records)
function register (record) {
var subRegistry = self.registry[record.type]
if (!subRegistry) subRegistry = self.registry[record.type] = []
else if (subRegistry.some(isDuplicateRecord(record))) return
subRegistry.push(record)
}
}
Server.prototype.unregister = function (records) {
var self = this
if (Array.isArray(records)) records.forEach(unregister)
else unregister(records)
function unregister (record) {
var type = record.type
if (!(type in self.registry)) return
self.registry[type] = self.registry[type].filter(function (r) {
return r.name !== record.name
})
}
}
Server.prototype._respondToQuery = function (query) {
var self = this
query.questions.forEach(function (question) {
var type = question.type
var name = question.name
// generate the answers section
var answers = type === 'ANY'
? flatten.depth(Object.keys(self.registry).map(self._recordsFor.bind(self, name)), 1)
: self._recordsFor(name, type)
if (answers.length === 0) return
// generate the additionals section
var additionals = []
if (type !== 'ANY') {
answers.forEach(function (answer) {
if (answer.type !== 'PTR') return
additionals = additionals
.concat(self._recordsFor(answer.data, 'SRV'))
.concat(self._recordsFor(answer.data, 'TXT'))
})
// to populate the A and AAAA records, we need to get a set of unique
// targets from the SRV record
additionals
.filter(function (record) {
return record.type === 'SRV'
})
.map(function (record) {
return record.data.target
})
.filter(unique())
.forEach(function (target) {
additionals = additionals
.concat(self._recordsFor(target, 'A'))
.concat(self._recordsFor(target, 'AAAA'))
})
}
self.mdns.respond({ answers: answers, additionals: additionals }, function (err) {
if (err) throw err // TODO: Handle this (if no callback is given, the error will be ignored)
})
})
}
Server.prototype._recordsFor = function (name, type) {
if (!(type in this.registry)) return []
return this.registry[type].filter(function (record) {
var _name = ~name.indexOf('.') ? record.name : record.name.split('.')[0]
return dnsEqual(_name, name)
})
}
function isDuplicateRecord (a) {
return function (b) {
return a.type === b.type &&
a.name === b.name &&
deepEqual(a.data, b.data)
}
}
function unique () {
var set = []
return function (obj) {
if (~set.indexOf(obj)) return false
set.push(obj)
return true
}
}

189
web/node_modules/bonjour/lib/registry.js generated vendored Normal file
View file

@ -0,0 +1,189 @@
'use strict'
var dnsEqual = require('dns-equal')
var flatten = require('array-flatten')
var Service = require('./service')
var REANNOUNCE_MAX_MS = 60 * 60 * 1000
var REANNOUNCE_FACTOR = 3
module.exports = Registry
function Registry (server) {
this._server = server
this._services = []
}
Registry.prototype.publish = function (opts) {
var service = new Service(opts)
service.start = start.bind(service, this)
service.stop = stop.bind(service, this)
service.start({ probe: opts.probe !== false })
return service
}
Registry.prototype.unpublishAll = function (cb) {
teardown(this._server, this._services, cb)
this._services = []
}
Registry.prototype.destroy = function () {
this._services.forEach(function (service) {
service._destroyed = true
})
}
function start (registry, opts) {
if (this._activated) return
this._activated = true
registry._services.push(this)
if (opts.probe) {
var service = this
probe(registry._server.mdns, this, function (exists) {
if (exists) {
service.stop()
service.emit('error', new Error('Service name is already in use on the network'))
return
}
announce(registry._server, service)
})
} else {
announce(registry._server, this)
}
}
function stop (registry, cb) {
if (!this._activated) return // TODO: What about the callback?
teardown(registry._server, this, cb)
var index = registry._services.indexOf(this)
if (index !== -1) registry._services.splice(index, 1)
}
/**
* Check if a service name is already in use on the network.
*
* Used before announcing the new service.
*
* To guard against race conditions where multiple services are started
* simultaneously on the network, wait a random amount of time (between
* 0 and 250 ms) before probing.
*
* TODO: Add support for Simultaneous Probe Tiebreaking:
* https://tools.ietf.org/html/rfc6762#section-8.2
*/
function probe (mdns, service, cb) {
var sent = false
var retries = 0
var timer
mdns.on('response', onresponse)
setTimeout(send, Math.random() * 250)
function send () {
// abort if the service have or is being stopped in the meantime
if (!service._activated || service._destroyed) return
mdns.query(service.fqdn, 'ANY', function () {
// This function will optionally be called with an error object. We'll
// just silently ignore it and retry as we normally would
sent = true
timer = setTimeout(++retries < 3 ? send : done, 250)
timer.unref()
})
}
function onresponse (packet) {
// Apparently conflicting Multicast DNS responses received *before*
// the first probe packet is sent MUST be silently ignored (see
// discussion of stale probe packets in RFC 6762 Section 8.2,
// "Simultaneous Probe Tiebreaking" at
// https://tools.ietf.org/html/rfc6762#section-8.2
if (!sent) return
if (packet.answers.some(matchRR) || packet.additionals.some(matchRR)) done(true)
}
function matchRR (rr) {
return dnsEqual(rr.name, service.fqdn)
}
function done (exists) {
mdns.removeListener('response', onresponse)
clearTimeout(timer)
cb(!!exists)
}
}
/**
* Initial service announcement
*
* Used to announce new services when they are first registered.
*
* Broadcasts right away, then after 3 seconds, 9 seconds, 27 seconds,
* and so on, up to a maximum interval of one hour.
*/
function announce (server, service) {
var delay = 1000
var packet = service._records()
server.register(packet)
;(function broadcast () {
// abort if the service have or is being stopped in the meantime
if (!service._activated || service._destroyed) return
server.mdns.respond(packet, function () {
// This function will optionally be called with an error object. We'll
// just silently ignore it and retry as we normally would
if (!service.published) {
service._activated = true
service.published = true
service.emit('up')
}
delay = delay * REANNOUNCE_FACTOR
if (delay < REANNOUNCE_MAX_MS && !service._destroyed) {
setTimeout(broadcast, delay).unref()
}
})
})()
}
/**
* Stop the given services
*
* Besides removing a service from the mDNS registry, a "goodbye"
* message is sent for each service to let the network know about the
* shutdown.
*/
function teardown (server, services, cb) {
if (!Array.isArray(services)) services = [services]
services = services.filter(function (service) {
return service._activated // ignore services not currently starting or started
})
var records = flatten.depth(services.map(function (service) {
service._activated = false
var records = service._records()
records.forEach(function (record) {
record.ttl = 0 // prepare goodbye message
})
return records
}), 1)
if (records.length === 0) return cb && cb()
server.unregister(records)
// send goodbye message
server.mdns.respond(records, function () {
services.forEach(function (service) {
service.published = false
})
if (cb) cb.apply(null, arguments)
})
}

98
web/node_modules/bonjour/lib/service.js generated vendored Normal file
View file

@ -0,0 +1,98 @@
'use strict'
var os = require('os')
var util = require('util')
var EventEmitter = require('events').EventEmitter
var serviceName = require('multicast-dns-service-types')
var txt = require('dns-txt')()
var TLD = '.local'
module.exports = Service
util.inherits(Service, EventEmitter)
function Service (opts) {
if (!opts.name) throw new Error('Required name not given')
if (!opts.type) throw new Error('Required type not given')
if (!opts.port) throw new Error('Required port not given')
this.name = opts.name
this.protocol = opts.protocol || 'tcp'
this.type = serviceName.stringify(opts.type, this.protocol)
this.host = opts.host || os.hostname()
this.port = opts.port
this.fqdn = this.name + '.' + this.type + TLD
this.subtypes = opts.subtypes || null
this.txt = opts.txt || null
this.published = false
this._activated = false // indicates intent - true: starting/started, false: stopping/stopped
}
Service.prototype._records = function () {
var records = [rr_ptr(this), rr_srv(this), rr_txt(this)]
var self = this
var interfaces = os.networkInterfaces()
Object.keys(interfaces).forEach(function (name) {
interfaces[name].forEach(function (addr) {
if (addr.internal) return
if (addr.family === 'IPv4') {
records.push(rr_a(self, addr.address))
} else {
records.push(rr_aaaa(self, addr.address))
}
})
})
return records
}
function rr_ptr (service) {
return {
name: service.type + TLD,
type: 'PTR',
ttl: 28800,
data: service.fqdn
}
}
function rr_srv (service) {
return {
name: service.fqdn,
type: 'SRV',
ttl: 120,
data: {
port: service.port,
target: service.host
}
}
}
function rr_txt (service) {
return {
name: service.fqdn,
type: 'TXT',
ttl: 4500,
data: txt.encode(service.txt)
}
}
function rr_a (service, ip) {
return {
name: service.host,
type: 'A',
ttl: 120,
data: ip
}
}
function rr_aaaa (service, ip) {
return {
name: service.host,
type: 'AAAA',
ttl: 120,
data: ip
}
}

49
web/node_modules/bonjour/package.json generated vendored Normal file
View file

@ -0,0 +1,49 @@
{
"name": "bonjour",
"version": "3.5.0",
"description": "A Bonjour/Zeroconf implementation in pure JavaScript",
"main": "index.js",
"dependencies": {
"array-flatten": "^2.1.0",
"deep-equal": "^1.0.1",
"dns-equal": "^1.0.0",
"dns-txt": "^2.0.2",
"multicast-dns": "^6.0.1",
"multicast-dns-service-types": "^1.1.0"
},
"devDependencies": {
"after-all": "^2.0.2",
"standard": "^6.0.8",
"tape": "^4.5.1"
},
"scripts": {
"test": "standard && tape test/*.js"
},
"repository": {
"type": "git",
"url": "https://github.com/watson/bonjour.git"
},
"keywords": [
"bonjour",
"zeroconf",
"zero",
"configuration",
"mdns",
"dns",
"service",
"discovery",
"multicast",
"broadcast",
"dns-sd"
],
"author": "Thomas Watson Steen <w@tson.dk> (https://twitter.com/wa7son)",
"license": "MIT",
"bugs": {
"url": "https://github.com/watson/bonjour/issues"
},
"homepage": "https://github.com/watson/bonjour",
"coordinates": [
55.68250900965318,
12.586377442991648
]
}

179
web/node_modules/bonjour/test/bonjour.js generated vendored Normal file
View file

@ -0,0 +1,179 @@
'use strict'
var os = require('os')
var dgram = require('dgram')
var tape = require('tape')
var afterAll = require('after-all')
var Service = require('../lib/service')
var Bonjour = require('../')
var getAddresses = function () {
var addresses = []
var itrs = os.networkInterfaces()
for (var i in itrs) {
var addrs = itrs[i]
for (var j in addrs) {
if (addrs[j].internal === false) {
addresses.push(addrs[j].address)
}
}
}
return addresses
}
var port = function (cb) {
var s = dgram.createSocket('udp4')
s.bind(0, function () {
var port = s.address().port
s.on('close', function () {
cb(port)
})
s.close()
})
}
var test = function (name, fn) {
tape(name, function (t) {
port(function (p) {
fn(Bonjour({ ip: '127.0.0.1', port: p, multicast: false }), t)
})
})
}
test('bonjour.publish', function (bonjour, t) {
var service = bonjour.publish({ name: 'foo', type: 'bar', port: 3000 })
t.ok(service instanceof Service)
t.equal(service.published, false)
service.on('up', function () {
t.equal(service.published, true)
bonjour.destroy()
t.end()
})
})
test('bonjour.unpublishAll', function (bonjour, t) {
t.test('published services', function (t) {
var service = bonjour.publish({ name: 'foo', type: 'bar', port: 3000 })
service.on('up', function () {
bonjour.unpublishAll(function (err) {
t.error(err)
t.equal(service.published, false)
bonjour.destroy()
t.end()
})
})
})
t.test('no published services', function (t) {
bonjour.unpublishAll(function (err) {
t.error(err)
t.end()
})
})
})
test('bonjour.find', function (bonjour, t) {
var next = afterAll(function () {
var browser = bonjour.find({ type: 'test' })
var ups = 0
browser.on('up', function (s) {
if (s.name === 'Foo Bar') {
t.equal(s.name, 'Foo Bar')
t.equal(s.fqdn, 'Foo Bar._test._tcp.local')
t.deepEqual(s.txt, {})
t.deepEqual(s.rawTxt, new Buffer('00', 'hex'))
} else {
t.equal(s.name, 'Baz')
t.equal(s.fqdn, 'Baz._test._tcp.local')
t.deepEqual(s.txt, { foo: 'bar' })
t.deepEqual(s.rawTxt, new Buffer('07666f6f3d626172', 'hex'))
}
t.equal(s.host, os.hostname())
t.equal(s.port, 3000)
t.equal(s.type, 'test')
t.equal(s.protocol, 'tcp')
t.equal(s.referer.address, '127.0.0.1')
t.equal(s.referer.family, 'IPv4')
t.ok(Number.isFinite(s.referer.port))
t.ok(Number.isFinite(s.referer.size))
t.deepEqual(s.subtypes, [])
t.deepEqual(s.addresses.sort(), getAddresses().sort())
if (++ups === 2) {
// use timeout in an attempt to make sure the invalid record doesn't
// bubble up
setTimeout(function () {
bonjour.destroy()
t.end()
}, 50)
}
})
})
bonjour.publish({ name: 'Foo Bar', type: 'test', port: 3000 }).on('up', next())
bonjour.publish({ name: 'Invalid', type: 'test2', port: 3000 }).on('up', next())
bonjour.publish({ name: 'Baz', type: 'test', port: 3000, txt: { foo: 'bar' } }).on('up', next())
})
test('bonjour.find - binary txt', function (bonjour, t) {
var next = afterAll(function () {
var browser = bonjour.find({ type: 'test', txt: { binary: true } })
browser.on('up', function (s) {
t.equal(s.name, 'Foo')
t.deepEqual(s.txt, { bar: new Buffer('buz') })
t.deepEqual(s.rawTxt, new Buffer('076261723d62757a', 'hex'))
bonjour.destroy()
t.end()
})
})
bonjour.publish({ name: 'Foo', type: 'test', port: 3000, txt: { bar: new Buffer('buz') } }).on('up', next())
})
test('bonjour.find - down event', function (bonjour, t) {
var service = bonjour.publish({ name: 'Foo Bar', type: 'test', port: 3000 })
service.on('up', function () {
var browser = bonjour.find({ type: 'test' })
browser.on('up', function (s) {
t.equal(s.name, 'Foo Bar')
service.stop()
})
browser.on('down', function (s) {
t.equal(s.name, 'Foo Bar')
bonjour.destroy()
t.end()
})
})
})
test('bonjour.findOne - callback', function (bonjour, t) {
var next = afterAll(function () {
bonjour.findOne({ type: 'test' }, function (s) {
t.equal(s.name, 'Callback')
bonjour.destroy()
t.end()
})
})
bonjour.publish({ name: 'Invalid', type: 'test2', port: 3000 }).on('up', next())
bonjour.publish({ name: 'Callback', type: 'test', port: 3000 }).on('up', next())
})
test('bonjour.findOne - emitter', function (bonjour, t) {
var next = afterAll(function () {
var browser = bonjour.findOne({ type: 'test' })
browser.on('up', function (s) {
t.equal(s.name, 'Emitter')
bonjour.destroy()
t.end()
})
})
bonjour.publish({ name: 'Emitter', type: 'test', port: 3000 }).on('up', next())
bonjour.publish({ name: 'Invalid', type: 'test2', port: 3000 }).on('up', next())
})

92
web/node_modules/bonjour/test/service.js generated vendored Normal file
View file

@ -0,0 +1,92 @@
'use strict'
var os = require('os')
var test = require('tape')
var Service = require('../lib/service')
var getAddressesRecords = function (host) {
var addresses_records = []
var itrs = os.networkInterfaces()
for (var i in itrs) {
var addrs = itrs[i]
for (var j in addrs) {
if (addrs[j].internal === false) {
addresses_records.push({ data: addrs[j].address, name: host, ttl: 120, type: addrs[j].family === 'IPv4' ? 'A' : 'AAAA' })
}
}
}
return addresses_records
}
test('no name', function (t) {
t.throws(function () {
new Service({ type: 'http', port: 3000 }) // eslint-disable-line no-new
}, 'Required name not given')
t.end()
})
test('no type', function (t) {
t.throws(function () {
new Service({ name: 'Foo Bar', port: 3000 }) // eslint-disable-line no-new
}, 'Required type not given')
t.end()
})
test('no port', function (t) {
t.throws(function () {
new Service({ name: 'Foo Bar', type: 'http' }) // eslint-disable-line no-new
}, 'Required port not given')
t.end()
})
test('minimal', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', port: 3000 })
t.equal(s.name, 'Foo Bar')
t.equal(s.protocol, 'tcp')
t.equal(s.type, '_http._tcp')
t.equal(s.host, os.hostname())
t.equal(s.port, 3000)
t.equal(s.fqdn, 'Foo Bar._http._tcp.local')
t.equal(s.txt, null)
t.equal(s.subtypes, null)
t.equal(s.published, false)
t.end()
})
test('protocol', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', port: 3000, protocol: 'udp' })
t.deepEqual(s.protocol, 'udp')
t.end()
})
test('host', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', port: 3000, host: 'example.com' })
t.deepEqual(s.host, 'example.com')
t.end()
})
test('txt', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', port: 3000, txt: { foo: 'bar' } })
t.deepEqual(s.txt, { foo: 'bar' })
t.end()
})
test('_records() - minimal', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', protocol: 'tcp', port: 3000 })
t.deepEqual(s._records(), [
{ data: s.fqdn, name: '_http._tcp.local', ttl: 28800, type: 'PTR' },
{ data: { port: 3000, target: os.hostname() }, name: s.fqdn, ttl: 120, type: 'SRV' },
{ data: new Buffer('00', 'hex'), name: s.fqdn, ttl: 4500, type: 'TXT' }
].concat(getAddressesRecords(s.host)))
t.end()
})
test('_records() - everything', function (t) {
var s = new Service({ name: 'Foo Bar', type: 'http', protocol: 'tcp', port: 3000, host: 'example.com', txt: { foo: 'bar' } })
t.deepEqual(s._records(), [
{ data: s.fqdn, name: '_http._tcp.local', ttl: 28800, type: 'PTR' },
{ data: { port: 3000, target: 'example.com' }, name: s.fqdn, ttl: 120, type: 'SRV' },
{ data: new Buffer('07666f6f3d626172', 'hex'), name: s.fqdn, ttl: 4500, type: 'TXT' }
].concat(getAddressesRecords(s.host)))
t.end()
})