mongrel2 0.52.2 → 0.53.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/ChangeLog +128 -2
- data/History.rdoc +10 -0
- data/Manifest.txt +1 -0
- data/Rakefile +1 -1
- data/lib/mongrel2.rb +3 -3
- data/lib/mongrel2/config.rb +2 -1
- data/lib/mongrel2/config/directory.rb +2 -1
- data/lib/mongrel2/config/dsl.rb +2 -1
- data/lib/mongrel2/config/filter.rb +2 -1
- data/lib/mongrel2/config/handler.rb +2 -1
- data/lib/mongrel2/config/host.rb +2 -1
- data/lib/mongrel2/config/log.rb +2 -1
- data/lib/mongrel2/config/mimetype.rb +2 -1
- data/lib/mongrel2/config/proxy.rb +2 -1
- data/lib/mongrel2/config/route.rb +2 -1
- data/lib/mongrel2/config/server.rb +2 -1
- data/lib/mongrel2/config/setting.rb +2 -1
- data/lib/mongrel2/config/statistic.rb +2 -1
- data/lib/mongrel2/config/xrequest.rb +2 -1
- data/lib/mongrel2/connection.rb +1 -1
- data/lib/mongrel2/constants.rb +2 -1
- data/lib/mongrel2/control.rb +2 -1
- data/lib/mongrel2/exceptions.rb +2 -1
- data/lib/mongrel2/handler.rb +9 -8
- data/lib/mongrel2/httprequest.rb +2 -1
- data/lib/mongrel2/httpresponse.rb +2 -1
- data/lib/mongrel2/jsonrequest.rb +2 -1
- data/lib/mongrel2/request.rb +16 -9
- data/lib/mongrel2/response.rb +14 -6
- data/lib/mongrel2/table.rb +24 -3
- data/lib/mongrel2/testing.rb +12 -25
- data/lib/mongrel2/websocket.rb +230 -148
- data/lib/mongrel2/xmlrequest.rb +2 -1
- data/spec/constants.rb +3 -2
- data/spec/helpers.rb +2 -1
- data/spec/matchers.rb +2 -1
- data/spec/mongrel2/config/directory_spec.rb +2 -1
- data/spec/mongrel2/config/dsl_spec.rb +2 -1
- data/spec/mongrel2/config/filter_spec.rb +2 -1
- data/spec/mongrel2/config/handler_spec.rb +2 -1
- data/spec/mongrel2/config/host_spec.rb +2 -1
- data/spec/mongrel2/config/log_spec.rb +2 -1
- data/spec/mongrel2/config/proxy_spec.rb +2 -1
- data/spec/mongrel2/config/route_spec.rb +2 -1
- data/spec/mongrel2/config/server_spec.rb +2 -1
- data/spec/mongrel2/config/setting_spec.rb +2 -1
- data/spec/mongrel2/config/statistic_spec.rb +2 -1
- data/spec/mongrel2/config/xrequest_spec.rb +2 -1
- data/spec/mongrel2/config_spec.rb +2 -1
- data/spec/mongrel2/connection_spec.rb +2 -1
- data/spec/mongrel2/constants_spec.rb +2 -1
- data/spec/mongrel2/control_spec.rb +2 -1
- data/spec/mongrel2/handler_spec.rb +4 -3
- data/spec/mongrel2/httprequest_spec.rb +2 -1
- data/spec/mongrel2/httpresponse_spec.rb +2 -1
- data/spec/mongrel2/request_spec.rb +7 -1
- data/spec/mongrel2/response_spec.rb +9 -1
- data/spec/mongrel2/table_spec.rb +4 -3
- data/spec/mongrel2/testing_spec.rb +142 -0
- data/spec/mongrel2/websocket_spec.rb +300 -136
- data/spec/mongrel2/xmlrequest_spec.rb +2 -1
- data/spec/mongrel2_spec.rb +2 -1
- metadata +6 -5
- metadata.gz.sig +0 -0
data/lib/mongrel2/xmlrequest.rb
CHANGED
data/spec/constants.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'uri'
|
4
5
|
|
@@ -115,7 +116,7 @@ module Mongrel2::TestConstants # :nodoc:all
|
|
115
116
|
|
116
117
|
TEST_WEBSOCKET_HEADERS = {
|
117
118
|
'connection' => 'Upgrade',
|
118
|
-
'FLAGS' => '
|
119
|
+
'FLAGS' => '0x89',
|
119
120
|
'host' => 'host.example.com:80',
|
120
121
|
'METHOD' => 'WEBSOCKET',
|
121
122
|
'origin' => 'http://host.example.com:80',
|
data/spec/helpers.rb
CHANGED
data/spec/matchers.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require_relative '../helpers'
|
4
5
|
|
@@ -191,7 +192,7 @@ describe Mongrel2::Handler, :db do
|
|
191
192
|
|
192
193
|
expect( handler.conn ).to receive( :reply_close ).with( request )
|
193
194
|
expect( handler.conn ).to receive( :reply ) do |reply|
|
194
|
-
expect( reply ).to be_a( Mongrel2::WebSocket::
|
195
|
+
expect( reply ).to be_a( Mongrel2::WebSocket::Response )
|
195
196
|
expect( reply.opcode ).to eq( :close )
|
196
197
|
reply.payload.rewind
|
197
198
|
expect( reply.payload.read ).to start_with( '1008 ' )
|
@@ -214,7 +215,7 @@ describe Mongrel2::Handler, :db do
|
|
214
215
|
|
215
216
|
response = handler.dispatch_request( request )
|
216
217
|
|
217
|
-
expect( response ).to be_a( Mongrel2::WebSocket::
|
218
|
+
expect( response ).to be_a( Mongrel2::WebSocket::Response )
|
218
219
|
end
|
219
220
|
|
220
221
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require_relative '../helpers'
|
4
5
|
|
@@ -164,6 +165,11 @@ describe Mongrel2::Request, :db do
|
|
164
165
|
expect( @req.server_chroot.to_s ).to eq( '/' )
|
165
166
|
end
|
166
167
|
|
168
|
+
|
169
|
+
it "can return an ID for which sender and connection it's from" do
|
170
|
+
expect( @req.socket_id ).to eq( "#{@req.sender_id}:#{@req.conn_id}" )
|
171
|
+
end
|
172
|
+
|
167
173
|
end
|
168
174
|
|
169
175
|
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require_relative '../helpers'
|
4
5
|
|
@@ -68,6 +69,13 @@ describe Mongrel2::Response do
|
|
68
69
|
end
|
69
70
|
|
70
71
|
|
72
|
+
it "can return an ID for which sender and connection it's for" do
|
73
|
+
response = Mongrel2::Response.new( TEST_UUID, 8 )
|
74
|
+
|
75
|
+
expect( response.socket_id ).to eq( "#{response.sender_id}:#{response.conn_id}" )
|
76
|
+
end
|
77
|
+
|
78
|
+
|
71
79
|
context "an instance with default values" do
|
72
80
|
|
73
81
|
let( :response ) { Mongrel2::Response.new(TEST_UUID, 8) }
|
data/spec/mongrel2/table_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require_relative '../helpers'
|
4
5
|
|
@@ -111,8 +112,8 @@ describe Mongrel2::Table do
|
|
111
112
|
|
112
113
|
|
113
114
|
it "dupes its inner hash when duped" do
|
114
|
-
@table['foom'] = 'a string'
|
115
|
-
@table['frong'] =
|
115
|
+
@table['foom'] = +'a string'
|
116
|
+
@table['frong'] = [+'eenie', +'meenie', +'mynie', +'moe']
|
116
117
|
|
117
118
|
newtable = @table.dup
|
118
119
|
newtable['idkfa'] = 'god'
|
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env rspec -cfd
|
2
|
+
|
3
|
+
require_relative '../helpers'
|
4
|
+
|
5
|
+
require 'mongrel2/testing'
|
6
|
+
|
7
|
+
|
8
|
+
describe Mongrel2, "testing library" do
|
9
|
+
|
10
|
+
|
11
|
+
describe "RequestFactory" do
|
12
|
+
|
13
|
+
let( :described_class ) { Mongrel2::RequestFactory }
|
14
|
+
|
15
|
+
let( :factory ) { described_class.new( route: '/testing' ) }
|
16
|
+
|
17
|
+
|
18
|
+
it "can be created with reasonable defaults" do
|
19
|
+
factory = described_class.new
|
20
|
+
|
21
|
+
expect( factory ).to be_a( described_class )
|
22
|
+
expect( factory.sender_id ).to eq( described_class.default_factory_config[:sender_id] )
|
23
|
+
expect( factory.host ).to eq( described_class.default_factory_config[:host] )
|
24
|
+
expect( factory.port ).to eq( described_class.default_factory_config[:port] )
|
25
|
+
expect( factory.route ).to eq( described_class.default_factory_config[:route] )
|
26
|
+
expect( factory.conn_id ).to eq( described_class.default_factory_config[:conn_id] )
|
27
|
+
|
28
|
+
expect( factory.headers ).to eq( described_class.default_headers )
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
it "can be created with overridden config values" do
|
33
|
+
factory = described_class.new( sender_id: 'another_sender_id', conn_id: 202 )
|
34
|
+
|
35
|
+
expect( factory ).to be_a( described_class )
|
36
|
+
expect( factory.sender_id ).to eq( 'another_sender_id' )
|
37
|
+
expect( factory.host ).to eq( described_class.default_factory_config[:host] )
|
38
|
+
expect( factory.port ).to eq( described_class.default_factory_config[:port] )
|
39
|
+
expect( factory.route ).to eq( described_class.default_factory_config[:route] )
|
40
|
+
expect( factory.conn_id ).to eq( 202 )
|
41
|
+
|
42
|
+
expect( factory.headers ).to eq( described_class.default_headers )
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
it "can create a valid OPTIONS request" do
|
47
|
+
req = factory.options( '/testing' )
|
48
|
+
|
49
|
+
expect( req ).to be_a( Mongrel2::HTTPRequest )
|
50
|
+
expect( req.path ).to eq( '/testing' )
|
51
|
+
expect( req.headers[:method] ).to eq( 'OPTIONS' )
|
52
|
+
expect( req.body ).to be_a( StringIO ).and( be_eof )
|
53
|
+
expect( req.scheme ).to eq( 'http' )
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
it "can create a valid GET request" do
|
58
|
+
req = factory.get( '/testing' )
|
59
|
+
|
60
|
+
expect( req ).to be_a( Mongrel2::HTTPRequest )
|
61
|
+
expect( req.path ).to eq( '/testing' )
|
62
|
+
expect( req.headers[:method] ).to eq( 'GET' )
|
63
|
+
expect( req.body ).to be_a( StringIO ).and( be_eof )
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
it "can create a valid HEAD request" do
|
68
|
+
req = factory.head( '/testing' )
|
69
|
+
|
70
|
+
expect( req ).to be_a( Mongrel2::HTTPRequest )
|
71
|
+
expect( req.path ).to eq( '/testing' )
|
72
|
+
expect( req.headers[:method] ).to eq( 'HEAD' )
|
73
|
+
expect( req.body ).to be_a( StringIO ).and( be_eof )
|
74
|
+
expect( req.scheme ).to eq( 'http' )
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
it "can create a valid POST request" do
|
79
|
+
body = <<~END_OF_BODY
|
80
|
+
collection=screening
|
81
|
+
page=3
|
82
|
+
page_size=50
|
83
|
+
END_OF_BODY
|
84
|
+
|
85
|
+
req = factory.post( '/testing', body )
|
86
|
+
|
87
|
+
expect( req ).to be_a( Mongrel2::HTTPRequest )
|
88
|
+
expect( req.path ).to eq( '/testing' )
|
89
|
+
expect( req.headers[:method] ).to eq( 'POST' )
|
90
|
+
expect( req.body ).to be_a( StringIO )
|
91
|
+
expect( req.body.string ).to eq( body )
|
92
|
+
expect( req.scheme ).to eq( 'http' )
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
describe "WebSocketRequestFactory" do
|
99
|
+
|
100
|
+
let( :described_class ) { Mongrel2::WebSocketRequestFactory }
|
101
|
+
|
102
|
+
|
103
|
+
it "can be created with reasonable defaults" do
|
104
|
+
factory = described_class.new
|
105
|
+
|
106
|
+
expect( factory ).to be_a( described_class )
|
107
|
+
expect( factory.sender_id ).to eq( described_class.default_factory_config[:sender_id] )
|
108
|
+
expect( factory.host ).to eq( described_class.default_factory_config[:host] )
|
109
|
+
expect( factory.port ).to eq( described_class.default_factory_config[:port] )
|
110
|
+
expect( factory.route ).to eq( described_class.default_factory_config[:route] )
|
111
|
+
expect( factory.conn_id ).to eq( described_class.default_factory_config[:conn_id] )
|
112
|
+
|
113
|
+
expect( factory.headers ).to eq( described_class.default_headers )
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
it "can be created with overridden config values" do
|
118
|
+
factory = described_class.new( sender_id: 'another_sender_id', conn_id: 202 )
|
119
|
+
|
120
|
+
expect( factory ).to be_a( described_class )
|
121
|
+
expect( factory.sender_id ).to eq( 'another_sender_id' )
|
122
|
+
expect( factory.host ).to eq( described_class.default_factory_config[:host] )
|
123
|
+
expect( factory.port ).to eq( described_class.default_factory_config[:port] )
|
124
|
+
expect( factory.route ).to eq( described_class.default_factory_config[:route] )
|
125
|
+
expect( factory.conn_id ).to eq( 202 )
|
126
|
+
|
127
|
+
expect( factory.headers ).to eq( described_class.default_headers )
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
it "can create a valid handshake request" do
|
132
|
+
factory = described_class.new( route: '/ws_testing' )
|
133
|
+
|
134
|
+
req = factory.handshake( '/ws_testing' )
|
135
|
+
|
136
|
+
expect( req ).to be_a( Mongrel2::WebSocket::ClientHandshake )
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- ruby -*-
|
2
|
+
# frozen_string_literal: true
|
2
3
|
#encoding: utf-8
|
3
4
|
|
4
5
|
require_relative '../helpers'
|
@@ -19,7 +20,7 @@ require 'mongrel2/websocket'
|
|
19
20
|
describe Mongrel2::WebSocket do
|
20
21
|
|
21
22
|
before( :all ) do
|
22
|
-
@factory = Mongrel2::
|
23
|
+
@factory = Mongrel2::WebSocketRequestFactory.new( route: '/websock' )
|
23
24
|
end
|
24
25
|
|
25
26
|
|
@@ -43,7 +44,8 @@ describe Mongrel2::WebSocket do
|
|
43
44
|
describe 'ClientHandshake' do
|
44
45
|
|
45
46
|
it "is the registered request type for WEBSOCKET_HANDSHAKE requests" do
|
46
|
-
expect( Mongrel2::Request.request_types[:WEBSOCKET_HANDSHAKE] ).
|
47
|
+
expect( Mongrel2::Request.request_types[:WEBSOCKET_HANDSHAKE] ).
|
48
|
+
to eq( Mongrel2::WebSocket::ClientHandshake )
|
47
49
|
end
|
48
50
|
|
49
51
|
|
@@ -104,121 +106,345 @@ describe Mongrel2::WebSocket do
|
|
104
106
|
}.to raise_error( Mongrel2::WebSocket::HandshakeError, /map_updates/i )
|
105
107
|
end
|
106
108
|
|
109
|
+
end
|
107
110
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
|
112
|
+
describe 'Request' do
|
113
|
+
|
114
|
+
it "is the registered request type for WEBSOCKET requests" do
|
115
|
+
expect( Mongrel2::Request.request_types[:WEBSOCKET] ).
|
116
|
+
to eq( Mongrel2::WebSocket::Request )
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
it "creates a correct inner frame from the request data" do
|
121
|
+
request = @factory.text( '/websock', 'Hi, here is a message!', :fin )
|
122
|
+
|
123
|
+
expect( request.frame ).to be_a( Mongrel2::WebSocket::Frame )
|
124
|
+
expect( request.frame.opcode ).to eq( :text )
|
125
|
+
expect( request.frame ).to be_fin()
|
126
|
+
|
127
|
+
expect( request.frame.payload.string ).to eq( 'Hi, here is a message!' )
|
128
|
+
expect( request.frame.payload.external_encoding ).to eq( Encoding::UTF_8 )
|
111
129
|
end
|
112
130
|
|
113
|
-
end
|
114
131
|
|
132
|
+
it "can create a response for itself" do
|
133
|
+
request = @factory.text( '/websock', 'Hi, here is a message!', :fin )
|
134
|
+
|
135
|
+
result = request.response
|
136
|
+
|
137
|
+
expect( result ).to be_a( Mongrel2::WebSocket::Response )
|
138
|
+
expect( result.sender_id ).to eq( request.sender_id )
|
139
|
+
expect( result.conn_id ).to eq( request.conn_id )
|
140
|
+
|
141
|
+
expect( result.frame ).to be_a( Mongrel2::WebSocket::Frame )
|
142
|
+
expect( result.frame.opcode ).to eq( :text )
|
143
|
+
|
144
|
+
expect( result.frame.payload ).to be_a( StringIO )
|
145
|
+
expect( result.frame.payload.string ).to eq( '' )
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
it "creates PONG responses with the same payload for PING frames" do
|
150
|
+
request = @factory.ping( '/websock', 'WOO', :fin )
|
151
|
+
|
152
|
+
result = request.response
|
153
|
+
|
154
|
+
expect( result ).to be_a( Mongrel2::WebSocket::Response )
|
155
|
+
expect( result.sender_id ).to eq( request.sender_id )
|
156
|
+
expect( result.conn_id ).to eq( request.conn_id )
|
157
|
+
expect( result.opcode ).to eq( :pong )
|
158
|
+
|
159
|
+
result.payload.rewind
|
160
|
+
expect( result.payload.read ).to eq( 'WOO' )
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
it "allows header flags and/or opcode to be specified when creating a response" do
|
165
|
+
request = @factory.text( '/websock', 'some bad data', :fin )
|
166
|
+
|
167
|
+
result = request.response( :close, :fin )
|
168
|
+
|
169
|
+
expect( result ).to be_a( Mongrel2::WebSocket::Response )
|
170
|
+
expect( result.sender_id ).to eq( request.sender_id )
|
171
|
+
expect( result.conn_id ).to eq( request.conn_id )
|
172
|
+
expect( result.opcode ).to eq( :close )
|
173
|
+
expect( result ).to be_fin()
|
174
|
+
|
175
|
+
result.payload.rewind
|
176
|
+
expect( result.payload.read ).to eq( '' )
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
it "allows reserved opcodes to be specified when creating a response" do
|
181
|
+
request = @factory.text( '/websock', 'some bad data', :fin )
|
182
|
+
|
183
|
+
result = request.response( 0xB )
|
184
|
+
|
185
|
+
expect( result ).to be_a( Mongrel2::WebSocket::Response )
|
186
|
+
expect( result.sender_id ).to eq( request.sender_id )
|
187
|
+
expect( result.conn_id ).to eq( request.conn_id )
|
188
|
+
expect( result.opcode ).to eq( :reserved )
|
189
|
+
expect( result.numeric_opcode ).to eq( 0xB )
|
190
|
+
|
191
|
+
result.payload.rewind
|
192
|
+
expect( result.payload.read ).to eq( '' )
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
115
196
|
|
116
197
|
|
117
198
|
describe 'Frame' do
|
118
199
|
|
119
|
-
it "
|
120
|
-
|
200
|
+
it "has an iterator for fragmentation" do
|
201
|
+
data = <<~END_DATA
|
202
|
+
That the only purpose for which power can be rightfully exercised
|
203
|
+
over any member of a civilised community, against his will, is to
|
204
|
+
prevent harm to others.
|
205
|
+
END_DATA
|
206
|
+
|
207
|
+
io = StringIO.new( data )
|
208
|
+
iter = Mongrel2::WebSocket::Frame.each_fragment( io, :text, size: 64 )
|
209
|
+
|
210
|
+
expect( iter ).to be_a( Enumerator )
|
211
|
+
frames = iter.to_a
|
212
|
+
|
213
|
+
expect( frames ).to all( be_a Mongrel2::WebSocket::Frame )
|
214
|
+
expect( frames.size ).to eq( 3 )
|
215
|
+
|
216
|
+
expect( frames[0] ).to_not be_fin()
|
217
|
+
expect( frames[0].opcode ).to eq( :text )
|
218
|
+
expect( frames[0].payload.string ).to eq( data[0..63] )
|
219
|
+
|
220
|
+
expect( frames[1] ).to_not be_fin()
|
221
|
+
expect( frames[1].opcode ).to eq( :continuation )
|
222
|
+
expect( frames[1].payload.string ).to eq( data[64..127] )
|
223
|
+
|
224
|
+
expect( frames[2] ).to be_fin()
|
225
|
+
expect( frames[2].opcode ).to eq( :continuation )
|
226
|
+
expect( frames[2].payload.string ).to eq( data[128..191] )
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
it "doesn't fragment if the data read by the fragmentation iterator fits in one frame" do
|
231
|
+
data = <<~END_DATA
|
232
|
+
That the only purpose for which power can be rightfully exercised
|
233
|
+
over any member of a civilised community, against his will, is to
|
234
|
+
prevent harm to others.
|
235
|
+
END_DATA
|
236
|
+
|
237
|
+
io = StringIO.new( data )
|
238
|
+
iter = Mongrel2::WebSocket::Frame.each_fragment( io, :text, size: 4096 )
|
239
|
+
|
240
|
+
expect( iter ).to be_a( Enumerator )
|
241
|
+
frames = iter.to_a
|
242
|
+
|
243
|
+
expect( frames ).to all( be_a Mongrel2::WebSocket::Frame )
|
244
|
+
expect( frames.size ).to eq( 1 )
|
245
|
+
|
246
|
+
expect( frames[0] ).to be_fin()
|
247
|
+
expect( frames[0].opcode ).to eq( :text )
|
248
|
+
expect( frames[0].payload.string ).to eq( data[0..4096] )
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
it "has a constructor for CONTINUATION frames" do
|
253
|
+
frame = Mongrel2::WebSocket::Frame.continuation
|
254
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
255
|
+
expect( frame ).to be_fin()
|
256
|
+
expect( frame ).to_not be_control()
|
257
|
+
expect( frame.opcode ).to eq( :continuation )
|
258
|
+
end
|
259
|
+
|
260
|
+
|
261
|
+
it "has a constructor for TEXT frames" do
|
262
|
+
frame = Mongrel2::WebSocket::Frame.text
|
263
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
264
|
+
expect( frame ).to be_fin()
|
265
|
+
expect( frame ).to_not be_control()
|
266
|
+
expect( frame.opcode ).to eq( :text )
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
it "has a constructor for BINARY frames" do
|
271
|
+
frame = Mongrel2::WebSocket::Frame.binary
|
272
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
273
|
+
expect( frame ).to be_fin()
|
274
|
+
expect( frame ).to_not be_control()
|
275
|
+
expect( frame.opcode ).to eq( :binary )
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
it "has a constructor for PING frames" do
|
280
|
+
frame = Mongrel2::WebSocket::Frame.ping
|
281
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
282
|
+
expect( frame ).to be_fin()
|
283
|
+
expect( frame ).to be_control()
|
284
|
+
expect( frame.opcode ).to eq( :ping )
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
it "has a constructor for PONG frames" do
|
289
|
+
frame = Mongrel2::WebSocket::Frame.pong
|
290
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
291
|
+
expect( frame ).to be_fin()
|
292
|
+
expect( frame ).to be_control()
|
293
|
+
expect( frame.opcode ).to eq( :pong )
|
294
|
+
end
|
295
|
+
|
296
|
+
|
297
|
+
it "has a constructor for CLOSE frames" do
|
298
|
+
frame = Mongrel2::WebSocket::Frame.close
|
299
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
300
|
+
expect( frame ).to be_fin()
|
301
|
+
expect( frame ).to be_control()
|
302
|
+
expect( frame.opcode ).to eq( :close )
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
it "is parsed from the body of a Mongrel2::WebSocket::Request" do
|
307
|
+
request = @factory.ping( '/websock', 'Ping!' )
|
308
|
+
frame = request.frame
|
309
|
+
|
310
|
+
expect( frame ).to be_a( Mongrel2::WebSocket::Frame )
|
311
|
+
expect( frame.flags ).to be_an( Integer )
|
312
|
+
expect( frame ).to be_fin
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
it "can set its flags by name" do
|
317
|
+
frame = Mongrel2::WebSocket::Frame.new
|
318
|
+
frame.flags = 0x00
|
319
|
+
|
320
|
+
frame.set_flags( :fin, :rsv2, :continuation )
|
321
|
+
|
322
|
+
expect( frame.flags ).to eq( FIN_FLAG | RSV2_FLAG | OPCODE[:continuation] )
|
323
|
+
end
|
324
|
+
|
325
|
+
|
326
|
+
it "can set its flags with an integer" do
|
327
|
+
frame = Mongrel2::WebSocket::Frame.new
|
328
|
+
frame.flags = 0x00
|
329
|
+
|
330
|
+
frame.set_flags( FIN_FLAG | OPCODE[:close] )
|
331
|
+
|
332
|
+
expect( frame ).to be_fin()
|
333
|
+
expect( frame.opcode ).to eq( :close )
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
it "can set its flags with a hex string" do
|
338
|
+
frame = Mongrel2::WebSocket::Frame.new
|
339
|
+
frame.flags = 0x00
|
340
|
+
|
341
|
+
frame.set_flags( '0x8A' )
|
342
|
+
|
343
|
+
expect( frame ).to be_fin()
|
344
|
+
expect( frame.opcode ).to eq( :pong )
|
121
345
|
end
|
122
346
|
|
123
347
|
|
124
348
|
it "knows that its FIN flag is not set if its FLAG header doesn't include that bit" do
|
125
|
-
frame =
|
126
|
-
frame.flags ^= ( frame.flags &
|
349
|
+
frame = Mongrel2::WebSocket::Frame.text( 'Hello!' )
|
350
|
+
frame.flags ^= ( frame.flags & FIN_FLAG )
|
127
351
|
expect( frame ).to_not be_fin()
|
128
352
|
end
|
129
353
|
|
130
354
|
|
131
355
|
it "knows that its FIN flag is set if its FLAG header includes that bit" do
|
132
|
-
frame =
|
356
|
+
frame = Mongrel2::WebSocket::Frame.text( 'Hello!' )
|
357
|
+
frame.flags |= FIN_FLAG
|
133
358
|
expect( frame ).to be_fin()
|
134
359
|
end
|
135
360
|
|
136
361
|
|
137
|
-
it "can unset its FIN flag" do
|
138
|
-
frame =
|
362
|
+
it "can unset its FIN flag via an accessor" do
|
363
|
+
frame = Mongrel2::WebSocket::Frame.text( 'Hello!', :fin )
|
139
364
|
frame.fin = false
|
140
365
|
expect( frame ).to_not be_fin()
|
141
366
|
end
|
142
367
|
|
143
368
|
|
144
369
|
it "can set its FIN flag" do
|
145
|
-
frame =
|
370
|
+
frame = Mongrel2::WebSocket::Frame.text( 'Hello!' )
|
371
|
+
frame.flags ^= ( frame.flags & FIN_FLAG )
|
146
372
|
frame.fin = true
|
147
373
|
expect( frame ).to be_fin()
|
148
374
|
end
|
149
375
|
|
150
376
|
|
151
377
|
it "knows that its opcode is continuation if its opcode is 0x0" do
|
152
|
-
expect( @factory.continuation(
|
378
|
+
expect( @factory.continuation('/websock').opcode ).to eq( :continuation )
|
153
379
|
end
|
154
380
|
|
155
381
|
|
156
382
|
it "knows that is opcode is 'text' if its opcode is 0x1" do
|
157
|
-
expect(
|
383
|
+
expect( Mongrel2::WebSocket::Frame.text('Hello!').opcode ).to eq( :text )
|
158
384
|
end
|
159
385
|
|
160
386
|
|
161
387
|
it "knows that is opcode is 'binary' if its opcode is 0x2" do
|
162
|
-
expect(
|
388
|
+
expect( Mongrel2::WebSocket::Frame.binary('Hello!').opcode ).to eq( :binary )
|
163
389
|
end
|
164
390
|
|
165
391
|
|
166
392
|
it "knows that is opcode is 'close' if its opcode is 0x8" do
|
167
|
-
expect(
|
393
|
+
expect( Mongrel2::WebSocket::Frame.close.opcode ).to eq( :close )
|
168
394
|
end
|
169
395
|
|
170
396
|
|
171
397
|
it "knows that is opcode is 'ping' if its opcode is 0x9" do
|
172
|
-
expect(
|
398
|
+
expect( Mongrel2::WebSocket::Frame.ping.opcode ).to eq( :ping )
|
173
399
|
end
|
174
400
|
|
175
401
|
|
176
402
|
it "knows that is opcode is 'pong' if its opcode is 0xA" do
|
177
|
-
expect(
|
403
|
+
expect( Mongrel2::WebSocket::Frame.pong.opcode ).to eq( :pong )
|
178
404
|
end
|
179
405
|
|
180
406
|
|
181
407
|
it "knows that its opcode is one of the reserved ones if it's 0x3" do
|
182
|
-
expect(
|
408
|
+
expect( Mongrel2::WebSocket::Frame.new('', 0x3).opcode ).to eq( :reserved )
|
183
409
|
end
|
184
410
|
|
185
411
|
|
186
412
|
it "knows that its opcode is one of the reserved ones if it's 0x4" do
|
187
|
-
expect(
|
413
|
+
expect( Mongrel2::WebSocket::Frame.new('', 0x4).opcode ).to eq( :reserved )
|
188
414
|
end
|
189
415
|
|
190
416
|
|
191
417
|
it "knows that its opcode is one of the reserved ones if it's 0xB" do
|
192
|
-
expect(
|
418
|
+
expect( Mongrel2::WebSocket::Frame.new('', 0xB).opcode ).to eq( :reserved )
|
193
419
|
end
|
194
420
|
|
195
421
|
|
196
422
|
it "knows that its opcode is one of the reserved ones if it's 0xD" do
|
197
|
-
expect(
|
423
|
+
expect( Mongrel2::WebSocket::Frame.new('', 0xD).opcode ).to eq( :reserved )
|
198
424
|
end
|
199
425
|
|
200
426
|
|
201
427
|
it "knows that its opcode is one of the reserved ones if it's 0xF" do
|
202
|
-
expect(
|
428
|
+
expect( Mongrel2::WebSocket::Frame.new('', 0xF).opcode ).to eq( :reserved )
|
203
429
|
end
|
204
430
|
|
205
431
|
|
206
432
|
it "allows its opcode to be set Symbolically" do
|
207
|
-
frame =
|
433
|
+
frame = Mongrel2::WebSocket::Frame.text( 'data' )
|
208
434
|
frame.opcode = :binary
|
209
435
|
expect( frame.numeric_opcode ).to eq( OPCODE[:binary] )
|
210
436
|
end
|
211
437
|
|
212
438
|
|
213
439
|
it "allows its opcode to be set Numerically" do
|
214
|
-
frame =
|
440
|
+
frame = Mongrel2::WebSocket::Frame.binary( 'data' )
|
215
441
|
frame.opcode = :text
|
216
442
|
expect( frame.numeric_opcode ).to eq( OPCODE[:text] )
|
217
443
|
end
|
218
444
|
|
219
445
|
|
220
446
|
it "allows its opcode to be set to one of the reserved opcodes Numerically" do
|
221
|
-
frame =
|
447
|
+
frame = Mongrel2::WebSocket::Frame.binary( 'data' )
|
222
448
|
frame.opcode = 0xC
|
223
449
|
expect( frame.opcode ).to eq( :reserved )
|
224
450
|
expect( frame.numeric_opcode ).to eq( 0xC )
|
@@ -226,152 +452,94 @@ describe Mongrel2::WebSocket do
|
|
226
452
|
|
227
453
|
|
228
454
|
it "knows that its RSV1 flag is set if its FLAG header includes that bit" do
|
229
|
-
expect(
|
455
|
+
expect( Mongrel2::WebSocket::Frame.ping('test', :rsv1) ).to be_rsv1()
|
230
456
|
end
|
231
457
|
|
232
458
|
|
233
459
|
it "knows that its RSV2 flag is set if its FLAG header includes that bit" do
|
234
|
-
expect(
|
460
|
+
expect( Mongrel2::WebSocket::Frame.ping('test', :rsv2) ).to be_rsv2()
|
235
461
|
end
|
236
462
|
|
237
463
|
|
238
464
|
it "knows that its RSV3 flag is set if its FLAG header includes that bit" do
|
239
|
-
expect(
|
465
|
+
expect( Mongrel2::WebSocket::Frame.ping('test', :rsv3) ).to be_rsv3()
|
240
466
|
end
|
241
467
|
|
242
468
|
|
243
469
|
it "knows that one of its RSV flags is set if its FLAG header includes RSV1" do
|
244
|
-
expect(
|
470
|
+
expect( Mongrel2::WebSocket::Frame.ping('test', :rsv1) ).to have_rsv_flags()
|
245
471
|
end
|
246
472
|
|
247
473
|
|
248
474
|
it "knows that one of its RSV flags is set if its FLAG header includes RSV2" do
|
249
|
-
expect(
|
475
|
+
expect( Mongrel2::WebSocket::Frame.ping('test', :rsv2) ).to have_rsv_flags()
|
250
476
|
end
|
251
477
|
|
252
478
|
|
253
479
|
it "knows that one of its RSV flags is set if its FLAG header includes RSV3" do
|
254
|
-
expect(
|
480
|
+
expect( Mongrel2::WebSocket::Frame.ping('test', :rsv3) ).to have_rsv_flags()
|
255
481
|
end
|
256
482
|
|
257
483
|
|
258
484
|
it "knows that no RSV flags are set if its FLAG header doesn't have any RSV bits" do
|
259
|
-
expect(
|
260
|
-
end
|
261
|
-
|
262
|
-
|
263
|
-
it "can create a response WebSocket::Frame for itself" do
|
264
|
-
frame = @factory.text( '/websock', "Hi, here's a message!", :fin )
|
265
|
-
|
266
|
-
result = frame.response
|
267
|
-
|
268
|
-
expect( result ).to be_a( Mongrel2::WebSocket::Frame )
|
269
|
-
expect( result.sender_id ).to eq( frame.sender_id )
|
270
|
-
expect( result.conn_id ).to eq( frame.conn_id )
|
271
|
-
expect( result.opcode ).to eq( :text )
|
272
|
-
|
273
|
-
result.payload.rewind
|
274
|
-
expect( result.payload.read ).to eq( '' )
|
275
|
-
end
|
276
|
-
|
277
|
-
|
278
|
-
it "creates PONG responses with the same payload for PING frames" do
|
279
|
-
frame = @factory.ping( '/websock', "WOO" )
|
280
|
-
|
281
|
-
result = frame.response
|
282
|
-
|
283
|
-
expect( result ).to be_a( Mongrel2::WebSocket::Frame )
|
284
|
-
expect( result.sender_id ).to eq( frame.sender_id )
|
285
|
-
expect( result.conn_id ).to eq( frame.conn_id )
|
286
|
-
expect( result.opcode ).to eq( :pong )
|
287
|
-
|
288
|
-
result.payload.rewind
|
289
|
-
expect( result.payload.read ).to eq( 'WOO' )
|
290
|
-
end
|
291
|
-
|
292
|
-
|
293
|
-
it "allows header flags and/or opcode to be specified when creating a response" do
|
294
|
-
frame = @factory.text( '/websock', "some bad data" )
|
295
|
-
|
296
|
-
result = frame.response( :close, :fin )
|
297
|
-
|
298
|
-
expect( result ).to be_a( Mongrel2::WebSocket::Frame )
|
299
|
-
expect( result.sender_id ).to eq( frame.sender_id )
|
300
|
-
expect( result.conn_id ).to eq( frame.conn_id )
|
301
|
-
expect( result.opcode ).to eq( :close )
|
302
|
-
expect( result ).to be_fin()
|
303
|
-
|
304
|
-
result.payload.rewind
|
305
|
-
expect( result.payload.read ).to eq( '' )
|
306
|
-
end
|
307
|
-
|
308
|
-
|
309
|
-
it "allows reserved opcodes to be specified when creating a response" do
|
310
|
-
frame = @factory.text( '/websock', "some bad data" )
|
311
|
-
|
312
|
-
result = frame.response( 0xB )
|
313
|
-
|
314
|
-
expect( result ).to be_a( Mongrel2::WebSocket::Frame )
|
315
|
-
expect( result.sender_id ).to eq( frame.sender_id )
|
316
|
-
expect( result.conn_id ).to eq( frame.conn_id )
|
317
|
-
expect( result.opcode ).to eq( :reserved )
|
318
|
-
expect( result.numeric_opcode ).to eq( 0xB )
|
319
|
-
|
320
|
-
result.payload.rewind
|
321
|
-
expect( result.payload.read ).to eq( '' )
|
485
|
+
expect( Mongrel2::WebSocket::Frame.ping('test') ).to_not have_rsv_flags()
|
322
486
|
end
|
323
487
|
|
324
488
|
|
325
489
|
it "can be streamed in chunks instead of read all at once" do
|
326
490
|
data = BINARY_DATA * 256
|
327
|
-
binary =
|
491
|
+
binary = Mongrel2::WebSocket::Frame.binary( data )
|
328
492
|
|
329
493
|
binary.chunksize = 16
|
330
494
|
expect( binary.each_chunk.to_a[0,2] ).to eq([
|
331
|
-
"\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00\a\xBD\xB3\xFE\x87\xEB".
|
332
|
-
"\xA9\x0En2q\xCE\x85\xAF)\x88w_d\xD6M\x9E".
|
495
|
+
"\x82\x7F\x00\x00\x00\x00\x00\x01\x00\x00\a\xBD\xB3\xFE\x87\xEB".b,
|
496
|
+
"\xA9\x0En2q\xCE\x85\xAF)\x88w_d\xD6M\x9E".b,
|
333
497
|
])
|
334
498
|
end
|
335
499
|
|
336
|
-
|
337
|
-
it "has a socket identifier" do
|
338
|
-
frame = @factory.text( '/websock', "data" )
|
339
|
-
expect( frame.socket_id ).to eq( "#{frame.sender_id}:#{frame.conn_id}" )
|
340
|
-
end
|
341
|
-
|
342
500
|
end
|
343
501
|
|
344
502
|
|
345
503
|
describe "a WebSocket text frame" do
|
346
504
|
|
347
|
-
|
348
|
-
@frame = @factory.text( '/websock', '', :fin )
|
349
|
-
end
|
505
|
+
let( :frame ) { Mongrel2::WebSocket::Frame.text }
|
350
506
|
|
351
507
|
|
352
508
|
it "automatically transcodes its payload to UTF8" do
|
353
509
|
text = "Стрелке!".encode( Encoding::KOI8_U )
|
354
|
-
|
510
|
+
frame << text
|
355
511
|
|
356
512
|
# 2-byte header
|
357
|
-
expect(
|
513
|
+
expect( frame.bytes.to_a[ 2..-1 ] ).
|
358
514
|
to eq([0xD0, 0xA1, 0xD1, 0x82, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xBB, 0xD0,
|
359
515
|
0xBA, 0xD0, 0xB5, 0x21])
|
360
516
|
end
|
361
517
|
|
518
|
+
|
519
|
+
it "automatically transcodes multi-part payloads to UTF8" do
|
520
|
+
text1 = "Стрелке!".encode( Encoding::KOI8_U )
|
521
|
+
text2 = "Chiitan 妖精ちぃたん"
|
522
|
+
frame << text1 << text2
|
523
|
+
|
524
|
+
# 2-byte header
|
525
|
+
expect( frame.bytes.to_a[ 2..-1 ] ).
|
526
|
+
to eq([ 0xD0, 0xA1, 0xD1, 0x82, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xBB, 0xD0,
|
527
|
+
0xBA, 0xD0, 0xB5, 0x21, 0x43, 0x68, 0x69, 0x69, 0x74, 0x61, 0x6e,
|
528
|
+
0x20, 0xe5, 0xa6, 0x96, 0xe7, 0xb2, 0xbe, 0xe3, 0x81, 0xa1, 0xe3,
|
529
|
+
0x81, 0x83, 0xe3, 0x81, 0x9f, 0xe3, 0x82, 0x93 ])
|
530
|
+
end
|
531
|
+
|
362
532
|
end
|
363
533
|
|
364
534
|
|
365
535
|
describe "a WebSocket binary frame" do
|
366
536
|
|
367
|
-
|
368
|
-
@frame = @factory.binary( '/websock', BINARY_DATA, :fin )
|
369
|
-
end
|
537
|
+
let( :frame ) { Mongrel2::WebSocket::Frame.binary(BINARY_DATA) }
|
370
538
|
|
371
539
|
|
372
540
|
it "doesn't try to transcode non-UTF8 data" do
|
373
541
|
# 4-byte header
|
374
|
-
expect(
|
542
|
+
expect( frame.bytes.to_a[ 4, 16 ] ).
|
375
543
|
to eq([ 0x07, 0xbd, 0xb3, 0xfe, 0x87, 0xeb, 0xa9, 0x0e, 0x6e, 0x32, 0x71,
|
376
544
|
0xce, 0x85, 0xaf, 0x29, 0x88 ])
|
377
545
|
end
|
@@ -381,15 +549,12 @@ describe Mongrel2::WebSocket do
|
|
381
549
|
|
382
550
|
describe "a WebSocket close frame" do
|
383
551
|
|
384
|
-
|
385
|
-
@frame = @factory.close( '/websock' )
|
386
|
-
end
|
552
|
+
let( :frame ) { Mongrel2::WebSocket::Frame.close }
|
387
553
|
|
388
554
|
|
389
555
|
it "has convenience methods for setting its payload via integer status code" do
|
390
|
-
|
391
|
-
|
392
|
-
expect( @frame.payload.read ).
|
556
|
+
frame.set_status( CLOSE_BAD_DATA )
|
557
|
+
expect( frame.payload.string ).
|
393
558
|
to eq( "%d %s\n" % [CLOSE_BAD_DATA, CLOSING_STATUS_DESC[CLOSE_BAD_DATA]] )
|
394
559
|
end
|
395
560
|
|
@@ -398,23 +563,21 @@ describe Mongrel2::WebSocket do
|
|
398
563
|
|
399
564
|
describe "WebSocket control frames" do
|
400
565
|
|
401
|
-
|
402
|
-
@frame = @factory.close( '/websock', "1002 Protocol error" )
|
403
|
-
end
|
566
|
+
let( :frame ) { Mongrel2::WebSocket::Frame.close("1002 Protocol error") }
|
404
567
|
|
405
568
|
|
406
569
|
it "raises an exception if its payload is bigger than 125 bytes" do
|
407
|
-
|
570
|
+
frame.body << "x" * 126
|
408
571
|
expect {
|
409
|
-
|
572
|
+
frame.validate
|
410
573
|
}.to raise_error( Mongrel2::WebSocket::FrameError, /cannot exceed 125 bytes/i )
|
411
574
|
end
|
412
575
|
|
413
576
|
|
414
577
|
it "raises an exception if it's fragmented" do
|
415
|
-
|
578
|
+
frame.fin = false
|
416
579
|
expect {
|
417
|
-
|
580
|
+
frame.validate
|
418
581
|
}.to raise_error( Mongrel2::WebSocket::FrameError, /fragmented/i )
|
419
582
|
end
|
420
583
|
|
@@ -424,15 +587,16 @@ describe Mongrel2::WebSocket do
|
|
424
587
|
describe "RFC examples (the applicable ones, anyway)" do
|
425
588
|
|
426
589
|
it "generates a single-frame unmasked text message correctly" do
|
427
|
-
raw_response =
|
590
|
+
raw_response = Mongrel2::WebSocket::Frame.text( "Hello", :fin ).to_s
|
428
591
|
expect( raw_response.bytes.to_a ).to eq( [ 0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f ] )
|
429
592
|
expect( raw_response.encoding ).to eq( Encoding::BINARY )
|
430
593
|
end
|
431
594
|
|
432
595
|
|
433
596
|
it "generates both parts of a fragmented unmasked text message correctly" do
|
434
|
-
first =
|
435
|
-
|
597
|
+
first = Mongrel2::WebSocket::Frame.text( 'Hel' )
|
598
|
+
first.fin = false
|
599
|
+
last = Mongrel2::WebSocket::Frame.continuation( 'lo' )
|
436
600
|
|
437
601
|
expect( first.bytes.to_a ).to eq( [ 0x01, 0x03, 0x48, 0x65, 0x6c ] )
|
438
602
|
expect( last.bytes.to_a ).to eq( [ 0x80, 0x02, 0x6c, 0x6f ] )
|
@@ -442,8 +606,8 @@ describe Mongrel2::WebSocket do
|
|
442
606
|
# The RFC's example is a masked response, but we're never a client, so never
|
443
607
|
# generate masked payloads.
|
444
608
|
it "generates a unmasked Ping request and (un)masked Ping response correctly" do
|
445
|
-
ping =
|
446
|
-
pong =
|
609
|
+
ping = Mongrel2::WebSocket::Frame.ping( 'Hello' )
|
610
|
+
pong = Mongrel2::WebSocket::Frame.pong( 'Hello' )
|
447
611
|
|
448
612
|
expect( ping.bytes.to_a ).to eq( [ 0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f ] )
|
449
613
|
expect( pong.bytes.to_a ).to eq( [ 0x8a, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f ] )
|
@@ -451,7 +615,7 @@ describe Mongrel2::WebSocket do
|
|
451
615
|
|
452
616
|
|
453
617
|
it "generates a 256-byte binary message in a single unmasked frame" do
|
454
|
-
binary =
|
618
|
+
binary = Mongrel2::WebSocket::Frame.binary( BINARY_DATA, :fin )
|
455
619
|
|
456
620
|
# 1 + 1 + 2
|
457
621
|
expect( binary.bytes.to_a[0,4] ).to eq( [ 0x82, 0x7E, 0x01, 0x00 ] )
|
@@ -462,7 +626,7 @@ describe Mongrel2::WebSocket do
|
|
462
626
|
it "generates a 64KiB binary message in a single unmasked frame correctly" do
|
463
627
|
data = BINARY_DATA * 256
|
464
628
|
|
465
|
-
binary =
|
629
|
+
binary = Mongrel2::WebSocket::Frame.binary( data, :fin )
|
466
630
|
|
467
631
|
# 1 + 1 + 8
|
468
632
|
expect( binary.bytes.to_a[0,10] ).
|