Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.4
164 changes: 80 additions & 84 deletions app/api/controllers/FileController.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,93 +5,89 @@
* @help :: See http://sailsjs.org/#!/documentation/concepts/Controllers
*/

var fs = require('fs-extra')
,path = require('path')
/* global sails */

const fs = require('fs-extra')
const path = require('path')

// Source: http://weeknumber.net/how-to/javascript
// Returns the ISO week of the date.
var getWeek = function(dt) {
var date = new Date(dt.getTime());
date.setHours(0, 0, 0, 0);
// Thursday in current week decides the year.
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
// January 4 is always in week 1.
var week1 = new Date(date.getFullYear(), 0, 4);
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000
- 3 + (week1.getDay() + 6) % 7) / 7);
const getWeek = function (dt) {
const date = new Date(dt.getTime())
date.setHours(0, 0, 0, 0)
// Thursday in current week decides the year.
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7)
// January 4 is always in week 1.
const week1 = new Date(date.getFullYear(), 0, 4)
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7)
}

module.exports = {

/**
* Handle incoming file upload.
*/
upload: function(req, res) {
// Use the session timestamp as the file timestamp (so that pcap parts for example
// end up to the same folder .. )
var dt = new Date(parseInt(req.params.filename.split('_')[0]));

sails.log.debug('[FileController] [' + dt.toString() + '] upload req client=' +
req.clientip+', version=' + req.params.version +
', deviceid=' + req.params.deviceid +
', filename=' + req.params.filename);

var dstdir = path.join(
sails.config.upload.datadir,
req.params.deviceid,
req.params.version.replace(/,/g,'.'),
dt.getFullYear()+'',
getWeek(dt)+'');

sails.log.verbose("[FileController] ensure dir " + dstdir);

fs.ensureDir(dstdir, function(err) {
if (err) {
sails.log.error(err);
return res.serverError();
}

// ug+rwx, o+rx
fs.chmodSync(dstdir, '775');

var dstfile = path.join(dstdir, req.params.filename);
sails.log.verbose("[FileController] start writing " + dstfile);

var pipe = req.pipe(fs.createWriteStream(dstfile));

pipe.on('error', function(err) {
sails.log.error(err);
return res.serverError();
});

pipe.on('finish', function() {
fs.stat(dstfile, function(err, stats) {
if (err || !stats || !stats.isFile()) {
sails.log.error("[FileController] failed to create " +
dstfile);
if (err) sails.log.error(err);
return res.serverError();

} else if (stats['size'] != req.headers['content-length']) {
// missing bytes
sails.log.debug("[FileController] failed to write " +
dstfile + ", wrote " + stats['size'] + " bytes " +
" got " + req.headers['content-length'] + " bytes");

fs.unlink(dstfile);
return res.serverError();

} else {
// all good
// ug+rw, o+r
fs.chmodSync(dstfile, '664');
sails.log.debug("[FileController] wrote " + stats['size'] +
" bytes to " + dstfile);
return res.ok();
}
}); // fstat
}); // onFinish
}); // ensureDir
} // upload
};
/**
* Handle incoming file upload.
*/
upload: function (req, res) {
// Use the session timestamp as the file timestamp (so that pcap parts for example
// end up to the same folder .. )
const dt = new Date(parseInt(req.params.filename.split('_')[0]))

sails.log.debug('[FileController] [' + dt.toString() + '] upload req client=' +
req.clientip + ', version=' + req.params.version +
', deviceid=' + req.params.deviceid +
', filename=' + req.params.filename)

const dstdir = path.join(
sails.config.upload.datadir,
req.params.deviceid,
req.params.version.replace(/,/g, '.'),
dt.getFullYear().toString(),
getWeek(dt).toString())

sails.log.verbose('[FileController] ensure dir ' + dstdir)

fs.ensureDir(dstdir, function (err) {
if (err) {
sails.log.error(err)
return res.serverError()
}

// ug+rwx, o+rx
fs.chmodSync(dstdir, '775')

const dstfile = path.join(dstdir, req.params.filename)
sails.log.verbose('[FileController] start writing ' + dstfile)

const pipe = req.pipe(fs.createWriteStream(dstfile))

pipe.on('error', function (err) {
sails.log.error(err)
return res.serverError()
})

pipe.on('finish', function () {
fs.stat(dstfile, function (err, stats) {
if (err || !stats || !stats.isFile()) {
sails.log.error('[FileController] failed to create ' + dstfile)
if (err) sails.log.error(err)
return res.serverError()
} else if (stats['size'].toString() !== req.headers['content-length']) {
// missing bytes
sails.log.debug('[FileController] failed to write ' +
dstfile + ', wrote ' + stats['size'] + ' bytes ' +
' got ' + req.headers['content-length'] + ' bytes')

fs.unlink(dstfile)
return res.serverError()
} else {
// all good
// ug+rw, o+r
fs.chmodSync(dstfile, '664')
sails.log.debug('[FileController] wrote ' + stats['size'] + ' bytes to ' + dstfile)
return res.ok()
}
}) // fstat
}) // onFinish
}) // ensureDir
} // upload
}
56 changes: 27 additions & 29 deletions app/api/responses/badRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,61 @@
* );
* ```
*/

module.exports = function badRequest(data, options) {

module.exports = function (data, options) {
'use strict'
// Get access to `req`, `res`, & `sails`
var req = this.req;
var res = this.res;
var sails = req._sails;
const req = this.req
const res = this.res
const sails = req._sails

// Set status code
res.status(400);
res.status(400)

// Log error to console
if (data !== undefined) {
sails.log.verbose('Sending 400 ("Bad Request") response: \n',data);
if (data) {
sails.log.verbose('Sending 400 ("Bad Request") response: \n', data)
} else {
sails.log.verbose('Sending 400 ("Bad Request") response')
}
else sails.log.verbose('Sending 400 ("Bad Request") response');

// Only include errors in response if application environment
// is not set to 'production'. In production, we shouldn't
// send back any identifying information about errors.
if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) {
data = undefined;
data = undefined
}

// If the user-agent wants JSON, always respond with JSON
// If views are disabled, revert to json
if (req.wantsJSON || sails.config.hooks.views === false) {
return res.jsonx(data);
return res.jsonx(data)
}

// If second argument is a string, we take that to mean it refers to a view.
// If it was omitted, use an empty object (`{}`)
options = (typeof options === 'string') ? { view: options } : options || {};
options = (typeof options === 'string') ? { view: options } : options || {}

// Attempt to prettify data for views, if it's a non-error object
var viewData = data;
if (!(viewData instanceof Error) && 'object' == typeof viewData) {
let viewData = data

if (!(viewData instanceof Error) && (typeof viewData === 'object')) {
try {
viewData = require('util').inspect(data, {depth: null});
}
catch(e) {
viewData = undefined;
viewData = require('util').inspect(data, {depth: null})
} catch (e) {
viewData = undefined
}
}

// If a view was provided in options, serve it.
// Otherwise try to guess an appropriate view, or if that doesn't
// work, just send JSON.
if (options.view) {
return res.view(options.view, { data: viewData, title: 'Bad Request' });
return res.view(options.view, { data: viewData, title: 'Bad Request' })
} else {
// If no second argument provided, try to serve the implied view,
// but fall back to sending JSON(P) if no view can be inferred.
return res.guessView({ data: viewData, title: 'Bad Request' }, function () {
return res.jsonx(data)
})
}

// If no second argument provided, try to serve the implied view,
// but fall back to sending JSON(P) if no view can be inferred.
else return res.guessView({ data: viewData, title: 'Bad Request' }, function couldNotGuessView () {
return res.jsonx(data);
});

};

}
83 changes: 39 additions & 44 deletions app/api/responses/forbidden.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,79 +11,74 @@
* return res.forbidden('Access denied.');
* ```
*/

