faye-websocket 0.10.5 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5dfb25398e331800baf73b73988b88639753fac9
4
- data.tar.gz: 86e8c6d23a38fa6e699be24dd0aa677a7ad29c0b
2
+ SHA256:
3
+ metadata.gz: 42cb4ec90fb1f2d1fd16739908d415035255136b33c1b8100f4370417d7afeee
4
+ data.tar.gz: b75409884d2ac82e84a59752027085106d1995e92d9603628400b13d7214bc4d
5
5
  SHA512:
6
- metadata.gz: 8900d2b969e66c6a9a338cf763c00f9c59728884ce52c7fe1034d852487c323b14bcab97b4a411761f6bd6d6af7f600f5a2de67c9275be912acbfe50598a0512
7
- data.tar.gz: 6f8df7095506203c476b487383653ef28641bfba255b5febec138aa17af53f9b4e234f951e0f554107bbc461292ef4998cd91c94a0045dc470dc7236f6cfd5aa
6
+ metadata.gz: 23293a16e2b1068bb1bd9a7c4e7516f9031185393e50d766833fe468bff7fb3b807d69015c022f35545cf41abb3e5ff9cf96282bb797ecba0eee60cea63de428
7
+ data.tar.gz: 46ac66a36431ee0adc04dbe5286499c38904b79e4da3259bb42c57c49ff97736568957da641fd640fedc237f67e258d06d5cbd0abb5d3d10eaf662f991368b67
@@ -1,152 +1,185 @@
1
+ ### 0.11.0 / 2020-07-31
2
+
3
+ - Implement TLS certificate verification and enable it by default on client
4
+ connections
5
+ - Add a `:tls` option to the client with sub-fields `:root_cert_file` and
6
+ `:verify_peer` for configuring TLS verification
7
+
8
+ ### 0.10.9 / 2019-06-13
9
+
10
+ - Use the EventMachine API rather than `IO#write` to write data; this uses the
11
+ event loop and avoids getting blocked by slow clients
12
+
13
+ ### 0.10.8 / 2019-06-10
14
+
15
+ - In the case of a close timeout, don't block on waiting for writing to the
16
+ socket to complete
17
+ - Fix a race condition that caused a timeout not to be cancelled immediately
18
+ when the WebSocket is closed
19
+ - Change license from MIT to Apache 2.0
20
+
21
+ ### 0.10.7 / 2017-02-22
22
+
23
+ - Emit an error if `EventMachine::Connection#unbind` is called with an error
24
+
25
+ ### 0.10.6 / 2017-01-22
26
+
27
+ - Forcibly close the I/O stream after a timeout if the peer does not respond
28
+ after calling `close()`
29
+
1
30
  ### 0.10.5 / 2016-11-12
2
31
 
3
- * Set the SNI hostname when making secure requests
32
+ - Set the SNI hostname when making secure requests
4
33
 
5
34
  ### 0.10.4 / 2016-05-20
6
35
 
7
- * Amend warnings issued when running with -W2
36
+ - Amend warnings issued when running with -W2
8
37
 
9
38
  ### 0.10.3 / 2016-02-24
10
39
 
11
- * Use `PATH_INFO` and `QUERY_STRING` rather than the non-standard `REQUEST_URI` from the Rack env
40
+ - Use `PATH_INFO` and `QUERY_STRING` rather than the non-standard `REQUEST_URI`
41
+ from the Rack env
12
42
 
13
43
  ### 0.10.2 / 2015-11-26
14
44
 
15
- * Fix the `headers` and `status` methods on `Client`, which were broken in the
45
+ - Fix the `headers` and `status` methods on `Client`, which were broken in the
16
46
  last release
17
47
 
18
48
  ### 0.10.1 / 2015-11-06
19
49
 
20
- * Make sure errors can be safely emitted if creating the driver fails
21
- * Prevent a race condition when binding `EM.attach` to the socket
50
+ - Make sure errors can be safely emitted if creating the driver fails
51
+ - Prevent a race condition when binding `EM.attach` to the socket
22
52
 
23
53
  ### 0.10.0 / 2015-07-08
24
54
 
25
- * Add the standard `code` and `reason` parameters to the `close` method
55
+ - Add the standard `code` and `reason` parameters to the `close` method
26
56
 
27
57
  ### 0.9.2 / 2014-12-21
28
58
 
29
- * Only emit `error` once, and don't emit it after `close`
59
+ - Only emit `error` once, and don't emit it after `close`
30
60
 
31
61
  ### 0.9.1 / 2014-12-18
32
62
 
33
- * Check that all options to the WebSocket constructor are recognized
63
+ - Check that all options to the WebSocket constructor are recognized
34
64
 
35
65
  ### 0.9.0 / 2014-12-13
36
66
 
37
- * Allow protocol extensions to be passed into websocket-extensions
67
+ - Allow protocol extensions to be passed into websocket-extensions
38
68
 
39
69
  ### 0.8.0 / 2014-11-08
40
70
 
41
- * Support connections via HTTP proxies
71
+ - Support connections via HTTP proxies
42
72
 
43
73
  ### 0.7.5 / 2014-10-04
44
74
 
45
- * Allow sockets to be closed when they are in any state other than `CLOSED`
75
+ - Allow sockets to be closed when they are in any state other than `CLOSED`
46
76
 
47
77
  ### 0.7.4 / 2014-07-06
48
78
 
49
- * Stop using `define_method` to implement `Event` properties, since it blows the method cache
50
- * Stop setup errors masking URI errors in `Client#initialize`
51
- * Make the Goliath adapter compatible with goliath-1.0.4.
79
+ - Stop using `define_method` to implement `Event` properties, since it blows the
80
+ method cache
81
+ - Stop setup errors masking URI errors in `Client#initialize`
82
+ - Make the Goliath adapter compatible with goliath-1.0.4.
52
83
 
53
84
  ### 0.7.3 / 2014-04-24
54
85
 
55
- * Remove an unneeded method override in the `WebSocket` class
86
+ - Remove an unneeded method override in the `WebSocket` class
56
87
 
57
88
  ### 0.7.2 / 2013-12-29
58
89
 
59
- * Fix WebSocket detection in cases where the web server does not produce an `env`
90
+ - Fix WebSocket detection in cases where the web server does not produce an
91
+ `env`
60
92
 
61
93
  ### 0.7.1 / 2013-12-03
62
94
 
