cloud-red
Version:
Harnessing Serverless for your cloud integration needs
124 lines (114 loc) • 3.56 kB
JavaScript
module.exports = function(RED) {
'use strict';
var awsUtil = require('./lib/aws');
const pathToRegexp = require('path-to-regexp');
const X_CLOUDRED_AWS_HEADER = 'x-cloudred-aws';
class ApiGatewayEventHandler {
/**
* ApiGatewayEventHandler
* @param {Object} props - LambdaHandler Properties
* @param {string} props.name - URLs to set up the routes
* @param {string} props.method - Method to set up the routes (for AWSHandler, only method used will be `post`)
* @param {string} props.url - Mapping of the AWS Events to the outgoing ports.export
*
*/
constructor(props) {
RED.nodes.createNode(this, props);
// public props
this.name = props.name;
this.method = props.method;
this.url = props.url;
this._regexp = pathToRegexp(this.url);
// handlers & middleware
this.close = this.close.bind(this);
this._createResponseWrapper = this._createResponseWrapper.bind(this);
this._getCloudRedHeader = this._getCloudRedHeader.bind(this);
this.callback = this.callback.bind(this);
// Init handler
RED.httpNode.mountEventHandler(this.callback);
//this.log(`APIGateway event handler mounted`);
}
close() {
RED.httpNode.unmountEventHandler(this.callback);
//this.log(`APIGateway event handler unmounted`);
}
_createResponseWrapper(res) {
var wrapper = {
_res: res
};
var toWrap = [
'append',
'attachment',
'cookie',
'clearCookie',
'download',
'end',
'format',
'get',
'json',
'jsonp',
'links',
'location',
'redirect',
'render',
'send',
'sendFile',
'sendStatus',
'set',
'status',
'type',
'vary'
];
toWrap.forEach(f => {
wrapper[f] = function() {
// node here before - pretty sure the this points ot the this of the outer function
this.warn(
RED._('httpin.errors.deprecated-call', { method: 'msg.res.' + f })
);
var result = res[f].apply(res, arguments);
if (result === res) {
return wrapper;
} else {
return result;
}
};
});
return wrapper;
}
_getCloudRedHeader(req) {
let value = req[X_CLOUDRED_AWS_HEADER] || req.body[X_CLOUDRED_AWS_HEADER];
if (!value) {
throw new Error(`Header: ${X_CLOUDRED_AWS_HEADER} not found`);
}
return value;
}
callback(req, res, next) {
// Check the route matches the props
let awsEventType = awsUtil.readTypeEvent(req);
// Filter only the api gateway events
if (awsEventType !== awsUtil.AWSEventTypes.APIGatewayEvent) {
return next();
}
// Filter the method
const httpMethod = this._getCloudRedHeader(req).event.httpMethod;
if (this.method.toLowerCase() !== httpMethod.toLowerCase()) {
return next();
}
// Filter the path
const httpPath = this._getCloudRedHeader(req).event.path;
const match = this._regexp.exec(httpPath);
if (match === null) {
return next();
}
// Pass the message to the next node
this.send({
_msgid: req._msgid,
_awsEventType: awsEventType,
req: req,
res: this._createResponseWrapper(res),
payload: req.body
});
}
}
RED.nodes.registerType('apigw-event-handler', ApiGatewayEventHandler);
};