From 96c359a0d1fa90136c16914d5c1732a244e489bb Mon Sep 17 00:00:00 2001 From: Graham Batty Date: Thu, 26 Feb 2009 15:36:57 -0700 Subject: [PATCH 1/3] 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 From 16a37f7ed2257aada193225bb880b56e6f0c6168 Mon Sep 17 00:00:00 2001 From: Graham Batty Date: Thu, 26 Feb 2009 16:23:56 -0700 Subject: [PATCH 2/3] Made it so that the expectation is that Handler.get raises NameError on failure instead of nil under the principle of obvious failure. --- lib/rack/handler.rb | 6 +----- test/spec_rack_handler.rb | 10 +++++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/rack/handler.rb b/lib/rack/handler.rb index 32ca27e..ab7f046 100644 --- a/lib/rack/handler.rb +++ b/lib/rack/handler.rb @@ -36,11 +36,7 @@ module Rack 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 + return Rack::Handler.const_get(server.gsub(/(^|_)([a-z])/) {|a| $2.upcase }) end end diff --git a/test/spec_rack_handler.rb b/test/spec_rack_handler.rb index daad7ea..9b20b8e 100644 --- a/test/spec_rack_handler.rb +++ b/test/spec_rack_handler.rb @@ -13,8 +13,10 @@ context "Rack::Handler" do 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 + specify "handler that doesn't exist should raise a NameError" do + lambda { + Rack::Handler.get('boom') + }.should.raise(NameError) end specify "should get unregistered, but already required, handler by name" do @@ -31,7 +33,9 @@ context "Rack::Handler" do $:.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 + lambda { + Rack::Handler.get('UnRegistered') + }.should.raise(NameError) 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 -- 1.6.1.2 From 43248433899572999b74763c7d0340efc37ec3af Mon Sep 17 00:00:00 2001 From: Graham Batty Date: Thu, 26 Feb 2009 16:51:56 -0700 Subject: [PATCH 3/3] Simplified options for unregistered handlers Made it so that it only accepts FullyCapsedClassNames for unregistered handlers as per suggestions in #rack irc channel. --- lib/rack/handler.rb | 21 ++++--------------- test/spec_rack_handler.rb | 6 +---- .../rack/handler/unregisteredlongtwo.rb | 7 ------ 3 files changed, 6 insertions(+), 28 deletions(-) delete mode 100644 test/unregistered_handler/rack/handler/unregisteredlongtwo.rb diff --git a/lib/rack/handler.rb b/lib/rack/handler.rb index ab7f046..9f666a6 100644 --- a/lib/rack/handler.rb +++ b/lib/rack/handler.rb @@ -18,25 +18,14 @@ module Rack else # 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. + # a proper filename. BlahBlahBlorp -> blah_blah_blorp begin - # first try blahblahblorp from BlahBlahBlorp (this is the cheaper case, so do it first) - require 'rack/handler/' + server.downcase + # 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 - # 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 + # ignore it, move on and fail later. end - # Now try to const_get the handler in question after properly capitalizing it. - # blah_blah_blorp -> BlahBlahBlorp - return Rack::Handler.const_get(server.gsub(/(^|_)([a-z])/) {|a| $2.upcase }) + return Rack::Handler.const_get(server) end end diff --git a/test/spec_rack_handler.rb b/test/spec_rack_handler.rb index 9b20b8e..fcf19b7 100644 --- a/test/spec_rack_handler.rb +++ b/test/spec_rack_handler.rb @@ -20,7 +20,7 @@ context "Rack::Handler" do end specify "should get unregistered, but already required, handler by name" do - Rack::Handler.get('lobster').should.equal Rack::Handler::Lobster + Rack::Handler.get('Lobster').should.equal Rack::Handler::Lobster end specify "should register custom handler" do @@ -31,15 +31,11 @@ context "Rack::Handler" do 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 lambda { Rack::Handler.get('UnRegistered') }.should.raise(NameError) - 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 diff --git a/test/unregistered_handler/rack/handler/unregisteredlongtwo.rb b/test/unregistered_handler/rack/handler/unregisteredlongtwo.rb deleted file mode 100644 index 3c2e4b8..0000000 --- a/test/unregistered_handler/rack/handler/unregisteredlongtwo.rb +++ /dev/null @@ -1,7 +0,0 @@ -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