Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a2d1fa84e4 | |||
| 4f31ad9851 | |||
| e27ce57c48 | |||
| eb6fac855c | |||
| 4009b68a43 | |||
| 063a1362df | |||
| b4dc4e1411 | |||
| ccaa8ea76e | |||
| 17fae3cc5c | |||
| 8e9f7923ad | |||
| acc3ea9795 | |||
| 01cdfb18db | |||
| 2634e930f9 | |||
| 5f3e939518 | |||
| b85f22e43b | |||
| 1f439f6e9c | |||
| 4b667a1ba5 | |||
| 49eab191cc | |||
| f3749cd347 | |||
| d97556a1dc | |||
| ba4da1077a | |||
| 560a78b18f | |||
| d690bada0b | |||
| 2aef23a530 | |||
| 3148348a3a | |||
| 641212d2b1 | |||
| c00bee21d3 | |||
| 02612c01cd | |||
| dc392490a8 | |||
| 0feee7974c | |||
| 91d8e1ad41 | |||
| c27fee0680 | |||
| 061494bc2c | |||
| 958d3a458f | |||
| 2d945cff5d | |||
| d3340cdd63 | |||
| 0d15d7a3ec | |||
| cdc7f0891b | |||
| f8c5b86e10 | |||
| 53db3d6c25 | |||
| dcb3375dda | |||
| 854c0a9658 | |||
| d753d09372 | |||
| febde17f0e | |||
| c52271c308 | |||
| 8460dd9f03 | |||
| 66fc108591 | |||
| 58491dea2b | |||
| cd220deb74 | |||
| 6c1689a73d | |||
| 29b94290e9 | |||
| 63e16f6341 | |||
| 39eeb1b884 | |||
| e0b2af3936 | |||
| b192dcb47b | |||
| e9daa1d55e | |||
| 6416235e4a | |||
| f52d11b17b | |||
| cd8f337278 | |||
| 76ffac630c | |||
| d2abdb1870 | |||
| f14a49b6eb | |||
| 73284c858c | |||
| ec5838e27e | |||
| 2627293613 |
@@ -1 +1,2 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
||||
+14
-1
@@ -1,6 +1,19 @@
|
||||
sudo: false
|
||||
language: node_js
|
||||
|
||||
node_js:
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
- "0.11"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "5"
|
||||
- "6"
|
||||
- "7"
|
||||
- "8"
|
||||
- "9"
|
||||
- "10"
|
||||
- "11"
|
||||
- "12"
|
||||
|
||||
before_install:
|
||||
- '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@~1.4.0'
|
||||
|
||||
+72
-53
@@ -1,115 +1,134 @@
|
||||
### 0.11.3 / 2019-06-10
|
||||
|
||||
- Fix a race condition that caused a timeout not to be cancelled immediately
|
||||
when the WebSocket is closed
|
||||
|
||||
### 0.11.2 / 2019-06-10
|
||||
|
||||
(This version was pulled due to an error when publishing)
|
||||
|
||||
### 0.11.1 / 2017-01-22
|
||||
|
||||
- Forcibly close the I/O stream after a timeout if the peer does not respond
|
||||
after calling `close()`
|
||||
|
||||
### 0.11.0 / 2016-02-24
|
||||
|
||||
- Introduce a `net` option to the `Client` class for setting things like, say,
|
||||
`servername`
|
||||
|
||||
### 0.10.0 / 2015-07-08
|
||||
|
||||
- Add the standard `code` and `reason` parameters to the `close` method
|
||||
|
||||
### 0.9.4 / 2015-03-08
|
||||
|
||||
- Don't send input to the driver before `start()` is called
|
||||
|
||||
### 0.9.3 / 2015-02-19
|
||||
|
||||
- Make sure the TCP socket is not left open when closing the connection
|
||||
|
||||
### 0.9.2 / 2014-12-21
|
||||
|
||||
- Only emit `error` once, and don't emit it after `close`
|
||||
|
||||
### 0.9.1 / 2014-12-18
|
||||
|
||||
- Check that all options to the WebSocket constructor are recognized
|
||||
|
||||
### 0.9.0 / 2014-12-13
|
||||
|
||||
* Allow protocol extensions to be passed into websocket-extensions
|
||||
|
||||
- Allow protocol extensions to be passed into websocket-extensions
|
||||
|
||||
### 0.8.1 / 2014-11-12
|
||||
|
||||
* Send the correct hostname when upgrading a connection to TLS
|
||||
|
||||
- Send the correct hostname when upgrading a connection to TLS
|
||||
|
||||
### 0.8.0 / 2014-11-08
|
||||
|
||||
* Support connections via HTTP proxies
|
||||
* Close the connection cleanly if we're still waiting for a handshake response
|
||||
|
||||
- Support connections via HTTP proxies
|
||||
- Close the connection cleanly if we're still waiting for a handshake response
|
||||
|
||||
### 0.7.3 / 2014-10-04
|
||||
|
||||
* Allow sockets to be closed when they are in any state other than `CLOSED`
|
||||
|
||||
- Allow sockets to be closed when they are in any state other than `CLOSED`
|
||||
|
||||
### 0.7.2 / 2013-12-29
|
||||
|
||||
* Make sure the `close` event is emitted by clients on Node v0.10
|
||||
|
||||
- Make sure the `close` event is emitted by clients on Node v0.10
|
||||
|
||||
### 0.7.1 / 2013-12-03
|
||||
|
||||
* Support the `maxLength` websocket-driver option
|
||||
* Make the client emit `error` events on network errors
|
||||
|
||||
- Support the `maxLength` websocket-driver option
|
||||
- Make the client emit `error` events on network errors
|
||||
|
||||
### 0.7.0 / 2013-09-09
|
||||
|
||||
* Allow the server to send custom headers with EventSource responses
|
||||
|
||||
- Allow the server to send custom headers with EventSource responses
|
||||
|
||||
### 0.6.1 / 2013-07-05
|
||||
|
||||
* Add `ca` option to the client for specifying certificate authorities
|
||||
* Start the server driver asynchronously so that `onopen` handlers can be added
|
||||
|
||||
- Add `ca` option to the client for specifying certificate authorities
|
||||
- Start the server driver asynchronously so that `onopen` handlers can be added
|
||||
|
||||
### 0.6.0 / 2013-05-12
|
||||
|
||||
* Add support for custom headers
|
||||
|
||||
- Add support for custom headers
|
||||
|
||||
### 0.5.0 / 2013-05-05
|
||||
|
||||
* Extract the protocol handlers into the `websocket-driver` library
|
||||
* Support the Node streaming API
|
||||
|
||||
- Extract the protocol handlers into the `websocket-driver` library
|
||||
- Support the Node streaming API
|
||||
|
||||
### 0.4.4 / 2013-02-14
|
||||
|
||||
* Emit the `close` event if TCP is closed before CLOSE frame is acked
|
||||
|
||||
- Emit the `close` event if TCP is closed before CLOSE frame is acked
|
||||
|
||||
### 0.4.3 / 2012-07-09
|
||||
|
||||
* Add `Connection: close` to EventSource response
|
||||
* Handle situations where `request.socket` is undefined
|
||||
|
||||
- Add `Connection: close` to EventSource response
|
||||
- Handle situations where `request.socket` is undefined
|
||||
|
||||
### 0.4.2 / 2012-04-06
|
||||
|
||||
* Add WebSocket error code `1011`.
|
||||
* Handle URLs with no path correctly by sending `GET /`
|
||||
|
||||
- Add WebSocket error code `1011`.
|
||||
- Handle URLs with no path correctly by sending `GET /`
|
||||
|
||||
### 0.4.1 / 2012-02-26
|
||||
|
||||
* Treat anything other than a `Buffer` as a string when calling `send()`
|
||||
|
||||
- Treat anything other than a `Buffer` as a string when calling `send()`
|
||||
|
||||
### 0.4.0 / 2012-02-13
|
||||
|
||||
* Add `ping()` method to server-side `WebSocket` and `EventSource`
|
||||
* Buffer `send()` calls until the draft-76 handshake is complete
|
||||
* Fix HTTPS problems on Node 0.7
|
||||
|
||||
- Add `ping()` method to server-side `WebSocket` and `EventSource`
|
||||
- Buffer `send()` calls until the draft-76 handshake is complete
|
||||
- Fix HTTPS problems on Node 0.7
|
||||
|
||||
### 0.3.1 / 2012-01-16
|
||||
|
||||
* Call `setNoDelay(true)` on `net.Socket` objects to reduce latency
|
||||
|
||||
- Call `setNoDelay(true)` on `net.Socket` objects to reduce latency
|
||||
|
||||
### 0.3.0 / 2012-01-13
|
||||
|
||||
* Add support for `EventSource` connections
|
||||
|
||||
- Add support for `EventSource` connections
|
||||
|
||||
### 0.2.0 / 2011-12-21
|
||||
|
||||
* Add support for `Sec-WebSocket-Protocol` negotiation
|
||||
* Support `hixie-76` close frames and 75/76 ignored segments
|
||||
* Improve performance of HyBi parsing/framing functions
|
||||
* Decouple parsers from TCP and reduce write volume
|
||||
|
||||
- Add support for `Sec-WebSocket-Protocol` negotiation
|
||||
- Support `hixie-76` close frames and 75/76 ignored segments
|
||||
- Improve performance of HyBi parsing/framing functions
|
||||
- Decouple parsers from TCP and reduce write volume
|
||||
|
||||
### 0.1.2 / 2011-12-05
|
||||
|
||||
* Detect closed sockets on the server side when TCP connection breaks
|
||||
* Make `hixie-76` sockets work through HAProxy
|
||||
|
||||
- Detect closed sockets on the server side when TCP connection breaks
|
||||
- Make `hixie-76` sockets work through HAProxy
|
||||
|
||||
### 0.1.1 / 2011-11-30
|
||||
|
||||
* Fix `addEventListener()` interface methods
|
||||
|
||||
- Fix `addEventListener()` interface methods
|
||||
|
||||
### 0.1.0 / 2011-11-27
|
||||
|
||||
* Initial release, based on WebSocket components from Faye
|
||||
- Initial release, based on WebSocket components from Faye
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Code of Conduct
|
||||
|
||||
All projects under the [Faye](https://github.com/faye) umbrella are covered by
|
||||
the [Code of Conduct](https://github.com/faye/code-of-conduct).
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
Copyright 2010-2019 James Coglan
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations under the License.
|
||||
@@ -1,23 +1,18 @@
|
||||
# faye-websocket
|
||||
|
||||
* Travis CI build: [](http://travis-ci.org/faye/faye-websocket-node)
|
||||
* Autobahn tests: [server](http://faye.jcoglan.com/autobahn/servers/),
|
||||
[client](http://faye.jcoglan.com/autobahn/clients/)
|
||||
# faye-websocket [](http://travis-ci.org/faye/faye-websocket-node)
|
||||
|
||||
This is a general-purpose WebSocket implementation extracted from the
|
||||
[Faye](http://faye.jcoglan.com) project. It provides classes for easily
|
||||
building WebSocket servers and clients in Node. It does not provide a server
|
||||
itself, but rather makes it easy to handle WebSocket connections within an
|
||||
existing [Node](http://nodejs.org/) application. It does not provide any
|
||||
abstraction other than the standard [WebSocket
|
||||
API](http://dev.w3.org/html5/websockets/).
|
||||
[Faye](http://faye.jcoglan.com) project. It provides classes for easily building
|
||||
WebSocket servers and clients in Node. It does not provide a server itself, but
|
||||
rather makes it easy to handle WebSocket connections within an existing
|
||||
[Node](https://nodejs.org/) application. It does not provide any abstraction
|
||||
other than the standard [WebSocket
|
||||
API](https://html.spec.whatwg.org/multipage/comms.html#network).
|
||||
|
||||
It also provides an abstraction for handling
|
||||
[EventSource](http://dev.w3.org/html5/eventsource/) connections, which are
|
||||
one-way connections that allow the server to push data to the client. They are
|
||||
based on streaming HTTP responses and can be easier to access via proxies than
|
||||
WebSockets.
|
||||
[EventSource](https://html.spec.whatwg.org/multipage/comms.html#server-sent-events)
|
||||
connections, which are one-way connections that allow the server to push data to
|
||||
the client. They are based on streaming HTTP responses and can be easier to access
|
||||
via proxies than WebSockets.
|
||||
|
||||
|
||||
## Installation
|
||||
@@ -77,8 +72,8 @@ If you need to detect when the WebSocket handshake is complete, you can use the
|
||||
|
||||
If the connection's protocol version supports it, you can call `ws.ping()` to
|
||||
send a ping message and wait for the client's response. This method takes a
|
||||
message string, and an optional callback that fires when a matching pong
|
||||
message is received. It returns `true` iff a ping message was sent. If the
|
||||
message string, and an optional callback that fires when a matching pong message
|
||||
is received. It returns `true` if and only if a ping message was sent. If the
|
||||
client does not support ping/pong, this method sends no data and returns
|
||||
`false`.
|
||||
|
||||
@@ -122,7 +117,7 @@ including any authorization information, custom headers and TLS config you
|
||||
require. Only the `origin` setting is required.
|
||||
|
||||
```js
|
||||
var ws = new WebSocket.Client('ws://www.example.com/', null, {
|
||||
var ws = new WebSocket.Client('ws://www.example.com/', [], {
|
||||
proxy: {
|
||||
origin: 'http://username:password@proxy.example.com',
|
||||
headers: {'User-Agent': 'node'},
|
||||
@@ -131,8 +126,8 @@ var ws = new WebSocket.Client('ws://www.example.com/', null, {
|
||||
});
|
||||
```
|
||||
|
||||
The `tls` value is a Node 'TLS options' object that will be passed to
|
||||
[`tls.connect()`](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
|
||||
The `tls` value is an object that will be passed to
|
||||
[`tls.connect()`](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
|
||||
|
||||
|
||||
## Subprotocol negotiation
|
||||
@@ -169,14 +164,14 @@ array of extensions to the `:extensions` option. For example, to add
|
||||
```js
|
||||
var deflate = require('permessage-deflate');
|
||||
|
||||
var ws = new WebSocket(request, null, {extensions: [deflate]});
|
||||
var ws = new WebSocket(request, socket, body, [], {extensions: [deflate]});
|
||||
```
|
||||
|
||||
|
||||
## Initialization options
|
||||
|
||||
Both the server- and client-side classes allow an options object to be passed
|
||||
in at initialization time, for example:
|
||||
Both the server- and client-side classes allow an options object to be passed in
|
||||
at initialization time, for example:
|
||||
|
||||
```js
|
||||
var ws = new WebSocket(request, socket, body, protocols, options);
|
||||
@@ -186,51 +181,54 @@ var ws = new WebSocket.Client(url, protocols, options);
|
||||
`protocols` is an array of subprotocols as described above, or `null`.
|
||||
`options` is an optional object containing any of these fields:
|
||||
|
||||
* `extensions` - an array of
|
||||
- `extensions` - an array of
|
||||
[websocket-extensions](https://github.com/faye/websocket-extensions-node)
|
||||
compatible extensions, as described above
|
||||
* `headers` - an object containing key-value pairs representing HTTP headers to
|
||||
- `headers` - an object containing key-value pairs representing HTTP headers to
|
||||
be sent during the handshake process
|
||||
* `maxLength` - the maximum allowed size of incoming message frames, in bytes.
|
||||
- `maxLength` - the maximum allowed size of incoming message frames, in bytes.
|
||||
The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
|
||||
* `ping` - an integer that sets how often the WebSocket should send ping
|
||||
frames, measured in seconds
|
||||
- `ping` - an integer that sets how often the WebSocket should send ping frames,
|
||||
measured in seconds
|
||||
|
||||
The client accepts some additional options:
|
||||
|
||||
* `proxy` - settings for a proxy as described above
|
||||
* `tls` - a Node 'TLS options' object containing TLS settings for the origin
|
||||
server, this will be passed to
|
||||
[`tls.connect()`](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
|
||||
* `ca` - (legacy) a shorthand for passing `{tls: {ca: value}}`
|
||||
- `proxy` - settings for a proxy as described above
|
||||
- `net` - an object containing settings for the origin server that will be
|
||||
passed to
|
||||
[`net.connect()`](https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener)
|
||||
- `tls` - an object containing TLS settings for the origin server, this will be
|
||||
passed to
|
||||
[`tls.connect()`](https://nodejs.org/api/tls.html#tls_tls_connect_options_callback)
|
||||
- `ca` - (legacy) a shorthand for passing `{tls: {ca: value}}`
|
||||
|
||||
|
||||
## WebSocket API
|
||||
|
||||
Both server- and client-side `WebSocket` objects support the following API.
|
||||
|
||||
* <b>`on('open', function(event) {})`</b> fires when the socket connection is
|
||||
- **`on('open', function(event) {})`** fires when the socket connection is
|
||||
established. Event has no attributes.
|
||||
* <b>`on('message', function(event) {})`</b> fires when the socket receives a
|
||||
message. Event has one attribute, <b>`data`</b>, which is either a `String`
|
||||
(for text frames) or a `Buffer` (for binary frames).
|
||||
* <b>`on('error', function(event) {})`</b> fires when there is a protocol error
|
||||
due to bad data sent by the other peer. This event is purely informational,
|
||||
you do not need to implement error recover.
|
||||
* <b>`on('close', function(event) {})`</b> fires when either the client or the
|
||||
server closes the connection. Event has two optional attributes,
|
||||
<b>`code`</b> and <b>`reason`</b>, that expose the status code and message
|
||||
sent by the peer that closed the connection.
|
||||
* <b>`send(message)`</b> accepts either a `String` or a `Buffer` and sends a
|
||||
text or binary message over the connection to the other peer.
|
||||
* <b>`ping(message = '', function() {})`</b> sends a ping frame with an
|
||||
optional message and fires the callback when a matching pong is received.
|
||||
* <b>`close(code, reason)`</b> closes the connection, sending the given status
|
||||
code and reason text, both of which are optional.
|
||||
* <b>`version`</b> is a string containing the version of the `WebSocket`
|
||||
protocol the connection is using.
|
||||
* <b>`protocol`</b> is a string (which may be empty) identifying the
|
||||
subprotocol the socket is using.
|
||||
- **`on('message', function(event) {})`** fires when the socket receives a
|
||||
message. Event has one attribute, **`data`**, which is either a `String` (for
|
||||
text frames) or a `Buffer` (for binary frames).
|
||||
- **`on('error', function(event) {})`** fires when there is a protocol error due
|
||||
to bad data sent by the other peer. This event is purely informational, you do
|
||||
not need to implement error recover.
|
||||
- **`on('close', function(event) {})`** fires when either the client or the
|
||||
server closes the connection. Event has two optional attributes, **`code`**
|
||||
and **`reason`**, that expose the status code and message sent by the peer
|
||||
that closed the connection.
|
||||
- **`send(message)`** accepts either a `String` or a `Buffer` and sends a text
|
||||
or binary message over the connection to the other peer.
|
||||
- **`ping(message, function() {})`** sends a ping frame with an optional message
|
||||
and fires the callback when a matching pong is received.
|
||||
- **`close(code, reason)`** closes the connection, sending the given status code
|
||||
and reason text, both of which are optional.
|
||||
- **`version`** is a string containing the version of the `WebSocket` protocol
|
||||
the connection is using.
|
||||
- **`protocol`** is a string (which may be empty) identifying the subprotocol
|
||||
the socket is using.
|
||||
|
||||
|
||||
## Handling EventSource connections in Node
|
||||
@@ -280,22 +278,22 @@ es.send('Breaking News!', {event: 'notification', id: '99'});
|
||||
|
||||
The `EventSource` object exposes the following properties:
|
||||
|
||||
* <b>`url`</b> is a string containing the URL the client used to create the
|
||||
- **`url`** is a string containing the URL the client used to create the
|
||||
EventSource.
|
||||
* <b>`lastEventId`</b> is a string containing the last event ID received by the
|
||||
client. You can use this when the client reconnects after a dropped
|
||||
connection to determine which messages need resending.
|
||||
- **`lastEventId`** is a string containing the last event ID received by the
|
||||
client. You can use this when the client reconnects after a dropped connection
|
||||
to determine which messages need resending.
|
||||
|
||||
When you initialize an EventSource with ` new EventSource()`, you can pass
|
||||
configuration options after the `response` parameter. Available options are:
|
||||
|
||||
* <b>`headers`</b> is an object containing custom headers to be set on the
|
||||
- **`headers`** is an object containing custom headers to be set on the
|
||||
EventSource response.
|
||||
* <b>`retry`</b> is a number that tells the client how long (in seconds) it
|
||||
should wait after a dropped connection before attempting to reconnect.
|
||||
* <b>`ping`</b> is a number that tells the server how often (in seconds) to
|
||||
send 'ping' packets to the client to keep the connection open, to defeat
|
||||
timeouts set by proxies. The client will ignore these messages.
|
||||
- **`retry`** is a number that tells the client how long (in seconds) it should
|
||||
wait after a dropped connection before attempting to reconnect.
|
||||
- **`ping`** is a number that tells the server how often (in seconds) to send
|
||||
'ping' packets to the client to keep the connection open, to defeat timeouts
|
||||
set by proxies. The client will ignore these messages.
|
||||
|
||||
For example, this creates a connection that allows access from any origin, pings
|
||||
every 15 seconds and is retryable every 10 seconds if the connection is broken:
|
||||
@@ -311,28 +309,3 @@ var es = new EventSource(request, response, {
|
||||
You can send a ping message at any time by calling `es.ping()`. Unlike
|
||||
WebSocket, the client does not send a response to this; it is merely to send
|
||||
some data over the wire to keep the connection alive.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2010-2014 James Coglan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the 'Software'), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
var WebSocket = require('../lib/faye/websocket'),
|
||||
var WebSocket = require('..').Client,
|
||||
deflate = require('permessage-deflate'),
|
||||
pace = require('pace');
|
||||
|
||||
@@ -7,7 +7,7 @@ var host = 'ws://localhost:9001',
|
||||
cases = 0,
|
||||
options = {extensions: [deflate]};
|
||||
|
||||
var socket = new WebSocket.Client(host + '/getCaseCount'),
|
||||
var socket = new WebSocket(host + '/getCaseCount'),
|
||||
url, progress;
|
||||
|
||||
socket.onmessage = function(event) {
|
||||
@@ -19,13 +19,13 @@ socket.onmessage = function(event) {
|
||||
var runCase = function(n) {
|
||||
if (n > cases) {
|
||||
url = host + '/updateReports?agent=' + agent;
|
||||
socket = new WebSocket.Client(url);
|
||||
socket = new WebSocket(url);
|
||||
socket.onclose = process.exit;
|
||||
return;
|
||||
}
|
||||
|
||||
url = host + '/runCase?case=' + n + '&agent=' + agent;
|
||||
socket = new WebSocket.Client(url, null, options);
|
||||
socket = new WebSocket(url, [], options);
|
||||
socket.pipe(socket);
|
||||
|
||||
socket.on('close', function() {
|
||||
|
||||
+14
-7
@@ -1,11 +1,18 @@
|
||||
var WebSocket = require('../lib/faye/websocket'),
|
||||
fs = require('fs');
|
||||
var WebSocket = require('..').Client,
|
||||
deflate = require('permessage-deflate'),
|
||||
fs = require('fs');
|
||||
|
||||
var url = process.argv[2],
|
||||
headers = {Origin: 'http://faye.jcoglan.com'},
|
||||
ca = fs.readFileSync(__dirname + '/../spec/server.crt'),
|
||||
proxy = {origin: process.argv[3], headers: {'User-Agent': 'Echo'}, tls: {ca: ca}},
|
||||
ws = new WebSocket.Client(url, null, {headers: headers, proxy: proxy, tls: {ca: ca}});
|
||||
var url = process.argv[2],
|
||||
proxy = process.argv[3],
|
||||
ca = fs.readFileSync(__dirname + '/../spec/server.crt'),
|
||||
tls = {ca: ca};
|
||||
|
||||
var ws = new WebSocket(url, [], {
|
||||
proxy: {origin: proxy, headers: {'User-Agent': 'Echo'}, tls: tls},
|
||||
tls: tls,
|
||||
headers: {Origin: 'http://faye.jcoglan.com'},
|
||||
extensions: [deflate]
|
||||
});
|
||||
|
||||
ws.onopen = function() {
|
||||
console.log('[open]', ws.headers);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
var WebSocket = require('../lib/faye/websocket'),
|
||||
var WebSocket = require('..'),
|
||||
deflate = require('permessage-deflate'),
|
||||
fs = require('fs'),
|
||||
http = require('http'),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var Stream = require('stream').Stream,
|
||||
util = require('util'),
|
||||
driver = require('websocket-driver'),
|
||||
|
||||
+10
-4
@@ -1,8 +1,10 @@
|
||||
// API references:
|
||||
//
|
||||
// * http://dev.w3.org/html5/websockets/
|
||||
// * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-eventtarget
|
||||
// * http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-event
|
||||
// * https://html.spec.whatwg.org/multipage/comms.html#network
|
||||
// * https://dom.spec.whatwg.org/#interface-eventtarget
|
||||
// * https://dom.spec.whatwg.org/#interface-event
|
||||
|
||||
'use strict';
|
||||
|
||||
var util = require('util'),
|
||||
driver = require('websocket-driver'),
|
||||
@@ -21,11 +23,11 @@ var WebSocket = function(request, socket, body, protocols, options) {
|
||||
var catchup = function() { self._stream.removeListener('data', catchup) };
|
||||
this._stream.on('data', catchup);
|
||||
|
||||
this._driver.io.write(body);
|
||||
API.call(this, options);
|
||||
|
||||
process.nextTick(function() {
|
||||
self._driver.start();
|
||||
self._driver.io.write(body);
|
||||
});
|
||||
};
|
||||
util.inherits(WebSocket, API);
|
||||
@@ -34,6 +36,10 @@ WebSocket.isWebSocket = function(request) {
|
||||
return driver.isWebSocket(request);
|
||||
};
|
||||
|
||||
WebSocket.validateOptions = function(options, validKeys) {
|
||||
driver.validateOptions(options, validKeys);
|
||||
};
|
||||
|
||||
WebSocket.WebSocket = WebSocket;
|
||||
WebSocket.Client = require('./websocket/client');
|
||||
WebSocket.EventSource = require('./eventsource');
|
||||
|
||||
+53
-12
@@ -1,10 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
var Stream = require('stream').Stream,
|
||||
util = require('util'),
|
||||
driver = require('websocket-driver'),
|
||||
EventTarget = require('./api/event_target'),
|
||||
Event = require('./api/event');
|
||||
|
||||
var API = function(options) {
|
||||
options = options || {};
|
||||
driver.validateOptions(options, ['headers', 'extensions', 'maxLength', 'ping', 'proxy', 'tls', 'ca']);
|
||||
|
||||
this.readable = this.writable = true;
|
||||
|
||||
@@ -30,13 +34,10 @@ var API = function(options) {
|
||||
|
||||
this._driver.on('open', function(e) { self._open() });
|
||||
this._driver.on('message', function(e) { self._receiveMessage(e.data) });
|
||||
this._driver.on('close', function(e) { self._finalize(e.reason, e.code) });
|
||||
this._driver.on('close', function(e) { self._beginClose(e.reason, e.code) });
|
||||
|
||||
this._driver.on('error', function(error) {
|
||||
var event = new Event('error', {message: error.message});
|
||||
event.initEvent('error', false, false);
|
||||
self.dispatchEvent(event);
|
||||
self._finalize('', 1006);
|
||||
self._emitError(error.message);
|
||||
});
|
||||
this.on('error', function() {});
|
||||
|
||||
@@ -64,6 +65,8 @@ API.OPEN = 1;
|
||||
API.CLOSING = 2;
|
||||
API.CLOSED = 3;
|
||||
|
||||
API.CLOSE_TIMEOUT = 30000;
|
||||
|
||||
var instance = {
|
||||
write: function(data) {
|
||||
return this.send(data);
|
||||
@@ -93,9 +96,23 @@ var instance = {
|
||||
return this._driver.ping(message, callback);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
close: function(code, reason) {
|
||||
if (code === undefined) code = 1000;
|
||||
if (reason === undefined) reason = '';
|
||||
|
||||
if (code !== 1000 && (code < 3000 || code > 4999))
|
||||
throw new Error("Failed to execute 'close' on WebSocket: " +
|
||||
"The code must be either 1000, or between 3000 and 4999. " +
|
||||
code + " is neither.");
|
||||
|
||||
if (this.readyState !== API.CLOSED) this.readyState = API.CLOSING;
|
||||
this._driver.close();
|
||||
var self = this;
|
||||
|
||||
this._closeTimer = setTimeout(function() {
|
||||
self._beginClose('', 1006);
|
||||
}, API.CLOSE_TIMEOUT);
|
||||
|
||||
this._driver.close(reason, code);
|
||||
},
|
||||
|
||||
_configureStream: function() {
|
||||
@@ -105,15 +122,16 @@ var instance = {
|
||||
this._stream.setNoDelay(true);
|
||||
|
||||
['close', 'end'].forEach(function(event) {
|
||||
this._stream.on(event, function() { self._finalize('', 1006) });
|
||||
this._stream.on(event, function() { self._finalizeClose() });
|
||||
}, this);
|
||||
|
||||
this._stream.on('error', function(error) {
|
||||
self._driver.emit('error', new Error('Network error: ' + self.url + ': ' + error.message));
|
||||
self._emitError('Network error: ' + self.url + ': ' + error.message);
|
||||
self._finalizeClose();
|
||||
});
|
||||
},
|
||||
|
||||
_open: function() {
|
||||
_open: function() {
|
||||
if (this.readyState !== API.CONNECTING) return;
|
||||
|
||||
this.readyState = API.OPEN;
|
||||
@@ -134,17 +152,40 @@ var instance = {
|
||||
this.dispatchEvent(event);
|
||||
},
|
||||
|
||||
_finalize: function(reason, code) {
|
||||
_emitError: function(message) {
|
||||
if (this.readyState >= API.CLOSING) return;
|
||||
|
||||
var event = new Event('error', {message: message});
|
||||
event.initEvent('error', false, false);
|
||||
this.dispatchEvent(event);
|
||||
},
|
||||
|
||||
_beginClose: function(reason, code) {
|
||||
if (this.readyState === API.CLOSED) return;
|
||||
this.readyState = API.CLOSING;
|
||||
this._closeParams = [reason, code];
|
||||
|
||||
if (this._stream) {
|
||||
this._stream.destroy();
|
||||
if (!this._stream.readable) this._finalizeClose();
|
||||
}
|
||||
},
|
||||
|
||||
_finalizeClose: function() {
|
||||
if (this.readyState === API.CLOSED) return;
|
||||
this.readyState = API.CLOSED;
|
||||
|
||||
if (this._closeTimer) clearTimeout(this._closeTimer);
|
||||
if (this._pingTimer) clearInterval(this._pingTimer);
|
||||
if (this._stream) this._stream.end();
|
||||
|
||||
if (this.readable) this.emit('end');
|
||||
this.readable = this.writable = false;
|
||||
|
||||
var event = new Event('close', {code: code || 1000, reason: reason || ''});
|
||||
var reason = this._closeParams ? this._closeParams[0] : '',
|
||||
code = this._closeParams ? this._closeParams[1] : 1006;
|
||||
|
||||
var event = new Event('close', {code: code, reason: reason});
|
||||
event.initEvent('close', false, false);
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var Event = function(eventType, options) {
|
||||
this.type = eventType;
|
||||
for (var key in options)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var Event = require('./event');
|
||||
|
||||
var EventTarget = {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('util'),
|
||||
net = require('net'),
|
||||
tls = require('tls'),
|
||||
crypto = require('crypto'),
|
||||
url = require('url'),
|
||||
driver = require('websocket-driver'),
|
||||
API = require('./api'),
|
||||
@@ -23,20 +24,25 @@ var Client = function(_url, protocols, options) {
|
||||
});
|
||||
}, this);
|
||||
|
||||
var proxy = options.proxy || {},
|
||||
endpoint = url.parse(proxy.origin || this.url),
|
||||
port = endpoint.port || DEFAULT_PORTS[endpoint.protocol],
|
||||
secure = SECURE_PROTOCOLS.indexOf(endpoint.protocol) >= 0,
|
||||
onConnect = function() { self._onConnect() },
|
||||
originTLS = options.tls || {},
|
||||
socketTLS = proxy.origin ? (proxy.tls || {}) : originTLS,
|
||||
self = this;
|
||||
var proxy = options.proxy || {},
|
||||
endpoint = url.parse(proxy.origin || this.url),
|
||||
port = endpoint.port || DEFAULT_PORTS[endpoint.protocol],
|
||||
secure = SECURE_PROTOCOLS.indexOf(endpoint.protocol) >= 0,
|
||||
onConnect = function() { self._onConnect() },
|
||||
netOptions = options.net || {},
|
||||
originTLS = options.tls || {},
|
||||
socketTLS = proxy.origin ? (proxy.tls || {}) : originTLS,
|
||||
self = this;
|
||||
|
||||
netOptions.host = socketTLS.host = endpoint.hostname;
|
||||
netOptions.port = socketTLS.port = port;
|
||||
|
||||
originTLS.ca = originTLS.ca || options.ca;
|
||||
socketTLS.servername = socketTLS.servername || endpoint.hostname;
|
||||
|
||||
this._stream = secure
|
||||
? tls.connect(port, endpoint.hostname, socketTLS, onConnect)
|
||||
: net.connect(port, endpoint.hostname, onConnect);
|
||||
? tls.connect(socketTLS, onConnect)
|
||||
: net.connect(netOptions, onConnect);
|
||||
|
||||
if (proxy.origin) this._configureProxy(proxy, originTLS);
|
||||
|
||||
|
||||
+34
-20
@@ -1,21 +1,35 @@
|
||||
{ "name" : "faye-websocket"
|
||||
, "description" : "Standards-compliant WebSocket server and client"
|
||||
, "homepage" : "http://github.com/faye/faye-websocket-node"
|
||||
, "author" : "James Coglan <jcoglan@gmail.com> (http://jcoglan.com/)"
|
||||
, "keywords" : ["websocket", "eventsource"]
|
||||
, "license" : "MIT"
|
||||
|
||||
, "version" : "0.9.0"
|
||||
, "engines" : {"node": ">=0.4.0"}
|
||||
, "main" : "./lib/faye/websocket"
|
||||
, "dependencies" : {"websocket-driver": ">=0.5.0"}
|
||||
, "devDependencies" : {"jstest": "", "pace": "", "permessage-deflate": ""}
|
||||
|
||||
, "scripts" : {"test": "jstest spec/runner.js"}
|
||||
|
||||
, "repository" : { "type" : "git"
|
||||
, "url" : "git://github.com/faye/faye-websocket-node.git"
|
||||
}
|
||||
|
||||
, "bugs" : "http://github.com/faye/faye-websocket-node/issues"
|
||||
{
|
||||
"name": "faye-websocket",
|
||||
"description": "Standards-compliant WebSocket server and client",
|
||||
"homepage": "https://github.com/faye/faye-websocket-node",
|
||||
"author": "James Coglan <jcoglan@gmail.com> (http://jcoglan.com/)",
|
||||
"keywords": [
|
||||
"websocket",
|
||||
"eventsource"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"version": "0.11.3",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"main": "./lib/faye/websocket",
|
||||
"dependencies": {
|
||||
"websocket-driver": ">=0.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jstest": "*",
|
||||
"pace": "*",
|
||||
"permessage-deflate": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jstest spec/runner.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/faye/faye-websocket-node.git"
|
||||
},
|
||||
"bugs": "https://github.com/faye/faye-websocket-node/issues"
|
||||
}
|
||||
|
||||
@@ -73,8 +73,11 @@ var WebSocketSteps = test.asyncSteps({
|
||||
this._ws.close()
|
||||
},
|
||||
|
||||
check_open: function(callback) {
|
||||
check_open: function(status, headers, callback) {
|
||||
this.assert( this._open )
|
||||
this.assertEqual( status, this._ws.statusCode )
|
||||
for (var name in headers)
|
||||
this.assertEqual( headers[name], this._ws.headers[name.toLowerCase()] )
|
||||
callback()
|
||||
},
|
||||
|
||||
@@ -154,7 +157,7 @@ test.describe("Client", function() { with(this) {
|
||||
sharedBehavior("socket client", function() { with(this) {
|
||||
it("can open a connection", function() { with(this) {
|
||||
open_socket(socket_url, protocols)
|
||||
check_open()
|
||||
check_open(101, {"Upgrade": "websocket"})
|
||||
check_protocol("echo")
|
||||
}})
|
||||
|
||||
@@ -211,7 +214,7 @@ test.describe("Client", function() { with(this) {
|
||||
|
||||
it("can be closed before connecting", function() { with(this) {
|
||||
open_socket_and_close_it_fast(socket_url, protocols)
|
||||
wait(10)
|
||||
wait(100)
|
||||
check_closed()
|
||||
check_never_opened()
|
||||
check_not_readable()
|
||||
|
||||
+10
-12
@@ -1,14 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICIzCCAYwCCQDZaunNGmqaHjANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJH
|
||||
QjETMBEGA1UECBMKU29tZS1TdGF0ZTEPMA0GA1UEBxMGTG9uZG9uMQ0wCwYDVQQK
|
||||
EwRGYXllMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTQwNjIxMDkzNjAyWhcNMTUw
|
||||
NjIxMDkzNjAyWjBWMQswCQYDVQQGEwJHQjETMBEGA1UECBMKU29tZS1TdGF0ZTEP
|
||||
MA0GA1UEBxMGTG9uZG9uMQ0wCwYDVQQKEwRGYXllMRIwEAYDVQQDEwlsb2NhbGhv
|
||||
c3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANc64/S51F2OVw1IGZql483S
|
||||
sUf7QiuHyHCYxeHB8CeTKXyaH5h3ITmmqjzT5MWgTYuXf39XRf2VqicLWqs0xIAc
|
||||
RKBE1VouLM0sbNzMv1yNG7im0bMywXNlOlOmUhtjYZvEx5I10UiJrVxIpEnNiCuZ
|
||||
dgCuB944l/lQrndkaqWtAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA1UmNwUA7KVaU
|
||||
jg3iofsr0UgFCNO9sZ6PeEoh6NETrckhYd1TB3S7QAgHMiu4e8cEVnlYyIm6oJnp
|
||||
l5edfaUHh3PGwt5jLzpg/l+OVT5qkixRJdazx+pd/CFYIgot2+7hEao9NC4GV1Tl
|
||||
yR0IxlKRsQO3iZlpe7/Klqjaq/r9tQM=
|
||||
MIIBuTCCASICCQDYxKMSaqIBUjANBgkqhkiG9w0BAQUFADAhMQswCQYDVQQGEwJV
|
||||
SzESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTE4MDcyNjEwMDc1MVoXDTE5MDcyNjEw
|
||||
MDc1MVowITELMAkGA1UEBhMCVUsxEjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkq
|
||||
hkiG9w0BAQEFAAOBjQAwgYkCgYEA0yhJUiPwtCyZz6B8F+7nczFx5dGN2FqHt3Vr
|
||||
X4Kw1bZYAibi2A1mLTUzq2XL1MkMZEKmU7Ed5W2XLE6pDBx+uwx2Ip+Ma04iPSIZ
|
||||
tpvYsDueWVWEsQ+ErT03l6b+tEDRBi5Phg6BkOyB8Wrt7hAeGCDZCpQCYtAJ/S51
|
||||
2BZTY2sCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCm3xXFjYREjaj7SzBKq8R0YN57
|
||||
v1a+6IG9Lc4LHKxg9BMK/duj3pBina0pK97acJVUUMljh6q1jcfU2nvp2JPky+DL
|
||||
A7Ct59/Q4KB2Hlo3uCKEQvgpXkuRUbtgtLDSnr6IOQpfOJV3wbZC9hhSAG9vxDwz
|
||||
Ntk1nrqynosPPRFkjQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
+13
-13
@@ -1,15 +1,15 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXQIBAAKBgQDXOuP0udRdjlcNSBmapePN0rFH+0Irh8hwmMXhwfAnkyl8mh+Y
|
||||
dyE5pqo80+TFoE2Ll39/V0X9laonC1qrNMSAHESgRNVaLizNLGzczL9cjRu4ptGz
|
||||
MsFzZTpTplIbY2GbxMeSNdFIia1cSKRJzYgrmXYArgfeOJf5UK53ZGqlrQIDAQAB
|
||||
AoGBAK8U+NrbUCXK5IWpYSqsR+PmwNANVIaUrjjqDg7X9MQ8skLqHUmpnx2GtnVE
|
||||
6ZTaEjq7wruUAxuF5CRe2CLtieouaLvF/gcAsff2Q4kL8taDrM54ECC69JFfijE4
|
||||
jJfEkoJRi1B0nq2QxJke3Sm3vrW2zLDqAZ4EUIh3uxXIYgcBAkEA+imv190S+bCM
|
||||
3H/3L5LHeTRwL58HWcYYjx+/K85yaCqf4wrwyYQ1jRho76uqkjq1mvL65nOniIxd
|
||||
NRnLTiQ+jwJBANxAiY4ww16fUkBGBh2np0FfDUhWgk5G5aZWHsK+5SJZXvlV0kmn
|
||||
kf2R+8hEzAAaOh3Y4d4UBXzOZCKh0nxYdgMCQQCNsQ7oNU+KHXWrbs+TIo/ZFtp0
|
||||
Hp8LOiiu6Exfg49JcNsevhOkED5ErI7DMXhrWtWB7h4uaVN7BAXHDdUZbW4BAkAp
|
||||
Yys1/+3GaxPOphniGq3wN8dML41e3i2rOwWevLZb5QVWvwy78HQbfQIeGOdooYUI
|
||||
NMgErih10ma4p0XhPdI3AkBFp830jNItVGZtVvNRmtx2AR370qMs+AwFTK76mcMW
|
||||
xysAGnAUv7h6Qx+M6b3He8OcWVMNqMiv8yI/o2PnsvUS
|
||||
MIICXQIBAAKBgQDTKElSI/C0LJnPoHwX7udzMXHl0Y3YWoe3dWtfgrDVtlgCJuLY
|
||||
DWYtNTOrZcvUyQxkQqZTsR3lbZcsTqkMHH67DHYin4xrTiI9Ihm2m9iwO55ZVYSx
|
||||
D4StPTeXpv60QNEGLk+GDoGQ7IHxau3uEB4YINkKlAJi0An9LnXYFlNjawIDAQAB
|
||||
AoGBAIX7Wgq0o1avtij4O8Uz4chF529buBU/3D2cU7UWx/3S5aT355gPaHXm/BIV
|
||||
VXB+4U38vGz+RWn+T53di4YTzpTZ2hUpsfR3qLPxEQDwws8NcGmaWMpkDNZYVMGi
|
||||
jC37g3TCNlaW+rpdAhKg8izORjQkY3XI4rClZczojkVC954BAkEA8fBLjrqXEc7I
|
||||
o1mTgduGBwYeBSRVoNLpTqQjrKfmmXFv1vntVhXZsqkgNgP4QJtLnr1IxAMxNeTK
|
||||
gNU7nDhQ0QJBAN9uAmHXQgDZijQOujBTQSd/XdIvFAouNGLvGDreoXqMG3o7vEuS
|
||||
H0rPj30u0zwJ7NluPKnshMjLWi/GWZaXX3sCQQDN/kLW65fk2aOLMaGeV0LuiA7X
|
||||
YfBmVi2/f5HAV9THoQYQjAu/2CrbK5T5aLfeilsAdTmXawBjWsHwn515jZmBAkBW
|
||||
nVDzGP2PUsXO1H69SSkS5L88Qd/k6nCIgePEvpWe6j2krw+ZxDW5TKl1f/eHaNmW
|
||||
mLOPtA7twFdf+ea1CE2NAkB+DytRQjaWstKAO8dpVzyZ9J6bP+FAEGy7lg7GJvKP
|
||||
HW14WK1OJ1luQ2vkftTPjJuE+5QDpkuXFMqJerzBtnL6
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
Reference in New Issue
Block a user