3

我正在尝试使用 League 的 AWS S3 v3 Flysystem 将文件从本地硬盘上传到 Amazon S3。这是我的功能:

/**
 * Uploads a file from local disk to S3
 * @param $filename string
 * @param Illuminate\Filesystem\FilesystemAdapter $s3
 * @param Illuminate\Filesystem\FilesystemAdapter $local
 * @param string $path
 */
protected function uploadFile($filename, $s3, $local, $path)
{
    $file = substr($filename, strrpos($filename, '/') + 1);

    if($local->has($filename)) {
        try {
            Log::info("Uploading file", ['filename' => $filename, 'host' => gethostname()]);
            $s3->write($path . $file, $local->read($filename));

            return $path . $file;
        } catch(\Exception $e) {
            Log::error('Error uploading file', ['filename' => $filename, 'message' => $e->getMessage(), 'host' => gethostname()]);
            return false;
        }

    } 

    Log::notice('File does not exist on local disk, cannot upload', ['filename' => $filename, 'host' => gethostname() ]);
    return false;
}

我不是 100% 确定发生了什么变化,但现在我们在尝试上传时从 AWS 收到此错误:

AWS HTTP 错误:客户端错误响应 [url] https://s3.amazonaws.com/bucket/directory/file.ext?partNumber=1&uploadId=BigLoNGsString_oF_CHARacTers.moREstuFF-- [状态代码] 400 [原因短语] 错误请求 XAmzContentSHA256Mismatch (客户端):提供的“x-amz-content-sha256”标头与计算的内容不匹配。

在上面的代码中,这个字符串是一个(非常大的 XML 字符串)的一部分,它作为被传递给catch块的异常消息而返回。

据我所知,阅读有关此错误的稀疏信息,我可以找到,这在某种程度上表明 S3 认为我发送的内容已损坏,因为上传的每个部分的此标头中放置的哈希与上传的每个部分不匹配亚马逊认为它应该是。

我相信在某些时候这可以正常工作,我只是不太确定从哪里开始调试它。本地文件的权限允许任何人读取它,我可以在我尝试将此文件上传到的 S3 存储桶中成功创建目录,因此我认为它与该方的权限没有任何关系。

我对这个错误意味着什么的理解正确吗?

如果有任何区别,我尝试上传到 S3 的文件是大型视频文件(通常 >250MB,<2GB)。

更新

我在本地也遇到了这个问题,所以我尝试了其中一个建议并重新启动了本地计算机,问题仍然存在。我尝试运行其他也使用相同功能的东西(它上传相关视频文件的较小 jpg 屏幕截图)并且它能够毫无问题地上传它们。有关更多上下文,以下是调用代码:

$format->setKiloBitrate($kiloBitrate);
if(!$local->has($newFilename)) {
    $video->save($format, $newFilename);
    Log::debug($extension . '@' . $kiloBitrate . 'kbps Encoding Finished');
} else {
    Log::debug("File already encoded!");
}

if(!$this->uploadFile($newFilename, $s3, $local, $remotePath . $kiloBitrate . '/')) {
    Log::error("Failed to upload file", ['filename' => $newFilename, 'host' => gethostname()]);
} else {
    $local->delete($newFilename);
}

以上$video是 的一个实例FFMpeg\Media\Video$format是 的一个实例FFMpeg\Format\Video\DefaultVideo。据我所知并且可以告诉,在该$video->save(...)行之后没有对文件进行其他更改

更新#2

问题消失了。不将此作为答案发布,因为它不是一个。这就是我所做的:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)                             
  - Removing aws/aws-sdk-php (3.1.0)
  - Installing aws/aws-sdk-php (3.2.0)
    Downloading: 100%

查看 github 上的aws sdk提交,我认为我的问题可能已通过提交的 PR 解决但真的不确定。

4

0 回答 0