sonixlabs-em-websocket 0.3.8 → 0.5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.rdoc +69 -0
  3. data/Gemfile +6 -0
  4. data/LICENCE +7 -0
  5. data/README.md +100 -56
  6. data/README.md.BACKUP.14928.md +195 -0
  7. data/README.md.BASE.14928.md +77 -0
  8. data/README.md.LOCAL.14928.md +98 -0
  9. data/README.md.REMOTE.14928.md +142 -0
  10. data/examples/echo.rb +23 -7
  11. data/examples/ping.rb +24 -0
  12. data/examples/test.html +5 -6
  13. data/lib/em-websocket.rb +4 -2
  14. data/lib/em-websocket/close03.rb +3 -0
  15. data/lib/em-websocket/close05.rb +3 -0
  16. data/lib/em-websocket/close06.rb +3 -0
  17. data/lib/em-websocket/close75.rb +2 -1
  18. data/lib/em-websocket/connection.rb +219 -73
  19. data/lib/em-websocket/framing03.rb +6 -11
  20. data/lib/em-websocket/framing05.rb +6 -11
  21. data/lib/em-websocket/framing07.rb +25 -20
  22. data/lib/em-websocket/framing76.rb +6 -15
  23. data/lib/em-websocket/handler.rb +69 -28
  24. data/lib/em-websocket/handler03.rb +0 -1
  25. data/lib/em-websocket/handler05.rb +0 -1
  26. data/lib/em-websocket/handler06.rb +0 -1
  27. data/lib/em-websocket/handler07.rb +0 -1
  28. data/lib/em-websocket/handler08.rb +0 -1
  29. data/lib/em-websocket/handler13.rb +0 -1
  30. data/lib/em-websocket/handler76.rb +2 -0
  31. data/lib/em-websocket/handshake.rb +156 -0
  32. data/lib/em-websocket/handshake04.rb +18 -56
  33. data/lib/em-websocket/handshake75.rb +15 -8
  34. data/lib/em-websocket/handshake76.rb +15 -14
  35. data/lib/em-websocket/masking04.rb +4 -30
  36. data/lib/em-websocket/message_processor_03.rb +13 -4
  37. data/lib/em-websocket/message_processor_06.rb +25 -13
  38. data/lib/em-websocket/version.rb +1 -1
  39. data/lib/em-websocket/websocket.rb +35 -24
  40. data/spec/helper.rb +82 -55
  41. data/spec/integration/common_spec.rb +90 -70
  42. data/spec/integration/draft03_spec.rb +84 -56
  43. data/spec/integration/draft05_spec.rb +14 -12
  44. data/spec/integration/draft06_spec.rb +66 -9
  45. data/spec/integration/draft13_spec.rb +59 -29
  46. data/spec/integration/draft75_spec.rb +46 -40
  47. data/spec/integration/draft76_spec.rb +113 -109
  48. data/spec/integration/gte_03_examples.rb +42 -0
  49. data/spec/integration/shared_examples.rb +174 -0
  50. data/spec/unit/framing_spec.rb +83 -110
  51. data/spec/unit/handshake_spec.rb +216 -0
  52. data/spec/unit/masking_spec.rb +2 -0
  53. metadata +31 -71
  54. data/examples/flash_policy_file_server.rb +0 -21
  55. data/examples/js/FABridge.js +0 -604
  56. data/examples/js/WebSocketMain.swf +0 -0
  57. data/examples/js/swfobject.js +0 -4
  58. data/examples/js/web_socket.js +0 -312
  59. data/lib/em-websocket/handler_factory.rb +0 -107
  60. data/spec/unit/handler_spec.rb +0 -147
@@ -20,28 +20,30 @@ describe "draft05" do
20
20
  }
21
21
  }
22
22
  end
23
-
24
- def start_server
25
- EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
26
- yield ws
27
- }
28
- end
29
23
 
30
24
  def start_client
31
- client = EM.connect('0.0.0.0', 12345, Draft03FakeWebSocketClient)
25
+ client = EM.connect('0.0.0.0', 12345, Draft05FakeWebSocketClient)
32
26
  client.send_data(format_request(@request))
33
27
  yield client if block_given?
28
+ return client
34
29
  end
35
30
 
