mongrel2 0.0.1
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.
- data.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/History.rdoc +4 -0
- data/Manifest.txt +66 -0
- data/README.rdoc +169 -0
- data/Rakefile +77 -0
- data/bin/m2sh.rb +600 -0
- data/data/mongrel2/bootstrap.html +25 -0
- data/data/mongrel2/config.sql +84 -0
- data/data/mongrel2/mimetypes.sql +855 -0
- data/examples/README.txt +6 -0
- data/examples/config.rb +54 -0
- data/examples/helloworld-handler.rb +31 -0
- data/examples/request-dumper.rb +45 -0
- data/examples/request-dumper.tmpl +71 -0
- data/examples/run +17 -0
- data/lib/mongrel2.rb +62 -0
- data/lib/mongrel2/config.rb +212 -0
- data/lib/mongrel2/config/directory.rb +78 -0
- data/lib/mongrel2/config/dsl.rb +206 -0
- data/lib/mongrel2/config/handler.rb +124 -0
- data/lib/mongrel2/config/host.rb +88 -0
- data/lib/mongrel2/config/log.rb +48 -0
- data/lib/mongrel2/config/mimetype.rb +15 -0
- data/lib/mongrel2/config/proxy.rb +15 -0
- data/lib/mongrel2/config/route.rb +51 -0
- data/lib/mongrel2/config/server.rb +58 -0
- data/lib/mongrel2/config/setting.rb +15 -0
- data/lib/mongrel2/config/statistic.rb +23 -0
- data/lib/mongrel2/connection.rb +212 -0
- data/lib/mongrel2/constants.rb +159 -0
- data/lib/mongrel2/control.rb +165 -0
- data/lib/mongrel2/exceptions.rb +59 -0
- data/lib/mongrel2/handler.rb +309 -0
- data/lib/mongrel2/httprequest.rb +51 -0
- data/lib/mongrel2/httpresponse.rb +187 -0
- data/lib/mongrel2/jsonrequest.rb +43 -0
- data/lib/mongrel2/logging.rb +241 -0
- data/lib/mongrel2/mixins.rb +143 -0
- data/lib/mongrel2/request.rb +148 -0
- data/lib/mongrel2/response.rb +74 -0
- data/lib/mongrel2/table.rb +216 -0
- data/lib/mongrel2/xmlrequest.rb +36 -0
- data/spec/lib/constants.rb +237 -0
- data/spec/lib/helpers.rb +246 -0
- data/spec/lib/matchers.rb +50 -0
- data/spec/mongrel2/config/directory_spec.rb +91 -0
- data/spec/mongrel2/config/dsl_spec.rb +218 -0
- data/spec/mongrel2/config/handler_spec.rb +118 -0
- data/spec/mongrel2/config/host_spec.rb +30 -0
- data/spec/mongrel2/config/log_spec.rb +95 -0
- data/spec/mongrel2/config/proxy_spec.rb +30 -0
- data/spec/mongrel2/config/route_spec.rb +83 -0
- data/spec/mongrel2/config/server_spec.rb +84 -0
- data/spec/mongrel2/config/setting_spec.rb +30 -0
- data/spec/mongrel2/config/statistic_spec.rb +30 -0
- data/spec/mongrel2/config_spec.rb +111 -0
- data/spec/mongrel2/connection_spec.rb +172 -0
- data/spec/mongrel2/constants_spec.rb +32 -0
- data/spec/mongrel2/control_spec.rb +192 -0
- data/spec/mongrel2/handler_spec.rb +261 -0
- data/spec/mongrel2/httpresponse_spec.rb +232 -0
- data/spec/mongrel2/logging_spec.rb +76 -0
- data/spec/mongrel2/mixins_spec.rb +62 -0
- data/spec/mongrel2/request_spec.rb +157 -0
- data/spec/mongrel2/response_spec.rb +81 -0
- data/spec/mongrel2/table_spec.rb +176 -0
- data/spec/mongrel2_spec.rb +34 -0
- metadata +294 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,232 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
}
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
|
15
|
+
require 'spec/lib/helpers'
|
16
|
+
|
17
|
+
require 'mongrel2'
|
18
|
+
require 'mongrel2/httprequest'
|
19
|
+
require 'mongrel2/httpresponse'
|
20
|
+
|
21
|
+
|
22
|
+
#####################################################################
|
23
|
+
### C O N T E X T S
|
24
|
+
#####################################################################
|
25
|
+
|
26
|
+
describe Mongrel2::HTTPResponse do
|
27
|
+
|
28
|
+
before( :all ) do
|
29
|
+
setup_logging( :fatal )
|
30
|
+
end
|
31
|
+
|
32
|
+
before( :each ) do
|
33
|
+
@response = Mongrel2::HTTPResponse.new( TEST_UUID, 299 )
|
34
|
+
end
|
35
|
+
|
36
|
+
after( :all ) do
|
37
|
+
reset_logging()
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
it "has a headers table" do
|
42
|
+
@response.headers.should be_a( Mongrel2::Table )
|
43
|
+
end
|
44
|
+
|
45
|
+
it "is a status 200 response if not set otherwise" do
|
46
|
+
@response.status_line.should == 'HTTP/1.1 200 OK'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "sets Date and Content-length headers automatically if they haven't been set" do
|
50
|
+
@response.header_data.should =~ /Content-length: 0/i
|
51
|
+
@response.header_data.should =~ /Date: #{HTTP_DATE}/i
|
52
|
+
end
|
53
|
+
|
54
|
+
it "doesn't have a body" do
|
55
|
+
@response.body.should be_empty()
|
56
|
+
end
|
57
|
+
|
58
|
+
it "knows it hasn't been handled" do
|
59
|
+
@response.should_not be_handled()
|
60
|
+
end
|
61
|
+
|
62
|
+
it "stringifies to a valid RFC2616 response string" do
|
63
|
+
@response.to_s.should =~ HTTP_RESPONSE
|
64
|
+
end
|
65
|
+
|
66
|
+
it "has some default headers" do
|
67
|
+
@response.headers['Server'].should == Mongrel2.version_string( true )
|
68
|
+
end
|
69
|
+
|
70
|
+
it "can be reset to a pristine state" do
|
71
|
+
@response.body << "Some stuff we want to get rid of later"
|
72
|
+
@response.headers['x-lunch-packed-by'] = 'Your Mom'
|
73
|
+
@response.status = HTTP::OK
|
74
|
+
|
75
|
+
@response.reset
|
76
|
+
|
77
|
+
@response.should_not be_handled()
|
78
|
+
@response.body.should == ''
|
79
|
+
@response.headers.should have(1).keys
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
it "can find the length of its body if it's a String" do
|
84
|
+
test_body = 'A string full of stuff'
|
85
|
+
@response.body = test_body
|
86
|
+
|
87
|
+
@response.get_content_length.should == test_body.length
|
88
|
+
end
|
89
|
+
|
90
|
+
it "can find the length of its body if it's a seekable IO" do
|
91
|
+
test_body = File.open( __FILE__, 'r' )
|
92
|
+
test_body.seek( 0, IO::SEEK_END )
|
93
|
+
length = test_body.tell
|
94
|
+
test_body.seek( 0, IO::SEEK_SET )
|
95
|
+
|
96
|
+
@response.body = test_body
|
97
|
+
|
98
|
+
@response.get_content_length.should == length
|
99
|
+
end
|
100
|
+
|
101
|
+
it "can find the length of its body even if it's an IO that's been set to do a partial read" do
|
102
|
+
test_body = File.open( __FILE__, 'r' )
|
103
|
+
test_body.seek( 0, IO::SEEK_END )
|
104
|
+
length = test_body.tell
|
105
|
+
test_body.seek( 100, IO::SEEK_SET )
|
106
|
+
|
107
|
+
@response.body = test_body
|
108
|
+
|
109
|
+
@response.get_content_length.should == length - 100
|
110
|
+
end
|
111
|
+
|
112
|
+
it "knows that it has been handled even if the status is set to NOT_FOUND" do
|
113
|
+
@response.status = HTTP::NOT_FOUND
|
114
|
+
@response.should be_handled()
|
115
|
+
end
|
116
|
+
|
117
|
+
it "knows if it has not yet been handled" do
|
118
|
+
@response.should_not be_handled()
|
119
|
+
@response.status = HTTP::OK
|
120
|
+
@response.should be_handled()
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
it "knows what category of response it is" do
|
125
|
+
@response.status = HTTP::CREATED
|
126
|
+
@response.status_category.should == 2
|
127
|
+
|
128
|
+
@response.status = HTTP::NOT_ACCEPTABLE
|
129
|
+
@response.status_category.should == 4
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
it "knows if its status indicates it is an informational response" do
|
134
|
+
@response.status = HTTP::PROCESSING
|
135
|
+
@response.status_category.should == 1
|
136
|
+
@response.status_is_informational?.should == true
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
it "knows if its status indicates it is a successful response" do
|
141
|
+
@response.status = HTTP::ACCEPTED
|
142
|
+
@response.status_category.should == 2
|
143
|
+
@response.status_is_successful?.should == true
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
it "knows if its status indicates it is a redirected response" do
|
148
|
+
@response.status = HTTP::SEE_OTHER
|
149
|
+
@response.status_category.should == 3
|
150
|
+
@response.status_is_redirect?.should == true
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
it "knows if its status indicates there was a client error" do
|
155
|
+
@response.status = HTTP::GONE
|
156
|
+
@response.status_category.should == 4
|
157
|
+
@response.status_is_clienterror?.should == true
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
it "knows if its status indicates there was a server error" do
|
162
|
+
@response.status = HTTP::VERSION_NOT_SUPPORTED
|
163
|
+
@response.status_category.should == 5
|
164
|
+
@response.status_is_servererror?.should == true
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
it "knows what the response content type is" do
|
169
|
+
headers = mock( 'headers' )
|
170
|
+
@response.stub!( :headers ).and_return( headers )
|
171
|
+
|
172
|
+
headers.should_receive( :[] ).
|
173
|
+
with( :content_type ).
|
174
|
+
and_return( 'text/erotica' )
|
175
|
+
|
176
|
+
@response.content_type.should == 'text/erotica'
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
it "can modify the response content type" do
|
181
|
+
headers = mock( 'headers' )
|
182
|
+
@response.stub!( :headers ).and_return( headers )
|
183
|
+
|
184
|
+
headers.should_receive( :[]= ).
|
185
|
+
with( :content_type, 'image/nude' )
|
186
|
+
|
187
|
+
@response.content_type = 'image/nude'
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
it "can find the length of its body if it's an IO" do
|
192
|
+
test_body_content = 'A string with some stuff in it'
|
193
|
+
test_body = StringIO.new( test_body_content )
|
194
|
+
@response.body = test_body
|
195
|
+
|
196
|
+
@response.get_content_length.should == test_body_content.length
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
it "raises a descriptive error message if it can't get the body's length" do
|
201
|
+
@response.body = Object.new
|
202
|
+
|
203
|
+
lambda {
|
204
|
+
@response.get_content_length
|
205
|
+
}.should raise_error( Mongrel2::ResponseError, /content length/i )
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
it "can build a valid HTTP status line for its status" do
|
210
|
+
@response.status = HTTP::SEE_OTHER
|
211
|
+
@response.status_line.should == "HTTP/1.1 303 See Other"
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
it "has pipelining disabled by default" do
|
216
|
+
@response.should_not be_keepalive()
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
it "has pipelining disabled if it's explicitly disabled" do
|
221
|
+
@response.keepalive = false
|
222
|
+
@response.should_not be_keepalive()
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
it "can be set to allow pipelining" do
|
227
|
+
@response.keepalive = true
|
228
|
+
@response.should be_keepalive()
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
}
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
require 'stringio'
|
15
|
+
|
16
|
+
require 'spec/lib/helpers'
|
17
|
+
|
18
|
+
require 'mongrel2'
|
19
|
+
require 'mongrel2/logging'
|
20
|
+
|
21
|
+
|
22
|
+
#####################################################################
|
23
|
+
### C O N T E X T S
|
24
|
+
#####################################################################
|
25
|
+
|
26
|
+
describe Mongrel2::Logging, "-extended module" do
|
27
|
+
|
28
|
+
before( :each ) do
|
29
|
+
@extended_module = Module.new do
|
30
|
+
extend Mongrel2::Logging
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have a default Logger" do
|
35
|
+
@extended_module.logger.should be_a( Logger )
|
36
|
+
@extended_module.default_logger.should equal( @extended_module.logger )
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should know if its default logger is replaced" do
|
40
|
+
@extended_module.should be_using_default_logger
|
41
|
+
@extended_module.logger = Logger.new( $stderr )
|
42
|
+
@extended_module.should_not be_using_default_logger
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has the default logger instance after being reset" do
|
46
|
+
@extended_module.reset_logger
|
47
|
+
@extended_module.logger.should equal( @extended_module.default_logger )
|
48
|
+
end
|
49
|
+
|
50
|
+
it "has the default log formatter instance after being reset" do
|
51
|
+
@extended_module.reset_logger
|
52
|
+
@extended_module.logger.formatter.should equal( @extended_module.default_log_formatter )
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
context "with new defaults" do
|
57
|
+
|
58
|
+
before( :each ) do
|
59
|
+
@sink = StringIO.new
|
60
|
+
@logger = Logger.new( @sink )
|
61
|
+
@formatter = Mongrel2::Logging::ColorFormatter.new( @logger )
|
62
|
+
|
63
|
+
@extended_module.default_logger = @logger
|
64
|
+
@extended_module.default_log_formatter = @formatter
|
65
|
+
end
|
66
|
+
|
67
|
+
it "uses the new defaults when the logging subsystem is reset" do
|
68
|
+
@extended_module.reset_logger
|
69
|
+
@extended_module.logger.should equal( @logger )
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
}
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
|
15
|
+
require 'spec/lib/helpers'
|
16
|
+
|
17
|
+
require 'mongrel2'
|
18
|
+
require 'mongrel2/mixins'
|
19
|
+
|
20
|
+
|
21
|
+
#####################################################################
|
22
|
+
### C O N T E X T S
|
23
|
+
#####################################################################
|
24
|
+
|
25
|
+
describe Mongrel2, "mixins" do
|
26
|
+
|
27
|
+
describe Mongrel2::Loggable do
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
@logfile = StringIO.new('')
|
31
|
+
Mongrel2.logger = Logger.new( @logfile )
|
32
|
+
|
33
|
+
@test_class = Class.new do
|
34
|
+
include Mongrel2::Loggable
|
35
|
+
|
36
|
+
def log_test_message( level, msg )
|
37
|
+
self.log.send( level, msg )
|
38
|
+
end
|
39
|
+
|
40
|
+
def logdebug_test_message( msg )
|
41
|
+
self.log_debug.debug( msg )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
@obj = @test_class.new
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
it "is able to output to the log via its #log method" do
|
49
|
+
@obj.log_test_message( :debug, "debugging message" )
|
50
|
+
@logfile.rewind
|
51
|
+
@logfile.read.should =~ /debugging message/
|
52
|
+
end
|
53
|
+
|
54
|
+
it "is able to output to the log via its #log_debug method" do
|
55
|
+
@obj.logdebug_test_message( "sexydrownwatch" )
|
56
|
+
@logfile.rewind
|
57
|
+
@logfile.read.should =~ /sexydrownwatch/
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,157 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
}
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
require 'tnetstring'
|
15
|
+
|
16
|
+
require 'spec/lib/helpers'
|
17
|
+
|
18
|
+
require 'mongrel2'
|
19
|
+
require 'mongrel2/request'
|
20
|
+
|
21
|
+
|
22
|
+
#####################################################################
|
23
|
+
### C O N T E X T S
|
24
|
+
#####################################################################
|
25
|
+
|
26
|
+
describe Mongrel2::Request do
|
27
|
+
|
28
|
+
before( :all ) do
|
29
|
+
setup_logging( :fatal )
|
30
|
+
end
|
31
|
+
|
32
|
+
after( :all ) do
|
33
|
+
reset_logging()
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
it "can parse a request message" do
|
38
|
+
|
39
|
+
message = make_request()
|
40
|
+
req = Mongrel2::Request.parse( message )
|
41
|
+
|
42
|
+
req.should be_a( Mongrel2::Request )
|
43
|
+
req.sender_id.should == TEST_UUID
|
44
|
+
req.conn_id.should == TEST_ID
|
45
|
+
|
46
|
+
req.headers.should be_a( Mongrel2::Table )
|
47
|
+
req.headers['Host'].should == TEST_HEADERS['host']
|
48
|
+
end
|
49
|
+
|
50
|
+
it "can parse a request message with TNetstring headers" do
|
51
|
+
|
52
|
+
message = make_tn_request()
|
53
|
+
req = Mongrel2::Request.parse( message )
|
54
|
+
|
55
|
+
req.should be_a( Mongrel2::Request )
|
56
|
+
req.sender_id.should == TEST_UUID
|
57
|
+
req.conn_id.should == TEST_ID
|
58
|
+
|
59
|
+
req.headers.should be_a( Mongrel2::Table )
|
60
|
+
req.headers.host.should == TEST_HEADERS['host']
|
61
|
+
end
|
62
|
+
|
63
|
+
it "can parse a request message with a JSON body" do
|
64
|
+
|
65
|
+
message = make_json_request()
|
66
|
+
req = Mongrel2::Request.parse( message )
|
67
|
+
|
68
|
+
req.should be_a( Mongrel2::JSONRequest )
|
69
|
+
req.sender_id.should == TEST_UUID
|
70
|
+
req.conn_id.should == TEST_ID
|
71
|
+
|
72
|
+
req.headers.should be_a( Mongrel2::Table )
|
73
|
+
req.headers.path.should == TEST_JSON_PATH
|
74
|
+
|
75
|
+
req.data.should == TEST_JSON_BODY
|
76
|
+
end
|
77
|
+
|
78
|
+
it "raises an UnhandledMethodError with the name of the method for METHOD verbs that " +
|
79
|
+
"don't look like HTTP ones" do
|
80
|
+
|
81
|
+
message = make_request( :headers => {'METHOD' => '!DIVULGE'} )
|
82
|
+
expect {
|
83
|
+
Mongrel2::Request.parse( message )
|
84
|
+
}.to raise_error( Mongrel2::UnhandledMethodError, /!DIVULGE/ )
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
describe "instances" do
|
89
|
+
|
90
|
+
before( :each ) do
|
91
|
+
message = make_json_request() # HTTPRequest overrides the #response method
|
92
|
+
@req = Mongrel2::Request.parse( message )
|
93
|
+
end
|
94
|
+
|
95
|
+
it "can return an appropriate response instance for themselves" do
|
96
|
+
result = @req.response
|
97
|
+
result.should be_a( Mongrel2::Response )
|
98
|
+
result.sender_id.should == @req.sender_id
|
99
|
+
result.conn_id.should == @req.conn_id
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
describe "framework support" do
|
106
|
+
|
107
|
+
before( :all ) do
|
108
|
+
@oldtypes = Mongrel2::Request.request_types
|
109
|
+
@original_default_proc = Mongrel2::Request.request_types.default_proc
|
110
|
+
end
|
111
|
+
|
112
|
+
before( :each ) do
|
113
|
+
Mongrel2::Request.request_types.default_proc = @original_default_proc
|
114
|
+
Mongrel2::Request.request_types.clear
|
115
|
+
end
|
116
|
+
|
117
|
+
after( :all ) do
|
118
|
+
Mongrel2::Request.request_types.default_proc = @original_default_proc
|
119
|
+
Mongrel2::Request.request_types.replace( @oldtypes )
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
it "includes a mechanism for overriding the default Request subclass" do
|
124
|
+
subclass = Class.new( Mongrel2::Request ) do
|
125
|
+
register_request_type self, :__default
|
126
|
+
end
|
127
|
+
|
128
|
+
Mongrel2::Request.subclass_for_method( 'GET' ).should == subclass
|
129
|
+
Mongrel2::Request.subclass_for_method( 'POST' ).should == subclass
|
130
|
+
Mongrel2::Request.subclass_for_method( 'JSON' ).should == subclass
|
131
|
+
end
|
132
|
+
|
133
|
+
it "includes a mechanism for overriding the Request subclass for a particular request " +
|
134
|
+
"method" do
|
135
|
+
subclass = Class.new( Mongrel2::Request ) do
|
136
|
+
register_request_type self, :GET
|
137
|
+
end
|
138
|
+
|
139
|
+
Mongrel2::Request.subclass_for_method( 'GET' ).should == subclass
|
140
|
+
Mongrel2::Request.subclass_for_method( 'POST' ).should_not == subclass
|
141
|
+
Mongrel2::Request.subclass_for_method( 'JSON' ).should_not == subclass
|
142
|
+
end
|
143
|
+
|
144
|
+
it "clears any cached method -> subclass lookups when the default subclass changes" do
|
145
|
+
Mongrel2::Request.subclass_for_method( 'OPTIONS' ) # cache OPTIONS -> Mongrel2::Request
|
146
|
+
|
147
|
+
subclass = Class.new( Mongrel2::Request ) do
|
148
|
+
register_request_type self, :__default
|
149
|
+
end
|
150
|
+
|
151
|
+
Mongrel2::Request.subclass_for_method( 'OPTIONS' ).should == subclass
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|