parent
66236e58a9
commit
8ae2dc83c9
9 changed files with 1312 additions and 0 deletions
@ -0,0 +1,13 @@ |
||||
{ |
||||
"name": "wiot-director", |
||||
"version": "0.0.1", |
||||
"description": "Director for wIoT systems.", |
||||
"main": "index.js", |
||||
"repository": "https://wiot.js.org", |
||||
"author": "iotcat", |
||||
"license": "MIT", |
||||
"dependencies": { |
||||
"express": "^4.17.1", |
||||
"log4js": "^6.3.0" |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
data/ |
@ -0,0 +1,59 @@ |
||||
const logger = require(__dirname + '/modules/log.js')(); |
||||
const nodetable = require(__dirname + '/modules/nodetable.js')(logger); |
||||
const node = require(__dirname + '/modules/node.js')(logger, nodetable); |
||||
const ns = require(__dirname + '/modules/ns.js')(logger, node); |
||||
const api = require(__dirname + '/modules/api.js')(logger, node, ns); |
||||
|
||||
|
||||
let OnlineBoard = []; |
||||
|
||||
setInterval(async ()=>{ |
||||
//console.log(await node.good.restart());
|
||||
//console.log('ddd')
|
||||
//console.log(await node.good.refresh());
|
||||
//console.log(await node.good.setNS('ccc', '192.168.3.253', 6789));
|
||||
//console.log(await node.good.checkNS('ccc', '111.111.11.11', 6789));
|
||||
//console.log(await node.good.setFunc('333Func', 'tmr.create():alarm(3000, tmr.ALARM_AUTO, function() print("hello") end)'));
|
||||
|
||||
/*l = await ns.get(['good', 'good3'], { |
||||
'good': { |
||||
'good3': { |
||||
port: 22, |
||||
ip: '111.222.333.44' |
||||
} |
||||
} |
||||
})*/ |
||||
|
||||
let online = []; |
||||
|
||||
Object.keys(node).forEach(nid => { |
||||
if(node[nid].status){ |
||||
online.push(nid); |
||||
} |
||||
}); |
||||
|
||||
if(online.some(nid => OnlineBoard.indexOf(nid) == -1)){ |
||||
OnlineBoard = online; |
||||
await ns.set(await ns.get(online/*, { |
||||
'good': { |
||||
'good3': { |
||||
port: 22, |
||||
ip: '111.222.333.44' |
||||
} |
||||
}, |
||||
'good3': { |
||||
'good': { |
||||
port: 22, |
||||
ip: '111.222.333.44' |
||||
} |
||||
}, |
||||
}*/)) |
||||
} |
||||
|
||||
|
||||
|
||||
},15000) |
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,140 @@ |
||||
module.exports = (logger, node, ns) => { |
||||
|
||||
|
||||
const log = logger.getLogger('weblog'); |
||||
const express = require('express'); |
||||
const app = express() |
||||
const port = 3001; |
||||
|
||||
app.get('/', (req, res) => { |
||||
res.send('Hello World!') |
||||
}) |
||||
|
||||
app.listen(port, () => { |
||||
log.info('API web server begin at ', port); |
||||
}) |
||||
|
||||
function isJson(str) { |
||||
try { |
||||
if (typeof JSON.parse(str) == "object") { |
||||
return true; |
||||
} |
||||
} catch(e) { |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
app.get('/status', (req, res) => { |
||||
if(!req.query.hasOwnProperty('query')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
if(!isJson(req.query.query)){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
let query = JSON.parse(req.query.query); |
||||
|
||||
let resData = {}; |
||||
query.forEach(nid => { |
||||
if(node.hasOwnProperty(nid)){ |
||||
resData[nid] = {}; |
||||
resData[nid].status = node[nid].status; |
||||
resData[nid].funcID = node[nid].info.funcID; |
||||
resData[nid].port = node[nid].info.localport; |
||||
resData[nid].ip = node[nid].info.localip; |
||||
resData[nid].ns = node[nid].ns; |
||||
resData[nid].heap = node[nid].info.heap; |
||||
resData[nid].spiff = node[nid].info.spiff; |
||||
resData[nid].HeartbeatInterval = node[nid].info.HeartbeatInterval; |
||||
resData[nid].LastUpTime = node[nid].info.LastUpTime; |
||||
resData[nid].LastActiveTime = node[nid].info.LastActiveTime; |
||||
resData[nid].LastRefreshTime = node[nid].LastRefreshTime; |
||||
resData[nid].LastRestartTime = node[nid].LastRestartTime; |
||||
} |
||||
}); |
||||
|
||||
res.send(resData); |
||||
log.info('[status]', JSON.stringify(req.query.query)); |
||||
}) |
||||
|
||||
|
||||
|
||||
app.get('/setFunc', async (req, res) => { |
||||
if(!req.query.hasOwnProperty('nid') || !req.query.hasOwnProperty('funcID') || !req.query.hasOwnProperty('func')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
let nid = req.query.nid, |
||||
funcID = req.query.funcID, |
||||
func = new Buffer(req.query.func, 'base64').toString() |
||||
|
||||
if(!node.hasOwnProperty(nid)){ |
||||
res.status(404).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if(!node[nid].status){ |
||||
res.status(503).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
let status = await node[nid].setFunc(funcID, func); |
||||
|
||||
|
||||
|
||||
res.send({status: status}); |
||||
log.info('[setFunc]', '<'+nid+'>', funcID, status); |
||||
}) |
||||
|
||||
|
||||
|
||||
app.get('/restart', async (req, res) => { |
||||
if(!req.query.hasOwnProperty('nid')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
let nid = req.query.nid; |
||||
|
||||
if(!node.hasOwnProperty(nid)){ |
||||
res.status(404).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if(!node[nid].status){ |
||||
res.status(503).send(); |
||||
return; |
||||
} |
||||
|
||||
|
||||
let status = await node[nid].restart(); |
||||
res.send({status: status}); |
||||
log.info('[restart]', '<'+nid+'>', status); |
||||
}) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
app.get('/log', (req, res) => { |
||||
if(!req.query.hasOwnProperty('type') || !req.query.hasOwnProperty('start')){ |
||||
res.status(500).send(); |
||||
return; |
||||
} |
||||
|
||||
res.send(); |
||||
log.info('[log]', req.query.type); |
||||
}) |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return null; |
||||
} |
@ -0,0 +1,29 @@ |
||||
module.exports = (node, nodetable) => { |
||||
|
||||
const LOG_PATH = __dirname + '/../data/log/'; |
||||
|
||||
|
||||
const log4js = require('log4js'); |
||||
|
||||
|
||||
log4js.configure({ |
||||
appenders: { |
||||
flow: {type: 'file', filename: LOG_PATH + 'flow.log'}, |
||||
access: {type: 'file', filename: LOG_PATH + 'access.log'}, |
||||
event: {type: 'file', filename: LOG_PATH + 'event.log'}, |
||||
nslog: {type: 'file', filename: LOG_PATH + 'ns.log'}, |
||||
weblog: {type: 'file', filename: LOG_PATH + 'web.log'}, |
||||
console: { type: 'console' } |
||||
}, |
||||
categories: { |
||||
flow: {appenders: [/*'flow',*/ 'console'], level: 'info' }, |
||||
//access: { appenders: ['access'], level: 'info' },
|
||||
event: {appenders: [/*'event', */'console'], level: 'info' }, |
||||
nslog: {appenders: [/*'nslog',*/ 'console'], level: 'info' }, |
||||
weblog: {appenders: [/*'weblog',*/ 'console'], level: 'info' }, |
||||
default: { appenders: ['console'], level: 'info' } |
||||
} |
||||
}); |
||||
|
||||
return log4js; |
||||
} |
@ -0,0 +1,281 @@ |
||||
module.exports = (logger, nodetable) => { |
||||
|
||||
|
||||
let nodes = {} |
||||
const CMD_DELAY = 200; |
||||
|
||||
let delay = (time_ms) => new Promise(resolve => { |
||||
setTimeout(()=>{ |
||||
resolve(); |
||||
}, time_ms); |
||||
}); |
||||
|
||||
|
||||
|
||||
const event = logger.getLogger('event'); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
nodetable.newNode((nid, info) => { |
||||
nodes[nid] = { |
||||
send: (name, body, isudp) => { |
||||
return nodetable.outgo(nid, { |
||||
to: nid, |
||||
from: "director", |
||||
name: name, |
||||
body: body |
||||
}, isudp); |
||||
}, |
||||
triggers: { |
||||
income: [ |
||||
function(name, body){ |
||||
if(name == '__getInfo'){ |
||||
nodes[nid].info.localport = body.port; |
||||
nodes[nid].info.localip = body.ip; |
||||
nodes[nid].info.funcID = body.funcID; |
||||
nodes[nid].info.HeartbeatInterval = body.HeartbeatInterval; |
||||
nodes[nid].ns = body.ns; |
||||
nodes[nid].LastRefreshTime = new Date().valueOf(); |
||||
} |
||||
}, |
||||
function(name, body){ |
||||
if(name == '__checkNS'){ |
||||
if(!nodes[nid].rns.hasOwnProperty(body.from) || nodes[nid].rns[body.from].ip != body.ip || nodes[nid].rns[body.from].port != body.port){ |
||||
nodes[nid].rns[body.from] = body; |
||||
nodes[nid].rns[body.from].updated = true; |
||||
} |
||||
nodes[nid].rns[body.from].LastCheckTime = new Date().valueOf(); |
||||
} |
||||
} |
||||
], |
||||
connect: [], |
||||
disconnect: [], |
||||
restart: [], |
||||
error: [] |
||||
}, |
||||
LastRefreshTime: 0, |
||||
LastRestartTime: 0, |
||||
ns: {}, |
||||
rns: {}, |
||||
on: (type, cb) => { |
||||
nodes[nid].triggers[type].push(cb); |
||||
}, |
||||
restart: () => new Promise((resolve) => { |
||||
let restartTime = new Date().valueOf(); |
||||
let counter = 100; |
||||
nodes[nid].send('__restart', ''); |
||||
let timer = () => { |
||||
setTimeout(()=>{ |
||||
if(nodes[nid].info.LastUpTime < restartTime){ |
||||
if(counter){ |
||||
if(nodes[nid].info.LastActiveTime > restartTime + 500){ |
||||
nodes[nid].send('__restart', ''); |
||||
restartTime = new Date().valueOf(); |
||||
counter = 100; |
||||
} |
||||
timer(); |
||||
counter --; |
||||
}else{ |
||||
resolve(false); |
||||
return; |
||||
} |
||||
}else{ |
||||
event.info('[CMD]', '<'+nid+'>', '__restart'); |
||||
resolve(true); |
||||
return; |
||||
} |
||||
}, 300); |
||||
}; |
||||
timer(); |
||||
}), |
||||
refresh: () => new Promise((resolve) => { |
||||
let startTime = new Date().valueOf(); |
||||
let counter = 100; |
||||
nodes[nid].send('__getInfo', ''); |
||||
let timer = () => { |
||||
setTimeout(async ()=>{ |
||||
if(nodes[nid].LastRefreshTime < startTime){ |
||||
if(counter){ |
||||
if(counter == 70 || counter == 40){ |
||||
nodes[nid].send('__getInfo', ''); |
||||
} |
||||
timer(); |
||||
counter--; |
||||
}else{ |
||||
resolve(false); |
||||
return; |
||||
} |
||||
}else{ |
||||
await delay(CMD_DELAY) |
||||
event.info('[CMD]', '<'+nid+'>', '__refresh'); |
||||
resolve(true); |
||||
return; |
||||
} |
||||
}, 300); |
||||
}; |
||||
timer(); |
||||
}), |
||||
setNS: (nsArr) => new Promise(async (resolve) => { |
||||
|
||||
|
||||
let checkLocalNS = () => Object.keys(nodes[nid].ns).every(id => { |
||||
if(nsArr.hasOwnProperty(id) && nodes[nid].ns[id].ip == nsArr[id].ip && nodes[nid].ns[id].port == nsArr[id].port){ |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
}) && Object.keys(nsArr).every(id => { |
||||
if(nodes[nid].ns.hasOwnProperty(id) && nodes[nid].ns[id].ip == nsArr[id].ip && nodes[nid].ns[id].port == nsArr[id].port){ |
||||
return true; |
||||
}else{ |
||||
return false; |
||||
} |
||||
}); |
||||
|
||||
|
||||
|
||||
if(checkLocalNS()){ |
||||
resolve(true); |
||||
return; |
||||
} |
||||
|
||||
|
||||
let body = {}; |
||||
Object.keys(nsArr).forEach(id => { |
||||
body[id] = { |
||||
ip: nsArr[id].ip, |
||||
port: nsArr[id].port |
||||
} |
||||
}); |
||||
|
||||
|
||||
nodes[nid].send('__setNS', body); |
||||
|
||||
|
||||
await delay(CMD_DELAY); |
||||
|
||||
if(checkLocalNS()){ |
||||
event.info('[CMD]', '<'+nid+'>', '__setNS', JSON.stringify(Object.keys(body))); |
||||
resolve(true); |
||||
}else{ |
||||
resolve(false); |
||||
} |
||||
|
||||
}), |
||||
checkNS: (id, ip, port) => new Promise(async (resolve) => { |
||||
|
||||
nodes[nid].send('__checkNS', { |
||||
to: id, |
||||
from: nid, |
||||
ip: ip, |
||||
port: port |
||||
}, true); |
||||
|
||||
await delay(CMD_DELAY); |
||||
|
||||
nodes[nid].send('__checkNS', { |
||||
to: id, |
||||
from: nid, |
||||
ip: ip, |
||||
port: port |
||||
},true); |
||||
|
||||
await delay(CMD_DELAY); |
||||
|
||||
event.info('[CMD]', '<'+nid+'>', '__checkNS', id); |
||||
resolve(); |
||||
|
||||
}), |
||||
setFunc: (id, func) => new Promise(async resolve => { |
||||
let restartTime = new Date().valueOf(); |
||||
let counter = 100; |
||||
if(nodes[nid].info.funcID == id) { |
||||
resolve(true); |
||||
return;
|
||||
} |
||||
nodes[nid].send('__setFunc', { |
||||
func: { |
||||
id: id, |
||||
online: func |
||||
} |
||||
}); |
||||
let timer = () => { |
||||
setTimeout(()=>{ |
||||
if(nodes[nid].info.LastUpTime < restartTime || nodes[nid].info.funcID != id){ |
||||
if(counter){ |
||||
if(nodes[nid].info.LastActiveTime > restartTime + 500){ |
||||
nodes[nid].send('__setFunc', { |
||||
func: { |
||||
id: id, |
||||
online: func |
||||
} |
||||
}); |
||||
restartTime = new Date().valueOf(); |
||||
//counter = 100;
|
||||
} |
||||
timer(); |
||||
counter --; |
||||
}else{ |
||||
resolve(false); |
||||
return; |
||||
} |
||||
}else{ |
||||
event.info('[CMD]', '<'+nid+'>', '__setFunc', id, func); |
||||
resolve(true); |
||||
return; |
||||
} |
||||
}, 300); |
||||
}; |
||||
timer(); |
||||
}) |
||||
}; |
||||
nodes[nid].info = info; |
||||
}); |
||||
|
||||
|
||||
nodetable.connect((nid, info) => { |
||||
nodes[nid].status = true; |
||||
if(new Date().valueOf() < nodes[nid].info.LastUpTime + nodes[nid].info.HeartbeatInterval){ |
||||
nodes[nid].triggers.restart.forEach(cb => { |
||||
cb(); |
||||
}); |
||||
nodes[nid].LastRestartTime = new Date().valueOf(); |
||||
event.info('[RESTART]', '<'+nid+'>', '{'+info.funcID+'}'); |
||||
} |
||||
nodes[nid].triggers.connect.forEach(cb => { |
||||
cb(); |
||||
}); |
||||
event.info('[CONNECT]', '<'+nid+'>', '{'+info.funcID+'}'); |
||||
|
||||
}); |
||||
|
||||
|
||||
nodetable.disconnect((nid, info) => { |
||||
nodes[nid].status = false; |
||||
nodes[nid].triggers.disconnect.forEach(cb => { |
||||
cb(); |
||||
}); |
||||
event.info('[DISCONNECT]', '<'+nid+'>', '{'+info.funcID+'}'); |
||||
}); |
||||
|
||||
nodetable.income((nid, info, data) => { |
||||
nodes[nid].status = true; |
||||
nodes[nid].triggers.income.forEach(cb => { |
||||
cb(data.name, data.body); |
||||
}); |
||||
}); |
||||
|
||||
|
||||
nodetable.error((nid, info) => { |
||||
nodes[nid].triggers.error.forEach(cb => { |
||||
cb(info.error); |
||||
}); |
||||
event.error('[ERROR]', '<'+nid+'>', '{'+info.funcID+'}', info.error); |
||||
}); |
||||
|
||||
|
||||
return nodes; |
||||
} |
@ -0,0 +1,269 @@ |
||||
module.exports = (logger, host = '0.0.0.0', port = 6789) => { |
||||
|
||||
let cbArr = { |
||||
income: [], |
||||
outgo: [], |
||||
forward: [], |
||||
newNode: [], |
||||
connect: [], |
||||
disconnect: [], |
||||
error: [] |
||||
}; |
||||
|
||||
|
||||
let o = { |
||||
income: cb => { //cb(nid, info{funcID, error}, data)
|
||||
cbArr.income.push(cb); |
||||
}, |
||||
forward: cb => { //cb(nid, info{funcID, error}, data)
|
||||
cbArr.forward.push(cb); |
||||
}, |
||||
outgo: (nid, data, isudp) => { |
||||
if(!nidtable.hasOwnProperty(nid) || !nidtable[nid].socket || (!nidtable[nid].status && !isudp)){ |
||||
flow.error('[OUTGOING]', '<nid lookup failure>', data.to+'<--'+data.from, data.name, data.body); |
||||
return false; |
||||
} |
||||
try{ |
||||
let raw = JSON.stringify(data); |
||||
if(raw.length>1300){ |
||||
let rawArr = []; |
||||
let flag = require('md5')(Math.random()).substring(0,1); |
||||
let n = 1300; |
||||
for (let i = 0; i < raw.length/n; i++) { |
||||
let prefix = '&'; |
||||
if(i == 0){ |
||||
prefix = '^'; |
||||
} |
||||
if(i >= raw.length/n - 1){ |
||||
prefix = '$'; |
||||
} |
||||
setTimeout(()=>{ |
||||
console.log(prefix + flag + raw.slice(n*i, n*(i+1))) |
||||
nidtable[nid].socket.write(prefix + flag + raw.slice(n*i, n*(i+1))); |
||||
}, i*2); |
||||
} |
||||
|
||||
|
||||
}else{ |
||||
nidtable[nid].socket.write(raw); |
||||
} |
||||
if(!isudp) nidtable[nid].status = false; |
||||
}catch(e){ |
||||
flow.error('[OUTGOING]', '<nid lookup failure>', data.to+'<--'+data.from, data.name, data.body); |
||||
} |
||||
|
||||
cbArr.outgo.forEach(cb => { |
||||
cb(nid, nidtable[nid], data); |
||||
}); |
||||
flow.log('[OUTGOING]', data.from + '-->' + data.to, data.name, data.body); |
||||
return true; |
||||
}, |
||||
newNode: cb => { |
||||
cbArr.newNode.push(cb); |
||||
}, |
||||
connect: cb => { |
||||
cbArr.connect.push(cb); |
||||
}, |
||||
disconnect: cb => { |
||||
cbArr.disconnect.push(cb); |
||||
}, |
||||
error: cb => { |
||||
cbArr.error.push(cb); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
let nidtable = {} |
||||
|
||||
|
||||
|
||||
function isJson(str) { |
||||
try { |
||||
if (typeof JSON.parse(str) == "object") { |
||||
return true; |
||||
} |
||||
} catch(e) { |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
|
||||
const net = require('net'); |
||||
|
||||
|
||||
|
||||
const flow = logger.getLogger('flow'); |
||||
const access = logger.getLogger('access'); |
||||
|
||||
|
||||
const server = net.createServer((socket) => { |
||||
access.trace('Unspecified', socket.remoteAddress+':'+socket.remotePort, 'New TCP request.'); |
||||
socket.setKeepAlive(true); |
||||
let nid = null; |
||||
socket.on('data', (data) => { |
||||
data = data.toString(); |
||||
if(!isJson(data)){ |
||||
access.error(nid, socket.remoteAddress+':'+socket.remotePort, 'Data is not JSON! Data::'+data); |
||||
return; |
||||
} |
||||
data = JSON.parse(data); |
||||
|
||||
if(data.hasOwnProperty('nid') && data.hasOwnProperty('funcID') && data.hasOwnProperty('port') && data.hasOwnProperty('ip') && data.hasOwnProperty('HeartbeatInterval') && data.hasOwnProperty('uptime')){ |
||||
nid = data.nid; |
||||
let isNew = false; |
||||
if(!nidtable.hasOwnProperty(nid)){ |
||||
nidtable[nid] = {}; |
||||
isNew = true; |
||||
} |
||||
if(nidtable[nid].socket){ |
||||
nidtable[nid].socket.destroy(); |
||||
nidtable[nid].socket = null; |
||||
nidtable[nid].ip = null; |
||||
nidtable[nid].port = null; |
||||
access.info(nid, socket.remoteAddress+':'+socket.remotePort, '[CLOSE]'); |
||||
cbArr.disconnect.forEach(cb => { |
||||
cb(nid, nidtable[nid]); |
||||
}); |
||||
} |
||||
nidtable[nid].status = true; |
||||
nidtable[nid].funcID = data.funcID; |
||||
nidtable[nid].localport = data.port; |
||||
nidtable[nid].localip = data.ip; |
||||
nidtable[nid].HeartbeatInterval = data.HeartbeatInterval; |
||||
nidtable[nid].LastUpTime = new Date().valueOf() - data.uptime*1000; |
||||
nidtable[nid].LastActiveTime = new Date().valueOf(); |
||||
nidtable[nid].ip = socket.remoteAddress; |
||||
nidtable[nid].port = socket.remotePort; |
||||
nidtable[nid].socket = socket; |
||||
|
||||
socket.setTimeout(2.2 * nidtable[nid].HeartbeatInterval); |
||||
|
||||
|
||||
if(isNew){ |
||||
cbArr.newNode.forEach(cb => { |
||||
cb(nid, nidtable[nid]); |
||||
}); |
||||
} |
||||
if(data.hasOwnProperty('error') && data.error){ |
||||
nidtable[nid].error = data.error; |
||||
cbArr.error.forEach(cb => { |
||||
cb(nid, nidtable[nid]); |
||||
}); |
||||
} |
||||
cbArr.connect.forEach(cb => { |
||||
cb(nid, nidtable[nid]); |
||||
}); |
||||
|
||||
|
||||
|
||||
access.info(nid, socket.remoteAddress+':'+socket.remotePort, 'New TCP connection. Data::', JSON.stringify(data)); |
||||
return; |
||||
} |
||||
|
||||
if(!nid){ |
||||
access.error(nid, socket.remoteAddress+':'+socket.remotePort, 'No nid is specified. Data::', data); |
||||
return; |
||||
} |
||||
nidtable[nid].LastActiveTime = new Date().valueOf(); |
||||
nidtable[nid].status = true; |
||||
|
||||
if(data.hasOwnProperty('uptime') && data.hasOwnProperty('heap') && data.hasOwnProperty('spiff')){ |
||||
nidtable[nid].LastUpTime = new Date().valueOf() - data.uptime*1000; |
||||
nidtable[nid].heap = data.heap; |
||||
nidtable[nid].spiff = data.spiff; |
||||
access.info(nid, socket.remoteAddress+':'+socket.remotePort, '[HEARTBEAT]', data); |
||||
return; |
||||
} |
||||
|
||||
if(!data.hasOwnProperty('from') || !data.hasOwnProperty('to') || !data.hasOwnProperty('name') || !data.hasOwnProperty('body')){ |
||||
access.error(nid, socket.remoteAddress+':'+socket.remotePort, 'Illegal package format. Data::', data); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if(data.to != 'director'){ |
||||
if(nidtable.hasOwnProperty(data.to)){ |
||||
try{ |
||||
nidtable[data.to].socket.write(JSON.stringify(data)); |
||||
flow.log('[FORWARD]', data.to+'<--'+data.from, data.name, data.body); |
||||
}catch(e){console.error(e)} |
||||
}else{ |
||||
flow.error('[FORWARD]', '<nid lookup failure>', data.to+'<--'+data.from, data.name, data.body); |
||||
} |
||||
cbArr.forward.forEach(cb => { |
||||
cb(nid, nidtable[nid], data); |
||||
}); |
||||
return; |
||||
} |
||||
|
||||
|
||||
if(data.to == 'director'){ |
||||
cbArr.income.forEach(cb => { |
||||
cb(nid, nidtable[nid], data); |
||||
}); |
||||
flow.log('[INCOMING]', data.to+'<--'+data.from, data.name, data.body ); |
||||
return; |
||||
} |
||||
|
||||
|
||||
|
||||
}); |
||||
|
||||
socket.setTimeout(60 * 1000); |
||||
socket.on('timeout', () => { |
||||
access.info(nid, socket.remoteAddress+':'+socket.remotePort, '[TIMEOUT]', 'After', socket.timeout, 'ms'); |
||||
try{ |
||||
nidtable[nid].socket = null; |
||||
nidtable[nid].ip = null; |
||||
nidtable[nid].port = null; |
||||
nidtable[nid].status = false; |
||||
access.info(nid, socket.remoteAddress+':'+socket.remotePort, '[CLOSE]'); |
||||
cbArr.disconnect.forEach(cb => { |
||||
cb(nid, nidtable[nid]); |
||||
}); |
||||
}catch(e){ |
||||
delete nidtable[nid]; |
||||
} |
||||
|
||||
socket.destroy(); |
||||
}); |
||||
|
||||
socket.on('error', function(err){ |
||||
access.error(nid, socket.remoteAddress+':'+socket.remotePort, '[ERROR]', 'Exist unsent package'); |
||||
}); |
||||
|
||||
socket.on('close', function(err){ |
||||
if(nid && nidtable[nid].socket === socket){ |
||||
nidtable[nid].socket = null; |
||||
nidtable[nid].ip = null; |
||||
nidtable[nid].port = null; |
||||
nidtable[nid].status = false; |
||||
access.info(nid, socket.remoteAddress+':'+socket.remotePort, '[CLOSE]'); |
||||
cbArr.disconnect.forEach(cb => { |
||||
cb(nid, nidtable[nid]); |
||||
}); |
||||
} |
||||
}) |
||||
}).on('error', (err) => { |
||||
|
||||
access.error('[ERROR]', 'Exist unsent package'); |
||||
}); |
||||
|
||||
// Grab an arbitrary unused port.
|
||||
server.listen({ |
||||
host: host, |
||||
port: port, |
||||
exclusive: true |
||||
}, () => { |
||||
access.info('TCP Server Begin at ', host + ':' + port); |
||||
}); |
||||
|
||||
|
||||
|
||||
|
||||
return o; |
||||
|
||||
|
||||
|
||||
} |
@ -0,0 +1,74 @@ |
||||
module.exports = (logger, node, nodetable) => { |
||||
|
||||
|
||||
const log = logger.getLogger('nslog'); |
||||
|
||||
|
||||
|
||||
const NS_DELAY = 2000; |
||||
|
||||
|
||||
let delay = (time_ms) => new Promise(resolve => { |
||||
setTimeout(()=>{ |
||||
resolve(); |
||||
}, time_ms); |
||||
}); |
||||
|
||||
|
||||
|
||||
let o = { |
||||
get: (nodeArr, refer) => new Promise(async resolve => { |
||||
let list = []; |
||||
nodeArr.forEach(nid => { |
||||
if(node.hasOwnProperty(nid)){ |
||||
list.push(nid); |
||||
} |
||||
}); |
||||
|
||||
let nsList = {}; |
||||
let beginTime = new Date().valueOf(); |
||||
for(nid1 of list){ |
||||
for(nid2 of list){ |
||||
if(nid1 != nid2){ |
||||
log.info('[CHECK]', nid2, '-->', nid1); |
||||
await node[nid2].checkNS(nid1, refer && refer[nid2] && refer[nid2][nid1] && refer[nid2][nid1].ip || node[nid1].info.localip, refer && refer[nid2] && refer[nid2][nid1] && refer[nid2][nid1].port || node[nid1].info.localport) |
||||
} |
||||
} |
||||
}; |
||||
|
||||
await delay(NS_DELAY); |
||||
|
||||
list.forEach(nid => { |
||||
Object.keys(node[nid].rns).forEach(nid2 => { |
||||
let rns = node[nid].rns[nid2]; |
||||
if(rns.LastCheckTime > beginTime){ |
||||
log.info('[VERIFIED]', nid2, '-->', nid); |
||||
if(!nsList.hasOwnProperty(nid2)){ |
||||
nsList[nid2] = {}; |
||||
} |
||||
nsList[nid2][nid] = { |
||||
ip: rns.ip, |
||||
port: rns.port |
||||
} |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
|
||||
resolve(nsList); |
||||
|
||||
}), |
||||
set: (nsList) => new Promise(async resolve => { |
||||
let status = true; |
||||
Object.keys(nsList).forEach(async nidf => { |
||||
log.info('[SET]', nidf, '::', JSON.stringify(nsList[nidf])); |
||||
status = status && await node[nidf].setNS(nsList[nidf]); |
||||
}); |
||||
resolve(status); |
||||
}) |
||||
} |
||||
|
||||
|
||||
|
||||
return o; |
||||
} |
@ -0,0 +1,446 @@ |
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. |
||||
# yarn lockfile v1 |
||||
|
||||
|
||||
accepts@~1.3.7: |
||||
version "1.3.7" |
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" |
||||
integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== |
||||
dependencies: |
||||
mime-types "~2.1.24" |
||||
negotiator "0.6.2" |
||||
|
||||
array-flatten@1.1.1: |
||||
version "1.1.1" |
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" |
||||
integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= |
||||
|
||||
body-parser@1.19.0: |
||||
version "1.19.0" |
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" |
||||
integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== |
||||
dependencies: |
||||
bytes "3.1.0" |
||||
content-type "~1.0.4" |
||||
debug "2.6.9" |
||||
depd "~1.1.2" |
||||
http-errors "1.7.2" |
||||
iconv-lite "0.4.24" |
||||
on-finished "~2.3.0" |
||||
qs "6.7.0" |
||||
raw-body "2.4.0" |
||||
type-is "~1.6.17" |
||||
|
||||
bytes@3.1.0: |
||||
version "3.1.0" |
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" |
||||
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== |
||||
|
||||
content-disposition@0.5.3: |
||||
version "0.5.3" |
||||
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" |
||||
integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== |
||||
dependencies: |
||||
safe-buffer "5.1.2" |
||||
|
||||
content-type@~1.0.4: |
||||
version "1.0.4" |
||||
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" |
||||
integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== |
||||
|
||||
cookie-signature@1.0.6: |
||||
version "1.0.6" |
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" |
||||
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= |
||||
|
||||
cookie@0.4.0: |
||||
version "0.4.0" |
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" |
||||
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== |
||||
|
||||
date-format@^2.1.0: |
||||
version "2.1.0" |
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-2.1.0.tgz#31d5b5ea211cf5fd764cd38baf9d033df7e125cf" |
||||
integrity sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA== |
||||
|
||||
date-format@^3.0.0: |
||||
version "3.0.0" |
||||
resolved "https://registry.yarnpkg.com/date-format/-/date-format-3.0.0.tgz#eb8780365c7d2b1511078fb491e6479780f3ad95" |
||||
integrity sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w== |
||||
|
||||
debug@2.6.9: |
||||
version "2.6.9" |
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" |
||||
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== |
||||
dependencies: |
||||
ms "2.0.0" |
||||
|
||||
debug@^4.1.1: |
||||
version "4.3.1" |
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" |
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== |
||||
dependencies: |
||||
ms "2.1.2" |
||||
|
||||
depd@~1.1.2: |
||||
version "1.1.2" |
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" |
||||
integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= |
||||
|
||||
destroy@~1.0.4: |
||||
version "1.0.4" |
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" |
||||
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= |
||||
|
||||
ee-first@1.1.1: |
||||
version "1.1.1" |
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" |
||||
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= |
||||
|
||||
encodeurl@~1.0.2: |
||||
version "1.0.2" |
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" |
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= |
||||
|
||||
escape-html@~1.0.3: |
||||
version "1.0.3" |
||||
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" |
||||
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= |
||||
|
||||
etag@~1.8.1: |
||||
version "1.8.1" |
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" |
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= |
||||
|
||||
express@^4.17.1: |
||||
version "4.17.1" |
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" |
||||
integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== |
||||
dependencies: |
||||
accepts "~1.3.7" |
||||
array-flatten "1.1.1" |
||||
body-parser "1.19.0" |
||||
content-disposition "0.5.3" |
||||
content-type "~1.0.4" |
||||
cookie "0.4.0" |
||||
cookie-signature "1.0.6" |
||||
debug "2.6.9" |
||||
depd "~1.1.2" |
||||
encodeurl "~1.0.2" |
||||
escape-html "~1.0.3" |
||||
etag "~1.8.1" |
||||
finalhandler "~1.1.2" |
||||
fresh "0.5.2" |
||||
merge-descriptors "1.0.1" |
||||
methods "~1.1.2" |
||||
on-finished "~2.3.0" |
||||
parseurl "~1.3.3" |
||||
path-to-regexp "0.1.7" |
||||
proxy-addr "~2.0.5" |
||||
qs "6.7.0" |
||||
range-parser "~1.2.1" |
||||
safe-buffer "5.1.2" |
||||
send "0.17.1" |
||||
serve-static "1.14.1" |
||||
setprototypeof "1.1.1" |
||||
statuses "~1.5.0" |
||||
type-is "~1.6.18" |
||||
utils-merge "1.0.1" |
||||
vary "~1.1.2" |
||||
|
||||
finalhandler@~1.1.2: |
||||
version "1.1.2" |
||||
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" |
||||
integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== |
||||
dependencies: |
||||
debug "2.6.9" |
||||
encodeurl "~1.0.2" |
||||
escape-html "~1.0.3" |
||||
on-finished "~2.3.0" |
||||
parseurl "~1.3.3" |
||||
statuses "~1.5.0" |
||||
unpipe "~1.0.0" |
||||
|
||||
flatted@^2.0.1: |
||||
version "2.0.2" |
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" |
||||
integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== |
||||
|
||||
forwarded@~0.1.2: |
||||
version "0.1.2" |
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" |
||||
integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= |
||||
|
||||
fresh@0.5.2: |
||||
version "0.5.2" |
||||
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" |
||||
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= |
||||
|
||||
fs-extra@^8.1.0: |
||||
version "8.1.0" |
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" |
||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== |
||||
dependencies: |
||||
graceful-fs "^4.2.0" |
||||
jsonfile "^4.0.0" |
||||
universalify "^0.1.0" |
||||
|
||||
graceful-fs@^4.1.6, graceful-fs@^4.2.0: |
||||
version "4.2.6" |
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" |
||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== |
||||
|
||||
http-errors@1.7.2: |
||||
version "1.7.2" |
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" |
||||
integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== |
||||
dependencies: |
||||
depd "~1.1.2" |
||||
inherits "2.0.3" |
||||
setprototypeof "1.1.1" |
||||
statuses ">= 1.5.0 < 2" |
||||
toidentifier "1.0.0" |
||||
|
||||
http-errors@~1.7.2: |
||||
version "1.7.3" |
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" |
||||
integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== |
||||
dependencies: |
||||
depd "~1.1.2" |
||||
inherits "2.0.4" |
||||
setprototypeof "1.1.1" |
||||
statuses ">= 1.5.0 < 2" |
||||
toidentifier "1.0.0" |
||||
|
||||
iconv-lite@0.4.24: |
||||
version "0.4.24" |
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" |
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== |
||||
dependencies: |
||||
safer-buffer ">= 2.1.2 < 3" |
||||
|
||||
inherits@2.0.3: |
||||
version "2.0.3" |
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" |
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= |
||||
|
||||
inherits@2.0.4: |
||||
version "2.0.4" |
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" |
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== |
||||
|
||||
ipaddr.js@1.9.1: |
||||
version "1.9.1" |
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" |
||||
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== |
||||
|
||||
jsonfile@^4.0.0: |
||||
version "4.0.0" |
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" |
||||
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= |
||||
optionalDependencies: |
||||
graceful-fs "^4.1.6" |
||||
|
||||
log4js@^6.3.0: |
||||
version "6.3.0" |
||||
resolved "https://registry.yarnpkg.com/log4js/-/log4js-6.3.0.tgz#10dfafbb434351a3e30277a00b9879446f715bcb" |
||||
integrity sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw== |
||||
dependencies: |
||||
date-format "^3.0.0" |
||||
debug "^4.1.1" |
||||
flatted "^2.0.1" |
||||
rfdc "^1.1.4" |
||||
streamroller "^2.2.4" |
||||
|
||||
media-typer@0.3.0: |
||||
version "0.3.0" |
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" |
||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= |
||||
|
||||
merge-descriptors@1.0.1: |
||||
version "1.0.1" |
||||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" |
||||
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= |
||||
|
||||
methods@~1.1.2: |
||||
version "1.1.2" |
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" |
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= |
||||
|
||||
mime-db@1.46.0: |
||||
version "1.46.0" |
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" |
||||
integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== |
||||
|
||||
mime-types@~2.1.24: |
||||
version "2.1.29" |
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" |
||||
integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== |
||||
dependencies: |
||||
mime-db "1.46.0" |
||||
|
||||
mime@1.6.0: |
||||
version "1.6.0" |
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" |
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== |
||||
|
||||
ms@2.0.0: |
||||
version "2.0.0" |
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" |
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= |
||||
|
||||
ms@2.1.1: |
||||
version "2.1.1" |
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" |
||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== |
||||
|
||||
ms@2.1.2: |
||||
version "2.1.2" |
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" |
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== |
||||
|
||||
negotiator@0.6.2: |
||||
version "0.6.2" |
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" |
||||
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== |
||||
|
||||
on-finished@~2.3.0: |
||||
version "2.3.0" |
||||
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" |
||||
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= |
||||
dependencies: |
||||
ee-first "1.1.1" |
||||
|
||||
parseurl@~1.3.3: |
||||
version "1.3.3" |
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" |
||||
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== |
||||
|
||||
path-to-regexp@0.1.7: |
||||
version "0.1.7" |
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" |
||||
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= |
||||
|
||||
proxy-addr@~2.0.5: |
||||
version "2.0.6" |
||||
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" |
||||
integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== |
||||
dependencies: |
||||
forwarded "~0.1.2" |
||||
ipaddr.js "1.9.1" |
||||
|
||||
qs@6.7.0: |
||||
version "6.7.0" |
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" |
||||
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== |
||||
|
||||
range-parser@~1.2.1: |
||||
version "1.2.1" |
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" |
||||
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== |
||||
|
||||
raw-body@2.4.0: |
||||
version "2.4.0" |
||||
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" |
||||
integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== |
||||
dependencies: |
||||
bytes "3.1.0" |
||||
http-errors "1.7.2" |
||||
iconv-lite "0.4.24" |
||||
unpipe "1.0.0" |
||||
|
||||
rfdc@^1.1.4: |
||||
version "1.3.0" |
||||
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" |
||||
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== |
||||
|
||||
safe-buffer@5.1.2: |
||||
version "5.1.2" |
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" |
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== |
||||
|
||||
"safer-buffer@>= 2.1.2 < 3": |
||||
version "2.1.2" |
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" |
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== |
||||
|
||||
send@0.17.1: |
||||
version "0.17.1" |
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" |
||||
integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== |
||||
dependencies: |
||||
debug "2.6.9" |
||||
depd "~1.1.2" |
||||
destroy "~1.0.4" |
||||
encodeurl "~1.0.2" |
||||
escape-html "~1.0.3" |
||||
etag "~1.8.1" |
||||
fresh "0.5.2" |
||||
http-errors "~1.7.2" |
||||
mime "1.6.0" |
||||
ms "2.1.1" |
||||
on-finished "~2.3.0" |
||||
range-parser "~1.2.1" |
||||
statuses "~1.5.0" |
||||
|
||||
serve-static@1.14.1: |
||||
version "1.14.1" |
||||
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" |
||||
integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== |
||||
dependencies: |
||||
encodeurl "~1.0.2" |
||||
escape-html "~1.0.3" |
||||
parseurl "~1.3.3" |
||||
send "0.17.1" |
||||
|
||||
setprototypeof@1.1.1: |
||||
version "1.1.1" |
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" |
||||
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== |
||||
|
||||
"statuses@>= 1.5.0 < 2", statuses@~1.5.0: |
||||
version "1.5.0" |
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" |
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= |
||||
|
||||
streamroller@^2.2.4: |
||||
version "2.2.4" |
||||
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.4.tgz#c198ced42db94086a6193608187ce80a5f2b0e53" |
||||
integrity sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ== |
||||
dependencies: |
||||
date-format "^2.1.0" |
||||
debug "^4.1.1" |
||||
fs-extra "^8.1.0" |
||||
|
||||
toidentifier@1.0.0: |
||||
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" |
||||
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== |
||||
|
||||
type-is@~1.6.17, type-is@~1.6.18: |
||||
version "1.6.18" |
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" |
||||
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== |
||||
dependencies: |
||||
media-typer "0.3.0" |
||||
mime-types "~2.1.24" |
||||
|
||||
universalify@^0.1.0: |
||||
version "0.1.2" |
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" |
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== |
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0: |
||||
version "1.0.0" |
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" |
||||
integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= |
||||
|
||||
utils-merge@1.0.1: |
||||
version "1.0.1" |
||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" |
||||
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= |
||||
|
||||
vary@~1.1.2: |
||||
version "1.1.2" |
||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" |
||||
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= |
Loading…
Reference in new issue