diff options
| author | Piotr Sarnacki <drogus@gmail.com> | 2010-09-03 12:48:21 +0200 | 
|---|---|---|
| committer | Piotr Sarnacki <drogus@gmail.com> | 2010-09-04 00:07:34 +0200 | 
| commit | 9f0a1ae14e2a9306605d7b572612ccf36fa8b2da (patch) | |
| tree | fc9d7161761452a392501876a183c9c4c684420c /actionpack/lib/action_dispatch/middleware | |
| parent | 89bd715f6be4235ac7632de10349e9939be04e75 (diff) | |
| download | rails-9f0a1ae14e2a9306605d7b572612ccf36fa8b2da.tar.gz rails-9f0a1ae14e2a9306605d7b572612ccf36fa8b2da.tar.bz2 rails-9f0a1ae14e2a9306605d7b572612ccf36fa8b2da.zip  | |
Optimize ActionDispatch::Static
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware')
| -rw-r--r-- | actionpack/lib/action_dispatch/middleware/static.rb | 86 | 
1 files changed, 35 insertions, 51 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index c2d686f514..e7e335df49 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -1,44 +1,43 @@  require 'rack/utils'  module ActionDispatch -  class Static -    class FileHandler -      def initialize(at, root) -        @at = at.chomp("/") -        @file_server = ::Rack::File.new(root) -      end - -      def file_exist?(path) -        (path = full_readable_path(path)) && File.file?(path) -      end - -      def directory_exist?(path) -        (path = full_readable_path(path)) && File.directory?(path) -      end - -      def call(env) -        env["PATH_INFO"].gsub!(/^#{@at}/, "") -        @file_server.call(env) -      end +  class FileHandler +    def initialize(at, root) +      @at, @root = at.chomp('/'), root.chomp('/') +      @compiled_at = Regexp.compile(/^#{Regexp.escape(at)}/) unless @at.blank? +      @compiled_root = Regexp.compile(/^#{Regexp.escape(root)}/) +      @file_server = ::Rack::File.new(root) + +      ext = ::ActionController::Base.page_cache_extension +      @ext = "{,#{ext},/index#{ext}}" +    end -      private -        def includes_path?(path) -          @at == "" || path =~ /^#{@at}/ +    def match?(path) +      path = path.dup +      if @compiled_at.blank? || path.sub!(@compiled_at, '') +        full_path = File.join(@root, ::Rack::Utils.unescape(path)) +        paths = "#{full_path}#{@ext}" + +        matches = Dir[paths] +        match = matches.detect { |m| File.file?(m) } +        if match +          match.sub!(@compiled_root, '') +          match          end +      end +    end -        def full_readable_path(path) -          return unless includes_path?(path) -          path = path.gsub(/^#{@at}/, "") -          File.join(@file_server.root, ::Rack::Utils.unescape(path)) -        end +    def call(env) +      @file_server.call(env)      end +  end +  class Static      FILE_METHODS = %w(GET HEAD).freeze      def initialize(app, roots)        @app = app -      roots = normalize_roots(roots) -      @file_handlers = file_handlers(roots) +      @file_handlers = create_file_handlers(roots)      end      def call(env) @@ -46,14 +45,9 @@ module ActionDispatch        method = env['REQUEST_METHOD']        if FILE_METHODS.include?(method) -        if file_handler = file_exist?(path) -          return file_handler.call(env) -        else -          cached_path = directory_exist?(path) ? "#{path}/index" : path -          cached_path += ::ActionController::Base.page_cache_extension - -          if file_handler = file_exist?(cached_path) -            env['PATH_INFO'] = cached_path +        @file_handlers.each do |file_handler| +          if match = file_handler.match?(path) +            env["PATH_INFO"] = match              return file_handler.call(env)            end          end @@ -63,22 +57,12 @@ module ActionDispatch      end      private -      def file_exist?(path) -        @file_handlers.detect { |f| f.file_exist?(path) } -      end +      def create_file_handlers(roots) +        roots = { '' => roots } unless roots.is_a?(Hash) -      def directory_exist?(path) -        @file_handlers.detect { |f| f.directory_exist?(path) } -      end - -      def normalize_roots(roots) -        roots.is_a?(Hash) ? roots : { "/" => roots.chomp("/") } -      end - -      def file_handlers(roots)          roots.map do |at, root| -          FileHandler.new(at, root) -        end +          FileHandler.new(at, root) if File.exist?(root) +        end.compact        end    end  end  | 
