2012-09-24 9 views
5

Sto utilizzando la seguente funzione php per fornire un accesso temporaneo al pubblico per un file privato.Impossibile eseguire l'override dell'intestazione di disposizione del contenuto in s3

function get_s3_signed_url($bucket, $resource, $AWS_S3_KEY, $AWS_s3_secret_key, $expire_seconds) { 
    $expires = time()+$expire_seconds; 
    // S3 Signed URL creation 
    $string_to_sign = "GET\n\n\n{$expires}\n/".str_replace(".s3.amazonAWS.com","", $bucket)."/$resource"; 
    $signature = urlencode(base64_encode((hash_hmac("sha1", utf8_encode($string_to_sign), $AWS_s3_secret_key, TRUE)))); 

    $authentication_params = "AWSAccessKeyId=".$AWS_S3_KEY; 
    $authentication_params.= "&Expires={$expires}"; 
    $authentication_params.= "&Signature={$signature}"; 

    return $link = "http://s3.amazonAWS.com/{$bucket}/{$resource}?{$authentication_params}"; 
}  

ho voluto aggiungere l'intestazione disposizione contenuti in modo da poter cambiare il nome del file per test.mp3 quando un utente tenta di accedere a questo URL che di default il nome del file per 982jdjd2p3.mp3

$privateUrl = array('privateUrl' => get_s3_signed_url('testbucket', '982jdjd2p3.mp3', $my_aws_key, $my_aws_secret_key, 60)); 

Ho provato ad aggiungere la seguente riga del codice alla funzione

$file_name = 'test.mp3';  
$authentication_params.= "&Content-Disposition={$file_name}"; 

Tuttavia quando scatto sopra l'url

http://s3.amazonAWS.com/testbucket/982jdjd2p3.mp3?AWSAccessKeyId=***&Expires=***&Signature=***&Content-Disposition=test.mp3

Il nome del file proposto deve essere salvato come 982jdjd2p3.mp3

Come faccio a ignorare l'intestazione disposizione contenuti per le richieste GET s3 di utilizzare questa funzione?

Vedere anche

Amazon S3 Change file download name

EDIT

Qui è la più recente tentativo di rinominare il file con una richiesta GET utilizzando questa funzione.

function get_s3_signed_url($bucket, $resource, $AWS_S3_KEY, $AWS_s3_secret_key, $expire_seconds) { 
    $expires = time()+$expire_seconds; 
    // S3 Signed URL creation 
    $filename='moot.mp3'; 
    $disposition = "response-content-disposition=" . urlencode("attachment; filename={$filename}");    

    $string_to_sign = "GET\n\n\n{$expires}\n/".str_replace(".s3.amazonAWS.com","", $bucket)."/$resource"; 
    $string_to_sign .= "?{$disposition}"; 
    $signature = urlencode(base64_encode((hash_hmac("sha1", utf8_encode($string_to_sign), $AWS_s3_secret_key, TRUE)))); 

    $authentication_params = "AWSAccessKeyId=".$AWS_S3_KEY; 
    $authentication_params.= "&Expires={$expires}"; 
    $authentication_params.= "&Signature={$signature}"; 
    $authentication_params.= "&{$disposition}"; 

    return $link = "http://s3.amazonAWS.com/{$bucket}/{$resource}?{$authentication_params}"; 
}  

risposta

10

Il problema con la funzione è che i valori di intestazione devono essere codificati nel collegamento ipertestuale finale, ma non per la firma. La seguente funzione corregge:

function get_s3_signed_url($bucket, $resource, $AWS_S3_KEY, $AWS_s3_secret_key, $expire_seconds, $save_as) 
{ 
    $expires = time()+$expire_seconds; 
    // S3 Signed URL creation 
    $headers = array(
     'response-content-disposition' => 'attachment; filename=' . $save_as, 
    ); 
    $resource = str_replace(array('%2F', '%2B'), array('/', '+'), rawurlencode($resource)); 

    $string_to_sign = "GET\n\n\n$expires\n/$bucket/$resource"; 
    $final_url = "http://s3.amazonaws.com/$bucket/$resource?"; 

    $append_char = '?'; 
    foreach ($headers as $header => $value) { 
     $final_url .= $header . '=' . urlencode($value) . '&'; 
     $string_to_sign .= $append_char . $header . '=' . $value; 
     $append_char = '&'; 
    } 

    $signature = urlencode(base64_encode(hash_hmac('sha1', $string_to_sign, $AWS_s3_secret_key, true))); 

    return $final_url . "AWSAccessKeyId=$AWS_S3_KEY&Expires=$expires&Signature=$signature"; 
} 
+0

Grazie Jack! Tuttavia, salva solo il titolo fino al primo spazio. Ad esempio se '$ save_as = 'ciao mondo';' il file verrebbe salvato come 'ciao'. In qualche modo intorno a questo? – user784637

+0

@ user784637 in questo caso si vorrebbe considerare l'aggiunta di virgolette doppie attorno ad esso, ad es. 'filename =" ciao world.txt "' –

1

formato del Content-Disposition non è valido, specificare disposition-type.

Esempio: Content-Disposition: attachment; filename=test.mp3;

Usa response-content-disposition nella firma e params:

$disposition = "response-content-disposition=" . urlencode("attachment; filename={$filename}"); 
/* ... */ 
$string_to_sign .= "?{$disposition}"; 
/* ... */ 
$authentication_params.= "&{$disposition}"; 
+0

Sono confuso su dove apportare tale modifica, posso farlo nello script php sopra riportato? Qual è il codice appropriato? – user784637

+0

Ho modificato la mia risposta. –

+0

Sfortunatamente quando provo ad ottenere un collegamento a una pagina .xml con il seguente errore ** La firma della richiesta che abbiamo calcolato non corrisponde alla firma che hai fornito. Controlla la tua chiave e il tuo metodo di firma. ** – user784637

Problemi correlati