36
- it "should open connection" do
31
+ it_behaves_like "a websocket server" do
32
+ let(:version) { 5 }
33
+ end
34
+
35
+ it_behaves_like "a WebSocket server drafts 3 and above" do
36
+ let(:version) { 5 }
37
+ end
38
+
39
+ it "should report that close codes are not supported" do
37
40
  em {
38
- start_server { |server|
39
- server.onopen {
40
- server.instance_variable_get(:@handler).class.should == EventMachine::WebSocket::Handler05
41
+ start_server { |ws|
42
+ ws.onopen {
43
+ ws.supports_close_codes?.should == false
41
44
  done
42
45
  }
43
46
  }
44
-
45
47
  start_client
46
48
  }
47
49
  end
@@ -1,5 +1,4 @@
1
1
  require 'helper'
2
- require 'integration/client_examples'
3
2
 
4
3
  describe "draft06" do
5
4
  include EM::SpecHelper
@@ -27,22 +26,26 @@ describe "draft06" do
27
26
  "Upgrade" => "websocket",
28
27
  "Connection" => "Upgrade",
29
28
  "Sec-WebSocket-Accept" => "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
29
+ "Sec-WebSocket-Protocol" => "sample",
30
30
  }
31
31
  }
32
32
  end
33
-
34
- def start_server
35
- EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
36
- yield ws
37
- }
38
- end
39
33
 
40
34
  def start_client
41
- client = EM.connect('0.0.0.0', 12345, Draft03FakeWebSocketClient)
35
+ client = EM.connect('0.0.0.0', 12345, Draft05FakeWebSocketClient)
42
36
  client.send_data(format_request(@request))
43
37
  yield client if block_given?
38
+ return client
44
39
  end
45
40
 
41
+ it_behaves_like "a websocket server" do
42
+ let(:version) { 6 }
43
+ end
44
+
45
+ it_behaves_like "a WebSocket server drafts 3 and above" do
46
+ let(:version) { 6 }
47
+ end
48
+
46
49
  it "should open connection" do
47
50
  em {
48
51
  start_server { |server|
@@ -84,5 +87,59 @@ describe "draft06" do
84
87
  }
85
88
  end
86
89
 
87
- it_should_behave_like "a websocket client"
90
+ it "should return close code and reason if closed via handshake" do
91
+ em {
92
+ start_server { |ws|
93
+ ws.onclose { |event|
94
+ # 2. Receive close event in server
95
+ event.should == {
96
+ :code => 4004,
97
+ :reason => "close reason",
98
+ :was_clean => true,
99
+ }
100
+ done
101
+ }
102
+ }
103
+ start_client { |client|
104
+ client.onopen {
105
+ # 1: Send close handshake
106
+ close_data = [4004].pack('n')
107
+ close_data << "close reason"
108
+ client.send_frame(:close, close_data)
109
+ }
110
+ }
111
+ }
112
+ end
113
+
114
+ it "should return close code 1005 if no code was specified" do
115
+ em {
116
+ start_server { |ws|
117
+ ws.onclose { |event|
118
+ event.should == {
119
+ :code => 1005,
120
+ :reason => "",
121
+ :was_clean => true,
122
+ }
123
+ done
124
+ }
125
+ }
126
+ start_client { |client|
127
+ client.onopen {
128
+ client.send_frame(:close, '')
129
+ }
130
+ }
131
+ }
132
+ end
133
+
134
+ it "should report that close codes are supported" do
135
+ em {
136
+ start_server { |ws|
137
+ ws.onopen {
138
+ ws.supports_close_codes?.should == true
139
+ done
140
+ }
141
+ }
142
+ start_client
143
+ }
144
+ end
88
145
  end
@@ -1,6 +1,6 @@
1
+ # encoding: BINARY
2
+
1
3
  require 'helper'
2
- require 'integration/shared_examples'
3
- require 'integration/client_examples'
4
4
 
5
5
  describe "draft13" do
6
6
  include EM::SpecHelper
@@ -28,48 +28,78 @@ describe "draft13" do
28
28
  "Upgrade" => "websocket",
29
29
  "Connection" => "Upgrade",
30
30
  "Sec-WebSocket-Accept" => "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=",
31
+ "Sec-WebSocket-Protocol" => "sample",
31
32
  }
32
33
  }
33
34
  end
34
35
 
36
+ def start_client
37
+ client = EM.connect('0.0.0.0', 12345, Draft07FakeWebSocketClient)
38
+ client.send_data(format_request(@request))
39
+ yield client if block_given?
40
+ return client
41
+ end
42
+
35
43
  it_behaves_like "a websocket server" do
