em-websocket 0.3.2 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,5 +1,10 @@
1
1
  = Changelog
2
2
 
3
+ == 0.3.5 / 2011-10-24
4
+
5
+ - new features:
6
+ - Support WebSocket draft 13
7
+
3
8
  == 0.3.2 / 2011-10-09
4
9
 
5
10
  - bugfixes:
@@ -0,0 +1,21 @@
1
+ # Super simple flash policy file server
2
+ # See https://github.com/igrigorik/em-websocket/issues/61
3
+
4
+ require 'eventmachine'
5
+
6
+ module FlashPolicy
7
+ def post_init
8
+ cross_domain_xml =<<-EOF
9
+ <cross-domain-policy>
10
+ <allow-access-from domain="*" to-ports="*" />
11
+ </cross-domain-policy>
12
+ EOF
13
+
14
+ send_data cross_domain_xml
15
+ close_connection_after_writing
16
+ end
17
+ end
18
+
19
+ EM.run {
20
+ EventMachine::start_server '0.0.0.0', 843, FlashPolicy
21
+ }
@@ -1,4 +1,5 @@
1
- require 'lib/em-websocket'
1
+ require 'em-websocket'
2
+ # requires the twitter-stream gem
2
3
  require 'twitter/json_stream'
3
4
  require 'json'
4
5
 
@@ -15,7 +16,8 @@ EventMachine.run {
15
16
 
16
17
  @twitter = Twitter::JSONStream.connect(
17
18
  :path => '/1/statuses/filter.json?track=ruby',
18
- :auth => "#{username}:#{password}"
19
+ :auth => "#{username}:#{password}",
20
+ :ssl => true
19
21
  )
20
22
 
21
23
  @twitter.each_item do |status|
@@ -37,8 +39,8 @@ EventMachine.run {
37
39
  ws.onclose {
38
40
  @channel.unsubscribe(sid)
39
41
  }
40
-
41
42
  }
43
+
42
44
  end
43
45
 
44
46
  puts "Server started"
data/lib/em-websocket.rb CHANGED
@@ -9,7 +9,7 @@ require "eventmachine"
9
9
  close75 close03 close05 close06
10
10
  masking04
11
11
  message_processor_03 message_processor_06
12
- handler_factory handler handler75 handler76 handler03 handler05 handler06 handler07 handler08
12
+ handler_factory handler handler75 handler76 handler03 handler05 handler06 handler07 handler08 handler13
13
13
  ].each do |file|
14
14
  require "em-websocket/#{file}"
15
15
  end
@@ -0,0 +1,10 @@
1
+ module EventMachine
2
+ module WebSocket
3
+ class Handler13 < Handler
4
+ include Handshake04
5
+ include Framing07
6
+ include MessageProcessor06
7
+ include Close06
8
+ end
9
+ end
10
+ end
@@ -90,7 +90,13 @@ module EventMachine
90
90
  when 7
91
91
  Handler07.new(connection, request, debug)
92
92
  when 8
93
+ # drafts 9, 10, 11 and 12 should never change the version
94
+ # number as they are all the same as version 08.
93
95
  Handler08.new(connection, request, debug)
96
+ when 13
97
+ # drafts 13 to 17 all identify as version 13 as they are
98
+ # only minor changes or text changes.
99
+ Handler13.new(connection, request, debug)
94
100
  else
95
101
  # According to spec should abort the connection
96
102
  raise WebSocketError, "Protocol version #{version} not supported"
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module Websocket
3
- VERSION = "0.3.2"
3
+ VERSION = "0.3.5"
4
4
  end
5
5
  end
data/spec/helper.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'rspec'
3
+ require 'em-spec/rspec'
3
4
  require 'pp'
4
5
  require 'em-http'
5
6
 
@@ -68,6 +69,32 @@ class Draft03FakeWebSocketClient < FakeWebSocketClient
68
69
  end
69
70
  end
70
71
 
