git ssb

0+

Dominic / multiblob-http



Tree: ab2db5816540d4eaf2e71a3d8b00a0b297c3da74

Files: ab2db5816540d4eaf2e71a3d8b00a0b297c3da74 / index.js

2896 bytesRaw
1var pull = require('pull-stream')
2var toPull = require('stream-to-pull-stream')
3
4var qs = require('querystring')
5var URL = require('url')
6
7var YEAR = 60*60*24*365
8
9function headers(res, hash) {
10 //don't set cache control because (i think) that tells
11 //the browser to not keep the cache
12 res.setHeader('cache-control', 'maxage='+YEAR)
13 //expires makes the brower not even revalidate.
14 res.setHeader('expires', new Date(Date.now()+YEAR*1000).toISOString())
15 res.setHeader('expiry', new Date(Date.now()+YEAR*1000).toISOString())
16 res.setHeader('etag', hash)
17}
18
19//host blobs
20module.exports = function (blobs, url, opts) {
21 opts = opts || {}
22 return function (req, res, next) {
23
24 next = next || function (err) {
25 res.writeHead(404, {'Content-Type': 'application/json'})
26 res.end(JSON.stringify({error: true, status: 404}))
27 }
28
29 if(req.method === 'POST' && req.url === url+'/add' && opts.readonly !== true)
30 pull(
31 toPull(req),
32 blobs.add(function (err, hash) {
33 res.end(hash)
34 })
35 )
36 else if(req.url.indexOf(url+'/get/') == 0) {
37 if(!(req.method === "GET" || req.method == 'HEAD')) return next()
38
39 var u = URL.parse('http://makeurlparseright.com'+req.url)
40 var hash = decodeURIComponent(u.pathname.substring((url+'/get/').length))
41 var q = qs.parse(u.query)
42
43
44 //if a browser revalidates, just tell them it hasn't changed, the hash has not changed.
45 if(req.headers['if-none-match'] === hash) {
46 headers(res, hash)
47 return res.writeHead(304), res.end()
48 }
49
50 //enable cors by default
51 if(opts.cors !== false) {
52 res.setHeader('Access-Control-Allow-Origin', '*')
53 }
54
55 // prevent timeout while waiting for blob
56 res.setTimeout(0)
57
58 blobs.size(hash, function (err, size) {
59 if(err) return next(err)
60 if(!size) return next(new Error('no blob:'+hash))
61
62 headers(res, hash)
63 res.setHeader('content-length', size)
64
65 if(q.filename)
66 res.setHeader('Content-Discosition', 'inline; filename='+q.filename)
67
68 if(q.gzip)
69 res.setHeader('Content-Encoding', 'gzip')
70
71 if(q.contentType)
72 res.setHeader('Content-Type', q.contentType)
73
74 //writing the status code now.
75 res.writeHead(200)
76 if(req.method === 'HEAD') return res.end()
77
78 pull(
79 blobs.get(hash),
80 //since this is an http stream, handle error the http way.
81 //there is nothing we can do about an error now, since
82 //we already wrote the headers. but since we included content-length
83 //the client will know it went wrong.
84// pull.through(null, function (err) {
85// if(err) throw err //DEBUG
86// if(err) next(err)
87// }),
88 toPull(res)
89 )
90 })
91 }
92 else next()
93 }
94}
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

Built with git-ssb-web