class Rack::Sendfile

def call(env)

def call(env)
  _, headers, body = response = @app.call(env)
  if body.respond_to?(:to_path)
    case type = variation(env)
    when /x-accel-redirect/i
      path = ::File.expand_path(body.to_path)
      if url = map_accel_path(env, path)
        headers[CONTENT_LENGTH] = '0'
        # '?' must be percent-encoded because it is not query string but a part of path
        headers[type.downcase] = ::Rack::Utils.escape_path(url).gsub('?', '%3F')
        obody = body
        response[2] = Rack::BodyProxy.new([]) do
          obody.close if obody.respond_to?(:close)
        end
      else
        env[RACK_ERRORS].puts "x-accel-mapping header missing"
      end
    when /x-sendfile|x-lighttpd-send-file/i
      path = ::File.expand_path(body.to_path)
      headers[CONTENT_LENGTH] = '0'
      headers[type.downcase] = path
      obody = body
      response[2] = Rack::BodyProxy.new([]) do
        obody.close if obody.respond_to?(:close)
      end
    when '', nil
    else
      env[RACK_ERRORS].puts "Unknown x-sendfile variation: '#{type}'.\n"
    end
  end
  response
end

def initialize(app, variation = nil, mappings = [])

def initialize(app, variation = nil, mappings = [])
  @app = app
  @variation = variation
  @mappings = mappings.map do |internal, external|
    [/^#{internal}/i, external]
  end
end

def map_accel_path(env, path)

def map_accel_path(env, path)
  if mapping = @mappings.find { |internal, _| internal =~ path }
    path.sub(*mapping)
  elsif mapping = env['HTTP_X_ACCEL_MAPPING']
    mapping.split(',').map(&:strip).each do |m|
      internal, external = m.split('=', 2).map(&:strip)
      new_path = path.sub(/^#{internal}/i, external)
      return new_path unless path == new_path
    end
    path
  end
end

def variation(env)

def variation(env)
  @variation ||
    env['sendfile.type'] ||
    env['HTTP_X_SENDFILE_TYPE']
end