36
- def start_server
37
- EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
38
- yield ws
39
- }
40
- end
44
+ let(:version) { 13 }
45
+ end
41
46
 
42
- def start_client
43
- client = EM.connect('0.0.0.0', 12345, Draft07FakeWebSocketClient)
44
- client.send_data(format_request(@request))
45
- yield client if block_given?
46
- end
47
+ it_behaves_like "a WebSocket server drafts 3 and above" do
48
+ let(:version) { 13 }
47
49
  end
48
50
 
49
51
  it "should send back the correct handshake response" do
50
52
  em {
51
- EM.add_timer(0.1) do
52
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
53
-
54
- # Create a fake client which sends draft 07 handshake
55
- connection = EM.connect('0.0.0.0', 12345, Draft07FakeWebSocketClient)
56
- connection.send_data(format_request(@request))
57
-
58
- connection.onopen {
59
- connection.handshake_response.lines.sort.
60
- should == format_response(@response).lines.sort
53
+ start_server
54
+
55
+ connection = start_client
56
+
57
+ connection.onopen {
58
+ connection.handshake_response.lines.sort.
59
+ should == format_response(@response).lines.sort
60
+ done
61
+ }
62
+ }
63
+ end
64
+
65
+ # TODO: This test would be much nicer with a real websocket client...
66
+ it "should support sending pings and binding to onpong" do
67
+ em {
68
+ start_server { |ws|
69
+ ws.onopen {
70
+ ws.should be_pingable
71
+ EM.next_tick {
72
+ ws.ping('hello').should == true
73
+ }
74
+
75
+ }
76
+ ws.onpong { |data|
77
+ data.should == 'hello'
61
78
  done
62
79
  }
63
- end
80
+ }
81
+
82
+ connection = start_client
83
+
84
+ # Confusing, fake onmessage means any data after the handshake
85
+ connection.onmessage { |data|
86
+ # This is what a ping looks like
87
+ data.should == "\x89\x05hello"
88
+ # This is what a pong looks like
89
+ connection.send_data("\x8a\x05hello")
90
+ }
64
91
  }
65
92
  end
66
93
 
67
- it_should_behave_like "a websocket client" do
68
- def start_server
69
- EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
70
- yield ws
94
+ it "should report that close codes are supported" do
95
+ em {
96
+ start_server { |ws|
97
+ ws.onopen {
98
+ ws.supports_close_codes?.should == true
99
+ done
100
+ }
71
101
  }
72
- end
102
+ start_client
103
+ }
73
104
  end
74
-
75
105
  end
@@ -1,5 +1,4 @@
1
1
  require 'helper'
2
- require 'integration/shared_examples'
3
2
 
4
3
  # These integration tests are older and use a different testing style to the
5
4
  # integration tests for newer drafts. They use EM::HttpRequest which happens
@@ -9,38 +8,35 @@ describe "WebSocket server draft75" do
9
8
  include EM::SpecHelper
10
9
  default_timeout 1
11
10
 
12
- it_behaves_like "a websocket server" do
13
- def start_server
14
- EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
15
- yield ws
16
- }
17
- end
11
+ def start_client
12
+ client = Draft75WebSocketClient.new
13
+ yield client if block_given?
14
+ return client
15
+ end
18
16
 
19
- def start_client
20
- client = Draft75WebSocketClient.new
21
- yield client if block_given?
22
- end
17
+ it_behaves_like "a websocket server" do
18
+ let(:version) { 75 }
23
19
  end
24
20
 
25
21
  it "should automatically complete WebSocket handshake" do
26
22
  em {
27
23
  MSG = "Hello World!"
28
24
  EventMachine.add_timer(0.1) do
29
- http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
30
- http.errback { fail }
31
- http.callback { http.response_header.status.should == 101 }
25
+ ws = EventMachine::WebSocketClient.connect('ws://127.0.0.1:12345/')
26
+ ws.errback { fail }
27
+ ws.callback { }
32
28
 
33
- http.stream { |msg|
34
- msg.should == MSG
29
+ ws.stream { |msg|
30
+ msg.data.should == MSG
35
31
  EventMachine.stop
36
32
  }
37
33
  end
38
34
 
39
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) do |ws|
35
+ start_server { |ws|
40
36
  ws.onopen {
41
37
  ws.send MSG
42
38
  }
43
- end
39
+ }
44
40
  }
