Thread Zip über CGI an Browser senden (8 answers)
Opened by roooot at 2008-03-26 13:14

roooot
 2008-03-26 13:14
#107496 #107496
User since
2008-03-03
276 Artikel
BenutzerIn
[default_avatar]
Hallo
ich erstelle mit Archive::Zip ein Zip Archiv. Das funktioniert. Nun möchte ich dieses Zip an den Browser schicken, damit der User das Downloaden kann. Zur Zeit öffne ich es und lese es in einer while Schleife wo dann immer ein best. Buffer an den Browser gesendet wird. Das Problem: Es kommen nur defekte Archive an. Das Originalarchiv auf dem Webserver funktioniert aber. Es liegt also am Senden (Zeilen 50-56).

Hier der Code:
Code (perl): (dl )
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
sub zip {
        use admin::tools;
        if(admin::tools::userRechte($main::session->param('user-id'),'d',$aktion)) {
                use File::Copy;
                use File::Path;
                
                my @r  = mysql::get('name,securestring','alben','`id` = \''.$aktion.'\' LIMIT 1');
                
                mkdir('./'.$r[0][0]);
                
                #share::logge('Bilderhashes: '.$main::cgi->param('bhash'));             
                # bildhash: format: hash1,hash2,hash3
                my @hashes = split(/\,/,$main::cgi->param('bhash'));
                
                
                use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
                my $zip = Archive::Zip->new() or seite::fehler( 500 , "ZIP ** FEHLER - KANN ZIP NICHT ERSTELLEN: $!" );
                $zip->zipfileComment( 'Galerie: '.$r[0][0]. '  (id:'.$aktion.') -- gedownloaded von http://r.port17.de/galerie/' ) or warn "ZIP ** WARNUNG - KANN ZIP KOMMENTAR NICHT HINFZUFUGEN";
                
                open FAKE, '> ./__ r.port17.de/galerie __';
                close FAKE;
                $zip->addFile( ' ./__ r.port17.de/galerie __' ) or warn "ZIP ** FEHLER - KANN FAKE NICHT ZU ZIP HINZUFUGEN: $!";
                unlink ( ' ./__ r.port17.de/galerie __' );
                
                foreach my $b (@hashes) {
                        my @r3 = mysql::get('name','bilder','`hash` = \''.$b.'\'');
                        
                        copy('./bilder/'.$r[0][1].'/org-'.$b.'.jpg','./'.$r[0][0].'/'.$r3[0][0].'.jpg') or warn "ZIP ** FEHLER - KANN ORGBILD './bilder/$r[0][1]/org-$b.jpg' NICHT VERSCHIEBEN: $!";
                        
                        $zip->addFile( './'.$r[0][0].'/'.$r3[0][0].'.jpg' ) or warn "ZIP ** FEHLER - KANN BILD NICHT ZU ZIP HINZUFUGEN: $!";
                }
                
                my @zeichen = ("a" .. "z","A" .. "Z", 0 .. 9);
                my $hash = join ("", @zeichen[map{rand @zeichen}(1 .. 10)]);
        
        
                unless($zip->writeToFileNamed('./.tmp/'.$hash.'.zip') == AZ_OK ) {
                                seite::fehler( 500 ,'ZIP ** FEHLER - KANN ZIPTMP NICHT SPEICHERN: !AZ_OK');     
                }       
        
                rmtree('./'.$r[0][0]);
                
                my $g = -s './.tmp/'.$hash.'.zip';
                
                print CGI::header(
                        -type => 'application/zip',
                        -Content_length => $g
                );
                                                                                        
                open(ZIP, '<./.tmp/'.$hash.'.zip') or seite::fehler( 500 , "ZIP ** FEHLER - KANN ZIPTMP NICHT EINLESEN: $!" );
                binmode(ZIP);
                my $buf;
                while(read ZIP,$buf,8192) {
                  print $buf;
                }
                close ZIP;
                
                unlink( './.tmp/'.$hash.'.zip' ) or warn "ZIP ** FEHLER - KANN ZIPTMP NICHT LOSCHEN: $!";               
        }
        else {
                seite::fehler('401','Rechte zum Download nicht ausreichend');
        }
}


Direkt auf das Zip kann ich ja nicht verlinken, da es im cgi-bin Verzeichnis liegt und das bei meinem Hoster so konfiguriert ist, dass dort alle Dateien ausgeführt werden, sprich es endet in nem 500er, weils ja keine gültige PERL/Cgi Anwendung ist.

Danke für eure Hilfe!









NACHTRAG:
Ich habe herausgefunden, dass es daran liegt, dass ich in dem header die Dateigröße mitschicke. Lasse ich sie weg und schicke nur den Type dann funktioniert alles. Unschöner nebeneffekt: Der Browser lädt die Datei und sagt während des Laden unbekannte Dateigröße. Genau das wollte ich umgehen.
Viele Grüße :)

View full thread Zip über CGI an Browser senden