From: Eric Wong Date: Wed, 7 May 2025 00:16:33 +0000 (+0000) Subject: httpd: psgix.io is the underlying IO object X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b78833f30a61dad264ac9c5c76e1f67234274aa;p=thirdparty%2Fpublic-inbox.git httpd: psgix.io is the underlying IO object PSGI::Extensions(3pm) states psgix.io should be "the raw IO socket", so we shall conform to that specification. For our codebase to continue taking advantage of public-inbox-daemon-specific features, we now expose the PublicInbox::HTTP object via $env->{'pi-httpd.client'}. The `pi-httpd.async' boolean field is now gone, since we can just test for the presence of `pi-httpd.app' or `pi-httpd.client' to avoid occupying another hash table entry. --- diff --git a/lib/PublicInbox/ExtMsg.pm b/lib/PublicInbox/ExtMsg.pm index dd7240fb2..251e430e8 100644 --- a/lib/PublicInbox/ExtMsg.pm +++ b/lib/PublicInbox/ExtMsg.pm @@ -141,7 +141,7 @@ sub ext_msg { ext_msg_ALL($ctx) // sub { $ctx->{-wcb} = $_[0]; # HTTP server write callback - if ($ctx->{env}->{'pi-httpd.async'}) { + if ($ctx->{env}->{'pi-httpd.app'}) { require PublicInbox::ConfigIter; my $iter = PublicInbox::ConfigIter->new( $ctx->{www}->{pi_cfg}, @@ -181,7 +181,7 @@ sub finalize_exact { push @{$ctx->{partial}}, [ $cur, $mids ]; } elsif ($ctx->{again} && length($mid) >= $MIN_PARTIAL_LEN) { bless $ctx, __PACKAGE__; - if ($ctx->{env}->{'pi-httpd.async'}) { + if ($ctx->{env}->{'pi-httpd.app'}) { $ctx->event_step; return; } diff --git a/lib/PublicInbox/GzipFilter.pm b/lib/PublicInbox/GzipFilter.pm index 2d164a4bf..386f7b6b3 100644 --- a/lib/PublicInbox/GzipFilter.pm +++ b/lib/PublicInbox/GzipFilter.pm @@ -31,7 +31,7 @@ my @GZIP_HDRS = qw(Vary Accept-Encoding Content-Encoding gzip); sub new { bless {}, shift } # qspawn filter -# for Qspawn if using $env->{'pi-httpd.async'} +# for Qspawn if using $env->{'pi-httpd.client'} sub attach { my ($self, $http_out) = @_; $self->{http_out} = $http_out; # PublicInbox::HTTP::{Chunked,Identity} @@ -54,8 +54,7 @@ sub gzf_maybe ($$) { bless { gz => gz_or_noop(@_) }, __PACKAGE__ } sub psgi_response { # $code may be an HTTP response code (e.g. 200) or a CODE ref (mbox_hdr) my ($self, $code, $res_hdr) = @_; - if ($self->{env}->{'pi-httpd.async'}) { - my $http = $self->{env}->{'psgix.io'}; # PublicInbox::HTTP + if (my $http = $self->{env}->{'pi-httpd.client'}) { $http->{forward} = $self; sub { my ($wcb) = @_; # -httpd provided write callback @@ -98,7 +97,7 @@ sub gone { # what: search/over/mm undef; } -# for GetlineResponse (via Qspawn) when NOT using $env->{'pi-httpd.async'} +# for GetlineResponse (via Qspawn) when NOT using $env->{'pi-httpd.client'} # Also used for ->getline callbacks sub translate { my $self = shift; # $_[1] => input @@ -181,7 +180,7 @@ sub bail { my $self = shift; carp @_; my $env = $self->{env} or return; - my $http = $env->{'psgix.io'} or return; # client abort + my $http = $env->{'pi-httpd.client'} or return; # client abort eval { $http->close }; # should hit our close carp "E: error in http->close: $@" if $@; eval { $self->close }; # just in case... @@ -191,7 +190,7 @@ sub bail { # this is public-inbox-httpd-specific sub async_blob_cb { # git->cat_async callback my ($bref, $oid, $type, $size, $self) = @_; - my $http = $self->{env}->{'psgix.io'}; # PublicInbox::HTTP + my $http = $self->{env}->{'pi-httpd.client'}; # PublicInbox::HTTP $http->{forward} or return; # client aborted my $smsg = $self->{smsg} or return bail($self, 'BUG: no smsg'); $type // return diff --git a/lib/PublicInbox/HTTP.pm b/lib/PublicInbox/HTTP.pm index 407f476b3..01a686a4d 100644 --- a/lib/PublicInbox/HTTP.pm +++ b/lib/PublicInbox/HTTP.pm @@ -157,7 +157,8 @@ sub app_dispatch { sysseek($input, 0, SEEK_SET) if defined $input; # note: NOT $self->{sock}, we want our close (+ PublicInbox::DS::close), # to do proper cleanup: - $env->{'psgix.io'} = $self; # for ->close or async_pass + $env->{'psgix.io'} = $self->{sock}; # for pi-httpd.ckhup + $env->{'pi-httpd.client'} = $self; # for ->close or async_pass my $res = Plack::Util::run_app($env->{'pi-httpd.app'}, $env); eval { if (ref($res) eq 'CODE') { diff --git a/lib/PublicInbox/HTTPD.pm b/lib/PublicInbox/HTTPD.pm index 55d728cbd..68ffaebe9 100644 --- a/lib/PublicInbox/HTTPD.pm +++ b/lib/PublicInbox/HTTPD.pm @@ -42,7 +42,7 @@ sub env_for ($$$) { # this to limit git-http-backend(1) parallelism. # We also check for the truthiness of this to # detect when to use async paths for slow blobs - 'pi-httpd.async' => 1, + # 'pi-httpd.client' => PublicInbox::HTTP object 'pi-httpd.app' => $self->{app}, 'pi-httpd.warn_cb' => $self->{warn_cb}, 'pi-httpd.ckhup' => $port ? \&PublicInbox::Daemon::tcp_hup : diff --git a/lib/PublicInbox/Limiter.pm b/lib/PublicInbox/Limiter.pm index f90c8b568..27a7015cf 100644 --- a/lib/PublicInbox/Limiter.pm +++ b/lib/PublicInbox/Limiter.pm @@ -81,7 +81,7 @@ sub _start_next { # on_destroy cb $rec = shift @{$self->{run_queue}} or return; ($start_cb, $ctx, $fail_cb) = @$rec; $ck = $ctx->{env}->{'pi-httpd.ckhup'} or last; - $ck->($ctx->{env}->{'psgix.io'}->{sock}) or last; + $ck->($ctx->{env}->{'psgix.io'}) or last; $fail_cb->($ctx, 499, 'client disconnected'); } _do_start $self, $start_cb, $ctx, $fail_cb; diff --git a/lib/PublicInbox/MailDiff.pm b/lib/PublicInbox/MailDiff.pm index ce268bfb7..a0e281c5e 100644 --- a/lib/PublicInbox/MailDiff.pm +++ b/lib/PublicInbox/MailDiff.pm @@ -60,7 +60,7 @@ sub next_smsg ($) { $ctx->write('', $ctx->_html_end); return $ctx->close; } - PublicInbox::DS::requeue($self) if $ctx->{env}->{'pi-httpd.async'}; + PublicInbox::DS::requeue($self) if $ctx->{env}->{'pi-httpd.app'}; } sub emit_msg_diff { @@ -112,7 +112,7 @@ sub event_step { my ($self) = @_; eval { my $ctx = $self->{ctx}; - if ($ctx->{env}->{'pi-httpd.async'}) { + if ($ctx->{env}->{'pi-httpd.app'}) { ibx_async_cat($ctx->{ibx}, $self->{smsg}->{blob}, \&diff_msg_i_async, $self); } else { @@ -128,7 +128,7 @@ sub event_step { sub begin_mail_diff { my ($self) = @_; - if ($self->{ctx}->{env}->{'pi-httpd.async'}) { + if ($self->{ctx}->{env}->{'pi-httpd.app'}) { PublicInbox::DS::requeue($self); } else { event_step($self) while $self->{smsg}; diff --git a/lib/PublicInbox/ManifestJsGz.pm b/lib/PublicInbox/ManifestJsGz.pm index f912f8123..ca37c1ad3 100644 --- a/lib/PublicInbox/ManifestJsGz.pm +++ b/lib/PublicInbox/ManifestJsGz.pm @@ -83,7 +83,7 @@ sub response { sub { $ctx->{-wcb} = $_[0]; # HTTP server callback ($ctx->{www}->{pi_cfg}->ALL || - !$ctx->{env}->{'pi-httpd.async'}) ? + !$ctx->{env}->{'pi-httpd.app'}) ? $iter->each_section : $iter->event_step; } } diff --git a/lib/PublicInbox/Qspawn.pm b/lib/PublicInbox/Qspawn.pm index bd8cd35b0..64a11cab1 100644 --- a/lib/PublicInbox/Qspawn.pm +++ b/lib/PublicInbox/Qspawn.pm @@ -234,7 +234,7 @@ sub istream_cb { # InputStream callback sub _yield_start { # may run later, much later... my ($self) = @_; - if ($self->{env}->{'pi-httpd.async'}) { + if ($self->{env}->{'pi-httpd.app'}) { my $rpipe = $self->{rpipe}; PublicInbox::InputStream::consume($rpipe, \&istream_cb, $self); } else { @@ -254,7 +254,7 @@ sub _yield_start { # may run later, much later... # sub for the PSGI server to call # # $env->{'qspawn.filter'} - filter object, responds to ->attach for -# pi-httpd.async and ->translate for generic +# pi-httpd.client and ->translate for generic # PSGI servers # # $limiter - the Limiter object to use (uses the def_limiter if not given) @@ -264,7 +264,7 @@ sub _yield_start { # may run later, much later... # and a string ref of the current buffer. Returns an arrayref # for PSGI responses. 2-element arrays in PSGI mean the # body will be streamed, later, via writes (push-based) to -# psgix.io. 3-element arrays means the body is available +# pi-httpd.client. 3-element arrays means the body is available # immediately (or streamed via ->getline (pull-based)). sub psgi_yield { diff --git a/lib/PublicInbox/SolverGit.pm b/lib/PublicInbox/SolverGit.pm index a17e15422..cca1a5169 100644 --- a/lib/PublicInbox/SolverGit.pm +++ b/lib/PublicInbox/SolverGit.pm @@ -175,7 +175,7 @@ sub solve_existing ($$) { my $try = $want->{try_gits} //= [ @{$self->{gits}} ]; # array copy my $git = $try->[0] // die 'BUG {try_gits} empty'; - if ($self->{psgi_env}->{'pi-httpd.async'}) { + if ($self->{psgi_env}->{'pi-httpd.app'}) { async_check({ git => $git }, $want->{oid_b}, \&ck_existing_cb, [ $self, $want ]); $git->schedule_cleanup; @@ -396,7 +396,7 @@ sub do_finish ($) { # let git disambiguate if oid_want was too short, # but long enough to be unambiguous: - if ($self->{psgi_env}->{'pi-httpd.async'}) { + if ($self->{psgi_env}->{'pi-httpd.app'}) { async_check { git => $self->{tmp_git} }, $oid_want, \&finish_cb, $self } else { @@ -451,7 +451,7 @@ sub event_step ($) { sub next_step ($) { # if outside of public-inbox-httpd, caller is expected to be # looping event_step, anyways - PublicInbox::DS::requeue($_[0]) if $_[0]->{psgi_env}->{'pi-httpd.async'} + PublicInbox::DS::requeue($_[0]) if $_[0]->{psgi_env}->{'pi-httpd.app'} } sub mark_found ($$$) { @@ -495,7 +495,7 @@ sub parse_ls_files ($$) { dbg($self, "index at:\n$mode_b $oid_b_full\t".git_quote($file)); my $tmp_git = $self->{tmp_git} or die 'no git working tree'; - if ($self->{psgi_env}->{'pi-httpd.async'}) { + if ($self->{psgi_env}->{'pi-httpd.app'}) { async_check { git => $tmp_git }, $oid_b_full, \&ck_size_cb, $self } else { @@ -678,7 +678,7 @@ sub resolve_patch ($$) { if (my $msgs = $want->{try_smsgs}) { my $smsg = shift @$msgs; - if ($self->{psgi_env}->{'pi-httpd.async'}) { + if ($self->{psgi_env}->{'pi-httpd.app'}) { return ibx_async_cat($want->{cur_ibx}, $smsg->{blob}, \&extract_diff_async, [$self, $want, $smsg]); @@ -744,7 +744,7 @@ sub solve ($$$$$) { $self->{found} = {}; # { abbr => [ ::Git, oid, type, size, $di ] } dbg($self, "solving $oid_want ..."); - if ($env->{'pi-httpd.async'}) { + if ($env->{'pi-httpd.app'}) { PublicInbox::DS::requeue($self); } else { event_step($self) while $self->{user_cb}; diff --git a/lib/PublicInbox/ViewVCS.pm b/lib/PublicInbox/ViewVCS.pm index 3ad279a72..76986f68c 100644 --- a/lib/PublicInbox/ViewVCS.pm +++ b/lib/PublicInbox/ViewVCS.pm @@ -134,7 +134,7 @@ sub do_cat_async { # favor git(1) over Lg2 (libgit2) for SHA-256 support my $ctx = ref $arg eq 'ARRAY' ? $arg->[0] : $arg; $ctx->{git}->cat_async($_, $cb, $arg) for @req; - if ($ctx->{env}->{'pi-httpd.async'}) { + if ($ctx->{env}->{'pi-httpd.app'}) { $ctx->{git}->watch_async; } else { # synchronous, generic PSGI $ctx->{git}->cat_async_wait; @@ -143,7 +143,7 @@ sub do_cat_async { sub do_check_async { my ($ctx, $cb, @req) = @_; - if ($ctx->{env}->{'pi-httpd.async'}) { + if ($ctx->{env}->{'pi-httpd.app'}) { async_check($ctx, $_, $cb, $ctx) for @req; } else { # synchronous, generic PSGI $ctx->{git}->check_async($_, $cb, $ctx) for @req; diff --git a/lib/PublicInbox/WWW.pm b/lib/PublicInbox/WWW.pm index 50f182af1..31099f09c 100644 --- a/lib/PublicInbox/WWW.pm +++ b/lib/PublicInbox/WWW.pm @@ -774,7 +774,7 @@ sub event_step { # called via requeue # gzf = PublicInbox::GzipFilter == $ctx my $gzf = shift(@{$self->{-low_prio_q}}) // return; PublicInbox::DS::requeue($self) if scalar(@{$self->{-low_prio_q}}); - my $http = $gzf->{env}->{'psgix.io'}; # PublicInbox::HTTP + my $http = $gzf->{env}->{'pi-httpd.client'}; # PublicInbox::HTTP $http->next_step($gzf->can('async_next')); } diff --git a/lib/PublicInbox/WwwAttach.pm b/lib/PublicInbox/WwwAttach.pm index d297ce7ac..f93f32b05 100644 --- a/lib/PublicInbox/WwwAttach.pm +++ b/lib/PublicInbox/WwwAttach.pm @@ -78,7 +78,7 @@ sub async_next { sub scan_attach ($) { # public-inbox-httpd only my ($ctx) = @_; - $ctx->{env}->{'psgix.io'}->{forward} = $ctx; + $ctx->{env}->{'pi-httpd.client'}->{forward} = $ctx; $ctx->smsg_blob($ctx->{smsg}); } @@ -94,7 +94,7 @@ sub get_attach ($$$) { return sub { # public-inbox-httpd-only $ctx->{wcb} = $_[0]; scan_attach($ctx); - } if $ctx->{env}->{'pi-httpd.async'}; + } if $ctx->{env}->{'pi-httpd.app'}; # generic PSGI: $eml = $ctx->{ibx}->smsg_eml($ctx->{smsg}); } elsif (!$ctx->{ibx}->over) { diff --git a/lib/PublicInbox/WwwListing.pm b/lib/PublicInbox/WwwListing.pm index 101da9b72..59b474193 100644 --- a/lib/PublicInbox/WwwListing.pm +++ b/lib/PublicInbox/WwwListing.pm @@ -156,7 +156,7 @@ sub response { \&list_match_i, $re, $ctx); sub { $ctx->{-wcb} = $_[0]; # HTTP server callback - $ctx->{env}->{'pi-httpd.async'} ? + $ctx->{env}->{'pi-httpd.app'} ? $iter->event_step : $iter->each_section; } } diff --git a/lib/PublicInbox/WwwStatic.pm b/lib/PublicInbox/WwwStatic.pm index 37f95a11a..68d11f756 100644 --- a/lib/PublicInbox/WwwStatic.pm +++ b/lib/PublicInbox/WwwStatic.pm @@ -55,9 +55,9 @@ sub r ($;$) { sub getline_response ($$$$$) { my ($env, $in, $off, $len, $path) = @_; my $r = bless {}, __PACKAGE__; - if ($env->{'pi-httpd.async'}) { # public-inbox-httpd-only mode + if (my $http = $env->{'pi-httpd.client'}) { # public-inbox-only mode $env->{'psgix.no-compress'} = 1; # do not chunk response - %$r = ( bypass => [$in, $off, $len, $env->{'psgix.io'}] ); + %$r = ( bypass => [$in, $off, $len, $http] ); } else { %$r = ( in => $in, off => $off, len => $len, path => $path ); } diff --git a/t/httpd-corner.psgi b/t/httpd-corner.psgi index 0dd840a01..b38ffd56e 100644 --- a/t/httpd-corner.psgi +++ b/t/httpd-corner.psgi @@ -81,8 +81,8 @@ my $app = sub { $code = 200; push @$body, "$env->{REMOTE_ADDR} $env->{REMOTE_PORT}"; } elsif ($path eq '/session_reused') { - my $http = $env->{'psgix.io'}; # PublicInbox::HTTP - $body = [ $http->{sock}->get_session_reused ? "y\n" : "n\n" ]; + my $sock = $env->{'psgix.io'}; # IO::Socket::SSL + $body = [ $sock->get_session_reused ? "y\n" : "n\n" ]; $code = 200; } elsif ($path eq '/callback') { return sub {