forked from ssb-junkyard/react-native-scuttlebot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserve-blobs.js
71 lines (64 loc) · 1.72 KB
/
serve-blobs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
var pull = require('pull-stream')
var cat = require('pull-cat')
var toPull = require('stream-to-pull-stream')
var ident = require('pull-identify-filetype')
var mime = require('mime-types')
var URL = require('url')
var http = require('http')
module.exports = function (sbot, cb) {
return http.createServer(ServeBlobs(sbot)).listen(7777, cb)
}
function ServeBlobs (sbot) {
return function (req, res, next) {
var parsed = URL.parse(req.url, true)
var hash = decodeURIComponent(parsed.pathname.slice(1))
waitFor(hash, function (_, has) {
if (!has) return respond(res, 404, 'File not found')
// optional name override
if (parsed.query.name) {
res.setHeader('Content-Disposition', 'inline; filename=' + encodeURIComponent(parsed.query.name))
}
// serve
res.setHeader('Content-Security-Policy', BlobCSP())
respondSource(res, sbot.blobs.get(hash), false)
})
}
function waitFor (hash, cb) {
sbot.blobs.has(hash, function (err, has) {
if (err) return cb(err)
if (has) {
cb(null, has)
} else {
sbot.blobs.want(hash, cb)
}
})
}
}
function respondSource (res, source, wrap) {
if (wrap) {
res.writeHead(200, {'Content-Type': 'text/html'})
pull(
cat([
pull.once('<html><body><script>'),
source,
pull.once('</script></body></html>')
]),
toPull.sink(res)
)
} else {
pull(
source,
ident(function (type) {
if (type) res.writeHead(200, {'Content-Type': mime.lookup(type)})
}),
toPull.sink(res)
)
}
}
function respond (res, status, message) {
res.writeHead(status)
res.end(message)
}
function BlobCSP () {
return 'default-src none; sandbox'
}