grayroute.js 3.28 KB
/**
 * 灰度界面代理中间件
 * @author h1bomb
 */
var request = require('request');

var config = require('../config/gray');
var _ = require('lodash');
var fs = require('fs');

/**
 * 灰度界面配置
 * @param  {Object} proxyRoute 
 * @return {Function}  返中间件
 */
module.exports = function(proxyRoute) {

   return function(req, ress, next) {
    //日志记录器
    var logger = req.app.logger;
    //方法名称
    var method = req.method;
    //访问路由路径
    var path = req.route?req.route.path:'';
    //路由的hash key
    var key = proxyRoute.genKey(method,path);
    //登出,清掉cookie
    if(path === '/logout') {
       req.session.gray = null;
       next();
       return;
    }

    //如果新系统路由没有,代理到老平台
    if(!proxyRoute.interfacesConfig[key]) {      
      //老系统调用地址
      var callUrl = config.url + req.originalUrl;
      var options = {
        method:method,
        url:callUrl,
        timeout:config.timeout,
        headers: req.headers,
        useQuerystring:true,
        form:req.body
      }
      //删除提交内容长度,代理会改变长度
      delete options.headers['content-length'];
      delete options.headers["accept-encoding"];
      //设置代理host
      options.headers['host'] = config.url.replace('http://','');
      if(!req.session.gray) {
        logger.log('warn','grayroute: cookie missed',req.session.user);
      } else {
        options.headers['cookie'] = req.session.gray;
      }
      if(req.files && _.keys(req.files).length>0) {
        options.formData = addFiles(req);
        delete options.form;
      }
      logger.log('info','grayroute: request options: %j',options,{});
      
      //发起代理请求
      if(req.headers['accept'].indexOf('text/html')>-1||req.xhr) { 
        request(options,function(err,res,body) {
          if(err) {
            logger.log('error','grayroute: request error:',err);
            ress.status(500).send('');
          } else if(res&&res.statusCode === 302) {
            //跳转
            ress.redirect(res.caseless.get('location'));
          }else {
            var ContentType = res.caseless.get('Content-Type');
            var isAttachment = res.caseless.get('content-disposition');
            if(isAttachment && isAttachment.indexOf('attachment')>-1) {
                request(options).pipe(ress);
            } else {
                ress.append('Content-Type',ContentType);
                ress.status(res.statusCode).send(body);
            }
          }
        });
      } else {
        request(options).pipe(ress);//如果是静态资源,直接管道传递结果
      }
    } else {

      //当不是老系统的URL,需要访问老系统保持session
      request({
        method:'GET',
        url: config.url + config.sessionKeep,
        headers: {
          'Cookie':req.session.gray
        }
      },function(err,res,body){
        var code = res?res.statusCode:'no response';
        logger.log('info','grayroute: session keep status:'+code);
      });
      next();
    }
  }
 }

/**
 * 添加文件到body中
 * @param {Object} req 请求对象
 */
 function addFiles(req) {
    var body = {};
    _.forEach(req.files,function(v,k){
      body[k] = fs.createReadStream(v.path);
    });
   _.merge(body,req.body);
   return body;
 }