63
- * Support the `max_length` websocket-driver option
64
- * Expose a `message` property on `error` events
95
+ - Support the `max_length` websocket-driver option
96
+ - Expose a `message` property on `error` events
65
97
 
66
98
  ### 0.7.0 / 2013-09-09
67
99
 
68
- * Allow the server to send custom headers with EventSource responses
100
+ - Allow the server to send custom headers with EventSource responses
69
101
 
70
102
  ### 0.6.3 / 2013-08-04
71
103
 
72
- * Stop implicitly depending on Rack 1.4
104
+ - Stop implicitly depending on Rack 1.4
73
105
 
74
106
  ### 0.6.2 / 2013-07-05
75
107
 
76
- * Catch errors thrown by EventMachine and emit `error` and `close` events
108
+ - Catch errors thrown by EventMachine and emit `error` and `close` events
77
109
 
78
110
  ### 0.6.1 / 2013-05-12
79
111
 
80
- * Release a gem without log and pid files in it
112
+ - Release a gem without log and pid files in it
81
113
 
82
114
  ### 0.6.0 / 2013-05-12
83
115
 
84
- * Add support for custom headers
116
+ - Add support for custom headers
85
117
 
86
118
  ### 0.5.0 / 2013-05-05
87
119
 
88
- * Extract the protocol handlers into the `websocket-driver` library
89
- * Support the `rack.hijack` API
90
- * Add support for Rainbows 4.5 and Puma
91
- * Officially support JRuby and Rubinius
120
+ - Extract the protocol handlers into the `websocket-driver` library
121
+ - Support the `rack.hijack` API
122
+ - Add support for Rainbows 4.5 and Puma
123
+ - Officially support JRuby and Rubinius
92
124
 
93
125
  ### 0.4.7 / 2013-02-14
94
126
 
95
- * Emit the `close` event if TCP is closed before CLOSE frame is acked
96
- * Treat the `Upgrade: websocket` header case-insensitively because of IE10
97
- * Do not suppress headers in the Thin and Rainbows adapters unless the status is `101`
127
+ - Emit the `close` event if TCP is closed before CLOSE frame is acked
128
+ - Treat the `Upgrade: websocket` header case-insensitively because of IE10
129
+ - Do not suppress headers in the Thin and Rainbows adapters unless the status is
130
+ `101`
98
131
 
99
132
  ### 0.4.6 / 2012-07-09
100
133
 
101
- * Add `Connection: close` to EventSource response
134
+ - Add `Connection: close` to EventSource response
102
135
 
103
136
  ### 0.4.5 / 2012-04-06
104
137
 
105
- * Add WebSocket error code `1011`.
106
- * Handle URLs with no path correctly by sending `GET /`
138
+ - Add WebSocket error code `1011`.
139
+ - Handle URLs with no path correctly by sending `GET /`
107
140
 
108
141
  ### 0.4.4 / 2012-03-16
109
142
 
110
- * Fix installation on JRuby with a platform-specific gem
143
+ - Fix installation on JRuby with a platform-specific gem
111
144
 
112
145
  ### 0.4.3 / 2012-03-12
113
146
 
114
- * Make `extconf.rb` a no-op on JRuby
147
+ - Make `extconf.rb` a no-op on JRuby
115
148
 
116
149
  ### 0.4.2 / 2012-03-09
117
150
 
118
- * Port masking-function C extension to Java for JRuby
151
+ - Port masking-function C extension to Java for JRuby
119
152
 
120
153
  ### 0.4.1 / 2012-02-26
121
154
 
122
- * Treat anything other than an `Array` as a string when calling `send()`
123
- * Fix error loading UTF-8 validation code on Ruby 1.9 with `-Ku` flag
155
+ - Treat anything other than an `Array` as a string when calling `send()`
156
+ - Fix error loading UTF-8 validation code on Ruby 1.9 with `-Ku` flag
124
157
 
125
158
  ### 0.4.0 / 2012-02-13
126
159
 
127
- * Add `ping()` method to server-side `WebSocket` and `EventSource`
128
- * Buffer `send()` calls until the draft-76 handshake is complete
160
+ - Add `ping()` method to server-side `WebSocket` and `EventSource`
161
+ - Buffer `send()` calls until the draft-76 handshake is complete
129
162
 
130
163
  ### 0.3.0 / 2012-01-13
131
164
 
132
- * Add support for `EventSource` connections
133
- * Support the Thin, Rainbows and Goliath web servers
165
+ - Add support for `EventSource` connections
166
+ - Support the Thin, Rainbows and Goliath web servers
134
167
 
135
168
  ### 0.2.0 / 2011-12-21
136
169
 
137
- * Add support for `Sec-WebSocket-Protocol` negotiation
138
- * Support `hixie-76` close frames and 75/76 ignored segments
139
- * Improve performance of HyBi parsing/framing functions
140
- * Write masking function in C
170
+ - Add support for `Sec-WebSocket-Protocol` negotiation
171
+ - Support `hixie-76` close frames and 75/76 ignored segments
172
+ - Improve performance of HyBi parsing/framing functions
173
+ - Write masking function in C
141
174
 
142
175
  ### 0.1.2 / 2011-12-05
143
176
 
144
- * Make `hixie-76` sockets work through HAProxy
177
+ - Make `hixie-76` sockets work through HAProxy
145
178
 
146
179
  ### 0.1.1 / 2011-11-30
147
180
 
148
- * Fix `add_event_listener()` interface methods
181
+ - Fix `add_event_listener()` interface methods
149
182
 
150
183
  ### 0.1.0 / 2011-11-27
151
184
 
