class WEBrick::HTTPAuth::DigestAuth

def _authenticate(req, res)

def _authenticate(req, res)
  unless digest_credentials = check_scheme(req)
    return false
  end
  auth_req = split_param_value(digest_credentials)
  if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
    req_params = MustParams + MustParamsAuth
  else
    req_params = MustParams
  end
  req_params.each{|key|
    unless auth_req.has_key?(key)
      error('%s: parameter missing. "%s"', auth_req['username'], key)
      raise HTTPStatus::BadRequest
    end
  }
  if !check_uri(req, auth_req)
    raise HTTPStatus::BadRequest
  end
  if auth_req['realm'] != @realm
    error('%s: realm unmatch. "%s" for "%s"',
          auth_req['username'], auth_req['realm'], @realm)
    return false
  end
  auth_req['algorithm'] ||= 'MD5'
  if auth_req['algorithm'].upcase != @algorithm.upcase
    error('%s: algorithm unmatch. "%s" for "%s"',
          auth_req['username'], auth_req['algorithm'], @algorithm)
    return false
  end
  if (@qop.nil? && auth_req.has_key?('qop')) ||
     (@qop && (! @qop.member?(auth_req['qop'])))
    error('%s: the qop is not allowed. "%s"',
          auth_req['username'], auth_req['qop'])
    return false
  end
  password = @userdb.get_passwd(@realm, auth_req['username'], @reload_db)
  unless password
    error('%s: the user is not allowed.', auth_req['username'])
    return false
  end
  nonce_is_invalid = false
  if @use_opaque
    info("@opaque = %s", @opaque.inspect) if $DEBUG
    if !(opaque = auth_req['opaque'])
      error('%s: opaque is not given.', auth_req['username'])
      nonce_is_invalid = true
    elsif !(opaque_struct = @opaques[opaque])
      error('%s: invalid opaque is given.', auth_req['username'])
      nonce_is_invalid = true
    elsif !check_opaque(opaque_struct, req, auth_req)
      @opaques.delete(auth_req['opaque'])
      nonce_is_invalid = true
    end
  elsif !check_nonce(req, auth_req)
    nonce_is_invalid = true
  end
  if /-sess$/i =~ auth_req['algorithm']
    ha1 = hexdigest(password, auth_req['nonce'], auth_req['cnonce'])
  else
    ha1 = password
  end
  if auth_req['qop'] == "auth" || auth_req['qop'] == nil
    ha2 = hexdigest(req.request_method, auth_req['uri'])
    ha2_res = hexdigest("", auth_req['uri'])
  elsif auth_req['qop'] == "auth-int"
    body_digest = @h.new
    req.body { |chunk| body_digest.update(chunk) }
    body_digest = body_digest.hexdigest
    ha2 = hexdigest(req.request_method, auth_req['uri'], body_digest)
    ha2_res = hexdigest("", auth_req['uri'], body_digest)
  end
  if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
    param2 = ['nonce', 'nc', 'cnonce', 'qop'].map{|key|
      auth_req[key]
    }.join(':')
    digest     = hexdigest(ha1, param2, ha2)
    digest_res = hexdigest(ha1, param2, ha2_res)
  else
    digest     = hexdigest(ha1, auth_req['nonce'], ha2)
    digest_res = hexdigest(ha1, auth_req['nonce'], ha2_res)
  end
  if digest != auth_req['response']
    error("%s: digest unmatch.", auth_req['username'])
    return false
  elsif nonce_is_invalid
    error('%s: digest is valid, but nonce is not valid.',
          auth_req['username'])
    return :nonce_is_stale
  elsif @use_auth_info_header
    auth_info = {
      'nextnonce' => generate_next_nonce(req),
      'rspauth'   => digest_res
    }
    if @use_opaque
      opaque_struct.time  = req.request_time
      opaque_struct.nonce = auth_info['nextnonce']
      opaque_struct.nc    = "%08x" % (auth_req['nc'].hex + 1)
    end
    if auth_req['qop'] == "auth" || auth_req['qop'] == "auth-int"
      ['qop','cnonce','nc'].each{|key|
        auth_info[key] = auth_req[key]
      }
    end
    res[@resp_info_field] = auth_info.keys.map{|key|
      if key == 'nc'
        key + '=' + auth_info[key]
      else
        key + "=" + HTTPUtils::quote(auth_info[key])
      end
    }.join(', ')
  end
  info('%s: authentication succeeded.', auth_req['username'])
  req.user = auth_req['username']
  return true
end