git ssb

0+

cel / ssb-exec



Tree: 464b2ebf04198512fa3e2bc5a3ab92e8e799ab93

Files: 464b2ebf04198512fa3e2bc5a3ab92e8e799ab93 / index.js

3177 bytesRaw
1/* ssb-exec
2 * © 2019 cel @f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519
3 *
4 * Usage of the works is permitted provided that this instrument is
5 * retained with the works, so that any entity that uses the works is
6 * notified of this instrument.
7 *
8 * DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
9 */
10
11var url = require('url')
12var path = require('path')
13var fs = require('fs')
14
15var blobsDir = path.resolve(__dirname, '../../blobs')
16
17exports.requireBlob = function (id) {
18 var m = /^\&([0-9a-zA-Z\/+=]{44})\.(sha256)$/.exec(id)
19 if (!m) throw new Error('invalid blob id: ' + id)
20 var hex = new Buffer(m[1], 'base64').toString('hex')
21 return require(path.join(blobsDir, m[2], hex.substr(0, 2), hex.substr(2)))
22}
23
24exports.name = 'exec'
25exports.version = '1.0.0'
26exports.manifest = {
27}
28exports.init = function (sbot, config) {
29 if (!sbot.ws || !sbot.ws.use) return console.trace('missing ssb-ws')
30 var prefix = '/exec'
31 var dir = path.join(config.path, 'exec')
32 blobsDir = path.join(config.path, 'blobs')
33 var mtimes = {}
34 console.log('[exec] init. dir:', dir, 'prefix:', prefix)
35
36 function getModule(resolved, tried, cb) {
37 try {
38 var module = require(resolved)
39 return cb(null, module)
40 } catch(e) {
41 if (tried || !e || !(e.code === 'ENOENT' || e.code === 'MODULE_NOT_FOUND')) return cb(e)
42 var m = /(sha256)\/([0-9a-f]{2})\/([0-9a-f]{62})/.exec(e.path || e.message)
43 if (!m) return cb(e)
44 var blobId = '&' + new Buffer(m[2] + m[3], 'hex').toString('base64') + '.' + m[1]
45 if (!sbot.blobs) return cb(new Error('Missing ssb-blobs plugin'))
46 if (typeof sbot.blobs.want !== 'function') return cb(new Error('missing blobs.want method'))
47 return sbot.blobs.want(blobId, function (err, has) {
48 if (err) return cb(new Error('Unable to get blob: ' + (err.stack || err)))
49 if (!has) return cb(new Error('Unable to get blob'))
50 getModule(resolved, true, cb)
51 })
52 }
53 }
54
55 sbot.ws.use(function (req, res, next) {
56 if (prefix !== req.url.substr(0, prefix.length)) return next()
57 if (prefix === req.url) {
58 res.writeHead(302, {Location: path.basename(prefix) + '/'})
59 return res.end()
60 }
61 try {
62 req.uri = url.parse(req.url.substr(prefix.length), true)
63 var file = path.normalize(path.join(dir, req.uri.pathname))
64 if (dir !== file.substr(0, dir.length)) {
65 res.writeHead(403)
66 return res.end('Forbidden')
67 }
68 var resolved = require.resolve(file)
69 var prevMtime = mtimes[resolved]
70 var mtime = fs.statSync(resolved).mtime.getTime()
71 if (mtime !== prevMtime) {
72 delete require.cache[resolved]
73 mtimes[resolved] = mtime
74 }
75 getModule(resolved, false, gotModule)
76 } catch(e) {
77 return gotError(e)
78 }
79
80 function gotError(err) {
81 try {
82 res.writeHead(err.code === 'ENOENT' || err.code === 'MODULE_NOT_FOUND' ? 404 : 500)
83 } finally {
84 res.end(err.stack || err)
85 }
86 }
87
88 function gotModule(err, module) {
89 if (err) return gotError(err)
90 try {
91 module(req, res, sbot, config)
92 } catch(e) {
93 gotError(e)
94 }
95 }
96 })
97}
98

Built with git-ssb-web