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
Thomas den Braber [ Di, 12 Januar 2010 13:49 ] [ ID #2028535 ]

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
torsten.foertsch [ Di, 12 Januar 2010 14:09 ] [ ID #2028536 ]

Re: Zip on the fly problem

--00504502aef7dbf91a047cfc3967
Content-Type: text/plain; charset=UTF-8

Not satisfied with the size of your file?

--00504502aef7dbf91a047cfc3967
Content-Type: text/html; charset=UTF-8

<br>Not satisfied with the size of your file?<br>

--00504502aef7dbf91a047cfc3967--
David Nicol [ Di, 12 Januar 2010 19:57 ] [ ID #2028545 ]

Re: Zip on the fly problem

--0003255573521ffcf2047d03208a
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Jan 12, 2010 at 7:49 AM, Thomas den Braber <thomas [at] delos.nl> 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.

--0003255573521ffcf2047d03208a
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On Tue, Jan 12, 2010 at 7:49 AM, Thomas den Braber <span dir=3D"ltr"><<a=
href=3D"mailto:thomas [at] delos.nl">thomas [at] delos.nl</a>></span> wrote:<div =
class=3D"gmail_quote"><div>[ ... ]=A0</div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">


The error is: 'IO error: seeking to rewrite local header : Invalid argu=
ment'<br></blockquote><div><br></div><div>That error means that after w=
riting something to the ZIP archive, it tried to go backwards to put what i=
t just wrote in the header, but found it couldn't do that because it=
9;s output is going over the network and what's already sent can't =
be changed.</div>

<div><br></div><div>A temporary file is certainly one fix, as people here h=
ave suggested. =A0The fact that it used to work means that it must be possi=
ble 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.</div>

<div><br></div><div>Hope this is at least a little helpful!</div><div><br><=
/div><div>----Scott.</div><div><br></div></div>

--0003255573521ffcf2047d03208a--
Scott Gifford [ Mi, 13 Januar 2010 04:11 ] [ ID #2028666 ]

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 <thomas [at] delos.nl> 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
Ronald J Kimball [ Mi, 13 Januar 2010 05:06 ] [ ID #2028667 ]

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 <rjk-perl-modperl [at] tamias.net>
To: Scott Gifford <sgifford [at] suspectclass.com>
Cc: Thomas den Braber <thomas [at] delos.nl>, modperl [at] 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 <thomas [at] delos.nl>
> 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
Thomas den Braber [ Mi, 13 Januar 2010 08:55 ] [ ID #2028668 ]

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.
>
....
aw [ Mi, 13 Januar 2010 09:21 ] [ ID #2028669 ]
Webserver » gmane.comp.apache.mod-perl » Zip on the fly problem

Vorheriges Thema: SetHandler perl-script not working
Nächstes Thema: Logs show reasonable request handling duration, but proxied clients timing out