]> Sergey Matveev's repositories - public-inbox.git/commitdiff
wwwtext: gzip text/plain responses, as well
authorEric Wong <e@yhbt.net>
Sun, 5 Jul 2020 23:27:20 +0000 (23:27 +0000)
committerEric Wong <e@yhbt.net>
Mon, 6 Jul 2020 20:01:15 +0000 (20:01 +0000)
Most of our plain-text responses are config files
big enough to warrant compression.

lib/PublicInbox/WwwText.pm
t/psgi_text.t

index b23a415e47c32be3391d5950054c36c7af185cb5..508005fba0ee315b603dd0fb2b365a14d318c092 100644 (file)
@@ -10,6 +10,8 @@ use PublicInbox::Linkify;
 use PublicInbox::WwwStream;
 use PublicInbox::Hval qw(ascii_html);
 use URI::Escape qw(uri_escape_utf8);
+use PublicInbox::GzipFilter qw(gzf_maybe);
+use Compress::Raw::Zlib qw(Z_FINISH Z_OK);
 our $QP_URL = 'https://xapian.org/docs/queryparser.html';
 our $WIKI_URL = 'https://en.wikipedia.org/wiki';
 my $hl = eval {
@@ -35,14 +37,23 @@ sub get_text {
                $code = 404;
                $txt = "404 Not Found ($key)\n";
        }
+       my $env = $ctx->{env};
        if ($raw) {
-               $hdr->[3] = bytes::length($txt);
-               return [ $code, $hdr, [ $txt ] ]
+               my $body;
+               if (my $gzf = $code == 200 ? gzf_maybe($hdr, $env) : undef) {
+                       my $zbuf = $gzf->translate($txt);
+                       undef $txt;
+                       $body = [ $zbuf .= $gzf->translate(undef) ];
+               } else {
+                       $body = [ $txt ];
+               }
+               $hdr->[3] = bytes::length($body->[0]);
+               return [ $code, $hdr, $body ]
        }
 
        # enforce trailing slash for "wget -r" compatibility
        if (!$have_tslash && $code == 200) {
-               my $url = $ctx->{-inbox}->base_url($ctx->{env});
+               my $url = $ctx->{-inbox}->base_url($env);
                $url .= "_/text/$key/";
 
                return [ 302, [ 'Content-Type', 'text/plain',
index 833bcaba777c32638c1e816d15a58e755192e100..9867feaa46407b7c1542fcdb8c0ae791d0f05157 100644 (file)
@@ -10,7 +10,7 @@ my $maindir = "$tmpdir/main.git";
 my $addr = 'test-public@example.com';
 my $cfgpfx = "publicinbox.test";
 my @mods = qw(HTTP::Request::Common Plack::Test URI::Escape Plack::Builder);
-require_mods(@mods);
+require_mods(@mods, 'IO::Uncompress::Gunzip');
 use_ok $_ foreach @mods;
 use PublicInbox::Import;
 use PublicInbox::Git;
@@ -26,17 +26,36 @@ my $www = PublicInbox::WWW->new($config);
 
 test_psgi(sub { $www->call(@_) }, sub {
        my ($cb) = @_;
-       my $res;
-       $res = $cb->(GET('/test/_/text/help/'));
-       like($res->content, qr!<title>public-inbox help.*</title>!,
-               'default help');
-       $res = $cb->(GET('/test/_/text/config/raw'));
+       my $gunzipped;
+       my $req = GET('/test/_/text/help/');
+       my $res = $cb->($req);
+       my $content = $res->content;
+       like($content, qr!<title>public-inbox help.*</title>!, 'default help');
+       $req->header('Accept-Encoding' => 'gzip');
+       $res = $cb->($req);
+       is($res->header('Content-Encoding'), 'gzip', 'got gzip encoding');
+       is($res->header('Content-Type'), 'text/html; charset=UTF-8',
+               'got gzipped HTML');
+       IO::Uncompress::Gunzip::gunzip(\($res->content) => \$gunzipped);
+       is($gunzipped, $content, 'gzipped content is correct');
+
+       $req = GET('/test/_/text/config/raw');
+       $res = $cb->($req);
+       $content = $res->content;
+       my $olen = $res->header('Content-Length');
        my $f = "$tmpdir/cfg";
        open my $fh, '>', $f or die;
-       print $fh $res->content or die;
+       print $fh $content or die;
        close $fh or die;
        my $cfg = PublicInbox::Config->new($f);
        is($cfg->{"$cfgpfx.address"}, $addr, 'got expected address in config');
+
+       $req->header('Accept-Encoding' => 'gzip');
+       $res = $cb->($req);
+       is($res->header('Content-Encoding'), 'gzip', 'got gzip encoding');
+       ok($res->header('Content-Length') < $olen, 'gzipped help is smaller');
+       IO::Uncompress::Gunzip::gunzip(\($res->content) => \$gunzipped);
+       is($gunzipped, $content);
 });
 
 done_testing();