72
+ class Draft07FakeWebSocketClient < FakeWebSocketClient
73
+ def send(application_data)
74
+ frame = ''
75
+ opcode = 1 # fake only supports text frames
76
+ byte1 = opcode | 0b10000000 # since more, rsv1-3 are 0
77
+ frame << byte1
78
+
79
+ length = application_data.size
80
+ if length <= 125
81
+ byte2 = length # since rsv4 is 0
82
+ frame << byte2
83
+ elsif length < 65536 # write 2 byte length
84
+ frame << 126
85
+ frame << [length].pack('n')
86
+ else # write 8 byte length
87
+ frame << 127
88
+ frame << [length >> 32, length & 0xFFFFFFFF].pack("NN")
89
+ end
90
+
91
+ frame << application_data
92
+
93
+ send_data(frame)
94
+ end
95
+ end
96
+
97
+
71
98
  # Wrap EM:HttpRequest in a websocket like interface so that it can be used in the specs with the same interface as FakeWebSocketClient
72
99
  class Draft75WebSocketClient
73
100
  def onopen(&blk); @onopen = blk; end
@@ -91,11 +118,6 @@ class Draft75WebSocketClient
91
118
  end
92
119
  end
93
120
 
94
- def failed
95
- EventMachine.stop
96
- fail
97
- end
98
-
99
121
  def format_request(r)
100
122
  data = "#{r[:method]} #{r[:path]} HTTP/1.1\r\n"
101
123
  header_lines = r[:headers].map { |k,v| "#{k}: #{v}" }
@@ -3,23 +3,26 @@ require 'helper'
3
3
  # These tests are not specifi to any particular draft of the specification
4
4
  #
5
5
  describe "WebSocket server" do
6
+ include EM::SpecHelper
7
+ default_timeout 1
8
+
6
9
  it "should fail on non WebSocket requests" do
7
- EM.run do
10
+ em {
8
11
  EventMachine.add_timer(0.1) do
9
12
  http = EventMachine::HttpRequest.new('http://127.0.0.1:12345/').get :timeout => 0
10
- http.errback { EM.stop }
11
- http.callback { failed }
13
+ http.errback { done }
14
+ http.callback { fail }
12
15
  end
13
16
 
14
17
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) {}
15
- end
18
+ }
16
19
  end
17
20
 
18
21
  it "should populate ws.request with appropriate headers" do
19
- EM.run do
22
+ em {
20
23
  EventMachine.add_timer(0.1) do
21
24
  http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
22
- http.errback { failed }
25
+ http.errback { fail }
23
26
  http.callback {
24
27
  http.response_header.status.should == 101
25
28
  http.close_connection
@@ -41,14 +44,14 @@ describe "WebSocket server" do
41
44
  EventMachine.stop
42
45
  }
43
46
  end
44
- end
47
+ }
45
48
  end
46
49
 
47
50
  it "should allow sending and retrieving query string args passed in on the connection request." do
48
- EM.run do
51
+ em {
49
52
  EventMachine.add_timer(0.1) do
50
53
  http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get(:query => {'foo' => 'bar', 'baz' => 'qux'}, :timeout => 0)
51
- http.errback { failed }
54
+ http.errback { fail }
52
55
  http.callback {
53
56
  http.response_header.status.should == 101
54
57
  http.close_connection
@@ -69,14 +72,14 @@ describe "WebSocket server" do
69
72
  EventMachine.stop
70
73
  }
71
74
  end
72
- end
75
+ }
73
76
  end
74
77
 
75
78
  it "should ws.response['Query'] to empty hash when no query string params passed in connection URI" do
76
- EM.run do
79
+ em {
77
80
  EventMachine.add_timer(0.1) do
78
81
  http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get(:timeout => 0)
79
- http.errback { failed }
82
+ http.errback { fail }
80
83
  http.callback {
81
84
  http.response_header.status.should == 101
82
85
  http.close_connection
@@ -94,18 +97,18 @@ describe "WebSocket server" do
94
97
  EventMachine.stop
95
98
  }
96
99
  end
97
- end
100
+ }
98
101
  end
99
102
 
100
103
  it "should raise an exception if frame sent before handshake complete" do
