crawler.js 5.73 KB
'use strict';

const Router = require('koa-router');

const {
    MemcachedHost
} = require('../../models');
const Operation = require('../../logger/operation');
const {
    Server
} = require('../../models');

const {DegradeServer} = require('../../models');
const zookeeper = require('node-zookeeper-client');
const tester = require('../../zookeeper/tester');
const getter = require('../../zookeeper/getter');
const Model = require('../../models/model');
const _ = require('lodash');
const ApiCache = require('../../ci/api_cache');

const envs = {
    p1oduction: '线上环境',
    preview: '灰度环境',
    test: '测试环境'
};

class Store extends Model {
    constructor() {
        super('abuse_protection');
    }
}
const store = new Store();
const makeServer = ((ipKey, uaKey, listName, black) => {
    const r = new Router;

    const servers = {
        ua: async(ctx, next) => {
            let list = await servers.getLists(uaKey);

            await ctx.render('action/crawler', {
                listName: listName,
                list: (list ? list.map((item) => {
                        return {name: item}
                    }) : ''),
                main_name: 'UA'
            });
        },
        ip: async(ctx, next) => {
            let list = await servers.getLists(ipKey);

            await ctx.render('action/crawler', {
                listName: listName,
                list: (list ? list.map((item) => {
                        return {name: item}
                    }) : ''),
                main_name: 'IP'
            });
        },
        change_ua: async(ctx, next) => {
            const doUpdate = async(ua) => {
                console.log('include ua:' + ua);

                let hosts = await MemcachedHost.findAll();
                await Promise.all(_.map(hosts, (h) => {
                    const key = `pc:limiter:ua:${black ? 'black' : 'white'}`,
                        value = JSON.parse(ua || '[]');

                    return (new ApiCache(h.host)).setKey(key, value, 0);
                }));
            };

            let result = await servers.setLists(ctx);
            await doUpdate(ctx.query.val);

            if (result) {
                ctx.body = {
                    listName: listName,
                    code: 200,
                    message: 'update success'
                };
            } else {
                ctx.body = {
                    listName: listName,
                    code: 500,
                    message: 'update fail,Please retry'
                }
            }
        },
        change_ip: async(ctx, next) => {
            let oldList = await servers.getLists(ipKey);

            const newList = JSON.parse(ctx.query.val || '[]');

            const exclude = async(ip) => {
                console.log('exclude:' + ip);

                let hosts = await MemcachedHost.findAll();
                await Promise.all(_.map(hosts, (h) => {
                    const key = `pc:limiter:${ip}`,
                        value = -1,
                        ttl = 0;

                    return (new ApiCache(h.host)).setKey(key, value, ttl);
                }));
            };

            const lock = async(ip) => {
                console.log('lock:' + ip);

                let hosts = await MemcachedHost.findAll();
                await Promise.all(_.map(hosts, (h) => {
                    const key = `pc:limiter:${ip}`,
                        value = 9999,
                        ttl = 60 * 60 * 24 * 30; // 封停一月

                    return (new ApiCache(h.host)).setKey(key, value, ttl);
                }));
            };

            const unlock = async(ip) => {
                console.log('unlock:' + ip);

                let hosts = await MemcachedHost.findAll();
                await Promise.all(_.map(hosts, (h) => {
                    const key = `pc:limiter:${ip}`;

                    return (new ApiCache(h.host)).delKey(key);
                }));
            };

            const unlockList = [];

            _.each(oldList, (item) => {
                if (_.indexOf(newList, item) < 0) {
                    unlockList.push(item);
                }
            });

            _.each(newList, (ip) => {
                if (black) {
                    lock(ip);
                } else {
                    exclude(ip);
                }
            });

            _.each(unlockList, (ip) => {
                unlock(ip);
            });

            let result = await servers.setLists(ctx);


            if (result) {
                ctx.body = {
                    listName: listName,
                    code: 200,
                    message: 'update success'
                };
            } else {
                ctx.body = {
                    code: 500,
                    message: 'update fail,Please retry'
                }
            }

        },
        getLists: async(path) => {
            const result = await store.findOne({
                path: path
            });

            return result && result.val ? JSON.parse(result.val) : [];
        },

        async setLists(ctx, type) {
            let {path, val} = ctx.query;

            const rec = await store.findOne({
                path: path
            });

            if (rec) {
                store.update({
                    path: path
                }, {
                    $set: {
                        val: val
                    }
                })
            } else {
                store.insert({
                    path: path,
                    val: val
                })
            }
        }
    };

    r.get('/ua', servers.ua);
    r.get('/ip', servers.ip);
    r.get('/change_ua', servers.change_ua);
    r.get('/change_ip', servers.change_ip);
    return r;
});

module.exports = makeServer;