Ik heb al een aantal jaren een php scriptje in gebruik waarmee files van m'n webserver gedownload kunnen worden. Sinds de overstap naar Fedora 4 en herinstallatie van apache en php blijkt dat files groter dan 2 Mb afgekapt worden op 2Mb. Als ik het download script omzeil, houden ze hun originele omvang. Apache lijkt dus goed ingesteld. Ik vind in php.ini wel een limiet voor een upload, maar niet voor een download. Waar kan dit aan liggen?
? welk script?Verwijderd schreef op vrijdag 30 september 2005 @ 13:02:
Ik heb al een aantal jaren een php scriptje in gebruik waarmee files van m'n webserver gedownload kunnen worden. Sinds de overstap naar Fedora 4 en herinstallatie van apache en php blijkt dat files groter dan 2 Mb afgekapt worden op 2Mb. Als ik het download script omzeil, houden ze hun originele omvang. Apache lijkt dus goed ingesteld. Ik vind in php.ini wel een limiet voor een upload, maar niet voor een download. Waar kan dit aan liggen?
Hoe word er gedownload?
Loop je misschien tegen een geheugen limiet aan?
Programmer - an organism that turns coffee into software.
Het script is pretty basic:
De files zijn bijvoorbeeld 8Mb groot, dus niet echt groot.
Welke geheugenlimit denk je aan?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| $file_name = clean($_GET["file_name"], 80); $base = basename($file_name); $document_root=clean(getenv("DOCUMENT_ROOT"),80); if(file_exists($document_root.$file_name)) { clearstatcache(); $fp=fopen($document_root.$file_name,"r"); $size = filesize($document_root.$file_name); header("Content-type:application/octet-stream"); header("Content-Disposition:attachment;filename=$base"); header("Content-Length: $size"); @fpassthru($fp); } else { header("Location:/php/thx.php?" . "status=F" . "&filename=$base"); } |
De files zijn bijvoorbeeld 8Mb groot, dus niet echt groot.
Welke geheugenlimit denk je aan?
[ Voor 10% gewijzigd door NMe op 30-09-2005 13:19 . Reden: [php]-tags toegevoegd. Doe je dat de volgende keer zelf? :) ]
Wat hierboven gezegd wordt... Je loopt tegen de geheugenlimiet aan. Ben daarom wel benieuwd naar je script, want het lijkt me niet dat bij een readfile of een fpassthru de hele file in het geheugen wordt gezet.
[edit] De geheugenlimiet is de hoeveelheid geheugen die PHP mag gebruiken. Op een windows machine wordt die afaik niet afgedwongen, op een Linux machine wel. Of dit het probleem is kun je zien aan een evt foutmelding. Aangezien je een binairy verstuurt is die niet echt terug te vinden in de output. Om hem te zien zou je dus foutmeldingen naar een logfile moeten sturen...
[edit] De geheugenlimiet is de hoeveelheid geheugen die PHP mag gebruiken. Op een windows machine wordt die afaik niet afgedwongen, op een Linux machine wel. Of dit het probleem is kun je zien aan een evt foutmelding. Aangezien je een binairy verstuurt is die niet echt terug te vinden in de output. Om hem te zien zou je dus foutmeldingen naar een logfile moeten sturen...
[ Voor 48% gewijzigd door T-MOB op 30-09-2005 13:14 ]
Regeren is vooruitschuiven
Alle files worden afgekapt op 1.954 kB. Ook als ik het via mijn Lan doe, dus een timeout kwestie is het dan ook niet.
[ Voor 50% gewijzigd door Verwijderd op 30-09-2005 13:13 ]
http://nl3.php.net/manual/nl/function.readfile.php#52598
Misschien loop je tegen dit probleem aan...
Misschien loop je tegen dit probleem aan...
Programmer - an organism that turns coffee into software.
Ik heb in php.ini de geheugenhoeveelheid (memory_limit) van 8 Mb eens verandert in 60 Mb,
dat maakte niks uit.
dat maakte niks uit.
Ik gebruik geen readfile maar een passthru van een filepointer, dus dat lijkt me niet van toepassing. Ik zal de script executietijd eens vergroten, maar ik verwacht daar ook niet zo veel van want via mijn LAN kost het natuurlijk allemaal zo goed als geen tijd..
[ Voor 4% gewijzigd door Verwijderd op 30-09-2005 13:20 ]
Heb je de link van Lucard wel bekeken? Daar staat namelijk gewoon een oplossing. readfile() en passthru() verschillen niet zoveel.
Regeren is vooruitschuiven
Krijg je trouwens een melding in het bestand of op scherm als je de @ voor de fpassthru weghaalt?
en waarom doe je dit
en waarom doe je dit
PHP:
1
2
3
| header("Location:/php/thx.php?" . "status=F" . "&filename=$base"); // ipv header("Location: /php/thx.php?status=F&filename=".$base); |
[ Voor 48% gewijzigd door LuCarD op 30-09-2005 13:27 ]
Programmer - an organism that turns coffee into software.
Ja, die link heb ik bekeken, maar ik dacht een herhaalde fread is wat anders dan een passthru van een filepointer. Een filepointer doorgeven kost weinig tijd, en ik neem aan dat het script dan eindigt terwijl de php-engine voor de data-overdracht zorgt. Bij een herhaalde fread lijkt me dat je dan afhankelijk van de size van de file de maximum executietijd moet veranderen OF de bewaking daarvan moet uitschakelen.
Ik wil die oplossing best proberen, maar het bestaande script heeft jaren goed gewerkt, dat vind ik zo vreemd.
Ik wil die oplossing best proberen, maar het bestaande script heeft jaren goed gewerkt, dat vind ik zo vreemd.
Het is een recent probleem met PHP, het is een bug die er ingeslopen is. Het kan zijn dat je een andere versie van PHP gebruikte op de oude machine waar het wel mee werkte.Verwijderd schreef op vrijdag 30 september 2005 @ 13:25:
Ja, die link heb ik bekeken, maar ik dacht een herhaalde fread is wat anders dan een passthru van een filepointer. Een filepointer doorgeven kost weinig tijd, en ik neem aan dat het script dan eindigt terwijl de php-engine voor de data-overdracht zorgt. Bij een herhaalde fread lijkt me dat je dan afhankelijk van de size van de file de maximum executietijd moet veranderen OF de bewaking daarvan moet uitschakelen.
Ik wil die oplossing best proberen, maar het bestaande script heeft jaren goed gewerkt, dat vind ik zo vreemd.
Programmer - an organism that turns coffee into software.
Ik krijg geen meldingen op mijn scherm als ik de @ weglaat.
Die concatenatie in dat header statement kan idd ook. Je moet bedenken dat deze code een paar jaar oud is en ik destijds veel minder ervaring en kennis van de mogelijkheden van php had. Na verloop van tijd leer je dan dat een boel dingen compacter en sneller kunnen.
Die concatenatie in dat header statement kan idd ook. Je moet bedenken dat deze code een paar jaar oud is en ik destijds veel minder ervaring en kennis van de mogelijkheden van php had. Na verloop van tijd leer je dan dat een boel dingen compacter en sneller kunnen.
Mja, in die post op PHP.net staat iets over PHP5. Ik weet niet of je van PHP versie bent geswitched. Dat zou iig een oorzaak kunnen zijn.
Regeren is vooruitschuiven
Dat is het zeker. Ik upgrade meestal als er een security issue is en het filesize-bijeffect had ik uiteraard niet verwacht. Ik draai nu 5.0.4,dus ik loop alweer iets achter ...LuCarD schreef op vrijdag 30 september 2005 @ 13:29:
[...]
Het is een recent probleem met PHP, het is een bug die er ingeslopen is. Het kan zijn dat je een andere versie van PHP gebruikte op de oude machine waar het wel mee werkte.
[ Voor 7% gewijzigd door Verwijderd op 30-09-2005 13:32 ]
Dat chunk-read idee werkt prima!
Het script is nu:
Bedankt voor alle suggesties!
Het script is nu:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
| include '/usr/local/apache/inc/clean.inc'; function readfile_chunked($filename,$retbytes=true) { $chunksize = 1*(1024*1024); // how many bytes per chunk $buffer = ''; $cnt =0; // $handle = fopen($filename, 'rb'); $handle = fopen($filename, 'rb'); if ($handle === false) { return false; } while (!feof($handle)) { $buffer = fread($handle, $chunksize); echo $buffer; flush(); if ($retbytes) { $cnt += strlen($buffer); } } $status = fclose($handle); if ($retbytes && $status) { return $cnt; // return num. bytes delivered like readfile() does. } return $status; } $file_name = clean($_GET["file_name"], 80); $base = basename($file_name); $document_root=clean(getenv("DOCUMENT_ROOT"),80); if(file_exists($document_root.$file_name)) { clearstatcache(); $size = filesize($document_root.$file_name); header("Content-type:application/octet-stream"); header("Content-Disposition:attachment;filename=$base"); header("Content-Length: $size"); $cnt = readfile_chunked($document_root.$file_name); } else { header("Location:/php/thx.php?" . "status=F" . "&filename=$base"); } |
Bedankt voor alle suggesties!
[ Voor 127% gewijzigd door Verwijderd op 30-09-2005 14:10 ]
Pagina: 1