Skip to content

added the wsf protocol #240

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
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);
});