openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
178 lines (146 loc) • 5.15 kB
JavaScript
var Channel, Channels, Q, SDC, application, auditing, config, dom, domain, extractContentType, findMatchingChannel, getJSONValByString, himSourceID, logger, matchChannel, matchContent, matchContentTypes, matchFunctions, matchJsonPath, matchRegex, matchRequest, matchUrlPattern, matchXpath, os, sdc, statsdServer, utils, xpath,
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
Q = require("q");
xpath = require("xpath");
dom = require("xmldom").DOMParser;
logger = require("winston");
config = require('../config/config');
utils = require('../utils');
auditing = require('../auditing');
Channels = require('../model/channels');
Channel = Channels.Channel;
statsdServer = config.get('statsd');
application = config.get('application');
himSourceID = config.get('auditing').auditEvents.auditSourceID;
SDC = require('statsd-client');
os = require('os');
domain = (os.hostname()) + "." + application.name + ".appMetrics";
sdc = new SDC(statsdServer);
matchContent = function(channel, ctx) {
if (channel.matchContentRegex) {
return matchRegex(channel.matchContentRegex, ctx.body);
} else if (channel.matchContentXpath && channel.matchContentValue) {
return matchXpath(channel.matchContentXpath, channel.matchContentValue, ctx.body);
} else if (channel.matchContentJson && channel.matchContentValue) {
return matchJsonPath(channel.matchContentJson, channel.matchContentValue, ctx.body);
} else if (channel.matchContentXpath || channel.matchContentJson) {
logger.error("Channel with name '" + channel.name + "' is invalid as it has a content match expression but no value to match");
return false;
} else {
return true;
}
};
matchRegex = function(regexPat, body) {
var regex;
regex = new RegExp(regexPat);
return regex.test(body.toString());
};
matchXpath = function(xpathStr, val, xml) {
var doc, xpathVal;
doc = new dom().parseFromString(xml.toString());
xpathVal = xpath.select(xpathStr, doc).toString();
return val === xpathVal;
};
matchJsonPath = function(jsonPath, val, json) {
var jsonObj, jsonVal;
jsonObj = JSON.parse(json.toString());
jsonVal = getJSONValByString(jsonObj, jsonPath);
return val === jsonVal.toString();
};
getJSONValByString = function(jsonObj, jsonPath) {
var part, parts;
jsonPath = jsonPath.replace(/\[(\w+)\]/g, '.$1');
jsonPath = jsonPath.replace(/^\./, '');
parts = jsonPath.split('.');
while (parts.length) {
part = parts.shift();
if (part in jsonObj) {
jsonObj = jsonObj[part];
} else {
return;
}
}
return jsonObj;
};
extractContentType = function(ctHeader) {
var index;
index = ctHeader.indexOf(';');
if (index !== -1) {
return ctHeader.substring(0, index).trim();
} else {
return ctHeader.trim();
}
};
matchUrlPattern = function(channel, ctx) {
var pat;
pat = new RegExp(channel.urlPattern);
return pat.test(ctx.request.path);
};
matchContentTypes = function(channel, ctx) {
var ct, ref;
if (((ref = channel.matchContentTypes) != null ? ref.length : void 0) > 0) {
if (ctx.request.header && ctx.request.header['content-type']) {
ct = extractContentType(ctx.request.header['content-type']);
if (indexOf.call(channel.matchContentTypes, ct) >= 0) {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return true;
}
};
matchFunctions = [matchUrlPattern, matchContent, matchContentTypes];
matchChannel = function(channel, ctx) {
return matchFunctions.every(function(matchFunc) {
return matchFunc(channel, ctx);
});
};
findMatchingChannel = function(channels, ctx) {
return channels.find(function(channel) {
return matchChannel(channel, ctx);
});
};
matchRequest = function(ctx, done) {
return utils.getAllChannelsInPriorityOrder(function(err, channels) {
var match;
if (err) {
ctx.response.status = 500;
logger.error('Could not fetch OpenHIM channels', err);
return done();
}
channels = channels.filter(Channels.isChannelEnabled);
match = findMatchingChannel(channels, ctx);
return done(null, match);
});
};
exports.koaMiddleware = function*(next) {
var match, matchReq, startTime;
if (statsdServer.enabled) {
startTime = new Date();
}
matchReq = Q.denodeify(matchRequest);
match = (yield matchReq(this));
if (match != null) {
logger.info("The channel that matches the request " + this.request.path + " is: " + match.name);
this.matchingChannel = match;
} else {
logger.info("No channel matched the request " + this.request.path);
}
if (statsdServer.enabled) {
sdc.timing(domain + ".authorisationMiddleware", startTime);
}
return (yield next);
};
if (process.env.NODE_ENV === "test") {
exports.matchContent = matchContent;
exports.matchRegex = matchRegex;
exports.matchXpath = matchXpath;
exports.matchJsonPath = matchJsonPath;
exports.extractContentType = extractContentType;
exports.matchRequest = matchRequest;
}
//# sourceMappingURL=requestMatching.js.map