Schrift
[thread]11522[/thread]

Zip über CGI an Browser senden

Leser: 1


<< >> 9 Einträge, 1 Seite
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 :)
lichtkind
 2008-03-26 13:24
#107497 #107497
User since
2004-03-22
5697 Artikel
ModeratorIn + EditorIn
[Homepage]
user image
noch ein nachtrag :)

es macht keinen sinn in einer sub use zu benutzen. entweder du schreibst es im kopf da es eh so oder so geladen wird oder in der sub mit require, dann wirds auch nur geladen wenn sub ausgeführt wird.
Wiki:Tutorien in der Wiki, mein zeug:
kephra, baumhaus, garten, gezwitscher

Es beginnt immer mit einer Entscheidung.
roooot
 2008-03-26 13:25
#107498 #107498
User since
2008-03-03
276 Artikel
BenutzerIn
[default_avatar]
Aha ok, das wusste ich nicht. :) Habs geändert. Danke.

Werden use immer geladen wenn der Interpreter das Script liest, egal wo sie stehen?
Viele Grüße :)
renee
 2008-03-26 13:29
#107499 #107499
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
roooot+2008-03-26 12:25:57--
Aha ok, das wusste ich nicht. :) Habs geändert. Danke.

Werden use immer geladen wenn der Interpreter das Script liest, egal wo sie stehen?


perl schaut sich das Skript an (ohne den "normalen" Code auszuführen) und prüft für jedes "use", ob das Modul schon geladen wurde. Wenn ja, dann mache nix, ansonsten lade das Modul.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2008-03-26 13:32
#107500 #107500
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
roooot+2008-03-26 12:14:22--
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.


Warum speicherst Du es im cgi-bin-Verzeichnis?
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
roooot
 2008-03-26 14:07
#107501 #107501
User since
2008-03-03
276 Artikel
BenutzerIn
[default_avatar]
Eigentlich ist das eine sehr gute Frage. Am liebsten würde ich es gar nicht speichern, sondern nur über das Script ausgeben.
Es handelt sich dabei um ein Bilderarchiv das passwortgeschützt ist. Dort können die User die Bilder auch anschauen und das Album als Archiv runterladen. Allerdings nur wenn sie die Berechtigungen dazu auch haben. Und das wird mithilfe einer Name/Passwort Kombination erreicht. Wenn ich das Archiv nun nicht über das Script ausgebe, dann kann jeder hinzu und kunz das Archiv runterladen.
Viele Grüße :)
renee
 2008-03-26 14:27
#107502 #107502
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Dann probier doch mal mittels $zip->writeToFileHandle( \*STDOUT ) oder so ähnlich das direkt auszugeben.
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
nepos
 2008-03-26 14:46
#107503 #107503
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Oder schreib das erzeugte Zip wenigstens in ein temporäres Verzeichnis wie /tmp/. Da kommt man per Browser auch nicht ran.
Strat
 2008-03-28 12:54
#107591 #107591
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
renee+2008-03-26 12:29:57--
perl schaut sich das Skript an (ohne den "normalen" Code auszuführen) und prüft für jedes "use", ob das Modul schon geladen wurde. Wenn ja, dann mache nix, ansonsten lade das Modul.


Das stimmt nur bei Modulen, nicht jedoch bei pragmas. strict/warnings/integer/... sind Pragmata, die einen lokalen Geltungsbereich haben, z.B.

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# das hier hat einen lokalen Geltungsbereich, und zwar den der aktuellen Datei,
# weil es in keinem Block steht
use warnings;
my $x = undef;
if( 1 ) {
    # gilt nur bis zum ende des Blockes, oder bis zum naechsten use warnings
    no warnings; 
    print "X1 = $x\n";

    # gilt bis zum Ende des Blockes, oder bis zum naechsten no warnings
    use warnings; 
    print "X2 = $x\n";
}
danach gilt wieder der vorherige status ausserhalb des blocks


Um einfach zwischen Pragmata und Modulen unterscheiden zu können, werden erstere normalerweise klein geschrieben...
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
<< >> 9 Einträge, 1 Seite



View all threads created 2008-03-26 13:14.