mongrel2 0.15.1 → 0.16.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.
@@ -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: []