2013-02-05 64 views
0

我有一個生成簽訂了PHP函數亞馬遜S3網址如下:S3標識的URL通過形式不工作提交

if(!function_exists('el_crypto_hmacSHA1')){ 
    /** 
    * Calculate the HMAC SHA1 hash of a string. 
    * 
    * @param string $key The key to hash against 
    * @param string $data The data to hash 
    * @param int $blocksize Optional blocksize 
    * @return string HMAC SHA1 
    */ 
    function el_crypto_hmacSHA1($key, $data, $blocksize = 64) { 
     if (strlen($key) > $blocksize) $key = pack('H*', sha1($key)); 
     $key = str_pad($key, $blocksize, chr(0x00)); 
     $ipad = str_repeat(chr(0x36), $blocksize); 
     $opad = str_repeat(chr(0x5c), $blocksize); 
     $hmac = pack('H*', sha1(
     ($key^$opad) . pack('H*', sha1(
      ($key^$ipad) . $data 
     )) 
    )); 
     return base64_encode($hmac); 
    } 
    } 

    if(!function_exists('el_s3_getTemporaryLink')){ 
    /** 
    * Create temporary URLs to your protected Amazon S3 files. 
    * 
    * @param string $accessKey Your Amazon S3 access key 
    * @param string $secretKey Your Amazon S3 secret key 
    * @param string $bucket The bucket (bucket.s3.amazonaws.com) 
    * @param string $path The target file path 
    * @param int $expires In minutes 
    * @return string Temporary Amazon S3 URL 
    * @see http://awsdocs.s3.amazonaws.com/S3/20060301/s3-dg-20060301.pdf 
    */ 

    function el_s3_getTemporaryLink($accessKey, $secretKey, $bucket, $path, $expires = 5) { 
     // Calculate expiry time 
     $expires = time() + intval(floatval($expires) * 60); 
     // Fix the path; encode and sanitize 
     $path = str_replace('%2F', '/', rawurlencode($path = ltrim($path, '/'))); 
     // Path for signature starts with the bucket 
     $signpath = '/'. $bucket .'/'. $path; 
     // S3 friendly string to sign 
     $signsz = implode("\n", $pieces = array('GET', null, null, $expires, $signpath)); 
     // Calculate the hash 
     $signature = el_crypto_hmacSHA1($secretKey, $signsz); 
     // Glue the URL ... 
     $url = sprintf('https://%s/%s', $bucket, $path); 
     // ... to the query string ... 
     $qs = http_build_query($pieces = array(
     'AWSAccessKeyId' => $accessKey, 
     'Expires' => $expires, 
     'Signature' => $signature, 
    )); 
     // ... and return the URL! 
     return $url.'?'.$qs; 
    } 

    } 

我有一個頁面,我用它來下載一個zip文件表單按鈕:

<?php 
// Grab the file url 
$file_url = get_post_meta($post->ID, 'file_url', true); 
// Grab just the filename with extension 
$file_name = basename($file_url); 

// AWS details     
$accessKey = "AKIAJJLX2F7GUDTQ23AA"; 
$secretKey = "<REMOVED>"; 
$bucket_name = "media.themixtapesite.com"; 

// Create new S3 Expiry URL 
$download_url = el_s3_getTemporaryLink($accessKey, $secretKey, $bucket_name, $file_name); 


if (is_user_logged_in()) { ?> 
<div class="download_button_div"> 
<?php echo '<form action="'.$download_url.'" class="download_button_div">'; ?> 
<!--Download counter--> 
<input type="hidden" name="download_counter" value="<?php (int)$download_count = get_post_meta($post->ID, 'download_counter', true); 
$download_count++; 
update_post_meta($post->ID, 'download_counter', $download_count); ?>"> 
<button type='submit' class='download_button'>Download</button> 
</form> 

正如你所看到的,我只是將表單動作設置爲我想下載的文件的URL。 這工作正常。它會生成一個已簽名的過期S3 URL並下載該文件。

在另一頁,我用的是相同的功能,但略有不同的形式,這是下載一個MP3文件:

<?php 
// Grab the file url 
$file_url = $mp3s; 
// Grab just the filename with extension 
$file_name = basename($file_url); 

// AWS details     
$accessKey = "AKIAJJLX2F7GUDTQ23AA"; 
$secretKey = "<REMOVED>"; 
$bucket_name = "mixtape2.s3.amazonaws.com"; 

// Create new S3 Expiry URL 
$download_url = el_s3_getTemporaryLink($accessKey, $secretKey, $bucket_name, $file_name); 
?> 

<!--Download individual MP3 file direct from player--> 

<span style="right:27px; position:absolute;"> 
<form action="download_file.php" method="post" name="downloadform"> 
<input name="file_name" value="<?php echo basename($mp3s); ?>" type="hidden"> 
<input name="real_file" value="<?php echo $download_url; ?>" type="hidden"> 
<input type="image" src="download.jpg" border="0" width="17" alt="Download the MP3" /> 
</form> 

正如你可以在這個表格上看到我提交使用POST到窗體另一個名爲'download_file.php'的文件進行處理。該「download_file.php」僅僅是這迫使一個mp3文件的下載,而不是在瀏覽器中打開一個文件:

<?php 
if(isset($_POST['file_name'])){ 
$player_file = $_POST['file_name']; 
header('Content-type: audio/mpeg3'); 
header('Content-Disposition: attachment; filename="themixtapesite_'.$player_file.'"'); 
readfile($_POST['real_file']); 
exit(); 
} 
?> 

這個問題我有,第二頁(其中我向「download_file上。 PHP),生成的URL不起作用。如果我提交表單,只需下載一個0kb的文件。 如果我查看源代碼,然後將鏈接複製並粘貼到瀏覽器中,我會收到S3錯誤消息,告訴我簽名不匹配。

我不明白爲什麼我的第一頁的作品,但我的第二頁沒有。這些URL都是使用相同的函數生成的?

任何幫助表示讚賞。

+2

第二個存儲桶名稱對我來說看起來很可疑。你是否試過簡單的'mixtape2'? – orique

+1

@orique - 謝謝!我知道這將會是我錯過的愚蠢! –

回答

0

感謝@orique發現我錯誤地輸入了我的存儲桶名稱。 愚蠢的錯誤...編碼失明!