]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
http: fix and test Trailer: rejection
authorEric Wong <e@80x24.org>
Wed, 2 Apr 2025 19:00:14 +0000 (19:00 +0000)
committerEric Wong <e@80x24.org>
Fri, 4 Apr 2025 19:52:40 +0000 (19:52 +0000)
We need to check for the existence of Trailers after successful
parsing.  I actually intend to support HTTP trailers, and I
noticed this while working on adding support for them.

lib/PublicInbox/HTTP.pm
t/httpd-corner.t

index 416fc4531d4c5d67e35c9a0760e2c602654f3bde..69cba8a630922c9bf626414da7b80807f4e4916e 100644 (file)
@@ -91,17 +91,15 @@ sub event_step { # called by PublicInbox::DS
        my %env = %{$self->{srv_env}}; # full hash copy
        my $r;
        while (($r = parse_http_request($$rbuf, \%env)) < 0) {
-               # We do not support Trailers in chunked requests, for
-               # now (they are rarely-used and git (as of 2.7.2) does
-               # not use them).
                # this length-check is necessary for PURE_PERL=1:
-               if ($r == -1 || $env{HTTP_TRAILER} ||
-                               ($r == -2 && length($$rbuf) > 0x4000)) {
+               ($r == -1 || ($r == -2 && length($$rbuf) > 0x4000)) and
                        return quit($self, 400);
-               }
                $self->do_read($rbuf, 8192, length($$rbuf)) or return;
        }
-       return quit($self, 400) if grep(/\s/, keys %env); # stop smugglers
+       # We do not support Trailers in chunked requests, for now.
+       # They're rarely-used and git (as of 2.7.2) does not use them.
+       return quit($self, 400) if exists($env{HTTP_TRAILER}) ||
+                                       grep(/\s/, keys %env); # stop smugglers
        $$rbuf = substr($$rbuf, $r);
        my $len = input_prepare($self, \%env) //
                return write_err($self, undef); # EMFILE/ENFILE
index a29e0657f4a25281f0aaf395d24cfdffadae506c..c57bc39fa4baa9b64dd92c0743a315d7cc5bacfd 100644 (file)
@@ -135,6 +135,14 @@ if ('test worker death') {
        sysread $conn, my $buf, 4096;
        like($buf, qr!\AHTTP/1\.[0-9] 400 !, 'got 400 response on bad request');
 }
+{
+       my $conn = $mkreq->($sock, 'Trailer rejected (for now)', <<EOM);
+PUT /sha1 HTTP/1.1\r\nTransfer-Encoding: chunked\r\nTrailer: Content-MD5\r\n\r
+EOM
+       sysread $conn, my $buf, 4096;
+       like $buf, qr!\AHTTP/1\.[0-9] 400 !,
+               'got 400 response on Trailer (for now)';
+}
 {
        my $conn = $mkreq->($sock, 'streaming callback',
                "GET /callback HTTP/1.0\r\n\r\n");