1
0

index.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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 query = url.parse(req.url,true).query;
  73. var id = query.id;
  74. var max = query.max;
  75. var length;
  76. db.once('open', function() {
  77. cleanListener();
  78. danmaku.find({player: id}, function (err, data) {
  79. if (err) {
  80. logger.error(err);
  81. }
  82. var json = `{"code": 1,"danmaku":[`;
  83. length = max ? Math.min(data.length, max) : data.length;
  84. for (var i = 0; i < length; i++) {
  85. json += JSON.stringify(data[i]);
  86. if (i !== length - 1) {
  87. json += `,`;
  88. }
  89. }
  90. json += `]}`;
  91. res.send(json);
  92. db.close();
  93. })
  94. });
  95. function errorListener (err) {
  96. cleanListener();
  97. logger.error(err);
  98. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  99. }
  100. function cleanListener () {
  101. db.removeListener('error', errorListener);
  102. }
  103. });
  104. app.post('/', function (req, res) {
  105. var body = '';
  106. var jsonStr;
  107. var db;
  108. var ip = req.headers['x-forwarded-for'] ||
  109. req.connection.remoteAddress ||
  110. req.socket.remoteAddress ||
  111. req.connection.socket.remoteAddress;
  112. // check black ip
  113. var blanklist = fs.readFileSync('blacklist').toString().split('\n');
  114. if (blanklist.indexOf(ip.split(',')[0]) !== -1) {
  115. logger.info(`Reject POST form ${ip} for black ip.`);
  116. res.send(`{"code": -1, "msg": "Rejected for black ip."}`);
  117. return;
  118. }
  119. // frequency limitation
  120. if (postIP.indexOf(ip) !== -1) {
  121. logger.info(`Reject POST form ${ip} for frequent operation.`);
  122. res.send(`{"code": -2, "msg": "Rejected for frequent operation."}`);
  123. return;
  124. }
  125. else {
  126. postIP.push(ip);
  127. setTimeout(function () {
  128. postIP.splice(0, 1);
  129. }, 1000);
  130. }
  131. req.on('data', dataListener);
  132. req.on('end', endListener);
  133. function dataListener (chunk) {
  134. body += chunk;
  135. }
  136. function endListener () {
  137. cleanListener();
  138. try {
  139. jsonStr = JSON.parse(body);
  140. } catch (err) {
  141. jsonStr = null;
  142. }
  143. // check data
  144. if (jsonStr.player === undefined
  145. || jsonStr.author === undefined
  146. || jsonStr.time === undefined
  147. || jsonStr.text === undefined
  148. || jsonStr.color === undefined
  149. || jsonStr.type === undefined
  150. || jsonStr.text.length >= 30) {
  151. logger.info(`Reject POST form ${ip} for illegal data: ${JSON.stringify(jsonStr)}`);
  152. res.send(`{"code": -3, "msg": "Rejected for illegal data"}`);
  153. return;
  154. }
  155. // check token: set it yourself
  156. function checkToken (token) {
  157. return true;
  158. }
  159. if (!checkToken(jsonStr.token)) {
  160. logger.info(`Rejected POST form ${ip} for illegal token: ${jsonStr.token}`);
  161. res.send(`{"code": -4, "msg": "Rejected for illegal token: ${jsonStr.token}"}`);
  162. return;
  163. }
  164. // check black username
  165. if (blanklist.indexOf(jsonStr.author) !== -1) {
  166. logger.info(`Reject POST form ${jsonStr.author} for black user.`);
  167. res.send(`{"code": -5, "msg": "Rejected for black user."}`);
  168. return;
  169. }
  170. logger.info(`POST form ${ip}, data: ${JSON.stringify(jsonStr)}`);
  171. mongoose.connect(mongodbUrl);
  172. db = mongoose.connection;
  173. db.on('error', errorListener);
  174. db.once('open', function() {
  175. cleandbListener();
  176. var dan = new danmaku({
  177. player: htmlEncode(jsonStr.player),
  178. author: htmlEncode(jsonStr.author),
  179. time: jsonStr.time,
  180. text: htmlEncode(jsonStr.text),
  181. color: htmlEncode(jsonStr.color),
  182. type: htmlEncode(jsonStr.type)
  183. });
  184. dan.save(function (err, d) {
  185. if (err) {
  186. logger.error(err);
  187. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  188. }
  189. else {
  190. res.send(`{"code": 1, "data": ${JSON.stringify(d)}}`);
  191. }
  192. db.close();
  193. });
  194. });
  195. }
  196. function errorListener (err) {
  197. cleandbListener();
  198. logger.error(err);
  199. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  200. }
  201. function cleandbListener () {
  202. db.removeListener('error', errorListener);
  203. }
  204. function cleanListener () {
  205. req.removeListener('data', dataListener);
  206. req.removeListener('end', endListener);
  207. }
  208. });
  209. app.get('/list', function (req, res) {
  210. mongoose.connect(mongodbUrl);
  211. var db = mongoose.connection;
  212. db.on('error', errorListener);
  213. db.once('open', function() {
  214. cleanListener();
  215. danmaku.distinct('player', function (err, data) {
  216. if (err) {
  217. logger.error(err);
  218. }
  219. var json = ``;
  220. for (var i = 0; i < data.length; i++) {
  221. json += data[i] + `<br>`;
  222. }
  223. res.send(json);
  224. db.close();
  225. })
  226. });
  227. function errorListener (err) {
  228. cleanListener();
  229. logger.error(err);
  230. res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
  231. }
  232. function cleanListener () {
  233. db.removeListener('error', errorListener);
  234. }
  235. });
  236. app.listen(1207);