faye-websocket 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of faye-websocket might be problematic. Click here for more details.
- data/CHANGELOG.txt +7 -0
- data/README.rdoc +27 -0
- data/examples/app.rb +1 -1
- data/lib/faye/eventsource.rb +13 -8
- data/lib/faye/websocket.rb +23 -8
- data/lib/faye/websocket/api.rb +35 -3
- data/lib/faye/websocket/draft75_parser.rb +4 -0
- data/lib/faye/websocket/draft76_parser.rb +6 -2
- data/lib/faye/websocket/hybi_parser.rb +18 -2
- data/spec/faye/websocket/draft75_parser_examples.rb +48 -0
- data/spec/faye/websocket/draft75_parser_spec.rb +0 -44
- data/spec/spec_helper.rb +1 -0
- metadata +15 -14
data/CHANGELOG.txt
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.4.0 / 2012-02-13
|
2
|
+
|
3
|
+
* Add ping() method to server-side WebSocket and EventSource
|
4
|
+
* Buffer send() calls until the draft-76 handshake is complete
|
5
|
+
* Fix HTTPS problems on Node 0.7
|
6
|
+
|
7
|
+
|
1
8
|
=== 0.3.0 / 2012-01-13
|
2
9
|
|
3
10
|
* Add support for EventSource connections
|
data/README.rdoc
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
= Faye::WebSocket
|
2
2
|
|
3
|
+
* Travis CI build: {<img src="https://secure.travis-ci.org/faye/faye-websocket-ruby.png" />}[http://travis-ci.org/faye/faye-websocket-ruby]
|
4
|
+
* Autobahn tests: {server}[http://faye.jcoglan.com/autobahn/servers/], {client}[http://faye.jcoglan.com/autobahn/clients/]
|
5
|
+
|
3
6
|
This is a robust, general-purpose WebSocket implementation extracted from the
|
4
7
|
{Faye}[http://faye.jcoglan.com] project. It provides classes for easily building
|
5
8
|
WebSocket servers and clients in Ruby. It does not provide a server itself, but
|
@@ -72,6 +75,26 @@ appropriate adapters automatically.
|
|
72
75
|
Faye::WebSocket.load_adapter('thin')
|
73
76
|
run App
|
74
77
|
|
78
|
+
Note that under certain circumstances (notably a draft-76 client connecting
|
79
|
+
through an HTTP proxy), the WebSocket handshake will not be complete after you
|
80
|
+
call `Faye::WebSocket.new` because the server will not have received the entire
|
81
|
+
handshake from the client yet. In this case, calls to `ws.send` will buffer the
|
82
|
+
message in memory until the handshake is complete, at which point any buffered
|
83
|
+
messages will be sent to the client.
|
84
|
+
|
85
|
+
If you need to detect when the WebSocket handshake is complete, you can use the
|
86
|
+
`onopen` event.
|
87
|
+
|
88
|
+
If the connection's protocol version supports it, you can call <tt>ws.ping()</tt>
|
89
|
+
to send a ping message and wait for the client's response. This method takes a
|
90
|
+
message string, and an optional callback that fires when a matching pong message
|
91
|
+
is received. It returns +true+ iff a ping message was sent. If the client does
|
92
|
+
not support ping/pong, this method sends no data and returns +false+.
|
93
|
+
|
94
|
+
ws.ping 'Mic check, one, two' do
|
95
|
+
# fires when pong is received
|
96
|
+
end
|
97
|
+
|
75
98
|
|
76
99
|
== Using the WebSocket client
|
77
100
|
|
@@ -206,6 +229,10 @@ retryable every 10 seconds if the connection is broken:
|
|
206
229
|
|
207
230
|
es = Faye::EventSource.new(es, :ping => 15, :retry => 10)
|
208
231
|
|
232
|
+
You can send a ping message at any time by calling <tt>es.ping()</tt>. Unlike
|
233
|
+
WebSocket the client does not send a response to this; it is merely to send some
|
234
|
+
data over the wire to keep the connection alive.
|
235
|
+
|
209
236
|
|
210
237
|
== Running your socket application
|
211
238
|
|
data/examples/app.rb
CHANGED
@@ -5,7 +5,7 @@ static = Rack::File.new(File.dirname(__FILE__))
|
|
5
5
|
|
6
6
|
App = lambda do |env|
|
7
7
|
if Faye::WebSocket.websocket?(env)
|
8
|
-
ws = Faye::WebSocket.new(env, ['irc', 'xmpp'])
|
8
|
+
ws = Faye::WebSocket.new(env, ['irc', 'xmpp'], :ping => 5)
|
9
9
|
p [:open, ws.url, ws.version, ws.protocol]
|
10
10
|
|
11
11
|
ws.onmessage = lambda do |event|
|
data/lib/faye/eventsource.rb
CHANGED
@@ -2,11 +2,9 @@ require File.expand_path('../websocket', __FILE__) unless defined?(Faye::WebSock
|
|
2
2
|
|
3
3
|
module Faye
|
4
4
|
class EventSource
|
5
|
-
DEFAULT_PING = 10
|
6
5
|
DEFAULT_RETRY = 5
|
7
6
|
|
8
|
-
include WebSocket::API
|
9
|
-
include WebSocket::API::ReadyStates
|
7
|
+
include WebSocket::API
|
10
8
|
attr_reader :env, :url, :ready_state
|
11
9
|
|
12
10
|
def self.eventsource?(env)
|
@@ -27,12 +25,14 @@ module Faye
|
|
27
25
|
|
28
26
|
def initialize(env, options = {})
|
29
27
|
@env = env
|
30
|
-
@ping = options[:ping]
|
28
|
+
@ping = options[:ping]
|
31
29
|
@retry = (options[:retry] || DEFAULT_RETRY).to_f
|
32
30
|
@url = EventSource.determine_url(env)
|
33
31
|
@stream = Stream.new(self)
|
34
32
|
|
35
33
|
@ready_state = CONNECTING
|
34
|
+
@send_buffer = []
|
35
|
+
EventMachine.next_tick { open }
|
36
36
|
|
37
37
|
callback = @env['async.callback']
|
38
38
|
callback.call([101, {}, @stream])
|
@@ -43,11 +43,11 @@ module Faye
|
|
43
43
|
"\r\n\r\n" +
|
44
44
|
"retry: #{ (@retry * 1000).floor }\r\n\r\n")
|
45
45
|
|
46
|
-
@ping_timer = EventMachine.add_periodic_timer(@ping) do
|
47
|
-
@stream.write(":\r\n\r\n")
|
48
|
-
end
|
49
|
-
|
50
46
|
@ready_state = OPEN
|
47
|
+
|
48
|
+
if @ping
|
49
|
+
@ping_timer = EventMachine.add_periodic_timer(@ping) { ping }
|
50
|
+
end
|
51
51
|
end
|
52
52
|
|
53
53
|
def last_event_id
|
@@ -73,6 +73,11 @@ module Faye
|
|
73
73
|
true
|
74
74
|
end
|
75
75
|
|
76
|
+
def ping(message = nil)
|
77
|
+
@stream.write(":\r\n\r\n")
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
76
81
|
def close
|
77
82
|
return if [CLOSING, CLOSED].include?(@ready_state)
|
78
83
|
@ready_state = CLOSED
|
data/lib/faye/websocket.rb
CHANGED
@@ -91,9 +91,11 @@ module Faye
|
|
91
91
|
attr_reader :env
|
92
92
|
include API
|
93
93
|
|
94
|
-
def initialize(env, supported_protos = nil)
|
95
|
-
@env
|
96
|
-
@stream
|
94
|
+
def initialize(env, supported_protos = nil, options = {})
|
95
|
+
@env = env
|
96
|
+
@stream = Stream.new(self)
|
97
|
+
@ping = options[:ping]
|
98
|
+
@ping_id = 0
|
97
99
|
|
98
100
|
@url = WebSocket.determine_url(@env)
|
99
101
|
@ready_state = CONNECTING
|
@@ -101,15 +103,26 @@ module Faye
|
|
101
103
|
|
102
104
|
@parser = WebSocket.parser(@env).new(self, :protocols => supported_protos)
|
103
105
|
|
106
|
+
@send_buffer = []
|
107
|
+
EventMachine.next_tick { open }
|
108
|
+
|
104
109
|
@callback = @env['async.callback']
|
105
110
|
@callback.call([101, {}, @stream])
|
106
111
|
@stream.write(@parser.handshake_response)
|
107
112
|
|
108
|
-
@ready_state = OPEN
|
113
|
+
@ready_state = OPEN if @parser.open?
|
109
114
|
|
110
|
-
|
111
|
-
|
112
|
-
|
115
|
+
if @ping
|
116
|
+
@ping_timer = EventMachine.add_periodic_timer(@ping) do
|
117
|
+
@ping_id += 1
|
118
|
+
ping(@ping_id.to_s)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def ping(message = '', &callback)
|
124
|
+
return false unless @parser.respond_to?(:ping)
|
125
|
+
@parser.ping(message, &callback)
|
113
126
|
end
|
114
127
|
|
115
128
|
def protocol
|
@@ -124,7 +137,9 @@ module Faye
|
|
124
137
|
|
125
138
|
def parse(data)
|
126
139
|
response = @parser.parse(data)
|
127
|
-
|
140
|
+
return unless response
|
141
|
+
@stream.write(response)
|
142
|
+
open
|
128
143
|
end
|
129
144
|
end
|
130
145
|
|
data/lib/faye/websocket/api.rb
CHANGED
@@ -9,6 +9,9 @@ module Faye
|
|
9
9
|
CLOSED = 3
|
10
10
|
end
|
11
11
|
|
12
|
+
class IllegalStateError < StandardError
|
13
|
+
end
|
14
|
+
|
12
15
|
require File.expand_path('../api/event_target', __FILE__)
|
13
16
|
require File.expand_path('../api/event', __FILE__)
|
14
17
|
include EventTarget
|
@@ -16,8 +19,26 @@ module Faye
|
|
16
19
|
|
17
20
|
attr_reader :url, :ready_state, :buffered_amount
|
18
21
|
|
22
|
+
private
|
23
|
+
|
24
|
+
def open
|
25
|
+
return if @parser and not @parser.open?
|
26
|
+
@ready_state = OPEN
|
27
|
+
|
28
|
+
buffer = @send_buffer || []
|
29
|
+
while message = buffer.shift
|
30
|
+
send(*message)
|
31
|
+
end
|
32
|
+
|
33
|
+
event = Event.new('open')
|
34
|
+
event.init_event('open', false, false)
|
35
|
+
dispatch_event(event)
|
36
|
+
end
|
37
|
+
|
38
|
+
public
|
39
|
+
|
19
40
|
def receive(data)
|
20
|
-
return false unless ready_state == OPEN
|
41
|
+
return false unless @ready_state == OPEN
|
21
42
|
event = Event.new('message')
|
22
43
|
event.init_event('message', false, false)
|
23
44
|
event.data = data
|
@@ -25,19 +46,30 @@ module Faye
|
|
25
46
|
end
|
26
47
|
|
27
48
|
def send(data, type = nil, error_type = nil)
|
28
|
-
|
49
|
+
if @ready_state == CONNECTING
|
50
|
+
if @send_buffer
|
51
|
+
@send_buffer << [data, type, error_type]
|
52
|
+
return true
|
53
|
+
else
|
54
|
+
raise IllegalStateError, 'Cannot call send(), socket is not open yet'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
return false if @ready_state == CLOSED
|
59
|
+
|
29
60
|
data = WebSocket.encode(data) if String === data
|
30
61
|
frame = @parser.frame(data, type, error_type)
|
31
62
|
@stream.write(frame) if frame
|
32
63
|
end
|
33
64
|
|
34
65
|
def close(code = nil, reason = nil, ack = true)
|
35
|
-
return if [CLOSING, CLOSED].include?(ready_state)
|
66
|
+
return if [CLOSING, CLOSED].include?(@ready_state)
|
36
67
|
|
37
68
|
@ready_state = CLOSING
|
38
69
|
|
39
70
|
close = lambda do
|
40
71
|
@ready_state = CLOSED
|
72
|
+
EventMachine.cancel_timer(@ping_timer) if @ping_timer
|
41
73
|
@stream.close_connection_after_writing
|
42
74
|
event = Event.new('close', :code => code || 1000, :reason => reason || '')
|
43
75
|
event.init_event('close', false, false)
|
@@ -22,8 +22,6 @@ module Faye
|
|
22
22
|
|
23
23
|
def handshake_signature(head)
|
24
24
|
return nil if head.empty?
|
25
|
-
@handshake_complete = true
|
26
|
-
|
27
25
|
env = @socket.env
|
28
26
|
|
29
27
|
key1 = env['HTTP_SEC_WEBSOCKET_KEY1']
|
@@ -32,11 +30,17 @@ module Faye
|
|
32
30
|
key2 = env['HTTP_SEC_WEBSOCKET_KEY2']
|
33
31
|
value2 = number_from_key(key2) / spaces_in_key(key2)
|
34
32
|
|
33
|
+
@handshake_complete = true
|
34
|
+
|
35
35
|
Digest::MD5.digest(big_endian(value1) +
|
36
36
|
big_endian(value2) +
|
37
37
|
head)
|
38
38
|
end
|
39
39
|
|
40
|
+
def open?
|
41
|
+
!!@handshake_complete
|
42
|
+
end
|
43
|
+
|
40
44
|
def parse(data)
|
41
45
|
return super if @handshake_complete
|
42
46
|
handshake_signature(data)
|
@@ -48,8 +48,9 @@ module Faye
|
|
48
48
|
@stage = 0
|
49
49
|
@masking = options[:masking]
|
50
50
|
@protocols = options[:protocols]
|
51
|
-
|
52
51
|
@protocols = @protocols.split(/\s*,\s*/) if String === @protocols
|
52
|
+
|
53
|
+
@ping_callbacks = {}
|
53
54
|
end
|
54
55
|
|
55
56
|
def version
|
@@ -87,7 +88,11 @@ module Faye
|
|
87
88
|
def create_handshake
|
88
89
|
Handshake.new(@socket.uri, @protocols)
|
89
90
|
end
|
90
|
-
|
91
|
+
|
92
|
+
def open?
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
91
96
|
def parse(data)
|
92
97
|
@reader.put(data.bytes.to_a)
|
93
98
|
buffer = true
|
@@ -172,6 +177,11 @@ module Faye
|
|
172
177
|
|
173
178
|
WebSocket.encode(frame)
|
174
179
|
end
|
180
|
+
|
181
|
+
def ping(message = '', &callback)
|
182
|
+
@ping_callbacks[message] = callback if callback
|
183
|
+
@socket.send(message, :ping)
|
184
|
+
end
|
175
185
|
|
176
186
|
def close(code = nil, reason = nil, &callback)
|
177
187
|
return if @closed
|
@@ -283,6 +293,12 @@ module Faye
|
|
283
293
|
when OPCODES[:ping] then
|
284
294
|
return @socket.close(ERRORS[:protocol_error], nil, false) if payload.size > 125
|
285
295
|
@socket.send(payload, :pong)
|
296
|
+
|
297
|
+
when OPCODES[:pong] then
|
298
|
+
message = WebSocket.encode(payload, true)
|
299
|
+
callback = @ping_callbacks[message]
|
300
|
+
@ping_callbacks.delete(message)
|
301
|
+
callback.call if callback
|
286
302
|
end
|
287
303
|
end
|
288
304
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding=utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "draft-75 parser" do
|
6
|
+
it "parses text frames" do
|
7
|
+
@web_socket.should_receive(:receive).with("Hello")
|
8
|
+
parse [0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "parses multiple frames from the same packet" do
|
12
|
+
@web_socket.should_receive(:receive).with("Hello").exactly(2)
|
13
|
+
parse [0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "parses text frames beginning 0x00-0x7F" do
|
17
|
+
@web_socket.should_receive(:receive).with("Hello")
|
18
|
+
parse [0x66, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "ignores frames with a length header" do
|
22
|
+
@web_socket.should_not_receive(:receive)
|
23
|
+
parse [0x80, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "parses text following an ignored block" do
|
27
|
+
@web_socket.should_receive(:receive).with("Hello")
|
28
|
+
parse [0x80, 0x02, 0x48, 0x65, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "parses multibyte text frames" do
|
32
|
+
@web_socket.should_receive(:receive).with(encode "Apple = ")
|
33
|
+
parse [0x00, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "parses frames received in several packets" do
|
37
|
+
@web_socket.should_receive(:receive).with(encode "Apple = ")
|
38
|
+
parse [0x00, 0x41, 0x70, 0x70, 0x6c, 0x65]
|
39
|
+
parse [0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff]
|
40
|
+
end
|
41
|
+
|
42
|
+
it "parses fragmented frames" do
|
43
|
+
@web_socket.should_receive(:receive).with("Hello")
|
44
|
+
parse [0x00, 0x48, 0x65, 0x6c]
|
45
|
+
parse [0x6c, 0x6f, 0xff]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -11,50 +11,6 @@ describe Faye::WebSocket::Draft75Parser do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe :parse do
|
14
|
-
shared_examples_for "draft-75 parser" do
|
15
|
-
it "parses text frames" do
|
16
|
-
@web_socket.should_receive(:receive).with("Hello")
|
17
|
-
parse [0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
18
|
-
end
|
19
|
-
|
20
|
-
it "parses multiple frames from the same packet" do
|
21
|
-
@web_socket.should_receive(:receive).with("Hello").exactly(2)
|
22
|
-
parse [0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
23
|
-
end
|
24
|
-
|
25
|
-
it "parses text frames beginning 0x00-0x7F" do
|
26
|
-
@web_socket.should_receive(:receive).with("Hello")
|
27
|
-
parse [0x66, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
28
|
-
end
|
29
|
-
|
30
|
-
it "ignores frames with a length header" do
|
31
|
-
@web_socket.should_not_receive(:receive)
|
32
|
-
parse [0x80, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]
|
33
|
-
end
|
34
|
-
|
35
|
-
it "parses text following an ignored block" do
|
36
|
-
@web_socket.should_receive(:receive).with("Hello")
|
37
|
-
parse [0x80, 0x02, 0x48, 0x65, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]
|
38
|
-
end
|
39
|
-
|
40
|
-
it "parses multibyte text frames" do
|
41
|
-
@web_socket.should_receive(:receive).with(encode "Apple = ")
|
42
|
-
parse [0x00, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff]
|
43
|
-
end
|
44
|
-
|
45
|
-
it "parses frames received in several packets" do
|
46
|
-
@web_socket.should_receive(:receive).with(encode "Apple = ")
|
47
|
-
parse [0x00, 0x41, 0x70, 0x70, 0x6c, 0x65]
|
48
|
-
parse [0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff]
|
49
|
-
end
|
50
|
-
|
51
|
-
it "parses fragmented frames" do
|
52
|
-
@web_socket.should_receive(:receive).with("Hello")
|
53
|
-
parse [0x00, 0x48, 0x65, 0x6c]
|
54
|
-
parse [0x6c, 0x6f, 0xff]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
14
|
it_should_behave_like "draft-75 parser"
|
59
15
|
end
|
60
16
|
|
data/spec/spec_helper.rb
CHANGED
@@ -4,6 +4,7 @@ require 'thin'
|
|
4
4
|
require 'rainbows'
|
5
5
|
require File.expand_path('../../lib/faye/websocket', __FILE__)
|
6
6
|
require File.expand_path('../../vendor/em-rspec/lib/em-rspec', __FILE__)
|
7
|
+
require File.expand_path('../faye/websocket/draft75_parser_examples', __FILE__)
|
7
8
|
|
8
9
|
Thin::Logging.silent = true
|
9
10
|
Unicorn::Configurator::DEFAULTS[:logger] = Logger.new(StringIO.new)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faye-websocket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-02-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement: &
|
16
|
+
requirement: &21030040 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.12.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *21030040
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rack
|
27
|
-
requirement: &
|
27
|
+
requirement: &21055040 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *21055040
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rainbows
|
38
|
-
requirement: &
|
38
|
+
requirement: &21054500 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.0.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *21054500
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rspec
|
49
|
-
requirement: &
|
49
|
+
requirement: &21054000 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 2.8.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *21054000
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake-compiler
|
60
|
-
requirement: &
|
60
|
+
requirement: &21053620 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *21053620
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: thin
|
71
|
-
requirement: &
|
71
|
+
requirement: &21053080 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: 1.2.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *21053080
|
80
80
|
description:
|
81
81
|
email: jcoglan@gmail.com
|
82
82
|
executables: []
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- examples/autobahn_client.rb
|
116
116
|
- spec/faye/websocket/draft75_parser_spec.rb
|
117
117
|
- spec/faye/websocket/client_spec.rb
|
118
|
+
- spec/faye/websocket/draft75_parser_examples.rb
|
118
119
|
- spec/faye/websocket/draft76_parser_spec.rb
|
119
120
|
- spec/faye/websocket/hybi_parser_spec.rb
|
120
121
|
- spec/server.key
|