perlapacheapache2zipmod-perl

Print Archive::Zip zip file to Apache2::RequestIO object


I have a website using mod_perl.

I'm creating a zip file in memory (using Archive::Zip), and I want to serve that file without having to write it to disk.

Archive::Zip will only output to a specified file handle, and I don't think Apache2::RequestIO provides me with one.

At the moment I just print the Zip file to *STDOUT and that works. But I'm sure there's a better way to do it. I'm printing everything else through the RequestRec object, e.g. $r->print(...)


Solution

  • Something like this should help...

    use Archive::Zip;
    my $zip = Archive::Zip->new();
    #create your zip here
    
    use IO::Scalar;
    my $memory_file = '';   #scalar as a file
    my $memfile_fh = IO::Scalar->new(\$memory_file); #filehandle to the scalar
    
    # write to the scalar $memory_file
    my $status = $zip->writeToFileHandle($memfile_fh);
    $memfile_fh->close;
    
    #print with apache
    #$r->content_type(".......");
    $r->print($memory_file);    #the content of a file-in-a-scalar
    

    EDIT: The above is obsoloted. from the Archive::Zip docs:

    Try to avoid IO::Scalar

    One of the most common ways to use Archive::Zip is to generate Zip files in-memory. Most people have use IO::Scalar for this purpose.

    Unfortunately, as of 1.11 this module no longer works with IO::Scalar as it incorrectly implements seeking.

    Anybody using IO::Scalar should consider porting to IO::String, which is smaller, lighter, and is implemented to be perfectly compatible with regular seekable filehandles.

    Support for IO::Scalar most likely will not be restored in the future, as IO::Scalar itself cannot change the way it is implemented due to back-compatibility issues.