Zip on the fly problem
Hi, I use Archive::Zip to generate zip files on the fly in Modperl 2.04 with code similar like this: my $zip = Archive::Zip->new(); my $member = $zip->addFile( '/home/testimg/test1.jpg', 'testfile1.jpg' ); if ($member){ $member->desiredCompressionLevel( 1 ); } $member = $zip->addFile( '/home/testimg/test2.ppt', 'testfile2.ppt' ); if ($member){ $member->desiredCompressionLevel( 1 ); } if ( $zip->numberOfMembers() ){ unless ( $zip->writeToFileHandle( \*STDOUT, 0) == Archive::Zip::AZ_OK) { print STDERR "Zip error: $!"; } } This works fine with Archive::Zip version 1.26 but fails with version 1.30 I checked the ARchibe::Zip code and could not find anything that can cause the problem accept for the change from using Compress::Zlib to Compress::Raw::Zlib. The error is: 'IO error: seeking to rewrite local header : Invalid argument' If I use desiredCompressionLevel(0) then there is no problem but no compression is done. The error is only related to Mod_perl. As a console script it runs fine. Problem is on both Windows and Linux (perl 5.10). Has anyone any idea what might be the problem? or have an alternative solution? Thanks, Thomas den Braber
Re: Zip on the fly problem
On Tuesday 12 January 2010 13:49:34 Thomas den Braber wrote: > I use Archive::Zip to generate zip files on the fly in Modperl 2.04 with > code similar like this: > > my $zip = Archive::Zip->new(); > my $member = $zip->addFile( '/home/testimg/test1.jpg', 'testfile1.jpg' ); > if ($member){ > $member->desiredCompressionLevel( 1 ); > } > $member = $zip->addFile( '/home/testimg/test2.ppt', 'testfile2.ppt' ); > if ($member){ > $member->desiredCompressionLevel( 1 ); > } > > if ( $zip->numberOfMembers() ){ > unless ( $zip->writeToFileHandle( \*STDOUT, 0) == Archive::Zip::AZ_OK) { > print STDERR "Zip error: $!"; > } > } > > This works fine with Archive::Zip version 1.26 but fails with version 1.30 > I checked the ARchibe::Zip code and could not find anything that can cause > the problem accept for the change from using Compress::Zlib to > Compress::Raw::Zlib. > > The error is: 'IO error: seeking to rewrite local header : Invalid > argument' > > If I use desiredCompressionLevel(0) then there is no problem but no > compression is done. > > The error is only related to Mod_perl. As a console script it runs fine. > Problem is on both Windows and Linux (perl 5.10). I can only guess here but does your console script write to a pipe or to a file? Could you try: script | cat >output.zip > Has anyone any idea what might be the problem? or have an alternative > solution? > Move the ZIP file generation to a PerlFixupHandler and have it write a temporary file. Then have the default handler ship the file and remove it in a request pool cleanup or so. This has the additional benefit of sending a Content-Length header (don't forget to update $r->finfo) which often leads to faster delivery. Torsten
Re: Zip on the fly problem
Not satisfied with the size of your file?
Re: Zip on the fly problem
On Tue, Jan 12, 2010 at 7:49 AM, Thomas den Braber wrote: [ ... ] > The error is: 'IO error: seeking to rewrite local header : Invalid > argument' > That error means that after writing something to the ZIP archive, it tried to go backwards to put what it just wrote in the header, but found it couldn't do that because it's output is going over the network and what's already sent can't be changed. A temporary file is certainly one fix, as people here have suggested. The fact that it used to work means that it must be possible to generate a ZIP file without seeking around, so my advice would be to poke around in the options and see if you find anything useful. Hope this is at least a little helpful! Scott.
Re: Zip on the fly problem
On Tue, Jan 12, 2010 at 10:11:04PM -0500, Scott Gifford wrote: > On Tue, Jan 12, 2010 at 7:49 AM, Thomas den Braber wrote: > [ ... ] > > > The error is: 'IO error: seeking to rewrite local header : Invalid > > argument' > > > > That error means that after writing something to the ZIP archive, it tried > to go backwards to put what it just wrote in the header, but found it > couldn't do that because it's output is going over the network and what's > already sent can't be changed. > > A temporary file is certainly one fix, as people here have suggested. The > fact that it used to work means that it must be possible to generate a ZIP > file without seeking around, so my advice would be to poke around in the > options and see if you find anything useful. The second argument to writeToFileHandle is supposed to address that: writeToFileHandle( $fileHandle [, $seekable] ) Write a zip archive to a file handle. Return AZ_OK on success. The optional second arg tells whether or not to try to seek backwards to re-write headers. ... If you pass a file handle that is not seekable (like if you're writing to a pipe or a socket), pass a false second argument: ... Thomas, are you sure the actual code in question is passing a false value as the second argument? Ronald
Re: Zip on the fly problem
Yes I am sure that second argument is false. In the old version I only used one argument but changed the second to 0 hoping that solved the problem. As Torsten was suggesting, I tested with: script | cat > file And yes that also fails with Archive::Zip 1.30 and worked ok with 1.26 script > file Worked in both versions. There is something wrong in the new Archive::Zip module I send a message to the CPAN forum hope they pick it up. Thank, Thomas den Braber -Original Message- From: Ronald J Kimball To: Scott Gifford Cc: Thomas den Braber , modperl@perl.apache.org Date: Tue, 12 Jan 2010 23:06:49 -0500 Subject: Re: Zip on the fly problem > On Tue, Jan 12, 2010 at 10:11:04PM -0500, Scott Gifford wrote: > > On Tue, Jan 12, 2010 at 7:49 AM, Thomas den Braber > wrote: > > [ ... ] > > > > > The error is: 'IO error: seeking to rewrite local header : Invalid > > > argument' > > > > > > > That error means that after writing something to the ZIP archive, it > tried > > to go backwards to put what it just wrote in the header, but found it > > couldn't do that because it's output is going over the network and > what's > > already sent can't be changed. > > > > A temporary file is certainly one fix, as people here have suggested. > The > > fact that it used to work means that it must be possible to generate > a ZIP > > file without seeking around, so my advice would be to poke around in > the > > options and see if you find anything useful. > > The second argument to writeToFileHandle is supposed to address that: > > writeToFileHandle( $fileHandle [, $seekable] ) > > Write a zip archive to a file handle. Return AZ_OK on success. The > optional second arg tells whether or not to try to seek backwards > to > re-write headers. > > ... > > If you pass a file handle that is not seekable (like if you're > writing > to a pipe or a socket), pass a false second argument: > > ... > > Thomas, are you sure the actual code in question is passing a false > value > as the second argument? > > Ronald
Re: Zip on the fly problem
Thanks guys for this informative thread. I use Archive::Zip extensively, including in mod_perl context. I have not encountered this problem yet, but will now make sure to keep an eye open for it when I upgrade my systems. Thomas den Braber wrote: Yes I am sure that second argument is false. In the old version I only used one argument but changed the second to 0 hoping that solved the problem. As Torsten was suggesting, I tested with: script | cat > file And yes that also fails with Archive::Zip 1.30 and worked ok with 1.26 script > file Worked in both versions. There is something wrong in the new Archive::Zip module I send a message to the CPAN forum hope they pick it up. ...