使用PHP、REST、Flex和AmazonS3放置/复制

使用PHP、REST、Flex和AmazonS3放置/复制,php,apache-flex,rest,amazon-s3,put,Php,Apache Flex,Rest,Amazon S3,Put,几周来,我一直在尝试使用web上的可用示例将REST请求正确格式化到Amazon AWS S3 API,但甚至无法成功连接 我已经找到了生成签名的代码,找到了格式化“要编码的字符串”的正确方法,以及http头文件。我已通过SignatureDesNotMatch错误处理,只是为了获得匿名用户无法执行复制功能,请验证消息 我有一个adobeflex应用程序的工作副本,它成功地上传了文件,但文件名是“原始的”。将REST与amazonapi一起使用的目的是执行文件的PUT(副本),这样我就可以将其重

几周来,我一直在尝试使用web上的可用示例将
REST请求
正确格式化到
Amazon AWS S3 API
,但甚至无法成功连接

我已经找到了生成签名的代码,找到了格式化“要编码的字符串”的正确方法,以及
http头文件
。我已通过
SignatureDesNotMatch
错误处理,只是为了获得
匿名用户无法执行复制功能,请验证
消息

我有一个
adobeflex
应用程序的工作副本,它成功地上传了文件,但文件名是“原始的”。将
REST
amazonapi
一起使用的目的是执行文件的
PUT
(副本),这样我就可以将其重命名为后端系统可以使用的名称

如果我能找到一种方法让这个
REST
提交工作,或者在上传时在
Flex
中指定一个“新”文件名,我可以避免整个
REST
情况

如果有人通过
REST
amazonapi
上成功执行了
PUT/Copy
命令,我会非常感兴趣的是这是如何实现的-或者如果有人能够使用
Flex
文件引用来更改目标文件名。browse()
method我也会永远感激任何指点


PHP代码如下所示:
$aws_key='removed_for_security';
$aws_secret='removed_for_security';
$source_file=$uploaded_s3_file;//要上载到S3的文件(在上述脚本中定义)
$aws_bucket='bucket';//AWS铲斗
$aws\u对象=$event\u file\u name;//AWS对象名(文件名)
如果(strlen($aws_secret)!=40)死亡($aws_secret应该正好是40字节长);
$file\u data=file\u get\u contents($source\u file);
如果($file\u data==false)死亡(“读取文件失败”。$source\u文件);
//打开到AmazonS3的HTTP连接
$fp=fsockopen(“s3.amazonaws.com”,80,$errno,$errstr,30);
如果(!$fp)死亡($errstr($errno)\n);
//上载对象
$file_length=strlen($file_data);//对于内容长度HTTP字段
$dt=gmdate('r');//基于GMT的时间戳
//准备要签名的字符串(请参阅AWS S3开发人员指南)
//正在准备要签名的字符串
$string2sign=“PUT
{$dt}
/{$aws_bucket}/{$aws_object}”;
//准备HTTP查询
//$query=“PUT/”$aws\u bucket。”/“$event\u file\u name.”HTTP/1.1
$query=“PUT/”$event\u file\u name.”HTTP/1.1
主机:{$aws_bucket}.s3.amazonaws.com
日期:{$dt}
x-amz-copy-source:/{$aws_bucket}/{$current_s3_filename}
x-amz-acl:公共读取
授权:AWS{$AWS\u key}:“.amazon\u hmac($string2sign)。”\n\n;
$query.=$file\u数据;
$resp=sendREST($fp,$query);
if(strpos($resp,,)!==false){
死亡($resp);
}
echo“已上载文件\n”;
//完成
echo“您的文件的URL是:http://s3.amazonaws.com/{$aws\u bucket}/{$aws\u object}\n”;
fclose($fp);
//发送HTTP查询和接收,支持简单的保持活动状态
函数sendREST($fp,$q,$debug=true){
如果($debug)回显“\n查询\n”;
fwrite($fp,$q);
$r='';
$check_header=true;
而(!feof($fp)){
$tr=fgets($fp,256);
如果($debug)回显“\n响应”;
$r.=$tr;
if($check_header)&(strpos($r,“\r\n\r\n”)!==false)){
//如果content length==0,则返回查询结果
if(strpos($r,'内容长度:0')!==false){
返回$r;
}
}
//保持活动状态响应不返回EOF
//它们以\r\n0\r\n\r\n字符串结尾
if(substr($r,-7)=“\r\n0\r\n\r\n”){
返回$r;
}
}
返回$r;
}
//hmac-sha1代码启动
//hmac-sha1函数:假设密钥为全局$aws_secret 40字节长
//阅读更多http://en.wikipedia.org/wiki/HMAC
//警告:第一次函数调用后,密钥($aws_secret)用0x0填充到64字节
函数amazon_hmac($stringToSign){
//amazon_hmac的帮助函数binsha1(返回sha1哈希的二进制值)
如果(!function_存在('binsha1')){
如果(版本比较(phpversion(),“5.0.0”,“>=”)){
函数binsha1($d){return sha1($d,true);}
}否则{
函数binsha1($d){返回包('H*',sha1($d));}
}
}
全球$aws_机密;
if(strlen($aws_secret)==40){
$aws_secret=$aws_secret.str_repeat(chr(0),24);
}
$ipad=str_重复(chr(0x36),64);
$opad=str_重复(chr(0x5c),64);
$hmac=binsha1($aws_secret^$opad).binsha1($aws_secret^$ipad.$stringToSign));
返回base64_编码($hmac);
}
//hmac-sha1代码结束
当我提交格式错误或不正确的标题时,我会收到预期的相应错误消息:

