rack-contrib-with-working-jsonp 0.9.2.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/COPYING +18 -0
 - data/README.rdoc +78 -0
 - data/Rakefile +97 -0
 - data/lib/rack/contrib.rb +37 -0
 - data/lib/rack/contrib/accept_format.rb +46 -0
 - data/lib/rack/contrib/backstage.rb +20 -0
 - data/lib/rack/contrib/bounce_favicon.rb +16 -0
 - data/lib/rack/contrib/callbacks.rb +37 -0
 - data/lib/rack/contrib/config.rb +16 -0
 - data/lib/rack/contrib/cookies.rb +50 -0
 - data/lib/rack/contrib/csshttprequest.rb +39 -0
 - data/lib/rack/contrib/deflect.rb +137 -0
 - data/lib/rack/contrib/etag.rb +20 -0
 - data/lib/rack/contrib/evil.rb +12 -0
 - data/lib/rack/contrib/garbagecollector.rb +14 -0
 - data/lib/rack/contrib/jsonp.rb +41 -0
 - data/lib/rack/contrib/lighttpd_script_name_fix.rb +16 -0
 - data/lib/rack/contrib/locale.rb +31 -0
 - data/lib/rack/contrib/mailexceptions.rb +120 -0
 - data/lib/rack/contrib/nested_params.rb +143 -0
 - data/lib/rack/contrib/not_found.rb +18 -0
 - data/lib/rack/contrib/post_body_content_type_parser.rb +40 -0
 - data/lib/rack/contrib/proctitle.rb +30 -0
 - data/lib/rack/contrib/profiler.rb +108 -0
 - data/lib/rack/contrib/relative_redirect.rb +44 -0
 - data/lib/rack/contrib/response_cache.rb +59 -0
 - data/lib/rack/contrib/route_exceptions.rb +49 -0
 - data/lib/rack/contrib/sendfile.rb +142 -0
 - data/lib/rack/contrib/signals.rb +63 -0
 - data/lib/rack/contrib/time_zone.rb +25 -0
 - data/rack-contrib.gemspec +88 -0
 - data/test/404.html +1 -0
 - data/test/Maintenance.html +1 -0
 - data/test/mail_settings.rb +12 -0
 - data/test/spec_rack_accept_format.rb +72 -0
 - data/test/spec_rack_backstage.rb +26 -0
 - data/test/spec_rack_callbacks.rb +65 -0
 - data/test/spec_rack_config.rb +22 -0
 - data/test/spec_rack_contrib.rb +8 -0
 - data/test/spec_rack_csshttprequest.rb +66 -0
 - data/test/spec_rack_deflect.rb +107 -0
 - data/test/spec_rack_etag.rb +23 -0
 - data/test/spec_rack_evil.rb +19 -0
 - data/test/spec_rack_garbagecollector.rb +13 -0
 - data/test/spec_rack_jsonp.rb +34 -0
 - data/test/spec_rack_lighttpd_script_name_fix.rb +16 -0
 - data/test/spec_rack_mailexceptions.rb +97 -0
 - data/test/spec_rack_nested_params.rb +46 -0
 - data/test/spec_rack_not_found.rb +17 -0
 - data/test/spec_rack_post_body_content_type_parser.rb +32 -0
 - data/test/spec_rack_proctitle.rb +26 -0
 - data/test/spec_rack_profiler.rb +37 -0
 - data/test/spec_rack_relative_redirect.rb +78 -0
 - data/test/spec_rack_response_cache.rb +137 -0
 - data/test/spec_rack_sendfile.rb +86 -0
 - metadata +174 -0
 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Rack::NotFound is a default endpoint. Initialize with the path to
         
     | 
| 
      
 3 
     | 
    
         
            +
              # your 404 page.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              class NotFound
         
     | 
| 
      
 6 
     | 
    
         
            +
                F = ::File
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(path)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  file = F.expand_path(path)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @content = F.read(file)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @length = @content.size.to_s
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                def call(env)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  [404, {'Content-Type' => 'text/html', 'Content-Length' => @length}, [@content]]
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            begin
         
     | 
| 
      
 2 
     | 
    
         
            +
              require 'json'
         
     | 
| 
      
 3 
     | 
    
         
            +
            rescue LoadError => e
         
     | 
| 
      
 4 
     | 
    
         
            +
              require 'json/pure'
         
     | 
| 
      
 5 
     | 
    
         
            +
            end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              # A Rack middleware for parsing POST/PUT body data when Content-Type is
         
     | 
| 
      
 10 
     | 
    
         
            +
              # not one of the standard supported types, like <tt>application/json</tt>.
         
     | 
