bless { gz => $gz }, __PACKAGE__;
}
+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";
package PublicInbox::Qspawn;
use strict;
-use warnings;
use PublicInbox::Spawn qw(popen_rd);
+use PublicInbox::GzipFilter;
# n.b.: we get EAGAIN with public-inbox-httpd, and EINTR on other PSGI servers
use Errno qw(EAGAIN EINTR);
my ($self) = @_;
my $r = rd_hdr($self) or return;
my $env = $self->{psgi_env};
- my $filter = delete $env->{'qspawn.filter'};
+ my $filter = delete $env->{'qspawn.filter'} //
+ PublicInbox::GzipFilter::qsp_maybe($r->[1], $env);
+
my $wcb = delete $env->{'qspawn.wcb'};
my $async = delete $self->{async};
if (scalar(@$r) == 3) { # error
return $qsp->psgi_return($env, undef, sub {
[ 200, [ qw(Content-Type application/octet-stream)]]
});
+ } elsif ($path eq '/psgi-return-compressible') {
+ require PublicInbox::Qspawn;
+ my $cmd = [qw(echo goodbye world)];
+ my $qsp = PublicInbox::Qspawn->new($cmd);
+ return $qsp->psgi_return($env, undef, sub {
+ [200, [qw(Content-Type text/plain)]]
+ });
} elsif ($path eq '/psgi-return-enoent') {
require PublicInbox::Qspawn;
my $cmd = [ 'this-better-not-exist-in-PATH'.rand ];
is($n, 30 * 1024 * 1024, 'got expected output from curl');
is($non_zero, 0, 'read all zeros');
- require_mods(@zmods, 2);
+ require_mods(@zmods, 4);
my $buf = xqx([$curl, '-sS', "$base/psgi-return-gzip"]);
is($?, 0, 'curl succesful');
IO::Uncompress::Gunzip::gunzip(\$buf => \(my $out));
is($out, "hello world\n");
+ my $curl_rdr = { 2 => \(my $curl_err = '') };
+ $buf = xqx([$curl, qw(-sSv --compressed),
+ "$base/psgi-return-compressible"], undef, $curl_rdr);
+ is($?, 0, 'curl --compressed successful');
+ is($buf, "goodbye world\n", 'gzipped response as expected');
+ like($curl_err, qr/\bContent-Encoding: gzip\b/,
+ 'curl got gzipped response');
}
{