查询:

PUT/bucket/1-132-1301047200-1.jpg HTTP/1.1主机:s3.amazonaws.com x-amz-acl:公共读取连接:保持活动内容长度:34102日期:2011年3月26日星期六00:43:36+0000授权:AWS-出于安全考虑删除-:gmgrobhefuirwwaqrgdkiqk/EQ=

HTTP/1.1 403禁止
x-amz-request-id:A7CB0311812CD721
x-amz-id-2:ZUY0mH4Q20Izgt/9BNhpJl9OoOCp59DKxlH2JJ6K+sksyxI8lFtmJrJOk1imxM/A
内容类型:应用程序/xml
传输编码:分块
日期:2011年3月26日星期六00:43:36 GMT
连接:关闭
服务器:AmazonS3
397签名不匹配我们计算的请求签名与您提供的签名不匹配。请检查您的密钥和签名方法。50 55 54 0a 0a 53 61 74 2c 20 32 36 20 4d 61 72 20 32 30 31 30 30 3a 34 3a 33 36 20 2b 30 30 30 0a 78 2d 61 6d 7a 2d 61 63 6c 3a 70 62 6c 69 63 2d 72 65 64 0a 2f 6d 68 2d 70 72 6f 64 75 63 74 69 6f 6e 2f 31 2d 31 33 32 2d 31 33 30 30 34 32 30 2d 31 2 E 6a 70 67A7CB0311812CD721ZUY0mH4Q20Izgt/9BNHPJL9OOOCP59DKXLH2J6K+sksyxI
$aws_key = 'removed_for_security';
$aws_secret = 'removed_for_security';
$source_file = $uploaded_s3_file; // file to upload to S3 (defined in above script)
$aws_bucket = 'bucket'; // AWS bucket
$aws_object = $event_file_name; // AWS object name (file name)
if (strlen($aws_secret) != 40) die("$aws_secret should be exactly 40 bytes long");
$file_data = file_get_contents($source_file);
if ($file_data == false) die("Failed to read file " . $source_file);

// opening HTTP connection to Amazon S3
$fp = fsockopen("s3.amazonaws.com", 80, $errno, $errstr, 30);
if (!$fp) die("$errstr ($errno)\n");

// Uploading object
$file_length = strlen($file_data); // for Content-Length HTTP field
$dt = gmdate('r'); // GMT based timestamp

// preparing String to Sign (see AWS S3 Developer Guide)
// preparing string to sign
$string2sign = "PUT


{$dt}
/{$aws_bucket}/{$aws_object}";

// preparing HTTP query 
// $query = "PUT /".$aws_bucket."/".$event_file_name." HTTP/1.1
$query = "PUT /" . $event_file_name . " HTTP/1.1
Host: {$aws_bucket}.s3.amazonaws.com
Date: {$dt}
x-amz-copy-source: /{$aws_bucket}/{$current_s3_filename}
x-amz-acl: public-read

Authorization: AWS {$aws_key}:" . amazon_hmac($string2sign) . "\n\n";

$query .= $file_data;
$resp = sendREST($fp, $query);
if (strpos($resp, '') !== false) {
     die($resp);
}
echo "FILE uploaded\n";

// done
echo "Your file's URL is: http://s3.amazonaws.com/{$aws_bucket}/{$aws_object}\n";
fclose($fp);

// Sending HTTP query and receiving, with trivial keep-alive support
function sendREST($fp, $q, $debug = true){
     if ($debug) echo "\nQUERY<<{$q}>>\n";
     fwrite($fp, $q);
     $r = '';
     $check_header = true;
     while (!feof($fp)) {
          $tr = fgets($fp, 256);
          if ($debug) echo "\nRESPONSE<<{$tr}>>";
          $r .= $tr;
          if (($check_header) && (strpos($r, "\r\n\r\n") !== false)) {

               // if content-length == 0, return query result
               if (strpos($r, 'Content-Length: 0') !== false) {
                    return $r;
               }
          }

          // Keep-alive responses does not return EOF
          // they end with \r\n0\r\n\r\n string
          if (substr($r, -7) == "\r\n0\r\n\r\n") {
               return $r;
          }
     }
     return $r;
}

