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.
- checksums.yaml +7 -0
- data/CHANGELOG.rdoc +69 -0
- data/Gemfile +6 -0
- data/LICENCE +7 -0
- data/README.md +100 -56
- data/README.md.BACKUP.14928.md +195 -0
- data/README.md.BASE.14928.md +77 -0
- data/README.md.LOCAL.14928.md +98 -0
- data/README.md.REMOTE.14928.md +142 -0
- data/examples/echo.rb +23 -7
- data/examples/ping.rb +24 -0
- data/examples/test.html +5 -6
- data/lib/em-websocket.rb +4 -2
- data/lib/em-websocket/close03.rb +3 -0
- data/lib/em-websocket/close05.rb +3 -0
- data/lib/em-websocket/close06.rb +3 -0
- data/lib/em-websocket/close75.rb +2 -1
- data/lib/em-websocket/connection.rb +219 -73
- data/lib/em-websocket/framing03.rb +6 -11
- data/lib/em-websocket/framing05.rb +6 -11
- data/lib/em-websocket/framing07.rb +25 -20
- data/lib/em-websocket/framing76.rb +6 -15
- data/lib/em-websocket/handler.rb +69 -28
- data/lib/em-websocket/handler03.rb +0 -1
- data/lib/em-websocket/handler05.rb +0 -1
- data/lib/em-websocket/handler06.rb +0 -1
- data/lib/em-websocket/handler07.rb +0 -1
- data/lib/em-websocket/handler08.rb +0 -1
- data/lib/em-websocket/handler13.rb +0 -1
- data/lib/em-websocket/handler76.rb +2 -0
- data/lib/em-websocket/handshake.rb +156 -0
- data/lib/em-websocket/handshake04.rb +18 -56
- data/lib/em-websocket/handshake75.rb +15 -8
- data/lib/em-websocket/handshake76.rb +15 -14
- data/lib/em-websocket/masking04.rb +4 -30
- data/lib/em-websocket/message_processor_03.rb +13 -4
- data/lib/em-websocket/message_processor_06.rb +25 -13
- data/lib/em-websocket/version.rb +1 -1
- data/lib/em-websocket/websocket.rb +35 -24
- data/spec/helper.rb +82 -55
- data/spec/integration/common_spec.rb +90 -70
- data/spec/integration/draft03_spec.rb +84 -56
- data/spec/integration/draft05_spec.rb +14 -12
- data/spec/integration/draft06_spec.rb +66 -9
- data/spec/integration/draft13_spec.rb +59 -29
- data/spec/integration/draft75_spec.rb +46 -40
- data/spec/integration/draft76_spec.rb +113 -109
- data/spec/integration/gte_03_examples.rb +42 -0
- data/spec/integration/shared_examples.rb +174 -0
- data/spec/unit/framing_spec.rb +83 -110
- data/spec/unit/handshake_spec.rb +216 -0
- data/spec/unit/masking_spec.rb +2 -0
- metadata +31 -71
- data/examples/flash_policy_file_server.rb +0 -21
- data/examples/js/FABridge.js +0 -604
- data/examples/js/WebSocketMain.swf +0 -0
- data/examples/js/swfobject.js +0 -4
- data/examples/js/web_socket.js +0 -312
- data/lib/em-websocket/handler_factory.rb +0 -107
- 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,
|
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
|
-
|
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 { |
|
39
|
-
|
40
|
-
|
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,
|
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
|
-
|
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
|
-
|
37
|
-
|
38
|
-
yield ws
|
39
|
-
}
|
40
|
-
end
|
44
|
+
let(:version) { 13 }
|
45
|
+
end
|
41
46
|
|
42
|
-
|
43
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
connection.
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
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
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
20
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
25
|
+
ws = EventMachine::WebSocketClient.connect('ws://127.0.0.1:12345/')
|
26
|
+
ws.errback { fail }
|
27
|
+
ws.callback { }
|
32
28
|
|
33
|
-
|
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
|
-
|
35
|
+
start_server { |ws|
|
40
36
|
ws.onopen {
|
41
37
|
ws.send MSG
|
42
38
|
}
|
43
|
-
|
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
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
|
79
|
+
ws.stream{|msg|}
|
86
80
|
end
|
87
81
|
|
88
|
-
|
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
|
-
|
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 =
|
102
|
-
http.errback {
|
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
|
-
|
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('
|
105
|
+
e.message.should match('Not an upgrade request')
|
112
106
|
EventMachine.stop
|
113
107
|
}
|
114
|
-
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
54
|
-
|
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
|
-
|
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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
fail
|
101
|
-
}
|
86
|
+
start_server { |ws|
|
87
|
+
# Fail if foobar message is received
|
88
|
+
ws.onmessage { |msg|
|
89
|
+
fail
|
102
90
|
}
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
connection.
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
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
|
-
|
131
|
+
start_server { |server|
|
150
132
|
server.onerror { |error|
|
151
|
-
error.should be_an_instance_of EM::WebSocket::
|
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
|
-
|
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
|
-
|
153
|
+
start_server { |server|
|
174
154
|
server.onerror { |error|
|
175
|
-
error.should be_an_instance_of EM::WebSocket::
|
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
|
-
|
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
|
-
|
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
|
-
|
209
|
-
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 12345) { }
|
186
|
+
start_server
|
210
187
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
218
|
-
|
219
|
-
|
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
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
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
|