index.jsView |
---|
11 | 11 … | var lru = require('lrucache') |
12 | 12 … | var webresolve = require('ssb-web-resolver') |
13 | 13 … | var serveEmoji = require('emoji-server')() |
14 | 14 … | var refs = require('ssb-ref') |
| 15 … | +var BoxStream = require('pull-box-stream') |
15 | 16 … | var h = require('hyperscript') |
16 | 17 … | var { |
17 | 18 … | MdRenderer, |
18 | 19 … | renderEmoji, |
28 | 29 … | var appHash = hash([fs.readFileSync(__filename)]) |
29 | 30 … | |
30 | 31 … | var urlIdRegex = /^(?:\/(([%&@]|%25|%26|%40)(?:[A-Za-z0-9\/+]|%2[Ff]|%2[Bb]){43}(?:=|%3[Dd])\.(?:sha256|ed25519))(?:\.([^?]*))?|(\/.*?))(?:\?(.*))?$/ |
31 | 32 … | |
| 33 … | +var zeros = new Buffer(24); zeros.fill(0) |
| 34 … | + |
32 | 35 … | function hash(arr) { |
33 | 36 … | return arr.reduce(function (hash, item) { |
34 | 37 … | return hash.update(String(item)) |
35 | 38 … | }, crypto.createHash('sha256')).digest('base64') |
98 | 101 … | } |
99 | 102 … | switch (m[2]) { |
100 | 103 … | case '%': return serveId(req, res, m[1], m[3], m[5]) |
101 | 104 … | case '@': return serveFeed(req, res, m[1], m[3], m[5]) |
102 | | - case '&': return serveBlob(req, res, sbot, m[1]) |
| 105 … | + case '&': return serveBlob(req, res, sbot, m[1], m[5]) |
103 | 106 … | } |
104 | 107 … | |
105 | 108 … | if (m[4] === '/') return serveHome(req, res, m[5]) |
106 | 109 … | return respond(res, 404, 'Not found') |
460 | 463 … | cb(null, msg) |
461 | 464 … | } |
462 | 465 … | } |
463 | 466 … | |
464 | | -function serveBlob(req, res, sbot, id) { |
465 | | - if (req.headers['if-none-match'] === id) return respond(res, 304) |
| 467 … | +function serveBlob(req, res, sbot, id, query) { |
| 468 … | + var q = query && qs.parse(query) |
| 469 … | + var unbox = q && typeof q.unbox === 'string' && q.unbox.replace(/\s/g, '+') |
| 470 … | + var etag = id + (unbox || '') |
| 471 … | + |
| 472 … | + if (req.headers['if-none-match'] === etag) return respond(res, 304) |
466 | 473 … | sbot.blobs.has(id, function (err, has) { |
467 | 474 … | if (err) { |
468 | 475 … | if (/^invalid/.test(err.message)) return respond(res, 400, err.message) |
469 | 476 … | else return respond(res, 500, err.message || err) |
470 | 477 … | } |
471 | 478 … | if (!has) return respond(res, 404, 'Not found') |
| 479 … | + |
| 480 … | + var unboxKey |
| 481 … | + if (unbox) { |
| 482 … | + try { unboxKey = new Buffer(unbox, 'base64') } |
| 483 … | + catch(e) { return respond(res, 400, err.message) } |
| 484 … | + if (unboxKey.length !== 32) return respond(res, 400, 'Bad blob key') |
| 485 … | + } |
| 486 … | + |
472 | 487 … | res.writeHead(200, { |
473 | 488 … | 'Cache-Control': 'public, max-age=315360000', |
474 | | - 'etag': id |
| 489 … | + 'etag': etag |
475 | 490 … | }) |
| 491 … | + |
476 | 492 … | pull( |
477 | 493 … | sbot.blobs.get(id), |
| 494 … | + unboxKey ? BoxStream.createUnboxStream(unboxKey, zeros) : null, |
478 | 495 … | toPull(res, function (err) { |
479 | 496 … | if (err) console.error('[viewer]', err) |
480 | 497 … | }) |
481 | 498 … | ) |