[PHP] Problemen met readfile()

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • EnsconcE
  • Registratie: Oktober 2001
  • Laatst online: 19-06 00:07
Ik heb een script geschreven waarmee direct linking voorkomen moet worden. Het script opzich is succesvol, het enige probleem is de volgende melding:
Allowed memory size of 33554432 exhausted (tried to allocate 88872960 bytes)

PHP:
1
2
3
4
5
6
header('Content-Description: File Transfer');
header('Content-Type: audio/mpeg');
header('Content-Length: ' . filesize("music/".$realDownloadFile));
header('Content-Disposition: attachment; filename="' . $downloadFile . '"');

readfile("music/" . $realDownloadFile);


ini_set("memory_limit","100M") helpt mij ook niet. Nu zit ik dus met het probleem dat dit script niet meer werkt, want hij heeft gefunctioneerd. Ik zou niet weten hoe ik hier verder moet.

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 22:41
Zonder output-buffering gaan werken, en gebruik maken van fpassthru?

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Implicit output buffering lijkt inderdaad aan te staan.
Aangezien je blijkbaar je memory limit nie tkon verhogen middels ini_set, gok ik dat je op een shared hosting zit en zul je de ob ook wel niet uit kunnen zetten.
Dan kun je beter met fopen en fread aan de lijn gaan om zo stukje voor stukje naar de browser te sturen.

Acties:
  • 0 Henk 'm!

  • EdwinG
  • Registratie: Oktober 2002
  • Laatst online: 22:41
frickY schreef op maandag 15 januari 2007 @ 18:04:
Implicit output buffering lijkt inderdaad aan te staan.
Hoort volgens mij bij readfile:
Leest een bestand en schrijft het naar de output buffer.

Bezoek eens een willekeurige pagina


Acties:
  • 0 Henk 'm!

  • EnsconcE
  • Registratie: Oktober 2001
  • Laatst online: 19-06 00:07
frickY schreef op maandag 15 januari 2007 @ 18:04:
Implicit output buffering lijkt inderdaad aan te staan.
Aangezien je blijkbaar je memory limit nie tkon verhogen middels ini_set, gok ik dat je op een shared hosting zit en zul je de ob ook wel niet uit kunnen zetten.
Dan kun je beter met fopen en fread aan de lijn gaan om zo stukje voor stukje naar de browser te sturen.
Ik zit inderdaad op een shared server. Fpasstrough had ik al geprobeerd, maar dan met de output_buffering aan. Aan de hand van de fpassthrough van EdwinG kwam ik een stukje code tegen waarvan ik het volgende heb gemaakt:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
set_time_limit(0);
ob_end_clean();

session_write_close();

header('Cache-Control: ');
header('Pragma: ');
header('Content-Description: File Transfer');
header('Content-Type: audio/mpeg');
header('Content-Length: ' . filesize($realDownloadFile));
header('Content-Disposition: attachment; filename="' . $downloadFile . '"');

if($file = fopen($realDownloadFile, "rb")){
    while ((!feof($file)) && (connection_status() == 0)) {
        print(fread($file, 1024*8));
        flush();
    }
    fclose($file);
}
return((connection_status() == 0) and !connection_aborted());


mijn dank is groot!

Acties:
  • 0 Henk 'm!

Verwijderd

@TS:
Je kunt direct linken beter tegengaan d.m.v. .htaccess als je daar beschikking over hebt.

Ik hoop overigens voor je dat in de map 'music' geen php-files e.d. staan, anders wordt het heel makkelijk deze te downloaden op deze manier. Wordt overigens op verschillende sites afgeraden om op deze manier (met de filename in de request-string) te werken.

Acties:
  • 0 Henk 'm!

  • EnsconcE
  • Registratie: Oktober 2001
  • Laatst online: 19-06 00:07
