Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion lib/WebSocketClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ function WebSocketClient(config) {
}

this._req = null;

switch (this.config.webSocketVersion) {
case 8:
case 13:
Expand All @@ -112,6 +112,40 @@ function WebSocketClient(config) {

util.inherits(WebSocketClient, EventEmitter);

function handleWsfProtocol(url) {
var path = require('path');
var fs = require('fs');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like at all this. Modules should not be loaded within functions but on the top of the file.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no problem, let's move it out

meno

On Thu, Jun 16, 2016, 23:26 Iñaki Baz Castillo [email protected]
wrote:

In lib/WebSocketClient.js
#240 (comment)
:

@@ -112,6 +112,40 @@ function WebSocketClient(config) {

util.inherits(WebSocketClient, EventEmitter);

+function handleWsfProtocol(url) {

  • var path = require('path');
  • var fs = require('fs');

I don't like at all this. Modules should not be loaded within functions
but on the top of the file.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/theturtle32/WebSocket-Node/pull/240/files/91c9b1d2ab8bb696192a7ee7b63bcafb982ef665#r67427092,
or mute the thread
https://github.com/notifications/unsubscribe/AABLJvfQ3PNafTCAYIORlUE8TvYZUxzyks5qMb-GgaJpZM4I3T8z
.

var parts = url.href.substring("wsf://".length).split(path.sep);
var sockName = "/";
if (parts[0] == "." || parts[0] == "..") {
sockName = "";
}
var found = false;
var sep = "";
for (var i = 0; i < parts.length; ++i) {
sockName += sep + parts[i];
// ugly sync but is this really worth change the hole api
var stat = fs.statSync(sockName);
try {
found = stat && stat.isSocket();
if (found) {
url.socketPath = sockName;
url.host = 'localhost';
url.hostname = 'localhost';
url.pathname = "kaputt";
url.path = '/' + parts.slice(i+1).join('/');
break;
}
} catch (e) {
// ignore
}
sep = path.sep
}
if (!found) {
throw new Error('no socket found in wsf url:' + url.href);
}
}

WebSocketClient.prototype.connect = function(requestUrl, protocols, origin, headers, extraRequestOptions) {
var self = this;
if (typeof(protocols) === 'string') {
Expand All @@ -137,6 +171,9 @@ WebSocketClient.prototype.connect = function(requestUrl, protocols, origin, head
if (!this.url.protocol) {
throw new Error('You must specify a full WebSocket URL, including protocol.');
}
if (this.url.protocol == "wsf:") {
handleWsfProtocol(this.url);
}
if (!this.url.host) {
throw new Error('You must specify a full WebSocket URL, including hostname. Relative URLs are not supported.');
}
Expand Down Expand Up @@ -224,6 +261,7 @@ WebSocketClient.prototype.connect = function(requestUrl, protocols, origin, head
// These options are always overridden by the library. The user is not
// allowed to specify these directly.
extend(requestOptions, {
socketPath: this.url.socketPath,
hostname: this.url.hostname,
port: this.url.port,
method: 'GET',
Expand Down
22 changes: 11 additions & 11 deletions lib/WebSocketRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ function WebSocketRequest(socket, httpRequest, serverConfig) {
this.remoteAddress = socket.remoteAddress;
this.remoteAddresses = [this.remoteAddress];
this.serverConfig = serverConfig;

// Watch for the underlying TCP socket closing before we call accept
this._socketIsClosing = false;
this._socketCloseHandler = this._handleSocketCloseBeforeAccept.bind(this);
this.socket.on('end', this._socketCloseHandler);
this.socket.on('close', this._socketCloseHandler);

this._resolved = false;
}

Expand Down Expand Up @@ -248,7 +248,7 @@ WebSocketRequest.prototype.parseCookies = function(str) {

WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, cookies) {
this._verifyResolution();

// TODO: Handle extensions

var protocolFullCase;
Expand Down Expand Up @@ -286,7 +286,7 @@ WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, co
}
if (this.requestedProtocols.indexOf(acceptedProtocol) === -1) {
this.reject(500);
throw new Error('Specified protocol was not requested by the client.');
throw new Error('Specified protocol was not requested by the client:'+acceptedProtocol+":"+this.requestedProtocols);
}

protocolFullCase = protocolFullCase.replace(headerSanitizeRegExp, '');
Expand Down Expand Up @@ -426,21 +426,21 @@ WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, co
// if (negotiatedExtensions) {
// response += 'Sec-WebSocket-Extensions: ' + negotiatedExtensions.join(', ') + '\r\n';
// }

// Mark the request resolved now so that the user can't call accept or
// reject a second time.
this._resolved = true;
this.emit('requestResolved', this);

response += '\r\n';

var connection = new WebSocketConnection(this.socket, [], acceptedProtocol, false, this.serverConfig);
connection.webSocketVersion = this.webSocketVersion;
connection.remoteAddress = this.remoteAddress;
connection.remoteAddresses = this.remoteAddresses;

var self = this;

if (this._socketIsClosing) {
// Handle case when the client hangs up before we get a chance to
// accept the connection and send our side of the opening handshake.
Expand All @@ -452,7 +452,7 @@ WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, co
cleanupFailedConnection(connection);
return;
}

self._removeSocketCloseListeners();
connection._addSocketEventListeners();
});
Expand All @@ -464,12 +464,12 @@ WebSocketRequest.prototype.accept = function(acceptedProtocol, allowedOrigin, co

WebSocketRequest.prototype.reject = function(status, reason, extraHeaders) {
this._verifyResolution();

// Mark the request resolved now so that the user can't call accept or
// reject a second time.
this._resolved = true;
this.emit('requestResolved', this);

if (typeof(status) !== 'number') {
status = 403;
}
Expand Down
95 changes: 95 additions & 0 deletions test/unit/fileSockets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env node

var test = require('tape');
var http = require('http');
var WebSocketServer = require('../../lib/WebSocketServer');
var WebSocketClient = require('../../lib/WebSocketClient');


function serverSide(t, sockFname) {
var server = http.createServer((request, response) => {
response.writeHead(404);
response.end();
});
server.listen(sockFname, () => { });
server.on('error', (e) => {
t.assert(true, false, "errors should not happen");
});

var wsServer = new WebSocketServer({ httpServer: server, autoAcceptConnections: false });
wsServer.on('request', (request) => {
var connection = request.accept('sockfname-protocol', request.origin);
connection.on('message', function(message) {
//console.log(">>",message);
switch (message.utf8Data) {
case "ping" :
connection.send("pong");
break;
case "bye" :
connection.close();
break;
}
});
connection.on('close', function(reasonCode, description) {
});
});
return server;
}

function clientSide(t, sockFname, cb) {
let client = new WebSocketClient();
client.on('connectFailed', (error) => {
console.error(error);
t.assert(true, false, "errors should not happen");
});

client.on('connect', (connection) => {
connection.on('error', (error) => {
t.assert(true, false, "errors should not happen");
});
connection.on('close', function() {
t.assert(true, true);
cb();
});
connection.on('message', function(message) {
switch (message.utf8Data) {
case "pong" :
connection.send("bye");
}
});
//console.log("<<ping");
connection.send("ping");
});
if (typeof(sockFname) == "number") {
client.connect('ws://localhost:'+sockFname+'/', 'sockfname-protocol');
} else {
client.connect('wsf://'+sockFname+'/', 'sockfname-protocol');
}
}

function run(t, socket, finCb) {
var server = serverSide(t, socket);
var i = 0;
var cb = function() {
//console.log("i="+i)
if (i < 10) {
++i;
clientSide(t, socket, cb);
} else {
server.close();
finCb && finCb();
}
}
clientSide(t, socket, cb);
}

test('use wsf to connect over file sockets', function(t) {
t.plan(10 + 1);
var sock = "./S.test."+process.pid;
run(t, sock);
});

test('use wsf to connect over tcp sockets', function(t) {
t.plan(10 + 1);
run(t, 4711);
});