2012-10-17 1 views
-1

Duplicate possible:
forcing a file download with php
force download of different filesObliger téléchargement depuis le serveur en php

J'essaie de permettre aux utilisateurs de télécharger des images de mon site en php. J'ai vu un tas d'articles à ce sujet, et j'essayais d'utiliser readfile des documents php. Mais je n'arrive pas à le faire fonctionner.

C'est le code pour le bouton que je suis en train de mettre en place pour lancer le téléchargement:

 <!-- download image button --> 
    <form class="grid_12" style="text-align: center;" action="../includes/download.php" method="post"> 
     <input type="hidden" name="id" value="<?php echo $photo->id; ?>" /> 
     <input type="hidden" name="img" value="<?php echo $photo->filename; ?>" /> 
     <?php if(isset($_GET['cat'])){?> 
      <input type="hidden" name="cat" value="<?php echo $_GET['cat']; ?>" /> 
     <?php } ?> 
     <div id="download"><input type="submit" name="submit" value="Download Photo" /></div> 
    </form> 

Et c'est le code que je l'ai mis dans mon fichier download.php (redirect_to est juste fonction qui appelle en-tête. (Lieu: var) où le var est ce que vous passez

<?php 
require_once('initialize.php'); 
?> 
<?php 
header("Content-type: application/force-download; filename=".$_POST['img']); 

// Force download of image file specified in URL query string and which 
// is in the same directory as this script: 
if(!empty($_POST['img'])) 
{ 
    $file = $_POST['img']; 
    if (file_exists($file)) { 
     header('Content-Description: File Transfer'); 
     header('Content-Type: application/octet-stream'); 
     header('Content-Disposition: attachment; filename='.basename($file)); 
     header('Content-Transfer-Encoding: binary'); 
     header('Expires: 0'); 
     header('Cache-Control: must-revalidate'); 
     header('Pragma: public'); 
     header('Content-Length: ' . filesize($file)); 
     ob_clean(); 
     flush(); 
     readfile($file); 
     exit; 
    } 

    $addy = "../public/photo.php?id=".$_POST['id']; 
    if(isset($_POST['cat'])){ 
     $addy .= "&cat=".$_POST['cat']; 
    } 
    redirect_to($addy); 
} 
header("HTTP/1.0 404 Not Found"); 
?> 

les variables cachées que je vous envoie dans le poste sont la plupart du temps pour la redirection de reprendre l'utilisateur à la page ils téléchargés à partir après le téléchargement commence Sur mon hôte local, je suis redirigé vers la page I cli cked le bouton de téléchargement sur. Sur mon serveur, je suis juste envoyé à une page blanche en s'enregistrant comme download.php. Je pense que cela a quelque chose à voir avec la mise en mémoire tampon de sortie potentiellement, parce que je reçois une page blanche. Ce qui signifie généralement qu'il y avait une sorte de sortie avant d'appeler la fonction header().

Si quelqu'un pouvait me donner un aperçu de ce que je fais mal ici, je l'apprécierais grandement, Merci d'avoir lu.

-Alan

+1

faire ob_start(); en haut de votre fichier de téléchargement –

+0

Votre script est probablement vulnérable à [path traversal] (https://www.owasp.org/index.php/Path_Traversal) qui permet de lire n'importe quel fichier sur votre serveur. – Gumbo

+1

Vous définissez l'en-tête 'Content-Type:' deux fois, je ne suis pas sûr de ce que le RFC dit à ce sujet ... vous voulez probablement vérifier cela en premier. – hakre

Répondre

0

Merci pour l'idée, je crois qu'il était une combinaison de ce hakre et GBD a souligné. J'appelais l'en-tête deux fois, parce que j'avais une mise en place comment j'ai vu un exemple mis en place. Puis j'ai utilisé l'exemple du doc ​​php pour readfile aussi ...

Puis j'ai dû fixer le chemin absolu pour le fichier image parce que je n'envoyais que le nom du fichier. Merci encore pour l'aide rapide que j'apprécie vraiment.

** Mise à jour

Ce tout arrangé pour moi sur mon hôte local, mais sur le serveur, il me faut maintenant une pleine page de symboles charabia au lieu de commencer le téléchargement ... Je vais examiner cette question et rediffuser quand je trouve la solution.

** Fix

Tout d'abord je devais aller dans mon fichier php.ini sur le serveur et changer allow_url_fopen = On pour que le serveur peut utiliser des méthodes de fichiers comme readfile, fopen, etc. Ensuite, j'avais aussi ajouter une mémoire tampon de sortie sur le fichier car il y avait tellement d'appels d'en-tête. Sans tampon de sortie, le premier a été appelé avant la mise en place de l'ensemble de l'appel.

Merci encore pour toute l'aide, il fonctionne sur mon hôte local et serveur maintenant.

Questions connexes