tests: add HTTP UNIX socket server testing support

The variable `$ipvnum` can now contain "unix" besides the integers 4
and 6 since the variable. Functions which receive this parameter
have their `$port` parameter renamed to `$port_or_path` to support a
path to the UNIX domain socket (as a "port" is only meaningful for TCP).

Signed-off-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
Peter Wu 2014-11-27 23:59:23 +01:00 committed by Daniel Stenberg
parent 99fb36797a
commit f1cc2a2c0c
5 changed files with 106 additions and 16 deletions

View File

@ -177,6 +177,7 @@ ftps
http http
http-ipv6 http-ipv6
http-proxy http-proxy
http-unix
https https
httptls+srp httptls+srp
httptls+srp-ipv6 httptls+srp-ipv6
@ -229,6 +230,7 @@ SSPI
GSS-API GSS-API
Kerberos Kerberos
SPNEGO SPNEGO
unix-sockets
as well as each protocol that curl supports. A protocol only needs to be as well as each protocol that curl supports. A protocol only needs to be
specified if it is different from the server (useful when the server specified if it is different from the server (useful when the server
@ -331,6 +333,7 @@ Available substitute variables include:
%HOSTIP - IPv4 address of the host running this test %HOSTIP - IPv4 address of the host running this test
%HTTP6PORT - IPv6 port number of the HTTP server %HTTP6PORT - IPv6 port number of the HTTP server
%HTTPPIPEPORT - Port number of the HTTP pipelining server %HTTPPIPEPORT - Port number of the HTTP pipelining server
%HTTPUNIXPATH - Path to the UNIX socket of the HTTP server
%HTTPPORT - Port number of the HTTP server %HTTPPORT - Port number of the HTTP server
%HTTPSPORT - Port number of the HTTPS server %HTTPSPORT - Port number of the HTTPS server
%HTTPTLS6PORT - IPv6 port number of the HTTP TLS server %HTTPTLS6PORT - IPv6 port number of the HTTP TLS server

View File

@ -81,6 +81,9 @@ The cURL Test Suite
machine, or just move the servers in case you have local services on any of machine, or just move the servers in case you have local services on any of
those ports. those ports.
The HTTP server supports listening on a UNIX domain socket, the default
location is 'http.sock'.
1.4 Run 1.4 Run
'make test'. This builds the test suite support code and invokes the 'make test'. This builds the test suite support code and invokes the

View File

@ -36,6 +36,7 @@ use serverhelp qw(
my $verbose = 0; # set to 1 for debugging my $verbose = 0; # set to 1 for debugging
my $port = 8990; # just a default my $port = 8990; # just a default
my $unix_socket; # location to place a listening UNIX socket
my $ipvnum = 4; # default IP version of http server my $ipvnum = 4; # default IP version of http server
my $idnum = 1; # dafault http server instance number my $idnum = 1; # dafault http server instance number
my $proto = 'http'; # protocol the http server speaks my $proto = 'http'; # protocol the http server speaks
@ -74,6 +75,13 @@ while(@ARGV) {
elsif($ARGV[0] eq '--ipv6') { elsif($ARGV[0] eq '--ipv6') {
$ipvnum = 6; $ipvnum = 6;
} }
elsif($ARGV[0] eq '--unix-socket') {
$ipvnum = 'unix';
if($ARGV[1]) {
$unix_socket = $ARGV[1];
shift @ARGV;
}
}
elsif($ARGV[0] eq '--gopher') { elsif($ARGV[0] eq '--gopher') {
$gopher = 1; $gopher = 1;
} }
@ -117,7 +125,12 @@ if(!$logfile) {
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" "; $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
$flags .= "--gopher " if($gopher); $flags .= "--gopher " if($gopher);
$flags .= "--connect $connect " if($connect); $flags .= "--connect $connect " if($connect);
$flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\""; if($ipvnum eq 'unix') {
$flags .= "--unix-socket '$unix_socket' ";
} else {
$flags .= "--ipv$ipvnum --port $port ";
}
$flags .= "--srcdir \"$srcdir\"";
if($verbose) { if($verbose) {
print STDERR "RUN: server/sws $flags\n"; print STDERR "RUN: server/sws $flags\n";

View File

@ -141,6 +141,7 @@ my $HTTPTLSPORT; # HTTP TLS (non-stunnel) server port
my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port my $HTTPTLS6PORT; # HTTP TLS (non-stunnel) IPv6 server port
my $HTTPPROXYPORT; # HTTP proxy port, when using CONNECT my $HTTPPROXYPORT; # HTTP proxy port, when using CONNECT
my $HTTPPIPEPORT; # HTTP pipelining port my $HTTPPIPEPORT; # HTTP pipelining port
my $HTTPUNIXPATH; # HTTP server UNIX domain socket path
my $srcdir = $ENV{'srcdir'} || '.'; my $srcdir = $ENV{'srcdir'} || '.';
my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
@ -202,10 +203,12 @@ my $ssl_version; # set if libcurl is built with SSL support
my $large_file; # set if libcurl is built with large file support my $large_file; # set if libcurl is built with large file support
my $has_idn; # set if libcurl is built with IDN support my $has_idn; # set if libcurl is built with IDN support
my $http_ipv6; # set if HTTP server has IPv6 support my $http_ipv6; # set if HTTP server has IPv6 support
my $http_unix; # set if HTTP server has UNIX sockets support
my $ftp_ipv6; # set if FTP server has IPv6 support my $ftp_ipv6; # set if FTP server has IPv6 support
my $tftp_ipv6; # set if TFTP server has IPv6 support my $tftp_ipv6; # set if TFTP server has IPv6 support
my $gopher_ipv6; # set if Gopher server has IPv6 support my $gopher_ipv6; # set if Gopher server has IPv6 support
my $has_ipv6; # set if libcurl is built with IPv6 support my $has_ipv6; # set if libcurl is built with IPv6 support
my $has_unix; # set if libcurl is built with UNIX sockets support
my $has_libz; # set if libcurl is built with libz support my $has_libz; # set if libcurl is built with libz support
my $has_getrlimit; # set if system has getrlimit() my $has_getrlimit; # set if system has getrlimit()
my $has_ntlm; # set if libcurl is built with NTLM support my $has_ntlm; # set if libcurl is built with NTLM support
@ -377,6 +380,13 @@ sub init_serverpidfile_hash {
} }
} }
} }
for my $proto (('http', 'imap', 'pop3', 'smtp')) {
for my $ssl (('', 's')) {
my $serv = servername_id("$proto$ssl", "unix", 1);
my $pidf = server_pidfilename("$proto$ssl", "unix", 1);
$serverpidfile{$serv} = $pidf;
}
}
} }
####################################################################### #######################################################################
@ -662,11 +672,11 @@ sub stopserver {
# All servers relative to the given one must be stopped also # All servers relative to the given one must be stopped also
# #
my @killservers; my @killservers;
if($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)s((\d*)(-ipv6|))$/) { if($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)s((\d*)(-ipv6|-unix|))$/) {
# given a stunnel based ssl server, also kill non-ssl underlying one # given a stunnel based ssl server, also kill non-ssl underlying one
push @killservers, "${1}${2}"; push @killservers, "${1}${2}";
} }
elsif($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)((\d*)(-ipv6|))$/) { elsif($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)((\d*)(-ipv6|-unix|))$/) {
# given a non-ssl server, also kill stunnel based ssl piggybacking one # given a non-ssl server, also kill stunnel based ssl piggybacking one
push @killservers, "${1}s${2}"; push @killservers, "${1}s${2}";
} }
@ -712,10 +722,12 @@ sub stopserver {
# assign requested address") # assign requested address")
# #
sub verifyhttp { sub verifyhttp {
my ($proto, $ipvnum, $idnum, $ip, $port) = @_; my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_;
my $server = servername_id($proto, $ipvnum, $idnum); my $server = servername_id($proto, $ipvnum, $idnum);
my $pid = 0; my $pid = 0;
my $bonus=""; my $bonus="";
# $port_or_path contains a path for UNIX sockets, sws ignores the port
my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
my $verifyout = "$LOGDIR/". my $verifyout = "$LOGDIR/".
servername_canon($proto, $ipvnum, $idnum) .'_verify.out'; servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
@ -735,6 +747,7 @@ sub verifyhttp {
$flags .= "--silent "; $flags .= "--silent ";
$flags .= "--verbose "; $flags .= "--verbose ";
$flags .= "--globoff "; $flags .= "--globoff ";
$flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
$flags .= "-1 " if($has_axtls); $flags .= "-1 " if($has_axtls);
$flags .= "--insecure " if($proto eq 'https'); $flags .= "--insecure " if($proto eq 'https');
$flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\""; $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
@ -1174,7 +1187,7 @@ sub responsiveserver {
# start the http server # start the http server
# #
sub runhttpserver { sub runhttpserver {
my ($proto, $verbose, $alt, $port) = @_; my ($proto, $verbose, $alt, $port_or_path) = @_;
my $ip = $HOSTIP; my $ip = $HOSTIP;
my $ipvnum = 4; my $ipvnum = 4;
my $idnum = 1; my $idnum = 1;
@ -1201,6 +1214,10 @@ sub runhttpserver {
$exe = "python $srcdir/http_pipe.py"; $exe = "python $srcdir/http_pipe.py";
$verbose_flag .= "1 "; $verbose_flag .= "1 ";
} }
elsif($alt eq "unix") {
# IP (protocol) is mutually exclusive with UNIX sockets
$ipvnum = "unix";
}
$server = servername_id($proto, $ipvnum, $idnum); $server = servername_id($proto, $ipvnum, $idnum);
@ -1226,7 +1243,12 @@ sub runhttpserver {
$flags .= $verbose_flag if($debugprotocol); $flags .= $verbose_flag if($debugprotocol);
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" "; $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
$flags .= "--id $idnum " if($idnum > 1); $flags .= "--id $idnum " if($idnum > 1);
$flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\""; if($ipvnum eq "unix") {
$flags .= "--unix-socket '$port_or_path' ";
} else {
$flags .= "--ipv$ipvnum --port $port_or_path ";
}
$flags .= "--srcdir \"$srcdir\"";
my $cmd = "$exe $flags"; my $cmd = "$exe $flags";
my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0); my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
@ -1241,7 +1263,7 @@ sub runhttpserver {
} }
# Server is up. Verify that we can speak to it. # Server is up. Verify that we can speak to it.
my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port); my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
if(!$pid3) { if(!$pid3) {
logmsg "RUN: $srvrname server failed verification\n"; logmsg "RUN: $srvrname server failed verification\n";
# failed to talk to it properly. Kill the server and return failure # failed to talk to it properly. Kill the server and return failure
@ -2082,7 +2104,7 @@ sub runsocksserver {
# be used to verify that a server present in %run hash is still functional # be used to verify that a server present in %run hash is still functional
# #
sub responsive_http_server { sub responsive_http_server {
my ($proto, $verbose, $alt, $port) = @_; my ($proto, $verbose, $alt, $port_or_path) = @_;
my $ip = $HOSTIP; my $ip = $HOSTIP;
my $ipvnum = 4; my $ipvnum = 4;
my $idnum = 1; my $idnum = 1;
@ -2095,8 +2117,12 @@ sub responsive_http_server {
elsif($alt eq "proxy") { elsif($alt eq "proxy") {
$idnum = 2; $idnum = 2;
} }
elsif($alt eq "unix") {
# IP (protocol) is mutually exclusive with UNIX sockets
$ipvnum = "unix";
}
return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port); return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
} }
####################################################################### #######################################################################
@ -2346,9 +2372,10 @@ sub checksystem {
@protocols = split(' ', lc($1)); @protocols = split(' ', lc($1));
# Generate a "proto-ipv6" version of each protocol to match the # Generate a "proto-ipv6" version of each protocol to match the
# IPv6 <server> name. This works even if IPv6 support isn't # IPv6 <server> name and a "proto-unix" to match the variant which
# uses UNIX domain sockets. This works even if support isn't
# compiled in because the <features> test will fail. # compiled in because the <features> test will fail.
push @protocols, map($_ . '-ipv6', @protocols); push @protocols, map(("$_-ipv6", "$_-unix"), @protocols);
# 'http-proxy' is used in test cases to do CONNECT through # 'http-proxy' is used in test cases to do CONNECT through
push @protocols, 'http-proxy'; push @protocols, 'http-proxy';
@ -2384,6 +2411,9 @@ sub checksystem {
if($feat =~ /IPv6/i) { if($feat =~ /IPv6/i) {
$has_ipv6 = 1; $has_ipv6 = 1;
} }
if($feat =~ /unix-sockets/i) {
$has_unix = 1;
}
if($feat =~ /libz/i) { if($feat =~ /libz/i) {
$has_libz = 1; $has_libz = 1;
} }
@ -2517,6 +2547,12 @@ sub checksystem {
} }
} }
if($has_unix) {
# client has UNIX sockets support, check whether the HTTP server has it
my @sws = `server/sws --version`;
$http_unix = 1 if($sws[0] =~ /unix/);
}
if(!$has_memory_tracking && $torture) { if(!$has_memory_tracking && $torture) {
die "can't run torture tests since curl was built without ". die "can't run torture tests since curl was built without ".
"TrackMemory feature (--enable-curldebug)"; "TrackMemory feature (--enable-curldebug)";
@ -2548,6 +2584,7 @@ sub checksystem {
logmsg sprintf(" track memory: %s\n", $has_memory_tracking?"ON ":"OFF"); logmsg sprintf(" track memory: %s\n", $has_memory_tracking?"ON ":"OFF");
logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF"); logmsg sprintf("* valgrind: %8s", $valgrind?"ON ":"OFF");
logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF"); logmsg sprintf(" HTTP IPv6 %s\n", $http_ipv6?"ON ":"OFF");
logmsg sprintf("* HTTP UNIX %s\n", $http_unix?"ON ":"OFF");
logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF"); logmsg sprintf("* FTP IPv6 %8s", $ftp_ipv6?"ON ":"OFF");
logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF"); logmsg sprintf(" Libtool lib: %s\n", $libtool?"ON ":"OFF");
logmsg sprintf("* Shared build: %-3s", $has_shared); logmsg sprintf("* Shared build: %-3s", $has_shared);
@ -2600,6 +2637,13 @@ sub checksystem {
} }
logmsg sprintf("* HTTP-PIPE/%d \n", $HTTPPIPEPORT); logmsg sprintf("* HTTP-PIPE/%d \n", $HTTPPIPEPORT);
if($has_unix) {
logmsg "* UNIX socket paths:\n";
if($http_unix) {
logmsg sprintf("* HTTP-UNIX:%s\n", $HTTPUNIXPATH);
}
}
$has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys'); $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
logmsg "***************************************** \n"; logmsg "***************************************** \n";
@ -2648,6 +2692,10 @@ sub subVariables {
$$thing =~ s/%TFTP6PORT/$TFTP6PORT/g; $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
$$thing =~ s/%TFTPPORT/$TFTPPORT/g; $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
# server UNIX domain socket paths
$$thing =~ s/%HTTPUNIXPATH/$HTTPUNIXPATH/g;
# client IP addresses # client IP addresses
$$thing =~ s/%CLIENT6IP/$CLIENT6IP/g; $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
@ -2924,6 +2972,9 @@ sub singletest {
elsif($1 eq "socks") { elsif($1 eq "socks") {
next; next;
} }
elsif($1 eq "unix-sockets") {
next if $has_unix;
}
# See if this "feature" is in the list of supported protocols # See if this "feature" is in the list of supported protocols
elsif (grep /^\Q$1\E$/i, @protocols) { elsif (grep /^\Q$1\E$/i, @protocols) {
next; next;
@ -2996,6 +3047,9 @@ sub singletest {
next; next;
} }
} }
elsif($1 eq "unix-sockets") {
next if !$has_unix;
}
elsif($1 eq "libz") { elsif($1 eq "libz") {
if(!$has_libz) { if(!$has_libz) {
next; next;
@ -3567,11 +3621,11 @@ sub singletest {
my @killservers; my @killservers;
foreach my $server (@killtestservers) { foreach my $server (@killtestservers) {
chomp $server; chomp $server;
if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) { if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
# given a stunnel ssl server, also kill non-ssl underlying one # given a stunnel ssl server, also kill non-ssl underlying one
push @killservers, "${1}${2}"; push @killservers, "${1}${2}";
} }
elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) { elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
# given a non-ssl server, also kill stunnel piggybacking one # given a non-ssl server, also kill stunnel piggybacking one
push @killservers, "${1}s${2}"; push @killservers, "${1}s${2}";
} }
@ -4085,7 +4139,7 @@ sub startservers {
$what =~ s/[^a-z0-9-]//g; $what =~ s/[^a-z0-9-]//g;
my $certfile; my $certfile;
if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) { if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
$certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem'; $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
} }
@ -4440,6 +4494,22 @@ sub startservers {
} }
} }
} }
elsif($what eq "http-unix") {
if($torture && $run{'http-unix'} &&
!responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
stopserver('http-unix');
}
if(!$run{'http-unix'}) {
($pid, $pid2) = runhttpserver("http", $verbose, "unix",
$HTTPUNIXPATH);
if($pid <= 0) {
return "failed starting HTTP-unix server";
}
logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
if($verbose);
$run{'http-unix'}="$pid $pid2";
}
}
elsif($what eq "none") { elsif($what eq "none") {
logmsg "* starts no server\n" if ($verbose); logmsg "* starts no server\n" if ($verbose);
} }
@ -4892,6 +4962,7 @@ $HTTPTLSPORT = $base++; # HTTP TLS (non-stunnel) server port
$HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port $HTTPTLS6PORT = $base++; # HTTP TLS (non-stunnel) IPv6 server port
$HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT $HTTPPROXYPORT = $base++; # HTTP proxy port, when using CONNECT
$HTTPPIPEPORT = $base++; # HTTP pipelining port $HTTPPIPEPORT = $base++; # HTTP pipelining port
$HTTPUNIXPATH = 'http.sock'; # HTTP server UNIX domain socket path
####################################################################### #######################################################################
# clear and create logging directory: # clear and create logging directory:

View File

@ -109,8 +109,8 @@ sub servername_str {
$ipver = (not $ipver) ? 'ipv4' : lc($ipver); $ipver = (not $ipver) ? 'ipv4' : lc($ipver);
die "unsupported IP version: '$ipver'" unless($ipver && die "unsupported IP version: '$ipver'" unless($ipver &&
($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6)$/)); ($ipver =~ /^(4|6|ipv4|ipv6|-ipv4|-ipv6|unix)$/));
$ipver = ($ipver =~ /6$/) ? '-IPv6' : ''; $ipver = ($ipver =~ /6$/) ? '-IPv6' : (($ipver =~ /unix$/) ? '-unix' : '');
$idnum = 1 if(not $idnum); $idnum = 1 if(not $idnum);
die "unsupported ID number: '$idnum'" unless($idnum && die "unsupported ID number: '$idnum'" unless($idnum &&