faye-websocket 0.10.5 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
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>