152
- * Initial release, based on WebSocket components from Faye
185
+ - Initial release, based on WebSocket components from Faye
@@ -0,0 +1,12 @@
1
+ Copyright 2010-2020 James Coglan
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4
+ this file except in compliance with the License. You may obtain a copy of the
5
+ License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software distributed
10
+ under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11
+ CONDITIONS OF ANY KIND, either express or implied. See the License for the
12
+ specific language governing permissions and limitations under the License.
data/README.md CHANGED
@@ -1,9 +1,4 @@
1
- # faye-websocket
2
-
3
- * Travis CI build: [![Build
4
- status](https://secure.travis-ci.org/faye/faye-websocket-ruby.svg)](http://travis-ci.org/faye/faye-websocket-ruby)
5
- * Autobahn tests: [server](http://faye.jcoglan.com/autobahn/servers/),
6
- [client](http://faye.jcoglan.com/autobahn/clients/)
1
+ # faye-websocket [![Build status](https://secure.travis-ci.org/faye/faye-websocket-ruby.svg)](http://travis-ci.org/faye/faye-websocket-ruby)
7
2
 
8
3
  This is a general-purpose WebSocket implementation extracted from the
9
4
  [Faye](http://faye.jcoglan.com) project. It provides classes for easily building
@@ -22,11 +17,11 @@ access via proxies than WebSockets.
22
17
  The following web servers are supported. Other servers that implement the
23
18
  `rack.hijack` API should also work.
24
19
 
25
- * [Goliath](http://postrank-labs.github.com/goliath/)
26
- * [Phusion Passenger](https://www.phusionpassenger.com/) >= 4.0 with nginx >= 1.4
27
- * [Puma](http://puma.io/) >= 2.0
28
- * [Rainbows](http://rainbows.bogomips.org/)
29
- * [Thin](http://code.macournoyer.com/thin/)
20
+ - [Goliath](http://postrank-labs.github.com/goliath/)
21
+ - [Phusion Passenger](https://www.phusionpassenger.com/) >= 4.0 with nginx >= 1.4
22
+ - [Puma](http://puma.io/) >= 2.0
23
+ - [Rainbows](http://rainbows.bogomips.org/)
24
+ - [Thin](http://code.macournoyer.com/thin/)
30
25
 
31
26
 
32
27
  ## Installation
@@ -65,7 +60,7 @@ App = lambda do |env|
65
60
 
66
61
  else
67
62
  # Normal HTTP request
68
- [200, {'Content-Type' => 'text/plain'}, ['Hello']]
63
+ [200, { 'Content-Type' => 'text/plain' }, ['Hello']]
69
64
  end
70
65
  end
71
66
  ```
@@ -133,7 +128,7 @@ including any authorization information and custom headers you require:
133
128
  ws = Faye::WebSocket::Client.new('ws://www.example.com/', [], {
134
129
  :proxy => {
135
130
  :origin => 'http://username:password@proxy.example.com',
136
- :headers => {'User-Agent' => 'ruby'}
131
+ :headers => { 'User-Agent' => 'ruby' }
137
132
  }
138
133
  })
139
134
  ```
@@ -190,45 +185,78 @@ ws = Faye::WebSocket::Client.new(url, protocols, options)
190
185
  `protocols` as an array of subprotocols as described above, or `nil`. `options`
191
186
  is an optional hash containing any of these keys:
192
187
 
193
- * `:extensions` - an array of
188
+ - `:extensions` - an array of
194
189
  [websocket-extensions](https://github.com/faye/websocket-extensions-ruby)
195
190
  compatible extensions, as described above
196
- * `:headers` - a hash containing key-value pairs representing HTTP headers to be
191
+ - `:headers` - a hash containing key-value pairs representing HTTP headers to be
197
192
  sent during the handshake process
198
- * `:max_length` - the maximum allowed size of incoming message frames, in bytes.
193
+ - `:max_length` - the maximum allowed size of incoming message frames, in bytes.
199
194
  The default value is `2^26 - 1`, or 1 byte short of 64 MiB.
200
- * `:ping` - an integer that sets how often the WebSocket should send ping
195
+ - `:ping` - an integer that sets how often the WebSocket should send ping
201
196
  frames, measured in seconds
202
- * `:tls` - a hash containing key-value pairs for specifying TLS parameters.
197
+ - `:tls` - a hash containing key-value pairs for specifying TLS parameters.
203
198
  These are passed along to EventMachine and you can find
204
199
  [more details here](http://rubydoc.info/gems/eventmachine/EventMachine%2FConnection%3Astart_tls)
205
200
 
201
+ ### Secure sockets
202
+
203
+ Starting with version 0.11.0, `Faye::WebSocket::Client` will verify the server
204
+ certificate for `wss` connections. This is not the default behaviour for
205
+ EventMachine's TLS interface, and so our defaults for the `:tls` option are a
206
+ little different.
207
+
208
+ First, `:verify_peer` is enabled by default. Our implementation checks that the
209
+ chain of certificates sent by the server is trusted by your root certificates,
210
+ and that the final certificate's hostname matches the hostname in the request
211
+ URL.
212
+
213
+ By default, we use your system's root certificate store by invoking
214
+ `OpenSSL::X509::Store#set_default_paths`. If you want to use a different set of
215
+ root certificates, you can pass them via the `:root_cert_file` option, which
216
+ takes a path or an array of paths to the certificates you want to use.
217
+
218
+ ```ruby
219
+ ws = Faye::WebSocket::Client.new('wss://example.com/', [], :tls => {
220
+ :root_cert_file => ['path/to/certificate.pem']
221
+ })
222
+ ```
223
+
224
+ If you want to switch off certificate verification altogether, then set
225
+ `:verify_peer` to `false`.
226
+
227
+ ```ruby
228
+ ws = Faye::WebSocket::Client.new('wss://example.com/', [], :tls => {
229
+ :verify_peer => false
230
+ })
231
+ ```
232
+
206
233
  ## WebSocket API
207
234
 
208
235
  Both the server- and client-side `WebSocket` objects support the following API:
209
236
 
210
- * <b>`on(:open) { |event| }`</b> fires when the socket connection is
211
- established. Event has no attributes.
212
- * <b>`on(:message) { |event| }`</b> fires when the socket receives a message.
213
- Event has one attribute, <b>`data`</b>, which is either a `String` (for text
214
- frames) or an `Array` of byte-sized integers (for binary frames).
215
- * <b>`on(:error) { |event| }`</b> fires when there is a protocol error due to
216
- bad data sent by the other peer. This event is purely informational, you do
217
- not need to implement error recovery.
218
- * <b>`on(:close) { |event| }`</b> fires when either the client or the server
219
- closes the connection. Event has two optional attributes, <b>`code`</b> and
220
- <b>`reason`</b>, that expose the status code and message sent by the peer that
237
+ - **`on(:open) { |event| }`** fires when the socket connection is established.
238
+ Event has no attributes.
239
+ - **`on(:message) { |event| }`** fires when the socket receives a message. Event
240
+ has one attribute, **`data`**, which is either a `String` (for text frames) or
241
+ an `Array` of unsigned integers, i.e. integers in the range `0..255` (for
242
+ binary frames).
243
+ - **`on(:error) { |event| }`** fires when there is a protocol error due to bad
244
+ data sent by the other peer. This event is purely informational, you do not
245
+ need to implement error recovery.
246
+ - **`on(:close) { |event| }`** fires when either the client or the server closes
247
+ the connection. Event has two optional attributes, **`code`** and
248
+ **`reason`**, that expose the status code and message sent by the peer that
221
249
  closed the connection.
222
- * <b>`send(message)`</b> accepts either a `String` or an `Array` of byte-sized
250
+ - **`send(message)`** accepts either a `String` or an `Array` of byte-sized
223
251
  integers and sends a text or binary message over the connection to the other
224
252
  peer; binary data must be encoded as an `Array`.
225
- * <b>`ping(message, &callback)`</b> sends a ping frame with an optional message
226
- and fires the callback when a matching pong is received.
227
- * <b>`close(code, reason)`</b> closes the connection, sending the given status
228
- code and reason text, both of which are optional.
229
- * <b>`version`</b> is a string containing the version of the `WebSocket`
230
- protocol the connection is using.
231
- * <b>`protocol`</b> is a string (which may be empty) identifying the subprotocol
253
+ - **`ping(message, &callback)`** sends a ping frame with an optional message and
254
+ fires the callback when a matching pong is received.
255
+ - **`close(code, reason)`** closes the connection, sending the given status code
256
+ and reason text, both of which are optional.
257
+ - **`version`** is a string containing the version of the `WebSocket` protocol
258
+ the connection is using.
259
+ - **`protocol`** is a string (which may be empty) identifying the subprotocol
232
260
  the socket is using.
233
261
 
234
262
 
@@ -261,7 +289,7 @@ App = lambda do |env|
261
289
 
262
290
  else
263
291
  # Normal HTTP request
264
- [200, {'Content-Type' => 'text/plain'}, ['Hello']]
292
+ [200, { 'Content-Type' => 'text/plain' }, ['Hello']]
265
293
  end
266
294
  end
267
295
  ```
@@ -276,29 +304,29 @@ es.send('Breaking News!', :event => 'notification', :id => '99')
276
304
 
277
305
  The `EventSource` object exposes the following properties:
278
306
 
279
- * <b>`url`</b> is a string containing the URL the client used to create the
307
+ - **`url`** is a string containing the URL the client used to create the
280
308
  EventSource.
281
- * <b>`last_event_id`</b> is a string containing the last event ID received by
282
- the client. You can use this when the client reconnects after a dropped
283
- connection to determine which messages need resending.
309
+ - **`last_event_id`** is a string containing the last event ID received by the
310
+ client. You can use this when the client reconnects after a dropped connection
311
+ to determine which messages need resending.
284
312
 
285
313
  When you initialize an EventSource with `Faye::EventSource.new`, you can pass
286
314
  configuration options after the `env` parameter. Available options are:
287
315
 
288
- * <b>`:headers`</b> is a hash containing custom headers to be set on the
316
+ - **`:headers`** is a hash containing custom headers to be set on the
289
317
  EventSource response.
290
- * <b>`:retry`</b> is a number that tells the client how long (in seconds) it
291
- should wait after a dropped connection before attempting to reconnect.
292
- * <b>`:ping`</b> is a number that tells the server how often (in seconds) to
293
- send 'ping' packets to the client to keep the connection open, to defeat
294
- timeouts set by proxies. The client will ignore these messages.
318
+ - **`:retry`** is a number that tells the client how long (in seconds) it should
319
+ wait after a dropped connection before attempting to reconnect.
320
+ - **`:ping`** is a number that tells the server how often (in seconds) to send
321
+ 'ping' packets to the client to keep the connection open, to defeat timeouts
322
+ set by proxies. The client will ignore these messages.
295
323
 
296
324
  For example, this creates a connection that allows access from any origin, pings
297
325
  every 15 seconds and is retryable every 10 seconds if the connection is broken:
298
326
 
299
327
  ```ruby
300
328
  es = Faye::EventSource.new(es,
301
- :headers => {'Access-Control-Allow-Origin' => '*'},
329
+ :headers => { 'Access-Control-Allow-Origin' => '*' },
302
330
  :ping => 15,
303
331
  :retry => 10
304
332
  )
@@ -487,27 +515,3 @@ class EchoServer < Goliath::API
487
515
  end
488
516
  end
489
517
  ```
490
-
491
-
492
- ## License
493
-
494
- (The MIT License)
495
-
496
- Copyright (c) 2010-2016 James Coglan
497
-
498
- Permission is hereby granted, free of charge, to any person obtaining a copy of
499
- this software and associated documentation files (the 'Software'), to deal in
500
- the Software without restriction, including without limitation the rights to
501
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
502
- the Software, and to permit persons to whom the Software is furnished to do so,
503
- subject to the following conditions:
504
-
505
- The above copyright notice and this permission notice shall be included in all
506
- copies or substantial portions of the Software.
507
-
508
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
509
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
510
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
511
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
512
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
513
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -63,7 +63,7 @@ module Faye
63
63
  end
64
64
 
65
65
  private
66
-
66
+
67
67
  def open
68
68
  return unless @ready_state == WebSocket::API::CONNECTING
69
69
 
@@ -83,9 +83,9 @@ module Faye
83
83
  gsub(/(\r\n|\r|\n)/, '\1data: ')
84
84
 
85
85
  frame = ""
86
- frame << "event: #{options[:event]}\r\n" if options[:event]
87
- frame << "id: #{options[:id]}\r\n" if options[:id]
88
- frame << "data: #{message}\r\n\r\n"
86
+ frame << "event: #{ options[:event] }\r\n" if options[:event]
87
+ frame << "id: #{ options[:id] }\r\n" if options[:id]
88
+ frame << "data: #{ message }\r\n\r\n"
89
89
 
90
90
  @stream.write(frame)
91
91
  true
@@ -79,6 +79,7 @@ module Faye
79
79
  end
80
80
 
81
81
  def write(data)
82
+ return @rack_hijack_io_reader.send_data(data) if @rack_hijack_io_reader
82
83
  return @rack_hijack_io.write(data) if @rack_hijack_io
83
84
  return @stream_send.call(data) if @stream_send
84
85
  rescue => e
@@ -17,9 +17,10 @@ module Faye
17
17
  class WebSocket
18
18
  root = File.expand_path('../websocket', __FILE__)
19
19
 
20
- autoload :Adapter, root + '/adapter'
21
- autoload :API, root + '/api'
22
- autoload :Client, root + '/client'
20
+ autoload :Adapter, root + '/adapter'
21
+ autoload :API, root + '/api'
22
+ autoload :Client, root + '/client'
23
+ autoload :SslVerifier, root + '/ssl_verifier'
23
24
 
24
25
  ADAPTERS = {
25
26
  'goliath' => :Goliath,
@@ -44,7 +45,7 @@ module Faye
44
45
  def self.load_adapter(backend)
45
46
  const = Kernel.const_get(ADAPTERS[backend]) rescue nil
46
47
  require(backend) unless const
47
- path = File.expand_path("../adapters/#{backend}.rb", __FILE__)
48
+ path = File.expand_path("../adapters/#{ backend }.rb", __FILE__)
48
49
  require(path) if File.file?(path)
49
50
  end
50
51
 
@@ -10,6 +10,8 @@ module Faye
10
10
  CLOSING = 2
11
11
  CLOSED = 3
12
12
 
13
+ CLOSE_TIMEOUT = 30
14
+
13
15
  include EventTarget
14
16
 
15
17
  extend Forwardable
@@ -36,12 +38,12 @@ module Faye
36
38
  @ping_id = 0
37
39
  @buffered_amount = 0
38
40
 
39
- @close_params = @ping_timer = @proxy = @stream = nil
41
+ @close_params = @close_timer = @ping_timer = @proxy = @stream = nil
40
42
  @onopen = @onmessage = @onclose = @onerror = nil
41
43
 
42
44
  @driver.on(:open) { |e| open }
43
45
  @driver.on(:message) { |e| receive_message(e.data) }
44
- @driver.on(:close) { |e| begin_close(e.reason, e.code) }
46
+ @driver.on(:close) { |e| begin_close(e.reason, e.code, :wait_for_write => true) }
45
47
 
46
48
  @driver.on(:error) do |error|
47
49
  emit_error(error.message)
@@ -81,10 +83,12 @@ module Faye
81
83
  unless code == 1000 or (code >= 3000 and code <= 4999)
82
84
  raise ArgumentError, "Failed to execute 'close' on WebSocket: " +
83
85
  "The code must be either 1000, or between 3000 and 4999. " +
84
- "#{code} is neither."
86
+ "#{ code } is neither."
85
87
  end
86
88
 
87
89
  @ready_state = CLOSING unless @ready_state == CLOSED
90
+ @close_timer = EventMachine.add_timer(CLOSE_TIMEOUT) { begin_close('', 1006) }
91
+
88
92
  @driver.close(reason, code)
89
93
  end
90
94
 
@@ -117,13 +121,17 @@ module Faye
117
121
  dispatch_event(event)
118
122
  end
119
123
 
120
- def begin_close(reason, code)
124
+ def begin_close(reason, code, options = {})
121
125
  return if @ready_state == CLOSED
122
126
  @ready_state = CLOSING
123
127
  @close_params = [reason, code]
124
128
 
125
129
  if @stream
126
- @stream.close_connection_after_writing
130
+ if options[:wait_for_write]
131
+ @stream.close_connection_after_writing
132
+ else
133
+ @stream.close_connection
134
+ end
127
135
  else
128
136
  finalize_close
129
137
  end
@@ -133,6 +141,7 @@ module Faye
133
141
  return if @ready_state == CLOSED
134
142
  @ready_state = CLOSED
135
143
 
144
+ EventMachine.cancel_timer(@close_timer) if @close_timer
136
145
  EventMachine.cancel_timer(@ping_timer) if @ping_timer
137
146
 
138
147
  reason = @close_params ? @close_params[0] : ''
@@ -10,7 +10,7 @@ module Faye::WebSocket::API
10
10
 
11
11
  def initialize(event_type, options)
12
12
  @type = event_type
13
- options.each { |key, value| instance_variable_set("@#{key}", value) }
13
+ options.each { |key, value| instance_variable_set("@#{ key }", value) }
14
14
  end
15
15
 
16
16
  def init_event(event_type, can_bubble, cancelable)
@@ -5,10 +5,10 @@ module Faye::WebSocket::API
5
5
  events = %w[open message error close]
6
6
 
7
7
  events.each do |event_type|
8
- define_method "on#{event_type}=" do |handler|
8
+ define_method "on#{ event_type }=" do |handler|
9
9
  EventMachine.next_tick do
10
10
  flush(event_type, handler)
11
- instance_variable_set("@on#{event_type}", handler)
11
+ instance_variable_set("@on#{ event_type }", handler)
12
12
  end
13
13
  end
14
14
  end
@@ -7,7 +7,7 @@ module Faye
7
7
  extend Forwardable
8
8
  include API
9
9
 
10
- DEFAULT_PORTS = {'http' => 80, 'https' => 443, 'ws' => 80, 'wss' => 443}
10
+ DEFAULT_PORTS = { 'http' => 80, 'https' => 443, 'ws' => 80, 'wss' => 443 }
11
11
  SECURE_PROTOCOLS = ['https', 'wss']
12
12
 
13
13
  def_delegators :@driver, :headers, :status
@@ -17,58 +17,72 @@ module Faye
17
17
  super(options) { ::WebSocket::Driver.client(self, :max_length => options[:max_length], :protocols => protocols) }
18
18
 
19
19
  proxy = options.fetch(:proxy, {})
20
- endpoint = URI.parse(proxy[:origin] || @url)
21
- port = endpoint.port || DEFAULT_PORTS[endpoint.scheme]
22
- @secure = SECURE_PROTOCOLS.include?(endpoint.scheme)
20
+ @endpoint = URI.parse(proxy[:origin] || @url)
21
+ port = @endpoint.port || DEFAULT_PORTS[@endpoint.scheme]
23
22
  @origin_tls = options.fetch(:tls, {})
24
23
  @socket_tls = proxy[:origin] ? proxy.fetch(:tls, {}) : @origin_tls
25
24
 
26
- if proxy[:origin]
27
- @proxy = @driver.proxy(proxy[:origin])
28
- if headers = proxy[:headers]
29
- headers.each { |name, value| @proxy.set_header(name, value) }
30
- end
25
+ configure_proxy(proxy)
31
26
 
32
- @proxy.on(:connect) do
33
- uri = URI.parse(@url)
34
- secure = SECURE_PROTOCOLS.include?(uri.scheme)
35
- @proxy = nil
27
+ EventMachine.connect(@endpoint.host, port, Connection) do |conn|
28
+ conn.parent = self
29
+ end
30
+ rescue => error
31
+ on_network_error(error)
32
+ end
36
33
 
37
- if secure
38
- origin_tls = {:sni_hostname => uri.host}.merge(@origin_tls)
39
- @stream.start_tls(origin_tls)
40
- end
34
+ private
35
+
36
+ def configure_proxy(proxy)
37
+ return unless proxy[:origin]
41
38
 
42
- @driver.start
43
- end
39
+ @proxy = @driver.proxy(proxy[:origin])
40
+ @proxy.on(:error) { |error| @driver.emit(:error, error) }
44
41
 
45
- @proxy.on(:error) do |error|
46
- @driver.emit(:error, error)
47
- end
42
+ if headers = proxy[:headers]
43
+ headers.each { |name, value| @proxy.set_header(name, value) }
48
44
  end
49
45
 
50
- EventMachine.connect(endpoint.host, port, Connection) do |conn|
51
- conn.parent = self
46
+ @proxy.on(:connect) do
47
+ @proxy = nil
48
+ start_tls(URI.parse(@url), @origin_tls)
49
+ @driver.start
52
50
  end
53
- rescue => error
54
- emit_error("Network error: #{url}: #{error.message}")
55
- finalize_close
56
51
  end
57
52
 
58
- private
53
+ def start_tls(uri, options)
54
+ return unless SECURE_PROTOCOLS.include?(uri.scheme)
55
+
56
+ tls_options = { :sni_hostname => uri.host, :verify_peer => true }.merge(options)
57
+ @ssl_verifier = SslVerifier.new(uri.host, tls_options)
58
+ @stream.start_tls(tls_options)
59
+ end
59
60
 
60
61
  def on_connect(stream)
61
62
  @stream = stream
62
-
63
- if @secure
64
- socket_tls = {:sni_hostname => URI.parse(@url).host}.merge(@socket_tls)
65
- @stream.start_tls(socket_tls)
66
- end
63
+ start_tls(@endpoint, @socket_tls)
67
64
 
68
65
  worker = @proxy || @driver
69
66
  worker.start
70
67
  end
71
68
 
69
+ def on_network_error(error)
70
+ emit_error("Network error: #{ @url }: #{ error.message }")
71
+ finalize_close
72
+ end
73
+
74
+ def ssl_verify_peer(cert)
75
+ @ssl_verifier.ssl_verify_peer(cert)
76
+ rescue => error
77
+ on_network_error(error)
78
+ end
79
+
80
+ def ssl_handshake_completed
81
+ @ssl_verifier.ssl_handshake_completed
82
+ rescue => error
83
+ on_network_error(error)
84
+ end
85
+
72
86
  module Connection
73
87
  attr_accessor :parent
74
88
 
@@ -76,11 +90,20 @@ module Faye
76
90
  parent.__send__(:on_connect, self)
77
91
  end
78
92
 
93
+ def ssl_verify_peer(cert)
94
+ parent.__send__(:ssl_verify_peer, cert)
95
+ end
96
+
97
+ def ssl_handshake_completed
98
+ parent.__send__(:ssl_handshake_completed)
99
+ end
100
+
79
101
  def receive_data(data)
80
102
  parent.__send__(:parse, data)
81
103
  end
82
104
 
83
- def unbind
105
+ def unbind(error = nil)
106
+ parent.__send__(:emit_error, error) if error
84
107
  parent.__send__(:finalize_close)
85
108
  end
86
109
 
@@ -0,0 +1,89 @@
1
+ # This code is based on the implementation in Faraday:
2
+ #
3
+ # https://github.com/lostisland/faraday/blob/v1.0.1/lib/faraday/adapter/em_http_ssl_patch.rb
4
+ #
5
+ # Faraday is published under the MIT license as detailed here:
6
+ #
7
+ # https://github.com/lostisland/faraday/blob/v1.0.1/LICENSE.md
8
+ #
9
+ # Copyright (c) 2009-2019 Rick Olson, Zack Hobson
10
+ #
11
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ # of this software and associated documentation files (the "Software"), to deal
13
+ # in the Software without restriction, including without limitation the rights
14
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ # copies of the Software, and to permit persons to whom the Software is
16
+ # furnished to do so, subject to the following conditions:
17
+ #
18
+ # The above copyright notice and this permission notice shall be included in
19
+ # all copies or substantial portions of the Software.
20
+
21
+ require 'openssl'
22
+
23
+ module Faye
24
+ class WebSocket
25
+
26
+ SSLError = Class.new(OpenSSL::SSL::SSLError)
27
+
28
+ class SslVerifier
29
+ def initialize(hostname, ssl_opts)
30
+ @hostname = hostname
31
+ @ssl_opts = ssl_opts
32
+ @cert_store = OpenSSL::X509::Store.new
33
+
34
+ if root = @ssl_opts[:root_cert_file]
35
+ [root].flatten.each { |ca_path| @cert_store.add_file(ca_path) }
36
+ else
37
+ @cert_store.set_default_paths
38
+ end
39
+ end
40
+
41
+ def ssl_verify_peer(cert_text)
42
+ return true unless should_verify?
43
+
44
+ certificate = parse_cert(cert_text)
45
+ return false unless certificate
46
+
47
+ unless @cert_store.verify(certificate)
48
+ raise SSLError, "Unable to verify the server certificate for '#{ @hostname }'"
49
+ end
50
+
51
+ store_cert(certificate)
52
+ @last_cert = certificate
53
+
54
+ true
55
+ end
56
+
57
+ def ssl_handshake_completed
58
+ return unless should_verify?
59
+
60
+ unless identity_verified?
61
+ raise SSLError, "Host '#{ @hostname }' does not match the server certificate"
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def should_verify?
68
+ @ssl_opts[:verify_peer] != false
69
+ end
70
+
71
+ def parse_cert(cert_text)
72
+ OpenSSL::X509::Certificate.new(cert_text)
73
+ rescue OpenSSL::X509::CertificateError
74
+ nil
75
+ end
76
+
77
+ def store_cert(certificate)
78
+ @cert_store.add_cert(certificate)
79
+ rescue OpenSSL::X509::StoreError => error
80
+ raise error unless error.message == 'cert already in hash table'
81
+ end
82
+
83
+ def identity_verified?
84
+ @last_cert and OpenSSL::SSL.verify_certificate_identity(@last_cert, @hostname)
85
+ end
86
+ end
87
+
88
+ end
89
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faye-websocket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.5
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Coglan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-12 00:00:00.000000000 Z
11
+ date: 2020-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eventmachine
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: public_suffix
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "<"
74
- - !ruby/object:Gem::Version
75
- version: 1.5.0
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "<"
81
- - !ruby/object:Gem::Version
82
- version: 1.5.0
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: puma
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -168,14 +154,14 @@ dependencies:
168
154
  name: goliath
169
155
  requirement: !ruby/object:Gem::Requirement
170
156
  requirements:
171
- - - ">="
157
+ - - ">"
172
158
  - !ruby/object:Gem::Version
173
159
  version: '0'
174
160
  type: :development
175
161
  prerelease: false
176
162
  version_requirements: !ruby/object:Gem::Requirement
177
163
  requirements:
178
- - - ">="
164
+ - - ">"
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0'
181
167
  - !ruby/object:Gem::Dependency
@@ -192,7 +178,7 @@ dependencies:
192
178
  - - ">="
193
179
  - !ruby/object:Gem::Version
194
180
  version: 4.0.0
195
- description:
181
+ description:
196
182
  email: jcoglan@gmail.com
197
183
  executables: []
198
184
  extensions: []
@@ -200,17 +186,8 @@ extra_rdoc_files:
200
186
  - README.md
201
187
  files:
202
188
  - CHANGELOG.md
189
+ - LICENSE.md
203
190
  - README.md
204
- - examples/app.rb
205
- - examples/autobahn_client.rb
206
- - examples/client.rb
207
- - examples/config.ru
208
- - examples/haproxy.conf
209
- - examples/proxy_server.rb
210
- - examples/rainbows.conf
211
- - examples/server.rb
212
- - examples/sse.html
213
- - examples/ws.html
214
191
  - lib/faye/adapters/goliath.rb
215
192
  - lib/faye/adapters/rainbows.rb
216
193
  - lib/faye/adapters/rainbows_client.rb
@@ -223,11 +200,12 @@ files:
223
200
  - lib/faye/websocket/api/event.rb
224
201
  - lib/faye/websocket/api/event_target.rb
225
202
  - lib/faye/websocket/client.rb
203
+ - lib/faye/websocket/ssl_verifier.rb
226
204
  homepage: https://github.com/faye/faye-websocket-ruby
227
205
  licenses:
228
- - MIT
206
+ - Apache-2.0
229
207
  metadata: {}
230
- post_install_message:
208
+ post_install_message:
231
209
  rdoc_options:
232
210
  - "--main"
233
211
  - README.md
@@ -246,9 +224,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
224
  - !ruby/object:Gem::Version
247
225
  version: '0'
248
226
  requirements: []
249
- rubyforge_project:
250
- rubygems_version: 2.5.1
251
- signing_key:
227
+ rubygems_version: 3.1.2
228
+ signing_key:
252
229
  specification_version: 4
253
230
  summary: Standards-compliant WebSocket server and client
254
231
  test_files: []
@@ -1,54 +0,0 @@
1
- require 'faye/websocket'
2
- require 'permessage_deflate'
3
- require 'rack'
4
-
5
- static = Rack::File.new(File.dirname(__FILE__))
6
- options = {:extensions => [PermessageDeflate], :ping => 5}
7
-
8
- App = lambda do |env|
9
- if Faye::WebSocket.websocket?(env)
10
- ws = Faye::WebSocket.new(env, ['irc', 'xmpp'], options)
11
- p [:open, ws.url, ws.version, ws.protocol]
12
-
13
- ws.onmessage = lambda do |event|
14
- ws.send(event.data)
15
- end
16
-
17
- ws.onclose = lambda do |event|
18
- p [:close, event.code, event.reason]
19
- ws = nil
20
- end
21
-
22
- ws.rack_response
23
-
24
- elsif Faye::EventSource.eventsource?(env)
25
- es = Faye::EventSource.new(env)
26
- time = es.last_event_id.to_i
27
-
28
- p [:open, es.url, es.last_event_id]
29
-
30
- loop = EM.add_periodic_timer(2) do
31
- time += 1
32
- es.send("Time: #{time}")
33
- EM.add_timer(1) do
34
- es.send('Update!!', :event => 'update', :id => time) if es
35
- end
36
- end
37
-
38
- es.send("Welcome!\n\nThis is an EventSource server.")
39
-
40
- es.onclose = lambda do |event|
41
- EM.cancel_timer(loop)
42
- p [:close, es.url]
43
- es = nil
44
- end
45
-
46
- es.rack_response
47
-
48
- else
49
- static.call(env)
50
- end
51
- end
52
-
53
- def App.log(message)
54
- end
@@ -1,48 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'cgi'
4
- require 'faye/websocket'
5
- require 'permessage_deflate'
6
- require 'progressbar'
7
-
8
- EM.run {
9
- host = 'ws://localhost:9001'
10
- ruby = RUBY_PLATFORM =~ /java/ ? 'jruby' : 'cruby'
11
- agent = CGI.escape("#{ruby}-#{RUBY_VERSION}")
12
- cases = 0
13
- options = {:extensions => [PermessageDeflate]}
14
-
15
- socket = Faye::WebSocket::Client.new("#{host}/getCaseCount")
16
- progress = nil
17
-
18
- socket.onmessage = lambda do |event|
19
- puts "Total cases to run: #{event.data}"
20
- cases = event.data.to_i
21
- progress = ProgressBar.new('Autobahn', cases)
22
- end
23
-
24
- run_case = lambda do |n|
25
- if n > cases
26
- socket = Faye::WebSocket::Client.new("#{host}/updateReports?agent=#{agent}")
27
- progress.finish
28
- socket.onclose = lambda { |e| EM.stop }
29
- next
30
- end
31
-
32
- url = "#{host}/runCase?case=#{n}&agent=#{agent}"
33
- socket = Faye::WebSocket::Client.new(url, [], options)
34
-
35
- socket.onmessage = lambda do |event|
36
- socket.send(event.data)
37
- end
38
-
39
- socket.on :close do |event|
40
- progress.inc
41
- run_case[n + 1]
42
- end
43
- end
44
-
45
- socket.onclose = lambda do |event|
46
- run_case[1]
47
- end
48
- }
@@ -1,34 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'faye/websocket'
4
- require 'eventmachine'
5
- require 'permessage_deflate'
6
-
7
- EM.run {
8
- url = ARGV[0]
9
- proxy = ARGV[1]
10
-
11
- ws = Faye::WebSocket::Client.new(url, [],
12
- :proxy => {:origin => proxy, :headers => {'User-Agent' => 'Echo'}},
13
- :headers => {'Origin' => 'http://faye.jcoglan.com'},
14
- :extensions => [PermessageDeflate]
15
- )
16
-
17
- ws.onopen = lambda do |event|
18
- p [:open, ws.headers]
19
- ws.send('mic check')
20
- end
21
-
22
- ws.onclose = lambda do |close|
23
- p [:close, close.code, close.reason]
24
- EM.stop
25
- end
26
-
27
- ws.onerror = lambda do |error|
28
- p [:error, error.message]
29
- end
30
-
31
- ws.onmessage = lambda do |message|
32
- p [:message, message.data]
33
- end
34
- }
@@ -1,13 +0,0 @@
1
- # Run using your favourite server:
2
- #
3
- # thin start -R examples/config.ru -p 7000
4
- # rainbows -c examples/rainbows.conf -E production examples/config.ru -p 7000
5
-
6
- require 'rubygems'
7
- require 'bundler/setup'
8
- require File.expand_path('../app', __FILE__)
9
-
10
- Faye::WebSocket.load_adapter('thin')
11
- Faye::WebSocket.load_adapter('rainbows')
12
-
13
- run App
@@ -1,20 +0,0 @@
1
- defaults
2
- mode http
3
- timeout client 5s
4
- timeout connect 5s
5
- timeout server 5s
6
-
7
- frontend all 0.0.0.0:3000
8
- mode http
9
- timeout client 120s
10
-
11
- option forwardfor
12
- option http-server-close
13
- option http-pretend-keepalive
14
-
15
- default_backend sockets
16
-
17
- backend sockets
18
- balance uri depth 2
19
- timeout server 120s
20
- server socket1 127.0.0.1:7000
@@ -1,14 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'eventmachine'
4
- require 'websocket/driver'
5
-
6
- require File.expand_path('../../spec/proxy_server', __FILE__)
7
-
8
- port = ARGV[0]
9
- secure = ARGV[1] == 'tls'
10
-
11
- EM.run {
12
- proxy = ProxyServer.new(:debug => true)
13
- proxy.listen(port, secure)
14
- }
@@ -1,3 +0,0 @@
1
- Rainbows! do
2
- use :EventMachine
3
- end
@@ -1,50 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
- require 'rack/content_length'
4
- require 'rack/chunked'
5
-
6
- port = ARGV[0] || 7000
7
- secure = ARGV[1] == 'tls'
8
- engine = ARGV[2] || 'thin'
9
- spec = File.expand_path('../../spec', __FILE__)
10
-
11
- require File.expand_path('../app', __FILE__)
12
- Faye::WebSocket.load_adapter(engine)
13
-
14
- case engine
15
-
16
- when 'goliath'
17
- class WebSocketServer < Goliath::API
18
- def response(env)
19
- App.call(env)
20
- end
21
- end
22
-
23
- when 'puma'
24
- events = Puma::Events.new($stdout, $stderr)
25
- binder = Puma::Binder.new(events)
26
- binder.parse(["tcp://0.0.0.0:#{port}"], App)
27
- server = Puma::Server.new(App, events)
28
- server.binder = binder
29
- server.run.join
30
-
31
- when 'rainbows'
32
- rackup = Unicorn::Configurator::RACKUP
33
- rackup[:port] = port
34
- rackup[:set_listener] = true
35
- options = rackup[:options]
36
- options[:config_file] = File.expand_path('../rainbows.conf', __FILE__)
37
- Rainbows::HttpServer.new(App, options).start.join
38
-
39
- when 'thin'
40
- thin = Rack::Handler.get('thin')
41
- thin.run(App, :Port => port) do |server|
42
- if secure
43
- server.ssl_options = {
44
- :private_key_file => spec + '/server.key',
45
- :cert_chain_file => spec + '/server.crt'
46
- }
47
- server.ssl = true
48
- end
49
- end
50
- end
@@ -1,38 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta http-equiv="Content-type" content="text/html; charset=utf-8">
5
- <title>EventSource test</title>
6
- </head>
7
- <body>
8
-
9
- <h1>EventSource test</h1>
10
- <ul></ul>
11
-
12
- <script type="text/javascript">
13
- var logger = document.getElementsByTagName('ul')[0],
14
- socket = new EventSource('/');
15
-
16
- var log = function(text) {
17
- logger.innerHTML += '<li>' + text + '</li>';
18
- };
19
-
20
- socket.onopen = function() {
21
- log('OPEN');
22
- };
23
-
24
- socket.onmessage = function(event) {
25
- log('MESSAGE: ' + event.data);
26
- };
27
-
28
- socket.addEventListener('update', function(event) {
29
- log('UPDATE(' + event.lastEventId + '): ' + event.data);
30
- });
31
-
32
- socket.onerror = function(event) {
33
- log('ERROR: ' + event.message);
34
- };
35
- </script>
36
-
37
- </body>
38
- </html>
@@ -1,43 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta http-equiv="Content-type" content="text/html; charset=utf-8">
5
- <title>WebSocket test</title>
6
- </head>
7
- <body>
8
-
9
- <h1>WebSocket test</h1>
10
- <ul></ul>
11
-
12
- <script type="text/javascript">
13
- var logger = document.getElementsByTagName('ul')[0],
14
- Socket = window.MozWebSocket || window.WebSocket,
15
- protos = ['foo', 'bar', 'xmpp'],
16
- socket = new Socket('ws://' + location.hostname + ':' + location.port + '/', protos),
17
- index = 0;
18
-
19
- var log = function(text) {
20
- logger.innerHTML += '<li>' + text + '</li>';
21
- };
22
-
23
- socket.addEventListener('open', function() {
24
- log('OPEN: ' + socket.protocol);
25
- socket.send('Hello, world');
26
- });
27
-
28
- socket.onerror = function(event) {
29
- log('ERROR: ' + event.message);
30
- };
31
-
32
- socket.onmessage = function(event) {
33
- log('MESSAGE: ' + event.data);
34
- setTimeout(function() { socket.send(++index + ' ' + event.data) }, 2000);
35
- };
36
-
37
- socket.onclose = function(event) {
38
- log('CLOSE: ' + event.code + ', ' + event.reason);
39
- };
40
- </script>
41
-
42
- </body>
43
- </html>