about summary refs log tree commit homepage
path: root/lib/PublicInbox/WwwStream.pm
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2020-07-05 23:27:18 +0000
committerEric Wong <e@yhbt.net>2020-07-06 20:01:15 +0000
commitb8b03f9c896432816019828b27708fa3b6903d83 (patch)
treed4fcf16173a04e9e35ac4916d9bcedc059f483cb /lib/PublicInbox/WwwStream.pm
parentcfd960f6a2c1cff9a9537b0758fcde1d3203b17f (diff)
downloadpublic-inbox-b8b03f9c896432816019828b27708fa3b6903d83.tar.gz
Plack::Middleware::Deflater forces us to use a memory-intensive
closure.  Instead, work towards building compressed strings in
memory to reduce the overhead of buffering large HTML output.
Diffstat (limited to 'lib/PublicInbox/WwwStream.pm')
-rw-r--r--lib/PublicInbox/WwwStream.pm27
1 files changed, 22 insertions, 5 deletions
diff --git a/lib/PublicInbox/WwwStream.pm b/lib/PublicInbox/WwwStream.pm
index 915a71ba..79ed6871 100644
--- a/lib/PublicInbox/WwwStream.pm
+++ b/lib/PublicInbox/WwwStream.pm
@@ -13,6 +13,8 @@ use base qw(Exporter);
 our @EXPORT_OK = qw(html_oneshot);
 use bytes (); # length
 use PublicInbox::Hval qw(ascii_html prurl);
+use Compress::Raw::Zlib qw(Z_FINISH Z_OK);
+use PublicInbox::GzipFilter qw(gzip_maybe);
 our $TOR_URL = 'https://www.torproject.org/';
 our $CODE_URL = 'https://public-inbox.org/public-inbox.git';
 
@@ -178,13 +180,28 @@ sub html_oneshot ($$;$) {
                 ctx => $ctx,
                 base_url => base_url($ctx),
         }, __PACKAGE__;
-        my @x = (_html_top($self), $sref ? $$sref : (), _html_end($self));
+        my @x;
+        my @h = ('Content-Type' => 'text/html; charset=UTF-8');
+        if (my $gz = gzip_maybe($ctx->{env})) {
+                my $err = $gz->deflate(_html_top($self), $x[0]);
+                die "gzip->deflate: $err" if $err != Z_OK;
+                if ($sref) {
+                        $err = $gz->deflate($sref, $x[0]);
+                        die "gzip->deflate: $err" if $err != Z_OK;
+                }
+                $err = $gz->deflate(_html_end($self), $x[0]);
+                die "gzip->deflate: $err" if $err != Z_OK;
+                $err = $gz->flush($x[0], Z_FINISH);
+                die "gzip->flush: $err" if $err != Z_OK;
+                push @h, qw(Vary Accept-Encoding Content-Encoding gzip);
+        } else {
+                @x = (_html_top($self), $sref ? $$sref : (), _html_end($self));
+        }
+
         my $len = 0;
         $len += bytes::length($_) for @x;
-        [ $code, [
-                'Content-Type' => 'text/html; charset=UTF-8',
-                'Content-Length' => $len
-        ], \@x ];
+        push @h, 'Content-Length', $len;
+        [ $code, \@h, \@x ]
 }
 
 1;