Digital Ocean:如何将所需的 ContentMD5 添加到生命周期、cors 或 acl 的 Bucket Policy PUT 请求中?

Digital Ocean: How to add required ContentMD5 to Bucket Policy PUT request for lifecycle, cors or acl?

我要在这里回答我自己的问题。我花了好几个小时才弄明白,因为在任何地方都没有这方面的信息,所以我想我应该 post 这个我会先看的地方。

我正在使用 AWS PHP SDK 发送 PUT 请求以将生命周期策略添加到我的 Digital Ocean space 并且不需要,因为它需要 ContentMD5 header .这里有两个问题,第一个问题是 SDK URL 编码了 path/key,这是 /?lifecycle、/?location 和 /?acl 的问题,因为它们变成了“/%3Flifecycle” -- 如果这不是您的请求路径的一部分,请跳过这一段。要暂时停止此操作以添加或更新存储桶策略,您必须在 SDK 文件中找到文件 RestSerializer.php,如果您使用 composer 添加 API,它将位于类似 /vendor/aws/aws-sdk-php/src/Api/Serializer/RestSerializer 的路径中.php 在您的 composer/websites 根目录中,它可能在 /var/www 中。在 RestSerializer.php 中找到两个 rawurlencode 函数调用并删除它们,但保留 value/argument "rawurlencode($varspecs[$k])" 变为 "$varspecs[$k]"。

现在请求将转到正确的 URL, 以生成 ContentMD5 您需要根据您的内容构建一些 PHP 代码正在做。如果您已将策略的 XML 文本放入文件中,请使用 md5_file(PATH_TO_FILE_HERE, true) 如果您使用的是字符串,请使用 md5(STRING_HERE, true)。然后将其包装在 base64_encode() 中,使其看起来像 base64_encode(md5_file('/path/file.xml', true)) 。最后,将其添加到您的 putObject 数组 'ContentMD5' => base64_encode(md5_file('/path/file.xml', true)) .

PHP 文件示例:

// $spaceS3Client is a new S3Client object.

// since its a file, I need to get the file first
$xmlfile = fopen('/spaces.xml', 'r+');

$request = $spaceS3Client->putObject([
  'Bucket' => 'myspacename',
  'Key' => '?lifecycle',
  'Body' => $xmlfile,
  'ContentType' => 'application/xml',
  'ContentMD5' => base64_encode(md5_file('/spaces.xml'', true))
]);

// close file
fclose($xmlfile);

// if you are having trouble connecting to your space in the first place with an S3Client object, since its set up for AWS and not DO you need to add an 'endpoint' to the array in new S3Client like 'endpoint' => 'https://'.$myspace.'.'.$myspaceregion.'.digitaloceanspaces.com'. You also need to add 'bucket_endpoint' => true.

这里有两个问题,第一个问题是 SDK URL 对 path/key 进行了编码,这是 /?lifecycle、/?location 和 /?acl 的问题,因为它们成为“/%3Flifecycle”——如果这不是您的请求路径的一部分,请跳过这一段。要暂时停止此操作以添加或更新存储桶策略,您必须在 SDK 文件中找到文件 RestSerializer.php,如果您使用 composer 添加 API,它将位于类似 /vendor/aws/aws-sdk-php/src/Api/Serializer/RestSerializer 的路径中.php 在您的 composer/websites 根目录中,它可能在 /var/www 中。在 RestSerializer.php 中找到两个 rawurlencode 函数调用并删除它们,但保留 value/argument "rawurlencode($varspecs[$k])" 变为 "$varspecs[$k]"。

现在请求将转到正确的 URL, 以生成 ContentMD5 您需要根据您的内容构建一些 PHP 代码正在做。如果您已将策略的 XML 文本放入文件中,请使用 md5_file(PATH_TO_FILE_HERE, true) 如果您使用的是字符串,请使用 md5(STRING_HERE, true)。然后将其包装在 base64_encode() 中,使其看起来像 base64_encode(md5_file('/path/file.xml', true)) 。最后,将其添加到您的 putObject 数组 'ContentMD5' => base64_encode(md5_file('/path/file.xml', true)) .

PHP 文件示例:

// $spaceS3Client is a new S3Client object.

// since its a file, I need to get the file first
$xmlfile = file_get_contents('/spaces.xml', 'r+');

$request = $spaceS3Client->putObject([
  'Bucket' => 'myspacename',
  'Key' => '?lifecycle',
  'Body' => $xmlfile,
  'ContentType' => 'application/xml',
  'ContentMD5' => base64_encode(md5_file('/spaces.xml', true))
]);

// if you are having trouble connecting to your space in the first place with an S3Client object, since its set up for AWS and not DO you need to add an 'endpoint' to the array in new S3Client like 'endpoint' => 'https://'.$myspace.'.'.$myspaceregion.'.digitaloceanspaces.com'. You also need to add 'bucket_endpoint' => true.

// to check the rules have been set use a getObject request and then use the code below to parse the response.

header('Content-type: text/xml');
$request = $request->toArray()["Body"];
echo $request;