main.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. var http = require('http');
  2. var qs = require('querystring');
  3. var fs = require('fs');
  4. var spawn = require('child_process').spawn;
  5. var helpers = require('./helpers.js');
  6. var v1 = require('./converters/v1.js');
  7. var v2 = require('./converters/v2.js');
  8. var MAX_FILE_SIZE = 5 * 1024 * 1024;
  9. var TMP_DIR_NAME = process.cwd() + '/' + 'tmp/';
  10. var SCRIPT = fs.readFileSync('./save_script_tpl.js', { encoding: 'utf8' });
  11. var PORT = 1337;
  12. if (!fs.existsSync(TMP_DIR_NAME)) {
  13. fs.mkdirSync(TMP_DIR_NAME);
  14. }
  15. var defaultHeaders = {
  16. 'Content-Type': 'text/plain',
  17. 'Access-Control-Allow-Origin': '*'
  18. };
  19. function respond(response, code, data, headers) {
  20. headers = helpers.apply({}, headers, defaultHeaders);
  21. response.writeHead(code, headers);
  22. response.end(data);
  23. if (code !== 200) { // something's not OK, "tweet" the reason, if not too long
  24. if (typeof data === 'string') {
  25. console.warn(data.length > 140 ? data.substr(0, 140) : data);
  26. }
  27. }
  28. }
  29. var counter = (function () {
  30. var value = 0,
  31. max_int = Math.pow(2, 32) - 1;
  32. return function () {
  33. if (value > max_int) {
  34. value = 0;
  35. }
  36. return value++;
  37. }
  38. })();
  39. console.log('Image server listening to requests on port ' + PORT + '.');
  40. http.createServer(function (request, response) {
  41. if (request.method === 'POST') {
  42. var body = '';
  43. request.on('data', function (data) {
  44. if (body.length <= MAX_FILE_SIZE) {
  45. body += data;
  46. } else {
  47. respond(response, 413, "Request entity too large.");
  48. }
  49. });
  50. request.on('end', function () {
  51. try {
  52. var config = qs.parse(body);
  53. } catch (e) {
  54. console.error("Parsing request data failed.", e);
  55. }
  56. if (config) {
  57. switch (config.version) {
  58. case '2':
  59. config = v2.convert(config);
  60. break;
  61. default:
  62. config = v1.convert(config);
  63. break;
  64. }
  65. }
  66. if (!config || !config.data) {
  67. respond(response, 400, "Bad request.");
  68. return;
  69. }
  70. console.log("Processing a request ...");
  71. var userFileName = (config.filename || 'chart') + '.' + config.format;
  72. var serverFileName = TMP_DIR_NAME + counter().toString() + '.' + config.format;
  73. var scriptFileName = TMP_DIR_NAME + counter().toString() + '.js';
  74. var script = helpers.interpolate(SCRIPT, helpers.apply(config, {
  75. filename: serverFileName
  76. }));
  77. fs.writeFile(scriptFileName, script, { encoding: 'utf8' }, function (err) {
  78. if (err) throw err;
  79. var phantom = spawn('phantomjs', [scriptFileName]);
  80. phantom.stdout.pipe(process.stdout); // proxy console output from phantom to node
  81. phantom.on('exit', function (code) {
  82. fs.unlink(scriptFileName, function () {
  83. if (err) throw err;
  84. console.log("Successfully deleted:", scriptFileName);
  85. });
  86. if (!code) {
  87. fs.readFile(serverFileName, function (err, data) {
  88. if (err) throw err;
  89. respond(response, 200, data, {
  90. 'Content-Type': config.contentType,
  91. 'Content-Disposition': 'attachment; filename=' + userFileName
  92. });
  93. fs.unlink(serverFileName, function () {
  94. if (err) throw err;
  95. console.log("Successfully deleted:", serverFileName);
  96. });
  97. });
  98. } else {
  99. respond(response, 500, "Internal server error.\n" +
  100. "phantomjs exited with code " + code);
  101. }
  102. });
  103. });
  104. });
  105. } else {
  106. respond(response, 400, "Bad request.");
  107. }
  108. }).listen(PORT);