Skip to content

Commit

Permalink
feat(origin): add origin config
Browse files Browse the repository at this point in the history
  • Loading branch information
tarotlwei committed Aug 23, 2018
1 parent 4684484 commit 57cb546
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 35 deletions.
104 changes: 104 additions & 0 deletions bin/proxy/http.origin.js
@@ -0,0 +1,104 @@
module.exports = function(req, res) {

const url = require('url');
const config = require('./config');

const origin = req.headers['origin'];
const allowOriginHost = config.allowOriginHost;

let obj,
i,
originDomain,
allowOrigin;
if (origin && allowOriginHost) {
allowOrigin = false;
try {
obj = {};
obj = url.parse(origin, true);
} catch (e) {}

if (obj.hostname) {
originDomain = obj.hostname;

for (i = 0; i < allowOriginHost.length; i++) {
if (allowOriginHost[i].host === undefined || allowOriginHost[i].host && hostMatch(req.headers.host, allowOriginHost[i].host)) {
if (allowOriginHost[i].origin === undefined || hostMatch(originDomain, allowOriginHost[i].origin)) {
// 允许跨域
allowOrigin = true;
break;
}
}
}
}

if (!res) {
return allowOrigin;
}

if (allowOrigin) {
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Credentials', true);

if (req.method === 'OPTIONS') {
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
if (req.headers['access-control-request-headers']) {
res.setHeader('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
}
res.writeHead(200, { 'Content-Type': 'text/html; charset=UTF-8' });
res.end();

}
} else {
res.writeHead(403, { 'Content-Type': 'text/html; charset=UTF-8' });
res.end();
}

}

return allowOrigin;
};


function hostMatch(source, expList) {
if (!source || !expList) {
return false;
}

if (typeof expList === 'string') {
expList = [expList];
}

for (let i = 0; i < expList.length; i++) {
if (shExpMatch(source, expList[i])) {
return true;
}
}

return false;
}

function shExpMatch(source, exp) {
if (!source || !exp) {
return false;
}

if (typeof exp === 'string') {
if (exp.startsWith('*.')) {
// *.xxxx 开头的
return '*.' + source.split('.').slice(1).join('.') === exp;
} else if (exp.startsWith('.')) {
// .xxx开头的,右对齐匹配就ok
return source.endsWith(exp);
} else if (exp === '*') {
return true;
} else {
// 字符串全等
return source === exp;
}
} else if (typeof exp === 'object' && exp.test) {
// 正则表达式
return exp.test(source);
}

return false;
}
7 changes: 7 additions & 0 deletions bin/proxy/http.route.js
Expand Up @@ -31,6 +31,7 @@ const CCFinder = require('runtime/CCFinder.js');
const parseBody = require('util/http/parseBody.js');
const TSW = require('api/keyman');
const tnm2 = require('api/tnm2');
const originCheck = require('./http.origin.js');


module.exports = function(req, res) {
Expand Down Expand Up @@ -527,6 +528,12 @@ function doRoute(req, res) {
// +1
req.headers['tsw-trace-steps'] = steps + 1;

originCheck(req, res);

if (res.headersSent || res.finished) {
return;
}

let modulePath = httpModMap.find(mod_act, req, res);

if (res.headersSent || res.finished) {
Expand Down
40 changes: 5 additions & 35 deletions bin/proxy/webSocketServer.js
@@ -1,44 +1,14 @@
const WebSocket = require('ws');
const http = require('http');
const url = require('url');
const config = require('./config.js');
const originCheck = require('./http.origin.js');

class webSocketServer extends WebSocket.Server {
handleUpgrade(req, socket, head, cb) {
const origin = req['headers']['origin'] || '';
if (origin) {
const obj = url.parse(origin);
const host = req['headers']['host'];

if (obj.host !== host) {
const allowWebSocketOriginHost = config.allowWebSocketOriginHost || [];
if (allowWebSocketOriginHost.length === 0) {
super.handleUpgrade(req, socket, head, cb);
return;
}

let i,
len,
v;
for (i = 0, len = allowWebSocketOriginHost.length; i < len; i++) {
v = allowWebSocketOriginHost[i];

if (typeof v === 'string') {
if (v !== obj.host) {
abortConnection(socket, 403);
return;
}
} else if (typeof v === 'object') {
if (!v.test || (v.test && !v.test(obj.host))) {
abortConnection(socket, 403);
return;
}
}
}
}
if (originCheck(req) !== false) {
super.handleUpgrade(req, socket, head, cb);
} else {
abortConnection(socket, 403);
}

super.handleUpgrade(req, socket, head, cb);
}
}

Expand Down

0 comments on commit 57cb546

Please sign in to comment.