【问题标题】:AWS S3 uploaded images are getting corruptedAWS S3 上传的图像已损坏
【发布时间】:2015-11-14 01:22:27
【问题描述】:

我正在使用 AWS ec2 ubuntu 机器。我的代码在 cakephp 中。当我尝试将任何图像上传到 AWS S3 时,它会损坏。

虽然它在核心 php 代码中运行良好。

这是我的控制器代码

 if ($this->User->saveAll($this->request->data)) {

                    // upload on s3
                    //create file name
                    // echo "<pre>"; print_r($_FILES); die;
                    $temp = explode(".", $_FILES["data"]["name"]["User"]['image']);
                    $newfilename = round(microtime(true)) . '.' . end($temp);

                    $filepath = $_FILES['data']['tmp_name']['User']['image'];
                    $id = $this->request->data['User']['id'];

                    try {
                        $result = $this->Amazon->S3->putObject(array(
                            'Signature' => 'v4',
                            'Bucket' => 'abc.sample',
                        'ACL' => 'authenticated-read',
                        'Key' => 'files/user/image/' . $id . "/" . $newfilename,
                        'ServerSideEncryption' => 'aws:kms',
                        'SourceFile' => $filepath,
                        'Body' => $filepath,
                        'ContentType' => $_FILES['data']['type']['User']['image'],

                    ));
                } catch (S3Exception $e) {
                    echo $e->getMessage() . "\n";
                }
}

如果我没有使用body 参数,那么它会显示以下错误

您必须为 Body 或 SourceFile 指定一个非空值 参数。

虽然以下代码在核心 php 中测试工作正常

$filepath = "/var/www/html/for_testing_aws/assets/img/avtar.png";

try {
    $result = $s3->putObject(array(
        'Bucket' => $bucketName,
        'ACL' => 'authenticated-read',
        'Key' => "avtar-auth.png",
        'ServerSideEncryption' => 'aws:kms',
        'SourceFile' => $filepath,
        'ContentType' => mime_content_type($filepath),
        'debug' => [
            'logfn' => function ($msg) {
                echo $msg . "\n";
            },
            'stream_size' => 0,
            'scrub_auth' => true,
            'http' => true,
        ],
    ));
} catch (S3Exception $e) {
    echo $e->getMessage() . "\n";
}

我创建了一个自定义组件来访问 SDK 的所有功能。参考https://github.com/Ali1/cakephp-amazon-aws-sdk。

检查一下

图像正确保存在我的 ec2 存储中。对于 ec2 服务器上的图像上传,我正在使用这个插件 https://github.com/josegonzalez/cakephp-upload

我尝试putobject 使用简单的表单上传方法,这也适用于我 这是代码

require 'aws-autoloader.php';

$credentials = new Aws\Credentials\Credentials('key 1', 'key2');
$bucketName = "";
$s3 = new Aws\S3\S3Client([
   // 'signature' => 'v4',
    'version' => 'latest',
    'region' => 'ap-southeast-1',
    'credentials' => $credentials,
    'http' => [
        'verify' => '/home/ubuntu/cacert.pem'
    ],
    'Statement' =>[
        'Action '=> "*",
    ],
//    'debug' => [
//        'logfn' => function ($msg) {
//            echo $msg . "\n";
//        },
//        'stream_size' => 0,
//        'scrub_auth' => true,
//        'http' => true,
//    ]
        ]);

$result = $s3->listBuckets();
foreach ($result['Buckets'] as $bucket) {
    // Each Bucket value will contain a Name and CreationDate

     $bucketName = $bucket['Name'];
}

 <form name="uploadimage" id="uploadimage" method="post" action="saveimg.php" enctype="multipart/form-data">
    <input type="file" name="file" value="file"/>
    <input type="submit" name="submit" value="submit" />
</form>

而 saveimg.php 是

$filepath = $_FILES['file']['tmp_name'];
try {
    $result = $s3->putObject(array(
        'Bucket' => $bucketName,
        'ACL' => 'authenticated-read',
        'Key' => $_FILES['file']['name'],
        'ServerSideEncryption' => 'aws:kms',
        'SourceFile' => $filepath,
        'ContentType' => mime_content_type($filepath),
        'debug' => [
            'logfn' => function ($msg) {
                echo $msg . "\n";
            },
            'stream_size' => 0,
            'scrub_auth' => true,
            'http' => true,
        ],
    ));
} catch (S3Exception $e) {
    echo $e->getMessage() . "\n";
}

当我尝试打开该文件时,显示以下消息。

【问题讨论】:

  • $filepath 不为空。也不例外。
  • 这是文件的临时位置。
  • 它将被损坏意味着我在两个地方上传文件,一个在我的 ec2 服务器上,另一个在 s3 上。 Ec2 服务器文件正在正确上传,同时在 s3 上面临损坏。
  • 您不是最终用户 =)。 查看文件的来源 - 例如是xml说访问被拒绝吗?是 0 字节吗?您需要确定一个特定问题,然后可能从那里进行调试(即您可能需要回答自己的问题)。
  • @urfusion,从 s3 下载“损坏”文件并查看其内容。使用文本编辑器或十六进制编辑器。

标签: php cakephp amazon-web-services amazon-s3 aws-php-sdk


【解决方案1】:

尝试读取您的文件 - 您传递的是路径而不是文件内容:

'Body' => $filepath,

应该是

'Body' => file_get_contents($filepath),

【讨论】:

  • 但它在我的测试文件上没有 file_get_contents 的情况下工作。并且在现场项目中没有成功。
  • @timstermatic 似乎是正确的。阅读文档 - 您必须指定 SourceFile 或 Body。如果您指定 SourceFile,您可以只传递文件的路径。但是如果你使用 Body,你必须传入文件的内容(使用类似 file_get_contents().docs.aws.amazon.com/AmazonS3/latest/dev/…
  • 您可以通过从 S3 下载“损坏”文件并使用文本编辑器打开它来验证这一点。我相信它实际上是一个包含源文件路径的文本文件。
猜你喜欢
  • 2020-04-15
  • 2021-03-15
  • 1970-01-01
  • 2022-08-17
  • 2022-08-13
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多