Skip to content

Commit 44a8566

Browse files
committed
[test] Continued work around Origin mismatch tests
1 parent 9ab54ab commit 44a8566

File tree

3 files changed

+126
-115
lines changed

3 files changed

+126
-115
lines changed

lib/node-http-proxy.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -588,12 +588,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
588588
_socket(socket);
589589

590590
// Remote host address
591-
var agent = _getAgent(options.host, options.port),
592-
remoteHost = options.host + (options.port - 80 === 0 ? '' : ':' + options.port);
591+
var protocolName = options.https || this.https ? 'https' : 'http',
592+
agent = _getAgent(options.host, options.port),
593+
remoteHost = options.host + (options.port - 80 === 0 ? '' : ':' + options.port);
593594

594595
// Change headers
595596
req.headers.host = remoteHost;
596-
req.headers.origin = 'http://' + options.host;
597+
req.headers.origin = protocolName + '://' + options.host;
597598

598599
outgoing = {
599600
host: options.host,

test/web-socket-proxy-test.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var vows = require('vows'),
2929
colors = require('colors'),
3030
request = require('request'),
3131
assert = require('assert'),
32+
argv = require('optimist').argv,
3233
websocket = require('./../vendor/websocket'),
3334
helpers = require('./helpers');
3435

@@ -42,8 +43,11 @@ catch (ex) {
4243
process.exit(1);
4344
}
4445

45-
var runner = new helpers.TestRunner();
46+
var protocol = argv.https ? 'https' : 'http',
47+
wsprotocol = argv.https ? 'wss' : 'ws',
48+
runner = new helpers.TestRunner(protocol);
4649

50+
require('eyes').inspect(protocol);
4751
vows.describe('node-http-proxy/websocket').addBatch({
4852
"When using server created by httpProxy.createServer()": {
4953
"with no latency" : {
@@ -65,8 +69,8 @@ vows.describe('node-http-proxy/websocket').addBatch({
6569
//
6670
// Setup the web socket against our proxy
6771
//
68-
var ws = new websocket.WebSocket('ws://localhost:8131/socket.io/websocket/', 'borf', {
69-
origin: 'http://localhost'
72+
var ws = new websocket.WebSocket(wsprotocol + '://localhost:8131/socket.io/websocket/', 'borf', {
73+
origin: 'https://localhost'
7074
});
7175

7276
ws.on('wsupgrade', function (req, res) {
@@ -101,8 +105,8 @@ vows.describe('node-http-proxy/websocket').addBatch({
101105
//
102106
// Setup the web socket against our proxy
103107
//
104-
var ws = new websocket.WebSocket('ws://localhost:8133/socket.io/websocket/', 'borf', {
105-
origin: 'http://localhost'
108+
var ws = new websocket.WebSocket(wsprotocol + '://localhost:8133/socket.io/websocket/', 'borf', {
109+
origin: 'https://localhost'
106110
});
107111

108112
ws.on('wsupgrade', function (req, res) {

vendor/websocket.js

+113-107
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ var buffer = require('buffer');
3535
var crypto = require('crypto');
3636
var events = require('events');
3737
var http = require('http');
38+
var https = require('https');
3839
var net = require('net');
3940
var urllib = require('url');
4041
var sys = require('sys');
@@ -178,16 +179,6 @@ var str2hex = function(str) {
178179
return out.trim();
179180
};
180181

181-
// Get the scheme for a URL, undefined if none is found
182-
var getUrlScheme = function(url) {
183-
var i = url.indexOf(':');
184-
if (i == -1) {
185-
return undefined;
186-
}
187-
188-
return url.substring(0, i);
189-
};
190-
191182
// Set a constant on the given object
192183
var setConstant = function(obj, name, value) {
193184
Object.defineProperty(obj, name, {
@@ -501,125 +492,140 @@ var WebSocket = function(url, proto, opts) {
501492
// that http.Client passes its constructor arguments through,
502493
// un-inspected to net.Stream.connect(). The latter accepts a
503494
// string as its first argument to connect to a UNIX socket.
504-
var httpClient = undefined;
505-
switch (getUrlScheme(url)) {
506-
case 'ws':
507-
var u = urllib.parse(url);
508-
httpClient = http.createClient(u.port || 80, u.hostname);
495+
var protocol, agent, port, u = urllib.parse(url);
496+
if (u.protocol === 'ws:' || u.protocol === 'wss:') {
497+
require('eyes').inspect(u);
498+
protocol = u.protocol === 'ws:' ? http : https;
499+
port = u.protocol === 'ws:' ? 80 : 443;
500+
agent = u.protocol === 'ws:' ? protocol.getAgent(u.hostname, u.port || port) : protocol.getAgent({
501+
host: u.hostname,
502+
port: u.port || port
503+
});
504+
509505
httpPath = (u.pathname || '/') + (u.search || '');
510506
httpHeaders.Host = u.hostname + (u.port ? (":" + u.port) : "");
511-
break;
512-
513-
case 'ws+unix':
514-
var sockPath = url.substring('ws+unix://'.length, url.length);
515-
httpClient = http.createClient(sockPath);
516-
httpHeaders.Host = 'localhost';
517-
break;
518-
519-
default:
507+
}
508+
else if (urlScheme === 'ws+unix') {
509+
throw new Error('ws+unix is not implemented');
510+
// var sockPath = url.substring('ws+unix://'.length, url.length);
511+
// httpClient = http.createClient(sockPath);
512+
// httpHeaders.Host = 'localhost';
513+
}
514+
else {
520515
throw new Error('Invalid URL scheme \'' + urlScheme + '\' specified.');
521516
}
522-
523-
httpClient.on('upgrade', (function() {
524-
var data = undefined;
525-
526-
return function(res, s, head) {
527-
stream = s;
528-
529-
//
530-
// Emit the `wsupgrade` event to inspect the raw
531-
// arguments returned from the websocket request.
532-
//
533-
self.emit('wsupgrade', httpHeaders, res, s, head);
517+
518+
if (!agent._events || agent._events['upgrade'].length === 0) {
519+
agent.on('upgrade', (function() {
520+
var data = undefined;
521+
522+
return function(res, s, head) {
523+
stream = s;
524+
525+
//
526+
// Emit the `wsupgrade` event to inspect the raw
527+
// arguments returned from the websocket request.
528+
//
529+
self.emit('wsupgrade', httpHeaders, res, s, head);
534530

535-
stream.on('data', function(d) {
536-
if (d.length <= 0) {
537-
return;
538-
}
531+
stream.on('data', function(d) {
532+
if (d.length <= 0) {
533+
return;
534+
}
539535

540-
if (!data) {
541-
data = d;
542-
} else {
543-
var data2 = new buffer.Buffer(data.length + d.length);
536+
if (!data) {
537+
data = d;
538+
} else {
539+
var data2 = new buffer.Buffer(data.length + d.length);
544540

545-
data.copy(data2, 0, 0, data.length);
546-
d.copy(data2, data.length, 0, d.length);
541+
data.copy(data2, 0, 0, data.length);
542+
d.copy(data2, data.length, 0, d.length);
547543

548-
data = data2;
549-
}
550-
551-
if (data.length >= 16) {
552-
var expected = computeSecretKeySignature(key1, key2, challenge);
553-
var actual = data.slice(0, 16).toString('binary');
544+
data = data2;
545+
}
554546

555-
// Handshaking fails; we're donezo
556-
if (actual != expected) {
557-
debug(
558-
'expected=\'' + str2hex(expected) + '\'; ' +
559-
'actual=\'' + str2hex(actual) + '\''
560-
);
547+
if (data.length >= 16) {
548+
var expected = computeSecretKeySignature(key1, key2, challenge);
549+
var actual = data.slice(0, 16).toString('binary');
561550

562-
process.nextTick(function() {
563-
// N.B. Emit 'wserror' here, as 'error' is a reserved word in the
564-
// EventEmitter world, and gets thrown.
565-
self.emit(
566-
'wserror',
567-
new Error('Invalid handshake from server:' +
568-
'expected \'' + str2hex(expected) + '\', ' +
569-
'actual \'' + str2hex(actual) + '\''
570-
)
551+
// Handshaking fails; we're donezo
552+
if (actual != expected) {
553+
debug(
554+
'expected=\'' + str2hex(expected) + '\'; ' +
555+
'actual=\'' + str2hex(actual) + '\''
571556
);
572557

573-
if (self.onerror) {
574-
self.onerror();
575-
}
558+
process.nextTick(function() {
559+
// N.B. Emit 'wserror' here, as 'error' is a reserved word in the
560+
// EventEmitter world, and gets thrown.
561+
self.emit(
562+
'wserror',
563+
new Error('Invalid handshake from server:' +
564+
'expected \'' + str2hex(expected) + '\', ' +
565+
'actual \'' + str2hex(actual) + '\''
566+
)
567+
);
568+
569+
if (self.onerror) {
570+
self.onerror();
571+
}
572+
573+
finishClose();
574+
});
575+
}
576576

577-
finishClose();
578-
});
579-
}
577+
//
578+
// Un-register our data handler and add the one to be used
579+
// for the normal, non-handshaking case. If we have extra
580+
// data left over, manually fire off the handler on
581+
// whatever remains.
582+
//
583+
stream.removeAllListeners('data');
584+
stream.on('data', dataListener);
580585

581-
// Un-register our data handler and add the one to be used
582-
// for the normal, non-handshaking case. If we have extra
583-
// data left over, manually fire off the handler on
584-
// whatever remains.
585-
//
586-
// XXX: This is lame. We should only remove the listeners
587-
// that we added.
588-
httpClient.removeAllListeners('upgrade');
589-
stream.removeAllListeners('data');
590-
stream.on('data', dataListener);
586+
readyState = OPEN;
591587

592-
readyState = OPEN;
588+
process.nextTick(function() {
589+
self.emit('open');
593590

594-
process.nextTick(function() {
595-
self.emit('open');
591+
if (self.onopen) {
592+
self.onopen();
593+
}
594+
});
596595

597-
if (self.onopen) {
598-
self.onopen();
596+
// Consume any leftover data
597+
if (data.length > 16) {
598+
stream.emit('data', data.slice(16, data.length));
599599
}
600-
});
601-
602-
// Consume any leftover data
603-
if (data.length > 16) {
604-
stream.emit('data', data.slice(16, data.length));
605600
}
606-
}
607-
});
608-
stream.on('fd', fdListener);
609-
stream.on('error', errorListener);
610-
stream.on('close', function() {
611-
errorListener(new Error('Stream closed unexpectedly.'));
612-
});
613-
614-
stream.emit('data', head);
615-
};
616-
})());
617-
httpClient.on('error', function(e) {
618-
httpClient.end();
601+
});
602+
stream.on('fd', fdListener);
603+
stream.on('error', errorListener);
604+
stream.on('close', function() {
605+
errorListener(new Error('Stream closed unexpectedly.'));
606+
});
607+
608+
stream.emit('data', head);
609+
};
610+
})());
611+
}
612+
613+
agent.on('error', function (e) {
619614
errorListener(e);
620615
});
621616

622-
var httpReq = httpClient.request(httpPath, httpHeaders);
617+
618+
var x = {
619+
host: u.hostname,
620+
method: 'GET',
621+
agent: agent,
622+
port: u.port,
623+
path: httpPath,
624+
headers: httpHeaders
625+
};
626+
require('eyes').inspect(x);
627+
var httpReq = protocol.request(x);
628+
623629
httpReq.write(challenge, 'binary');
624630
httpReq.end();
625631
})();

0 commit comments

Comments
 (0)