+ my $ctx = $self->{ctx} or return;
+ my $ibx = $ctx->{-inbox};
+ my $gz = $self->{gz};
+ my $msgs = $self->{msgs};
+ do {
+ # work on existing result set
+ while (defined(my $smsg = shift @$msgs)) {
+ # id_batch may return integers
+ ref($smsg) or
+ $smsg = $ctx->{srch}->{over_ro}->get_art($smsg);
+
+ my $msg = eval { $ibx->msg_by_smsg($smsg) } or next;
+ $msg = Email::Simple->new($msg);
+ $gz->write(PublicInbox::Mbox::msg_str($ctx, $msg,
+ $smsg->mid));
+
+ # use subject of first message as subject
+ if (my $hdr = delete $self->{hdr}) {
+ my $fn = set_filename($self->{fn}, $msg);
+ push @$hdr, 'Content-Disposition',
+ "inline; filename=$fn.mbox.gz";
+ return $hdr;
+ }
+ 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 '';
+ }
+
+ # refill result set
+ $msgs = $self->{msgs} = $self->{cb}->();
+ } while (@$msgs);
+ $gz->close;
+ # signal that we're done and can return undef next call:
+ delete $self->{ctx};
+ ${delete $self->{buf}};