]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
http: set Content-Length for simple array responses
authorEric Wong <e@80x24.org>
Wed, 19 Jun 2024 23:41:03 +0000 (23:41 +0000)
committerEric Wong <e@80x24.org>
Thu, 20 Jun 2024 22:41:58 +0000 (22:41 +0000)
We'll be able to combine the header and body in a single
writev(2) call in the next commit.

lib/PublicInbox/Compat.pm
lib/PublicInbox/HTTP.pm

index 78cba90e15e0f5910e07261fb2b392613ccc6975..8ed2d7a18222c4709211b595dc8c05eb1c26c4e0 100644 (file)
@@ -8,7 +8,7 @@ use v5.12;
 use parent qw(Exporter);
 require List::Util;
 
-our @EXPORT_OK = qw(uniqstr);
+our @EXPORT_OK = qw(uniqstr sum0);
 
 # uniqstr is in List::Util 1.45+, which means Perl 5.26+;
 # so maybe 2030 for us since we need to support enterprise distros.
@@ -21,4 +21,6 @@ no warnings 'once';
        grep { !$seen{$_}++ } @_;
 };
 
+*sum0 = List::Util->can('sum0') // sub (@) { List::Util::sum(@_) // 0 };
+
 1;
index 3ca0d18c4892f72e6d99fe623bebe2c08e95817b..d0e5aa291f42a03b2f113232c5301fbf15330890 100644 (file)
@@ -21,6 +21,7 @@
 package PublicInbox::HTTP;
 use strict;
 use parent qw(PublicInbox::DS);
+use bytes qw(length);
 use Fcntl qw(:seek);
 use Plack::HTTPParser qw(parse_http_request); # XS or pure Perl
 use Plack::Util;
@@ -36,6 +37,7 @@ use constant {
        CHUNK_MAX_HDR => 256,
 };
 use Errno qw(EAGAIN);
+use PublicInbox::Compat qw(sum0);
 
 # Use the same configuration parameter as git since this is primarily
 # a slow-client sponge for git-http-backend
@@ -165,7 +167,7 @@ sub app_dispatch {
        }
 }
 
-sub response_header_write {
+sub response_header_write ($$$) {
        my ($self, $env, $res) = @_;
        my $proto = $env->{SERVER_PROTOCOL} or return; # HTTP/0.9 :P
        my $status = $res->[0];
@@ -189,6 +191,11 @@ sub response_header_write {
        my $term = defined($len) || $chunked;
        my $prot_persist = ($proto eq 'HTTP/1.1') && ($conn !~ /\bclose\b/i);
        my $alive;
+       if (!$term && ref($res->[2]) eq 'ARRAY') {
+               $len = sum0(map length, @{$res->[2]});
+               $h .= "Content-Length: $len\r\n";
+               $term = 1;
+       }
        if (!$term && $prot_persist) { # auto-chunk
                $chunked = $alive = 2;
                $alive = 3 if $env->{REQUEST_METHOD} eq 'HEAD';
@@ -454,7 +461,7 @@ use v5.12;
 sub write {
        # ([$http], $buf) = @_;
        PublicInbox::HTTP::chunked_write($_[0]->[0], $_[1]);
-       $_[0]->[0]->{sock} ? length($_[1]) : undef;
+       $_[0]->[0]->{sock} ? bytes::length($_[1]) : undef;
 }
 
 sub close {
@@ -469,7 +476,7 @@ our @ISA = qw(PublicInbox::HTTP::Chunked);
 sub write {
        # ([$http], $buf) = @_;
        PublicInbox::HTTP::identity_write($_[0]->[0], $_[1]);
-       $_[0]->[0]->{sock} ? length($_[1]) : undef;
+       $_[0]->[0]->{sock} ? bytes::length($_[1]) : undef;
 }
 
 1;