Zip on the fly problem

2010-01-12 Thread Thomas den Braber
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

2010-01-12 Thread Torsten Förtsch
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

2010-01-12 Thread David Nicol
Not satisfied with the size of your file?


Re: Zip on the fly problem

2010-01-12 Thread Scott Gifford
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

2010-01-12 Thread Ronald J Kimball
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

2010-01-12 Thread Thomas den Braber
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

2010-01-13 Thread André Warnier

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.


...