diff options
Diffstat (limited to 'src/files.js')
-rw-r--r-- | src/files.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/files.js b/src/files.js new file mode 100644 index 0000000..fd9c8fd --- /dev/null +++ b/src/files.js | |||
@@ -0,0 +1,112 @@ | |||
1 | 'use strict'; | ||
2 | |||
3 | var fs = require('fs'), | ||
4 | path = require('path'), | ||
5 | ejs = require('ejs'), | ||
6 | rimraf = require('rimraf'), | ||
7 | HttpError = require('connect-lastmile').HttpError, | ||
8 | HttpSuccess = require('connect-lastmile').HttpSuccess; | ||
9 | |||
10 | exports = module.exports = { | ||
11 | get: get, | ||
12 | put: put, | ||
13 | del: del | ||
14 | }; | ||
15 | |||
16 | var FILE_BASE = path.resolve(__dirname, '../files'); | ||
17 | |||
18 | // http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js | ||
19 | function copyFile(source, target, cb) { | ||
20 | var cbCalled = false; | ||
21 | |||
22 | var rd = fs.createReadStream(source); | ||
23 | rd.on("error", function(err) { | ||
24 | done(err); | ||
25 | }); | ||
26 | |||
27 | var wr = fs.createWriteStream(target); | ||
28 | wr.on("error", function(err) { | ||
29 | done(err); | ||
30 | }); | ||
31 | |||
32 | wr.on("close", function(ex) { | ||
33 | done(); | ||
34 | }); | ||
35 | |||
36 | rd.pipe(wr); | ||
37 | |||
38 | function done(err) { | ||
39 | if (!cbCalled) { | ||
40 | cb(err); | ||
41 | cbCalled = true; | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | function render(view, options) { | ||
47 | return ejs.render(fs.readFileSync(view, 'utf8'), options); | ||
48 | } | ||
49 | |||
50 | function getAbsolutePath(filePath) { | ||
51 | var absoluteFilePath = path.resolve(FILE_BASE, filePath); | ||
52 | |||
53 | if (absoluteFilePath.indexOf(FILE_BASE) !== 0) return null; | ||
54 | return absoluteFilePath; | ||
55 | } | ||
56 | |||
57 | function get(req, res, next) { | ||
58 | var filePath = req.params[0]; | ||
59 | var absoluteFilePath = getAbsolutePath(filePath); | ||
60 | if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); | ||
61 | |||
62 | fs.stat(absoluteFilePath, function (error, result) { | ||
63 | if (error) return next(new HttpError(404, error)); | ||
64 | |||
65 | console.log('get', absoluteFilePath, result); | ||
66 | |||
67 | if (result.isFile()) return res.sendfile(absoluteFilePath); | ||
68 | if (result.isDirectory()) return res.status(200).send({ entries: fs.readdirSync(absoluteFilePath) }); | ||
69 | |||
70 | return next(new HttpError(500, 'unsupported type')); | ||
71 | }); | ||
72 | } | ||
73 | |||
74 | function put(req, res, next) { | ||
75 | var filePath = req.params[0]; | ||
76 | |||
77 | if (!req.files.file) return next(new HttpError(400, 'missing file')); | ||
78 | |||
79 | var absoluteFilePath = getAbsolutePath(filePath); | ||
80 | if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); | ||
81 | |||
82 | fs.stat(absoluteFilePath, function (error, result) { | ||
83 | if (error && error.code !== 'ENOENT') return next(new HttpError(500, error)); | ||
84 | |||
85 | console.log('put', absoluteFilePath, result, req.files.file); | ||
86 | |||
87 | if (result && result.isDirectory()) return next(new HttpError(409, 'cannot put on directories')); | ||
88 | if (!result || result.isFile()) { | ||
89 | return copyFile(req.files.file.path, absoluteFilePath, function (error) { | ||
90 | if (error) return next(new HttpError(500, error)); | ||
91 | next(new HttpSuccess(201, {})); | ||
92 | }); | ||
93 | } | ||
94 | |||
95 | return next(new HttpError(500, 'unsupported type')); | ||
96 | }); | ||
97 | } | ||
98 | |||
99 | function del(req, res, next) { | ||
100 | var filePath = req.params[0]; | ||
101 | var absoluteFilePath = getAbsolutePath(filePath); | ||
102 | if (!absoluteFilePath) return next(new HttpError(403, 'Path not allowed')); | ||
103 | |||
104 | fs.stat(absoluteFilePath, function (error, result) { | ||
105 | if (error) return next(new HttpError(404, error)); | ||
106 | |||
107 | rimraf(absoluteFilePath, function (error) { | ||
108 | if (error) return next(new HttpError(500, 'Unable to remove')); | ||
109 | next(new HttpError(200, {})); | ||
110 | }); | ||
111 | }); | ||
112 | } | ||