session dans script de download

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 11:23

Bonjour,

Je vous sollicite car je comprends pas pourquoi ca marche pas. Je veux sécuriser ma page de téléchargement ("telechar.php") mais quand je rajoute mon p'tit bout de script (concernant la session) ma page ne fonctionne plus alors que je suis (quasi) sur de moi. Mon acrobat s'ouvre et me marque : "Une erreur est survenue lors de l'ouverture de ce document. Fichier introuvable."

Si je retire la condition if, ca marche.

Voici mon code :
<? session_start();
if (!isset($_SESSION["login"])) { 
header("location : index.php");
}else{
require_once("parametres.php");
$q = "SELECT id,link FROM matable WHERE id = '".$_GET["id"]."'";
$r = mysql_query($q);
while($rows=mysql_fetch_array($r)){
$filename = $rows["link"];
}
 
function download($filename) { 
    header("Content-Type: application/octet-stream"); 
    header("Content-Disposition: attachment; filename=".basename($filename) ); 
    header("Accept-Ranges: bytes"); 
    header("Content-Length: ".filesize($filename) ); 
    readfile($filename); 
} 
 
download($filename);
}
?>
Erreur ou incompatibilité ?

Je veux protéger ceci car même en sécurisant un dossier de destination quelqu'un qui tapperait dans l'url telechar.php?id=1 aurait accès au fichier soit disant sécurisé.

Kerrang

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 avr. 2007, 11:33

Ajoute la commande exit() juste après ton header(). En effet, la fonction header() envoi l'information de redirection au serveur, mais n'interrompt pas pour autant l'exécution du code. Un exit te permet d'arrêter l'exécution de ce qui va suivre.

Tu dois aussi pouvoir éviter ton erreur en mettant l'appel à ta fonction dans le else{} pour qu'il ne soit pas exécuté après le header() :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 11:46

Merci Ryle mais le problème subsiste. J'ai rajouté le exit();

Si une session n'est pas ouverte et que je tape : telechar.php?id=1 //j'arrive maintenant à une page toute blanche.

Si ma session est ouverte et que je tape : telechar.php?id=1 //même erreur que tout à l'heure fichier introuvable

Si je retire la condition if, ca marche mais c'est pas sécurisé du tout :?

Schcreugneugneu

Kerrang

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 avr. 2007, 11:59

Bon alors on va essayer de bidouiller et commencer par retirer le superflu :
<?php
session_start(); 

if (!isset($_SESSION["login"])) {  
  header("location : index.php"); 
  exit();
} // pas besoin de else, si le if() est vrai, le exit fera quitter le code

require_once("parametres.php"); 

$q = "SELECT link FROM matable WHERE id = ".$_GET["id"]; // pas d'apostrophe autour des nombres
$r = mysql_query($q); 

if ($rows=mysql_fetch_array($r)){ // un if au lieu d'un while puisque un seul résultat attendu
  $filename = $rows["link"]; 

  if(is_file($filename)) { // le fichier existe ?  
    // pas besoin d'une fonction puisqu'appellé une seule fois
    header("Content-Type: application/octet-stream");  
    header("Content-Disposition: attachment; filename=".basename($filename) );  
    header("Accept-Ranges: bytes");  
    header("Content-Length: ".filesize($filename) );  
    readfile($filename);  
  }
  else
    echo 'Fichier non trouvé';
}  
else
  echo 'Aucune correspondance en base';

?>
Quoi ça donne ? (euh... t'as vraiment une table qui s'appelle matable ? :))
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 12:04

Complément et erratum...

Ma fonction se trouve bien dans le else (cf dernière accolade)

Sinon je viens de m'appercevoir d'un truc très louche.

Si une session est ouverte et que je tape dans l'url telech.php?id=1, ca marche ! J'ai accès au document.

Si je clique depuis le lien href=telech.php?id=1 (donc la même chose), ca fonctionne pas, même en target="_blank" :(

Zarb, non ?

Kerrang

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 avr. 2007, 12:18

Il a des guillemets ton href pour délimiter sa valeur ? sinon c'est mal :)

Code : Tout sélectionner

href="telech.php?id=1"
Tu as vérifié dans l'url que l'adresse était bonne depuis le lien ?
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 12:22

Nos réponses se sont croisées ^^

Merci pour tous ces commentaires Ryle, je comprends mieux certaines choses. A moi de chopper certains réflexes ;)

J'ai encore un souci majeur. Le script gère parfaitement les sessions maintenant, mais pour accéder à mon document, il faut que je tape dans la barre d'adresse telech.php?id=1 pour que ça marche car depuis un lien ca ne marche pas :shock: (Fichier introuvable)

Kerrang

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 12:27

Encore réponses croisées lol

Oui j'avais des quotes, mais avec des guillemets, pas mieux...

Voici comment se présente mon lien :
echo "<a href=\"telech.php?id=".$row["id"]."\">"
Kerrang

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 12:53

Nouvelle indication (désolé pour la série de 3 j'chui pas encore membre :))

Quand la boite de dialogue s'ouvre et que je fais ouvrir ca ne marche pas, par contre le "enregistrement sur le disque" fonctionne |*()

Kerrang

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 avr. 2007, 13:30

Vraiment bizare cette histoire... ouvre le gestionnaire de tache et dans la liste des processus arrête le process acrord32 ou un truc du genre (c'est acrobat). Il se peut qu'il ait gardé en cache les erreurs précédentes et ne parvienne pas à ouvrir correctement le fichier depuis l'adresse.

Essaye ensuite de nouveau d'ouvrir ton fichier depuis le lien, ca devrait le relancer et peut être enfin te donner le résultat attendu :)
(désolé pour la série de 3 j'chui pas encore membre :))
Bah alors ?! qu'est ce que tu attends pour aller t'inscrire ? ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 14:31

Re,

Mon processus se referme à chaque fermeture d'acrobat.

Donc, j'ai relancé le script qui m'a ouvert acrobat. De là, j'ai fermé le processus mais ca ne marche pas mieux :/

C'est étrange...

Quand je saisis dans l'url telech.php?id=1 la fonction ouvrir de la boite de dialogue marche mais impossible d'enregistrer le document. Quand je clique sur le lien c'est enregistrer qui marche et pas ouvrir.

POURQUOI ???!!!!! (tant de haine) :cry:

Kerrang

Kerrang
Invité n'ayant pas de compte PHPfrance

10 avr. 2007, 14:55

J'ai trouvé la soluce sur le net dans un cas FPDF.

Voici la ligne à ajouter pour que ça marche :
header("Cache-control: private, must-revalidate");
Sous Mozilla, je viens de vérifier avant de faire la modif, ca fonctionnait nickel donc c'est encore IE (one more time) qui coinçait.

S'il y a moyen de me confirmer ça Ryle, ça serait cool.

Merci pour tout !

Kerrang

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

10 avr. 2007, 15:18

Il semble donc bien que le problème provenait de la mise en cache des essais précédents :)

Il existe d'autres options dans le header pour forcer à recharger le cache (expires, pragma, ..) mais si celle-ci est suffisante, c'est peut être pas la peine de s'embêter d'avantage :)

Bon pis... c'est pas tout mais... t'es toujours pas inscrit toi ?! ;)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Petit nouveau ! | 1 Messages

10 avr. 2007, 15:52

Lol, bah voila c'est chose faite :langue:

Tu gères Ryle :pouce:

Kerrang