-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathstreamFile.js
More file actions
85 lines (67 loc) · 2.09 KB
/
streamFile.js
File metadata and controls
85 lines (67 loc) · 2.09 KB
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
var fsPath = require('path')
var config = require('../config/config.js')
var when = require('when')
function streamFile(req, res, next, gfs) {
var path = req.path.replace(/^\/data/, '')
var extname = fsPath.extname(path)
var model = path.split('/')[1]
var cacheControl
var expires = ''
if (config.server.useCDN) {
res.redirect(301, config.server.cdnRoot + path)
return when.resolve()
}
switch(model) {
case 'dist':
case 'graph':
// minimal caching, please
cacheControl = 'public, must-revalidate'
break;
default:
// strong caching
cacheControl = 'public'
expires = 'Sun, 17-Jan-2038 19:14:07 GMT'
break;
}
return gfs.stat(path)
.then(function(stat) {
if (!stat)
return res.status(404).send();
if (req.header('If-None-Match') === stat.md5)
return res.status(304).send();
res.header('Content-Type', stat.contentType)
res.header('Cache-Control', cacheControl)
if (expires)
res.header('Expires', expires)
if (req.headers.range) {
// stream partial file range
var parts = req.headers.range.replace(/bytes[=:]/, "").split("-");
var partialstart = parts[0];
var partialend = parts[1];
// start&end offset are inclusive, end is optional
var start = parseInt(partialstart, 10);
var end = partialend ? parseInt(partialend, 10) : (stat.length - 1);
var chunksize = (end - start) + 1;
res.header('Content-Range', 'bytes ' + start + '-' + end + '/' + stat.length);
res.header('Content-Length', chunksize)
res.header('Accept-Ranges', 'bytes')
res.status(206);
var range = {startPos: start, endPos: end};
gfs.createReadStream(path, range)
.on('error', next)
.pipe(res);
} else {
// stream whole file in a single request
// only accept range-requests on audio and video
var rangeableTypes = ['.mp3', '.m4a', '.ogg', '.mp4', '.ogm', '.ogv']
if (rangeableTypes.indexOf(extname) !== -1)
res.header('Accept-Ranges', 'bytes')
res.header('ETag', stat.md5);
res.header('Content-Length', stat.length)
gfs.createReadStream(path)
.on('error', next)
.pipe(res)
}
})
}
module.exports = streamFile