通过curl将文件上传到s3时出现400错误

c0vxltue  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(219)

编辑

我很难调试PHP甚至Golang,但事实证明,直接发送Curl请求解决了我的问题

curl -v -F $Signature -F $Date -F $Credential -F $Key -F $Algo -F $Policy -F $File $Url

我试过将请求转换为PHP,但是仍然无法使其工作。

编辑结束

我的服务提供商不提供AWS S3访问密钥和密码,但只允许我通过AWS规定的格式(https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html)上传文件。因此,我正在探索使用一个程序将文件上传到他们的服务器以自动化我的东西的选项。
表单的工作原理非常好。但是当我通过PHP CURL模拟相同的请求时,它总是给我400个错误。我已经从AWS的示例中删除了不需要的表单部分,并试图使CURL中的请求尽可能接近。
有人能指出我的 curl 请求有什么问题吗?

工作HTML表单

<form action="https://<CLIENT NAME>.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    <input type="input"  name="key" value="something.pdf" /><br />
    <input type="text"   name="X-Amz-Credential" value="<SOME key>/20221017/REGION/s3/aws4_request" />
    <input type="text"   name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256" />
    <input type="text"   name="X-Amz-Date" value="20221017T162325Z" />
    <input type="hidden" name="X-Amz-Signature" value='<SIGNATURE>' />
    <input type="hidden" name="Policy" value="<POLICY>" />
    <input type="file"   name="file" /> <br />
    <input type="submit" name="submit" value="Upload to Amazon S3" />
  </form>

我正在尝试的示例PHP curl 代码

<?php
if (isset($_POST['btnUpload'])) {
    $url = "https://<SERVICE PROVIDER>.s3.amazonaws.com/";
    $filename = $_FILES['file']['name'];
    $filedata = $_FILES['file']['tmp_name'];
    $filesize = $_FILES['file']['size'];
    if ($filedata != '') {
        $headers = array(
            "enctype: multipart/form-data", 
            'Accept-Language: en-US,en;q=0.5',
            'Connection: keep-alive',
            'Upgrade-Insecure-Requests: 1',
            "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
            "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7",
            "Keep-Alive: 300",
            "Connection: keep-alive"
        ); 

        
        $postfields = array(
            "file" => "", 
            "x-amz-signature" => "<SIGNATURE>", 
            "x-amz-date" => "20221017T173731Z", 
            "x-amz-credential" => "<EY>/20221017/ap-south-1/s3/aws4_request",
            "key" => "<SAMPLE.FILE>", 
            "policy" => "<POLICY>",
            "x-amz-algorithm" => "AWS4-HMAC-SHA256"
        );

        $ch = curl_init();
        $options = array(
            CURLOPT_URL => $url,
            CURLOPT_HEADER => true,
            CURLOPT_POST => 1,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_POSTFIELDS => $postfields,
            CURLOPT_INFILESIZE => $filesize,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLINFO_HEADER_OUT => true,
            CURLOPT_USERAGENT=>'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42',
            CURLOPT_ENCODING=>'gzip, deflate, br'
        ); // cURL options

        curl_setopt_array($ch, $options);
        curl_exec($ch);

        if(!curl_errno($ch)) {
           
            $info = curl_getinfo($ch);
            if ($info['http_code'] == 200)
                $errmsg = "File uploaded successfully";
        } else {
           
            $errmsg = curl_error($ch);
        }
        $info = curl_getinfo($ch);
        print_r($info);
        curl_close($ch);
    }
}

?>
<form action="" method="post" name="frmUpload" enctype="multipart/form-data">
<tr>
  <td>Upload</td>
  <td align="center">:</td>
  <td><input name="file" type="file" id="file"/></td>
</tr>
<tr>
  <td>&nbsp;</td>
  <td align="center">&nbsp;</td>
  <td><input name="btnUpload" type="submit" value="Upload" /></td>
</tr>
qxgroojn

qxgroojn1#

更新

