2009-04-21 16 views
5

Tengo archivos en el S3 de Amazon. Se nombran con una identificación única así que no hay duplicados. Estoy accediendo a ellos usando una URL autorizada. Necesito poder pasarlos al navegador, pero necesito cambiarles el nombre. En este momento estoy usando fopen, pero está descargando el archivo a mi servidor antes de servir el archivo al navegador. ¿Cómo puedo hacer que los archivos pasen por mi servidor al navegador? ¿O cómo guardo la descarga, descargando un pequeño fragmento en mi servidor y transfiriéndolo al navegador mientras descargo el siguiente fragmento?En php, quiero descargar un archivo s3 al navegador sin almacenarlo en mi servidor

Además, me gustaría utilizar CloudFront pero no ofrecen URL autenticadas. Creo que puedo usar CURL para enviar las credenciales para la solicitud. ¿Puedo hacer este tipo de archivo de "transferencia" que se sirve con CURL?

Gracias!

Respuesta

5

No sé cómo funciona S3, así que no sé si esta solución es posible. ¿Pero no podría simplemente redirigir el navegador del usuario al archivo? Si entiendo correctamente, S3 te permite crear URLs web para cualquiera de los archivos en tu cubo. Entonces, si, digamos, estas son descargas pagadas, entonces podría have S3 generate a temporary URL for that download y luego eliminar eso una vez que el usuario lo haya descargado.

Si eso no es una opción, puede probar estas clases PHP:

  • HTTP protocol client - Una clase que implementa las solicitudes HTTP a los recursos (utilizado por la envoltura de secuencia más adelante). Permite que las solicitudes se transmitan.
  • gHttp - Una envoltura de flujos HTTP que permite tratar los recursos HTTP remotos como archivos, utilizando funciones como fopen(), fread(), etc.
  • Amazon S3 Stream Wrapper - Una corriente de Amazon S3 envoltorio por el mismo promotor como gHttp. También permite el acceso a recursos remotos como archivos normales a través del fopen('s3://...').

Editar:

This page tiene la información sobre la forma de "preautenticar" una solicitud mediante la codificación de la clave de autenticación en la URL. Se encuentra en la sección titulada: Autenticación de solicitud de cadena de consulta alternativa.

// I'm only implementing the parts required for GET requests. 
// POST uploads will require additional components. 
function getStringToSign($req, $expires, $uri) { 
    return "$req\n\n\n$expires\n$uri"; 
} 

function encodeSignature($sig, $key) { 
    $sig = utf8_encode($sig); 
    $sig = hash_hmac('sha1', $sig, $key); 
    $sig = base64_encode($sig); 
    return urlencode($sig); 
} 

$expires = strtotime('+1 hour'); 
$stringToSign = getStringToSign('GET', $expires, $uri); 
$signature = encodeSignature($stringToSign, $awsKey); 

$url .= '?AWSAccessKeyId='.$awsKeyId 
     .'&Expires='.$expires 
     .'&Signature='.$signature; 

A continuación, sólo redirigir al usuario a $url, y deben ser capaces de descargar el archivo. La firma está codificada por un esquema de encriptación unidireccional (sha1), por lo que no hay riesgo de que se descubra su clave de acceso secreta de AWS.

+0

La única preocupación que tendría con la redirección es que necesita verificar que su seguridad no se transfiere. Si la redirección requiere autorización, se la está dando al cliente. – Joe

+0

Bueno, es por eso que se genera una URL pública temporal. De esta forma, no se pasa información de autenticación, y la URL desaparece una vez que el usuario ha recibido el archivo (o después de un cierto límite de tiempo). – Calvin

+0

No creo que esto solucione mi riesgo de cambio de nombre. Si muevo dos archivos a una carpeta pública para permitir la descarga directamente, tendría que darles nombres amistosos allí. Es posible que tengan el mismo nombre, y luego estoy atascado. – Corey

1

¿Ha intentado usar http_get, con request_options para especificar httpauth y httpauthtype? Aunque no recuerdo si este método supone un tipo de cadena válida, que podría no funcionar bien para el binario.

Si es exitoso, entonces debería ser capaz de proporcionar el tipo MIME correcto y escribir en el navegador.

+0

Gracias, Joe. Lo miraré. – Corey

0

¿Has probado bu simplemente usando readfile ("http://username:[email protected]/filename.ext")?

Eso solo omitirá y escribirá directamente en el buffer de salida; sin embargo, si el tipo de contenido es motivo de preocupación, debe verificarlo primero.

El uso de la URL como argumento para readfile también requiere que PHP se compile con urlwrapper-support.

Cuestiones relacionadas