sonixlabs-em-websocket 0.3.8 → 0.5.1.1

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