| 
      
 11 
     | 
    
         
            +
              #
         
     | 
| 
      
 12 
     | 
    
         
            +
              # TODO: Find a better name.
         
     | 
| 
      
 13 
     | 
    
         
            +
              #
         
     | 
| 
      
 14 
     | 
    
         
            +
              class PostBodyContentTypeParser
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                # Constants
         
     | 
| 
      
 17 
     | 
    
         
            +
                #
         
     | 
| 
      
 18 
     | 
    
         
            +
                CONTENT_TYPE = 'CONTENT_TYPE'.freeze
         
     | 
| 
      
 19 
     | 
    
         
            +
                POST_BODY = 'rack.input'.freeze
         
     | 
| 
      
 20 
     | 
    
         
            +
                FORM_INPUT = 'rack.request.form_input'.freeze
         
     | 
| 
      
 21 
     | 
    
         
            +
                FORM_HASH = 'rack.request.form_hash'.freeze
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                # Supported Content-Types
         
     | 
| 
      
 24 
     | 
    
         
            +
                #
         
     | 
| 
      
 25 
     | 
    
         
            +
                APPLICATION_JSON = 'application/json'.freeze
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def initialize(app)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @app = app
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def call(env)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  case env[CONTENT_TYPE]
         
     | 
| 
      
 33 
     | 
    
         
            +
                  when APPLICATION_JSON
         
     | 
| 
      
 34 
     | 
    
         
            +
                    env.update(FORM_HASH => JSON.parse(env[POST_BODY].read), FORM_INPUT => env[POST_BODY])
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @app.call(env)
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 2 
     | 
    
         
            +
              # Middleware to update the process title ($0) with information about the
         
     | 
| 
      
 3 
     | 
    
         
            +
              # current request. Based loosely on:
         
     | 
| 
      
 4 
     | 
    
         
            +
              # - http://purefiction.net/mongrel_proctitle/
         
     | 
| 
      
 5 
     | 
    
         
            +
              # - http://github.com/grempe/thin-proctitle/tree/master
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # NOTE: This will not work properly in a multi-threaded environment.
         
     | 
| 
      
 8 
     | 
    
         
            +
              class ProcTitle
         
     | 
| 
      
 9 
     | 
    
         
            +
                F = ::File
         
     | 
| 
      
 10 
     | 
    
         
            +
                PROGNAME = F.basename($0)
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(app)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @app = app
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @appname = Dir.pwd.split('/').reverse.
         
     | 
| 
      
 15 
     | 
    
         
            +
                    find { |name| name !~ /^(\d+|current|releases)$/ } || PROGNAME
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @requests = 0
         
     | 
| 
      
 17 
     | 
    
         
            +
                  $0 = "#{PROGNAME} [#{@appname}] init ..."
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def call(env)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  host, port = env['SERVER_NAME'], env['SERVER_PORT']
         
     | 
| 
      
 22 
     | 
    
         
            +
                  meth, path = env['REQUEST_METHOD'], env['PATH_INFO']
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @requests += 1
         
     | 
| 
      
 24 
     | 
    
         
            +
                  $0 = "#{PROGNAME} [#{@appname}/#{port}] (#{@requests}) " \
         
     | 
| 
      
 25 
     | 
    
         
            +
                       "#{meth} #{path}"
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  @app.call(env)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,108 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'ruby-prof'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Set the profile=process_time query parameter to download a
         
     | 
| 
      
 5 
     | 
    
         
            +
              # calltree profile of the request.
         
     | 
| 
      
 6 
     | 
    
         
            +
              #
         
     | 
| 
      
 7 
     | 
    
         
            +
              # Pass the :printer option to pick a different result format.
         
     | 
| 
      
 8 
     | 
    
         
            +
              class Profiler
         
     | 
| 
      
 9 
     | 
    
         
            +
                MODES = %w(
         
     | 
| 
      
 10 
     | 
    
         
            +
                  process_time
         
     | 
| 
      
 11 
     | 
    
         
            +
                  wall_time
         
     | 
| 
      
 12 
     | 
    
         
            +
                  cpu_time
         
     | 
| 
      
 13 
     | 
    
         
            +
                  allocations
         
     | 
| 
      
 14 
     | 
    
         
            +
                  memory
         
     | 
| 
      
 15 
     | 
    
         
            +
                  gc_runs
         
     | 
| 
      
 16 
     | 
    
         
            +
                  gc_time
         
     | 
| 
      
 17 
     | 
    
         
            +
                )
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                DEFAULT_PRINTER = RubyProf::CallTreePrinter
         
     | 
