1 # Copyright (C) 2016-2021 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
11 my $path = $env->{PATH_INFO};
12 my $in = $env->{'psgi.input'};
15 my $h = [ 'Content-Type' => 'text/plain' ];
17 if ($path eq '/sha1') {
18 my $sha1 = Digest::SHA->new('SHA-1');
21 my $r = $in->read($buf, 4096);
22 die "read err: $!" unless defined $r;
27 push @$body, $sha1->hexdigest;
28 } elsif (my $fifo = $env->{HTTP_X_CHECK_FIFO}) {
29 if ($path eq '/slow-header') {
31 open my $f, '<', $fifo or
32 die "open $fifo: $!\n";
35 $_[0]->([200, $h, \@r ]);
37 } elsif ($path eq '/slow-body') {
39 my $fh = $_[0]->([200, $h]);
40 open my $f, '<', $fifo or
41 die "open $fifo: $!\n";
43 while (defined(my $l = <$f>)) {
49 } elsif ($path eq '/host-port') {
51 push @$body, "$env->{REMOTE_ADDR} $env->{REMOTE_PORT}";
52 } elsif ($path eq '/callback') {
55 my $buf = "hello world\n";
56 push @$h, 'Content-Length', length($buf);
57 my $fh = $res->([200, $h]);
61 } elsif ($path eq '/empty') {
63 } elsif ($path eq '/getline-die') {
65 $body = Plack::Util::inline_object(
66 getline => sub { die 'GETLINE FAIL' },
67 close => sub { die 'CLOSE FAIL' },
69 } elsif ($path eq '/close-die') {
71 $body = Plack::Util::inline_object(
72 getline => sub { undef },
73 close => sub { die 'CLOSE FAIL' },
75 } elsif ($path eq '/async-big') {
76 require PublicInbox::Qspawn;
77 open my $null, '>', '/dev/null' or die;
78 my $rdr = { 2 => fileno($null) };
79 my $cmd = [qw(dd if=/dev/zero count=30 bs=1024k)];
80 my $qsp = PublicInbox::Qspawn->new($cmd, undef, $rdr);
81 return $qsp->psgi_return($env, undef, sub {
83 # make $rd_hdr retry sysread + $parse_hdr in Qspawn:
84 return until length($$bref) > 8000;
86 [ 200, [ qw(Content-Type application/octet-stream) ]];
88 } elsif ($path eq '/psgi-return-gzip') {
89 require PublicInbox::Qspawn;
90 require PublicInbox::GzipFilter;
91 my $cmd = [qw(echo hello world)];
92 my $qsp = PublicInbox::Qspawn->new($cmd);
93 $env->{'qspawn.filter'} = PublicInbox::GzipFilter->new;
94 return $qsp->psgi_return($env, undef, sub {
95 [ 200, [ qw(Content-Type application/octet-stream)]]
97 } elsif ($path eq '/psgi-return-compressible') {
98 require PublicInbox::Qspawn;
99 my $cmd = [qw(echo goodbye world)];
100 my $qsp = PublicInbox::Qspawn->new($cmd);
101 return $qsp->psgi_return($env, undef, sub {
102 [200, [qw(Content-Type text/plain)]]
104 } elsif ($path eq '/psgi-return-enoent') {
105 require PublicInbox::Qspawn;
106 my $cmd = [ 'this-better-not-exist-in-PATH'.rand ];
107 my $qsp = PublicInbox::Qspawn->new($cmd);
108 return $qsp->psgi_return($env, undef, sub {
109 [ 200, [ qw(Content-Type application/octet-stream)]]
111 } elsif ($path eq '/pid') {
120 enable 'ContentLength';