mongrel2 0.15.1 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/ChangeLog +51 -1
- data/History.rdoc +5 -0
- data/Manifest.txt +5 -0
- data/README.rdoc +14 -9
- data/bin/m2sh.rb +2 -0
- data/data/mongrel2/bootstrap.html +24 -22
- data/data/mongrel2/css/master.css +30 -1
- data/data/mongrel2/js/websock-test.js +108 -0
- data/data/mongrel2/websock-test.html +33 -0
- data/examples/config.rb +10 -10
- data/examples/ws-echo.rb +251 -0
- data/lib/mongrel2.rb +3 -2
- data/lib/mongrel2/config/server.rb +2 -0
- data/lib/mongrel2/connection.rb +2 -2
- data/lib/mongrel2/handler.rb +42 -28
- data/lib/mongrel2/request.rb +4 -3
- data/lib/mongrel2/testing.rb +201 -2
- data/lib/mongrel2/websocket.rb +561 -0
- data/spec/lib/constants.rb +2 -1
- data/spec/mongrel2/httprequest_spec.rb +1 -0
- data/spec/mongrel2/request_spec.rb +1 -1
- data/spec/mongrel2/websocket_spec.rb +295 -0
- metadata +48 -46
- metadata.gz.sig +0 -0
data/spec/lib/constants.rb
CHANGED
@@ -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
|
|
@@ -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.
|
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-
|
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: &
|
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: *
|
51
|
+
version_requirements: *70305464835520
|
52
52
|
- !ruby/object:Gem::Dependency
|
53
53
|
name: sequel
|
54
|
-
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: *
|
62
|
+
version_requirements: *70305464833340
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
name: amalgalite
|
65
|
-
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: *
|
73
|
+
version_requirements: *70305464831960
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
75
|
name: tnetstring
|
76
|
-
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: *
|
84
|
+
version_requirements: *70305464844480
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: yajl-ruby
|
87
|
-
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: *
|
95
|
+
version_requirements: *70305464842260
|
96
96
|
- !ruby/object:Gem::Dependency
|
97
97
|
name: trollop
|
98
|
-
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: *
|
106
|
+
version_requirements: *70305464839740
|
107
107
|
- !ruby/object:Gem::Dependency
|
108
108
|
name: sysexits
|
109
|
-
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: *
|
117
|
+
version_requirements: *70305464852820
|
118
118
|
- !ruby/object:Gem::Dependency
|
119
119
|
name: zmq
|
120
|
-
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: *
|
128
|
+
version_requirements: *70305464851800
|
129
129
|
- !ruby/object:Gem::Dependency
|
130
130
|
name: hoe-mercurial
|
131
|
-
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: *
|
139
|
+
version_requirements: *70305464850060
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
141
|
name: hoe-highline
|
142
|
-
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: *
|
150
|
+
version_requirements: *70305464859060
|
151
151
|
- !ruby/object:Gem::Dependency
|
152
152
|
name: configurability
|
153
|
-
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: *
|
161
|
+
version_requirements: *70305464855380
|
162
162
|
- !ruby/object:Gem::Dependency
|
163
163
|
name: rspec
|
164
|
-
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: *
|
172
|
+
version_requirements: *70305464868220
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
174
|
name: rdoc
|
175
|
-
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: *
|
183
|
+
version_requirements: *70305464871220
|
184
184
|
- !ruby/object:Gem::Dependency
|
185
185
|
name: hoe
|
186
|
-
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: *
|
195
|
-
description: !
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
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
|
325
|
+
summary: Ruby-Mongrel2 is a complete Ruby (1.9-only) connector for Mongrel2[http://mongrel2.org/]
|
324
326
|
test_files: []
|