101
- EM.run {
104
+ em {
102
105
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |c|
103
106
  # We're not using a real client so the handshake will not be sent
104
107
  EM.add_timer(0.1) {
105
108
  lambda {
106
109
  c.send('early message')
107
110
  }.should raise_error('Cannot send data before onopen callback')
108
- EM.stop
111
+ done
109
112
  }
110
113
  }
111
114
 
@@ -2,6 +2,9 @@ require 'helper'
2
2
  require 'integration/shared_examples'
3
3
 
4
4
  describe "draft03" do
5
+ include EM::SpecHelper
6
+ default_timeout 1
7
+
5
8
  before :each do
6
9
  @request = {
7
10
  :port => 80,
@@ -50,11 +53,11 @@ describe "draft03" do
50
53
  # http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-03#section-4.6
51
54
  describe "examples from the spec" do
52
55
  it "should accept a single-frame text message" do
53
- EM.run do
56
+ em {
54
57
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
55
58
  ws.onmessage { |msg|
56
59
  msg.should == 'Hello'
57
- EM.stop
60
+ done
58
61
  }
59
62
  }
60
63
 
@@ -66,15 +69,15 @@ describe "draft03" do
66
69
  connection.onopen {
67
70
  connection.send_data("\x04\x05Hello")
68
71
  }
69
- end
72
+ }
70
73
  end
71
74
 
72
75
  it "should accept a fragmented text message" do
73
- EM.run do
76
+ em {
74
77
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
75
78
  ws.onmessage { |msg|
76
79
  msg.should == 'Hello'
77
- EM.stop
80
+ done
78
81
  }
79
82
  }
80
83
 
@@ -87,11 +90,11 @@ describe "draft03" do
87
90
  connection.send_data("\x84\x03Hel")
88
91
  connection.send_data("\x00\x02lo")
89
92
  }
90
- end
93
+ }
91
94
  end
92
95
 
93
96
  it "should accept a ping request and respond with the same body" do
94
- EM.run do
97
+ em {
95
98
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws| }
96
99
 
97
100
  # Create a fake client which sends draft 76 handshake
@@ -106,19 +109,19 @@ describe "draft03" do
106
109
  connection.onmessage { |frame|
107
110
  next if frame.nil?
108
111
  frame.should == "\x03\x05Hello"
109
- EM.stop
112
+ done
110
113
  }
111
- end
114
+ }
112
115
  end
113
116
 
114
117
  it "should accept a 256 bytes binary message in a single frame" do
115
- EM.run do
118
+ em {
116
119
  data = "a" * 256
117
120
 
118
121
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
119
122
  ws.onmessage { |msg|
120
123
  msg.should == data
121
- EM.stop
124
+ done
122
125
  }
123
126
  }
124
127
 
@@ -130,17 +133,17 @@ describe "draft03" do
130
133
  connection.onopen {
131
134
  connection.send_data("\x05\x7E\x01\x00" + data)
132
135
  }
133
- end
136
+ }
134
137
  end
135
138
 
136
139
  it "should accept a 64KiB binary message in a single frame" do
137
- EM.run do
140
+ em {
138
141
  data = "a" * 65536
139
142
 
140
143
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
141
144
  ws.onmessage { |msg|
142
145
  msg.should == data
143
- EM.stop
146
+ done
144
147
  }
145
148
  }
146
149
 
@@ -152,13 +155,13 @@ describe "draft03" do
152
155
  connection.onopen {
153
156
  connection.send_data("\x05\x7F\x00\x00\x00\x00\x00\x01\x00\x00" + data)
154
157
  }
155
- end
158
+ }
156
159
  end
157
160
  end
158
161
 
159
162
  describe "close handling" do
160
163
  it "should respond to a new close frame with a close frame" do
161
- EM.run do
164
+ em {
162
165
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws| }
163
166
 
164
167
  # Create a fake client which sends draft 76 handshake
@@ -173,13 +176,13 @@ describe "draft03" do
173
176
  # Check that close ack received
174
177
  connection.onmessage { |frame|
175
178
  frame.should == "\x01\x00"
176
- EM.stop
179
+ done
177
180
  }
178
- end
181
+ }
179
182
  end
180
183
 
181
184
  it "should close the connection on receiving a close acknowlegement" do
182
- EM.run do
185
+ em {
183
186
  ack_received = false
184
187
 
185
188
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
@@ -205,13 +208,13 @@ describe "draft03" do
205
208
  # 4. Check that connection is closed _after_ the ack
206
209
  connection.onclose {
207
210
  ack_received.should == true
208
- EM.stop
211
+ done
209
212
  }
210
- end
213
+ }
211
214
  end
212
215
 
213
216
  it "should not allow data frame to be sent after close frame sent" do
