Skip to content

Instantly share code, notes, and snippets.

@geekingfrog
Last active October 15, 2015 08:44
Show Gist options
  • Save geekingfrog/cfec24819a7c21d85f59 to your computer and use it in GitHub Desktop.
Save geekingfrog/cfec24819a7c21d85f59 to your computer and use it in GitHub Desktop.
simple http duplicator
const forward = {host: 'duckduckgo.com', port: 80};
const duplicates = [{host: 'google.com', port: 80}];
const trace = console.trace.bind(console);
process.on('uncaughtException', console.trace.bind(console, 'uncaught exception:'));
const http = require('http');
const request = require('request');
const dns = require('dns');
const Promise = require('bluebird');
const memoizedDns = (function wrapper() {
const cache = new Map();
const lookup = Promise.promisify(dns.lookup, dns);
const maxTs = 5000;
return function memoizedDnsWrapped(url) {
const isCached = cache.get(url);
const isInFlight = isCached && !cache.get(url).ts;
const isStale = isCached && Date.now() - cache.get(url).ts > maxTs;
if (isInFlight) return cache.get(url);
if (isCached && !isStale) return cache.get(url).val;
console.log('looking up %s', url);
const result = lookup(url).timeout(2000).then(([ip]) => {
cache.set(url, { ts: Date.now(), val: Promise.resolve(ip) });
console.log('%s resolved to %s', url, ip);
return ip;
}).catch(cache.delete(url));
cache.set(url, result);
return result;
};
})();
const server = http.createServer((req, res) => {
console.log('got %s request to %s', req.method, req.url);
memoizedDns(forward.host)
.then((ip) =>{
req.pipe(request({
method: req.method,
url: `http://${ip}:${forward.port || 80}${req.url}`,
headers: req.headers,
}).on('error', () => trace.bind('socket hang up?'))).pipe(res)
.on('error', trace.bind('got error'));
}).catch(console.trace.bind(console, 'Error while forwarding'));
function dupRequest(dup) {
return (
memoizedDns(dup.host)
.then((ip) => {
req.pipe(request({
method: req.method,
url: `http://${ip}:${dup.port || 80}${req.url}`,
headers: req.headers,
}).once('error', (err) => {
console.error('error in dup request to :', dup.host, err);
trace();
}));
})
);
}
duplicates.map((dup) => {
dupRequest(dup).catch(trace.bind('Error while duplicating to ' + dup.host));
});
});
const port = 80;
server.listen(port, (err) => {
if (err) {
console.error('error while starting:', err);
process.exit(1);
}
console.log(`started on port ${port}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment