mongrel2 0.15.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,8 @@ require 'mongrel2' unless defined?( Mongrel2 )
10
10
  ### A collection of constants used in testing
11
11
  module Mongrel2::TestConstants # :nodoc:all
12
12
 
13
- include Mongrel2::Constants
13
+ include Mongrel2::Constants,
14
+ Mongrel2::WebSocket::Constants
14
15
 
15
16
  unless defined?( TEST_HOST )
16
17
 
@@ -17,6 +17,7 @@ require 'spec/lib/helpers'
17
17
 
18
18
  require 'mongrel2'
19
19
  require 'mongrel2/httprequest'
20
+ require 'mongrel2/httpresponse'
20
21
 
21
22
 
22
23
  #####################################################################
@@ -113,7 +113,7 @@ describe Mongrel2::Request do
113
113
  describe "framework support" do
114
114
 
115
115
  before( :all ) do
116
- @oldtypes = Mongrel2::Request.request_types
116
+ @oldtypes = Mongrel2::Request.request_types.dup
117
117
  @original_default_proc = Mongrel2::Request.request_types.default_proc
118
118
  end
119
119
 
@@ -0,0 +1,295 @@
1
+ #!/usr/bin/env ruby
2
+ #encoding: utf-8
3
+
4
+ BEGIN {
5
+ require 'pathname'
6
+ basedir = Pathname.new( __FILE__ ).dirname.parent.parent
7
+
8
+ libdir = basedir + "lib"
9
+
10
+ $LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
11
+ $LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
12
+ }
13
+
14
+ require 'rspec'
15
+ require 'tnetstring'
16
+ require 'securerandom'
17
+
18
+ require 'spec/lib/helpers'
19
+
20
+ require 'mongrel2'
21
+ require 'mongrel2/websocket'
22
+
23
+
24
+ #####################################################################
25
+ ### C O N T E X T S
26
+ #####################################################################
27
+
28
+ describe Mongrel2::WebSocket do
29
+
30
+ before( :all ) do
31
+ setup_logging( :fatal )
32
+ @factory = Mongrel2::WebSocketFrameFactory.new( route: '/websock' )
33
+ end
34
+
35
+ after( :all ) do
36
+ reset_logging()
37
+ end
38
+
39
+ # Data for testing payload of binary frames
40
+ BINARY_DATA =
41
+ "\a\xBD\xB3\xFE\x87\xEB\xA9\x0En2q\xCE\x85\xAF)\x88w_d\xD6M" +
42
+ "\x9E\xAF\xCB\x89\x8F\xC8\xA0\x80ZL+\a\x9C\xF7{`\x9E'\xCF\xD9" +
43
+ "\xE8\xA5\x9C\xF7T\xE2\xDD\xF5\xE9\x14\x1F,?\xD2\nQ\f\x06\x96" +
44
+ "\x19\xB7\x06\x9F\xCD+*\x01\xC7\x98\xFE\x8A\x81\x04\xFF\xA7.J" +
45
+ "\xF1\x9F\x9E\xEB$<;\x99>q\xBA\x12\xB3&i\xCCaE}\xAA\x87>ya\x0E" +
46
+ "\xB0n\xD8lN\xE5\b\x83\xBB\x1D1\xFD\e\x84\xC1\xB4\x99\xC7\xCA" +
47
+ "\xF8}C\xF2\xC6\x04\xA208\xA1\xCF\xB9\xFF\xF2\x9C~mbi\xBC\xE0" +
48
+ "\xBE\xFER\xB5B#\xF1Z^\xB6\x80\xD2\x8E=t\xC6\x86`\xFAY\xD9\x01" +
49
+ "\xBF\xA7\x88\xE1rf?C\xB8XC\xEF\x9F\xB1j,\xC7\xE4\x9E\x86)7\"f0" +
50
+ "\xA0FH\xFC\x99\xCA\xB3D\x06ar\x9C\xEC\xE9\xAEj:\xFD\x1C\x06H\xF0" +
51
+ "\xF1w~\xEC\r\x7F\x00\xED\xD88\x81\xF0/\x99\xD7\x9D\xA9C\x06\xEF" +
52
+ "\x9B\xF3\x17\a\xDB\v{\e\xA3\tKTPV\xB8\xCB\xBB\xC9\x87f\\\xD0\x165"
53
+ BINARY_DATA.force_encoding( Encoding::ASCII_8BIT )
54
+
55
+
56
+ describe 'Frame' do
57
+
58
+ it "is the registered request type for WEBSOCKET requests" do
59
+ Mongrel2::Request.request_types[:WEBSOCKET].should == Mongrel2::WebSocket::Frame
60
+ end
61
+
62
+ it "knows that its FIN flag is not set if its FLAG header doesn't include that bit" do
63
+ frame = @factory.text( '/websock', 'Hello!' )
64
+ frame.flags ^= ( frame.flags & Mongrel2::WebSocket::FIN_FLAG )
65
+ frame.should_not be_fin()
66
+ end
67
+
68
+ it "knows that its FIN flag is set if its FLAG header includes that bit" do
69
+ frame = @factory.text( '/websock', 'Hello!', :fin )
70
+ frame.should be_fin()
71
+ end
72
+
73
+ it "can unset its FIN flag" do
74
+ frame = @factory.text( '/websock', 'Hello!', :fin )
75
+ frame.fin = false
76
+ frame.should_not be_fin()
77
+ end
78
+
79
+ it "can set its FIN flag" do
80
+ frame = @factory.text( '/websock', 'Hello!' )
81
+ frame.fin = true
82
+ frame.should be_fin()
83
+ end
84
+
85
+ it "knows that its opcode is continuation if its opcode is 0x0" do
86
+ @factory.continuation( '/websock' ).opcode.should == :continuation
87
+ end
88
+
89
+ it "knows that is opcode is 'text' if its opcode is 0x1" do
90
+ @factory.text( '/websock', 'Hello!' ).opcode.should == :text
91
+ end
92
+
93
+ it "knows that is opcode is 'binary' if its opcode is 0x2" do
94
+ @factory.binary( '/websock', 'Hello!' ).opcode.should == :binary
95
+ end
96
+
97
+ it "knows that is opcode is 'close' if its opcode is 0x8" do
98
+ @factory.close( '/websock' ).opcode.should == :close
99
+ end
100
+
101
+ it "knows that is opcode is 'ping' if its opcode is 0x9" do
102
+ @factory.ping( '/websock' ).opcode.should == :ping
103
+ end
104
+
105
+ it "knows that is opcode is 'pong' if its opcode is 0xA" do
106
+ @factory.pong( '/websock' ).opcode.should == :pong
107
+ end
108
+
109
+ it "knows that its RSV1 flag is set if its FLAG header includes that bit" do
110
+ @factory.ping( '/websock', 'test', :rsv1 ).should be_rsv1()
111
+ end
112
+
113
+ it "knows that its RSV2 flag is set if its FLAG header includes that bit" do
114
+ @factory.ping( '/websock', 'test', :rsv2 ).should be_rsv2()
115
+ end
116
+
117
+ it "knows that its RSV3 flag is set if its FLAG header includes that bit" do
118
+ @factory.ping( '/websock', 'test', :rsv3 ).should be_rsv3()
119
+ end
120
+
121
+ it "knows that one of its RSV flags is set if its FLAG header includes RSV1" do
122
+ @factory.ping( '/websock', 'test', :rsv1 ).should have_rsv_flags()
123
+ end
124
+
125
+ it "knows that one of its RSV flags is set if its FLAG header includes RSV2" do
126
+ @factory.ping( '/websock', 'test', :rsv2 ).should have_rsv_flags()
127
+ end
128
+
129
+ it "knows that one of its RSV flags is set if its FLAG header includes RSV3" do
130
+ @factory.ping( '/websock', 'test', :rsv3 ).should have_rsv_flags()
131
+ end
132
+
133
+ it "knows that no RSV flags are set if its FLAG header doesn't have any RSV bits" do
134
+ @factory.ping( '/websock', 'test' ).should_not have_rsv_flags()
135
+ end
136
+
137
+ it "can create a response WebSocket::Frame for itself" do
138
+ frame = @factory.text( '/websock', "Hi, here's a message!", :fin )
139
+
140
+ result = frame.response
141
+
142
+ result.should be_a( Mongrel2::WebSocket::Frame )
143
+ result.sender_id.should == frame.sender_id
144
+ result.conn_id.should == frame.conn_id
145
+ result.opcode.should == :text
146
+
147
+ result.payload.should == ''
148
+ end
149
+
150
+ it "creates PONG responses with the same payload for PING frames" do
151
+ frame = @factory.ping( '/websock', "WOO" )
152
+
153
+ result = frame.response
154
+
155
+ result.should be_a( Mongrel2::WebSocket::Frame )
156
+ result.sender_id.should == frame.sender_id
157
+ result.conn_id.should == frame.conn_id
158
+ result.opcode.should == :pong
159
+
160
+ result.payload.should == 'WOO'
161
+ end
162
+
163
+ it "allows header flags and/or opcode to be specified when creating a response" do
164
+ frame = @factory.text( '/websock', "some bad data" )
165
+
166
+ result = frame.response( :close, :fin )
167
+
168
+ result.should be_a( Mongrel2::WebSocket::Frame )
169
+ result.sender_id.should == frame.sender_id
170
+ result.conn_id.should == frame.conn_id
171
+ result.opcode.should == :close
172
+ result.should be_fin()
173
+
174
+ result.payload.should == ''
175
+ end
176
+
177
+ end
178
+
179
+
180
+ describe "a WebSocket text frame" do
181
+
182
+ before( :each ) do
183
+ @frame = @factory.text( '/websock', 'Damn the torpedoes!', :fin )
184
+ end
185
+
186
+ it "automatically transcodes its payload to UTF8" do
187
+ text = "Стрелке!".encode( Encoding::KOI8_U )
188
+ @frame.payload.replace( text )
189
+
190
+ @frame.to_s[ 2..-1 ].bytes.to_a.should ==
191
+ [0xD0, 0xA1, 0xD1, 0x82, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xBB, 0xD0,
192
+ 0xBA, 0xD0, 0xB5, 0x21]
193
+ end
194
+
195
+ end
196
+
197
+
198
+ describe "a WebSocket binary frame" do
199
+ before( :each ) do
200
+ @frame = @factory.binary( '/websock', BINARY_DATA, :fin )
201
+ end
202
+
203
+ it "doesn't try to transcode non-UTF8 data" do
204
+ @frame.to_s.encoding.should == Encoding::ASCII_8BIT
205
+ end
206
+ end
207
+
208
+
209
+ describe "a WebSocket close frame" do
210
+ before( :each ) do
211
+ @frame = @factory.close( '/websock' )
212
+ end
213
+
214
+ it "has convenience methods for setting its payload via integer status code" do
215
+ @frame.set_status( CLOSE_BAD_DATA )
216
+ @frame.to_s[ 2..-1 ].should == "%d %s" %
217
+ [ CLOSE_BAD_DATA, CLOSING_STATUS_DESC[CLOSE_BAD_DATA] ]
218
+ end
219
+
220
+ end
221
+
222
+
223
+ describe "WebSocket control frames" do
224
+ before( :each ) do
225
+ @frame = @factory.close( '/websock', "1002 Protocol error" )
226
+ end
227
+
228
+
229
+ it "raises an exception if its payload is bigger than 125 bytes" do
230
+ @frame.body = "x" * 126
231
+ expect {
232
+ @frame.to_s
233
+ }.to raise_error( Mongrel2::WebSocket::FrameError, /cannot exceed 125 bytes/i )
234
+ end
235
+
236
+ it "raises an exception if it's fragmented" do
237
+ @frame.fin = false
238
+ expect {
239
+ @frame.to_s
240
+ }.to raise_error( Mongrel2::WebSocket::FrameError, /fragmented/i )
241
+ end
242
+
243
+ end
244
+
245
+
246
+ describe "RFC examples (the applicable ones, anyway)" do
247
+
248
+ it "generates a single-frame unmasked text message correctly" do
249
+ raw_response = @factory.text( '/websock', "Hello", :fin ).to_s
250
+ raw_response.bytes.to_a.should == [ 0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f ]
251
+ raw_response.encoding.should == Encoding::BINARY
252
+ end
253
+
254
+ it "generates both parts of a fragmented unmasked text message correctly" do
255
+ first = @factory.text( '/websock', 'Hel' )
256
+ last = @factory.continuation( '/websock', 'lo', :fin )
257
+
258
+ first.bytes.to_a.should == [ 0x01, 0x03, 0x48, 0x65, 0x6c ]
259
+ last.bytes.to_a.should == [ 0x80, 0x02, 0x6c, 0x6f ]
260
+ end
261
+
262
+ # The RFC's example is a masked response, but we're never a client, so never
263
+ # generate masked payloads.
264
+ it "generates a unmasked Ping request and (un)masked Ping response correctly" do
265
+ ping = @factory.ping( '/websock', 'Hello' )
266
+ pong = @factory.pong( '/websock', 'Hello' )
267
+
268
+ ping.bytes.to_a.should == [ 0x89, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f ]
269
+ pong.bytes.to_a.should == [ 0x8a, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f ]
270
+ end
271
+
272
+
273
+ it "generates a 256-byte binary message in a single unmasked frame" do
274
+ binary = @factory.binary( '/websock', BINARY_DATA, :fin )
275
+
276
+ # 1 + 1 + 2
277
+ binary.to_s[0,4].bytes.to_a.should == [ 0x82, 0x7E, 0x01, 0x00 ]
278
+ binary.to_s[4..-1].should == BINARY_DATA
279
+ end
280
+
281
+ it "generates a 64KiB binary message in a single unmasked frame correctly" do
282
+ data = BINARY_DATA * 256
283
+
284
+ binary = @factory.binary( '/websock', data, :fin )
285
+
286
+ # 1 + 1 + 8
287
+ binary.to_s[0,10].bytes.to_a.should ==
288
+ [ 0x82, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 ]
289
+ binary.to_s[10..-1].should == data
290
+ end
291
+
292
+ end
293
+
294
+ end
295
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongrel2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.1
4
+ version: 0.16.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -36,11 +36,11 @@ cert_chain:
36
36
  YUhDS0xaZFNLai9SSHVUT3QrZ2JsUmV4OEZBaDhOZUEKY21saFhlNDZwWk5K
37
37
  Z1dLYnhaYWg4NWpJang5NWhSOHZPSStOQU01aUg5a09xSzEzRHJ4YWNUS1Bo
38
38
  cWo1UGp3RgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
39
- date: 2012-03-02 00:00:00.000000000 Z
39
+ date: 2012-03-10 00:00:00.000000000 Z
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: nokogiri
43
- requirement: &70344063433420 !ruby/object:Gem::Requirement
43
+ requirement: &70305464835520 !ruby/object:Gem::Requirement
44
44
  none: false
45
45
  requirements:
46
46
  - - ~>
@@ -48,10 +48,10 @@ dependencies:
48
48
  version: '1.5'
49
49
  type: :runtime
50
50
  prerelease: false
51
- version_requirements: *70344063433420
51
+ version_requirements: *70305464835520
52
52
  - !ruby/object:Gem::Dependency
53
53
  name: sequel
54
- requirement: &70344063432920 !ruby/object:Gem::Requirement
54
+ requirement: &70305464833340 !ruby/object:Gem::Requirement
55
55
  none: false
56
56
  requirements:
57
57
  - - ~>
@@ -59,10 +59,10 @@ dependencies:
59
59
  version: '3.31'
60
60
  type: :runtime
61
61
  prerelease: false
62
- version_requirements: *70344063432920
62
+ version_requirements: *70305464833340
63
63
  - !ruby/object:Gem::Dependency
64
64
  name: amalgalite
65
- requirement: &70344063448860 !ruby/object:Gem::Requirement
65
+ requirement: &70305464831960 !ruby/object:Gem::Requirement
66
66
  none: false
67
67
  requirements:
68
68
  - - ~>
@@ -70,10 +70,10 @@ dependencies:
70
70
  version: '1.1'
71
71
  type: :runtime
72
72
  prerelease: false
73
- version_requirements: *70344063448860
73
+ version_requirements: *70305464831960
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: tnetstring
76
- requirement: &70344063448440 !ruby/object:Gem::Requirement
76
+ requirement: &70305464844480 !ruby/object:Gem::Requirement
77
77
  none: false
78
78
  requirements:
79
79
  - - ~>
@@ -81,10 +81,10 @@ dependencies:
81
81
  version: '0.3'
82
82
  type: :runtime
83
83
  prerelease: false
84
- version_requirements: *70344063448440
84
+ version_requirements: *70305464844480
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: yajl-ruby
87
- requirement: &70344063448020 !ruby/object:Gem::Requirement
87
+ requirement: &70305464842260 !ruby/object:Gem::Requirement
88
88
  none: false
89
89
  requirements:
90
90
  - - ~>
@@ -92,10 +92,10 @@ dependencies:
92
92
  version: '1.0'
93
93
  type: :runtime
94
94
  prerelease: false
95
- version_requirements: *70344063448020
95
+ version_requirements: *70305464842260
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: trollop
98
- requirement: &70344063447600 !ruby/object:Gem::Requirement
98
+ requirement: &70305464839740 !ruby/object:Gem::Requirement
99
99
  none: false
100
100
  requirements:
101
101
  - - ~>
@@ -103,10 +103,10 @@ dependencies:
103
103
  version: '1.16'
104
104
  type: :runtime
105
105
  prerelease: false
106
- version_requirements: *70344063447600
106
+ version_requirements: *70305464839740
107
107
  - !ruby/object:Gem::Dependency
108
108
  name: sysexits
109
- requirement: &70344063447180 !ruby/object:Gem::Requirement
109
+ requirement: &70305464852820 !ruby/object:Gem::Requirement
110
110
  none: false
111
111
  requirements:
112
112
  - - ~>
@@ -114,10 +114,10 @@ dependencies:
114
114
  version: '1.0'
115
115
  type: :runtime
116
116
  prerelease: false
117
- version_requirements: *70344063447180
117
+ version_requirements: *70305464852820
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: zmq
120
- requirement: &70344063446760 !ruby/object:Gem::Requirement
120
+ requirement: &70305464851800 !ruby/object:Gem::Requirement
121
121
  none: false
122
122
  requirements:
123
123
  - - ~>
@@ -125,10 +125,10 @@ dependencies:
125
125
  version: 2.1.4
126
126
  type: :runtime
127
127
  prerelease: false
128
- version_requirements: *70344063446760
128
+ version_requirements: *70305464851800
129
129
  - !ruby/object:Gem::Dependency
130
130
  name: hoe-mercurial
131
- requirement: &70344063446340 !ruby/object:Gem::Requirement
131
+ requirement: &70305464850060 !ruby/object:Gem::Requirement
132
132
  none: false
133
133
  requirements:
134
134
  - - ~>
@@ -136,10 +136,10 @@ dependencies:
136
136
  version: 1.3.1
137
137
  type: :development
138
138
  prerelease: false
139
- version_requirements: *70344063446340
139
+ version_requirements: *70305464850060
140
140
  - !ruby/object:Gem::Dependency
141
141
  name: hoe-highline
142
- requirement: &70344063445860 !ruby/object:Gem::Requirement
142
+ requirement: &70305464859060 !ruby/object:Gem::Requirement
143
143
  none: false
144
144
  requirements:
145
145
  - - ~>
@@ -147,10 +147,10 @@ dependencies:
147
147
  version: 0.0.1
148
148
  type: :development
149
149
  prerelease: false
150
- version_requirements: *70344063445860
150
+ version_requirements: *70305464859060
151
151
  - !ruby/object:Gem::Dependency
152
152
  name: configurability
153
- requirement: &70344063445400 !ruby/object:Gem::Requirement
153
+ requirement: &70305464855380 !ruby/object:Gem::Requirement
154
154
  none: false
155
155
  requirements:
156
156
  - - ~>
@@ -158,10 +158,10 @@ dependencies:
158
158
  version: '1.0'
159
159
  type: :development
160
160
  prerelease: false
161
- version_requirements: *70344063445400
161
+ version_requirements: *70305464855380
162
162
  - !ruby/object:Gem::Dependency
163
163
  name: rspec
164
- requirement: &70344063444980 !ruby/object:Gem::Requirement
164
+ requirement: &70305464868220 !ruby/object:Gem::Requirement
165
165
  none: false
166
166
  requirements:
167
167
  - - ~>
@@ -169,10 +169,10 @@ dependencies:
169
169
  version: '2.8'
170
170
  type: :development
171
171
  prerelease: false
172
- version_requirements: *70344063444980
172
+ version_requirements: *70305464868220
173
173
  - !ruby/object:Gem::Dependency
174
174
  name: rdoc
175
- requirement: &70344063444560 !ruby/object:Gem::Requirement
175
+ requirement: &70305464871220 !ruby/object:Gem::Requirement
176
176
  none: false
177
177
  requirements:
178
178
  - - ~>
@@ -180,10 +180,10 @@ dependencies:
180
180
  version: '3.10'
181
181
  type: :development
182
182
  prerelease: false
183
- version_requirements: *70344063444560
183
+ version_requirements: *70305464871220
184
184
  - !ruby/object:Gem::Dependency
185
185
  name: hoe
186
- requirement: &70344063444080 !ruby/object:Gem::Requirement
186
+ requirement: &70305464910100 !ruby/object:Gem::Requirement
187
187
  none: false
188
188
  requirements:
189
189
  - - ~>
@@ -191,22 +191,19 @@ dependencies:
191
191
  version: '2.13'
192
192
  type: :development
193
193
  prerelease: false
194
- version_requirements: *70344063444080
195
- description: ! "Ruby-Mongrel2 is a complete Ruby (1.9-only) connector for \nMongrel2[http://mongrel2.org/].\n\nThis
196
- library includes configuration-database ORM classes, a Ruby\nimplementation of the
197
- 'm2sh' tool, a configuration DSL for generating config\ndatabases in pure Ruby,
198
- a Control port interface object, and handler classes \nfor creating applications
199
- or higher-level frameworks.\n\nIt differs from the original Mongrel2 Ruby library
200
- (m2r), and the\nmongrel2-rack library in several ways:\n\n* It uses the C extension
201
- for 0MQ (zmq) instead of the FFI one. If you\n strongly prefer the FFI library,
202
- both of the other Mongrel2 libraries use\n it, so you'll want to stick to one of
203
- them.\n\n* It doesn't come with a Rack handler, or Rails examples, or anything fancy.
204
- I\n intend to build my own webby framework bits around Mongrel2, and I thought\n
205
- \ maybe someone else might want to as well. If you don't, well again, there\n are
206
- two other libraries for you.\n\n* It includes configuration stuff. I want to make
207
- tools that use the Mongrel2\n config database, so I wrote config classes. Sequel::Model
208
- made it\n stupid-easy. There's also a DSL for generating a config database, too,\n
209
- \ mostly because I found it an interesting exercise, and I like the way it\n looks."
194
+ version_requirements: *70305464910100
195
+ description: ! 'Ruby-Mongrel2 is a complete Ruby (1.9-only) connector for
196
+
197
+ Mongrel2[http://mongrel2.org/].
198
+
199
+
200
+ This library includes configuration-database ORM classes, a Ruby
201
+
202
+ implementation of the ''m2sh'' tool, a configuration DSL for generating config
203
+
204
+ databases in pure Ruby, a Control port interface object, and handler classes
205
+
206
+ for creating applications or higher-level frameworks.'
210
207
  email:
211
208
  - ged@FaerieMUD.org
212
209
  executables:
@@ -231,13 +228,16 @@ files:
231
228
  - data/mongrel2/bootstrap.html
232
229
  - data/mongrel2/config.sql
233
230
  - data/mongrel2/css/master.css
231
+ - data/mongrel2/js/websock-test.js
234
232
  - data/mongrel2/mimetypes.sql
233
+ - data/mongrel2/websock-test.html
235
234
  - examples/README.txt
236
235
  - examples/config.rb
237
236
  - examples/helloworld-handler.rb
238
237
  - examples/request-dumper.rb
239
238
  - examples/request-dumper.tmpl
240
239
  - examples/run
240
+ - examples/ws-echo.rb
241
241
  - lib/mongrel2.rb
242
242
  - lib/mongrel2/config.rb
243
243
  - lib/mongrel2/config/directory.rb
@@ -266,6 +266,7 @@ files:
266
266
  - lib/mongrel2/response.rb
267
267
  - lib/mongrel2/table.rb
268
268
  - lib/mongrel2/testing.rb
269
+ - lib/mongrel2/websocket.rb
269
270
  - lib/mongrel2/xmlrequest.rb
270
271
  - spec/lib/constants.rb
271
272
  - spec/lib/helpers.rb
@@ -293,6 +294,7 @@ files:
293
294
  - spec/mongrel2/request_spec.rb
294
295
  - spec/mongrel2/response_spec.rb
295
296
  - spec/mongrel2/table_spec.rb
297
+ - spec/mongrel2/websocket_spec.rb
296
298
  - spec/mongrel2_spec.rb
297
299
  homepage: http://deveiate.org/projects/Ruby-Mongrel2/
298
300
  licenses:
@@ -320,5 +322,5 @@ rubyforge_project: mongrel2
320
322
  rubygems_version: 1.8.16
321
323
  signing_key:
322
324
  specification_version: 3
323
- summary: Ruby-Mongrel2 is a complete Ruby (1.9-only) connector for Mongrel2[http://mongrel2.org/]
325
+ summary: Ruby-Mongrel2 is a complete Ruby (1.9-only) connector for Mongrel2[http://mongrel2.org/]
324
326
  test_files: []