package Apache::GZip;

use strict;
use Apache::Constants qw(:common);
use Compress::Zlib qw(deflateInit crc32 MAX_WBITS Z_DEFLATED);
use Apache::Forward ();
use vars qw($VERSION @ISA);

use constant GZIP_MAGIC => 0x1f8b;
use constant OS_MAGIC => 0x03;

$VERSION = '1.00';
@ISA = qw(Apache::Forward);

sub handler ($$) {
    my($class, $r) = @_;
    #return DECLINED unless $r->header_in("Accept-Encoding") =~ /gzip/;
    $r->content_encoding('gzip');
    $class->SUPER::handler($r);
}

sub TIEHANDLE {
    my $class = shift;
    my $r = shift; 
    my $self = $class->SUPER::TIEHANDLE($r, @_);
    my $d = deflateInit(-WindowBits => -MAX_WBITS()) || return;
    @{$self}{'crc','d','l','h'} = (crc32(undef),$d,0,0);
    $r->push_handlers(PerlHandler => sub { $self->flush });
    return $self;
}

sub gzheader {
    pack("nccVcc", GZIP_MAGIC, Z_DEFLATED, 0,time,0, OS_MAGIC)
}

sub PRINT {
    my $self = shift;
    $self->forward(gzheader()) unless $self->{'h'}++;
    foreach (@_) {
 	my $data = $self->{d}->deflate($_);
 	$self->{l} += length($_);
 	$self->{crc} = crc32($_, $self->{crc});
 	$self->forward($data);
    }
}

sub flush {
    my $self = shift;
    my $data = $self->{d}->flush;
    return unless $self->{'h'};
    $self->forward($data);
    $self->forward(pack("V V", $self->{'crc'}, $self->{'l'}));
}

1;
__END__


