Thorsten Lorenz 000eb533de emitting proxySocket on proxyServer
- emitted once proxySocket was created and socket was piped into it
- needed to support sniffing messages coming from proxy target
2014-09-29 20:09:46 -04:00

129 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var http = require('http'),
https = require('https'),
common = require('../common'),
passes = exports;
/*!
* Array of passes.
*
* A `pass` is just a function that is executed on `req, socket, options`
* so that you can easily add new checks while still keeping the base
* flexible.
*/
/*
* Websockets Passes
*
*/
var passes = exports;
[
/**
* WebSocket requests must have the `GET` method and
* the `upgrade:websocket` header
*
* @param {ClientRequest} Req Request object
* @param {Socket} Websocket
*
* @api private
*/
function checkMethodAndHeader (req, socket) {
if (req.method !== 'GET' || !req.headers.upgrade) {
socket.destroy();
return true;
}
if (req.headers.upgrade.toLowerCase() !== 'websocket') {
socket.destroy();
return true;
}
},
/**
* Sets `x-forwarded-*` headers if specified in config.
*
* @param {ClientRequest} Req Request object
* @param {Socket} Websocket
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
function XHeaders(req, socket, options) {
if(!options.xfwd) return;
var values = {
for : req.connection.remoteAddress || req.socket.remoteAddress,
port : common.getPort(req),
proto: req.connection.pair ? 'wss' : 'ws'
};
['for', 'port', 'proto'].forEach(function(header) {
req.headers['x-forwarded-' + header] =
(req.headers['x-forwarded-' + header] || '') +
(req.headers['x-forwarded-' + header] ? ',' : '') +
values[header];
});
},
/**
* Does the actual proxying. Make the request and upgrade it
* send the Switching Protocols request and pipe the sockets.
*
* @param {ClientRequest} Req Request object
* @param {Socket} Websocket
* @param {Object} Options Config object passed to the proxy
*
* @api private
*/
function stream(req, socket, options, head, server, clb) {
common.setupSocket(socket);
if (head && head.length) socket.unshift(head);
var proxyReq = (~['https:', 'wss:'].indexOf(options.target.protocol) ? https : http).request(
common.setupOutgoing(options.ssl || {}, options, req)
);
// Error Handler
proxyReq.on('error', onOutgoingError);
proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) {
proxySocket.on('error', onOutgoingError);
// The pipe below will end proxySocket if socket closes cleanly, but not
// if it errors (eg, vanishes from the net and starts returning
// EHOSTUNREACH). We need to do that explicitly.
socket.on('error', function () {
proxySocket.end();
});
common.setupSocket(proxySocket);
if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead);
socket.write('HTTP/1.1 101 Switching Protocols\r\n');
socket.write(Object.keys(proxyRes.headers).map(function(i) {
return i + ": " + proxyRes.headers[i];
}).join('\r\n') + '\r\n\r\n');
proxySocket.pipe(socket).pipe(proxySocket);
server.emit('proxySocket', proxySocket);
});
return proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT
function onOutgoingError(err) {
if (clb) {
clb(err, req, socket);
} else {
server.emit('error', err, req, socket);
}
}
}
] // <--
.forEach(function(func) {
passes[func.name] = func;
});