删除Wasabi CDN Bucket 204错误不删除

Deleting Wasabi CDN Bucket 204 Error Not Deleting

所以我正在尝试以编程方式从我的一个存储桶中删除 Wasabi CDN 对象。我的请求是发回 204 并显示成功,但什么都没有 moved/deleted。我正在使用 node/javascript 来执行此操作。

这是我应该删除存储桶的函数。

import expressAsyncHandler from 'express-async-handler'
import User from '../../models/User.js'
import axios from 'axios'
import aws4 from 'aws4'

/**
 * @desc:   THIS is going to be a testing function that will be added into admin delete user and all related docs.
 * @route:  DELETE
 * @access: Private - Admin Route for when deleting user will delete the CDN username bucket aswell
 * @goalHere: The goal of this function is to delete the user bucket from CDN. So that if we d
 * @comment: This is a testing function that will be added into deleteVideo.js. Unless we just await this function in deleteVideo.js.
 */

export const deleteUserBucket = expressAsyncHandler(async (req, res, next) => {
  try {
    const user = await User.findOne({ username: req.user.username })
    const username = user.username

    let request = {
      host: process.env.CDN_HOST,
      method: 'DELETE',
      url: `https://s3.wasabisys.com/truthcasting/${username}?force_delete=true`,
      path: `/truthcasting/${username}?force_delete=true`,
      headers: {
        'Content-Type': 'application/json',
      },
      service: 's3',
      region: 'us-east-1',
      maxContentLength: Infinity,
      maxBodyLength: Infinity,
    }

    let signedRequest = aws4.sign(request, {
      accessKeyId: process.env.CDN_KEY,
      secretAccessKey: process.env.CDN_SECRET,
    })

    //delete the Host and Content-Length headers
    delete signedRequest.headers.Host
    delete signedRequest.headers['Content-Length']

    const response = await axios(signedRequest)
    console.log(response.data)
    console.log('successfully deleted user bucket', response.status)

    return res.status(200).json({
      message: `Successfully deleted user bucket`,
    })
  } catch (error) {
    console.log(error)

    return res.status(500).json({
      message: `Problem with deleting user bucket`,
    })
  }
})

export default deleteUserBucket

当我在 POSTMAN 中向 {{dev}}api/admin/deleteuserbucket 发送 http DELETE 请求时,它会给我一个 204 ok 的响应,这就是响应。

{
    "message": "Successfully deleted user bucket"
}

然后我去我的 Wasabi CDN Buckets 检查它是否被删除,在这种情况下它是 goodstock 并且它仍然存在。感觉我在这里遗漏了一些愚蠢的东西。

在 S3 中,删除存储桶 API 调用 return 204 No content and an empty response body on successful delete.

有了那个 URL,您正在对对象而不是存储桶发出删除请求:

URL: `https://s3.wasabisys.com/truthcasting/${username}?force_delete=true`

在此 URL 中传递的用户名将被解释为键,S3 将在存储桶的根目录中查找对象。

另外,为什么不使用 AWS SDK 删除存储桶而不是重新实现所有这些。为此检查 AWS docs

因此,要删除根存储桶中的内容,您需要将其指向完整的对象。话虽这么说,我在原始 post 代码中设置它的方式是返回 204(“Wasabi 预期 API”)并且由于我没有指向而没有删除任何内容它到完整的对象路径。我还发现,如果您想批量删除而不是删除一个文件,您可以一个一个地使用 aws-sdk 节点包对您的对象执行获取请求,然后使用该响应循环遍历对象并删除你需要的东西。这是一个例子。希望这可以在不久的将来对某人有所帮助。

import expressAsyncHandler from 'express-async-handler'
import User from '../../models/User.js'
import axios from 'axios'
import aws4 from 'aws4'
import errorHandler from '../../middleware/error.js'
import AWS from 'aws-sdk'

/**
 * @desc:   THIS is going to be a testing function that will be added into admin delete user and all related docs.
 * @route:  DELETE
 * @access: Private - Admin Route for when deleting user will delete the CDN username bucket aswell
 * @goalHere: The goal of this function is to delete the user bucket from CDN. So that if we d
 * @comment: This is a testing function that will be added into deleteVideo.js. Unless we just await this function in deleteVideo.js.
 */

export const deleteUserBucket = expressAsyncHandler(async (req, res, next) => {
  const username = req.body.username
  try {
    // Connection
    // This is how you can use the .aws credentials file to fetch the credentials
    const credentials = new AWS.SharedIniFileCredentials({
      profile: 'wasabi',
    })
    AWS.config.credentials = credentials

    // This is a configuration to directly use a profile from aws credentials file.
    AWS.config.credentials.accessKeyId = process.env.CDN_KEY
    AWS.config.credentials.secretAccessKey = process.env.CDN_SECRET

    // Set the AWS region. us-east-1 is default for IAM calls.
    AWS.config.region = 'us-east-1'

    // Set an endpoint.
    const ep = new AWS.Endpoint('s3.wasabisys.com')

    // Create an S3 client
    const s3 = new AWS.S3({ endpoint: ep })

    // The following example retrieves an object for an S3 bucket.
    // set the details for the bucket and key
    const object_get_params = {
      Bucket: 'truthcasting',
      Prefix: `${username}/`,
      //Key: `cnfishead/videos/4:45:14-PM-5-6-2022-VIDDYOZE-Logo-Drop.mp4`,
      // Key: `cnfishead/images/headshot.04f99695-photo.jpg`,
    }

    // get the object that we just uploaded.
    // get the uploaded test_file
    // s3.getObject(object_get_params, function (err, data) {
    //   if (err) console.log(err, err.stack) // an error occurred
    //   else console.log(data) // successful response
    // })

    // get the object that we just uploaded.
    // get the uploaded test_file
    await s3.listObjectsV2(object_get_params, (err, data) => {
      if (err) {
        console.log(err)
        return res.status(500).json({
          message: 'Error getting object',
          error: err,
        })
      } else {
        console.log(data)
        //TODO Change this for loop to a async for loop. Like this: for await (const file of data.Contents) { }
        for (let i = 0; i < data.Contents.length; i++) {
          const object_delete_params = {
            Bucket: 'truthcasting',
            Key: data.Contents[i].Key,
          }
          s3.deleteObject(object_delete_params, (err, data) => {
            if (err) {
              console.log(err)
              return res.status(500).json({
                message: 'Error deleting object',
                error: err,
              })
            } else {
              console.log(data)
            }
          })
        }
        if (data.IsTruncated) {
          console.log('Truncated')
          getObjectFromBucket(req, res, next)
        }
        //console.log('Not Truncated')
        res.status(200).json({
          message: `Successfully retrieved + deleted ${data.Contents.length} objects`,
          data: data,
        })
      }
    })
  } catch (error) {
    console.log(error)
    errorHandler(error, req, res)
  }
})

export default deleteUserBucket