45
41
  end
46
42
 
@@ -50,17 +46,16 @@ describe "WebSocket server draft75" do
50
46
  received = []
51
47
 
52
48
  EventMachine.add_timer(0.1) do
53
- http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
54
- http.errback { fail }
55
- http.stream {|msg|}
56
- http.callback {
57
- http.response_header.status.should == 101
58
- http.send messages[0]
59
- http.send messages[1]
49
+ ws = EventMachine::WebSocketClient.connect('ws://127.0.0.1:12345/')
50
+ ws.errback { fail }
51
+ ws.stream {|msg|}
52
+ ws.callback {
53
+ ws.send_msg messages[0]
54
+ ws.send_msg messages[1]
60
55
  }
61
56
  end
62
57
 
63
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) do |ws|
58
+ start_server { |ws|
64
59
  ws.onopen {}
65
60
  ws.onclose {}
66
61
  ws.onmessage {|msg|
@@ -69,49 +64,60 @@ describe "WebSocket server draft75" do
69
64
 
70
65
  EventMachine.stop if received.size == messages.size
71
66
  }
72
- end
67
+ }
73
68
  }
74
69
  end
75
70
 
76
71
  it "should call onclose callback when client closes connection" do
77
72
  em {
78
73
  EventMachine.add_timer(0.1) do
79
- http = EventMachine::HttpRequest.new('ws://127.0.0.1:12345/').get :timeout => 0
80
- http.errback { fail }
81
- http.callback {
82
- http.response_header.status.should == 101
83
- http.close_connection
74
+ ws = EventMachine::WebSocketClient.connect('ws://127.0.0.1:12345/')
75
+ ws.errback { fail }
76
+ ws.callback {
77
+ ws.close_connection
84
78
  }
85
- http.stream{|msg|}
79
+ ws.stream{|msg|}
86
80
  end
87
81
 
88
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) do |ws|
82
+ start_server { |ws|
89
83
  ws.onopen {}
90
84
  ws.onclose {
91
85
  ws.state.should == :closed
92
86
  EventMachine.stop
93
87
  }
94
- end
88
+ }
95
89
  }
96
90
  end
97
91
 
98
92
  it "should call onerror callback with raised exception and close connection on bad handshake" do
99
93
  em {
100
94
  EventMachine.add_timer(0.1) do
101
- http = EventMachine::HttpRequest.new('http://127.0.0.1:12345/').get :timeout => 0
102
- http.errback { http.response_header.status.should == 0 }
95
+ http = EM::HttpRequest.new('http://127.0.0.1:12345/').get
96
+ http.errback { }
103
97
  http.callback { fail }
104
98
  end
105
99
 
106
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) do |ws|
100
+ start_server { |ws|
107
101
  ws.onopen { fail }
108
102
  ws.onclose { EventMachine.stop }
109
103
  ws.onerror {|e|
110
104
  e.should be_an_instance_of EventMachine::WebSocket::HandshakeError
111
- e.message.should match('Connection and Upgrade headers required')
105
+ e.message.should match('Not an upgrade request')
112
106
  EventMachine.stop
113
107
  }
114
- end
108
+ }
109
+ }
110
+ end
111
+
112
+ it "should report that close codes are not supported" do
113
+ em {
114
+ start_server { |ws|
115
+ ws.onopen {
116
+ ws.supports_close_codes?.should == false
117
+ done
118
+ }
119
+ }
120
+ start_client
115
121
  }
116
122
  end
117
123
  end
@@ -1,5 +1,6 @@
1
+ # encoding: BINARY
2
+
1
3
  require 'helper'
2
- require 'integration/shared_examples'
3
4
 
4
5
  describe "WebSocket server draft76" do
5
6
  include EM::SpecHelper
@@ -33,130 +34,109 @@ describe "WebSocket server draft76" do
33
34
  :body => "8jKS\'y:G*Co,Wxa-"
34
35
  }
35
36
  end
36
-
37
- it_behaves_like "a websocket server" do
38
- def start_server
39
- EM::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
40
- yield ws
41
- }
42
- end
43
37
 
44
- def start_client
45
- client = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
46
- client.send_data(format_request(@request))
47
- yield client if block_given?
48
- end
38
+ def start_client
39
+ client = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
40
+ client.send_data(format_request(@request))
41
+ yield client if block_given?
42
+ return client
43
+ end
44
+
45
+ it_behaves_like "a websocket server" do
46
+ let(:version) { 76 }
49
47
  end
