index.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. var url = require('url');
  2. var fs = require('fs');
  3. var mongoose = require('mongoose');
  4. var express = require('express');
  5. var app = express();
  6. var log4js = require('log4js');
  7. log4js.configure({
  8. appenders: [
  9. {
  10. type: "file",
  11. filename: 'DPlayer.log',
  12. maxLogSize: 20480,
  13. backups: 3,
  14. category: [ 'DPlayer','console' ]
  15. },
  16. {
  17. type: "console"
  18. }
  19. ],
  20. replaceConsole: true
  21. });
  22. var logger = log4js.getLogger('DPlayer');
  23. logger.setLevel('INFO');
  24. logger.info(`🍻 DPlayer start! Cheers!`);
  25. var postIP = [];
  26. var mongodbUrl;
  27. if (process.env.MONGODB_USERNAME && process.env.MONGODB_PASSWORD && process.env.MONGODB_PORT_27017_TCP_ADDR && process.env.MONGODB_PORT_27017_TCP_PORT && process.env.MONGODB_INSTANCE_NAME) {
  28. mongodbUrl = 'mongodb://' + process.env.MONGODB_USERNAME + ':' + process.env.MONGODB_PASSWORD + '@' + process.env.MONGODB_PORT_27017_TCP_ADDR + ':' + process.env.MONGODB_PORT_27017_TCP_PORT + '/' + process.env.MONGODB_INSTANCE_NAME;
  29. }
  30. else {
  31. mongodbUrl = 'mongodb://localhost:27017/danmaku';
  32. }
  33. var danmakuSchema = new mongoose.Schema({
  34. player: String,
  35. author: String,
  36. time: Number,
  37. text: String,
  38. color: String,
  39. type: String
  40. });
  41. var danmaku = mongoose.model('dan', danmakuSchema);
  42. app.all('*', function(req, res, next) {
  43. res.header('Access-Control-Allow-Origin', '*');
  44. res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
  45. res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  46. if (req.method == 'OPTIONS') {
  47. res.send(200);
  48. }
  49. else {
  50. next();
  51. }
  52. });
  53. app.get('/', function (req, res) {
  54. var ip = req.headers['x-forwarded-for'] ||
  55. req.connection.remoteAddress ||
  56. req.socket.remoteAddress ||
  57. req.connection.socket.remoteAddress;
  58. logger.info(`GET form IP: ${ip}`);
  59. mongoose.connect(mongodbUrl);
  60. var db = mongoose.connection;
  61. db.on('error', errorListener);
  62. var id = url.parse(req.url,true).query.id;
  63. db.once('open', function() {
  64. cleanListener();
  65. danmaku.find({player: id}, function (err, data) {
  66. if (err) {
  67. logger.error(err);
  68. }
  69. var json = `{"code": 1,"danmaku":[`;
  70. for (var i = 0; i < data.length; i++) {
  71. json += JSON.stringify(data[i]);
  72. if (i !== data.length - 1) {
  73. json += `,`;
  74. }
  75. }
  76. json += `]}`;
  77. res.send(json);
  78. db.close();
  79. })
  80. });
  81. function errorListener (err) {
  82. cleanListener();
  83. logger.error(err);
  84. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  85. }
  86. function cleanListener () {
  87. db.removeListener('error', errorListener);
  88. }
  89. });
  90. app.post('/', function (req, res) {
  91. var body = '';
  92. var jsonStr;
  93. var db;
  94. var ip = req.headers['x-forwarded-for'] ||
  95. req.connection.remoteAddress ||
  96. req.socket.remoteAddress ||
  97. req.connection.socket.remoteAddress;
  98. // check black ip
  99. var blanklist = fs.readFileSync('blacklist').toString().split('\n');
  100. if (blanklist.indexOf(ip) !== -1) {
  101. logger.info(`Reject POST form ${ip} for black ip.`);
  102. res.send(`{"code": -1, "msg": "Rejected for black ip."}`);
  103. return;
  104. }
  105. // frequency limitation
  106. if (postIP.indexOf(ip) !== -1) {
  107. logger.info(`Reject POST form ${ip} for frequent operation.`);
  108. res.send(`{"code": -2, "msg": "Rejected for frequent operation."}`);
  109. return;
  110. }
  111. else {
  112. postIP.push(ip);
  113. setTimeout(function () {
  114. postIP.splice(0, 1);
  115. }, 1000);
  116. }
  117. req.on('data', dataListener);
  118. req.on('end', endListener);
  119. function dataListener (chunk) {
  120. body += chunk;
  121. }
  122. function endListener () {
  123. cleanListener();
  124. try {
  125. jsonStr = JSON.parse(body);
  126. } catch (err) {
  127. jsonStr = null;
  128. }
  129. // check data
  130. console.log(jsonStr.player, jsonStr.author, jsonStr.time, jsonStr.text, jsonStr.color, jsonStr.type);
  131. if (jsonStr.player === undefined
  132. || jsonStr.author === undefined
  133. || jsonStr.time === undefined
  134. || jsonStr.text === undefined
  135. || jsonStr.color === undefined
  136. || jsonStr.type === undefined) {
  137. logger.info(`Reject POST form ${ip} for illegal data: ${JSON.stringify(jsonStr)}`);
  138. res.send(`{"code": -3, "msg": "Rejected for illegal data"}`);
  139. return;
  140. }
  141. // check token: set it yourself
  142. function checkToken (token) {
  143. return true;
  144. }
  145. if (!checkToken(jsonStr.token)) {
  146. logger.info(`Rejected POST form ${ip} for illegal token: ${jsonStr.token}`);
  147. res.send(`{"code": -4, "msg": "Rejected for illegal token: ${jsonStr.token}"}`);
  148. return;
  149. }
  150. // check black username
  151. if (blanklist.indexOf(jsonStr.author) !== -1) {
  152. logger.info(`Reject POST form ${jsonStr.author} for black user.`);
  153. res.send(`{"code": -5, "msg": "Rejected for black user."}`);
  154. return;
  155. }
  156. logger.info(`POST form ${ip}, data: ${JSON.stringify(jsonStr)}`);
  157. mongoose.connect(mongodbUrl);
  158. db = mongoose.connection;
  159. db.on('error', errorListener);
  160. db.once('open', function() {
  161. cleandbListener();
  162. var dan = new danmaku({
  163. player: jsonStr.player,
  164. author: jsonStr.author,
  165. time: jsonStr.time,
  166. text: jsonStr.text,
  167. color: jsonStr.color,
  168. type: jsonStr.type
  169. });
  170. dan.save(function (err, d) {
  171. if (err){
  172. logger.error(err);
  173. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  174. }
  175. else {
  176. res.send(`{"code": 1, "data": ${JSON.stringify(d)}}`);
  177. }
  178. db.close();
  179. });
  180. });
  181. }
  182. function errorListener (err) {
  183. cleandbListener();
  184. logger.error(err);
  185. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  186. }
  187. function cleandbListener () {
  188. db.removeListener('error', errorListener);
  189. }
  190. function cleanListener () {
  191. req.removeListener('data', dataListener);
  192. req.removeListener('end', endListener);
  193. }
  194. });
  195. app.listen(1207);