h2o/t/50fastcgi.t
2023-04-25 09:13:29 +09:00

141 lines
4.6 KiB
Perl

use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use File::Temp qw(tempdir);
use Net::EmptyPort qw(check_port);
use Test::More;
use t::Util;
plan skip_all => 'curl not found'
unless prog_exists('curl');
plan skip_all => 'plackup not found'
unless prog_exists('plackup');
plan skip_all => 'cannot run perl -MPlack::Handler::FCGI'
if system("perl -MPlack::Handler::FCGI /dev/null > /dev/null 2>&1") != 0;
my $tempdir = tempdir(CLEANUP => 1);
my $fcgi_port = empty_port();
# gather information of test data
my %files = map { do {
my $fn = DOC_ROOT . "/$_";
+($_ => { size => (stat $fn)[7], md5 => md5_file($fn) });
} } qw(index.txt halfdome.jpg);
sub doit {
my ($tcp, $keepalive) = @_;
subtest "tcp:$tcp,keepalive:$keepalive" => sub {
# spawn upstream
unlink "$tempdir/fcgi.sock";
my $upstream = spawn_server(
argv => [
qw(plackup -s FCGI --access-log /dev/null --listen),
($tcp ? "127.0.0.1:$fcgi_port" : "$tempdir/fcgi.sock"),
ASSETS_DIR . "/upstream.psgi",
],
is_ready => sub {
$tcp ? check_port($fcgi_port) : -e "$tempdir/fcgi.sock";
},
);
# spawn h2o
my $server = spawn_h2o(<< "EOT");
hosts:
default:
paths:
"/":
fastcgi.connect:
@{[$tcp ? "host: 127.0.0.1" : ""]}
port: @{[$tcp ? $fcgi_port : "$tempdir/fcgi.sock"]}
type: @{[$tcp ? "tcp" : "unix"]}
fastcgi.timeout.keepalive: @{[$keepalive ? 5000 : 0]}
EOT
# the tests
subtest 'files' => sub {
run_with_curl($server, sub {
my ($proto, $port, $curl) = @_;
for my $file (sort keys %files) {
my $content = `$curl --silent --show-error $proto://127.0.0.1:$port/$file`;
is length($content), $files{$file}->{size}, "$proto://127.0.0.1/$file (size)";
is md5_hex($content), $files{$file}->{md5}, "$proto://127.0.0.1/$file (md5)";
}
});
};
subtest 'echo' => sub {
# send header that exceeds the max. length fcgi record (the size of the response also exceeds the record size, and uses chunked encoding)
run_with_curl($server, sub {
my ($proto, $port, $curl) = @_;
plan skip_all => "skip due to curl bug #659"
if $curl =~ /--http2/;
my $content = `$curl --silent --show-error -H foo:@{["0123456789"x7000]} $proto://127.0.0.1:$port/echo-headers`;
like $content, qr/^foo: (0123456789){7000,7000}$/mi;
if ($proto eq 'https') {
like $content, qr/^https: on$/m;
} else {
unlike $content, qr/^https: on$/m;
}
});
};
subtest 'cookie-merge' => sub {
plan skip_all => "curl does not support HTTP/2"
unless curl_supports_http2();
plan skip_all => "cowardly skipping to avoid https://github.com/plack/Plack/pull/511; unless PLACK_ENV=deployment is set"
unless $ENV{PLACK_ENV} && $ENV{PLACK_ENV} eq 'deployment';
my $content = `curl --http2 --silent --show-error --insecure -H "cookie:a=b;c=d" https://127.0.0.1:$server->{tls_port}/echo-headers`;
like $content, qr/^cookie: a=b;\s*c=d$/mi;
};
delete $server->{guard};
};
}
doit(0, 0);
doit(1, 0);
doit(0, 1);
doit(1, 1);
# see https://httpoxy.org
subtest 'httpoxy' => sub {
my $doit = sub {
my ($drop, $cb) = @_;
unlink "$tempdir/fcgi.sock";
my $upstream = spawn_server(
argv => [
qw(plackup -s FCGI --access-log /dev/null --listen),
"$tempdir/fcgi.sock",
ASSETS_DIR . "/upstream.psgi",
],
is_ready => sub {
-e "$tempdir/fcgi.sock";
},
);
# spawn h2o
my $dropconf = $drop ? << 'EOT' : "";
setenv:
HTTP_PROXY: ""
EOT
my $server = spawn_h2o(<< "EOT");
hosts:
default:
paths:
"/":
fastcgi.connect:
port: $tempdir/fcgi.sock
type: unix
$dropconf
EOT
run_with_curl($server, sub {
my ($proto, $port, $curl) = @_;
my $content = `$curl --silent --show-error -H proxy:foobar $proto://127.0.0.1:$port/echo-headers`;
$cb->($content);
});
};
$doit->(undef, sub {
like $_[0], qr{^proxy: foobar$}mi, "keep";
});
$doit->(1, sub {
like $_[0], qr{^proxy: $}mi, "drop";
});
};
done_testing();