50
48
 
51
49
  it "should send back the correct handshake response" do
52
50
  em {
53
- EM.add_timer(0.1) do
54
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
55
-
56
- # Create a fake client which sends draft 76 handshake
57
- connection = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
58
- connection.send_data(format_request(@request))
59
-
51
+ start_server
52
+
53
+ start_client { |connection|
60
54
  connection.onopen {
61
55
  connection.handshake_response.lines.sort.
62
56
  should == format_response(@response).lines.sort
63
57
  done
64
58
  }
65
- end
59
+ }
66
60
  }
67
61
  end
68
62
 
69
63
  it "should send closing frame back and close the connection after recieving closing frame" do
70
64
  em {
71
- EM.add_timer(0.1) do
72
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
73
-
74
- # Create a fake client which sends draft 76 handshake
75
- connection = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
76
- connection.send_data(format_request(@request))
77
-
78
- # Send closing frame after handshake complete
79
- connection.onopen {
80
- connection.send_data(EM::WebSocket::Handler76::TERMINATE_STRING)
81
- }
82
-
83
- # Check that this causes a termination string to be returned and the
84
- # connection close
85
- connection.onclose {
86
- connection.packets[0].should ==
87
- EM::WebSocket::Handler76::TERMINATE_STRING
88
- done
89
- }
90
- end
65
+ start_server
66
+
67
+ connection = start_client
68
+
69
+ # Send closing frame after handshake complete
70
+ connection.onopen {
71
+ connection.send_data(EM::WebSocket::Handler76::TERMINATE_STRING)
72
+ }
73
+
74
+ # Check that this causes a termination string to be returned and the
75
+ # connection close
76
+ connection.onclose {
77
+ connection.packets[0].should ==
78
+ EM::WebSocket::Handler76::TERMINATE_STRING
79
+ done
80
+ }
91
81
  }
92
82
  end
93
83
 
94
84
  it "should ignore any data received after the closing frame" do
95
85
  em {
96
- EM.add_timer(0.1) do
97
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
98
- # Fail if foobar message is received
99
- ws.onmessage { |msg|
100
- fail
101
- }
86
+ start_server { |ws|
87
+ # Fail if foobar message is received
88
+ ws.onmessage { |msg|
89
+ fail
102
90
  }
103
-
104
- # Create a fake client which sends draft 76 handshake
105
- connection = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
106
- connection.send_data(format_request(@request))
107
-
108
- # Send closing frame after handshake complete, followed by another msg
109
- connection.onopen {
110
- connection.send_data(EM::WebSocket::Handler76::TERMINATE_STRING)
111
- connection.send('foobar')
112
- }
113
-
114
- connection.onclose {
115
- done
116
- }
117
- end
91
+ }
92
+
93
+ connection = start_client
94
+
95
+ # Send closing frame after handshake complete, followed by another msg
96
+ connection.onopen {
97
+ connection.send_data(EM::WebSocket::Handler76::TERMINATE_STRING)
98
+ connection.send('foobar')
99
+ }
100
+
101
+ connection.onclose {
102
+ done
103
+ }
118
104
  }
119
105
  end
120
106
 
121
107
  it "should accept null bytes within the frame after a line return" do
122
108
  em {
123
- EM.add_timer(0.1) do
124
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |ws|
125
- ws.onmessage { |msg|
126
- msg.should == "\n\000"
127
- }
128
- }
129
-
130
- # Create a fake client which sends draft 76 handshake
131
- connection = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
132
- connection.send_data(format_request(@request))
133
-
134
- # Send closing frame after handshake complete
135
- connection.onopen {
136
- connection.send_data("\000\n\000\377")
137
- connection.send_data(EM::WebSocket::Handler76::TERMINATE_STRING)
109
+ start_server { |ws|
110
+ ws.onmessage { |msg|
111
+ msg.should == "\n\000"
138
112
  }
139
-
140
- connection.onclose {
141
- done
142
- }
143
- end
113
+ }
114
+
115
+ connection = start_client
116
+
117
+ # Send closing frame after handshake complete
118
+ connection.onopen {
119
+ connection.send_data("\000\n\000\377")
120
+ connection.send_data(EM::WebSocket::Handler76::TERMINATE_STRING)
121
+ }
122
+
123
+ connection.onclose {
124
+ done
125
+ }
144
126
  }
