Skip to content

Instantly share code, notes, and snippets.

@hoffination
Last active October 10, 2018 15:02
Show Gist options
  • Save hoffination/ffc5d69ac12b7f46ba017f0461d813c9 to your computer and use it in GitHub Desktop.
Save hoffination/ffc5d69ac12b7f46ba017f0461d813c9 to your computer and use it in GitHub Desktop.
Proxy service to record requests and filter unwanted requests
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