]>
git.immae.eu Git - perso/Immae/Projets/Nodejs/Surfer.git/blob - src/files.js
3 var async
= require('async'),
5 path
= require('path'),
7 debug
= require('debug')('files'),
8 mkdirp
= require('mkdirp'),
9 HttpError
= require('connect-lastmile').HttpError
,
10 HttpSuccess
= require('connect-lastmile').HttpSuccess
;
14 exports
= module
.exports = function (basePath
) {
24 // http://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js
25 function copyFile(source
, target
, cb
) {
29 mkdirp(path
.dirname(target
), function (error
) {
30 if (error
) return cb(error
);
32 var rd
= fs
.createReadStream(source
);
33 rd
.on("error", function(err
) {
37 var wr
= fs
.createWriteStream(target
);
38 wr
.on("error", function(err
) {
42 wr
.on("close", function(ex
) {
57 function createDirectory(targetPath
, callback
) {
58 mkdirp(targetPath
, function (error
) {
59 if (error
) return callback(error
);
64 function isProtected(targetPath
) {
65 return targetPath
.indexOf(getAbsolutePath('_admin')) === 0;
68 function getAbsolutePath(filePath
) {
69 var absoluteFilePath
= path
.resolve(path
.join(gBasePath
, filePath
));
71 if (absoluteFilePath
.indexOf(gBasePath
) !== 0) return null;
72 return absoluteFilePath
;
75 function removeBasePath(filePath
) {
76 return filePath
.slice(gBasePath
.length
);
79 function get(req
, res
, next
) {
80 var filePath
= decodeURIComponent(req
.params
[0]);
81 var absoluteFilePath
= getAbsolutePath(filePath
);
82 if (!absoluteFilePath
) return next(new HttpError(403, 'Path not allowed'));
84 fs
.stat(absoluteFilePath
, function (error
, result
) {
85 if (error
) return next(new HttpError(404, error
));
87 debug('get', absoluteFilePath
);
89 if (!result
.isDirectory() && !result
.isFile()) return next(new HttpError(500, 'unsupported type'));
90 if (result
.isFile()) return res
.sendFile(absoluteFilePath
);
92 async
.map(fs
.readdirSync(absoluteFilePath
), function (filePath
, callback
) {
93 fs
.stat(path
.join(absoluteFilePath
, filePath
), function (error
, result
) {
94 if (error
) return callback(error
);
97 isDirectory: result
.isDirectory(),
98 isFile: result
.isFile(),
102 birthtime: result
.birthtime
,
107 }, function (error
, results
) {
108 if (error
) return next(new HttpError(500, error
));
109 res
.status(222).send({ entries: results
});
114 function put(req
, res
, next
) {
115 var filePath
= decodeURIComponent(req
.params
[0]);
117 if (!(req
.files
&& req
.files
.file
) && !req
.query
.directory
) return next(new HttpError(400, 'missing file or directory'));
118 if ((req
.files
&& req
.files
.file
) && req
.query
.directory
) return next(new HttpError(400, 'either file or directory'));
120 var absoluteFilePath
= getAbsolutePath(filePath
);
121 if (!absoluteFilePath
|| isProtected(absoluteFilePath
)) return next(new HttpError(403, 'Path not allowed'));
123 fs
.stat(absoluteFilePath
, function (error
, result
) {
124 if (error
&& error
.code
!== 'ENOENT') return next(new HttpError(500, error
));
126 debug('put', absoluteFilePath
);
128 if (result
&& req
.query
.directory
) return next(new HttpError(409, 'name already exists'));
129 if (result
&& result
.isDirectory()) return next(new HttpError(409, 'cannot put on directories'));
131 if (req
.query
.directory
) {
132 return createDirectory(absoluteFilePath
, function (error
) {
133 if (error
) return next(new HttpError(500, error
));
134 next(new HttpSuccess(201, {}));
136 } else if (!result
|| result
.isFile()) {
137 return copyFile(req
.files
.file
.path
, absoluteFilePath
, function (error
) {
138 if (error
) return next(new HttpError(500, error
));
139 next(new HttpSuccess(201, {}));
143 return next(new HttpError(500, 'unsupported type'));
147 function del(req
, res
, next
) {
148 var filePath
= decodeURIComponent(req
.params
[0]);
149 var recursive
= !!req
.query
.recursive
;
150 var dryRun
= !!req
.query
.dryRun
;
152 var absoluteFilePath
= getAbsolutePath(filePath
);
153 if (!absoluteFilePath
) return next(new HttpError(404, 'Not found'));
155 if (isProtected(absoluteFilePath
)) return next(new HttpError(403, 'Path not allowed'));
157 // absoltueFilePath has to have the base path prepended
158 if (absoluteFilePath
.length
<= gBasePath
.length
) return next(new HttpError(404, 'Not found'));
160 fs
.stat(absoluteFilePath
, function (error
, result
) {
161 if (error
) return next(new HttpError(404, error
));
163 if (result
.isDirectory() && !recursive
) return next(new HttpError(403, 'Is directory'));
165 // add globs to get file listing
166 if (result
.isDirectory()) absoluteFilePath
+= '/**';
168 rm(absoluteFilePath
, { dryRun: dryRun
, force: true }).then(function (result
) {
169 result
= result
.map(removeBasePath
);
170 next(new HttpSuccess(200, { entries: result
}));
171 }, function (error
) {
172 console
.error(error
);
173 next(new HttpError(500, 'Unable to remove'));