cdn_cache.js 5.5 KB
/**
 *
 * @author: chenfeng<feng.chen@yoho.cn>
 * @date: 16/10/19
 */

'use strict';
const Model = require('./model');
const utils = require('utility');
const rp = require('request-promise');
const ws = require('../../lib/ws');
const Capi = require('qcloudapi-sdk');
const qiniu = require('qiniu')
const cdnConfig = require('../../config/cdn_config');

const qiniuCOnfig = cdnConfig.main

const capi = new Capi(Object.assign({
    serviceType: 'cdn'
}, cdnConfig.qcloud));

const mac = new qiniu.auth.digest.Mac(qiniuCOnfig.accessKey, qiniuCOnfig.secretKey);

const qiniuCdn = new qiniu.cdn.CdnManager(mac);

class CdnCache extends Model {
    constructor() {
        super('cdn_page');
    }
    async removeCache(queryUris, objectType, cloud) {
        let self = this;

        if (cloud === 'qcloud') {
            self._cleanQcloudCache({
                ObjectPath: queryUris,
                ObjectType: objectType
            })
        } else if (cloud === 'qiniu') {
            self._qiniuClear(objectType, queryUris)
        } else {
            self._requestApi({
                Action: 'RefreshObjectCaches',
                ObjectPath: queryUris,
                ObjectType: objectType
            })
        }
    }
    async _cleanQcloudCache(params) {
        let self = this;
        let qCloudParams = self._getQcloudParams(params);

        if (!Object.keys(qCloudParams).length) {
            return;
        }

        capi.request(qCloudParams, function(err, res) {
            if (err || res.code) {
                return self._broadcast(`清理腾讯云失败:${res && res.message}`)
            }

            self._broadcast(`清理腾讯云提交成功,RefreshTaskId:${res.data.task_id}`)
        })
    }
    async _requestApi(params) {
        let self = this;
        let cdns = await self.findAll();

        if (!cdns.length) {
            return;
        }
        params = Object.assign(params, {
            Format: 'JSON',
            Version: '2014-11-11',
            AccessKeyId: cdns[0].keyId,
            SignatureMethod: 'HMAC-SHA1',
            TimeStamp: self._getUtcTime(new Date()),
            SignatureVersion: '1.0',
            SignatureNonce: parseInt(Math.random() * 100000, 10) + ''
        });
        let sign = self._sign(params, cdns[0].keySecret);
        params.Signature = sign;
        rp({
            uri: `${cdns[0].scheme}://${cdns[0].cdnApi}`,
            qs: params,
            json: true
        })
        .then(function (res) {
            self._broadcast(`清理阿里云提交成功,RefreshTaskId:${res.RefreshTaskId}`)
        })
        .catch(function (err) {
            self._broadcast(`清理阿里云失败:${JSON.stringify(err.response.body)}`)
        });

    }
    _getUrlList(str = '') {
        return str.split('\n');
    }
    _getQcloudParams(params) {
        let param = {};
        let type = params.ObjectType === 'File' ? 'urls' : 'dirs';
        let list = this._getUrlList(params.ObjectPath);

        param.Action = params.ObjectType === 'File' ? 'RefreshCdnUrl' : 'RefreshCdnDir';

        list.forEach((url, index) => {
            param[`${type}.${index}`] = url;
        });

        return param;
    }
    _getUtcTime(date) {
        let year = date.getUTCFullYear();
        let month = date.getUTCMonth() + 1;
        let day = date.getUTCDate() < 10 ? '0' + date.getUTCDate() : date.getUTCDate();
        let hour = date.getUTCHours() < 10 ? '0' + date.getUTCHours() : date.getUTCHours();
        let minute = date.getUTCMinutes() < 10 ? '0' + date.getUTCMinutes() : date.getUTCMinutes();
        let second = date.getUTCSeconds() < 10 ? '0' + date.getUTCSeconds() : date.getUTCSeconds();
        month = month < 10 ? '0' + month : month;

        return `${year}-${month}-${day}T${hour}:${minute}:${second}Z`
    }
    _sign(params, keySecret) {
        let data = {};
        Object.keys(params).sort().forEach(k => data[k]=params[k]);
        let signString = '';
        Object.keys(data).forEach(k => {
            data[k] = encodeURIComponent(data[k])
            signString += `&${k}=${data[k]}`;
        });
        if (signString) {
            signString = `GET&%2F&${encodeURIComponent(signString.substring(1, signString.length))}`;
            let sign = utils.hmac('sha1', keySecret + '&', signString); 
            return sign;
        }
        return '';
    }
    _broadcast(message) {
        console.log(message)
        ws.broadcast(`/cdn_cache/log`, {
            message: message
        });
    }
    async init() {
        let count = await this.count({});
        if (count === 0) {
            await this.insert({
                scheme: 'https',
                cdnApi: 'cdn.aliyuncs.com',
                keyId: 'Mt6m3xVdWddj8bDe',
                keySecret: 'ExHpmJJ7ayJEEMz2LUffKRe3ehMGDs'
            })
        }
    }
    async _qiniuClear(type, urls) {
        urls = this._getUrlList(urls);

        let self = this;

        if (type === 'File') {
            qiniuCdn.refreshUrls(urls, function(err, res, info) {
                if (err) {
                    self._broadcast(`清除七牛cdn失败 ${err}`)
                } else {
                    self._broadcast(`清除七牛cdn成功 ${res}`)
                }
            })
        } else {
            qiniuCdn.refreshDirs(urls, function(err, res, info) {
                if (err) {
                    self._broadcast(`清除七牛cdn失败 ${err}`)
                } else {
                    self._broadcast(`清除七牛cdn成功 ${res}`)
                }
            })
        }
    }
}

module.exports = CdnCache;