|
@@ -1,6 +1,8 @@
|
|
|
var debug = require('debug')('ylt:server');
|
|
|
+var Q = require('q');
|
|
|
|
|
|
var ylt = require('../../index');
|
|
|
+var ScreenshotHandler = require('../../screenshotHandler');
|
|
|
var RunsQueue = require('../datastores/runsQueue');
|
|
|
var RunsDatastore = require('../datastores/runsDatastore');
|
|
|
var ResultsDatastore = require('../datastores/resultsDatastore');
|
|
@@ -24,10 +26,17 @@ var ApiController = function(app) {
|
|
|
params: {
|
|
|
url: req.body.url,
|
|
|
waitForResponse: req.body.waitForResponse !== false && req.body.waitForResponse !== 'false' && req.body.waitForResponse !== 0,
|
|
|
- partialResult: req.body.partialResult || null
|
|
|
+ partialResult: req.body.partialResult || null,
|
|
|
+ screenshot: req.body.screenshot !== false && req.body.screenshot !== 'false' && req.body.screenshot !== 0
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ // Create a temporary folder to save the screenshot
|
|
|
+ var screenshot;
|
|
|
+ if (run.params.screenshot) {
|
|
|
+ screenshot = ScreenshotHandler.getScreenshotTempFile();
|
|
|
+ }
|
|
|
+
|
|
|
// Add test to the testQueue
|
|
|
debug('Adding test %s to the queue', run.runId);
|
|
|
var queuePromise = queue.push(run.runId);
|
|
@@ -49,81 +58,121 @@ var ApiController = function(app) {
|
|
|
|
|
|
debug('Launching test %s on %s', run.runId, run.params.url);
|
|
|
|
|
|
- ylt(run.params.url)
|
|
|
+ var runOptions = {
|
|
|
+ screenshot: run.params.screenshot ? screenshot.getTmpFilePath() : false
|
|
|
+ };
|
|
|
|
|
|
- .then(function(data) {
|
|
|
+ return ylt(run.params.url, runOptions);
|
|
|
|
|
|
- debug('Success');
|
|
|
-
|
|
|
+ })
|
|
|
+ // Phantomas completed, let's save the screenshot if any
|
|
|
+ .then(function(data) {
|
|
|
+
|
|
|
+ debug('Success');
|
|
|
+ data.runId = run.runId;
|
|
|
+
|
|
|
+
|
|
|
+ // Some conditional steps are made if there is a screenshot
|
|
|
+ var screenshotPromise = Q.resolve();
|
|
|
+
|
|
|
+ if (run.params.screenshot) {
|
|
|
+
|
|
|
+ // Replace the empty promise created earlier with Q.resolve()
|
|
|
+ screenshotPromise = screenshot.toThumbnail(640)
|
|
|
+
|
|
|
+ // Read screenshot
|
|
|
+ .then(function(screenshotBuffer) {
|
|
|
+
|
|
|
+ if (screenshotBuffer) {
|
|
|
+ debug('Image optimized');
|
|
|
+ data.screenshotBuffer = screenshotBuffer;
|
|
|
+
|
|
|
+ // Official path to get the image
|
|
|
+ data.screenshotUrl = '/result/' + data.runId + '/screenshot.jpg';
|
|
|
+ }
|
|
|
+
|
|
|
+ delete data.params.options.screenshot;
|
|
|
+
|
|
|
+ })
|
|
|
+ // Delete screenshot temporary file
|
|
|
+ .then(screenshot.deleteTmpFile);
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- // Save result in datastore
|
|
|
- data.runId = run.runId;
|
|
|
- resultsDatastore.saveResult(data)
|
|
|
- .then(function() {
|
|
|
-
|
|
|
- runsDatastore.markAsComplete(run.runId);
|
|
|
-
|
|
|
- // Send result if the user was waiting
|
|
|
- if (run.params.waitForResponse) {
|
|
|
-
|
|
|
- // If the user only wants a portion of the result (partialResult option)
|
|
|
- switch(run.params.partialResult) {
|
|
|
- case 'generalScores':
|
|
|
- res.redirect(302, '/api/results/' + run.runId + '/generalScores');
|
|
|
- break;
|
|
|
- case 'rules':
|
|
|
- res.redirect(302, '/api/results/' + run.runId + '/rules');
|
|
|
- break;
|
|
|
- case 'javascriptExecutionTree':
|
|
|
- res.redirect(302, '/api/results/' + run.runId + '/javascriptExecutionTree');
|
|
|
- break;
|
|
|
- case 'phantomas':
|
|
|
- res.redirect(302, '/api/results/' + run.runId + '/toolsResults/phantomas');
|
|
|
- break;
|
|
|
- default:
|
|
|
- res.redirect(302, '/api/results/' + run.runId);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- })
|
|
|
- .fail(function(err) {
|
|
|
- debug('Saving results to resultsDatastore failed:');
|
|
|
- debug(err);
|
|
|
-
|
|
|
- res.status(500).send('Saving results failed');
|
|
|
- });
|
|
|
+ // Let's continue
|
|
|
+ screenshotPromise
|
|
|
|
|
|
+ // Save results
|
|
|
+ .then(function() {
|
|
|
+ return resultsDatastore.saveResult(data);
|
|
|
})
|
|
|
|
|
|
+ // Mark as the run as complete and send the response if the request is still waiting
|
|
|
+ .then(function() {
|
|
|
+
|
|
|
+ debug('Result saved in datastore');
|
|
|
+
|
|
|
+ runsDatastore.markAsComplete(run.runId);
|
|
|
+
|
|
|
+ if (run.params.waitForResponse) {
|
|
|
+
|
|
|
+ // If the user only wants a portion of the result (partialResult option)
|
|
|
+ switch(run.params.partialResult) {
|
|
|
+ case 'generalScores':
|
|
|
+ res.redirect(302, '/api/results/' + run.runId + '/generalScores');
|
|
|
+ break;
|
|
|
+ case 'rules':
|
|
|
+ res.redirect(302, '/api/results/' + run.runId + '/rules');
|
|
|
+ break;
|
|
|
+ case 'javascriptExecutionTree':
|
|
|
+ res.redirect(302, '/api/results/' + run.runId + '/javascriptExecutionTree');
|
|
|
+ break;
|
|
|
+ case 'phantomas':
|
|
|
+ res.redirect(302, '/api/results/' + run.runId + '/toolsResults/phantomas');
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ res.redirect(302, '/api/results/' + run.runId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ })
|
|
|
.fail(function(err) {
|
|
|
-
|
|
|
console.error('Test failed for URL: %s', run.params.url);
|
|
|
console.error(err.toString());
|
|
|
|
|
|
runsDatastore.markAsFailed(run.runId, err.toString());
|
|
|
|
|
|
- res.status(400).send('Bad request');
|
|
|
+ res.status(500).send('An error occured');
|
|
|
+ });
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ .fail(function(err) {
|
|
|
|
|
|
- })
|
|
|
+ console.error('Test failed for URL: %s', run.params.url);
|
|
|
+ console.error(err.toString());
|
|
|
|
|
|
- .finally(function() {
|
|
|
- queue.remove(run.runId);
|
|
|
- });
|
|
|
+ runsDatastore.markAsFailed(run.runId, err.toString());
|
|
|
+
|
|
|
+ res.status(400).send('Bad request');
|
|
|
+
|
|
|
+ })
|
|
|
|
|
|
- }).fail(function(err) {
|
|
|
- console.error('Error or YLT\'s core instanciation');
|
|
|
- console.error(err);
|
|
|
- console.error(err.stack);
|
|
|
+ .finally(function() {
|
|
|
+ queue.remove(run.runId);
|
|
|
});
|
|
|
|
|
|
- // The user doesn't not want to wait for the response, sending the run ID only
|
|
|
+
|
|
|
+ // The user doesn't want to wait for the response, sending the run ID only
|
|
|
if (!run.params.waitForResponse) {
|
|
|
console.log('Sending response without waiting.');
|
|
|
res.setHeader('Content-Type', 'application/json');
|
|
|
res.send(JSON.stringify({runId: run.runId}));
|
|
|
}
|
|
|
+
|
|
|
});
|
|
|
|
|
|
+
|
|
|
// Retrive one run by id
|
|
|
app.get('/api/runs/:id', function(req, res) {
|
|
|
var runId = req.params.id;
|