index.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. function htmlEncode(str) {
  26. return str.replace(/&/g, "&")
  27. .replace(/</g, "&lt;")
  28. .replace(/>/g, "&gt;")
  29. .replace(/"/g, "&quot;")
  30. .replace(/'/g, "&#x27;")
  31. .replace(/\//g, "&#x2f;");
  32. }
  33. var postIP = [];
  34. var mongodbUrl;
  35. 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) {
  36. 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;
  37. }
  38. else {
  39. mongodbUrl = 'mongodb://localhost:27017/danmaku';
  40. }
  41. var danmakuSchema = new mongoose.Schema({
  42. player: {
  43. type: [String], index: true
  44. },
  45. author: String,
  46. time: Number,
  47. text: String,
  48. color: String,
  49. type: String
  50. });
  51. var danmaku = mongoose.model('dan', danmakuSchema);
  52. app.all('*', function(req, res, next) {
  53. res.header('Access-Control-Allow-Origin', '*');
  54. res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
  55. res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
  56. if (req.method == 'OPTIONS') {
  57. res.send(200);
  58. }
  59. else {
  60. next();
  61. }
  62. });
  63. app.get('/', function (req, res) {
  64. var ip = req.headers['x-forwarded-for'] ||
  65. req.connection.remoteAddress ||
  66. req.socket.remoteAddress ||
  67. req.connection.socket.remoteAddress;
  68. logger.info(`GET form IP: ${ip}`);
  69. mongoose.connect(mongodbUrl);
  70. var db = mongoose.connection;
  71. db.on('error', errorListener);
  72. var id = url.parse(req.url,true).query.id;
  73. db.once('open', function() {
  74. cleanListener();
  75. danmaku.find({player: id}, function (err, data) {
  76. if (err) {
  77. logger.error(err);
  78. }
  79. var json = `{"code": 1,"danmaku":[`;
  80. for (var i = 0; i < data.length; i++) {
  81. json += JSON.stringify(data[i]);
  82. if (i !== data.length - 1) {
  83. json += `,`;
  84. }
  85. }
  86. json += `]}`;
  87. res.send(json);
  88. db.close();
  89. })
  90. });
  91. function errorListener (err) {
  92. cleanListener();
  93. logger.error(err);
  94. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  95. }
  96. function cleanListener () {
  97. db.removeListener('error', errorListener);
  98. }
  99. });
  100. app.post('/', function (req, res) {
  101. var body = '';
  102. var jsonStr;
  103. var db;
  104. var ip = req.headers['x-forwarded-for'] ||
  105. req.connection.remoteAddress ||
  106. req.socket.remoteAddress ||
  107. req.connection.socket.remoteAddress;
  108. // check black ip
  109. var blanklist = fs.readFileSync('blacklist').toString().split('\n');
  110. if (blanklist.indexOf(ip.split(',')[0]) !== -1) {
  111. logger.info(`Reject POST form ${ip} for black ip.`);
  112. res.send(`{"code": -1, "msg": "Rejected for black ip."}`);
  113. return;
  114. }
  115. // frequency limitation
  116. if (postIP.indexOf(ip) !== -1) {
  117. logger.info(`Reject POST form ${ip} for frequent operation.`);
  118. res.send(`{"code": -2, "msg": "Rejected for frequent operation."}`);
  119. return;
  120. }
  121. else {
  122. postIP.push(ip);
  123. setTimeout(function () {
  124. postIP.splice(0, 1);
  125. }, 1000);
  126. }
  127. req.on('data', dataListener);
  128. req.on('end', endListener);
  129. function dataListener (chunk) {
  130. body += chunk;
  131. }
  132. function endListener () {
  133. cleanListener();
  134. try {
  135. jsonStr = JSON.parse(body);
  136. } catch (err) {
  137. jsonStr = null;
  138. }
  139. // check data
  140. if (jsonStr.player === undefined
  141. || jsonStr.author === undefined
  142. || jsonStr.time === undefined
  143. || jsonStr.text === undefined
  144. || jsonStr.color === undefined
  145. || jsonStr.type === undefined
  146. || jsonStr.text.length >= 30) {
  147. logger.info(`Reject POST form ${ip} for illegal data: ${JSON.stringify(jsonStr)}`);
  148. res.send(`{"code": -3, "msg": "Rejected for illegal data"}`);
  149. return;
  150. }
  151. // check token: set it yourself
  152. function checkToken (token) {
  153. return true;
  154. }
  155. if (!checkToken(jsonStr.token)) {
  156. logger.info(`Rejected POST form ${ip} for illegal token: ${jsonStr.token}`);
  157. res.send(`{"code": -4, "msg": "Rejected for illegal token: ${jsonStr.token}"}`);
  158. return;
  159. }
  160. // check black username
  161. if (blanklist.indexOf(jsonStr.author) !== -1) {
  162. logger.info(`Reject POST form ${jsonStr.author} for black user.`);
  163. res.send(`{"code": -5, "msg": "Rejected for black user."}`);
  164. return;
  165. }
  166. logger.info(`POST form ${ip}, data: ${JSON.stringify(jsonStr)}`);
  167. mongoose.connect(mongodbUrl);
  168. db = mongoose.connection;
  169. db.on('error', errorListener);
  170. db.once('open', function() {
  171. cleandbListener();
  172. var dan = new danmaku({
  173. player: htmlEncode(jsonStr.player),
  174. author: htmlEncode(jsonStr.author),
  175. time: jsonStr.time,
  176. text: htmlEncode(jsonStr.text),
  177. color: htmlEncode(jsonStr.color),
  178. type: htmlEncode(jsonStr.type)
  179. });
  180. dan.save(function (err, d) {
  181. if (err) {
  182. logger.error(err);
  183. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  184. }
  185. else {
  186. res.send(`{"code": 1, "data": ${JSON.stringify(d)}}`);
  187. }
  188. db.close();
  189. });
  190. });
  191. }
  192. function errorListener (err) {
  193. cleandbListener();
  194. logger.error(err);
  195. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  196. }
  197. function cleandbListener () {
  198. db.removeListener('error', errorListener);
  199. }
  200. function cleanListener () {
  201. req.removeListener('data', dataListener);
  202. req.removeListener('end', endListener);
  203. }
  204. });
  205. app.get('/list', function (req, res) {
  206. mongoose.connect(mongodbUrl);
  207. var db = mongoose.connection;
  208. db.on('error', errorListener);
  209. db.once('open', function() {
  210. cleanListener();
  211. danmaku.distinct('player', function (err, data) {
  212. if (err) {
  213. logger.error(err);
  214. }
  215. var json = ``;
  216. for (var i = 0; i < data.length; i++) {
  217. json += data[i] + `<br>`;
  218. }
  219. res.send(json);
  220. db.close();
  221. })
  222. });
  223. function errorListener (err) {
  224. cleanListener();
  225. logger.error(err);
  226. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  227. }
  228. function cleanListener () {
  229. db.removeListener('error', errorListener);
  230. }
  231. });
  232. app.listen(1207);