2012-09-24 11 views
5

Estoy usando la siguiente función php para dar acceso temporal al público a un archivo privado.No se puede anular el encabezado de disposición de contenido en 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}"; 
}  

que quería añadir el encabezado de disposición de contenido para que pueda cambiar el nombre del archivo a test.mp3 cuando un usuario intenta acceder a esta url que por defecto es el nombre del archivo a 982jdjd2p3.mp3

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

He intentado añadir la siguiente línea de código a la función

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

Sin embargo, cuando hago clic en la URL

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

El nombre del archivo es propuesto para ser guardado como 982jdjd2p3.mp3

¿Cómo puedo reemplazar el encabezado de disposición de contenido para peticiones GET s3 utilizando esta función?

Ver también

Amazon S3 Change file download name

EDITAR

Aquí es el más reciente intento de cambiar el nombre del archivo con una petición de obtención de utilizar esta función.

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}"; 
}  

Respuesta

10

El problema con su función es que los valores de cabecera deben ser codificados en el hipervínculo final, pero no para su firma. La siguiente función corrige eso:

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

Gracias Jack! Sin embargo, solo guarda el título hasta el primer espacio. Por ejemplo, si '$ save_as = 'hello world';' el archivo se guardará como 'hello'. De cualquier forma alrededor de esto? – user784637

+0

@ user784637 en ese caso, debería considerar agregar comillas dobles a su alrededor, p. 'filename =" hello world.txt "' –

1

formato de su Content-Disposition no es válida, especifique disposition-type.

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

Uso response-content-disposition en la firma y params:

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

Estoy confundido acerca de dónde hacer ese cambio, ¿puedo hacerlo en el script php anterior? ¿Cuál es el código apropiado? – user784637

+0

He editado mi respuesta. –

+0

Lamentablemente, cuando intento obtener un enlace a una página .xml con el siguiente error ** La firma de solicitud que calculamos no coincide con la firma que proporcionó. Compruebe la clave y el método de firma. ** – user784637

Cuestiones relacionadas