module.exports = function forbidden (data, options) {

module.exports = function (data, options) {
'use strict'
// Get access to `req`, `res`, & `sails`
var req = this.req;
var res = this.res;
var sails = req._sails;
const req = this.req
const res = this.res
const sails = req._sails

// Set status code
res.status(403);
res.status(403)

// Log error to console
if (data !== undefined) {
sails.log.verbose('Sending 403 ("Forbidden") response: \n',data);
if (data) {
sails.log.verbose('Sending 403 ("Forbidden") response: \n', data)
} else {
sails.log.verbose('Sending 403 ("Forbidden") response')
}
else sails.log.verbose('Sending 403 ("Forbidden") response');

// Only include errors in response if application environment
// is not set to 'production'. In production, we shouldn't
// send back any identifying information about errors.
if (sails.config.environment === 'production' && sails.config.keepResponseErrors !== true) {
data = undefined;
data = undefined
}

// If the user-agent wants JSON, always respond with JSON
// If views are disabled, revert to json
if (req.wantsJSON || sails.config.hooks.views === false) {
return res.jsonx(data);
return res.jsonx(data)
}

// If second argument is a string, we take that to mean it refers to a view.
// If it was omitted, use an empty object (`{}`)
options = (typeof options === 'string') ? { view: options } : options || {};
options = (typeof options === 'string') ? { view: options } : options || {}

// Attempt to prettify data for views, if it's a non-error object
var viewData = data;
if (!(viewData instanceof Error) && 'object' == typeof viewData) {
let viewData = data

if (!(viewData instanceof Error) && (typeof viewData === 'object')) {
try {
viewData = require('util').inspect(data, {depth: null});
}
catch(e) {
viewData = undefined;
viewData = require('util').inspect(data, {depth: null})
} catch (e) {
viewData = undefined
}
}

// If a view was provided in options, serve it.
// Otherwise try to guess an appropriate view, or if that doesn't
// work, just send JSON.
if (options.view) {
return res.view(options.view, { data: viewData, title: 'Forbidden' });
}

// If no second argument provided, try to serve the default view,
// but fall back to sending JSON(P) if any errors occur.
else return res.view('403', { data: viewData, title: 'Forbidden' }, function (err, html) {

// If a view error occured, fall back to JSON(P).
if (err) {
//
// Additionally:
// • If the view was missing, ignore the error but provide a verbose log.
if (err.code === 'E_VIEW_FAILED') {
sails.log.verbose('res.forbidden() :: Could not locate view for error page (sending JSON instead). Details: ',err);
}
// Otherwise, if this was a more serious error, log to the console with the details.
else {
sails.log.warn('res.forbidden() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err);
return res.view(options.view, { data: viewData, title: 'Forbidden' })
} else {
// If no second argument provided, try to serve the default view,
// but fall back to sending JSON(P) if any errors occur.
return res.view('403', { data: viewData, title: 'Forbidden' }, function (err, html) {
// If a view error occured, fall back to JSON(P).
if (err) {
// Additionally:
// • If the view was missing, ignore the error but provide a verbose log.
if (err.code === 'E_VIEW_FAILED') {
sails.log.verbose('res.forbidden() :: Could not locate view for error page (sending JSON instead). Details: ', err)
} else {
// Otherwise, if this was a more serious error, log to the console with the details.
sails.log.warn('res.forbidden() :: When attempting to render error page view, an error occured (sending JSON instead). Details: ', err)
}
return res.jsonx(data)
}
return res.jsonx(data);
}

return res.send(html);
});

};

return res.send(html)
})
}
}
Loading