Last active
April 23, 2018 06:57
-
-
Save awestover89/a53c0f2811c566c902a473ea22e825a5 to your computer and use it in GitHub Desktop.
Node.js lambda function for gw_proxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var http = require('http'); | |
var https = require('https'); | |
var util = require('util'); | |
exports.handler = function(event, context, callback) { | |
console.log(util.inspect(event, 3)); | |
console.log(util.inspect(context, 3)); | |
// setup request options and parameters | |
var options = { | |
host: event.requestParams.hostname, | |
port: event.requestParams.port, | |
path: event.requestParams.path, | |
method: event.requestParams.method | |
}; | |
// if you have headers set them otherwise set the property to an empty map | |
if (event.params && event.params.header && Object.keys(event.params.header).length > 0) { | |
options.headers = event.params.header | |
} else { | |
options.headers = {}; | |
} | |
// Grab the correct "Host" header | |
options.headers["Host"] = event.requestParams.hostname; | |
// Force the user agent and the "forwaded for" headers because we want to | |
// take them from the API Gateway context rather than letting Node.js set the Lambda ones | |
options.headers["User-Agent"] = event.context["user-agent"]; | |
options.headers["X-Forwarded-For"] = event.context["source-ip"]; | |
options.headers["X-dt-account-id"] = event.context["x-dt-account-id"]; | |
// if I don't have a content type I force it application/json | |
// Test invoke in the API Gateway console does not pass a value | |
if (!options.headers["Content-Type"]) { | |
options.headers["Content-Type"] = "application/json"; | |
} | |
// modify the path if necessary | |
if (event.params && event.params.path && Object.keys(event.params.path).length > 0) { | |
var updatedPath = replacePathParams(event.params.path, event.requestParams.path); | |
options.path = updatedPath; | |
} | |
// build the query string | |
if (event.params && event.params.querystring && Object.keys(event.params.querystring).length > 0) { | |
var queryString = generateQueryString(event.params.querystring); | |
if (queryString !== "") { | |
options.path += "?" + queryString; | |
} | |
} | |
// Define my callback to read the response and generate a JSON output for API Gateway. | |
// The JSON output is parsed by the mapping templates | |
callback = function(response) { | |
var responseString = ''; | |
// Another chunk of data has been recieved, so append it to `str` | |
response.on('data', function (chunk) { | |
responseString += chunk; | |
}); | |
// The whole response has been received | |
response.on('end', function () { | |
console.log(responseString); | |
// Parse response to json | |
var jsonResponse = JSON.parse(responseString); | |
var output = { | |
status: response.statusCode, | |
bodyJson: jsonResponse, | |
headers: response.headers | |
}; | |
// if the response was a 200 we can just pass the entire JSON back to | |
// API Gateway for parsing. If the backend returned a non 200 status | |
// then we return it as an error | |
if (response.statusCode == 200) { | |
context.succeed(output); | |
} else { | |
// set the output JSON as a string inside the body property | |
output.bodyJson = responseString; | |
// stringify the whole thing again so that we can read it with | |
// the $util.parseJson method in the mapping templates | |
context.fail(JSON.stringify(output)); | |
} | |
}); | |
} | |
var req; | |
if (event.requestParams.scheme == 'http') { | |
req = http.request(options, callback); | |
} | |
else { | |
req = https.request(options, callback); | |
} | |
if (event.bodyJson && event.bodyJson !== "") { | |
req.write(JSON.stringify(event.bodyJson)); | |
} | |
req.on('error', function(e) { | |
console.log('problem with request: ' + e.message); | |
context.fail(JSON.stringify({ | |
status: 500, | |
bodyJson: JSON.stringify({ message: "Internal server error" }) | |
})); | |
}); | |
req.end(); | |
} | |
function replacePathParams(pathParams, path) { | |
var updatedPath = path; | |
for(var p in pathParams) { | |
if (pathParams.hasOwnProperty(p)) { | |
console.log('Replacing {' + p + '} with ' + pathParams[p]); | |
updatedPath = updatedPath.replace('{' + p + '}', pathParams[p]); | |
} | |
} | |
return updatedPath; | |
} | |
function generateQueryString(params) { | |
var str = []; | |
for(var p in params) { | |
if (params.hasOwnProperty(p)) { | |
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(params[p])); | |
} | |
} | |
return str.join("&"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment