From 96c359a0d1fa90136c16914d5c1732a244e489bb Mon Sep 17 00:00:00 2001 From: Graham Batty Date: Thu, 26 Feb 2009 15:36:57 -0700 Subject: [PATCH] Made auto-registration of unknown handlers much smarter. This should make it possible for the responsibility for handler definition to be on the people writing servers without making life difficult for the user. ie. 'gem install thin', if thin includes its rack adapter, would make 'rackup -s thin' just work, which is how it should be. --- lib/rack/handler.rb | 26 +++++++++++++++++++- test/spec_rack_handler.rb | 21 +++++++++++++++- .../rack/handler/unregistered.rb | 7 +++++ .../rack/handler/unregistered_long_one.rb | 7 +++++ .../rack/handler/unregisteredlongtwo.rb | 7 +++++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/unregistered_handler/rack/handler/unregistered.rb create mode 100644 test/unregistered_handler/rack/handler/unregistered_long_one.rb create mode 100644 test/unregistered_handler/rack/handler/unregisteredlongtwo.rb diff --git a/lib/rack/handler.rb b/lib/rack/handler.rb index 1018af6..32ca27e 100644 --- a/lib/rack/handler.rb +++ b/lib/rack/handler.rb @@ -16,7 +16,31 @@ module Rack klass.split("::").each { |x| obj = obj.const_get(x) } obj else - Rack::Handler.const_get(server.capitalize) + # try to require the matching rack handler file (presumably from another gem) + # the next couple of parts attempt to manipulate a proper constant name into + # a proper filename. BlahBlahBlorp -> either blah_blah_blorp or blahblahblorp. + begin + # first try blahblahblorp from BlahBlahBlorp (this is the cheaper case, so do it first) + require 'rack/handler/' + server.downcase + rescue LoadError + begin + # next try and find blah_blorp_bloop from BlahBlorpBloop + require 'rack/handler/' + server.gsub(/^[A-Z]/) {|a| a.downcase }.gsub(/[A-Z]/) {|a| "_#{a.downcase}" } + rescue LoadError + begin + require 'rack/handler/' + server.gsub(/_/, '') + rescue LoadError + # ignore it, move on and fail later. + end + end + end + # Now try to const_get the handler in question after properly capitalizing it. + # blah_blah_blorp -> BlahBlahBlorp + begin + return Rack::Handler.const_get(server.gsub(/(^|_)([a-z])/) {|a| $2.upcase }) + rescue NameError + return nil + end end end diff --git a/test/spec_rack_handler.rb b/test/spec_rack_handler.rb index 95052c7..daad7ea 100644 --- a/test/spec_rack_handler.rb +++ b/test/spec_rack_handler.rb @@ -12,8 +12,12 @@ context "Rack::Handler" do Rack::Handler.get('mongrel').should.equal Rack::Handler::Mongrel Rack::Handler.get('webrick').should.equal Rack::Handler::WEBrick end + + specify "handler that doesn't exist should return nil" do + Rack::Handler.get('boom').should.equal nil + end - specify "should get unregistered handler by name" do + specify "should get unregistered, but already required, handler by name" do Rack::Handler.get('lobster').should.equal Rack::Handler::Lobster end @@ -21,4 +25,19 @@ context "Rack::Handler" do Rack::Handler.register('rock_lobster', 'RockLobster') Rack::Handler.get('rock_lobster').should.equal RockLobster end + + specify "should not need registration for properly coded handlers even if not already required" do + begin + $:.push "test/unregistered_handler" + Rack::Handler.get('unregistered').should.equal Rack::Handler::Unregistered + Rack::Handler.get('Unregistered').should.equal Rack::Handler::Unregistered + Rack::Handler.get('UnRegistered').should.equal nil + Rack::Handler.get('unregistered_long_one').should.equal Rack::Handler::UnregisteredLongOne + Rack::Handler.get('UnregisteredLongOne').should.equal Rack::Handler::UnregisteredLongOne + Rack::Handler.get('unregistered_long_two').should.equal Rack::Handler::UnregisteredLongTwo + Rack::Handler.get('UnregisteredLongTwo').should.equal Rack::Handler::UnregisteredLongTwo + ensure + $:.delete "test/unregistered_handler" + end + end end diff --git a/test/unregistered_handler/rack/handler/unregistered.rb b/test/unregistered_handler/rack/handler/unregistered.rb new file mode 100644 index 0000000..6dd9436 --- /dev/null +++ b/test/unregistered_handler/rack/handler/unregistered.rb @@ -0,0 +1,7 @@ +module Rack + module Handler + # this class doesn't do anything, we're just seeing if we get it. + class Unregistered + end + end +end \ No newline at end of file diff --git a/test/unregistered_handler/rack/handler/unregistered_long_one.rb b/test/unregistered_handler/rack/handler/unregistered_long_one.rb new file mode 100644 index 0000000..1920685 --- /dev/null +++ b/test/unregistered_handler/rack/handler/unregistered_long_one.rb @@ -0,0 +1,7 @@ +module Rack + module Handler + # this class doesn't do anything, we're just seeing if we get it. + class UnregisteredLongOne + end + end +end \ No newline at end of file diff --git a/test/unregistered_handler/rack/handler/unregisteredlongtwo.rb b/test/unregistered_handler/rack/handler/unregisteredlongtwo.rb new file mode 100644 index 0000000..3c2e4b8 --- /dev/null +++ b/test/unregistered_handler/rack/handler/unregisteredlongtwo.rb @@ -0,0 +1,7 @@ +module Rack + module Handler + # this class doesn't do anything, we're just seeing if we get it. + class UnregisteredLongTwo + end + end +end \ No newline at end of file -- 1.6.1.2