| 
      
 20 
     | 
    
         
            +
                DEFAULT_CONTENT_TYPE = 'application/octet-stream'
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                PRINTER_CONTENT_TYPE = {
         
     | 
| 
      
 23 
     | 
    
         
            +
                  RubyProf::FlatPrinter => 'text/plain',
         
     | 
| 
      
 24 
     | 
    
         
            +
                  RubyProf::GraphPrinter => 'text/plain',
         
     | 
| 
      
 25 
     | 
    
         
            +
                  RubyProf::GraphHtmlPrinter => 'text/html'
         
     | 
| 
      
 26 
     | 
    
         
            +
                }
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                # Accepts a :printer => [:call_tree|:graph_html|:graph|:flat] option
         
     | 
| 
      
 29 
     | 
    
         
            +
                # defaulting to :call_tree.
         
     | 
| 
      
 30 
     | 
    
         
            +
                def initialize(app, options = {})
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @app = app
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @printer = parse_printer(options[:printer])
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @times = (options[:times] || 1).to_i
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def call(env)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  if mode = profiling?(env)
         
     | 
| 
      
 38 
     | 
    
         
            +
                    profile(env, mode)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  else
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @app.call(env)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                private
         
     | 
| 
      
 45 
     | 
    
         
            +
                  def profiling?(env)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    unless RubyProf.running?
         
     | 
| 
      
 47 
     | 
    
         
            +
                      request = Rack::Request.new(env)
         
     | 
| 
      
 48 
     | 
    
         
            +
                      if mode = request.params.delete('profile')
         
     | 
| 
      
 49 
     | 
    
         
            +
                        if RubyProf.const_defined?(mode.upcase)
         
     | 
| 
      
 50 
     | 
    
         
            +
                          mode
         
     | 
| 
      
 51 
     | 
    
         
            +
                        else
         
     | 
| 
      
 52 
     | 
    
         
            +
                          env['rack.errors'].write "Invalid RubyProf measure_mode: " +
         
     | 
| 
      
 53 
     | 
    
         
            +
                            "#{mode}. Use one of #{MODES.to_a.join(', ')}"
         
     | 
| 
      
 54 
     | 
    
         
            +
                          false
         
     | 
| 
      
 55 
     | 
    
         
            +
                        end
         
     | 
| 
      
 56 
     | 
    
         
            +
                      end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                  def profile(env, mode)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    RubyProf.measure_mode = RubyProf.const_get(mode.upcase)
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    GC.enable_stats if GC.respond_to?(:enable_stats)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    result = RubyProf.profile do
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @times.times { @app.call(env) }
         
     | 
| 
      
 66 
     | 
    
         
            +
                    end
         
     | 
| 
      
 67 
     | 
    
         
            +
                    GC.disable_stats if GC.respond_to?(:disable_stats)
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    [200, headers(@printer, env, mode), print(@printer, result)]
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  def print(printer, result)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    body = StringIO.new
         
     | 
| 
      
 74 
     | 
    
         
            +
                    printer.new(result).print(body, :min_percent => 0.01)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    body.rewind
         
     | 
| 
      
 76 
     | 
    
         
            +
                    body
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def headers(printer, env, mode)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    headers = { 'Content-Type' => PRINTER_CONTENT_TYPE[printer] || DEFAULT_CONTENT_TYPE }
         
     | 
| 
      
 81 
     | 
    
         
            +
                    if printer == RubyProf::CallTreePrinter
         
     | 
| 
      
 82 
     | 
    
         
            +
                      filename = ::File.basename(env['PATH_INFO'])
         
     | 
| 
      
 83 
     | 
    
         
            +
                      headers['Content-Disposition'] =
         
     | 
| 
      
 84 
     | 
    
         
            +
                        %(attachment; filename="#{filename}.#{mode}.tree")
         
     | 
| 
      
 85 
     | 
    
         
            +
                    end
         
     | 
| 
      
 86 
     | 
    
         
            +
                    headers
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  def parse_printer(printer)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    if printer.nil?
         
     | 
| 
      
 91 
     | 
    
         
            +
                      DEFAULT_PRINTER
         
     | 
| 
      
 92 
     | 
    
         
            +
                    elsif printer.is_a?(Class)
         
     | 
| 
      
 93 
     | 
    
         
            +
                      printer
         
     | 
| 
      
 94 
     | 
    
         
            +
                    else
         
     | 
| 
      
 95 
     | 
    
         
            +
                      name = "#{camel_case(printer)}Printer"
         
     | 
| 
      
 96 
     | 
    
         
            +
                      if RubyProf.const_defined?(name)
         
     | 
| 
      
 97 
     | 
    
         
            +
                        RubyProf.const_get(name)
         
     | 
