mongrel2 0.52.2 → 0.53.0
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 +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] ).
|