+sub gz_or_noop {
+ my ($res_hdr, $env) = @_;
+ if (($env->{HTTP_ACCEPT_ENCODING} // '') =~ /\bgzip\b/) {
+ $env->{'plack.skip-deflater'} = 1;
+ push @$res_hdr, @GZIP_HDRS;
+ gzip_or_die();
+ } else {
+ PublicInbox::CompressNoop::new();
+ }
+}
+
+sub gzf_maybe ($$) { bless { gz => gz_or_noop(@_) }, __PACKAGE__ }
+
+sub psgi_response {
+ my ($self, $code, $res_hdr) = @_;
+ my $env = $self->{env};
+ $self->{gz} //= gz_or_noop($res_hdr, $env);
+ if ($env->{'pi-httpd.async'}) {
+ my $http = $env->{'psgix.io'}; # PublicInbox::HTTP
+ $http->{forward} = $self;
+ sub {
+ my ($wcb) = @_; # -httpd provided write callback
+ $self->{http_out} = $wcb->([$code, $res_hdr]);
+ $self->can('async_next')->($http); # start stepping
+ };
+ } else { # generic PSGI code path
+ [ $code, $res_hdr, $self ];
+ }
+}
+
+sub qsp_maybe ($$) {
+ my ($res_hdr, $env) = @_;
+ return if ($env->{HTTP_ACCEPT_ENCODING} // '') !~ /\bgzip\b/;
+ my $hdr = join("\n", @$res_hdr);
+ return if $hdr !~ m!^Content-Type\n
+ (?:(?:text/(?:html|plain))|
+ application/atom\+xml)\b!ixsm;
+ return if $hdr =~ m!^Content-Encoding\ngzip\n!smi;
+ return if $hdr =~ m!^Content-Length\n[0-9]+\n!smi;
+ return if $hdr =~ m!^Transfer-Encoding\n!smi;
+ # in case Plack::Middleware::Deflater is loaded:
+ return if $env->{'plack.skip-deflater'}++;
+ push @$res_hdr, @GZIP_HDRS;
+ bless {}, __PACKAGE__;
+}
+
+sub gzip_or_die () {
+ my ($gz, $err) = Compress::Raw::Zlib::Deflate->new(%OPT);
+ $err == Z_OK or die "Deflate->new failed: $err";
+ $gz;
+}
+