Digital Ocean: Как добавить необходимый ContentMD5 в запрос PUT Bucket Policy для жизненного цикла, cors или acl? - PullRequest
0 голосов
/ 07 мая 2019

Я собираюсь ответить на свой вопрос здесь.Мне потребовались часы, чтобы выяснить это, поскольку информации об этом нигде нет, поэтому я решил опубликовать это где-нибудь, и сначала посмотрю.

Я использовал AWS PHP SDK для отправки запроса PUT, чтобы добавитьполитики жизненного цикла для моего пространства Digital Ocean, и она не будет принята, так как требует заголовок ContentMD5.Здесь есть две проблемы, первая проблема заключается в том, что URL-адрес SDK кодирует путь / ключ, который является проблемой с /? Жизненным циклом, /? Местоположением и /? Acl, поскольку они становятся "/% 3Flifecycle" - пропустите этот параграф, еслиэто не часть вашего запроса.Чтобы временно остановить это, чтобы добавить или обновить политику сегмента, вы должны найти файл RestSerializer.php в файлах SDK. Если вы добавили API с помощью composer, он будет находиться по пути, например / vendor / aws / aws-sdk-php /src / Api / Serializer / RestSerializer.php в корне вашего композитора / веб-сайтов, который, вероятно, будет находиться в / var / www.В RestSerializer.php найдите два вызова функции rawurlencode и удалите их, но оставьте значение / аргумент «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.

1 Ответ

0 голосов
/ 07 мая 2019

Здесь есть две проблемы, первая проблема заключается в том, что URL-адрес SDK кодирует путь / ключ, который является проблемой с /? Жизненным циклом, /? Местоположением и /? Acl, поскольку они становятся "/% 3Flifecycle" - пропустить этот параграф, если он не является частью вашего пути запроса. Чтобы временно остановить это, чтобы добавить или обновить политику сегмента, вы должны найти файл RestSerializer.php в файлах SDK. Если вы добавили API с помощью composer, он будет находиться по пути, например / vendor / aws / aws-sdk-php / src / Api / Serializer / RestSerializer.php в корне вашего композитора / веб-сайтов, который, вероятно, будет находиться в / var / www. В RestSerializer.php найдите два вызова функции rawurlencode и удалите их, но оставьте значение / аргумент «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;

...