214
- EM.run {
217
+ em {
215
218
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
216
219
  ws.onopen {
217
220
  # 2. Send a close frame
@@ -224,7 +227,7 @@ describe "draft03" do
224
227
  lambda {
225
228
  ws.send('hello world')
226
229
  }.should raise_error(EM::WebSocket::WebSocketError, 'Cannot send data frame since connection is closing')
227
- EM.stop
230
+ done
228
231
  }
229
232
  }
230
233
  }
@@ -236,7 +239,7 @@ describe "draft03" do
236
239
  end
237
240
 
238
241
  it "should still respond to control frames after close frame sent" do
239
- EM.run {
242
+ em {
240
243
  EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
241
244
  ws.onopen {
242
245
  # 2. Send a close frame
@@ -258,7 +261,7 @@ describe "draft03" do
258
261
  else
259
262
  # 4. Check that the pong is received
260
263
  frame.should == "\x03\x05Hello"
261
- EM.stop
264
+ done
262
265
  end
263
266
  }
264
267
  }
@@ -1,6 +1,9 @@
1
1
  require 'helper'
2
2
 
3
3
  describe "draft05" do
4
+ include EM::SpecHelper
5
+ default_timeout 1
6
+
4
7
  before :each do
5
8
  @request = {
6
9
  :port => 80,
@@ -31,11 +34,11 @@ describe "draft05" do
31
34
  end
32
35
 
33
36
  it "should open connection" do
34
- EM.run {
37
+ em {
35
38
  start_server { |server|
36
39
  server.onopen {
37
40
  server.instance_variable_get(:@handler).class.should == EventMachine::WebSocket::Handler05
38
- EM.stop
41
+ done
39
42
  }
40
43
  }
41
44
 
@@ -1,6 +1,9 @@
1
1
  require 'helper'
2
2
 
3
3
  describe "draft06" do
4
+ include EM::SpecHelper
5
+ default_timeout 1
6
+
4
7
  before :each do
5
8
  @request = {
6
9
  :port => 80,
@@ -40,7 +43,7 @@ describe "draft06" do
40
43
  end
41
44
 
42
45
  it "should open connection" do
43
- EM.run {
46
+ em {
44
47
  start_server { |server|
45
48
  server.onopen {
46
49
  server.instance_variable_get(:@handler).class.should == EventMachine::WebSocket::Handler06
@@ -51,22 +54,24 @@ describe "draft06" do
51
54
  client.onopen {
52
55
  client.handshake_response.lines.sort.
53
56
  should == format_response(@response).lines.sort
54
- EM.stop
57
+ done
55
58
  }
56
59
  }
57
60
  }
58
61
  end
59
62
 
60
63
  it "should accept a single-frame text message (masked)" do
61
- EM.run do
64
+ em {
62
65
  start_server { |server|
63
66
  server.onmessage { |msg|
64
67
  msg.should == 'Hello'
65
- msg.encoding.should == Encoding.find("UTF-8")
66
- EM.stop
68
+ if msg.respond_to?(:encoding)
69
+ msg.encoding.should == Encoding.find("UTF-8")
70
+ end
71
+ done
67
72
  }
68
73
  server.onerror {
69
- failed
74
+ fail
70
75
  }
71
76
  }
72
77
 
@@ -75,6 +80,6 @@ describe "draft06" do
75
80
  client.send_data("\x00\x00\x01\x00\x84\x05Ielln")
76
81
  }
77
82
  }
78
- end
83
+ }
79
84
  end
80
85
  end
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+ require 'integration/shared_examples'
3
+
4
+ describe "draft13" do
5
+ include EM::SpecHelper
6
+ default_timeout 1
7
+
8
+ before :each do
9
+ @request = {
10
+ :port => 80,
11
+ :method => "GET",
12
+ :path => "/demo",
13
+ :headers => {
14
+ 'Host' => 'example.com',
15
+ 'Upgrade' => 'websocket',
16
+ 'Connection' => 'Upgrade',
17
+ 'Sec-WebSocket-Key' => 'dGhlIHNhbXBsZSBub25jZQ==',
18
+ 'Sec-WebSocket-Protocol' => 'sample',
19
+ 'Sec-WebSocket-Origin' => 'http://example.com',
20
+ 'Sec-WebSocket-Version' => '13'
21
+ }
22
+ }
23
+
24
+ @response = {
25
+ :protocol => "HTTP/1.1 101 Switching Protocols\r\n",
26
+ :headers => {
27
+ "Upgrade" => "websocket",
28
+ "Connection" => "Upgrade",
29
+ "Sec-WebSocket-Accept" => "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
30
+ }
31
+ }
32
+ end
33
+
34
+ it_behaves_like "a websocket server" do
35
+ def start_server
36
+ EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
37
+ yield ws
38
+ }
39
+ end
40
+
41
+ def start_client
42
+ client = EM.connect('0.0.0.0', 12345, Draft07FakeWebSocketClient)
43
+ client.send_data(format_request(@request))
44
+ yield client if block_given?
45
+ end
46
+ end
47
+
48
+ it "should send back the correct handshake response" do
49
+ em {
50
+ EM.add_timer(0.1) do
51
+ EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
52
+
53
+ # Create a fake client which sends draft 07 handshake
54
+ connection = EM.connect('0.0.0.0', 12345, Draft07FakeWebSocketClient)
55
+ connection.send_data(format_request(@request))
56
+
57
+ connection.onopen {
58
+ connection.handshake_response.lines.sort.
59
+ should == format_response(@response).lines.sort
60
+ done
61
+ }
62
+ end
63
+ }
64
+ end
65
+ end
@@ -6,6 +6,8 @@ require 'integration/shared_examples'
6
6
  # to currently estabish a websocket connection using the draft75 protocol.
7
7
  #
8
8
  describe "WebSocket server draft75" do
9
+ include EM::SpecHelper
10
+ default_timeout 1
9
11
 
10
12
  it_behaves_like "a websocket server" do
11
13
  def start_server
@@ -21,11 +23,11 @@ describe "WebSocket server draft75" do
21
23
  end
22
24
 
23
25
  it "should automatically complete WebSocket handshake" do
24
- EM.run do
26
+ em {
25
27
  MSG = "Hello World!"
26
28
  EventMachine.add_timer(0.1) do
27
29
  http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
28
- http.errback { failed }
30
+ http.errback { fail }
29
31
  http.callback { http.response_header.status.should == 101 }
30
32
 
31
33
  http.stream { |msg|
@@ -39,17 +41,17 @@ describe "WebSocket server draft75" do
39
41
  ws.send MSG
40
42
  }
41
43
  end
42
- end
44
+ }
43
45
  end
44
46
 
45
47
  it "should split multiple messages into separate callbacks" do
46
- EM.run do
48
+ em {
47
49
  messages = %w[1 2]
48
50
  received = []
49
51
 
50
52
  EventMachine.add_timer(0.1) do
51
53
  http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
52
- http.errback { failed }
54
+ http.errback { fail }
53
55
  http.stream {|msg|}
54
56
  http.callback {
55
57
  http.response_header.status.should == 101
@@ -68,14 +70,14 @@ describe "WebSocket server draft75" do
68
70
  EventMachine.stop if received.size == messages.size
69
71
  }
70
72
  end
71
- end
73
+ }
72
74
  end
73
75
 
74
76
  it "should call onclose callback when client closes connection" do
75
- EM.run do
77
+ em {
76
78
  EventMachine.add_timer(0.1) do
77
79
  http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
78
- http.errback { failed }
80
+ http.errback { fail }
79
81
  http.callback {
80
82
  http.response_header.status.should == 101
81
83
  http.close_connection
@@ -90,19 +92,19 @@ describe "WebSocket server draft75" do
90
92
  EventMachine.stop
91
93
  }
92
94
  end
93
- end
95
+ }
94
96
  end
95
97
 
96
98
  it "should call onerror callback with raised exception and close connection on bad handshake" do
97
- EM.run do
99
+ em {
98
100
  EventMachine.add_timer(0.1) do
99
101
  http = EventMachine::HttpRequest.new('http://127.0.0.1:12345/').get :timeout => 0
100
102
  http.errback { http.response_header.status.should == 0 }
101
- http.callback { failed }
103
+ http.callback { fail }
102
104
  end
103
105
 
104
106
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) do |ws|
105
- ws.onopen { failed }
107
+ ws.onopen { fail }
106
108
  ws.onclose { EventMachine.stop }
107
109
  ws.onerror {|e|
108
110
  e.should be_an_instance_of EventMachine::WebSocket::HandshakeError
@@ -110,6 +112,6 @@ describe "WebSocket server draft75" do
110
112
  EventMachine.stop
111
113
  }
112
114
  end
113
- end
115
+ }
114
116
  end
115
117
  end
@@ -2,6 +2,9 @@ require 'helper'
2
2
  require 'integration/shared_examples'
3
3
 
4
4
  describe "WebSocket server draft76" do
5
+ include EM::SpecHelper
6
+ default_timeout 1
7
+
5
8
  before :each do
6
9
  @request = {
7
10
  :port => 80,
@@ -46,7 +49,7 @@ describe "WebSocket server draft76" do
46
49
  end
47
50
 
48
51
  it "should send back the correct handshake response" do
49
- EM.run do
52
+ em {
50
53
  EM.add_timer(0.1) do
51
54
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
52
55
 
@@ -57,14 +60,14 @@ describe "WebSocket server draft76" do
57
60
  connection.onopen {
58
61
  connection.handshake_response.lines.sort.
59
62
  should == format_response(@response).lines.sort
60
- EM.stop
63
+ done
61
64
  }
62
65
  end
63
- end
66
+ }
64
67
  end
65
68
 
66
69
  it "should send closing frame back and close the connection after recieving closing frame" do
67
- EM.run do
70
+ em {
68
71
  EM.add_timer(0.1) do
69
72
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
70
73
 
@@ -82,19 +85,19 @@ describe "WebSocket server draft76" do
82
85
  connection.onclose {
83
86
  connection.packets[0].should ==
84
87
  EM::WebSocket::Handler76::TERMINATE_STRING
85
- EM.stop
88
+ done
86
89
  }
87
90
  end
88
- end
91
+ }
89
92
  end
90
93
 
91
94
  it "should ignore any data received after the closing frame" do
92
- EM.run do
95
+ em {
93
96
  EM.add_timer(0.1) do
94
97
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
95
98
  # Fail if foobar message is received
96
99
  ws.onmessage { |msg|
97
- failed
100
+ fail
98
101
  }
99
102
  }
100
103
 
@@ -109,14 +112,14 @@ describe "WebSocket server draft76" do
109
112
  }
110
113
 
111
114
  connection.onclose {
112
- EM.stop
115
+ done
113
116
  }
114
117
  end
115
- end
118
+ }
116
119
  end
117
120
 
118
121
  it "should accept null bytes within the frame after a line return" do
119
- EM.run do
122
+ em {
120
123
  EM.add_timer(0.1) do
121
124
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
122
125
  ws.onmessage { |msg|
@@ -135,19 +138,19 @@ describe "WebSocket server draft76" do
135
138
  }
136
139
 
137
140
  connection.onclose {
138
- EM.stop
141
+ done
139
142
  }
140
143
  end
141
- end
144
+ }
142
145
  end
143
146
 
144
147
  it "should handle unreasonable frame lengths by calling onerror callback" do
145
- EM.run do
148
+ em {
146
149
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |server|
147
150
  server.onerror { |error|
148
151
  error.should be_an_instance_of EM::WebSocket::DataError
149
152
  error.message.should == "Frame length too long (1180591620717411303296 bytes)"
150
- EM.stop
153
+ done
151
154
  }
152
155
  }
153
156
 
@@ -162,16 +165,16 @@ describe "WebSocket server draft76" do
162
165
  client.onopen {
163
166
  client.send_data("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00")
164
167
  }
165
- end
168
+ }
166
169
  end
167
170
 
168
171
  it "should handle impossible frames by calling onerror callback" do
169
- EM.run do
172
+ em {
170
173
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |server|
171
174
  server.onerror { |error|
172
175
  error.should be_an_instance_of EM::WebSocket::DataError
173
176
  error.message.should == "Invalid frame received"
174
- EM.stop
177
+ done
175
178
  }
176
179
  }
177
180
 
@@ -182,16 +185,16 @@ describe "WebSocket server draft76" do
182
185
  client.onopen {
183
186
  client.send_data("foobar") # Does not start with \x00 or \xff
184
187
  }
185
- end
188
+ }
186
189
  end
