aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/files.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/files.js')
-rw-r--r--src/files.js112
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
3var 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
10exports = module.exports = {
11 get: get,
12 put: put,
13 del: del
14};
15
16var FILE_BASE = path.resolve(__dirname, '../files');
17
18// http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js
19function 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
46function render(view, options) {
47 return ejs.render(fs.readFileSync(view, 'utf8'), options);
48}
49
50function 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
57function 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
74function 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
99function 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}