faye-websocket 0.10.9 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/LICENSE.md +12 -0
- data/README.md +34 -1
- data/lib/faye/websocket.rb +4 -3
- data/lib/faye/websocket/client.rb +39 -19
- data/lib/faye/websocket/ssl_verifier.rb +89 -0
- metadata +9 -17
- data/examples/app.rb +0 -54
- data/examples/autobahn_client.rb +0 -49
- data/examples/client.rb +0 -33
- data/examples/config.ru +0 -12
- data/examples/haproxy.conf +0 -20
- data/examples/proxy_server.rb +0 -13
- data/examples/rainbows.conf +0 -3
- data/examples/server.rb +0 -51
- data/examples/sse.html +0 -38
- data/examples/ws.html +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42cb4ec90fb1f2d1fd16739908d415035255136b33c1b8100f4370417d7afeee
|
4
|
+
data.tar.gz: b75409884d2ac82e84a59752027085106d1995e92d9603628400b13d7214bc4d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23293a16e2b1068bb1bd9a7c4e7516f9031185393e50d766833fe468bff7fb3b807d69015c022f35545cf41abb3e5ff9cf96282bb797ecba0eee60cea63de428
|
7
|
+
data.tar.gz: 46ac66a36431ee0adc04dbe5286499c38904b79e4da3259bb42c57c49ff97736568957da641fd640fedc237f67e258d06d5cbd0abb5d3d10eaf662f991368b67
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
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
|
+
|
1
8
|
### 0.10.9 / 2019-06-13
|
2
9
|
|
3
10
|
- Use the EventMachine API rather than `IO#write` to write data; this uses the
|
data/LICENSE.md
ADDED
@@ -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
@@ -198,6 +198,38 @@ is an optional hash containing any of these keys:
|
|
198
198
|
These are passed along to EventMachine and you can find
|
199
199
|
[more details here](http://rubydoc.info/gems/eventmachine/EventMachine%2FConnection%3Astart_tls)
|
200
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
|
+
|
201
233
|
## WebSocket API
|
202
234
|
|
203
235
|
Both the server- and client-side `WebSocket` objects support the following API:
|
@@ -206,7 +238,8 @@ Both the server- and client-side `WebSocket` objects support the following API:
|
|
206
238
|
Event has no attributes.
|
207
239
|
- **`on(:message) { |event| }`** fires when the socket receives a message. Event
|
208
240
|
has one attribute, **`data`**, which is either a `String` (for text frames) or
|
209
|
-
an `Array` of
|
241
|
+
an `Array` of unsigned integers, i.e. integers in the range `0..255` (for
|
242
|
+
binary frames).
|
210
243
|
- **`on(:error) { |event| }`** fires when there is a protocol error due to bad
|
211
244
|
data sent by the other peer. This event is purely informational, you do not
|
212
245
|
need to implement error recovery.
|
data/lib/faye/websocket.rb
CHANGED
@@ -17,9 +17,10 @@ module Faye
|
|
17
17
|
class WebSocket
|
18
18
|
root = File.expand_path('../websocket', __FILE__)
|
19
19
|
|
20
|
-
autoload :Adapter,
|
21
|
-
autoload :API,
|
22
|
-
autoload :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,
|
@@ -17,20 +17,18 @@ 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
|
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
25
|
configure_proxy(proxy)
|
27
26
|
|
28
|
-
EventMachine.connect(endpoint.host, port, Connection) do |conn|
|
27
|
+
EventMachine.connect(@endpoint.host, port, Connection) do |conn|
|
29
28
|
conn.parent = self
|
30
29
|
end
|
31
30
|
rescue => error
|
32
|
-
|
33
|
-
finalize_close
|
31
|
+
on_network_error(error)
|
34
32
|
end
|
35
33
|
|
36
34
|
private
|
@@ -46,31 +44,45 @@ module Faye
|
|
46
44
|
end
|
47
45
|
|
48
46
|
@proxy.on(:connect) do
|
49
|
-
uri = URI.parse(@url)
|
50
|
-
secure = SECURE_PROTOCOLS.include?(uri.scheme)
|
51
47
|
@proxy = nil
|
52
|
-
|
53
|
-
if secure
|
54
|
-
origin_tls = { :sni_hostname => uri.host }.merge(@origin_tls)
|
55
|
-
@stream.start_tls(origin_tls)
|
56
|
-
end
|
57
|
-
|
48
|
+
start_tls(URI.parse(@url), @origin_tls)
|
58
49
|
@driver.start
|
59
50
|
end
|
60
51
|
end
|
61
52
|
|
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
|
60
|
+
|
62
61
|
def on_connect(stream)
|
63
62
|
@stream = stream
|
64
|
-
|
65
|
-
if @secure
|
66
|
-
socket_tls = { :sni_hostname => URI.parse(@url).host }.merge(@socket_tls)
|
67
|
-
@stream.start_tls(socket_tls)
|
68
|
-
end
|
63
|
+
start_tls(@endpoint, @socket_tls)
|
69
64
|
|
70
65
|
worker = @proxy || @driver
|
71
66
|
worker.start
|
72
67
|
end
|
73
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
|
+
|
74
86
|
module Connection
|
75
87
|
attr_accessor :parent
|
76
88
|
|
@@ -78,6 +90,14 @@ module Faye
|
|
78
90
|
parent.__send__(:on_connect, self)
|
79
91
|
end
|
80
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
|
+
|
81
101
|
def receive_data(data)
|
82
102
|
parent.__send__(:parse, data)
|
83
103
|
end
|
@@ -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.
|
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:
|
11
|
+
date: 2020-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -178,7 +178,7 @@ dependencies:
|
|
178
178
|
- - ">="
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: 4.0.0
|
181
|
-
description:
|
181
|
+
description:
|
182
182
|
email: jcoglan@gmail.com
|
183
183
|
executables: []
|
184
184
|
extensions: []
|
@@ -186,17 +186,8 @@ extra_rdoc_files:
|
|
186
186
|
- README.md
|
187
187
|
files:
|
188
188
|
- CHANGELOG.md
|
189
|
+
- LICENSE.md
|
189
190
|
- README.md
|
190
|
-
- examples/app.rb
|
191
|
-
- examples/autobahn_client.rb
|
192
|
-
- examples/client.rb
|
193
|
-
- examples/config.ru
|
194
|
-
- examples/haproxy.conf
|
195
|
-
- examples/proxy_server.rb
|
196
|
-
- examples/rainbows.conf
|
197
|
-
- examples/server.rb
|
198
|
-
- examples/sse.html
|
199
|
-
- examples/ws.html
|
200
191
|
- lib/faye/adapters/goliath.rb
|
201
192
|
- lib/faye/adapters/rainbows.rb
|
202
193
|
- lib/faye/adapters/rainbows_client.rb
|
@@ -209,11 +200,12 @@ files:
|
|
209
200
|
- lib/faye/websocket/api/event.rb
|
210
201
|
- lib/faye/websocket/api/event_target.rb
|
211
202
|
- lib/faye/websocket/client.rb
|
203
|
+
- lib/faye/websocket/ssl_verifier.rb
|
212
204
|
homepage: https://github.com/faye/faye-websocket-ruby
|
213
205
|
licenses:
|
214
206
|
- Apache-2.0
|
215
207
|
metadata: {}
|
216
|
-
post_install_message:
|
208
|
+
post_install_message:
|
217
209
|
rdoc_options:
|
218
210
|
- "--main"
|
219
211
|
- README.md
|
@@ -232,8 +224,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
224
|
- !ruby/object:Gem::Version
|
233
225
|
version: '0'
|
234
226
|
requirements: []
|
235
|
-
rubygems_version: 3.
|
236
|
-
signing_key:
|
227
|
+
rubygems_version: 3.1.2
|
228
|
+
signing_key:
|
237
229
|
specification_version: 4
|
238
230
|
summary: Standards-compliant WebSocket server and client
|
239
231
|
test_files: []
|
data/examples/app.rb
DELETED
@@ -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
|
data/examples/autobahn_client.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
require 'cgi'
|
3
|
-
require 'faye/websocket'
|
4
|
-
require 'permessage_deflate'
|
5
|
-
require 'progressbar'
|
6
|
-
|
7
|
-
EM.run {
|
8
|
-
ruby = RUBY_PLATFORM =~ /java/ ? 'jruby' : 'mri-ruby'
|
9
|
-
version = defined?(RUBY_ENGINE_VERSION) ? RUBY_ENGINE_VERSION : RUBY_VERSION
|
10
|
-
version += " (#{ RUBY_VERSION })" if ruby == 'jruby'
|
11
|
-
|
12
|
-
host = 'ws://0.0.0.0:9001'
|
13
|
-
agent = CGI.escape("#{ ruby }-#{ version }")
|
14
|
-
cases = 0
|
15
|
-
options = { :extensions => [PermessageDeflate] }
|
16
|
-
|
17
|
-
socket = Faye::WebSocket::Client.new("#{ host }/getCaseCount")
|
18
|
-
progress = nil
|
19
|
-
|
20
|
-
socket.onmessage = lambda do |event|
|
21
|
-
puts "Total cases to run: #{ event.data }"
|
22
|
-
cases = event.data.to_i
|
23
|
-
progress = ProgressBar.create(:title => 'Autobahn', :total => cases)
|
24
|
-
end
|
25
|
-
|
26
|
-
run_case = lambda do |n|
|
27
|
-
if n > cases
|
28
|
-
socket = Faye::WebSocket::Client.new("#{ host }/updateReports?agent=#{ agent }")
|
29
|
-
socket.onclose = lambda { |e| EM.stop }
|
30
|
-
next
|
31
|
-
end
|
32
|
-
|
33
|
-
url = "#{ host }/runCase?case=#{ n }&agent=#{ agent }"
|
34
|
-
socket = Faye::WebSocket::Client.new(url, [], options)
|
35
|
-
|
36
|
-
socket.onmessage = lambda do |event|
|
37
|
-
socket.send(event.data)
|
38
|
-
end
|
39
|
-
|
40
|
-
socket.on :close do |event|
|
41
|
-
progress.increment
|
42
|
-
run_case[n + 1]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
socket.onclose = lambda do |event|
|
47
|
-
run_case[1]
|
48
|
-
end
|
49
|
-
}
|
data/examples/client.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
require 'faye/websocket'
|
3
|
-
require 'eventmachine'
|
4
|
-
require 'permessage_deflate'
|
5
|
-
|
6
|
-
EM.run {
|
7
|
-
url = ARGV[0]
|
8
|
-
proxy = ARGV[1]
|
9
|
-
|
10
|
-
ws = Faye::WebSocket::Client.new(url, [],
|
11
|
-
:proxy => { :origin => proxy, :headers => { 'User-Agent' => 'Echo' } },
|
12
|
-
:headers => { 'Origin' => 'http://faye.jcoglan.com' },
|
13
|
-
:extensions => [PermessageDeflate]
|
14
|
-
)
|
15
|
-
|
16
|
-
ws.onopen = lambda do |event|
|
17
|
-
p [:open, ws.headers]
|
18
|
-
ws.send('mic check')
|
19
|
-
end
|
20
|
-
|
21
|
-
ws.onclose = lambda do |close|
|
22
|
-
p [:close, close.code, close.reason]
|
23
|
-
EM.stop
|
24
|
-
end
|
25
|
-
|
26
|
-
ws.onerror = lambda do |error|
|
27
|
-
p [:error, error.message]
|
28
|
-
end
|
29
|
-
|
30
|
-
ws.onmessage = lambda do |message|
|
31
|
-
p [:message, message.data]
|
32
|
-
end
|
33
|
-
}
|
data/examples/config.ru
DELETED
@@ -1,12 +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 'bundler/setup'
|
7
|
-
require File.expand_path('../app', __FILE__)
|
8
|
-
|
9
|
-
Faye::WebSocket.load_adapter('thin')
|
10
|
-
Faye::WebSocket.load_adapter('rainbows')
|
11
|
-
|
12
|
-
run App
|
data/examples/haproxy.conf
DELETED
@@ -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
|
data/examples/proxy_server.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
require 'eventmachine'
|
3
|
-
require 'websocket/driver'
|
4
|
-
|
5
|
-
require File.expand_path('../../spec/proxy_server', __FILE__)
|
6
|
-
|
7
|
-
port = ARGV[0]
|
8
|
-
secure = ARGV[1] == 'tls'
|
9
|
-
|
10
|
-
EM.run {
|
11
|
-
proxy = ProxyServer.new(:debug => true)
|
12
|
-
proxy.listen(port, secure)
|
13
|
-
}
|
data/examples/rainbows.conf
DELETED
data/examples/server.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'bundler/setup'
|
2
|
-
require 'rack/content_length'
|
3
|
-
require 'rack/chunked'
|
4
|
-
|
5
|
-
port = ARGV[0] || 7000
|
6
|
-
secure = ARGV[1] == 'tls'
|
7
|
-
engine = ARGV[2] || 'thin'
|
8
|
-
spec = File.expand_path('../../spec', __FILE__)
|
9
|
-
|
10
|
-
require File.expand_path('../app', __FILE__)
|
11
|
-
Faye::WebSocket.load_adapter(engine)
|
12
|
-
|
13
|
-
case engine
|
14
|
-
|
15
|
-
when 'goliath'
|
16
|
-
class WebSocketServer < Goliath::API
|
17
|
-
def response(env)
|
18
|
-
App.call(env)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
when 'puma'
|
23
|
-
require 'puma/binder'
|
24
|
-
require 'puma/events'
|
25
|
-
events = Puma::Events.new($stdout, $stderr)
|
26
|
-
binder = Puma::Binder.new(events)
|
27
|
-
binder.parse(["tcp://0.0.0.0:#{ port }"], App)
|
28
|
-
server = Puma::Server.new(App, events)
|
29
|
-
server.binder = binder
|
30
|
-
server.run.join
|
31
|
-
|
32
|
-
when 'rainbows'
|
33
|
-
rackup = Unicorn::Configurator::RACKUP
|
34
|
-
rackup[:port] = port
|
35
|
-
rackup[:set_listener] = true
|
36
|
-
options = rackup[:options]
|
37
|
-
options[:config_file] = File.expand_path('../rainbows.conf', __FILE__)
|
38
|
-
Rainbows::HttpServer.new(App, options).start.join
|
39
|
-
|
40
|
-
when 'thin'
|
41
|
-
thin = Rack::Handler.get('thin')
|
42
|
-
thin.run(App, :Host => '0.0.0.0', :Port => port) do |server|
|
43
|
-
if secure
|
44
|
-
server.ssl_options = {
|
45
|
-
:private_key_file => spec + '/server.key',
|
46
|
-
:cert_chain_file => spec + '/server.crt'
|
47
|
-
}
|
48
|
-
server.ssl = true
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
data/examples/sse.html
DELETED
@@ -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>
|
data/examples/ws.html
DELETED
@@ -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>
|