X-Git-Url: http://www.git.stargrave.org/?p=public-inbox.git;a=blobdiff_plain;f=lib%2FPublicInbox%2FIMAPdeflate.pm;fp=lib%2FPublicInbox%2FIMAPdeflate.pm;h=0000000000000000000000000000000000000000;hp=d5929ef26ed5dfd85d2d74e62172b75758066bf0;hb=23af251dd607c4e75ab1e68063f2c885c48cc035;hpb=9b0c238f887475d920a8589b492ec15c63770152 diff --git a/lib/PublicInbox/IMAPdeflate.pm b/lib/PublicInbox/IMAPdeflate.pm deleted file mode 100644 index d5929ef2..00000000 --- a/lib/PublicInbox/IMAPdeflate.pm +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright (C) 2020-2021 all contributors -# License: AGPL-3.0+ -# TODO: reduce duplication from PublicInbox::NNTPdeflate - -# RFC 4978 -package PublicInbox::IMAPdeflate; -use strict; -use warnings; -use 5.010_001; -use base qw(PublicInbox::IMAP); -use Compress::Raw::Zlib; - -my %IN_OPT = ( - -Bufsize => 1024, - -WindowBits => -15, # RFC 1951 - -AppendOutput => 1, -); - -# global deflate context and buffer -my $zbuf = \(my $buf = ''); -my $zout; -{ - my $err; - ($zout, $err) = Compress::Raw::Zlib::Deflate->new( - # nnrpd (INN) and Compress::Raw::Zlib favor MemLevel=9, - # the zlib C library and git use MemLevel=8 as the default - # -MemLevel => 9, - -Bufsize => 65536, # same as nnrpd - -WindowBits => -15, # RFC 1951 - -AppendOutput => 1, - ); - $err == Z_OK or die "Failed to initialize zlib deflate stream: $err"; -} - -sub enable { - my ($class, $self, $tag) = @_; - my ($in, $err) = Compress::Raw::Zlib::Inflate->new(%IN_OPT); - if ($err != Z_OK) { - $self->err("Inflate->new failed: $err"); - $self->write(\"$tag BAD failed to activate compression\r\n"); - return; - } - $self->write(\"$tag OK DEFLATE active\r\n"); - bless $self, $class; - $self->{zin} = $in; -} - -# overrides PublicInbox::NNTP::compressed -sub compressed { 1 } - -sub do_read ($$$$) { - my ($self, $rbuf, $len, $off) = @_; - - my $zin = $self->{zin} or return; # closed - my $doff; - my $dbuf = delete($self->{dbuf}) // ''; - $doff = length($dbuf); - my $r = PublicInbox::DS::do_read($self, \$dbuf, $len, $doff) or return; - - # Workaround inflate bug appending to OOK scalars: - # - # We only have $off if the client is pipelining, and pipelining - # is where our substr() OOK optimization in event_step makes sense. - if ($off) { - my $copy = $$rbuf; - undef $$rbuf; - $$rbuf = $copy; - } - - # assert(length($$rbuf) == $off) as far as NNTP.pm is concerned - # -ConsumeInput is true, so $dbuf is automatically emptied - my $err = $zin->inflate($dbuf, $rbuf); - if ($err == Z_OK) { - $self->{dbuf} = $dbuf if $dbuf ne ''; - $r = length($$rbuf) and return $r; - # nothing ready, yet, get more, later - $self->requeue; - } else { - delete $self->{zin}; - $self->close; - } - 0; -} - -# override PublicInbox::DS::msg_more -sub msg_more ($$) { - my $self = $_[0]; - - # $_[1] may be a reference or not for ->deflate - my $err = $zout->deflate($_[1], $zbuf); - $err == Z_OK or die "->deflate failed $err"; - 1; -} - -sub zflush ($) { - my ($self) = @_; - - my $deflated = $zbuf; - $zbuf = \(my $next = ''); - - my $err = $zout->flush($deflated, Z_FULL_FLUSH); - $err == Z_OK or die "->flush failed $err"; - - # We can still let the lower socket layer do buffering: - PublicInbox::DS::msg_more($self, $$deflated); -} - -# compatible with PublicInbox::DS::write, so $_[1] may be a reference or not -sub write ($$) { - my $self = $_[0]; - return PublicInbox::DS::write($self, $_[1]) if ref($_[1]) eq 'CODE'; - - my $deflated = $zbuf; - $zbuf = \(my $next = ''); - - # $_[1] may be a reference or not for ->deflate - my $err = $zout->deflate($_[1], $deflated); - $err == Z_OK or die "->deflate failed $err"; - $err = $zout->flush($deflated, Z_FULL_FLUSH); - $err == Z_OK or die "->flush failed $err"; - - # We can still let the socket layer do buffering: - PublicInbox::DS::write($self, $deflated); -} - -1;