Het zou idd via de htaccess kunnen, maar die is eenvoudig te omzeilen. Het is beter te controleren door php te gebruiken. Ik maak dan ook gebruik van een controle systeem of mensen daadwerkelijk van de website afkomen als ze de bestanden aanroepen.

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Waarom niet gewoon zoiets? Dit gebruik ik en het werkt gewoon goed:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(file_exists($location)){
    ob_clean();
    $fp = fopen($location, "rb");
    header("Content-Type: ".$mime);
    header("Content-Length: ".$size);
    if($url[2]=="download") { 
        //via $_SERVER['PATH_INFO'] kijk ik of er op gegeven moment download
        //ergens in de url voorkomt om het opslaan van het bestand te
        //forceren
        header("Content-Disposition: attachment; filename=\"".$name."\"");
    }else{
        header("Content-Disposition: inline; filename=\"".$name."\"");
    }
    header("Content-Transfer-Encoding: binary\n");
    fpassthru($fp);
    exit;
}else{
    //File doesn't exist
    echo "Het bestand bestaat niet!";
}

Verder kan je als je met php het bestand aanbiedt ipv met .htaccess ook goed met rechten werken. Bijv dat je ingelogd moet zijn om het bestand te kunnen downloaden of dat je een email moet accepteren etc etc.

[ Voor 12% gewijzigd door mithras op 16-01-2007 08:35 ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Verwijderd schreef op dinsdag 16 januari 2007 @ 06:43:
@TS:
Je kunt direct linken beter tegengaan d.m.v. .htaccess als je daar beschikking over hebt.
Juist niet. Op die methode ben je afhaneklijk van de referer die de borwser meegeeft. Veel antivirussoftware en firewalls zetten die tegenwoordig uit, ook heb je toolbars om zel de referer in te kunnen vullen.

Verder ben ik het met je eens. Je kunt beter met ID's werken die in een tabelletje aan je bestandsnamen zijn gekoppelt.
Met een beetje pech heb je register_globals ook aanstaan, en kan ik op mijn pc een cookie aanmaken voor jouw domein met "location=;/etc/passwd", of bijv je MySQL user tabel.

[ Voor 14% gewijzigd door frickY op 16-01-2007 08:47 ]


Acties:
  • 0 Henk 'm!

  • EnsconcE
  • Registratie: Oktober 2001
  • Laatst online: 19-06 00:07
frickY schreef op dinsdag 16 januari 2007 @ 08:45:
[...]

Juist niet. Op die methode ben je afhaneklijk van de referer die de borwser meegeeft. Veel antivirussoftware en firewalls zetten die tegenwoordig uit, ook heb je toolbars om zel de referer in te kunnen vullen.

Verder ben ik het met je eens. Je kunt beter met ID's werken die in een tabelletje aan je bestandsnamen zijn gekoppelt.
Met een beetje pech heb je register_globals ook aanstaan, en kan ik op mijn pc een cookie aanmaken voor jouw domein met "location=;/etc/passwd", of bijv je MySQL user tabel.
In mijn script wordt er geen gebruik gemaakt van cookies, weliwaar wel van sessies maar daar wordt alleen gekeken of je een pagina bent geweest op booleaanse wijze. Het downloaden van de bestanden wordt geheel afgehandelt door het download script.
mithras schreef op dinsdag 16 januari 2007 @ 08:33:
Waarom niet gewoon zoiets? Dit gebruik ik en het werkt gewoon goed:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if(file_exists($location)){
    ob_clean();
    $fp = fopen($location, "rb");
    header("Content-Type: ".$mime);
    header("Content-Length: ".$size);
    if($url[2]=="download") { 
        //via $_SERVER['PATH_INFO'] kijk ik of er op gegeven moment download
        //ergens in de url voorkomt om het opslaan van het bestand te
        //forceren
        header("Content-Disposition: attachment; filename=\"".$name."\"");
    }else{
        header("Content-Disposition: inline; filename=\"".$name."\"");
    }
    header("Content-Transfer-Encoding: binary\n");
    fpassthru($fp);
    exit;
}else{
    //File doesn't exist
    echo "Het bestand bestaat niet!";
}

Verder kan je als je met php het bestand aanbiedt ipv met .htaccess ook goed met rechten werken. Bijv dat je ingelogd moet zijn om het bestand te kunnen downloaden of dat je een email moet accepteren etc etc.
Inloggen kan idd, maar zo is de website ook alweer niet opgezet. Ik wil alle downloads in de database bijhouden en er is een datalimiet. Op dit moment zit de website daar nog niet tegenaan maar ik zou door middel van een algoritme kunnen bepalen of men wel of niet mag downloaden.
Pagina: 1