about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/mongrel.rb23
-rw-r--r--test/test_uriclassifier.rb16
2 files changed, 28 insertions, 11 deletions
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 87afe00..8debb28 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -53,6 +53,7 @@ module Mongrel
     def initialize
       @handler_map = {}
       @matcher = //
+      @root_handler = nil
     end
     
     # Register a handler object at a particular URI. The handler can be whatever
@@ -78,8 +79,11 @@ module Mongrel
     
     # Resolve a request URI by finding the best partial match in the registered
     # handler URIs.
-    def resolve(request_uri)      
-      if match = @matcher.match(request_uri)
+    def resolve(request_uri)
+      if @root_handler
+        # Optimization for the pathological case of only one handler on "/"; e.g. Rails
+        [Const::SLASH, request_uri, @root_handler]
+      elsif match = @matcher.match(request_uri)
         uri = match.to_s
         path_info = match.post_match
         # A root mounted ("/") handler must resolve such that path info matches the original URI.
@@ -93,12 +97,17 @@ module Mongrel
     private
     
     def rebuild
-      routes = @handler_map.keys.sort.sort_by do |uri|
-        -uri.length
+      if @handler_map.size == 1 and @handler_map[Const::SLASH]
+        @root_handler = @handler_map.values.first
+      else
+        @root_handler = nil
+        routes = @handler_map.keys.sort.sort_by do |uri|
+          -uri.length
+        end
+        @matcher = Regexp.new(routes.map do |uri|
+          Regexp.new('^' + Regexp.escape(uri))
+        end.join('|'))
       end
-      @matcher = Regexp.new(routes.map do |uri|
-        Regexp.new('^' + Regexp.escape(uri))
-      end.join('|'))
     end    
     
   end
diff --git a/test/test_uriclassifier.rb b/test/test_uriclassifier.rb
index cf77384..2acb042 100644
--- a/test/test_uriclassifier.rb
+++ b/test/test_uriclassifier.rb
@@ -15,11 +15,19 @@ class URIClassifierTest < Test::Unit::TestCase
     uri_classifier.register("/test", 1)
     
     script_name, path_info, value = uri_classifier.resolve("/test")
-    assert value
     assert_equal 1, value
     assert_equal "/test", script_name
   end
-
+  
+  def test_root_handler_only
+    uri_classifier = URIClassifier.new
+    uri_classifier.register("/", 1)
+    
+    script_name, path_info, value = uri_classifier.resolve("/test")
+    assert_equal 1, value
+    assert_equal "/", script_name
+    assert_equal "/test", path_info
+  end
 
   def test_uri_prefix_ops
     test = "/pre/fix/test"
@@ -30,7 +38,7 @@ class URIClassifierTest < Test::Unit::TestCase
 
     script_name, path_info, value = uri_classifier.resolve(prefix)
     script_name, path_info, value = uri_classifier.resolve(test)
-    assert value
+    assert_equal 1, value
     assert_equal prefix, script_name
     assert_equal test[script_name.length .. -1], path_info
 
@@ -219,7 +227,7 @@ class URIClassifierTest < Test::Unit::TestCase
       @classifier.register(uri, 1)
     end
     
-#    puts "#{@uris.size} URIs / #{@requests.size * 10000} requests"
+    puts "#{@uris.size} URIs / #{@requests.size * 10000} requests"
 
     Benchmark.bm do |x|
       x.report do