initial import

initial import

Авторeinaros
Коммитерeinaros
14 лет назад
Файлов изменено: 8
+231
–0
19093dc
Родители v1.x
.gitignore
0 100644
@@ -0,0 +1,5 @@
npm-debug.log
node_modules
history/
cache/
.*.swp
Makefile
0 100644
@@ -0,0 +1,13 @@
ALL_TESTS = $(shell find test/ -name '*.test.js')
run-tests:
    @./node_modules/.bin/expresso \
        -t 2000 \
        --serial \
        $(TESTFLAGS) \
        $(TESTS)
test:
    @$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests
.PHONY: test
index.js
0 100644
@@ -0,0 +1 @@
module.exports = require('./lib/Wetsock');
No newline at end of file
lib/Wetsock.js
0 100644
@@ -0,0 +1,68 @@
var util = require('util');
var events = require('events');
var http = require('http');
var crypto = require('crypto');
function Wetsock(server, port, options) {
    var serverPort = 80;
    if (typeof port === 'number') serverPort = port;
    else if (typeof port === 'object') options = port;
    options = options || {};
    options.origin = options.origin || null;
    
    var key = 'dGhlIHNhbXBsZSBub25jZQ==';
    var shasum = crypto.createHash('sha1');  
    shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");  
    var expectedServerKey = shasum.digest('base64');
    
    var requestOptions = {
        port: serverPort, 
        host: server,
        headers: {
            'Connection''Upgrade'
            'Upgrade''websocket',
            'Sec-WebSocket-Version'13,
            'Sec-WebSocket-Key': key
        }
    };
    if (options.origin) requestOptions.headers.origin = options.origin;
    
    var req = http.request(requestOptions);
    req.end();
    this._socket = null;
    this._state = 'connecting';
    var self = this;
    req.on('upgrade'function(res, socket, upgradeHead) {
        if (self._state == 'disconnected') {
            socket.end();
            return;
        }
        var serverKey = res.headers['sec-websocket-accept'];
        if (typeof serverKey == 'undefined' || serverKey !== expectedServerKey) {
            self.emit('error''invalid server key');
            socket.end();
            return;
        }
        self._socket = socket;
        self._state = 'connected';
        self.emit('connect');
    });
}
util.inherits(Wetsock, events.EventEmitter);
Wetsock.prototype.close = function() {
    if (this._socket) {
        this._socket.end();
        this._socket = null;
    }
    else if (this._state == 'connecting') {
        this._state = 'disconnected';
    }
}
Wetsock.prototype.send = function(data, options) {
    if (this._state != 'connected'throw 'not connected';
    
}
module.exports = Wetsock;
No newline at end of file
package.json
0 100644
@@ -0,0 +1,20 @@
{
  "author":"Einar Otto Stangvik <einaros@gmail.com> (http://2x.io)",
  "name":"wetsock",
  "description":"microscopic websocket client",
  "version":"0.0.1",
  "repository":{
    "type":"git",
    "url":"git://github.com/einaros/wetsock.git"
  },
  "scripts":{
    "test":"make test"
  },
  "engines":{
    "node":"~0.6.0"
  },
  "dependencies":{
    "expresso":"latest"
  },
  "devDependencies":{}
}
test/Wetsock.test.js
0 100644
@@ -0,0 +1,42 @@
var assert = require('assert');
var Wetsock = require('../');
var server = require('./server');
var port = 20000;
module.exports = {
    'can connect to echo service'function() {
        var ws = new Wetsock('echo.websocket.org');
        ws.on('connect'function() {
            ws.close();
        });
    },
    'can disconnect before connection is established'function(done) {
        var ws = new Wetsock('echo.websocket.org');
        ws.close();
        ws.on('connect'function() {
            assert.fail('connect shouldnt be raised here');
        });
        ws.on('disconnect'function() {
            done();
        });
    },
    'send before connect should fail'function(done) {
        var ws = new Wetsock('echo.websocket.org');
        try {
            ws.send('hi');            
        }
        catch (e) {
            ws.close();
            done();
        }
    },
    'invalid server key is denied'function(done) {
        var srv = server.listen(++port, server.handlers.invalidKey);
        var ws = new Wetsock('localhost', port);
        ws.on('error'function() {
            srv.close();
            done();
        });
    },    
}
No newline at end of file
test/server.js
0 100644
@@ -0,0 +1,82 @@
var http = require('http');
var crypto = require('crypto');
function validRequestHandler(req, socket) {
    if (typeof req.headers.upgrade === 'undefined' || 
        req.headers.upgrade.toLowerCase() !== 'websocket') {
        throw 'invalid headers';
        return;
    }
    if (!req.headers['sec-websocket-key']) {
        socket.end();
        throw 'websocket key is missing';
    }
        
    // calc key
    var key = req.headers['sec-websocket-key'];    
    var shasum = crypto.createHash('sha1');    
    shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");    
    key = shasum.digest('base64');
    var headers = [
          'HTTP/1.1 101 Switching Protocols'
        'Upgrade: websocket'
        'Connection: Upgrade'
        'Sec-WebSocket-Accept: ' + key
    ];
    socket.write(headers.concat('''').join('\r\n'));
    socket.end();
    // socket.on('data', function (data) {
    //     self.parser.add(data);
    // });
}
function invalidRequestHandler(req, socket) {
    if (typeof req.headers.upgrade === 'undefined' || 
        req.headers.upgrade.toLowerCase() !== 'websocket') {
        throw 'invalid headers';
        return;
    }
    if (!req.headers['sec-websocket-key']) {
        socket.end();
        throw 'websocket key is missing';
    }
        
    // calc key
    var key = req.headers['sec-websocket-key'];    
    var shasum = crypto.createHash('sha1');    
    shasum.update(key + "bogus");    
    key = shasum.digest('base64');
    var headers = [
          'HTTP/1.1 101 Switching Protocols'
        'Upgrade: websocket'
        'Connection: Upgrade'
        'Sec-WebSocket-Accept: ' + key
    ];
    socket.write(headers.concat('''').join('\r\n'));
    socket.end();
    // socket.on('data', function (data) {
    //     self.parser.add(data);
    // });
}
module.exports = {
    handlers: {
        valid: validRequestHandler,
        invalidKey: invalidRequestHandler,        
    },
    listenfunction(port, handler) {
        var srv = http.createServer(function (req, res) {
            res.writeHead(200, {'Content-Type''text/plain'});
            res.end('okay');
        });
        srv.on('upgrade', handler || validRequestHandler);
        srv.listen(port, '127.0.0.1');
        return srv;
    }
};
No newline at end of file

Cherry-pick

Команда cherry-pick позволяет выбрать отдельные коммиты из одной ветки и применить их к другой.