187
190
 
188
191
  it "should handle invalid http requests by raising HandshakeError passed to onerror callback" do
189
- EM.run {
192
+ em {
190
193
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |server|
191
194
  server.onerror { |error|
192
195
  error.should be_an_instance_of EM::WebSocket::HandshakeError
193
196
  error.message.should == "Invalid HTTP header"
194
- EM.stop
197
+ done
195
198
  }
196
199
  }
197
200
 
@@ -201,7 +204,7 @@ describe "WebSocket server draft76" do
201
204
  end
202
205
 
203
206
  it "should handle handshake request split into two TCP packets" do
204
- EM.run do
207
+ em {
205
208
  EM.add_timer(0.1) do
206
209
  EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
207
210
 
@@ -214,7 +217,7 @@ describe "WebSocket server draft76" do
214
217
  connection.onopen {
215
218
  connection.handshake_response.lines.sort.
216
219
  should == format_response(@response).lines.sort
217
- EM.stop
220
+ done
218
221
  }
219
222
 
220
223
  EM.add_timer(0.1) do
@@ -222,6 +225,6 @@ describe "WebSocket server draft76" do
222
225
  connection.send_data(data[(data.length / 2)..-1])
223
226
  end
224
227
  end
225
- end
228
+ }
226
229
  end
227
230
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  shared_examples_for "a websocket server" do
4
4
  it "should call onerror if an application error raised in onopen" do
5
- EM.run {
5
+ em {
6
6
  start_server { |ws|
7
7
  ws.onopen {
8
8
  raise "application error"
@@ -10,7 +10,7 @@ shared_examples_for "a websocket server" do
10
10
 
11
11
  ws.onerror { |e|
12
12
  e.message.should == "application error"
13
- EM.stop
13
+ done
14
14
  }
15
15
  }
16
16
 
@@ -19,7 +19,7 @@ shared_examples_for "a websocket server" do
19
19
  end
20
20
 
21
21
  it "should call onerror if an application error raised in onmessage" do
22
- EM.run {
22
+ em {
23
23
  start_server { |server|
24
24
  server.onmessage {
25
25
  raise "application error"
@@ -27,7 +27,7 @@ shared_examples_for "a websocket server" do
27
27
 
28
28
  server.onerror { |e|
29
29
  e.message.should == "application error"
30
- EM.stop
30
+ done
31
31
  }
32
32
  }
33
33
 
@@ -40,7 +40,7 @@ shared_examples_for "a websocket server" do
40
40
  end
41
41
 
42
42
  it "should call onerror in an application error raised in onclose" do
43
- EM.run {
43
+ em {
44
44
  start_server { |server|
45
45
  server.onclose {
46
46
  raise "application error"
@@ -48,7 +48,7 @@ shared_examples_for "a websocket server" do
48
48
 
49
49
  server.onerror { |e|
50
50
  e.message.should == "application error"
51
- EM.stop
51
+ done
52
52
  }
53
53
  }
54
54
 
@@ -65,7 +65,7 @@ shared_examples_for "a websocket server" do
65
65
  # Only run these tests on ruby 1.9
66
66
  if "a".respond_to?(:force_encoding)
67
67
  it "should raise error if you try to send non utf8 text data to ws" do
68
- EM.run do
68
+ em {
69
69
  start_server { |server|
70
70
  server.onopen {
71
71
  # Create a string which claims to be UTF-8 but which is not
@@ -80,12 +80,12 @@ shared_examples_for "a websocket server" do
80
80
  server.onerror { |error|
81
81
  error.class.should == EventMachine::WebSocket::WebSocketError
82
82
  error.message.should == "Data sent to WebSocket must be valid UTF-8 but was UTF-8 (valid: false)"
83
- EM.stop
83
+ done
84
84
  }
85
85
  }
86
86
 
87
87
  start_client { }
88
- end
88
+ }
89
89
  end
90
90
  end
91
91
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-websocket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-10-17 00:00:00.000000000Z
13
+ date: 2011-10-24 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: eventmachine
17
- requirement: &70120715076200 !ruby/object:Gem::Requirement
17
+ requirement: &70358050200200 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 0.12.9
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70120715076200
25
+ version_requirements: *70358050200200
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: addressable
28
- requirement: &70120715061040 !ruby/object:Gem::Requirement
28
+ requirement: &70358050199560 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,32 @@ dependencies:
33
33
  version: 2.1.1
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70120715061040
36
+ version_requirements: *70358050199560
37
+ - !ruby/object:Gem::Dependency
38
+ name: em-spec
39
+ requirement: &70358050199080 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 0.2.5
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *70358050199080
48
+ - !ruby/object:Gem::Dependency
49
+ name: eventmachine
50
+ requirement: &70358050198540 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.12.10
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *70358050198540
37
59
  - !ruby/object:Gem::Dependency
38
60
  name: em-http-request
39
- requirement: &70120715060520 !ruby/object:Gem::Requirement
61
+ requirement: &70358050197960 !ruby/object:Gem::Requirement
40
62
  none: false
41
63
  requirements:
42
64
  - - ~>
@@ -44,21 +66,21 @@ dependencies:
44
66
  version: 0.2.6
45
67
  type: :development
46
68
  prerelease: false
47
- version_requirements: *70120715060520
69
+ version_requirements: *70358050197960
48
70
  - !ruby/object:Gem::Dependency
49
71
  name: rspec
50
- requirement: &70120715059920 !ruby/object:Gem::Requirement
72
+ requirement: &70358050197280 !ruby/object:Gem::Requirement
51
73
  none: false
52
74
  requirements:
53
75
  - - ~>
54
76
  - !ruby/object:Gem::Version
55
- version: 2.5.0
77
+ version: 2.6.0
56
78
  type: :development
57
79
  prerelease: false
58
- version_requirements: *70120715059920
80
+ version_requirements: *70358050197280
59
81
  - !ruby/object:Gem::Dependency
60
82
  name: rake
61
- requirement: &70120715059420 !ruby/object:Gem::Requirement
83
+ requirement: &70358050176420 !ruby/object:Gem::Requirement
62
84
  none: false
63
85
  requirements:
64
86
  - - ! '>='
@@ -66,7 +88,7 @@ dependencies:
66
88
  version: '0'
67
89
  type: :development
68
90
  prerelease: false
69
- version_requirements: *70120715059420
91
+ version_requirements: *70358050176420
70
92
  description: EventMachine based WebSocket server
71
93
  email:
72
94
  - ilya@igvita.com
@@ -82,6 +104,7 @@ files:
82
104
  - Rakefile
83
105
  - em-websocket.gemspec
84
106
  - examples/echo.rb
107
+ - examples/flash_policy_file_server.rb
85
108
  - examples/js/FABridge.js
86
109
  - examples/js/WebSocketMain.swf
87
110
  - examples/js/swfobject.js
@@ -106,6 +129,7 @@ files:
106
129
  - lib/em-websocket/handler06.rb
107
130
  - lib/em-websocket/handler07.rb
108
131
  - lib/em-websocket/handler08.rb
132
+ - lib/em-websocket/handler13.rb
109
133
  - lib/em-websocket/handler75.rb
110
134
  - lib/em-websocket/handler76.rb
111
135
  - lib/em-websocket/handler_factory.rb
@@ -122,6 +146,7 @@ files:
122
146
  - spec/integration/draft03_spec.rb
123
147
  - spec/integration/draft05_spec.rb
124
148
  - spec/integration/draft06_spec.rb
149
+ - spec/integration/draft13_spec.rb
125
150
  - spec/integration/draft75_spec.rb
126
151
  - spec/integration/draft76_spec.rb
127
152
  - spec/integration/shared_examples.rb
@@ -148,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
173
  version: '0'
149
174
  requirements: []
150
175
  rubyforge_project: em-websocket
151
- rubygems_version: 1.8.6
176
+ rubygems_version: 1.8.11
152
177
  signing_key:
153
178
  specification_version: 3
154
179
  summary: EventMachine based WebSocket server
@@ -158,6 +183,7 @@ test_files:
158
183
  - spec/integration/draft03_spec.rb
159
184
  - spec/integration/draft05_spec.rb
160
185
  - spec/integration/draft06_spec.rb
186
+ - spec/integration/draft13_spec.rb
161
187
  - spec/integration/draft75_spec.rb
162
188
  - spec/integration/draft76_spec.rb
163
189
  - spec/integration/shared_examples.rb