UNPKG

2.56 kBJavaScriptView Raw
1var toDuplex = require('stream-to-pull-stream').duplex
2var net = require('net')
3var fs = require('fs')
4var path = require('path')
5var debug = require('debug')('multiserver:unix')
6
7// hax on double transform
8var started = false
9
10module.exports = function (opts) {
11 const socket = path.join(opts.path || '', 'socket')
12 const addr = 'unix:' + socket
13 let scope = opts.scope || 'device'
14 opts = opts || {}
15 return {
16 name: 'unix',
17 scope: function() { return scope },
18 server: function (onConnection, cb) {
19 if (started) return
20
21 if (scope !== "device") {
22 debug('Insecure scope for unix socket! Reverting to device scope')
23 scope = 'device'
24 }
25
26 debug('listening on socket %s', addr)
27
28 var server = net.createServer(opts, function (stream) {
29 stream = toDuplex(stream)
30 stream.address = addr
31 onConnection(stream)
32 }).listen(socket, cb)
33
34 server.on('error', function (e) {
35 if (e.code == 'EADDRINUSE') {
36 var clientSocket = new net.Socket()
37 clientSocket.on('error', function(e) {
38 if (e.code == 'ECONNREFUSED') {
39 fs.unlinkSync(socket)
40 server.listen(socket)
41 }
42 })
43
44 clientSocket.connect({ path: socket }, function() {
45 debug('someone else is listening on socket!')
46 })
47 }
48 })
49
50 if (process.platform !== 'win32') {
51 fs.chmodSync(socket, 0600)
52 }
53
54 started = true
55
56 return function () {
57 server.close()
58 }
59 },
60 client: function (opts, cb) {
61 debug('unix socket client')
62 var started = false
63 var stream = net.connect(opts.path)
64 .on('connect', function () {
65 if(started) return
66 started = true
67
68 var _stream = toDuplex(stream)
69 _stream.address = addr
70 cb(null, _stream)
71 })
72 .on('error', function (err) {
73 debug('err? %o', err)
74 if(started) return
75 started = true
76 cb(err)
77 })
78
79 return function () {
80 started = true
81 stream.destroy()
82 cb(new Error('multiserver.unix: aborted'))
83 }
84 },
85 //MUST be unix:socket_path
86 parse: function (s) {
87 var ary = s.split(':')
88 if(ary.length < 2) return null
89 if('unix' !== ary.shift()) return null
90 return {
91 name: '',
92 path: ary.shift()
93 }
94 },
95 stringify: function (_scope) {
96 if(scope !== _scope) return null
97 return ['unix', socket].join(':')
98 }
99 }
100}