2009-04-21 17 views
5

J'ai des fichiers sur Amazon S3. Ils sont nommés avec un identifiant unique, donc il n'y a pas de doublons. J'y accède en utilisant une URL autorisée. Je dois pouvoir les transmettre au navigateur, mais j'ai besoin de les renommer. En ce moment j'utilise fopen, mais il télécharge le fichier sur mon serveur avant de servir le fichier au navigateur. Comment puis-je faire passer les fichiers par mon serveur au navigateur? Ou comment tamponner le téléchargement - télécharger un petit morceau sur mon serveur et le transmettre au navigateur lors du téléchargement du morceau suivant?En php, je veux télécharger un fichier s3 dans le navigateur sans le stocker sur mon serveur

Aussi - J'aimerais vraiment utiliser CloudFront mais ils n'offrent pas d'URL authentifiées. Je crois que je peux utiliser CURL pour envoyer des informations d'identification pour la demande - puis-je faire ce genre de «passage à travers» le fichier servant avec CURL?

Merci!

Répondre

5

Je ne suis pas familier avec le fonctionnement de S3, donc je ne sais pas si cette solution est possible. Mais ne pourriez-vous pas simplement rediriger le navigateur de l'utilisateur vers le fichier? Si je comprends bien, S3 vous permet de créer des URL Web pour l'un des fichiers de votre compartiment. Donc, si, disons, ce sont des téléchargements payants, alors vous pouvez have S3 generate a temporary URL for that download et ensuite supprimer une fois que l'utilisateur l'a téléchargé.

Si ce n'est pas une option, vous pouvez essayer ces classes PHP:

  • HTTP protocol client - Une classe qui implémente les demandes de ressources HTTP (utilisé par le gestionnaire de flux ci-dessous). Permet aux demandes d'être diffusées.
  • gHttp - Une enveloppe de flux HTTP qui vous permet de traiter les ressources HTTP à distance sous forme de fichiers, en utilisant des fonctions comme fopen(), fread(), etc.
  • Amazon S3 Stream Wrapper - Une enveloppe de flux Amazon S3 par le même développeur que ghttp. Permet également d'accéder aux ressources distantes comme des fichiers ordinaires via fopen('s3://...').

Edit:

This page a l'info sur la façon de "pré-Authentifier" une requête en codant la clé d'authentification dans l'URL. C'est sous la section intitulée: Query String Request Authentication Alternative.

// 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; 

Ensuite, il suffit de rediriger l'utilisateur à $url, et ils devraient être en mesure de télécharger le fichier. La signature est codée par un schéma de chiffrement unidirectionnel (sha1), il n'y a donc pas de risque que votre clé d'accès secrète AWS soit découverte.

+0

L'un que je voudrais avoir avec la redirection est que vous devez vérifier que votre sécurité n'est pas transmise. Si la redirection nécessite une autorisation, vous le donnez au client. – Joe

+0

Eh bien, c'est pourquoi une URL publique temporaire est générée. De cette façon, aucune information d'authentification n'est transmise et l'URL est supprimée une fois que l'utilisateur a reçu le fichier (ou après une certaine limite de temps). – Calvin

+0

Je ne pense pas que cela résout mon risque de renommage. Si je déplace deux fichiers dans un dossier public pour autoriser le téléchargement directement, je devrais leur donner des noms conviviaux. C'est possible qu'ils aient le même nom, et ensuite je suis coincé. – Corey

1

Avez-vous essayé d'utiliser http_get, avec request_options pour spécifier le httpauth et httpauthtype? Bien que je ne me souviens pas si cette méthode suppose un type de chaîne valide, ce qui pourrait ne pas fonctionner pour bien binaire.

Si cela réussit, vous devriez pouvoir fournir le bon type MIME et écrire dans le navigateur.

+0

Merci, Joe. Je vais regarder dedans. – Corey

0

Avez-vous essayé d'utiliser simplement readfile ("http://username:[email protected]/filename.ext")? Cela va simplement contourner et écrire directement dans le buffer de sortie, mais si le type de contenu est important, vous devez le vérifier en premier.

L'utilisation de en URL comme argument de readfile nécessite également que PHP soit compilé avec urlwrapper-support.