嗯。我似乎不能让它工作,即使在本地主机上的curl。你有什么想法?我不可能想到任何理由AWS会检测到我的请求-Chilarai
我的做法是用AWS的表单创建一个HTML页面。我在Firefox中提交表单。然后我进入Firefox开发者工具中的Network选项卡,右键单击请求并复制请求。
然后,我转到https://curlconverter.com/php/并将Firefox curl转换为PHP curl代码。

更新结束

我不认为问题出在你的代码上。问题更有可能是Cloudflare或类似的东西。他们让自己成为了互联网交通警察。我猜这可能是一个安全证书问题。AWS可能不希望你和你的curl访问他们的网站。
据报告,Cloudflare对浏览器的TLS/SSL握手进行了分析和指纹识别,并将握手指纹与用户代理进行了比较,如果不匹配,则会显示“Cloudflare 403禁止”
如果你在谷歌上搜索“Cloudflare 403 Forbidden”,你会发现关于这个主题的文章并不缺乏。
这些家伙已经修复了403的一些原因。
PHP cURL 403 forbidden – How to solve it
根据你的要求,你可以把你的工作做得很好。
我看到你正在使用CURLINFO_HEADER_OUT => true,。如果能看到请求头的样子就好了。
您的“Working HTML Form”没有可供测试的URL,因此我在您提供的链接中使用了“example.html”表单。
我没有对HTML进行任何更改。
甚至这两行HTML也不行:

<input type="hidden" name="Policy" value='<Base64-encoded policy string>' />
<input type="hidden" name="X-Amz-Signature" value="<signature-value>" />

这是Firefox转换为PHP curl的请求。
我没有得到响应,连接在请求完成之前被重置。
我没有办法测试这个代码没有一个AWS帐户。
比较您的curl请求头可能会很有用。

<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://sigv4examplebucket.s3.amazonaws.com/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0',
    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language' => 'en-US,en;q=0.5',
    'Accept-Encoding' => 'gzip, deflate',
    'Content-Type' => 'multipart/form-data; boundary=---------------------------127362855031316784522161324660',
    'Origin' => '<http://my test site>.com',
    'DNT' => '1',
    'Connection' => 'keep-alive',
    'Referer' => <http://my test site>.com/',
    'Upgrade-Insecure-Requests' => '1',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="key"\r\n\r\nuser/user1/\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="acl"\r\n\r\npublic-read\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="success_action_redirect"\r\n\r\nhttp://sigv4examplebucket.s3.amazonaws.com/successful_upload.html\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="Content-Type"\r\n\r\nimage/jpeg\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="x-amz-meta-uuid"\r\n\r\n14365123651274\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="x-amz-server-side-encryption"\r\n\r\nAES256\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="X-Amz-Credential"\r\n\r\nAKIAIOSFODNN7EXAMPLE/20151229/us-east-1/s3/aws4_request\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="X-Amz-Algorithm"\r\n\r\nAWS4-HMAC-SHA256\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="X-Amz-Date"\r\n\r\n20151229T000000Z\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="x-amz-meta-tag"\r\n\r\n\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="Policy"\r\n\r\n<Base64-encoded policy string>\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="X-Amz-Signature"\r\n\r\n<signature-value>\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="file"; filename="1-1.png"\r\nContent-Type: image/png\r\n\r\n-----------------------------127362855031316784522161324660\r\nContent-Disposition: form-data; name="submit"\r\n\r\nUpload to Amazon S3\r\n-----------------------------127362855031316784522161324660--\r\n');

$response = curl_exec($ch);

curl_close($ch);

和实际的请求头

POST / undefined
Host: sigv4examplebucket.s3.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:107.0) Gecko/20100101 Firefox/107.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------134195551233585171272903941613
Content-Length: 26595
Origin: http://<my test site>.com
DNT: 1
Connection: keep-alive
Referer: http://<my test site>.com/
Upgrade-Insecure-Requests: 1

相关问题