// hmac-sha1 code START
// hmac-sha1 function: assuming key is global $aws_secret 40 bytes long
// read more at http://en.wikipedia.org/wiki/HMAC
// warning: key($aws_secret) is padded to 64 bytes with 0x0 after first function call
function amazon_hmac($stringToSign) {

     // helper function binsha1 for amazon_hmac (returns binary value of sha1 hash)
     if (!function_exists('binsha1')) {
          if (version_compare(phpversion(), "5.0.0", ">=")) {
               function binsha1($d) { return sha1($d, true); }
          } else {
               function binsha1($d) { return pack('H*', sha1($d)); }
          }
     }
     global $aws_secret;
     if (strlen($aws_secret) == 40) {
          $aws_secret = $aws_secret . str_repeat(chr(0), 24);
     }
     $ipad = str_repeat(chr(0x36), 64);
     $opad = str_repeat(chr(0x5c), 64);
     $hmac = binsha1(($aws_secret ^ $opad) . binsha1(($aws_secret ^ $ipad) . $stringToSign));
     return base64_encode($hmac);
}
// hmac-sha1 code END
<?php
// Complain wildly.
    ini_set('display_errors', true);
    error_reporting(-1);
// Set these yourself.
    define('AWS_KEY', '');
    define('AWS_SECRET_KEY', '');
// We'll assume that the SDK is in our current directory
    include_once 'sdk-1.3.1/sdk.class.php';
    include_once 'sdk-1.3.1/services/s3.class.php';
// Set the bucket and name of the file we're sending.
// It happens that we're actually uploading the file and 
// keeping the name, so we're re-using the variable
// below.
    $bucket_name = 'my_very_first_bucket';
    $file_to_upload = 'example.txt';
// Fire up the object
    $s3 = new AmazonS3(AWS_KEY, AWS_SECRET_KEY);
// This returns a "CFResponse"
    $r = $s3->create_object(
        $bucket_name,
        $file_to_upload,
        array(
        // Filename of the thing we're uploading
            'fileUpload' => (__DIR__ . '/' . $file_to_upload),
        // ACL'd public.
            'acl' => AmazonS3::ACL_PUBLIC,
        // No wai.
            'contentType' => 'text/plain',
        // The docs say it'll guess this, but may as well.
            'length' => filesize(__DIR__ . '/' . $file_to_upload)
        )
    );
// Did it work?
    echo "Worked: ";
    var_dump($r->isOK());
// Status as in HTTP.
    echo "\nStatus: ";
    var_dump($r->status);
// The public URL by which we can reach this object.
    echo "\nURL: ";
    echo $s3->get_object_url($bucket_name, $file_to_upload);
// Tada!
    echo "\n";
    $r = $s3->copy_object(
        array( 'bucket' => $bucket_name, 'filename' => $file_to_upload ),
        array( 'bucket' => $bucket_name, 'filename' => 'foo.txt' )
    );
// Did it work?
    echo "Worked: ";
    var_dump($r->isOK());
// Status as in HTTP.
    echo "\nStatus: ";
    var_dump($r->status);

// The public URL by which we can reach this object.
    echo "\nURL: ";
    echo $s3->get_object_url($bucket_name, 'foo.txt');

    echo "\nDelete: ";
// Nuke?
    $r = $s3->delete_object($bucket_name, $file_to_upload);
// Did it work?
    echo "Worked: ";
    var_dump($r->isOK());
// Status as in HTTP.
    echo "\nStatus: ";
    var_dump($r->status);
// Complain wildly.
    ini_set('display_errors', true);
    error_reporting(-1);
// Set these yourself.
    define('AWS_KEY', 'removed for security');
    define('AWS_SECRET_KEY', 'removed for security');
// We'll assume that the SDK is in our current directory
    include_once 'includes/sdk-1.3.1/sdk.class.php';
    include_once 'includes/sdk-1.3.1/services/s3.class.php';
// Set the bucket and name of the file we're sending.
// It happens that we're actually uploading the file and 
// keeping the name, so we're re-using the variable
// below.
    $bucket = 'bucket';
    $file_to_upload = 'example.txt';
    $Source_file_to_copy = 'Album.jpg';
    $Destination_file = 'Album2.jpg';
// Fire up the object
// Instantiate the class
$s3 = new AmazonS3();
$response = $s3->copy_object(
    array( // Source
        'bucket' => $bucket,
        'filename' => $Source_file_to_copy
    ),
    array( // Destination
        'bucket' => $bucket,
        'filename' => $Destination_file
    )
);
// Success?
var_dump($response->isOK());