From c0456ca8c644b47766a6ecbde5346f91934fbf8b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 10 Feb 2025 21:09:34 +0000 Subject: [PATCH] git_http_backend: input_prepare: die on unrecoverable errors We shouldn't be guarding against errors at this level to return 500 errors, but rather we can rely on existing eval wrappers in the stack (e.g. Plack::Util::run_app and Qspawn->parse_hdr_done) to capture errors and return the HTTP 500 status. --- lib/PublicInbox/Cgit.pm | 2 +- lib/PublicInbox/GitHTTPBackend.pm | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/PublicInbox/Cgit.pm b/lib/PublicInbox/Cgit.pm index 480d1df69..a7ee48b9e 100644 --- a/lib/PublicInbox/Cgit.pm +++ b/lib/PublicInbox/Cgit.pm @@ -105,7 +105,7 @@ sub call { @cgi_env{@PASS_ENV} = @$env{@PASS_ENV}; # spawn ignores undef vals $cgi_env{HTTPS} = 'on' if $env->{'psgi.url_scheme'} eq 'https'; - my $rdr = input_prepare($env) or return r(500); + my $rdr = { 0 => input_prepare($env) }; my $qsp = PublicInbox::Qspawn->new($self->{cmd}, \%cgi_env, $rdr); my $limiter = $self->{pi_cfg}->limiter('-cgit'); $qsp->psgi_yield($env, $limiter, $parse_cgi_headers, $ctx); diff --git a/lib/PublicInbox/GitHTTPBackend.pm b/lib/PublicInbox/GitHTTPBackend.pm index 57d2ec7ba..3dce4dbb4 100644 --- a/lib/PublicInbox/GitHTTPBackend.pm +++ b/lib/PublicInbox/GitHTTPBackend.pm @@ -7,6 +7,7 @@ package PublicInbox::GitHTTPBackend; use strict; use v5.10.1; use Fcntl qw(:seek); +use autodie qw(sysseek); use IO::Handle; # ->flush use HTTP::Date qw(time2str); use PublicInbox::Limiter; @@ -41,8 +42,6 @@ sub serve { serve_dumb($env, $git, $path); } -sub ucarp { Carp::carp(@_); undef } - my $prev = 0; my $exp; sub cache_one_year { @@ -103,8 +102,7 @@ sub serve_smart ($$$;$) { ($pi_cfg ? $pi_cfg->limiter('-httpbackend', 32) : undef); $env{GIT_HTTP_EXPORT_ALL} = '1'; $env{PATH_TRANSLATED} = "$git->{git_dir}/$path"; - my $rdr = input_prepare($env) or return r(500); - $rdr->{quiet} = 1; + my $rdr = { 0 => input_prepare($env), quiet => 1 }; my $cmd = $git->cmd('http-backend'); splice @$cmd, 1, 0, '-c', 'safe.directory=*'; my $qsp = PublicInbox::Qspawn->new($cmd, \%env, $rdr); @@ -116,19 +114,19 @@ sub input_prepare { my $input = $env->{'psgi.input'}; my $fd = eval { fileno($input) }; - return { 0 => $fd } if (defined $fd && $fd >= 0); + return $fd if (defined $fd && $fd >= 0); my $id = "git-http.input.$env->{REMOTE_ADDR}:$env->{REMOTE_PORT}"; - my $in = tmpfile($id) // return ucarp("tmpfile: $!"); + my $in = tmpfile($id) // die "tmpfile: $!"; my $buf; while (1) { - my $r = $input->read($buf, 8192) // return ucarp("read $!"); + my $r = $input->read($buf, 8192) // die "read: $!"; last if $r == 0; - print $in $buf // return ucarp("print: $!"); + print $in $buf; } # ensure it's visible to git-http-backend(1): - $in->flush // return ucarp("flush: $!"); - sysseek($in, 0, SEEK_SET) // return ucarp($env, "seek: $!"); - { 0 => $in }; + $in->flush // die "flush: $!"; + sysseek $in, 0, SEEK_SET; + $in; } sub parse_cgi_headers { # {parse_hdr} for Qspawn -- 2.47.3