mountebank-test
Version:
Over the wire test doubles
100 lines (82 loc) • 3.07 kB
JavaScript
;
var net = require('net'),
Q = require('q'),
url = require('url'),
errors = require('../../util/errors');
function create (logger, encoding) {
function socketName (socket) {
return socket.host + ':' + socket.port;
}
function format (request) {
return request.data.toString(encoding);
}
function connectionInfoFor (proxyDestination) {
if (typeof proxyDestination === 'string') {
var parts = url.parse(proxyDestination);
if (parts.protocol !== 'tcp:') {
throw errors.InvalidProxyError('Unable to proxy to any protocol other than tcp',
{ source: proxyDestination });
}
return { host: parts.hostname, port: parts.port };
}
else {
// old syntax, inconsistent with http proxies: { host: 'localhost', port: 3000 }
// left for backwards compatibility prior to version 1.4.1
return proxyDestination;
}
}
function getProxyRequest (proxyDestination, originalRequest) {
var buffer = new Buffer(originalRequest.data, encoding),
socket = net.connect(connectionInfoFor(proxyDestination), function () {
socket.write(buffer, function () { socket.end(); });
});
return socket;
}
function proxy (socket) {
var packets = [];
var deferred = Q.defer();
socket.on('data', function (data) {
packets.push(data);
});
socket.on('end', function () {
deferred.resolve({ data: Buffer.concat(packets).toString(encoding) });
});
return deferred.promise;
}
function to (proxyDestination, originalRequest) {
function log (direction, what) {
logger.debug('Proxy %s %s %s %s %s',
originalRequest.requestFrom, direction, JSON.stringify(format(what)), direction, socketName(proxyDestination));
}
var deferred = Q.defer(),
proxiedRequest;
try {
proxiedRequest = getProxyRequest(proxyDestination, originalRequest);
log('=>', originalRequest);
proxy(proxiedRequest).done(function (response) {
log('<=', response);
deferred.resolve(response);
});
proxiedRequest.once('error', function (error) {
if (error.code === 'ENOTFOUND') {
deferred.reject(errors.InvalidProxyError('Cannot resolve ' + JSON.stringify(proxyDestination)));
}
else if (error.code === 'ECONNREFUSED') {
deferred.reject(errors.InvalidProxyError('Unable to connect to ' + JSON.stringify(proxyDestination)));
}
else {
deferred.reject(error);
}
});
} catch (e) {
deferred.reject(e);
}
return deferred.promise;
}
return {
to: to
};
}
module.exports = {
create: create
};