Skip to content
This repository has been archived by the owner on Mar 27, 2018. It is now read-only.

Commit

Permalink
Initial implementation of draft76 handshaking support
Browse files Browse the repository at this point in the history
  • Loading branch information
miksago committed Jun 10, 2010
1 parent f61b848 commit 22650f0
Showing 1 changed file with 44 additions and 6 deletions.
50 changes: 44 additions & 6 deletions lib/ws/connection.js
Expand Up @@ -28,9 +28,6 @@ function Connection(server, req, socket, upgradeHead){

if(! checkVersion.call(this)){
this.reject("Invalid version.");
} else if(this.version == "draft76"){
debug.call(this, this.version+" connection");
this.reject("Draft76 is not yet supported.");
} else {
debug.call(this, this.version+" connection");

Expand Down Expand Up @@ -60,8 +57,9 @@ Connection.prototype.__state__ = 0;
Object.defineProperty(Connection.prototype, "readyState", {
set: function(state){
if(typeof state == "number"){
var oldstate = this.__state__;
this.__state__ = state;
this.emit("readyStateChange", this.__state__);
this.emit("readyStateChange", this.__state__, oldstate);
} else {
throw new Error("The value must be a number");
}
Expand Down Expand Up @@ -146,10 +144,10 @@ function setup(){
parser.write(data);
});

conn.addListener("readyStateChange", function(state){
conn.addListener("readyStateChange", function(state, oldstate){
if(state == 4){
attachClient.call(conn);
} else if( state == 5 ){
} else if( state == 5 && oldstate == 4){
detachClient.call(conn);
conn.emit("close");
}
Expand Down Expand Up @@ -356,5 +354,45 @@ handshake.draft75 = function(){
};

/* Using draft76 (security model), work out and send the handshake. */
function pack(num) {
var result = '';
result += String.fromCharCode(num >> 24 & 0xFF);
result += String.fromCharCode(num >> 16 & 0xFF);
result += String.fromCharCode(num >> 8 & 0xFF);
result += String.fromCharCode(num & 0xFF);
return result;
};

handshake.draft76 = function(){
var data = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
+ "Upgrade: WebSocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Origin: "+websocket_origin.call(this)+"\r\n"
+ "Sec-WebSocket-Location: "+websocket_location.call(this);

var strkey1 = this._req.headers['sec-websocket-key1']
, strkey2 = this._req.headers['sec-websocket-key2'];

var numkey1 = parseInt(strkey1.replace(/[^\d]/g, ""), 10)
, numkey2 = parseInt(strkey2.replace(/[^\d]/g, ""), 10);

var spaces1 = strkey1.replace(/[^\ ]/g, "").length
, spaces2 = strkey2.replace(/[^\ ]/g, "").length;

if (spaces1 == 0 || spaces2 == 0 || numkey1 % spaces1 != 0 || numkey2 % spaces2 != 0) {
this.reject("WebSocket contained an invalid key -- closing connection.");
} else {
var key1 = pack(parseInt(numkey1/spaces1))
, key2 = pack(parseInt(numkey2/spaces2));

var hash = require("crypto").createHash("md5");
hash.update([key1, key2, this._upgradeHead.toString("binary")].join(""));

data += "\r\n\r\n";
data += hash.digest("binary");

this._req.socket.write(data, "binary");
this._req.socket.flush();
this.readyState = 4;
}
};

0 comments on commit 22650f0

Please sign in to comment.