1 # Copyright (C) all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3 # corner case tests for the generic PSGI server
4 # Usage: plackup [OPTIONS] /path/to/this/file
9 my $pi_config = $ENV{PI_CONFIG} // 'unset'; # capture ASAP
12 my $path = $env->{PATH_INFO};
13 my $in = $env->{'psgi.input'};
16 my $h = [ 'Content-Type' => 'text/plain' ];
18 if ($path eq '/sha1') {
19 my $sha1 = Digest::SHA->new('SHA-1');
22 my $r = $in->read($buf, 4096);
23 die "read err: $!" unless defined $r;
28 push @$body, $sha1->hexdigest;
29 } elsif (my $fifo = $env->{HTTP_X_CHECK_FIFO}) {
30 if ($path eq '/slow-header') {
32 open my $f, '<', $fifo or
33 die "open $fifo: $!\n";
36 $_[0]->([200, $h, \@r ]);
38 } elsif ($path eq '/slow-body') {
40 my $fh = $_[0]->([200, $h]);
41 open my $f, '<', $fifo or
42 die "open $fifo: $!\n";
44 while (defined(my $l = <$f>)) {
50 } elsif ($path eq '/host-port') {
52 push @$body, "$env->{REMOTE_ADDR} $env->{REMOTE_PORT}";
53 } elsif ($path eq '/callback') {
56 my $buf = "hello world\n";
57 push @$h, 'Content-Length', length($buf);
58 my $fh = $res->([200, $h]);
62 } elsif ($path eq '/empty') {
64 } elsif ($path eq '/getline-die') {
66 $body = Plack::Util::inline_object(
67 getline => sub { die 'GETLINE FAIL' },
68 close => sub { die 'CLOSE FAIL' },
70 } elsif ($path eq '/close-die') {
72 $body = Plack::Util::inline_object(
73 getline => sub { undef },
74 close => sub { die 'CLOSE FAIL' },
76 } elsif ($path eq '/async-big') {
77 require PublicInbox::Qspawn;
78 open my $null, '>', '/dev/null' or die;
79 my $rdr = { 2 => fileno($null) };
80 my $cmd = [qw(dd if=/dev/zero count=30 bs=1024k)];
81 my $qsp = PublicInbox::Qspawn->new($cmd, undef, $rdr);
82 return $qsp->psgi_return($env, undef, sub {
84 # make $rd_hdr retry sysread + $parse_hdr in Qspawn:
85 return until length($$bref) > 8000;
87 [ 200, [ qw(Content-Type application/octet-stream) ]];
89 } elsif ($path eq '/psgi-return-gzip') {
90 require PublicInbox::Qspawn;
91 require PublicInbox::GzipFilter;
92 my $cmd = [qw(echo hello world)];
93 my $qsp = PublicInbox::Qspawn->new($cmd);
94 $env->{'qspawn.filter'} = PublicInbox::GzipFilter->new;
95 return $qsp->psgi_return($env, undef, sub {
96 [ 200, [ qw(Content-Type application/octet-stream)]]
98 } elsif ($path eq '/psgi-return-compressible') {
99 require PublicInbox::Qspawn;
100 my $cmd = [qw(echo goodbye world)];
101 my $qsp = PublicInbox::Qspawn->new($cmd);
102 return $qsp->psgi_return($env, undef, sub {
103 [200, [qw(Content-Type text/plain)]]
105 } elsif ($path eq '/psgi-return-enoent') {
106 require PublicInbox::Qspawn;
107 my $cmd = [ 'this-better-not-exist-in-PATH'.rand ];
108 my $qsp = PublicInbox::Qspawn->new($cmd);
109 return $qsp->psgi_return($env, undef, sub {
110 [ 200, [ qw(Content-Type application/octet-stream)]]
112 } elsif ($path eq '/pid') {
115 } elsif ($path eq '/url_scheme') {
117 push @$body, $env->{'psgi.url_scheme'}
118 } elsif ($path eq '/PI_CONFIG') {
120 push @$body, $pi_config; # show value at ->refresh_groups
126 enable 'ContentLength';