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 | 
            +
             |