Last active
October 10, 2018 15:02
-
-
Save hoffination/ffc5d69ac12b7f46ba017f0461d813c9 to your computer and use it in GitHub Desktop.
Proxy service to record requests and filter unwanted requests
This file contains 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 express = require('express'); | |
var expressProxy = require('express-http-proxy'); | |
var yakbak = require('yakbak'); | |
/** | |
* Create proxy service that caches calls | |
* @param { Object } config | |
* @param { string } config.serverHost - host of destination service | |
* @param { number } config.port - port to provide the proxy on localhost | |
* @param { string } [config.recordDir] - directory to store recordings within (default is /responses) | |
* @param { string[] } [config.filteredPaths] - paths to pass-through to the destination without recording (default is []) | |
* @param { boolean } [config.alwaysCallApi] - flag to pass-through all requests to destination without recording (default is false) | |
*/ | |
function proxyRecorder({ serverHost, port, recordDir = '/responses', filteredPaths = [], alwaysCallApi = false }) { | |
var server = yakbak(serverHost, { | |
dirname: __dirname + '/' + recordDir, | |
hash: hashMethod | |
}); | |
return express() | |
.use(function(req, res, next) { | |
const isFiltered = filteredPaths.reduce((prev, curr) => prev || req.path.indexOf(curr) !== -1, false); | |
if (isFiltered || alwaysCallApi) { | |
console.info('proxy - no record, real call'); | |
return expressProxy(serverHost)(req, res, next); | |
} | |
console.info('proxy - cache record'); | |
return server(req, res); | |
}) | |
.listen(port, () => { | |
console.log('Running proxy for ', serverHost, ' on port ', port); | |
}); | |
} | |
proxyRecorder({ serverHost: 'https://aws.random.cat', port: 1236, recordDir: 'cat', filteredPaths: ['/cat'] }); | |
proxyRecorder({ serverHost: 'https://randomfox.ca', port: 1237 }); | |
// hashing algorithm for requests | |
// source: https://github.com/flickr/incoming-message-hash/ | |
var crypto = require('crypto'); | |
var url = require('url'); | |
function hashMethod(req, body, algorithm, encoding) { | |
var hash = createHash(algorithm); | |
updateHash(hash, req); | |
hash.write(body); | |
return hash.digest(encoding || 'hex'); | |
} | |
function createHash(algorithm) { | |
return crypto.createHash(algorithm || 'md5'); | |
} | |
function updateHash(hash, req) { | |
var parts = url.parse(req.url, true); | |
hash.update(req.httpVersion); | |
hash.update(req.method); | |
hash.update(parts.pathname); | |
hash.update(JSON.stringify(sort(parts.query))); | |
// hash.update(JSON.stringify(sort(req.headers))); | |
hash.update(JSON.stringify(sort(req.trailers))); | |
} | |
function sort(obj) { | |
var ret = {}; | |
Object.keys(obj) | |
.sort() | |
.forEach(function(key) { | |
ret[key] = obj[key]; | |
}); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment