Browse Source

Better api: log; blacklist; bug fixing

DIYgod 9 years ago
parent
commit
f1a9b8664f
10 changed files with 169 additions and 37 deletions
  1. 2 1
      .gitignore
  2. 1 3
      README.md
  3. 2 1
      demo/index.html
  4. 0 0
      dist/DPlayer.min.js
  5. 0 0
      dist/DPlayer.min.js.map
  6. 3 0
      nodejs/blacklist
  7. 159 16
      nodejs/index.js
  8. 1 0
      nodejs/package.json
  9. 1 1
      package.json
  10. 0 15
      src/DPlayer.js

+ 2 - 1
.gitignore

@@ -1,4 +1,5 @@
 .idea
 node_modules
 demo2
-npm-debug.log
+npm-debug.log
+DPlayer.log

+ 1 - 3
README.md

@@ -7,7 +7,7 @@
 [![Travis](https://img.shields.io/travis/DIYgod/DPlayer.svg?style=flat-square)](https://travis-ci.org/DIYgod/DPlayer)
 [![%e2%9d%a4](https://img.shields.io/badge/made%20with-%e2%9d%a4-ff69b4.svg?style=flat-square)](https://www.anotherhome.net/)
 
-Wow, such a lovely HTML5 danmaku video player
+> Wow, such a lovely HTML5 danmaku video player
 
 ## Introduction
 
@@ -43,8 +43,6 @@ $ npm run build
 
 - [ ] 快捷键: 空格暂停,双击全屏, 方向键控制进度
 
-- [ ] 弹幕相关
-
 - [ ] icon 动画
 
 - [ ] 右键

+ 2 - 1
demo/index.html

@@ -66,7 +66,8 @@
         },
         danmaku: {
             id: '9E2E3368B56CDBB4',
-            api: 'http://dplayer.daoapp.io/'
+            api: 'https://dplayer.daoapp.io/',
+            token: 'tokendemo'
         }
     });
     dp.init();

File diff suppressed because it is too large
+ 0 - 0
dist/DPlayer.min.js


File diff suppressed because it is too large
+ 0 - 0
dist/DPlayer.min.js.map


+ 3 - 0
nodejs/blacklist

@@ -0,0 +1,3 @@
+Can be username and IP
+username
+0.0.0.0

+ 159 - 16
nodejs/index.js

@@ -1,9 +1,39 @@
 var url = require('url');
+var fs = require('fs');
 var mongoose = require('mongoose');
-var 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;
 var express = require('express');
 var app = express();
 
+var log4js = require('log4js');
+log4js.configure({
+    appenders: [
+        {
+            type: "file",
+            filename: 'DPlayer.log',
+            maxLogSize: 20480,
+            backups: 3,
+            category: [ 'DPlayer','console' ]
+        },
+        {
+            type: "console"
+        }
+    ],
+    replaceConsole: true
+});
+var logger = log4js.getLogger('DPlayer');
+logger.setLevel('INFO');
+logger.info(`🍻 DPlayer start! Cheers!`);
+
+var postIP = [];
+
+var mongodbUrl;
+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) {
+    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;
+}
+else {
+    mongodbUrl = 'mongodb://localhost:27017/danmaku';
+}
+
 var danmakuSchema = new mongoose.Schema({
     player: String,
     author: String,
@@ -27,16 +57,23 @@ app.all('*', function(req, res, next) {
     }
 });
 
-app.get('/', function(req, res) {
+app.get('/', function (req, res) {
+    var ip = req.headers['x-forwarded-for'] ||
+             req.connection.remoteAddress ||
+             req.socket.remoteAddress ||
+             req.connection.socket.remoteAddress;
+    logger.info(`GET form IP: ${ip}`);
+
     mongoose.connect(mongodbUrl);
     var db = mongoose.connection;
-    db.on('error',console.error);
+    db.on('error', errorListener);
 
     var id = url.parse(req.url,true).query.id;
     db.once('open', function() {
+        cleanListener();
         danmaku.find({player: id}, function (err, data) {
             if (err) {
-                console.error(err);
+                logger.error(err);
             }
 
             var json = `{"code": 1,"danmaku":[`;
@@ -47,32 +84,138 @@ app.get('/', function(req, res) {
                 }
             }
             json += `]}`;
-            res.write(json);
-            res.end();
+            res.send(json);
             db.close();
         })
     });
+
+    function errorListener (err) {
+        cleanListener();
+        logger.error(err);
+        res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
+    }
+
+    function cleanListener () {
+        db.removeListener('error', errorListener);
+    }
 });
 
 app.post('/', function (req, res) {
-    var body = '', jsonStr;
-    req.on('data', function (chunk) {
+    var body = '';
+    var jsonStr;
+    var db;
+    var ip = req.headers['x-forwarded-for'] ||
+             req.connection.remoteAddress ||
+             req.socket.remoteAddress ||
+             req.connection.socket.remoteAddress;
+
+    // check black ip
+    var blanklist = fs.readFileSync('blacklist').toString().split('\n');
+    if (blanklist.indexOf(ip) !== -1) {
+        logger.info(`Reject POST form ${ip} for black ip.`);
+        res.send(`{"code": -1, "msg": "Rejected for black ip."}`);
+        return;
+    }
+
+    // frequency limitation
+    if (postIP.indexOf(ip) !== -1) {
+        logger.info(`Reject POST form ${ip} for frequent operation.`);
+        res.send(`{"code": -2, "msg": "Rejected for frequent operation."}`);
+        return;
+    }
+    else {
+        postIP.push(ip);
+        setTimeout(function () {
+            postIP.splice(0, 1);
+        }, 1000);
+    }
+
+    req.on('data', dataListener);
+    req.on('end', endListener);
+
+    function dataListener (chunk) {
         body += chunk;
-    });
-    req.on('end', function () {
+    }
+    function endListener () {
+        cleanListener();
         try {
             jsonStr = JSON.parse(body);
         } catch (err) {
             jsonStr = null;
         }
 
-        var dan = new danmaku({player: jsonStr.player, author: jsonStr.author, time: jsonStr.time, text: jsonStr.text, color: jsonStr.color, type: jsonStr.type});
-        dan.save(function (err, d) {
-            if (err){
-                console.error(err);
-            }
+        // check data
+        console.log(jsonStr.player, jsonStr.author, jsonStr.time, jsonStr.text, jsonStr.color, jsonStr.type);
+        if (jsonStr.player === undefined
+            || jsonStr.author === undefined
+            || jsonStr.time === undefined
+            || jsonStr.text === undefined
+            || jsonStr.color === undefined
+            || jsonStr.type === undefined) {
+            logger.info(`Reject POST form ${ip} for illegal data: ${JSON.stringify(jsonStr)}`);
+            res.send(`{"code": -3, "msg": "Rejected for illegal data"}`);
+            return;
+        }
+        
+        // check token: set it yourself
+        function checkToken (token) {
+            return true;
+        }
+        if (!checkToken(jsonStr.token)) {
+            logger.info(`Rejected POST form ${ip} for illegal token: ${jsonStr.token}`);
+            res.send(`{"code": -4, "msg": "Rejected for illegal token: ${jsonStr.token}"}`);
+            return;
+        }
+
+        // check black username
+        if (blanklist.indexOf(jsonStr.author) !== -1) {
+            logger.info(`Reject POST form ${jsonStr.author} for black user.`);
+            res.send(`{"code": -5, "msg": "Rejected for black user."}`);
+            return;
+        }
+
+        logger.info(`POST form ${ip}, data: ${JSON.stringify(jsonStr)}`);
+
+        mongoose.connect(mongodbUrl);
+        db = mongoose.connection;
+        db.on('error', errorListener);
+        db.once('open', function() {
+            cleandbListener();
+
+            var dan = new danmaku({
+                player: jsonStr.player,
+                author: jsonStr.author,
+                time: jsonStr.time,
+                text: jsonStr.text,
+                color: jsonStr.color,
+                type: jsonStr.type
+            });
+            dan.save(function (err, d) {
+                if (err){
+                    logger.error(err);
+                    res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
+                }
+                else {
+                    res.send(`{"code": 1, "data": ${JSON.stringify(d)}}`);
+                }
+                db.close();
+            });
         });
-    });
+    }
+
+    function errorListener (err) {
+        cleandbListener();
+        logger.error(err);
+        res.send(`{"code": 0, "msg": "Error happens, please contact system administrator."}`);
+    }
+
+    function cleandbListener () {
+        db.removeListener('error', errorListener);
+    }
+    function cleanListener () {
+        req.removeListener('data', dataListener);
+        req.removeListener('end', endListener);
+    }
 });
 
 app.listen(1207);

+ 1 - 0
nodejs/package.json

@@ -8,6 +8,7 @@
   "devDependencies": {},
   "dependencies": {
     "express": "^4.13.4",
+    "log4js": "^0.6.36",
     "mongoose": "^4.1.9"
   }
 }

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "dplayer",
-  "version": "0.0.1",
+  "version": "0.0.2",
   "description": "Wow, such a lovely HTML5 danmaku video player",
   "main": "dist/DPlayer.min.js",
   "scripts": {

File diff suppressed because it is too large
+ 0 - 15
src/DPlayer.js


Some files were not shown because too many files changed in this diff