Commit 0fad03cb authored by Ximin Luo's avatar Ximin Luo

Imported Upstream version 0.7.2+ds1.349b7460

parent 5f88f369
language: node_js
npm_args: --ws:native
node_js:
- "0.8"
- "0.12"
- "0.11"
- "0.10"
- "0.9"
- "0.8"
- "iojs-v1.1"
- "iojs-v1.0"
- "iojs-v2.0"
before_install:
- "npm install -g npm@2.1.18"
matrix:
fast_finish: true
allow_failures:
- node_js: "0.11"
- node_js: "0.9"
- node_js: "iojs-v1.1"
- node_js: "iojs-v1.0"
- node_js: "iojs-v2.0"
# ws: a node.js websocket library
[![Build Status](https://travis-ci.org/einaros/ws.svg?branch=master)](https://travis-ci.org/einaros/ws)
[![Build Status](https://travis-ci.org/websockets/ws.svg?branch=master)](https://travis-ci.org/websockets/ws)
`ws` is a simple to use WebSocket implementation, up-to-date against RFC-6455,
and [probably the fastest WebSocket library for node.js][archive].
Passes the quite extensive Autobahn test suite. See http://einaros.github.com/ws
Passes the quite extensive Autobahn test suite. See http://websockets.github.com/ws
for the full reports.
## Protocol support
......@@ -135,6 +135,13 @@ ws.on('message', function message(data, flags) {
});
```
### Browserify users
When including ws via a browserify bundle, ws returns global.WebSocket which has slightly different API.
You should use the standard WebSockets API instead.
https://developer.mozilla.org/en-US/docs/WebSockets/Writing_WebSocket_client_applications#Availability_of_WebSockets
### Other examples
For a full example with a browser client communicating with a ws server, see the
......@@ -153,11 +160,11 @@ make test
## API Docs
See the doc/ directory for Node.js-like docs for the ws classes.
See [`/doc/ws.md`](https://github.com/websockets/ws/blob/master/doc/ws.md) for Node.js-like docs for the ws classes.
## Changelog
We're using the GitHub `releases` for changelog entries.
We're using the GitHub [`releases`](https://github.com/websockets/ws/releases) for changelog entries.
## License
......
bufferutil=1.0.1
utf-8-validate=1.0.1
ultron=1.0.1
bufferutil=1.1.0
utf-8-validate=1.1.0
ultron=1.0.2
options.js=0.20.gff53d0a
wscat=0.1.gaa46950
wscat=0.3.g6d2391a
......@@ -16,6 +16,7 @@ This class is a WebSocket server. It is an `EventEmitter`.
* `noServer` Boolean
* `disableHixie` Boolean
* `clientTracking` Boolean
* `perMessageDeflate` Boolean|Object
* `callback` Function
Construct a new server object.
......@@ -53,6 +54,18 @@ If `verifyClient` is not set then the handshake is automatically accepted.
If `handleProtocols` is not set then the handshake is accepted regardless the value of Sec-WebSocket-Protocol header. If it is set but the user does not invoke the `cb` callback then the handshake is rejected with error HTTP 501.
### options.perMessageDeflate
`perMessageDeflate` can be used to control the behavior of [permessage-deflate extension](https://tools.ietf.org/html/draft-ietf-hybi-permessage-compression-19). The extension is disabled when `false`. Defaults to `true`. If an object is provided then that is extension parameters:
* `serverNoContextTakeover` Boolean: Whether to use context take over or not.
* `clientNoContextTakeover` Boolean: The value to be requested to clients whether to use context take over or not.
* `serverMaxWindowBits` Number: The value of windowBits.
* `clientMaxWindowBits` Number: The value of max windowBits to be requested to clients.
* `memLevel` Number: The value of memLevel.
If a property is empty then either an offered configuration or a default value is used.
### server.close()
Close the server and terminate all clients
......@@ -86,9 +99,10 @@ When a new WebSocket connection is established. `socket` is an object of type `w
This class represents a WebSocket connection. It is an `EventEmitter`.
### new ws.WebSocket(address, [options])
### new ws.WebSocket(address, [protocols], [options])
* `address` String|Array
* `address` String
* `protocols` String|Array
* `options` Object
* `protocol` String
* `agent` Agent
......@@ -104,9 +118,14 @@ This class represents a WebSocket connection. It is an `EventEmitter`.
* `ca` Array
* `ciphers` String
* `rejectUnauthorized` Boolean
* `perMessageDeflate` Boolean|Object
Instantiating with an `address` creates a new WebSocket client object. If `address` is an Array (request, socket, rest), it is instantiated as a Server client (e.g. called from the `ws.Server`).
### options.perMessageDeflate
Parameters of permessage-deflate extension which have the same form with the one for `ws.Server` except the direction of requests. (e.g. `serverNoContextTakeover` is the value to be requested to the server)
### websocket.bytesReceived
Received bytes count.
......
......@@ -578,7 +578,7 @@ function initAsClient(address, protocols, options) {
var agent = options.value.agent;
var headerHost = serverUrl.hostname;
// Append port number to Host and Origin header, only if specified in the url
// Append port number to Host header, only if specified in the url
// and non-default
if (serverUrl.port) {
if ((isSecure && (port !== 443)) || (!isSecure && (port !== 80))){
......@@ -593,7 +593,6 @@ function initAsClient(address, protocols, options) {
'Connection': 'Upgrade',
'Upgrade': 'websocket',
'Host': headerHost,
'Origin': headerHost,
'Sec-WebSocket-Version': options.value.protocolVersion,
'Sec-WebSocket-Key': key
}
......@@ -665,7 +664,7 @@ function initAsClient(address, protocols, options) {
req.on('error', function onerror(error) {
self.emit('error', error);
cleanupWebsocketResources.call(this, error);
cleanupWebsocketResources.call(self, error);
});
req.once('response', function response(res) {
......@@ -677,7 +676,7 @@ function initAsClient(address, protocols, options) {
self.emit('error', error);
}
cleanupWebsocketResources.call(this, error);
cleanupWebsocketResources.call(self, error);
});
req.once('upgrade', function upgrade(res, socket, upgradeHead) {
......
'use strict';
var has = Object.prototype.hasOwnProperty;
/**
* An auto incrementing id which we can use to create "unique" Ultron instances
* so we can track the event emitters that are added through the Ultron
......@@ -77,9 +79,7 @@ Ultron.prototype.remove = function remove() {
args = [];
for (event in this.ee._events) {
if (this.ee._events.hasOwnProperty(event)) {
args.push(event);
}
if (has.call(this.ee._events, event)) args.push(event);
}
}
......@@ -89,6 +89,10 @@ Ultron.prototype.remove = function remove() {
for (var j = 0; j < listeners.length; j++) {
event = listeners[j];
//
// Once listeners have a `listener` property that stores the real listener
// in the EventEmitter that ships with Node.js.
//
if (event.listener) {
if (event.listener.__ultron !== this.id) continue;
delete event.listener.__ultron;
......
......@@ -2,7 +2,7 @@
"author": "Einar Otto Stangvik <einaros@gmail.com> (http://2x.io)",
"name": "ws",
"description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455",
"version": "0.7.1",
"version": "0.7.2",
"license": "MIT",
"keywords": [
"Hixie",
......@@ -25,14 +25,14 @@
"ultron": "1.0.x"
},
"optionalDependencies": {
"bufferutil": "1.0.x",
"utf-8-validate": "1.0.x"
"bufferutil": "1.1.x",
"utf-8-validate": "1.1.x"
},
"devDependencies": {
"ansi": "0.3.x",
"benchmark": "0.3.x",
"expect.js": "0.3.x",
"mocha": "2.0.x",
"mocha": "2.2.x",
"should": "4.3.x",
"tinycolor": "0.0.x"
},
......
......@@ -342,6 +342,25 @@ describe('WebSocket', function() {
});
});
it('can handle error before request is upgraded', function(done) {
// Here, we don't create a server, to guarantee that the connection will
// fail before the request is upgraded
++port;
var ws = new WebSocket('ws://localhost:' + port);
ws.on('open', function() {
assert.fail('connect shouldnt be raised here');
});
ws.on('close', function() {
assert.fail('close shouldnt be raised here');
});
ws.on('error', function() {
setTimeout(function() {
assert.equal(ws.readyState, WebSocket.CLOSED);
done();
}, 50)
});
});
it('invalid server key is denied', function(done) {
server.createServer(++port, server.handlers.invalidKey, function(srv) {
var ws = new WebSocket('ws://localhost:' + port);
......@@ -1779,17 +1798,30 @@ describe('WebSocket', function() {
});
});
it('includes the origin header with port number', function(done) {
it('lacks default origin header', function(done) {
var srv = http.createServer();
srv.listen(++port, function() {
srv.on('upgrade', function(req, socket, upgradeHeade) {
assert.equal('localhost:' + port, req.headers['origin']);
req.headers.should.not.have.property('origin');
srv.close();
done();
});
var ws = new WebSocket('ws://localhost:' + port);
});
});
it('honors origin set in options', function(done) {
var srv = http.createServer();
srv.listen(++port, function() {
var options = {origin: 'https://example.com:8000'}
srv.on('upgrade', function(req, socket, upgradeHeade) {
assert.equal(options.origin, req.headers['origin']);
srv.close();
done();
});
var ws = new WebSocket('ws://localhost:' + port, options);
});
});
});
describe('permessage-deflate', function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment