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.
- 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
|