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
7 require PublicInbox::SHA;
8 if (defined(my $f = $ENV{TEST_OPEN_FIFO})) {
9 open my $fh, '>', $f or die "open($f): $!";
15 if (defined(my $f = $ENV{TEST_EXIT_FIFO})) {
16 open my $fh, '>', $f or die "open($f): $!";
17 say $fh "bye from $$";
22 my $pi_config = $ENV{PI_CONFIG} // 'unset'; # capture ASAP
25 my $path = $env->{PATH_INFO};
26 my $in = $env->{'psgi.input'};
29 my $h = [ 'Content-Type' => 'text/plain' ];
31 if ($path eq '/sha1') {
32 my $sha1 = PublicInbox::SHA->new(1);
35 my $r = $in->read($buf, 4096);
36 die "read err: $!" unless defined $r;
41 push @$body, $sha1->hexdigest;
42 } elsif (my $fifo = $env->{HTTP_X_CHECK_FIFO}) {
43 if ($path eq '/slow-header') {
45 open my $f, '<', $fifo or
46 die "open $fifo: $!\n";
49 $_[0]->([200, $h, \@r ]);
51 } elsif ($path eq '/slow-body') {
53 my $fh = $_[0]->([200, $h]);
54 open my $f, '<', $fifo or
55 die "open $fifo: $!\n";
57 while (defined(my $l = <$f>)) {
63 } elsif ($path eq '/host-port') {
65 push @$body, "$env->{REMOTE_ADDR} $env->{REMOTE_PORT}";
66 } elsif ($path eq '/callback') {
69 my $buf = "hello world\n";
70 push @$h, 'Content-Length', length($buf);
71 my $fh = $res->([200, $h]);
75 } elsif ($path eq '/empty') {
77 } elsif ($path eq '/getline-die') {
79 $body = Plack::Util::inline_object(
80 getline => sub { die 'GETLINE FAIL' },
81 close => sub { die 'CLOSE FAIL' },
83 } elsif ($path eq '/close-die') {
85 $body = Plack::Util::inline_object(
86 getline => sub { undef },
87 close => sub { die 'CLOSE FAIL' },
89 } elsif ($path eq '/async-big') {
90 require PublicInbox::Qspawn;
91 open my $null, '>', '/dev/null' or die;
92 my $rdr = { 2 => fileno($null) };
93 my $cmd = [qw(dd if=/dev/zero count=30 bs=1024k)];
94 my $qsp = PublicInbox::Qspawn->new($cmd, undef, $rdr);
95 return $qsp->psgi_yield($env, undef, sub {
97 # make $rd_hdr retry sysread + $parse_hdr in Qspawn:
98 return until length($$bref) > 8000;
100 [ 200, [ qw(Content-Type application/octet-stream) ]];
102 } elsif ($path eq '/psgi-yield-gzip') {
103 require PublicInbox::Qspawn;
104 require PublicInbox::GzipFilter;
105 my $cmd = [qw(echo hello world)];
106 my $qsp = PublicInbox::Qspawn->new($cmd);
107 $env->{'qspawn.filter'} = PublicInbox::GzipFilter->new;
108 return $qsp->psgi_yield($env, undef, sub {
109 [ 200, [ qw(Content-Type application/octet-stream)]]
111 } elsif ($path eq '/psgi-yield-compressible') {
112 require PublicInbox::Qspawn;
113 my $cmd = [qw(echo goodbye world)];
114 my $qsp = PublicInbox::Qspawn->new($cmd);
115 return $qsp->psgi_yield($env, undef, sub {
116 [200, [qw(Content-Type text/plain)]]
118 } elsif ($path eq '/psgi-yield-enoent') {
119 require PublicInbox::Qspawn;
120 my $cmd = [ 'this-better-not-exist-in-PATH'.rand ];
121 my $qsp = PublicInbox::Qspawn->new($cmd);
122 return $qsp->psgi_yield($env, undef, sub {
123 [ 200, [ qw(Content-Type application/octet-stream)]]
125 } elsif ($path eq '/pid') {
128 } elsif ($path eq '/url_scheme') {
130 push @$body, $env->{'psgi.url_scheme'}
131 } elsif ($path eq '/PI_CONFIG') {
133 push @$body, $pi_config; # show value at ->refresh_groups
134 } elsif ($path =~ m!\A/exit-fifo(.+)\z!) {
136 $ENV{TEST_EXIT_FIFO} = $1; # for END {}
137 push @$body, "fifo $1 registered";
143 enable 'ContentLength';