如何使用 PHP Curl 将文件上传到 AWS Presigned URL?

2022-01-22 00:00:00 amazon-web-services postman curl php

我正在尝试使用 PHP 通过预签名 URL 将文件从 '<form enctype="multipart/form-data"><input type="file">...' 上传到 AWS卷曲.

I'm trying to upload a file from a '<form enctype="multipart/form-data"><input type="file">...' to AWS via a presigned URL using PHP Curl.

虽然文件似乎上传成功,但在我下载最近上传的文件后,尝试打开新下载的文件失败.我收到此文件已损坏"或我们似乎不支持此文件格式"或我们无法打开此文件",具体取决于文件类型.我在上传时没有通过 curl_exec 或 curl_error 从 AWS 得到任何响应.

While the file appears to be uploaded successfully, after I download the recently uploaded file, trying to open the newly downloaded file fails. I get either "this file is corrupted" or "it looks like we don't support this file format" or "we cant open this file" depending on the file type. I'm getting no response from AWS via curl_exec or curl_error on the upload.

我基本上是从 POSTMAN 复制 PHP 代码,因为当文件附加为二进制"时,POSTMAN 会成功上传文件.由于我的代码在我的代码中通过 CURLOPT_POSTFIELDS 附加了文件,这可能是个问题吗?我见过的所有其他示例都通过 curl_file_create 和 CURLOPT_POSTFIELDS 附加文件,所以这就是我正在使用的.

I basically copied the PHP code from POSTMAN since POSTMAN uploads the file successfully when the file is attached as "binary". Since my code attaches the file via CURLOPT_POSTFIELDS in my code, could this be a problem? Every other example I've seen attaches the file via curl_file_create and CURLOPT_POSTFIELDS, so that's what I'm using.

我上传文件的唯一说明是:

The only instructions I have in uploading the file is:

curl -X PUT 
  "https://PRESIGNED_PUT_URL_FROM_RESPONSE" 
  --upload-file ~/Documents/Files/the_file.pdf

我尝试将标头中的内容类型更改为实际上传的文件类型,但都不起作用.我已经尝试过 CURLFile 和 curl_file_create.上传到我的测试服务器和我的网站服务器后的文件在上传到AWS之前仍然有效.

I've tried to change the content-type in the header to the actual uploaded file type, but neither works. I've tried both CURLFile and curl_file_create. The files after uploading to my test server and my website server are all still valid prior to upload to AWS.

    $file_name = $post_files[$FILES_file]["name"];
    $content_type = $post_files[$FILES_file]["type"];
    $TheFileSize = $post_files[$FILES_file]["size"];
    $tmp_name = $post_files[$FILES_file]["tmp_name"];
    $curl = curl_init();
    $cFile = curl_file_create($tmp_name, $content_type, $file_name);

    $payload = array('upload-file' => $cFile);

    $curlOptions = array(
            CURLOPT_URL            => $TheAWSPresignedURL,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_CUSTOMREQUEST  => "PUT",
            CURLOPT_ENCODING       => "",
            CURLOPT_POST           => 1,
            CURLOPT_MAXREDIRS      => 10,
            CURLOPT_TIMEOUT        => 300,
            CURLOPT_HTTP_VERSION   => CURL_HTTP_VERSION_1_1,
            CURLOPT_INFILESIZE     => $TheFileSize,
            CURLOPT_HTTPHEADER     => array(
                "Accept: */*",
                "Accept-Encoding: gzip, deflate",
                "Cache-Control: no-cache",
                "Connection: keep-alive",
                "Content-Length: ".$TheFileSize,
                "Content-Type: multipart/form-data",
                "Host: s3.amazonaws.com"
            ),
        );
    curl_setopt_array($curl, $curlOptions);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);  
    $response = curl_exec($curl);

我正在寻找要通过预签名 URL 成功上传到 AWS、成功下载并成功打开的文件.

I'm looking for the file to be uploaded successfully to AWS via a presigned URL, downloaded successfully, and opened successfully.

[更新]

尝试上传文本文件而不是图像和 pdf,这是我们开发的主要文件类型.下载这些文件最终成功"了,因为我能够打开它们,但是,文本文件的开头添加了文本.

Attempted to upload text files instead of images and pdfs, which were the main file types we were developing for. Downloading those files ended up being "successful" in that I was able to open them up, however, there was text added to the beginning of the text file.

如果作为 Content-Type:multipart/form-data 上传,文件仍然可以下载,但打开时,此文本会添加到文件开头.

If uploaded as Content-Type:multipart/form-data, the file was still downloadable, but when opened it, this text was added to the beginning of the file.

--------------9cd644e15677104b内容处置:表单数据;名称="上传文件";文件名="SimpleTextFile.txt"内容类型:text/plain

如果作为 Content-Type: $content_type 上传,下载链接会在新的浏览器窗口中打开文件,并将此文本添加到文件中.

If uploaded as Content-Type: $content_type, the download link opened the file in a new browser window with this text added to the file.

--------------3dca3db029b41ae2内容处置:附件;名称="上传文件";文件名="SimpleTextFile2.txt"内容类型:text/plain

推荐答案

$payload = array('upload-file' => $cFile); 替换为 $payload = file_get_contents( $tmp_name ); 解决了我的问题.看起来我根本不需要 curl_file_create 或数组和键 upload-file .

Replacing $payload = array('upload-file' => $cFile); with $payload = file_get_contents( $tmp_name ); solved my issue. Looks like I don't need curl_file_create or the array and key upload-file at all.

另外,https://stackoverflow.com/a/21888136 提到直接加载内容应该删除标题信息,并且它做了.

Also, https://stackoverflow.com/a/21888136 metioned loading the content directly should remove the header information, and it did.

感谢大家的洞察力,因为您确实为我指明了正确的方向!

Thanks all for insight, as you did point me in the right direction!

相关文章