如何在AWS SDK for PHP中为PutBucketLifecycleConfiguration添加Content-MD5
问题详情
我正在使用AWS SDK for PHP(版本3),通过PutBucketLifecycleConfiguration配置S3存储桶生命周期规则,但遇到以下错误:
Aws\S3\Exception\S3Exception: Error executing "PutBucketLifecycleConfiguration" on "http://ceph:8000/testcachebucket?lifecycle"; AWS HTTP error: Client error:
PUT http://ceph:8000/testcachebucket?lifecycleresulted in a400 Bad Requestresponse:InvalidRequestMissing required header for this reques (truncated...) InvalidRequest (client): Missing required header for this request: Content-MD5 -
return (<Error><Code>InvalidRequest</Code><Message>Missing required header for this request: Content-MD5</Message><BucketName>testcachebucket</BucketName><RequestId>tx000000000000000000608-0067bc52d0-16f97-default</RequestId><HostId>16f97-default-default</HostId></Error>)
根据AWS文档,调用该REST API请求时需要Content-MD5请求头,但PHP SDK文档未说明如何添加。当前代码如下:
$this->s3Client->PutBucketLifecycleConfiguration([ 'Bucket' => $bucket, 'LifecycleConfiguration' => [ 'Rules' => $opts, ], ]);
解决方法
AWS SDK for PHP v3支持两种方式添加Content-MD5头,适配Ceph这类强制要求该头的兼容存储:
方案1:单个请求启用自动MD5计算
利用SDK内置的calculate_md5请求选项,开启后会自动序列化配置内容、计算MD5并添加请求头,这是最简便的方式:
$this->s3Client->PutBucketLifecycleConfiguration([ 'Bucket' => $bucket, 'LifecycleConfiguration' => [ 'Rules' => $opts, ], '@http' => [ 'calculate_md5' => true ] ]);
方案2:全局启用自动MD5计算
如果需要所有PUT请求都自动添加Content-MD5头,可以在创建S3客户端时配置全局HTTP选项:
$s3Client = new Aws\S3\S3Client([ 'version' => 'latest', 'region' => 'your-region', 'endpoint' => 'http://ceph:8000', 'http' => [ 'calculate_md5' => true ] ]);
方案3:手动计算并添加(进阶)
若需要自定义MD5计算逻辑,可以手动序列化配置内容、计算MD5后通过请求头传递:
// 获取命令序列化器,生成配置XML内容 $command = $this->s3Client->getCommand('PutBucketLifecycleConfiguration', [ 'Bucket' => $bucket, 'LifecycleConfiguration' => ['Rules' => $opts] ]); $xmlContent = $command->getSerializer()->serialize($command)->getBody()->getContents(); // 计算Content-MD5值 $contentMd5 = base64_encode(md5($xmlContent, true)); // 发起请求时添加头信息 $this->s3Client->PutBucketLifecycleConfiguration([ 'Bucket' => $bucket, 'LifecycleConfiguration' => [ 'Rules' => $opts, ], '@http' => [ 'headers' => [ 'Content-MD5' => $contentMd5 ] ] ]);
内容的提问来源于stack exchange,提问作者Roukmoute

