about summary refs log tree commit homepage
path: root/lib/PublicInbox/MboxGz.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-11-16 02:34:38 +0000
committerEric Wong <e@80x24.org>2019-11-16 11:05:01 +0000
commitcbf748a8a038fd51a7ace57570c0267f8162999b (patch)
tree796875699eb4c84f5a4dedf018a0bfe47f19332e /lib/PublicInbox/MboxGz.pm
parente84f0a4fe260060b2055ed4c856308b4bb73b641 (diff)
downloadpublic-inbox-cbf748a8a038fd51a7ace57570c0267f8162999b.tar.gz
It'll make using Compress::Raw::Zlib easier, since we
can use that and import constants more easily.
Diffstat (limited to 'lib/PublicInbox/MboxGz.pm')
-rw-r--r--lib/PublicInbox/MboxGz.pm64
1 files changed, 64 insertions, 0 deletions
diff --git a/lib/PublicInbox/MboxGz.pm b/lib/PublicInbox/MboxGz.pm
new file mode 100644
index 00000000..2919ad6a
--- /dev/null
+++ b/lib/PublicInbox/MboxGz.pm
@@ -0,0 +1,64 @@
+# Copyright (C) 2015-2019 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
+package PublicInbox::MboxGz;
+use strict;
+use warnings;
+use Email::Simple;
+use PublicInbox::Hval qw/to_filename/;
+use PublicInbox::Mbox;
+use IO::Compress::Gzip;
+
+sub new {
+        my ($class, $ctx, $cb) = @_;
+        my $buf = '';
+        $ctx->{base_url} = $ctx->{-inbox}->base_url($ctx->{env});
+        bless {
+                buf => \$buf,
+                gz => IO::Compress::Gzip->new(\$buf, Time => 0),
+                cb => $cb,
+                ctx => $ctx,
+        }, $class;
+}
+
+sub response {
+        my ($class, $ctx, $cb, $fn) = @_;
+        my $body = $class->new($ctx, $cb);
+        # http://www.iana.org/assignments/media-types/application/gzip
+        my @h = qw(Content-Type application/gzip);
+        if ($fn) {
+                $fn = to_filename($fn);
+                push @h, 'Content-Disposition', "inline; filename=$fn.mbox.gz";
+        }
+        [ 200, \@h, $body ];
+}
+
+# called by Plack::Util::foreach or similar
+sub getline {
+        my ($self) = @_;
+        my $ctx = $self->{ctx} or return;
+        my $gz = $self->{gz};
+        while (my $smsg = $self->{cb}->()) {
+                my $mref = $ctx->{-inbox}->msg_by_smsg($smsg) or next;
+                my $h = Email::Simple->new($mref)->header_obj;
+                $gz->write(PublicInbox::Mbox::msg_hdr($ctx, $h, $smsg->{mid}));
+                $gz->write(PublicInbox::Mbox::msg_body($$mref));
+
+                my $bref = $self->{buf};
+                if (length($$bref) >= 8192) {
+                        my $ret = $$bref; # copy :<
+                        ${$self->{buf}} = '';
+                        return $ret;
+                }
+
+                # be fair to other clients on public-inbox-httpd:
+                return '';
+        }
+        delete($self->{gz})->close;
+        # signal that we're done and can return undef next call:
+        delete $self->{ctx};
+        ${delete $self->{buf}};
+}
+
+sub close {} # noop
+
+1;