| 
      
 98 
     | 
    
         
            +
                      else
         
     | 
| 
      
 99 
     | 
    
         
            +
                        DEFAULT_PRINTER
         
     | 
| 
      
 100 
     | 
    
         
            +
                      end
         
     | 
| 
      
 101 
     | 
    
         
            +
                    end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                  def camel_case(word)
         
     | 
| 
      
 105 
     | 
    
         
            +
                    word.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
              end
         
     | 
| 
      
 108 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rack'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Rack::RelativeRedirect is a simple middleware that converts relative paths in
         
     | 
| 
      
 4 
     | 
    
         
            +
            # redirects in absolute urls, so they conform to RFC2616. It allows the user to
         
     | 
| 
      
 5 
     | 
    
         
            +
            # specify the absolute path to use (with a sensible default), and handles
         
     | 
| 
      
 6 
     | 
    
         
            +
            # relative paths (those that don't start with a slash) as well.
         
     | 
| 
      
 7 
     | 
    
         
            +
            class Rack::RelativeRedirect
         
     | 
| 
      
 8 
     | 
    
         
            +
              SCHEME_MAP = {'http'=>'80', 'https'=>'443'}
         
     | 
| 
      
 9 
     | 
    
         
            +
              # The default proc used if a block is not provided to .new
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Just uses the url scheme of the request and the server name.
         
     | 
| 
      
 11 
     | 
    
         
            +
              DEFAULT_ABSOLUTE_PROC = proc do |env, res|
         
     | 
| 
      
 12 
     | 
    
         
            +
                port = env['SERVER_PORT']
         
     | 
| 
      
 13 
     | 
    
         
            +
                scheme = env['rack.url_scheme']
         
     | 
| 
      
 14 
     | 
    
         
            +
                "#{scheme}://#{env['SERVER_NAME']}#{":#{port}" unless SCHEME_MAP[scheme] == port}"
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              # Initialize a new RelativeRedirect object with the given arguments.  Arguments:
         
     | 
| 
      
 18 
     | 
    
         
            +
              # * app : The next middleware in the chain.  This is always called.
         
     | 
| 
      
 19 
     | 
    
         
            +
              # * &block : If provided, it is called with the environment and the response
         
     | 
| 
      
 20 
     | 
    
         
            +
              #   from the next middleware. It should return a string representing the scheme
         
     | 
| 
      
 21 
     | 
    
         
            +
              #   and server name (such as 'http://example.org').
         
     | 
