bm_scaffold_async_router
Version:
本木前端脚手架-异步路由版
152 lines (142 loc) • 5.12 kB
JavaScript
/**
* @Author: songqi
* @Date: 2016-07-15
* @Email: songqi@benmu-health.com
* @Last modified by: songqi
* @Last modified time: 2016-11-10
*/
var fs = require('fs'),
url = require('url'),
_ = require('lodash'),
path = require('path'),
http = require('http'),
https = require('https'),
readConfig = require('../../utils/readConfig');
const getAllInfo = (req, body) => {
var target = req.target ? req.target + '/' : '';
var options, module;
if (req.client.ssl) {
options = url.parse('https://' + target + req.url.slice(1));
options['rejectUnauthorized'] = false;
module = https;
} else {
options = url.parse('http://' + target + req.url.slice(1));
module = http;
}
options['headers'] = req.headers;
return {
options,
module,
data: body
}
}
function proxyRequest(request, response, next) {
var body = '';
if (request.method == 'OPTIONS') {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
response.setHeader('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
response.statusCode = 200;
response.end();
return;
}
if (request.method == 'POST') {
request.on('data', function (data) {
body += data;
});
request.on('end', function () {
var info = getAllInfo(request, body);
var req = info.module.request(info.options, (remoteRequest) => {
console.log(remoteRequest.statusCode)
if (remoteRequest.statusCode === 200) {
response.setHeader('Content-Type', remoteRequest.headers['content-type']);
remoteRequest.pipe(response);
} else {
response.writeHead(remoteRequest.statusCode);
response.end();
}
}).on('error', function () {
next();
})
info.data && req.write(info.data);
req.end();
});
} else {
var info = getAllInfo(request, body);
var req = info.module.request(info.options, (remoteRequest) => {
response.setHeader('Content-Type', remoteRequest.headers['content-type']);
remoteRequest.pipe(response);
}).on('error', function () {
next();
})
req.end();
}
}
function testProxy(request, proxyConfig) {
if (request.url.slice(0, proxyConfig.route.length) === proxyConfig.route) {
request.url = request.url.slice(proxyConfig.route.length);
proxyConfig.target && (request.target = proxyConfig.target);
return request;
} else {
return false;
}
}
function Proxy(options) {
var config = _.assign({
root: path.join(process.cwd(), '../'),
proxy: ''
}, {
proxy: readConfig.get('proxy')
});
return function (request, response, next) {
if (!config.proxy || _.isArray(config.proxy) && !config.proxy.length) {
next();
return;
}
if (typeof config.root === 'string') {
config.root = [config.root]
} else if (!_.isArray(config.root)) {
throw new Error('No root specified')
}
var pathChecks = [];
config.root.forEach(function (root, i) {
var _isProxy = false,
_proxy = false,
p = path.resolve(root) + request.url;
fs.access(p, function (err) {
pathChecks.push(err ? false : true);
if (config.root.length == ++i) {
var pathExists = pathChecks.some(function (p) {
return p;
});
if (pathExists) {
next();
} else {
if (_.isArray(config.proxy)) {
_isProxy = config.proxy.some(function (item) {
_proxy = testProxy(request, item);
if (_proxy) {
proxyRequest(_proxy, response, next);
return true
}
})
if (!_isProxy) {
next();
}
} else if (config.proxy && config.proxy.route) {
_proxy = testProxy(request, config.proxy);
if (_proxy) {
proxyRequest(_proxy, response, next);
} else {
next();
}
} else {
next();
}
}
}
});
})
}
}
module.exports = Proxy