145
127
  end
146
128
 
147
129
  it "should handle unreasonable frame lengths by calling onerror callback" do
148
130
  em {
149
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |server|
131
+ start_server { |server|
150
132
  server.onerror { |error|
151
- error.should be_an_instance_of EM::WebSocket::DataError
133
+ error.should be_an_instance_of EM::WebSocket::WSMessageTooBigError
152
134
  error.message.should == "Frame length too long (1180591620717411303296 bytes)"
153
135
  done
154
136
  }
155
137
  }
156
138
 
157
- # Create a fake client which sends draft 76 handshake
158
- client = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
159
- client.send_data(format_request(@request))
139
+ client = start_client
160
140
 
161
141
  # This particular frame indicates a message length of
162
142
  # 1180591620717411303296 bytes. Such a message would previously cause
@@ -170,17 +150,15 @@ describe "WebSocket server draft76" do
170
150
 
171
151
  it "should handle impossible frames by calling onerror callback" do
172
152
  em {
173
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |server|
153
+ start_server { |server|
174
154
  server.onerror { |error|
175
- error.should be_an_instance_of EM::WebSocket::DataError
155
+ error.should be_an_instance_of EM::WebSocket::WSProtocolError
176
156
  error.message.should == "Invalid frame received"
177
157
  done
178
158
  }
179
159
  }
180
160
 
181
- # Create a fake client which sends draft 76 handshake
182
- client = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
183
- client.send_data(format_request(@request))
161
+ client = start_client
184
162
 
185
163
  client.onopen {
186
164
  client.send_data("foobar") # Does not start with \x00 or \xff
@@ -190,10 +168,10 @@ describe "WebSocket server draft76" do
190
168
 
191
169
  it "should handle invalid http requests by raising HandshakeError passed to onerror callback" do
192
170
  em {
193
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { |server|
171
+ start_server { |server|
194
172
  server.onerror { |error|
195
173
  error.should be_an_instance_of EM::WebSocket::HandshakeError
196
- error.message.should == "Invalid HTTP header"
174
+ error.message.should == "Invalid HTTP header: Could not parse data entirely (1 != 29)"
197
175
  done
198
176
  }
199
177
  }
@@ -205,26 +183,52 @@ describe "WebSocket server draft76" do
205
183
 
206
184
  it "should handle handshake request split into two TCP packets" do
207
185
  em {
208
- EM.add_timer(0.1) do
209
- EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
186
+ start_server
210
187
 
211
- # Create a fake client which sends draft 76 handshake
212
- connection = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
213
- data = format_request(@request)
214
- # Sends first half of the request
215
- connection.send_data(data[0...(data.length / 2)])
188
+ # Create a fake client which sends draft 76 handshake
189
+ connection = EM.connect('0.0.0.0', 12345, FakeWebSocketClient)
190
+ data = format_request(@request)
191
+ # Sends first half of the request
192
+ connection.send_data(data[0...(data.length / 2)])
193
+
194
+ connection.onopen {
195
+ connection.handshake_response.lines.sort.
196
+ should == format_response(@response).lines.sort
197
+ done
198
+ }
216
199
 
217
- connection.onopen {
218
- connection.handshake_response.lines.sort.
219
- should == format_response(@response).lines.sort
200
+ EM.add_timer(0.1) do
201
+ # Sends second half of the request
202
+ connection.send_data(data[(data.length / 2)..-1])
203
+ end
204
+ }
205
+ end
206
+
207
+ it "should report that close codes are not supported" do
208
+ em {
209
+ start_server { |ws|
210
+ ws.onopen {
211
+ ws.supports_close_codes?.should == false
220
212
  done
221
213
  }
214
+ }
215
+ start_client
216
+ }
217
+ end
222
218
 
223
- EM.add_timer(0.1) do
224
- # Sends second half of the request
225
- connection.send_data(data[(data.length / 2)..-1])
226
- end
227
- end
219
+ it "should call onclose when the server closes the connection [antiregression]" do
220
+ em {
221
+ start_server { |ws|
222
+ ws.onopen {
223
+ EM.add_timer(0.1) {
224
+ ws.close()
225
+ }
226
+ }
227
+ ws.onclose {
228
+ done
229
+ }
230
+ }
231
+ start_client
228
232
  }
229
233
  end
230
234
  end