| 
      
 22 
     | 
    
         
            +
              def initialize(app, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 24 
     | 
    
         
            +
                @absolute_proc = block || DEFAULT_ABSOLUTE_PROC
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
              # Call the next middleware with the environment.  If the request was a
         
     | 
| 
      
 28 
     | 
    
         
            +
              # redirect (response status 301, 302, or 303), and the location header does
         
     | 
| 
      
 29 
     | 
    
         
            +
              # not start with an http or https url scheme, call the block provided by new
         
     | 
| 
      
 30 
     | 
    
         
            +
              # and use that to make the Location header an absolute url.  If the Location
         
     | 
| 
      
 31 
     | 
    
         
            +
              # does not start with a slash, make location relative to the path requested.
         
     | 
| 
      
 32 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 33 
     | 
    
         
            +
                res = @app.call(env)
         
     | 
| 
      
 34 
     | 
    
         
            +
                if [301,302,303].include?(res[0]) and loc = res[1]['Location'] and !%r{\Ahttps?://}o.match(loc)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  absolute = @absolute_proc.call(env, res)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  res[1]['Location'] = if %r{\A/}.match(loc)
         
     | 
| 
      
 37 
     | 
    
         
            +
                    "#{absolute}#{loc}"
         
     | 
| 
      
 38 
     | 
    
         
            +
                  else
         
     | 
| 
      
 39 
     | 
    
         
            +
                    "#{absolute}#{File.dirname(Rack::Utils.unescape(env['PATH_INFO']))}/#{loc}"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
                res
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rack'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            # Rack::ResponseCache is a Rack middleware that caches responses for successful
         
     | 
| 
      
 5 
     | 
    
         
            +
            # GET requests with no query string to disk or any ruby object that has an
         
     | 
| 
      
 6 
     | 
    
         
            +
            # []= method (so it works with memcached).  When caching to disk, it works similar to
         
     | 
| 
      
 7 
     | 
    
         
            +
            # Rails' page caching, allowing you to cache dynamic pages to static files that can
         
     | 
| 
      
 8 
     | 
    
         
            +
            # be served directly by a front end webserver.
         
     | 
| 
      
 9 
     | 
    
         
            +
            class Rack::ResponseCache
         
     | 
| 
      
 10 
     | 
    
         
            +
              # The default proc used if a block is not provided to .new
         
     | 
| 
      
 11 
     | 
    
         
            +
              # It unescapes the PATH_INFO of the environment, and makes sure that it doesn't
         
     | 
| 
      
 12 
     | 
    
         
            +
              # include '..'.  If the Content-Type of the response is text/(html|css|xml),
         
     | 
| 
      
 13 
     | 
    
         
            +
              # return a path with the appropriate extension (.html, .css, or .xml).
         
     | 
| 
      
 14 
     | 
    
         
            +
              # If the path ends with a / and the Content-Type is text/html, change the basename
         
     | 
| 
      
 15 
     | 
    
         
            +
              # of the path to index.html.
         
     | 
| 
      
 16 
     | 
    
         
            +
              DEFAULT_PATH_PROC = proc do |env, res|
         
     | 
| 
      
 17 
     | 
    
         
            +
                path = Rack::Utils.unescape(env['PATH_INFO'])
         
     | 
| 
      
 18 
     | 
    
         
            +
                if !path.include?('..') and match = /text\/((?:x|ht)ml|css)/o.match(res[1]['Content-Type'])
         
     | 
| 
      
 19 
     | 
    
         
            +
                  type = match[1]
         
     | 
| 
      
 20 
     | 
    
         
            +
                  path = "#{path}.#{type}" unless /\.#{type}\z/.match(path)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  path = File.join(File.dirname(path), 'index.html') if type == 'html' and File.basename(path) == '.html'
         
     | 
| 
      
 22 
     | 
    
         
            +
                  path
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              # Initialize a new ReponseCache object with the given arguments.  Arguments:
         
     | 
| 
      
 27 
     | 
    
         
            +
              # * app : The next middleware in the chain.  This is always called.
         
     | 
| 
      
 28 
     | 
    
         
            +
              # * cache : The place to cache responses.  If a string is provided, a disk
         
     | 
| 
      
 29 
     | 
    
         
            +
              #   cache is used, and all cached files will use this directory as the root directory.
         
     | 
| 
      
 30 
     | 
    
         
            +
              #   If anything other than a string is provided, it should respond to []=, which will
         
     | 
| 
      
 31 
     | 
    
         
            +
              #   be called with a path string and a body value (the 3rd element of the response).
         
     | 
| 
      
 32 
     | 
    
         
            +
              # * &block : If provided, it is called with the environment and the response from the next middleware.
         
     | 
| 
      
 33 
     | 
    
         
            +
              #   It should return nil or false if the path should not be cached, and should return
         
     | 
| 
      
 34 
     | 
    
         
            +
              #   the pathname to use as a string if the result should be cached.
         
     | 
| 
      
 35 
     | 
    
         
            +
              #   If not provided, the DEFAULT_PATH_PROC is used.
         
     | 
| 
      
 36 
     | 
    
         
            +
              def initialize(app, cache, &block)
         
     | 
| 
      
 37 
     | 
    
         
            +
                @app = app
         
     | 
| 
      
 38 
     | 
    
         
            +
                @cache = cache
         
     | 
| 
      
 39 
     | 
    
         
            +
                @path_proc = block || DEFAULT_PATH_PROC
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              # Call the next middleware with the environment.  If the request was successful (response status 200),
         
     | 
| 
      
 43 
     | 
    
         
            +
              # was a GET request, and had an empty query string, call the block set up in initialize to get the path.
         
     | 
| 
      
 44 
     | 
    
         
            +
              # If the cache is a string, create any necessary middle directories, and cache the file in the appropriate
         
     | 
| 
      
 45 
     | 
    
         
            +
              # subdirectory of cache.  Otherwise, cache the body of the reponse as the value with the path as the key.
         
     | 
| 
      
 46 
     | 
    
         
            +
              def call(env)
         
     | 
| 
      
 47 
     | 
    
         
            +
                res = @app.call(env)
         
     | 
| 
      
 48 
     | 
    
         
            +
                if env['REQUEST_METHOD'] == 'GET' and env['QUERY_STRING'] == '' and res[0] == 200 and path = @path_proc.call(env, res)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  if @cache.is_a?(String)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    path = File.join(@cache, path) if @cache
         
     | 
| 
      
 51 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.dirname(path))
         
     | 
| 
      
 52 
     | 
    
         
            +
                    File.open(path, 'wb'){|f| res[2].each{|c| f.write(c)}}
         
     | 
| 
      
 53 
     | 
    
         
            +
                  else
         
     | 
| 
      
 54 
     | 
    
         
            +
                    @cache[path] = res[2]
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
                res
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,49 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 2 
     | 
    
         
            +
              class RouteExceptions
         
     | 
| 
      
 3 
     | 
    
         
            +
                ROUTES = [
         
     | 
| 
      
 4 
     | 
    
         
            +
                  [Exception, '/error/internal']
         
     | 
| 
      
 5 
     | 
    
         
            +
                ]
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                PATH_INFO = 'rack.route_exceptions.path_info'.freeze
         
     | 
| 
      
 8 
     | 
    
         
            +
                EXCEPTION = 'rack.route_exceptions.exception'.freeze
         
     | 
| 
      
 9 
     | 
    
         
            +
                RETURNED  = 'rack.route_exceptions.returned'.freeze
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def route(exception, to)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    ROUTES.delete_if{|k,v| k == exception }
         
     | 
| 
      
 14 
     | 
    
         
            +
                    ROUTES << [exception, to]
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  alias []= route
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def initialize(app)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @app = app
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def call(env, try_again = true)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  returned = @app.call(env)
         
     | 
| 
      
 26 
     | 
    
         
            +
                rescue Exception => exception
         
     | 
| 
      
 27 
     | 
    
         
            +
                  raise(exception) unless try_again
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  ROUTES.each do |klass, to|
         
     | 
| 
      
 30 
     | 
    
         
            +
                    next unless klass === exception
         
     | 
| 
      
 31 
     | 
    
         
            +
                    return route(to, env, returned, exception)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  raise(exception)
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def route(to, env, returned, exception)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  env.merge!(
         
     | 
| 
      
 39 
     | 
    
         
            +
                    PATH_INFO => env['PATH_INFO'],
         
     | 
| 
      
 40 
     | 
    
         
            +
                    EXCEPTION => exception,
         
     | 
| 
      
 41 
     | 
    
         
            +
                    RETURNED => returned
         
     | 
| 
      
 42 
     | 
    
         
            +
                  )
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  env['PATH_INFO'] = to
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  call(env, try_again = false)
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,142 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rack/file'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Rack
         
     | 
| 
      
 4 
     | 
    
         
            +
              class File #:nodoc:
         
     | 
| 
      
 5 
     | 
    
         
            +
                alias :to_path :path
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              # = Sendfile
         
     | 
| 
      
 9 
     | 
    
         
            +
              #
         
     | 
| 
      
 10 
     | 
    
         
            +
              # The Sendfile middleware intercepts responses whose body is being
         
     | 
| 
      
 11 
     | 
    
         
            +
              # served from a file and replaces it with a server specific X-Sendfile
         
     | 
| 
      
 12 
     | 
    
         
            +
              # header. The web server is then responsible for writing the file contents
         
     | 
| 
      
 13 
     | 
    
         
            +
              # to the client. This can dramatically reduce the amount of work required
         
     | 
| 
      
 14 
     | 
    
         
            +
              # by the Ruby backend and takes advantage of the web servers optimized file
         
     | 
| 
      
 15 
     | 
    
         
            +
              # delivery code.
         
     | 
| 
      
 16 
     | 
    
         
            +
              #
         
     | 
| 
      
 17 
     | 
    
         
            +
              # In order to take advantage of this middleware, the response body must
         
     | 
| 
      
 18 
     | 
    
         
            +
              # respond to +to_path+ and the request must include an X-Sendfile-Type
         
     | 
| 
      
 19 
     | 
    
         
            +
              # header. Rack::File and other components implement +to_path+ so there's
         
     | 
| 
      
 20 
     | 
    
         
            +
              # rarely anything you need to do in your application. The X-Sendfile-Type
         
     | 
| 
      
 21 
     | 
    
         
            +
              # header is typically set in your web servers configuration. The following
         
     | 
| 
      
 22 
     | 
    
         
            +
              # sections attempt to document
         
     | 
| 
      
 23 
     | 
    
         
            +
              #
         
     | 
| 
      
 24 
     | 
    
         
            +
              # === Nginx
         
     | 
| 
      
 25 
     | 
    
         
            +
              #
         
     | 
| 
      
 26 
     | 
    
         
            +
              # Nginx supports the X-Accel-Redirect header. This is similar to X-Sendfile
         
     | 
| 
      
 27 
     | 
    
         
            +
              # but requires parts of the filesystem to be mapped into a private URL
         
     | 
| 
      
 28 
     | 
    
         
            +
              # hierarachy.
         
     | 
| 
      
 29 
     | 
    
         
            +
              #
         
     | 
| 
      
 30 
     | 
    
         
            +
              # The following example shows the Nginx configuration required to create
         
     | 
| 
      
 31 
     | 
    
         
            +
              # a private "/files/" area, enable X-Accel-Redirect, and pass the special
         
     | 
| 
      
 32 
     | 
    
         
            +
              # X-Sendfile-Type and X-Accel-Mapping headers to the backend:
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              #   location /files/ {
         
     | 
| 
      
 35 
     | 
    
         
            +
              #     internal;
         
     | 
| 
      
 36 
     | 
    
         
            +
              #     alias /var/www/;
         
     | 
| 
      
 37 
     | 
    
         
            +
              #   }
         
     | 
| 
      
 38 
     | 
    
         
            +
              #
         
     | 
| 
      
 39 
     | 
    
         
            +
              #   location / {
         
     | 
| 
      
 40 
     | 
    
         
            +
              #     proxy_redirect     false;
         
     | 
| 
      
 41 
     | 
    
         
            +
              #
         
     | 
| 
      
 42 
     | 
    
         
            +
              #     proxy_set_header   Host                $host;
         
     | 
| 
      
 43 
     | 
    
         
            +
              #     proxy_set_header   X-Real-IP           $remote_addr;
         
     | 
| 
      
 44 
     | 
    
         
            +
              #     proxy_set_header   X-Forwarded-For     $proxy_add_x_forwarded_for;
         
     | 
| 
      
 45 
     | 
    
         
            +
              #
         
     | 
| 
      
 46 
     | 
    
         
            +
              #     proxy_set_header   X-Sendfile-Type     X-Accel-Redirect
         
     | 
| 
      
 47 
     | 
    
         
            +
              #     proxy_set_header   X-Accel-Mapping     /files/=/var/www/;
         
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              #     proxy_pass         http://127.0.0.1:8080/;
         
     | 
| 
      
 50 
     | 
    
         
            +
              #   }
         
     | 
| 
      
 51 
     | 
    
         
            +
              #
         
     | 
| 
      
 52 
     | 
    
         
            +
              # Note that the X-Sendfile-Type header must be set exactly as shown above. The
         
     | 
| 
      
 53 
     | 
    
         
            +
              # X-Accel-Mapping header should specify the name of the private URL pattern,
         
     | 
| 
      
 54 
     | 
    
         
            +
              # followed by an equals sign (=), followed by the location on the file system
         
     | 
| 
      
 55 
     | 
    
         
            +
              # that it maps to. The middleware performs a simple substitution on the
         
     | 
| 
      
 56 
     | 
    
         
            +
              # resulting path.
         
     | 
| 
      
 57 
     | 
    
         
            +
              #
         
     | 
| 
      
 58 
     | 
    
         
            +
              # See Also: http://wiki.codemongers.com/NginxXSendfile
         
     | 
| 
      
 59 
     | 
    
         
            +
              #
         
     | 
| 
      
 60 
     | 
    
         
            +
              # === lighttpd
         
     | 
| 
      
 61 
     | 
    
         
            +
              #
         
     | 
| 
      
 62 
     | 
    
         
            +
              # Lighttpd has supported some variation of the X-Sendfile header for some
         
     | 
| 
      
 63 
     | 
    
         
            +
              # time, although only recent version support X-Sendfile in a reverse proxy
         
     | 
| 
      
 64 
     | 
    
         
            +
              # configuration.
         
     | 
| 
      
 65 
     | 
    
         
            +
              #
         
     | 
| 
      
 66 
     | 
    
         
            +
              #   $HTTP["host"] == "example.com" {
         
     | 
| 
      
 67 
     | 
    
         
            +
              #      proxy-core.protocol = "http"
         
     | 
| 
      
 68 
     | 
    
         
            +
              #      proxy-core.balancer = "round-robin"
         
     | 
| 
      
 69 
     | 
    
         
            +
              #      proxy-core.backends = (
         
     | 
| 
      
 70 
     | 
    
         
            +
              #        "127.0.0.1:8000",
         
     | 
| 
      
 71 
     | 
    
         
            +
              #        "127.0.0.1:8001",
         
     | 
| 
      
 72 
     | 
    
         
            +
              #        ...
         
     | 
| 
      
 73 
     | 
    
         
            +
              #      )
         
     | 
| 
      
 74 
     | 
    
         
            +
              #
         
     | 
| 
      
 75 
     | 
    
         
            +
              #      proxy-core.allow-x-sendfile = "enable"
         
     | 
| 
      
 76 
     | 
    
         
            +
              #      proxy-core.rewrite-request = (
         
     | 
| 
      
 77 
     | 
    
         
            +
              #        "X-Sendfile-Type" => (".*" => "X-Sendfile")
         
     | 
| 
      
 78 
     | 
    
         
            +
              #      )
         
     | 
| 
      
 79 
     | 
    
         
            +
              #    }
         
     | 
| 
      
 80 
     | 
    
         
            +
              #
         
     | 
| 
      
 81 
     | 
    
         
            +
              # See Also: http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore
         
     | 
| 
      
 82 
     | 
    
         
            +
              #
         
     | 
| 
      
 83 
     | 
    
         
            +
              # === Apache
         
     | 
| 
      
 84 
     | 
    
         
            +
              #
         
     | 
| 
      
 85 
     | 
    
         
            +
              # X-Sendfile is supported under Apache 2.x using a separate module:
         
     | 
| 
      
 86 
     | 
    
         
            +
              #
         
     | 
| 
      
 87 
     | 
    
         
            +
              # http://tn123.ath.cx/mod_xsendfile/
         
     | 
| 
      
 88 
     | 
    
         
            +
              #
         
     | 
| 
      
 89 
     | 
    
         
            +
              # Once the module is compiled and installed, you can enable it using
         
     | 
| 
      
 90 
     | 
    
         
            +
              # XSendFile config directive:
         
     | 
| 
      
 91 
     | 
    
         
            +
              #
         
     | 
| 
      
 92 
     | 
    
         
            +
              #   RequestHeader Set X-Sendfile-Type X-Sendfile
         
     | 
| 
      
 93 
     | 
    
         
            +
              #   ProxyPassReverse / http://localhost:8001/
         
     | 
| 
      
 94 
     | 
    
         
            +
              #   XSendFile on
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              class Sendfile
         
     | 
| 
      
 97 
     | 
    
         
            +
                F = ::File
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                def initialize(app, variation=nil)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @app = app
         
     | 
| 
      
 101 
     | 
    
         
            +
                  @variation = variation
         
     | 
| 
      
 102 
     | 
    
         
            +
                end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                def call(env)
         
     | 
| 
      
 105 
     | 
    
         
            +
                  status, headers, body = @app.call(env)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  if body.respond_to?(:to_path)
         
     | 
| 
      
 107 
     | 
    
         
            +
                    case type = variation(env)
         
     | 
| 
      
 108 
     | 
    
         
            +
                    when 'X-Accel-Redirect'
         
     | 
| 
      
 109 
     | 
    
         
            +
                      path = F.expand_path(body.to_path)
         
     | 
| 
      
 110 
     | 
    
         
            +
                      if url = map_accel_path(env, path)
         
     | 
| 
      
 111 
     | 
    
         
            +
                        headers[type] = url
         
     | 
| 
      
 112 
     | 
    
         
            +
                        body = []
         
     | 
| 
      
 113 
     | 
    
         
            +
                      else
         
     | 
| 
      
 114 
     | 
    
         
            +
                        env['rack.errors'] << "X-Accel-Mapping header missing"
         
     | 
| 
      
 115 
     | 
    
         
            +
                      end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    when 'X-Sendfile', 'X-Lighttpd-Send-File'
         
     | 
| 
      
 117 
     | 
    
         
            +
                      path = F.expand_path(body.to_path)
         
     | 
| 
      
 118 
     | 
    
         
            +
                      headers[type] = path
         
     | 
| 
      
 119 
     | 
    
         
            +
                      body = []
         
     | 
| 
      
 120 
     | 
    
         
            +
                    when '', nil
         
     | 
| 
      
 121 
     | 
    
         
            +
                    else
         
     | 
| 
      
 122 
     | 
    
         
            +
                      env['rack.errors'] << "Unknown x-sendfile variation: '#{variation}'.\n"
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
                  [status, headers, body]
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
              private
         
     | 
| 
      
 129 
     | 
    
         
            +
                def variation(env)
         
     | 
| 
      
 130 
     | 
    
         
            +
                  @variation ||
         
     | 
| 
      
 131 
     | 
    
         
            +
                    env['sendfile.type'] ||
         
     | 
| 
      
 132 
     | 
    
         
            +
                    env['HTTP_X_SENDFILE_TYPE']
         
     | 
| 
      
 133 
     | 
    
         
            +
                end
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                def map_accel_path(env, file)
         
     | 
| 
      
 136 
     | 
    
         
            +
                  if mapping = env['HTTP_X_ACCEL_MAPPING']
         
     | 
| 
      
 137 
     | 
    
         
            +
                    internal, external = mapping.split('=', 2).map{ |p| p.strip }
         
     | 
| 
      
 138 
     | 
    
         
            +
                    file.sub(/^#{internal}/i, external)
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
              end
         
     | 
| 
      
 142 
     | 
    
         
            +
            end
         
     |