Revert "Update to 7.40.1"
[platform/upstream/curl.git] / tests / runtests.pl
index 749840b..da71414 100755 (executable)
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
 #
 # This software is licensed as described in the file COPYING, which
 # you should have received as part of this distribution. The terms
@@ -56,7 +56,8 @@
 # These should be the only variables that might be needed to get edited:
 
 BEGIN {
-    @INC=(@INC, $ENV{'srcdir'}, ".");
+    push(@INC, $ENV{'srcdir'}) if(defined $ENV{'srcdir'});
+    push(@INC, ".");
     # run time statistics needs Time::HiRes
     eval {
         no warnings "all";
@@ -100,7 +101,7 @@ use sshhelp qw(
     find_sshd
     find_ssh
     find_sftp
-    find_gnutls_serv
+    find_httptlssrv
     sshversioninfo
     );
 
@@ -115,28 +116,31 @@ my $CLIENT6IP="[::1]";    # address which curl uses for incoming connections
 
 my $base = 8990; # base port number
 
-my $HTTPPORT; # HTTP server port
-my $HTTP6PORT; # HTTP IPv6 server port
-my $HTTPSPORT; # HTTPS server port
-my $FTPPORT; # FTP server port
-my $FTP2PORT; # FTP server 2 port
-my $FTPSPORT; # FTPS server port
-my $FTP6PORT; # FTP IPv6 server port
-my $TFTPPORT; # TFTP
-my $TFTP6PORT; # TFTP
-my $SSHPORT; # SCP/SFTP
-my $SOCKSPORT; # SOCKS4/5 port
-my $POP3PORT; # POP3
-my $POP36PORT; # POP3 IPv6 server port
-my $IMAPPORT; # IMAP
-my $IMAP6PORT; # IMAP IPv6 server port
-my $SMTPPORT; # SMTP
-my $SMTP6PORT; # SMTP IPv6 server port
-my $RTSPPORT; # RTSP
-my $RTSP6PORT; # RTSP IPv6 server port
-my $GOPHERPORT; # Gopher
-my $GOPHER6PORT; # Gopher IPv6 server port
-my $HTTPTLSSRPPORT; # TLS-SRP HTTP port
+my $HTTPPORT;            # HTTP server port
+my $HTTP6PORT;           # HTTP IPv6 server port
+my $HTTPSPORT;           # HTTPS (stunnel) server port
+my $FTPPORT;             # FTP server port
+my $FTP2PORT;            # FTP server 2 port
+my $FTPSPORT;            # FTPS (stunnel) server port
+my $FTP6PORT;            # FTP IPv6 server port
+my $TFTPPORT;            # TFTP
+my $TFTP6PORT;           # TFTP
+my $SSHPORT;             # SCP/SFTP
+my $SOCKSPORT;           # SOCKS4/5 port
+my $POP3PORT;            # POP3
+my $POP36PORT;           # POP3 IPv6 server port
+my $IMAPPORT;            # IMAP
+my $IMAP6PORT;           # IMAP IPv6 server port
+my $SMTPPORT;            # SMTP
+my $SMTP6PORT;           # SMTP IPv6 server port
+my $RTSPPORT;            # RTSP
+my $RTSP6PORT;           # RTSP IPv6 server port
+my $GOPHERPORT;          # Gopher
+my $GOPHER6PORT;         # Gopher IPv6 server port
+my $HTTPTLSPORT;         # HTTP TLS (non-stunnel) server port
+my $HTTPTLS6PORT;        # HTTP TLS (non-stunnel) IPv6 server port
+my $HTTPPROXYPORT;       # HTTP proxy port, when using CONNECT
+my $HTTPPIPEPORT;        # HTTP pipelining port
 
 my $srcdir = $ENV{'srcdir'} || '.';
 my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests
@@ -148,8 +152,10 @@ my $LOGDIR="log";
 my $TESTDIR="$srcdir/data";
 my $LIBDIR="./libtest";
 my $UNITDIR="./unit";
+# TODO: change this to use server_inputfilename()
 my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server
 my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server
+my $PROXYIN="$LOGDIR/proxy.input"; # what curl sent the proxy
 my $CURLLOG="$LOGDIR/curl.log"; # all command lines run
 my $FTPDCMD="$LOGDIR/ftpserver.cmd"; # copy ftp server instructions here
 my $SERVERLOGS_LOCK="$LOGDIR/serverlogs.lock"; # server logs advisor read lock
@@ -170,8 +176,8 @@ my $TESTCASES="all";
 my $perl="perl -I$srcdir";
 my $server_response_maxtime=13;
 
-my $debug_build=0; # curl built with --enable-debug
-my $curl_debug=0;  # curl built with --enable-curldebug (memory tracking)
+my $debug_build=0;          # built debug enabled (--enable-debug)
+my $has_memory_tracking=0;  # built with memory tracking (--enable-curldebug)
 my $libtool;
 
 # name of the file that the memory debugging creates:
@@ -183,14 +189,14 @@ my $memanalyze="$perl $srcdir/memanalyze.pl";
 my $pwd = getcwd();          # current working directory
 
 my $start;
-my $forkserver=0;
 my $ftpchecktime=1; # time it took to verify our test FTP server
 
-my $stunnel = checkcmd("stunnel4") || checkcmd("stunnel");
+my $stunnel = checkcmd("stunnel4") || checkcmd("tstunnel") || checkcmd("stunnel");
 my $valgrind = checktestcmd("valgrind");
 my $valgrind_logfile="--logfile";
 my $valgrind_tool;
 my $gdb = checktestcmd("gdb");
+my $httptlssrv = find_httptlssrv();
 
 my $ssl_version; # set if libcurl is built with SSL support
 my $large_file;  # set if libcurl is built with large file support
@@ -203,31 +209,40 @@ my $has_ipv6;    # set if libcurl is built with IPv6 support
 my $has_libz;    # set if libcurl is built with libz support
 my $has_getrlimit;  # set if system has getrlimit()
 my $has_ntlm;    # set if libcurl is built with NTLM support
-my $has_ntlm_sso; # set if libcurl is built with NTLM single-sign-on support
+my $has_ntlm_wb; # set if libcurl is built with NTLM delegation to winbind
+my $has_sspi;    # set if libcurl is built with SSPI support
 my $has_charconv;# set if libcurl is built with CharConv support
 my $has_tls_srp; # set if libcurl is built with TLS-SRP support
+my $has_metalink;# set if curl is built with Metalink support
 
-my $has_openssl; # built with a lib using an OpenSSL-like API
-my $has_gnutls;  # built with GnuTLS
-my $has_nss;     # built with NSS
-my $has_yassl;   # built with yassl
-my $has_polarssl;# built with polarssl
-my $has_axtls;   # built with axTLS
+my $has_openssl;  # built with a lib using an OpenSSL-like API
+my $has_gnutls;   # built with GnuTLS
+my $has_nss;      # built with NSS
+my $has_yassl;    # built with yassl
+my $has_polarssl; # built with polarssl
+my $has_axtls;    # built with axTLS
+my $has_winssl;   # built with WinSSL    (Secure Channel aka Schannel)
+my $has_darwinssl;# build with DarwinSSL (Secure Transport)
 
-my $has_shared;  # built shared
+my $has_shared = "unknown";  # built shared
+
+my $resolver;     # string to hold the resolver backend
+my $has_cares;    # if built with c-ares
+my $has_threadedres; # if built with threaded resolver
 
 my $ssllib;      # name of the lib we use (for human presentation)
 my $has_crypto;  # set if libcurl is built with cryptographic support
 my $has_textaware; # set if running on a system that has a text mode concept
   # on files. Windows for example
-my @protocols;   # array of supported protocols
+
+my @protocols;   # array of lowercase supported protocol servers
 
 my $skipped=0;  # number of tests skipped; reported in main loop
 my %skipped;    # skipped{reason}=counter, reasons for skip
 my @teststat;   # teststat[testnum]=reason, reasons for skip
 my %disabled_keywords;  # key words of tests to skip
 my %enabled_keywords;   # key words of tests to run
-my %disabled;           # disabled test cases 
+my %disabled;           # disabled test cases
 
 my $sshdid;      # for socks server, ssh daemon version id
 my $sshdvernum;  # for socks server, ssh daemon version number
@@ -251,17 +266,20 @@ my $testnumcheck; # test number, set in singletest sub.
 my %oldenv;
 
 #######################################################################
-# variables the command line options may set
+# variables that command line options may set
 #
 
 my $short;
+my $automakestyle;
 my $verbose;
 my $debugprotocol;
 my $anyway;
 my $gdbthis;      # run test case with gdb debugger
+my $gdbxwin;      # use windowed gdb when using gdb
 my $keepoutfiles; # keep stdout and stderr files after tests
 my $listonly;     # only list the tests
 my $postmortem;   # display detailed info about failed tests
+my $run_event_based; # run curl with --test-event to test the event API
 
 my %run;          # running server
 my %doesntrun;    # servers that don't work, identified by pidfile
@@ -293,6 +311,8 @@ if (!$USER) {
 
 # enable memory debugging if curl is compiled with it
 $ENV{'CURL_MEMDEBUG'} = $memdump;
+$ENV{'CURL_ENTROPY'}="12345678";
+$ENV{'CURL_FORCETIME'}=1; # for debug NTLM magic
 $ENV{'HOME'}=$pwd;
 
 sub catch_zap {
@@ -328,10 +348,10 @@ delete $ENV{'CURL_CA_BUNDLE'} if($ENV{'CURL_CA_BUNDLE'});
 # Load serverpidfile hash with pidfile names for all possible servers.
 #
 sub init_serverpidfile_hash {
-  for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp')) {
+  for my $proto (('ftp', 'http', 'imap', 'pop3', 'smtp', 'http')) {
     for my $ssl (('', 's')) {
       for my $ipvnum ((4, 6)) {
-        for my $idnum ((1, 2)) {
+        for my $idnum ((1, 2, 3)) {
           my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
           my $pidf = server_pidfilename("$proto$ssl", $ipvnum, $idnum);
           $serverpidfile{$serv} = $pidf;
@@ -339,7 +359,7 @@ sub init_serverpidfile_hash {
       }
     }
   }
-  for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'http+tls-srp')) {
+  for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'gopher', 'httptls')) {
     for my $ipvnum ((4, 6)) {
       for my $idnum ((1, 2)) {
         my $serv = servername_id($proto, $ipvnum, $idnum);
@@ -392,7 +412,7 @@ sub startnew {
         die "error: exec() has returned";
     }
 
-    # Ugly hack but ssh client doesn't support pid files
+    # Ugly hack but ssh client and gnutls-serv don't support pid files
     if ($fake) {
         if(open(OUT, ">$pidfile")) {
             print OUT $child . "\n";
@@ -415,7 +435,7 @@ sub startnew {
         if(-f $pidfile && -s $pidfile && open(PID, "<$pidfile")) {
             $pid2 = 0 + <PID>;
             close(PID);
-            if(($pid2 > 0) && kill(0, $pid2)) {
+            if(($pid2 > 0) && pidexists($pid2)) {
                 # if $pid2 is valid, then make sure this pid is alive, as
                 # otherwise it is just likely to be the _previous_ pidfile or
                 # similar!
@@ -482,7 +502,9 @@ sub checktestcmd {
 #
 sub runclient {
     my ($cmd)=@_;
-    return system($cmd);
+    my $ret = system($cmd);
+    print "CMD ($ret): $cmd\n" if($verbose && !$torture);
+    return $ret;
 
 # This is one way to test curl on a remote machine
 #    my $out = system("ssh $CLIENTIP cd \'$pwd\' \\; \'$cmd\'");
@@ -565,7 +587,7 @@ sub torture {
         else {
             $ret = runclient($testcmd);
         }
-        #logmsg "$_ Returned " . $ret >> 8 . "\n";
+        #logmsg "$_ Returned " . ($ret >> 8) . "\n";
 
         # Now clear the variable again
         delete $ENV{'CURL_MEMLIMIT'} if($ENV{'CURL_MEMLIMIT'});
@@ -579,7 +601,7 @@ sub torture {
 
         # verify that it returns a proper error code, doesn't leak memory
         # and doesn't core dump
-        if($ret & 255) {
+        if(($ret & 255) || ($ret >> 8) >= 128) {
             logmsg " system() returned $ret\n";
             $fail=1;
         }
@@ -631,20 +653,20 @@ sub stopserver {
     # All servers relative to the given one must be stopped also
     #
     my @killservers;
-    if($server =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
-        # given an ssl server, also kill non-ssl underlying one
+    if($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)s((\d*)(-ipv6|))$/) {
+        # given a stunnel based ssl server, also kill non-ssl underlying one
         push @killservers, "${1}${2}";
     }
-    elsif($server =~ /^(ftp|http|imap|pop3|smtp)(.*)$/) {
-        # given a non-ssl server, also kill ssl piggybacking one
+    elsif($server =~ /^(ftp|http|imap|pop3|smtp|httppipe)((\d*)(-ipv6|))$/) {
+        # given a non-ssl server, also kill stunnel based ssl piggybacking one
         push @killservers, "${1}s${2}";
     }
-    elsif($server =~ /^(socks)(.*)$/) {
-        # given an socks server, also kill ssh underlying one
+    elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
+        # given a socks server, also kill ssh underlying one
         push @killservers, "ssh${2}";
     }
-    elsif($server =~ /^(ssh)(.*)$/) {
-        # given an ssh server, also kill socks piggybacking one
+    elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
+        # given a ssh server, also kill socks piggybacking one
         push @killservers, "socks${2}";
     }
     push @killservers, $server;
@@ -653,8 +675,7 @@ sub stopserver {
     #
     foreach my $server (@killservers) {
         if($run{$server}) {
-            # we must prepend a space since $pidlist may already contain
-            # a pid
+            # we must prepend a space since $pidlist may already contain a pid
             $pidlist .= " $run{$server}";
             $run{$server} = 0;
         }
@@ -679,8 +700,8 @@ sub stopserver {
 # Verify that the server that runs on $ip, $port is our server.  This also
 # implies that we can speak with it, as there might be occasions when the
 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
-# assign requested address" #
-
+# assign requested address")
+#
 sub verifyhttp {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
@@ -759,8 +780,8 @@ sub verifyhttp {
 # Verify that the server that runs on $ip, $port is our server.  This also
 # implies that we can speak with it, as there might be occasions when the
 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
-# assign requested address" #
-
+# assign requested address")
+#
 sub verifyftp {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
@@ -775,14 +796,6 @@ sub verifyftp {
     if($proto eq "ftps") {
         $extra .= "--insecure --ftp-ssl-control ";
     }
-    elsif($proto eq "smtp") {
-        # SMTP is a bit different since it requires more options and it
-        # has _no_ output!
-        $extra .= "--mail-rcpt verifiedserver ";
-        $extra .= "--mail-from fake ";
-        $extra .= "--upload /dev/null ";
-        $extra .= "--stderr - "; # move stderr to parse the verbose stuff
-    }
 
     my $flags = "--max-time $server_response_maxtime ";
     $flags .= "--silent ";
@@ -831,8 +844,8 @@ sub verifyftp {
 # Verify that the server that runs on $ip, $port is our server.  This also
 # implies that we can speak with it, as there might be occasions when the
 # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
-# assign requested address" #
-
+# assign requested address")
+#
 sub verifyrtsp {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
@@ -904,7 +917,7 @@ sub verifyrtsp {
 # Verify that the ssh server has written out its pidfile, recovering
 # the pid from the file and returning it if a process with that pid is
 # actually alive.
-
+#
 sub verifyssh {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
@@ -917,7 +930,7 @@ sub verifyssh {
     if($pid > 0) {
         # if we have a pid it is actually our ssh server,
         # since runsshserver() unlinks previous pidfile
-        if(!kill(0, $pid)) {
+        if(!pidexists($pid)) {
             logmsg "RUN: SSH server has died after starting up\n";
             checkdied($pid);
             unlink($pidfile);
@@ -930,7 +943,7 @@ sub verifyssh {
 #######################################################################
 # Verify that we can connect to the sftp server, properly authenticate
 # with generated config and key files and run a simple remote pwd.
-
+#
 sub verifysftp {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
@@ -965,17 +978,16 @@ sub verifysftp {
 }
 
 #######################################################################
-# Verify that the TLS-SRP HTTP server that runs on $ip, $port is our server.
-# This also implies that we can speak with it, as there might be occasions when
-# the server runs fine but we cannot talk to it ("Failed to connect to ::1:
-# Can't assign requested address" #
-
-sub verifyhttptlssrp {
+# Verify that the non-stunnel HTTP TLS extensions capable server that runs
+# on $ip, $port is our server.  This also implies that we can speak with it,
+# as there might be occasions when the server runs fine but we cannot talk
+# to it ("Failed to connect to ::1: Can't assign requested address")
+#
+sub verifyhttptls {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
     my $pidfile = server_pidfilename($proto, $ipvnum, $idnum);
     my $pid = 0;
-    my $bonus="";
 
     my $verifyout = "$LOGDIR/".
         servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
@@ -990,7 +1002,9 @@ sub verifyhttptlssrp {
     $flags .= "--verbose ";
     $flags .= "--globoff ";
     $flags .= "--insecure ";
-    $flags .= "--tlsauthtype SRP --tlsuser jsmith --tlspassword abc ";
+    $flags .= "--tlsauthtype SRP ";
+    $flags .= "--tlsuser jsmith ";
+    $flags .= "--tlspassword abc ";
     $flags .= "\"https://$ip:$port/verifiedserver\"";
 
     my $cmd = "$VCURL $flags 2>$verifylog";
@@ -1023,9 +1037,19 @@ sub verifyhttptlssrp {
         close(FILE);
     }
 
-    if($data && ($data =~ /GNUTLS/) && open(FILE, "<$pidfile")) {
+    if($data && ($data =~ /(GNUTLS|GnuTLS)/) && open(FILE, "<$pidfile")) {
         $pid=0+<FILE>;
         close(FILE);
+        if($pid > 0) {
+            # if we have a pid it is actually our httptls server,
+            # since runhttptlsserver() unlinks previous pidfile
+            if(!pidexists($pid)) {
+                logmsg "RUN: $server server has died after starting up\n";
+                checkdied($pid);
+                unlink($pidfile);
+                $pid = -1;
+            }
+        }
         return $pid;
     }
     elsif($res == 6) {
@@ -1042,7 +1066,7 @@ sub verifyhttptlssrp {
 
 #######################################################################
 # STUB for verifying socks
-
+#
 sub verifysocks {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
     my $server = servername_id($proto, $ipvnum, $idnum);
@@ -1055,7 +1079,7 @@ sub verifysocks {
     if($pid > 0) {
         # if we have a pid it is actually our socks server,
         # since runsocksserver() unlinks previous pidfile
-        if(!kill(0, $pid)) {
+        if(!pidexists($pid)) {
             logmsg "RUN: SOCKS server has died after starting up\n";
             checkdied($pid);
             unlink($pidfile);
@@ -1071,6 +1095,11 @@ sub verifysocks {
 # particular can take a long time to start if it needs to generate
 # keys on a slow or loaded host.
 #
+# Just for convenience, test harness uses 'https' and 'httptls' literals
+# as values for 'proto' variable in order to differentiate different
+# servers. 'https' literal is used for stunnel based https test servers,
+# and 'httptls' is used for non-stunnel https test servers.
+#
 
 my %protofunc = ('http' => \&verifyhttp,
                  'https' => \&verifyhttp,
@@ -1079,12 +1108,13 @@ my %protofunc = ('http' => \&verifyhttp,
                  'pop3' => \&verifyftp,
                  'imap' => \&verifyftp,
                  'smtp' => \&verifyftp,
+                 'httppipe' => \&verifyhttp,
                  'ftps' => \&verifyftp,
                  'tftp' => \&verifyftp,
                  'ssh' => \&verifyssh,
                  'socks' => \&verifysocks,
                  'gopher' => \&verifyhttp,
-                 'http+tls-srp' => \&verifyhttptlssrp);
+                 'httptls' => \&verifyhttptls);
 
 sub verifyserver {
     my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
@@ -1109,13 +1139,33 @@ sub verifyserver {
     return $pid;
 }
 
+#######################################################################
+# Single shot server responsiveness test. This should only be used
+# to verify that a server present in %run hash is still functional
+#
+sub responsiveserver {
+    my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
+    my $prev_verbose = $verbose;
+
+    $verbose = 0;
+    my $fun = $protofunc{$proto};
+    my $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
+    $verbose = $prev_verbose;
+
+    if($pid > 0) {
+        return 1; # responsive
+    }
 
+    my $srvrname = servername_str($proto, $ipvnum, $idnum);
+    logmsg " server precheck FAILED (unresponsive $srvrname server)\n";
+    return 0;
+}
 
 #######################################################################
 # start the http server
 #
 sub runhttpserver {
-    my ($proto, $verbose, $ipv6, $port) = @_;
+    my ($proto, $verbose, $alt, $port) = @_;
     my $ip = $HOSTIP;
     my $ipvnum = 4;
     my $idnum = 1;
@@ -1124,13 +1174,24 @@ sub runhttpserver {
     my $pidfile;
     my $logfile;
     my $flags = "";
+    my $exe = "$perl $srcdir/httpserver.pl";
+    my $verbose_flag = "--verbose ";
 
-
-    if($ipv6) {
+    if($alt eq "ipv6") {
         # if IPv6, use a different setup
         $ipvnum = 6;
         $ip = $HOST6IP;
     }
+    elsif($alt eq "proxy") {
+        # basically the same, but another ID
+        $idnum = 2;
+    }
+    elsif($alt eq "pipe") {
+        # basically the same, but another ID
+        $idnum = 3;
+        $exe = "python $srcdir/http_pipe.py";
+        $verbose_flag .= "1 ";
+    }
 
     $server = servername_id($proto, $ipvnum, $idnum);
 
@@ -1151,17 +1212,92 @@ sub runhttpserver {
 
     $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
 
-    $flags .= "--fork " if($forkserver);
     $flags .= "--gopher " if($proto eq "gopher");
-    $flags .= "--verbose " if($debugprotocol);
+    $flags .= "--connect $HOSTIP " if($alt eq "proxy");
+    $flags .= $verbose_flag if($debugprotocol);
     $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
     $flags .= "--id $idnum " if($idnum > 1);
     $flags .= "--ipv$ipvnum --port $port --srcdir \"$srcdir\"";
 
-    my $cmd = "$perl $srcdir/httpserver.pl $flags";
+    my $cmd = "$exe $flags";
+    my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
+
+    if($httppid <= 0 || !pidexists($httppid)) {
+        # it is NOT alive
+        logmsg "RUN: failed to start the $srvrname server\n";
+        stopserver($server, "$pid2");
+        displaylogs($testnumcheck);
+        $doesntrun{$pidfile} = 1;
+        return (0,0);
+    }
+
+    # Server is up. Verify that we can speak to it.
+    my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
+    if(!$pid3) {
+        logmsg "RUN: $srvrname server failed verification\n";
+        # failed to talk to it properly. Kill the server and return failure
+        stopserver($server, "$httppid $pid2");
+        displaylogs($testnumcheck);
+        $doesntrun{$pidfile} = 1;
+        return (0,0);
+    }
+    $pid2 = $pid3;
+
+    if($verbose) {
+        logmsg "RUN: $srvrname server is now running PID $httppid\n";
+    }
+
+    sleep(1);
+
+    return ($httppid, $pid2);
+}
+
+#######################################################################
+# start the http server
+#
+sub runhttp_pipeserver {
+    my ($proto, $verbose, $alt, $port) = @_;
+    my $ip = $HOSTIP;
+    my $ipvnum = 4;
+    my $idnum = 1;
+    my $server;
+    my $srvrname;
+    my $pidfile;
+    my $logfile;
+    my $flags = "";
+
+    if($alt eq "ipv6") {
+        # No IPv6
+    }
+
+    $server = servername_id($proto, $ipvnum, $idnum);
+
+    $pidfile = $serverpidfile{$server};
+
+    # don't retry if the server doesn't work
+    if ($doesntrun{$pidfile}) {
+        return (0,0);
+    }
+
+    my $pid = processexists($pidfile);
+    if($pid > 0) {
+        stopserver($server, "$pid");
+    }
+    unlink($pidfile) if(-f $pidfile);
+
+    $srvrname = servername_str($proto, $ipvnum, $idnum);
+
+    $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
+
+    $flags .= "--verbose 1 " if($debugprotocol);
+    $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
+    $flags .= "--id $idnum " if($idnum > 1);
+    $flags .= "--port $port --srcdir \"$srcdir\"";
+
+    my $cmd = "$srcdir/http_pipe.py $flags";
     my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
 
-    if($httppid <= 0 || !kill(0, $httppid)) {
+    if($httppid <= 0 || !pidexists($httppid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1192,7 +1328,7 @@ sub runhttpserver {
 }
 
 #######################################################################
-# start the https server (or rather, tunnel)
+# start the https stunnel based server
 #
 sub runhttpsserver {
     my ($verbose, $ipv6, $certfile) = @_;
@@ -1242,7 +1378,7 @@ sub runhttpsserver {
     my $cmd = "$perl $srcdir/secureserver.pl $flags";
     my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
 
-    if($httpspid <= 0 || !kill(0, $httpspid)) {
+    if($httpspid <= 0 || !pidexists($httpspid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1275,14 +1411,14 @@ sub runhttpsserver {
 }
 
 #######################################################################
-# start the TLS-SRP HTTP server
+# start the non-stunnel HTTP TLS extensions capable server
 #
-sub runhttptlssrpserver {
-    my ($verbose) = @_;
-    my $proto = "http+tls-srp";
-    my $ip = $HOSTIP;
-    my $port = $HTTPTLSSRPPORT;
-    my $ipvnum = 4;
+sub runhttptlsserver {
+    my ($verbose, $ipv6) = @_;
+    my $proto = "httptls";
+    my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
+    my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
+    my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
     my $idnum = 1;
     my $server;
     my $srvrname;
@@ -1290,6 +1426,10 @@ sub runhttptlssrpserver {
     my $logfile;
     my $flags = "";
 
+    if(!$httptlssrv) {
+        return (0,0);
+    }
+
     $server = servername_id($proto, $ipvnum, $idnum);
 
     $pidfile = $serverpidfile{$server};
@@ -1309,23 +1449,17 @@ sub runhttptlssrpserver {
 
     $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
 
-    $flags .= "--fork " if($forkserver);
     $flags .= "--http ";
-    $flags .= "-d 1 " if($debugprotocol);
+    $flags .= "--debug 1 " if($debugprotocol);
     $flags .= "--port $port ";
-    $flags .= "--srppasswd certs/srp-verifier-db --srppasswdconf certs/srp-verifier-conf ";
-    $flags .=" >log/gnutls.out 2>&1";
+    $flags .= "--priority NORMAL:+SRP ";
+    $flags .= "--srppasswd $srcdir/certs/srp-verifier-db ";
+    $flags .= "--srppasswdconf $srcdir/certs/srp-verifier-conf";
 
-    # Find gnutls-serv
-    my $gnutlsserv = find_gnutls_serv();
-    if(!$gnutlsserv) {
-        logmsg "RUN: cannot find gnutls-serv\n";
-        return (0,0);
-    }
-    my $cmd = "$gnutlsserv $flags";
-    my ($httptlssrppid, $pid2) = startnew($cmd, $pidfile, 1, 1);
+    my $cmd = "$httptlssrv $flags > $logfile 2>&1";
+    my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1); # fake pidfile
 
-    if($httptlssrppid <= 0 || !kill(0, $httptlssrppid)) {
+    if($httptlspid <= 0 || !pidexists($httptlspid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1334,12 +1468,12 @@ sub runhttptlssrpserver {
         return (0,0);
     }
 
-    # Server is up. Verify that we can speak to it.
+    # Server is up. Verify that we can speak to it. PID is from fake pidfile
     my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
     if(!$pid3) {
         logmsg "RUN: $srvrname server failed verification\n";
         # failed to talk to it properly. Kill the server and return failure
-        stopserver($server, "$httptlssrppid $pid2");
+        stopserver($server, "$httptlspid $pid2");
         displaylogs($testnumcheck);
         $doesntrun{$pidfile} = 1;
         return (0,0);
@@ -1347,12 +1481,12 @@ sub runhttptlssrpserver {
     $pid2 = $pid3;
 
     if($verbose) {
-        logmsg "RUN: $srvrname server is now running PID $httptlssrppid\n";
+        logmsg "RUN: $srvrname server is now running PID $httptlspid\n";
     }
 
     sleep(1);
 
-    return ($httptlssrppid, $pid2);
+    return ($httptlspid, $pid2);
 }
 
 #######################################################################
@@ -1420,7 +1554,7 @@ sub runpingpongserver {
     my $cmd = "$perl $srcdir/ftpserver.pl $flags";
     my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
 
-    if($ftppid <= 0 || !kill(0, $ftppid)) {
+    if($ftppid <= 0 || !pidexists($ftppid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1502,7 +1636,7 @@ sub runftpsserver {
     my $cmd = "$perl $srcdir/secureserver.pl $flags";
     my ($ftpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
 
-    if($ftpspid <= 0 || !kill(0, $ftpspid)) {
+    if($ftpspid <= 0 || !pidexists($ftpspid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1584,7 +1718,7 @@ sub runtftpserver {
     my $cmd = "$perl $srcdir/tftpserver.pl $flags";
     my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
 
-    if($tftppid <= 0 || !kill(0, $tftppid)) {
+    if($tftppid <= 0 || !pidexists($tftppid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1665,7 +1799,7 @@ sub runrtspserver {
     my $cmd = "$perl $srcdir/rtspserver.pl $flags";
     my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
 
-    if($rtsppid <= 0 || !kill(0, $rtsppid)) {
+    if($rtsppid <= 0 || !pidexists($rtsppid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1747,7 +1881,7 @@ sub runsshserver {
     # passed to startnew, when this happens startnew completes without being
     # able to read the pidfile and consequently returns a zero pid2 above.
 
-    if($sshpid <= 0 || !kill(0, $sshpid)) {
+    if($sshpid <= 0 || !pidexists($sshpid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         stopserver($server, "$pid2");
@@ -1902,9 +2036,9 @@ sub runsocksserver {
 
     # start our socks server
     my $cmd="$ssh -N -F $sshconfig $ip > $sshlog 2>&1";
-    my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1);
+    my ($sshpid, $pid2) = startnew($cmd, $pidfile, 30, 1); # fake pidfile
 
-    if($sshpid <= 0 || !kill(0, $sshpid)) {
+    if($sshpid <= 0 || !pidexists($sshpid)) {
         # it is NOT alive
         logmsg "RUN: failed to start the $srvrname server\n";
         display_sshlog();
@@ -1916,7 +2050,7 @@ sub runsocksserver {
         return (0,0);
     }
 
-    # Ugly hack but ssh doesn't support pid files
+    # Ugly hack but ssh doesn't support pid files. PID is from fake pidfile.
     my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
     if(!$pid3) {
         logmsg "RUN: $srvrname server failed verification\n";
@@ -1935,6 +2069,124 @@ sub runsocksserver {
 }
 
 #######################################################################
+# Single shot http and gopher server responsiveness test. This should only
+# be used to verify that a server present in %run hash is still functional
+#
+sub responsive_http_server {
+    my ($proto, $verbose, $alt, $port) = @_;
+    my $ip = $HOSTIP;
+    my $ipvnum = 4;
+    my $idnum = 1;
+
+    if($alt eq "ipv6") {
+        # if IPv6, use a different setup
+        $ipvnum = 6;
+        $ip = $HOST6IP;
+    }
+    elsif($alt eq "proxy") {
+        $idnum = 2;
+    }
+
+    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
+}
+
+#######################################################################
+# Single shot pingpong server responsiveness test. This should only be
+# used to verify that a server present in %run hash is still functional
+#
+sub responsive_pingpong_server {
+    my ($proto, $id, $verbose, $ipv6) = @_;
+    my $port;
+    my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
+    my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
+    my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
+
+    if($proto eq "ftp") {
+        $port = ($idnum>1)?$FTP2PORT:$FTPPORT;
+
+        if($ipvnum==6) {
+            # if IPv6, use a different setup
+            $port = $FTP6PORT;
+        }
+    }
+    elsif($proto eq "pop3") {
+        $port = ($ipvnum==6) ? $POP36PORT : $POP3PORT;
+    }
+    elsif($proto eq "imap") {
+        $port = ($ipvnum==6) ? $IMAP6PORT : $IMAPPORT;
+    }
+    elsif($proto eq "smtp") {
+        $port = ($ipvnum==6) ? $SMTP6PORT : $SMTPPORT;
+    }
+    else {
+        print STDERR "Unsupported protocol $proto!!\n";
+        return 0;
+    }
+
+    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
+}
+
+#######################################################################
+# Single shot rtsp server responsiveness test. This should only be
+# used to verify that a server present in %run hash is still functional
+#
+sub responsive_rtsp_server {
+    my ($verbose, $ipv6) = @_;
+    my $port = $RTSPPORT;
+    my $ip = $HOSTIP;
+    my $proto = 'rtsp';
+    my $ipvnum = 4;
+    my $idnum = 1;
+
+    if($ipv6) {
+        # if IPv6, use a different setup
+        $ipvnum = 6;
+        $port = $RTSP6PORT;
+        $ip = $HOST6IP;
+    }
+
+    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
+}
+
+#######################################################################
+# Single shot tftp server responsiveness test. This should only be
+# used to verify that a server present in %run hash is still functional
+#
+sub responsive_tftp_server {
+    my ($id, $verbose, $ipv6) = @_;
+    my $port = $TFTPPORT;
+    my $ip = $HOSTIP;
+    my $proto = 'tftp';
+    my $ipvnum = 4;
+    my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
+
+    if($ipv6) {
+        # if IPv6, use a different setup
+        $ipvnum = 6;
+        $port = $TFTP6PORT;
+        $ip = $HOST6IP;
+    }
+
+    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
+}
+
+#######################################################################
+# Single shot non-stunnel HTTP TLS extensions capable server
+# responsiveness test. This should only be used to verify that a
+# server present in %run hash is still functional
+#
+sub responsive_httptls_server {
+    my ($verbose, $ipv6) = @_;
+    my $proto = "httptls";
+    my $port = ($ipv6 && ($ipv6 =~ /6$/)) ? $HTTPTLS6PORT : $HTTPTLSPORT;
+    my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
+    my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
+    my $idnum = 1;
+
+    return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
+}
+
+#######################################################################
 # Remove all files in the specified directory
 #
 sub cleardir {
@@ -1985,21 +2237,27 @@ sub filteroff {
 # compare test results with the expected output, we might filter off
 # some pattern that is allowed to differ, output test results
 #
-
 sub compare {
     # filter off patterns _before_ this comparison!
-    my ($subject, $firstref, $secondref)=@_;
+    my ($testnum, $testname, $subject, $firstref, $secondref)=@_;
 
     my $result = compareparts($firstref, $secondref);
 
     if($result) {
+        # timestamp test result verification end
+        $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
+
         if(!$short) {
-            logmsg "\n $subject FAILED:\n";
+            logmsg "\n $testnum: $subject FAILED:\n";
             logmsg showdiff($LOGDIR, $firstref, $secondref);
         }
-        else {
+        elsif(!$automakestyle) {
             logmsg "FAILED\n";
         }
+        else {
+            # automakestyle
+            logmsg "FAIL: $testnum - $testname - $subject\n";
+        }
     }
     return $result;
 }
@@ -2032,6 +2290,7 @@ sub checksystem {
     @version = <VERSOUT>;
     close(VERSOUT);
 
+    $resolver="stock";
     for(@version) {
         chomp;
 
@@ -2042,44 +2301,10 @@ sub checksystem {
             $libcurl = $2;
             if($curl =~ /mingw32/) {
                 # This is a windows minw32 build, we need to translate the
-                # given path to the "actual" windows path.
-
-                my @m = `mount`;
-                my $matchlen;
-                my $bestmatch;
-                my $mount;
-
-# example mount output:
-# C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
-# c:\ActiveState\perl on /perl type user (binmode)
-# C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
-# C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
-
-                foreach $mount (@m) {
-                    if( $mount =~ /(.*) on ([^ ]*) type /) {
-                        my ($mingw, $real)=($2, $1);
-                        if($pwd =~ /^$mingw/) {
-                            # the path we got from pwd starts with the path
-                            # we found on this line in the mount output
-
-                            my $len = length($real);
-                            if($len > $matchlen) {
-                                # we remember the match that is the longest
-                                $matchlen = $len;
-                                $bestmatch = $real;
-                            }
-                        }
-                    }
-                }
-                if(!$matchlen) {
-                    logmsg "Serious error, can't find our \"real\" path\n";
-                }
-                else {
-                    # now prepend the prefix from the mount command to build
-                    # our "actual path"
-                    $pwd = "$bestmatch$pwd";
-                }
-                $pwd =~ s#\\#/#g;
+                # given path to the "actual" windows path. The MSYS shell
+                # has a builtin 'pwd -W' command which converts the path.
+                $pwd = `sh -c "echo \$(pwd -W)"`;
+                chomp($pwd);
             }
             elsif ($curl =~ /win32/) {
                # Native Windows builds don't understand the
@@ -2095,6 +2320,10 @@ sub checksystem {
                # through a shell.
                chomp($pwd = `cygpath -m $pwd`);
            }
+           if ($libcurl =~ /winssl/i) {
+               $has_winssl=1;
+               $ssllib="WinSSL";
+           }
            elsif ($libcurl =~ /openssl/i) {
                $has_openssl=1;
                $ssllib="OpenSSL";
@@ -2109,43 +2338,48 @@ sub checksystem {
            }
            elsif ($libcurl =~ /yassl/i) {
                $has_yassl=1;
-               $has_openssl=1;
                $ssllib="yassl";
            }
            elsif ($libcurl =~ /polarssl/i) {
                $has_polarssl=1;
-               $has_openssl=1;
                $ssllib="polarssl";
-           } 
-          elsif ($libcurl =~ /axtls/i) {
-              $has_axtls=1;
-              $ssllib="axTLS";
-          }
+           }
+           elsif ($libcurl =~ /axtls/i) {
+               $has_axtls=1;
+               $ssllib="axTLS";
+           }
+           elsif ($libcurl =~ /securetransport/i) {
+               $has_darwinssl=1;
+               $ssllib="DarwinSSL";
+           }
+           if ($libcurl =~ /ares/i) {
+               $has_cares=1;
+               $resolver="c-ares";
+           }
         }
         elsif($_ =~ /^Protocols: (.*)/i) {
             # these are the protocols compiled in to this libcurl
-            @protocols = split(' ', $1);
+            @protocols = split(' ', lc($1));
 
             # Generate a "proto-ipv6" version of each protocol to match the
             # IPv6 <server> name. This works even if IPv6 support isn't
             # compiled in because the <features> test will fail.
-            push @protocols, map($_ . "-ipv6", @protocols);
+            push @protocols, map($_ . '-ipv6', @protocols);
 
-            # Hack - we need a different, non-stunnel server to test HTTP
-            # TLS-SRP, but we don't want to add HTTP+TLS-SRP as a protocol
-            # throughout curl
-            if ($has_gnutls) {
-                push @protocols, ('http+tls-srp');
-            }
+            # 'http-proxy' is used in test cases to do CONNECT through
+            push @protocols, 'http-proxy';
+
+            # 'http-pipe' is the special server for testing pipelining
+            push @protocols, 'http-pipe';
 
             # 'none' is used in test cases to mean no server
-            push @protocols, ('none');
+            push @protocols, 'none';
         }
         elsif($_ =~ /^Features: (.*)/i) {
             $feat = $1;
             if($feat =~ /TrackMemory/i) {
-                # curl was built with --enable-curldebug (memory tracking)
-                $curl_debug = 1;
+                # built with memory tracking support (--enable-curldebug)
+                $has_memory_tracking = 1;
             }
             if($feat =~ /debug/i) {
                 # curl was built with --enable-debug
@@ -2172,10 +2406,16 @@ sub checksystem {
             if($feat =~ /NTLM/i) {
                 # NTLM enabled
                 $has_ntlm=1;
+               # Use this as a proxy for any cryptographic authentication
+                $has_crypto=1;
             }
-            if($feat =~ /NTLM_SSO/i) {
-                # NTLM single-sign-on enabled
-                $has_ntlm_sso=1;
+            if($feat =~ /NTLM_WB/i) {
+                # NTLM delegation to winbind daemon ntlm_auth helper enabled
+                $has_ntlm_wb=1;
+            }
+            if($feat =~ /SSPI/i) {
+                # SSPI enabled
+                $has_sspi=1;
             }
             if($feat =~ /CharConv/i) {
                 # CharConv enabled
@@ -2185,6 +2425,38 @@ sub checksystem {
                 # TLS-SRP enabled
                 $has_tls_srp=1;
             }
+            if($feat =~ /Metalink/i) {
+                # Metalink enabled
+                $has_metalink=1;
+            }
+            if($feat =~ /AsynchDNS/i) {
+                if(!$has_cares) {
+                    # this means threaded resolver
+                    $has_threadedres=1;
+                    $resolver="threaded";
+                }
+            }
+        }
+        #
+        # Test harness currently uses a non-stunnel server in order to
+        # run HTTP TLS-SRP tests required when curl is built with https
+        # protocol support and TLS-SRP feature enabled. For convenience
+        # 'httptls' may be included in the test harness protocols array
+        # to differentiate this from classic stunnel based 'https' test
+        # harness server.
+        #
+        if($has_tls_srp) {
+            my $add_httptls;
+            for(@protocols) {
+                if($_ =~ /^https(-ipv6|)$/) {
+                    $add_httptls=1;
+                    last;
+                }
+            }
+            if($add_httptls && (! grep /^httptls$/, @protocols)) {
+                push @protocols, 'httptls';
+                push @protocols, 'httptls-ipv6';
+            }
         }
     }
     if(!$curl) {
@@ -2238,17 +2510,14 @@ sub checksystem {
         }
     }
 
-    if(!$curl_debug && $torture) {
-        die "can't run torture tests since curl was not built with curldebug";
+    if(!$has_memory_tracking && $torture) {
+        die "can't run torture tests since curl was built without ".
+            "TrackMemory feature (--enable-curldebug)";
     }
 
     $has_shared = `sh $CURLCONFIG --built-shared`;
     chomp $has_shared;
 
-    # curl doesn't list cryptographic support separately, so assume it's
-    # always available
-    $has_crypto=1;
-
     my $hostname=join(' ', runclientoutput("hostname"));
     my $hosttype=join(' ', runclientoutput("uname -a"));
 
@@ -2259,15 +2528,23 @@ sub checksystem {
     "* Host: $hostname",
     "* System: $hosttype");
 
+    if($has_memory_tracking && $has_threadedres) {
+        $has_memory_tracking = 0;
+        logmsg("*\n",
+               "*** DISABLES memory tracking when using threaded resolver\n",
+               "*\n");
+    }
+
     logmsg sprintf("* Server SSL:   %8s", $stunnel?"ON ":"OFF");
     logmsg sprintf("  libcurl SSL:  %s\n", $ssl_version?"ON ":"OFF");
     logmsg sprintf("* debug build:  %8s", $debug_build?"ON ":"OFF");
-    logmsg sprintf("  track memory: %s\n", $curl_debug?"ON ":"OFF");
+    logmsg sprintf("  track memory: %s\n", $has_memory_tracking?"ON ":"OFF");
     logmsg sprintf("* valgrind:     %8s", $valgrind?"ON ":"OFF");
     logmsg sprintf("  HTTP IPv6     %s\n", $http_ipv6?"ON ":"OFF");
     logmsg sprintf("* FTP IPv6      %8s", $ftp_ipv6?"ON ":"OFF");
     logmsg sprintf("  Libtool lib:  %s\n", $libtool?"ON ":"OFF");
-    logmsg sprintf("* Shared build:      %s\n", $has_shared);
+    logmsg sprintf("* Shared build:      %-3s", $has_shared);
+    logmsg sprintf("  Resolver:     %s\n", $resolver);
     if($ssl_version) {
         logmsg sprintf("* SSL library: %13s\n", $ssllib);
     }
@@ -2307,6 +2584,14 @@ sub checksystem {
         logmsg sprintf("IMAP-IPv6/%d ", $IMAP6PORT);
         logmsg sprintf("SMTP-IPv6/%d\n", $SMTP6PORT);
     }
+    if($httptlssrv) {
+        logmsg sprintf("*   HTTPTLS/%d ", $HTTPTLSPORT);
+        if($has_ipv6) {
+            logmsg sprintf("HTTPTLS-IPv6/%d ", $HTTPTLS6PORT);
+        }
+        logmsg "\n";
+    }
+    logmsg sprintf("*   HTTP-PIPE/%d \n", $HTTPPIPEPORT);
 
     $has_textaware = ($^O eq 'MSWin32') || ($^O eq 'msys');
 
@@ -2319,36 +2604,59 @@ sub checksystem {
 #
 sub subVariables {
   my ($thing) = @_;
-  $$thing =~ s/%HOSTIP/$HOSTIP/g;
-  $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
-  $$thing =~ s/%HOST6IP/$HOST6IP/g;
-  $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
-  $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
-  $$thing =~ s/%FTPPORT/$FTPPORT/g;
+
+  # ports
+
   $$thing =~ s/%FTP6PORT/$FTP6PORT/g;
   $$thing =~ s/%FTP2PORT/$FTP2PORT/g;
   $$thing =~ s/%FTPSPORT/$FTPSPORT/g;
-  $$thing =~ s/%SRCDIR/$srcdir/g;
-  $$thing =~ s/%PWD/$pwd/g;
-  $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
-  $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
-  $$thing =~ s/%SSHPORT/$SSHPORT/g;
-  $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
-  $$thing =~ s/%POP3PORT/$POP3PORT/g;
-  $$thing =~ s/%POP36PORT/$POP36PORT/g;
-  $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
+  $$thing =~ s/%FTPPORT/$FTPPORT/g;
+
+  $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
+  $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
+
+  $$thing =~ s/%HTTPTLS6PORT/$HTTPTLS6PORT/g;
+  $$thing =~ s/%HTTPTLSPORT/$HTTPTLSPORT/g;
+  $$thing =~ s/%HTTP6PORT/$HTTP6PORT/g;
+  $$thing =~ s/%HTTPSPORT/$HTTPSPORT/g;
+  $$thing =~ s/%HTTPPORT/$HTTPPORT/g;
+  $$thing =~ s/%HTTPPIPEPORT/$HTTPPIPEPORT/g;
+  $$thing =~ s/%PROXYPORT/$HTTPPROXYPORT/g;
+
   $$thing =~ s/%IMAP6PORT/$IMAP6PORT/g;
-  $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
+  $$thing =~ s/%IMAPPORT/$IMAPPORT/g;
+
+  $$thing =~ s/%POP36PORT/$POP36PORT/g;
+  $$thing =~ s/%POP3PORT/$POP3PORT/g;
+
+  $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
+  $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
+
   $$thing =~ s/%SMTP6PORT/$SMTP6PORT/g;
+  $$thing =~ s/%SMTPPORT/$SMTPPORT/g;
+
+  $$thing =~ s/%SOCKSPORT/$SOCKSPORT/g;
+  $$thing =~ s/%SSHPORT/$SSHPORT/g;
+
+  $$thing =~ s/%TFTP6PORT/$TFTP6PORT/g;
+  $$thing =~ s/%TFTPPORT/$TFTPPORT/g;
+
+  # client IP addresses
+
+  $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
+  $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
+
+  # server IP addresses
+
+  $$thing =~ s/%HOST6IP/$HOST6IP/g;
+  $$thing =~ s/%HOSTIP/$HOSTIP/g;
+
+  # misc
+
   $$thing =~ s/%CURL/$CURL/g;
+  $$thing =~ s/%PWD/$pwd/g;
+  $$thing =~ s/%SRCDIR/$srcdir/g;
   $$thing =~ s/%USER/$USER/g;
-  $$thing =~ s/%CLIENTIP/$CLIENTIP/g;
-  $$thing =~ s/%CLIENT6IP/$CLIENT6IP/g;
-  $$thing =~ s/%RTSPPORT/$RTSPPORT/g;
-  $$thing =~ s/%RTSP6PORT/$RTSP6PORT/g;
-  $$thing =~ s/%GOPHERPORT/$GOPHERPORT/g;
-  $$thing =~ s/%GOPHER6PORT/$GOPHER6PORT/g;
-  $$thing =~ s/%HTTPTLSSRPPORT/$HTTPTLSSRPPORT/g;
 
   # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
   # used for time-out tests and that whould work on most hosts as these
@@ -2425,7 +2733,11 @@ sub timestampskippedevents {
 # Run a single specified test case
 #
 sub singletest {
-    my ($testnum, $count, $total)=@_;
+    my ($evbased, # 1 means switch on if possible (and "curl" is tested)
+                  # returns "not a test" if it can't be used for this test
+        $testnum,
+        $count,
+        $total)=@_;
 
     my @what;
     my $why;
@@ -2459,103 +2771,257 @@ sub singletest {
         @what = getpart("client", "features");
     }
 
+    # We require a feature to be present
     for(@what) {
         my $f = $_;
         $f =~ s/\s//g;
 
-        $feature{$f}=$f; # we require this feature
+        if($f =~ /^([^!].*)$/) {
+            # Store the feature for later
+            $feature{$1} = $1;
 
-        if($f eq "SSL") {
-            if($ssl_version) {
-                next;
+            if($1 eq "SSL") {
+                if($ssl_version) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "OpenSSL") {
-            if($has_openssl) {
-                next;
+            elsif($1 eq "OpenSSL") {
+                if($has_openssl) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "GnuTLS") {
-            if($has_gnutls) {
-                next;
+            elsif($1 eq "GnuTLS") {
+                if($has_gnutls) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "NSS") {
-            if($has_nss) {
-                next;
+            elsif($1 eq "NSS") {
+                if($has_nss) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "axTLS") {
-            if($has_axtls) {
-                next;
+            elsif($1 eq "axTLS") {
+                if($has_axtls) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "unittest") {
-            if($debug_build) {
-                next;
+            elsif($1 eq "WinSSL") {
+                if($has_winssl) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "large_file") {
-            if($large_file) {
-                next;
+            elsif($1 eq "DarwinSSL") {
+                if($has_darwinssl) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "idn") {
-            if($has_idn) {
-                next;
+            elsif($1 eq "unittest") {
+                if($debug_build) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "ipv6") {
-            if($has_ipv6) {
-                next;
+            elsif($1 eq "debug") {
+                if($debug_build) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "libz") {
-            if($has_libz) {
-                next;
+            elsif($1 eq "TrackMemory") {
+                if($has_memory_tracking) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "NTLM") {
-            if($has_ntlm) {
-                next;
+            elsif($1 eq "large_file") {
+                if($large_file) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "NTLM_SSO") {
-            if($has_ntlm_sso) {
-                next;
+            elsif($1 eq "idn") {
+                if($has_idn) {
+                    next;
+                }
             }
-        }
-        elsif($f eq "getrlimit") {
-            if($has_getrlimit) {
+            elsif($1 eq "ipv6") {
+                if($has_ipv6) {
+                    next;
+                }
+            }
+            elsif($1 eq "libz") {
+                if($has_libz) {
+                    next;
+                }
+            }
+            elsif($1 eq "NTLM") {
+                if($has_ntlm) {
+                    next;
+                }
+            }
+            elsif($1 eq "NTLM_WB") {
+                if($has_ntlm_wb) {
+                    next;
+                }
+            }
+            elsif($1 eq "SSPI") {
+                if($has_sspi) {
+                    next;
+                }
+            }
+            elsif($1 eq "getrlimit") {
+                if($has_getrlimit) {
+                    next;
+                }
+            }
+            elsif($1 eq "crypto") {
+                if($has_crypto) {
+                    next;
+                }
+            }
+            elsif($1 eq "TLS-SRP") {
+                if($has_tls_srp) {
+                    next;
+                }
+            }
+            elsif($1 eq "Metalink") {
+                if($has_metalink) {
+                    next;
+                }
+            }
+            elsif($1 eq "socks") {
                 next;
             }
-        }
-        elsif($f eq "crypto") {
-            if($has_crypto) {
+            # See if this "feature" is in the list of supported protocols
+            elsif (grep /^\Q$1\E$/i, @protocols) {
                 next;
             }
+
+            $why = "curl lacks $1 support";
+            last;
         }
-        elsif($f eq "TLS-SRP") {
-            if($has_tls_srp) {
+    }
+
+    # We require a feature to not be present
+    if(!$why) {
+        for(@what) {
+            my $f = $_;
+            $f =~ s/\s//g;
+
+            if($f =~ /^!(.*)$/) {
+                if($1 eq "SSL") {
+                    if(!$ssl_version) {
+                        next;
+                    }
+                }
+                elsif($1 eq "OpenSSL") {
+                    if(!$has_openssl) {
+                        next;
+                    }
+                }
+                elsif($1 eq "GnuTLS") {
+                    if(!$has_gnutls) {
+                        next;
+                    }
+                }
+                elsif($1 eq "NSS") {
+                    if(!$has_nss) {
+                        next;
+                    }
+                }
+                elsif($1 eq "axTLS") {
+                    if(!$has_axtls) {
+                        next;
+                    }
+                }
+                elsif($1 eq "WinSSL") {
+                    if(!$has_winssl) {
+                        next;
+                    }
+                }
+                elsif($1 eq "DarwinSSL") {
+                    if(!$has_darwinssl) {
+                        next;
+                    }
+                }
+                elsif($1 eq "TrackMemory") {
+                    if(!$has_memory_tracking) {
+                        next;
+                    }
+                }
+                elsif($1 eq "large_file") {
+                    if(!$large_file) {
+                        next;
+                    }
+                }
+                elsif($1 eq "idn") {
+                    if(!$has_idn) {
+                        next;
+                    }
+                }
+                elsif($1 eq "ipv6") {
+                    if(!$has_ipv6) {
+                        next;
+                    }
+                }
+                elsif($1 eq "libz") {
+                    if(!$has_libz) {
+                        next;
+                    }
+                }
+                elsif($1 eq "NTLM") {
+                    if(!$has_ntlm) {
+                        next;
+                    }
+                }
+                elsif($1 eq "NTLM_WB") {
+                    if(!$has_ntlm_wb) {
+                        next;
+                    }
+                }
+                elsif($1 eq "SSPI") {
+                    if(!$has_sspi) {
+                        next;
+                    }
+                }
+                elsif($1 eq "getrlimit") {
+                    if(!$has_getrlimit) {
+                        next;
+                    }
+                }
+                elsif($1 eq "crypto") {
+                    if(!$has_crypto) {
+                        next;
+                    }
+                }
+                elsif($1 eq "TLS-SRP") {
+                    if(!$has_tls_srp) {
+                        next;
+                    }
+                }
+                elsif($1 eq "Metalink") {
+                    if(!$has_metalink) {
+                        next;
+                    }
+                }
+                else {
+                    next;
+                }
+            }
+            else {
                 next;
             }
-        }
-        elsif($f eq "socks") {
-            next;
-        }
-        # See if this "feature" is in the list of supported protocols
-        elsif (grep /^$f$/, @protocols) {
-            next;
-        }
 
-        $why = "curl lacks $f support";
-        last;
+            $why = "curl has $1 support";
+            last;
+        }
     }
 
     if(!$why) {
         my @keywords = getpart("info", "keywords");
         my $match;
         my $k;
+
+        if(!$keywords[0]) {
+            $why = "missing the <keywords> section!";
+        }
+
         for $k (@keywords) {
             chomp $k;
             if ($disabled_keywords{$k}) {
@@ -2585,6 +3051,9 @@ sub singletest {
         delete $oldenv{$var};
     }
 
+    # remove test server commands file before servers are started/verified
+    unlink($FTPDCMD) if(-f $FTPDCMD);
+
     # timestamp required servers verification start
     $timesrvrini{$testnum} = Time::HiRes::time() if($timestats);
 
@@ -2669,27 +3138,35 @@ sub singletest {
         $teststat[$testnum]=$why; # store reason for this test case
 
         if(!$short) {
-            printf "test %03d SKIPPED: $why\n", $testnum;
+            if($skipped{$why} <= 3) {
+                # show only the first three skips for each reason
+                logmsg sprintf("test %03d SKIPPED: $why\n", $testnum);
+            }
         }
 
         timestampskippedevents($testnum);
         return -1;
     }
-    logmsg sprintf("test %03d...", $testnum);
+    logmsg sprintf("test %03d...", $testnum) if(!$automakestyle);
 
     # extract the reply data
     my @reply = getpart("reply", "data");
     my @replycheck = getpart("reply", "datacheck");
 
+    my %replyattr = getpartattr("reply", "data");
+    my %replycheckattr = getpartattr("reply", "datacheck");
+
     if (@replycheck) {
         # we use this file instead to check the final output against
 
-        my %hash = getpartattr("reply", "datacheck");
-        if($hash{'nonewline'}) {
+        if($replycheckattr{'nonewline'}) {
             # Yes, we must cut off the final newline from the final line
             # of the datacheck
             chomp($replycheck[$#replycheck]);
         }
+        if($replycheckattr{'mode'}) {
+            $replyattr{'mode'} = $replycheckattr{'mode'};
+        }
 
         @reply=@replycheck;
     }
@@ -2697,6 +3174,9 @@ sub singletest {
     # this is the valid protocol blurb curl should generate
     my @protocol= fixarray ( getpart("verify", "protocol") );
 
+    # this is the valid protocol blurb curl should generate to a proxy
+    my @proxyprot = fixarray ( getpart("verify", "proxy") );
+
     # redirected stdout/stderr to these files
     $STDOUT="$LOGDIR/stdout$testnum";
     $STDERR="$LOGDIR/stderr$testnum";
@@ -2714,12 +3194,9 @@ sub singletest {
 
     # name of the test
     my @testname= getpart("client", "name");
-
-    if(!$short) {
-        my $name = $testname[0];
-        $name =~ s/\n//g;
-        logmsg "[$name]\n";
-    }
+    my $testname = $testname[0];
+    $testname =~ s/\n//g;
+    logmsg "[$testname]\n" if(!$short);
 
     if($listonly) {
         timestampskippedevents($testnum);
@@ -2734,9 +3211,10 @@ sub singletest {
         chomp $tool;
     }
 
-    # remove server output logfiles
+    # remove server output logfile
     unlink($SERVERIN);
     unlink($SERVER2IN);
+    unlink($PROXYIN);
 
     if(@ftpservercmd) {
         # write the instructions to file
@@ -2757,7 +3235,7 @@ sub singletest {
         # there was no command given, use something silly
         $cmd="-";
     }
-    if($curl_debug) {
+    if($has_memory_tracking) {
         unlink($memdump);
     }
 
@@ -2810,6 +3288,7 @@ sub singletest {
     my $CMDLINE;
     my $cmdargs;
     my $cmdtype = $cmdhash{'type'} || "default";
+    my $fail_due_event_based = $evbased;
     if($cmdtype eq "perl") {
         # run the command line prepended with "perl"
         $cmdargs ="$cmd";
@@ -2817,10 +3296,30 @@ sub singletest {
         $tool=$CMDLINE;
         $disablevalgrind=1;
     }
+    elsif($cmdtype eq "shell") {
+        # run the command line prepended with "/bin/sh"
+        $cmdargs ="$cmd";
+        $CMDLINE = "/bin/sh ";
+        $tool=$CMDLINE;
+        $disablevalgrind=1;
+    }
     elsif(!$tool) {
-        # run curl, add --verbose for debug information output
-       $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
-        $cmdargs ="$out --include --verbose --trace-time $cmd";
+        # run curl, add suitable command line options
+        $cmd = "-1 ".$cmd if(exists $feature{"SSL"} && ($has_axtls));
+
+        my $inc="";
+        if((!$cmdhash{'option'}) || ($cmdhash{'option'} !~ /no-include/)) {
+            $inc = " --include";
+        }
+
+        $cmdargs = "$out$inc ";
+        $cmdargs .= "--trace-ascii log/trace$testnum ";
+        $cmdargs .= "--trace-time ";
+        if($evbased) {
+            $cmdargs .= "--test-event ";
+            $fail_due_event_based--;
+        }
+        $cmdargs .= $cmd;
     }
     else {
         $cmdargs = " $cmd"; # $cmd is the command line for the test file
@@ -2834,17 +3333,36 @@ sub singletest {
         }
 
         if(! -f $CMDLINE) {
-            print "The tool set in the test case for this: '$tool' does not exist\n";
+            logmsg "The tool set in the test case for this: '$tool' does not exist\n";
             timestampskippedevents($testnum);
             return -1;
         }
         $DBGCURL=$CMDLINE;
     }
 
+    if($gdbthis) {
+        # gdb is incompatible with valgrind, so disable it when debugging
+        # Perhaps a better approach would be to run it under valgrind anyway
+        # with --db-attach=yes or --vgdb=yes.
+        $disablevalgrind=1;
+    }
+
+    if($fail_due_event_based) {
+        logmsg "This test cannot run event based\n";
+        return -1;
+    }
+
     my @stdintest = getpart("client", "stdin");
 
     if(@stdintest) {
         my $stdinfile="$LOGDIR/stdin-for-$testnum";
+
+        my %hash = getpartattr("client", "stdin");
+        if($hash{'nonewline'}) {
+            # cut off the final newline from the final line of the stdin data
+            chomp($stdintest[$#stdintest]);
+        }
+
         writearray($stdinfile, \@stdintest);
 
         $cmdargs .= " <$stdinfile";
@@ -2862,6 +3380,8 @@ sub singletest {
             my $valgrindcmd = "$valgrind ";
             $valgrindcmd .= "$valgrind_tool " if($valgrind_tool);
             $valgrindcmd .= "--leak-check=yes ";
+            $valgrindcmd .= "--suppressions=$srcdir/valgrind.supp ";
+           # $valgrindcmd .= "--gen-suppressions=all ";
             $valgrindcmd .= "--num-callers=16 ";
             $valgrindcmd .= "${valgrind_logfile}=$LOGDIR/valgrind$testnum";
             $CMDLINE = "$valgrindcmd $CMDLINE";
@@ -2914,7 +3434,8 @@ sub singletest {
                        "$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
     }
     elsif($gdbthis) {
-        runclient("$gdb --directory libtest $DBGCURL -x $LOGDIR/gdbcmd");
+        my $GDBW = ($gdbxwin) ? "-w" : "";
+        runclient("$gdb --directory libtest $DBGCURL $GDBW -x $LOGDIR/gdbcmd");
         $cmdres=0; # makes it always continue after a debugged run
     }
     else {
@@ -2974,6 +3495,10 @@ sub singletest {
     # Test harness ssh server does not have this synchronization mechanism,
     # this implies that some ssh server based tests might need a small delay
     # once that the client command has run to avoid false test failures.
+    #
+    # gnutls-serv also lacks this synchronization mechanism, so gnutls-serv
+    # based tests might need a small delay once that the client command has
+    # run to avoid false test failures.
 
     sleep($postcommanddelay) if($postcommanddelay);
 
@@ -2991,20 +3516,20 @@ sub singletest {
         my @killservers;
         foreach my $server (@killtestservers) {
             chomp $server;
-            if($server =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
-                # given an ssl server, also kill non-ssl underlying one
+            if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
+                # given a stunnel ssl server, also kill non-ssl underlying one
                 push @killservers, "${1}${2}";
             }
-            elsif($server =~ /^(ftp|http|imap|pop3|smtp)(.*)$/) {
-                # given a non-ssl server, also kill ssl piggybacking one
+            elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|))$/) {
+                # given a non-ssl server, also kill stunnel piggybacking one
                 push @killservers, "${1}s${2}";
             }
-            elsif($server =~ /^(socks)(.*)$/) {
-                # given an socks server, also kill ssh underlying one
+            elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
+                # given a socks server, also kill ssh underlying one
                 push @killservers, "ssh${2}";
             }
-            elsif($server =~ /^(ssh)(.*)$/) {
-                # given an ssh server, also kill socks piggybacking one
+            elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
+                # given a ssh server, also kill socks piggybacking one
                 push @killservers, "socks${2}";
             }
             push @killservers, $server;
@@ -3047,7 +3572,7 @@ sub singletest {
     }
 
     # remove the test server commands file after each test
-    unlink($FTPDCMD);
+    unlink($FTPDCMD) if(-f $FTPDCMD);
 
     # run the postcheck command
     my @postcheck= getpart("client", "postcheck");
@@ -3095,6 +3620,7 @@ sub singletest {
     my $errorcode = $err[0] || "0";
     my $ok="";
     my $res;
+    chomp $errorcode;
     if (@validstdout) {
         # verify redirected stdout
         my @actual = loadarray($STDOUT);
@@ -3109,7 +3635,8 @@ sub singletest {
         my $filemode=$hash{'mode'};
         if($filemode && ($filemode eq "text") && $has_textaware) {
             # text mode when running on windows: fix line endings
-            map s/\r\n/\n/g, @actual;
+            map s/\r\n/\n/g, @validstdout;
+            map s/\n/\r\n/g, @validstdout;
         }
 
         if($hash{'nonewline'}) {
@@ -3118,10 +3645,8 @@ sub singletest {
             chomp($validstdout[$#validstdout]);
         }
 
-        $res = compare("stdout", \@actual, \@validstdout);
+        $res = compare($testnum, $testname, "stdout", \@actual, \@validstdout);
         if($res) {
-            # timestamp test result verification end
-            $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
             return 1;
         }
         $ok .= "s";
@@ -3130,22 +3655,66 @@ sub singletest {
         $ok .= "-"; # stdout not checked
     }
 
-    my %replyattr = getpartattr("reply", "data");
+    if(@protocol) {
+        # Verify the sent request
+        my @out = loadarray($SERVERIN);
+
+        # what to cut off from the live protocol sent by curl
+        my @strip = getpart("verify", "strip");
+
+        my @protstrip=@protocol;
+
+        # check if there's any attributes on the verify/protocol section
+        my %hash = getpartattr("verify", "protocol");
+
+        if($hash{'nonewline'}) {
+            # Yes, we must cut off the final newline from the final line
+            # of the protocol data
+            chomp($protstrip[$#protstrip]);
+        }
+
+        for(@strip) {
+            # strip off all lines that match the patterns from both arrays
+            chomp $_;
+            @out = striparray( $_, \@out);
+            @protstrip= striparray( $_, \@protstrip);
+        }
+
+        # what parts to cut off from the protocol
+        my @strippart = getpart("verify", "strippart");
+        my $strip;
+        for $strip (@strippart) {
+            chomp $strip;
+            for(@out) {
+                eval $strip;
+            }
+        }
+
+        $res = compare($testnum, $testname, "protocol", \@out, \@protstrip);
+        if($res) {
+            return 1;
+        }
+
+        $ok .= "p";
+
+    }
+    else {
+        $ok .= "-"; # protocol not checked
+    }
+
     if(!$replyattr{'nocheck'} && (@reply || $replyattr{'sendzero'})) {
         # verify the received data
         my @out = loadarray($CURLOUT);
-        my %hash = getpartattr("reply", "data");
         # get the mode attribute
-        my $filemode=$hash{'mode'};
+        my $filemode=$replyattr{'mode'};
         if($filemode && ($filemode eq "text") && $has_textaware) {
             # text mode when running on windows: fix line endings
-            map s/\r\n/\n/g, @out;
+            map s/\r\n/\n/g, @reply;
+            map s/\n/\r\n/g, @reply;
         }
 
-        $res = compare("data", \@out, \@reply);
+        $res = compare($testnum, $testname, "data", \@out, \@reply);
         if ($res) {
-            # timestamp test result verification end
-            $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
             return 1;
         }
         $ok .= "d";
@@ -3157,10 +3726,8 @@ sub singletest {
     if(@upload) {
         # verify uploaded data
         my @out = loadarray("$LOGDIR/upload.$testnum");
-        $res = compare("upload", \@out, \@upload);
+        $res = compare($testnum, $testname, "upload", \@out, \@upload);
         if ($res) {
-            # timestamp test result verification end
-            $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
             return 1;
         }
         $ok .= "u";
@@ -3169,17 +3736,18 @@ sub singletest {
         $ok .= "-"; # upload not checked
     }
 
-    if(@protocol) {
-        # Verify the sent request
-        my @out = loadarray($SERVERIN);
+    if(@proxyprot) {
+        # Verify the sent proxy request
+        my @out = loadarray($PROXYIN);
 
-        # what to cut off from the live protocol sent by curl
+        # what to cut off from the live protocol sent by curl, we use the
+        # same rules as for <protocol>
         my @strip = getpart("verify", "strip");
 
-        my @protstrip=@protocol;
+        my @protstrip=@proxyprot;
 
         # check if there's any attributes on the verify/protocol section
-        my %hash = getpartattr("verify", "protocol");
+        my %hash = getpartattr("verify", "proxy");
 
         if($hash{'nonewline'}) {
             # Yes, we must cut off the final newline from the final line
@@ -3204,67 +3772,73 @@ sub singletest {
             }
         }
 
-        $res = compare("protocol", \@out, \@protstrip);
+        $res = compare($testnum, $testname, "proxy", \@out, \@protstrip);
         if($res) {
-            # timestamp test result verification end
-            $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
             return 1;
         }
 
-        $ok .= "p";
+        $ok .= "P";
 
     }
     else {
         $ok .= "-"; # protocol not checked
     }
 
-    my @outfile=getpart("verify", "file");
-    if(@outfile) {
-        # we're supposed to verify a dynamically generated file!
-        my %hash = getpartattr("verify", "file");
+    my $outputok;
+    for my $partsuffix (('', '1', '2', '3', '4')) {
+        my @outfile=getpart("verify", "file".$partsuffix);
+        if(@outfile || partexists("verify", "file".$partsuffix) ) {
+            # we're supposed to verify a dynamically generated file!
+            my %hash = getpartattr("verify", "file".$partsuffix);
 
-        my $filename=$hash{'name'};
-        if(!$filename) {
-            logmsg "ERROR: section verify=>file has no name attribute\n";
-            stopservers($verbose);
-            # timestamp test result verification end
-            $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
-            return -1;
-        }
-        my @generated=loadarray($filename);
+            my $filename=$hash{'name'};
+            if(!$filename) {
+                logmsg "ERROR: section verify=>file$partsuffix ".
+                       "has no name attribute\n";
+                stopservers($verbose);
+                # timestamp test result verification end
+                $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
+                return -1;
+            }
+            my @generated=loadarray($filename);
 
-        # what parts to cut off from the file
-        my @stripfile = getpart("verify", "stripfile");
+            # what parts to cut off from the file
+            my @stripfile = getpart("verify", "stripfile".$partsuffix);
 
-        my $filemode=$hash{'mode'};
-        if($filemode && ($filemode eq "text") && $has_textaware) {
-            # text mode when running on windows means adding an extra
-            # strip expression
-            push @stripfile, "s/\r\n/\n/";
-        }
+            my $filemode=$hash{'mode'};
+            if($filemode && ($filemode eq "text") && $has_textaware) {
+                # text mode when running on windows: fix line endings
+                map s/\r\n/\n/g, @outfile;
+                map s/\n/\r\n/g, @outfile;
+            }
 
-        my $strip;
-        for $strip (@stripfile) {
-            chomp $strip;
-            for(@generated) {
-                eval $strip;
+            my $strip;
+            for $strip (@stripfile) {
+                chomp $strip;
+                my @newgen;
+                for(@generated) {
+                    eval $strip;
+                    if($_) {
+                        push @newgen, $_;
+                    }
+                }
+                # this is to get rid of array entries that vanished (zero
+                # length) because of replacements
+                @generated = @newgen;
             }
-        }
 
-        @outfile = fixarray(@outfile);
+            @outfile = fixarray(@outfile);
 
-        $res = compare("output", \@generated, \@outfile);
-        if($res) {
-            # timestamp test result verification end
-            $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
-            return 1;
-        }
+            $res = compare($testnum, $testname, "output ($filename)",
+                           \@generated, \@outfile);
+            if($res) {
+                return 1;
+            }
 
-        $ok .= "o";
-    }
-    else {
-        $ok .= "-"; # output not checked
+            $outputok = 1; # output checked
+        }
     }
+    $ok .= ($outputok) ? "o" : "-"; # output checked or not
 
     # accept multiple comma-separated error codes
     my @splerr = split(/ *, */, $errorcode);
@@ -3282,8 +3856,8 @@ sub singletest {
     }
     else {
         if(!$short) {
-            printf("\n%s returned $cmdres, %d was expected\n",
-                   (!$tool)?"curl":$tool, $errorcode);
+            logmsg sprintf("\n%s returned $cmdres, when expecting %s\n",
+                           (!$tool)?"curl":$tool, $errorcode);
         }
         logmsg " exit FAILED\n";
         # timestamp test result verification end
@@ -3291,9 +3865,9 @@ sub singletest {
         return 1;
     }
 
-    if($curl_debug) {
+    if($has_memory_tracking) {
         if(! -f $memdump) {
-            logmsg "\n** ALERT! memory debugging with no output file?\n"
+            logmsg "\n** ALERT! memory tracking with no output file?\n"
                 if(!$cmdtype eq "perl");
         }
         else {
@@ -3347,8 +3921,13 @@ sub singletest {
             }
             my @e = valgrindparse($srcdir, $feature{'SSL'}, "$LOGDIR/$vgfile");
             if(@e && $e[0]) {
-                logmsg " valgrind ERROR ";
-                logmsg @e;
+                if($automakestyle) {
+                    logmsg "FAIL: $testnum - $testname - valgrind\n";
+                }
+                else {
+                    logmsg " valgrind ERROR ";
+                    logmsg @e;
+                }
                 # timestamp test result verification end
                 $timevrfyend{$testnum} = Time::HiRes::time() if($timestats);
                 return 1;
@@ -3365,6 +3944,8 @@ sub singletest {
     else {
         $ok .= "-"; # valgrind not checked
     }
+    # add 'E' for event-based
+    $ok .= $evbased ? "E" : "-";
 
     logmsg "$ok " if(!$short);
 
@@ -3374,7 +3955,13 @@ sub singletest {
     my $left=sprintf("remaining: %02d:%02d",
                      $estleft/60,
                      $estleft%60);
-    printf "OK (%-3d out of %-3d, %s)\n", $count, $total, $left;
+
+    if(!$automakestyle) {
+        logmsg sprintf("OK (%-3d out of %-3d, %s)\n", $count, $total, $left);
+    }
+    else {
+        logmsg "PASS: $testnum - $testname\n";
+    }
 
     # the test succeeded, remove all log files
     if(!$keepoutfiles) {
@@ -3389,6 +3976,7 @@ sub singletest {
 
 #######################################################################
 # Stop all running test servers
+#
 sub stopservers {
     my $verbose = $_[0];
     #
@@ -3436,17 +4024,17 @@ sub stopservers {
 # startservers() starts all the named servers
 #
 # Returns: string with error reason or blank for success
-
+#
 sub startservers {
     my @what = @_;
     my ($pid, $pid2);
     for(@what) {
         my (@whatlist) = split(/\s+/,$_);
         my $what = lc($whatlist[0]);
-        $what =~ s/[^a-z0-9-+]//g;
+        $what =~ s/[^a-z0-9-]//g;
 
         my $certfile;
-        if($what =~ /^(ftp|http|imap|pop3|smtp)s(.*)$/) {
+        if($what =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|))$/) {
             $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
         }
 
@@ -3454,6 +4042,10 @@ sub startservers {
            ($what eq "ftp") ||
            ($what eq "imap") ||
            ($what eq "smtp")) {
+            if($torture && $run{$what} &&
+               !responsive_pingpong_server($what, "", $verbose)) {
+                stopserver($what);
+            }
             if(!$run{$what}) {
                 ($pid, $pid2) = runpingpongserver($what, "", $verbose);
                 if($pid <= 0) {
@@ -3464,6 +4056,10 @@ sub startservers {
             }
         }
         elsif($what eq "ftp2") {
+            if($torture && $run{'ftp2'} &&
+               !responsive_pingpong_server("ftp", "2", $verbose)) {
+                stopserver('ftp2');
+            }
             if(!$run{'ftp2'}) {
                 ($pid, $pid2) = runpingpongserver("ftp", "2", $verbose);
                 if($pid <= 0) {
@@ -3474,6 +4070,10 @@ sub startservers {
             }
         }
         elsif($what eq "ftp-ipv6") {
+            if($torture && $run{'ftp-ipv6'} &&
+               !responsive_pingpong_server("ftp", "", $verbose, "ipv6")) {
+                stopserver('ftp-ipv6');
+            }
             if(!$run{'ftp-ipv6'}) {
                 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
                 if($pid <= 0) {
@@ -3485,17 +4085,27 @@ sub startservers {
             }
         }
         elsif($what eq "gopher") {
+            if($torture && $run{'gopher'} &&
+               !responsive_http_server("gopher", $verbose, 0, $GOPHERPORT)) {
+                stopserver('gopher');
+            }
             if(!$run{'gopher'}) {
                 ($pid, $pid2) = runhttpserver("gopher", $verbose, 0,
                                               $GOPHERPORT);
                 if($pid <= 0) {
                     return "failed starting GOPHER server";
                 }
-                printf ("* pid gopher => %d %d\n", $pid, $pid2) if($verbose);
+                logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
+                    if($verbose);
                 $run{'gopher'}="$pid $pid2";
             }
         }
         elsif($what eq "gopher-ipv6") {
+            if($torture && $run{'gopher-ipv6'} &&
+               !responsive_http_server("gopher", $verbose, "ipv6",
+                                       $GOPHER6PORT)) {
+                stopserver('gopher-ipv6');
+            }
             if(!$run{'gopher-ipv6'}) {
                 ($pid, $pid2) = runhttpserver("gopher", $verbose, "ipv6",
                                               $GOPHER6PORT);
@@ -3508,19 +4118,45 @@ sub startservers {
             }
         }
         elsif($what eq "http") {
+            if($torture && $run{'http'} &&
+               !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
+                stopserver('http');
+            }
             if(!$run{'http'}) {
                 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
                                               $HTTPPORT);
                 if($pid <= 0) {
                     return "failed starting HTTP server";
                 }
-                printf ("* pid http => %d %d\n", $pid, $pid2) if($verbose);
+                logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
+                    if($verbose);
                 $run{'http'}="$pid $pid2";
             }
         }
+        elsif($what eq "http-proxy") {
+            if($torture && $run{'http-proxy'} &&
+               !responsive_http_server("http", $verbose, "proxy",
+                                       $HTTPPROXYPORT)) {
+                stopserver('http-proxy');
+            }
+            if(!$run{'http-proxy'}) {
+                ($pid, $pid2) = runhttpserver("http", $verbose, "proxy",
+                                              $HTTPPROXYPORT);
+                if($pid <= 0) {
+                    return "failed starting HTTP-proxy server";
+                }
+                logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
+                    if($verbose);
+                $run{'http-proxy'}="$pid $pid2";
+            }
+        }
         elsif($what eq "http-ipv6") {
+            if($torture && $run{'http-ipv6'} &&
+               !responsive_http_server("http", $verbose, "IPv6", $HTTP6PORT)) {
+                stopserver('http-ipv6');
+            }
             if(!$run{'http-ipv6'}) {
-                ($pid, $pid2) = runhttpserver("http", $verbose, "IPv6",
+                ($pid, $pid2) = runhttpserver("http", $verbose, "ipv6",
                                               $HTTP6PORT);
                 if($pid <= 0) {
                     return "failed starting HTTP-IPv6 server";
@@ -3530,7 +4166,28 @@ sub startservers {
                 $run{'http-ipv6'}="$pid $pid2";
             }
         }
+        elsif($what eq "http-pipe") {
+            if($torture && $run{'http-pipe'} &&
+               !responsive_http_server("http", $verbose, "pipe",
+                                       $HTTPPIPEPORT)) {
+                stopserver('http-pipe');
+            }
+            if(!$run{'http-pipe'}) {
+                ($pid, $pid2) = runhttpserver("http", $verbose, "pipe",
+                                              $HTTPPIPEPORT);
+                if($pid <= 0) {
+                    return "failed starting HTTP-pipe server";
+                }
+                logmsg sprintf ("* pid http-pipe => %d %d\n", $pid, $pid2)
+                    if($verbose);
+                $run{'http-pipe'}="$pid $pid2";
+            }
+        }
         elsif($what eq "rtsp") {
+            if($torture && $run{'rtsp'} &&
+               !responsive_rtsp_server($verbose)) {
+                stopserver('rtsp');
+            }
             if(!$run{'rtsp'}) {
                 ($pid, $pid2) = runrtspserver($verbose);
                 if($pid <= 0) {
@@ -3541,6 +4198,10 @@ sub startservers {
             }
         }
         elsif($what eq "rtsp-ipv6") {
+            if($torture && $run{'rtsp-ipv6'} &&
+               !responsive_rtsp_server($verbose, "IPv6")) {
+                stopserver('rtsp-ipv6');
+            }
             if(!$run{'rtsp-ipv6'}) {
                 ($pid, $pid2) = runrtspserver($verbose, "IPv6");
                 if($pid <= 0) {
@@ -3551,7 +4212,6 @@ sub startservers {
                 $run{'rtsp-ipv6'}="$pid $pid2";
             }
         }
-
         elsif($what eq "ftps") {
             if(!$stunnel) {
                 # we can't run ftps tests without stunnel
@@ -3565,6 +4225,10 @@ sub startservers {
                 # stop server when running and using a different cert
                 stopserver('ftps');
             }
+            if($torture && $run{'ftp'} &&
+               !responsive_pingpong_server("ftp", "", $verbose)) {
+                stopserver('ftp');
+            }
             if(!$run{'ftp'}) {
                 ($pid, $pid2) = runpingpongserver("ftp", "", $verbose);
                 if($pid <= 0) {
@@ -3588,17 +4252,21 @@ sub startservers {
         }
         elsif($what eq "https") {
             if(!$stunnel) {
-                # we can't run ftps tests without stunnel
+                # we can't run https tests without stunnel
                 return "no stunnel";
             }
             if(!$ssl_version) {
-                # we can't run ftps tests if libcurl is SSL-less
+                # we can't run https tests if libcurl is SSL-less
                 return "curl lacks SSL support";
             }
             if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
                 # stop server when running and using a different cert
                 stopserver('https');
             }
+            if($torture && $run{'http'} &&
+               !responsive_http_server("http", $verbose, 0, $HTTPPORT)) {
+                stopserver('http');
+            }
             if(!$run{'http'}) {
                 ($pid, $pid2) = runhttpserver("http", $verbose, 0,
                                               $HTTPPORT);
@@ -3618,21 +4286,49 @@ sub startservers {
                 $run{'https'}="$pid $pid2";
             }
         }
-        elsif($what eq "http+tls-srp") {
-            if(!$has_gnutls) {
-                return "no GnuTLS";
+        elsif($what eq "httptls") {
+            if(!$httptlssrv) {
+                # for now, we can't run http TLS-EXT tests without gnutls-serv
+                return "no gnutls-serv";
             }
-            if(!$run{'http+tls-srp'}) {
-                ($pid, $pid2) = runhttptlssrpserver($verbose);
+            if($torture && $run{'httptls'} &&
+               !responsive_httptls_server($verbose, "IPv4")) {
+                stopserver('httptls');
+            }
+            if(!$run{'httptls'}) {
+                ($pid, $pid2) = runhttptlsserver($verbose, "IPv4");
                 if($pid <= 0) {
-                    return "failed starting HTTP+TLS-SRP server (gnutls-serv)";
+                    return "failed starting HTTPTLS server (gnutls-serv)";
                 }
-                logmsg sprintf("* pid http+tls-srp => %d %d\n", $pid, $pid2)
+                logmsg sprintf("* pid httptls => %d %d\n", $pid, $pid2)
                     if($verbose);
-                $run{'http+tls-srp'}="$pid $pid2";
+                $run{'httptls'}="$pid $pid2";
+            }
+        }
+        elsif($what eq "httptls-ipv6") {
+            if(!$httptlssrv) {
+                # for now, we can't run http TLS-EXT tests without gnutls-serv
+                return "no gnutls-serv";
+            }
+            if($torture && $run{'httptls-ipv6'} &&
+               !responsive_httptls_server($verbose, "IPv6")) {
+                stopserver('httptls-ipv6');
+            }
+            if(!$run{'httptls-ipv6'}) {
+                ($pid, $pid2) = runhttptlsserver($verbose, "IPv6");
+                if($pid <= 0) {
+                    return "failed starting HTTPTLS-IPv6 server (gnutls-serv)";
+                }
+                logmsg sprintf("* pid httptls-ipv6 => %d %d\n", $pid, $pid2)
+                    if($verbose);
+                $run{'httptls-ipv6'}="$pid $pid2";
             }
         }
         elsif($what eq "tftp") {
+            if($torture && $run{'tftp'} &&
+               !responsive_tftp_server("", $verbose)) {
+                stopserver('tftp');
+            }
             if(!$run{'tftp'}) {
                 ($pid, $pid2) = runtftpserver("", $verbose);
                 if($pid <= 0) {
@@ -3643,6 +4339,10 @@ sub startservers {
             }
         }
         elsif($what eq "tftp-ipv6") {
+            if($torture && $run{'tftp-ipv6'} &&
+               !responsive_tftp_server("", $verbose, "IPv6")) {
+                stopserver('tftp-ipv6');
+            }
             if(!$run{'tftp-ipv6'}) {
                 ($pid, $pid2) = runtftpserver("", $verbose, "IPv6");
                 if($pid <= 0) {
@@ -3707,7 +4407,6 @@ sub startservers {
 #
 # Returns: a string, blank if everything is fine or a reason why it failed
 #
-
 sub serverfortest {
     my ($testnum)=@_;
 
@@ -3718,14 +4417,28 @@ sub serverfortest {
         return "no server specified";
     }
 
-    for (@what) {
-        my $proto = lc($_);
-        chomp $proto;
-        $proto =~ s/\s.*//g;  # take first word
-        if (! grep /^\Q$proto\E$/, @protocols) {
-            if (substr($proto,0,5) ne "socks") {
-                return "curl lacks $proto support";
+    for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
+        my $srvrline = $what[$i];
+        chomp $srvrline if($srvrline);
+        if($srvrline =~ /^(\S+)((\s*)(.*))/) {
+            my $server = "${1}";
+            my $lnrest = "${2}";
+            my $tlsext;
+            if($server =~ /^(httptls)(\+)(ext|srp)(\d*)(-ipv6|)$/) {
+                $server = "${1}${4}${5}";
+                $tlsext = uc("TLS-${3}");
+            }
+            if(! grep /^\Q$server\E$/, @protocols) {
+                if(substr($server,0,5) ne "socks") {
+                    if($tlsext) {
+                        return "curl lacks $tlsext support";
+                    }
+                    else {
+                        return "curl lacks $server server support";
+                    }
+                }
             }
+            $what[$i] = "$server$lnrest" if($tlsext);
         }
     }
 
@@ -3891,24 +4604,38 @@ while(@ARGV) {
         $DBGCURL=$CURL=$ARGV[1];
         shift @ARGV;
     }
+    elsif ($ARGV[0] eq "-vc") {
+        # use this path to a curl used to verify servers
+
+        # Particularly useful when you introduce a crashing bug somewhere in
+        # the development version as then it won't be able to run any tests
+        # since it can't verify the servers!
+
+        $VCURL=$ARGV[1];
+        shift @ARGV;
+    }
     elsif ($ARGV[0] eq "-d") {
         # have the servers display protocol output
         $debugprotocol=1;
     }
-    elsif ($ARGV[0] eq "-f") {
-        # run fork-servers, which makes the server fork for all new
-        # connections This is NOT what you wanna do without knowing exactly
-        # why and for what
-        $forkserver=1;
-    }
     elsif ($ARGV[0] eq "-g") {
         # run this test with gdb
         $gdbthis=1;
     }
+    elsif ($ARGV[0] eq "-gw") {
+        # run this test with windowed gdb
+        $gdbthis=1;
+        $gdbxwin=1;
+    }
     elsif($ARGV[0] eq "-s") {
         # short output
         $short=1;
     }
+    elsif($ARGV[0] eq "-am") {
+        # automake-style output
+        $short=1;
+        $automakestyle=1;
+    }
     elsif($ARGV[0] eq "-n") {
         # no valgrind
         undef $valgrind;
@@ -3928,6 +4655,10 @@ while(@ARGV) {
         # continue anyway, even if a test fail
         $anyway=1;
     }
+    elsif($ARGV[0] eq "-e") {
+        # run the tests cases event based if possible
+        $run_event_based=1;
+    }
     elsif($ARGV[0] eq "-p") {
         $postmortem=1;
     }
@@ -3976,6 +4707,7 @@ Usage: runtests.pl [options] [test selection(s)]
   -c path  use this curl executable
   -d       display server debug info
   -g       run the test case with gdb
+  -gw      run the test case with gdb as a windowed application
   -h       this help text
   -k       keep stdout and stderr files present after tests
   -l       list all test case names/descriptions
@@ -3984,8 +4716,10 @@ Usage: runtests.pl [options] [test selection(s)]
   -r       run time statistics
   -rf      full run time statistics
   -s       short output
+  -am      automake style output PASS/FAIL: [number] [name]
   -t[N]    torture (simulate memory alloc failures); N means fail Nth alloc
   -v       verbose output
+  -vc path use this curl only to verify the existing servers
   [num]    like "5 6 9" or " 5 to 22 " to run those tests only
   [!num]   like "!5 !6 !9" to disable those tests
   [keyword] like "IPv6" to select only tests containing the key word
@@ -4082,29 +4816,31 @@ if ($gdbthis) {
     }
 }
 
-$HTTPPORT =  $base++; # HTTP server port
-$HTTPSPORT = $base++; # HTTPS server port
-$FTPPORT =   $base++; # FTP server port
-$FTPSPORT =  $base++; # FTPS server port
-$HTTP6PORT = $base++; # HTTP IPv6 server port (different IP protocol
-                        # but we follow the same port scheme anyway)
-$FTP2PORT =  $base++; # FTP server 2 port
-$FTP6PORT =  $base++; # FTP IPv6 port
-$TFTPPORT =  $base++; # TFTP (UDP) port
-$TFTP6PORT = $base++; # TFTP IPv6 (UDP) port
-$SSHPORT =   $base++; # SSH (SCP/SFTP) port
-$SOCKSPORT = $base++; # SOCKS port
-$POP3PORT =  $base++;
-$POP36PORT = $base++;
-$IMAPPORT =  $base++;
-$IMAP6PORT = $base++;
-$SMTPPORT =  $base++;
-$SMTP6PORT = $base++;
-$RTSPPORT =  $base++;
-$RTSP6PORT = $base++;
-$GOPHERPORT =$base++;
-$GOPHER6PORT=$base++;
-$HTTPTLSSRPPORT=$base++;
+$HTTPPORT        = $base++; # HTTP server port
+$HTTPSPORT       = $base++; # HTTPS (stunnel) server port
+$FTPPORT         = $base++; # FTP server port
+$FTPSPORT        = $base++; # FTPS (stunnel) server port
+$HTTP6PORT       = $base++; # HTTP IPv6 server port
+$FTP2PORT        = $base++; # FTP server 2 port
+$FTP6PORT        = $base++; # FTP IPv6 port
+$TFTPPORT        = $base++; # TFTP (UDP) port
+$TFTP6PORT       = $base++; # TFTP IPv6 (UDP) port
+$SSHPORT         = $base++; # SSH (SCP/SFTP) port
+$SOCKSPORT       = $base++; # SOCKS port
+$POP3PORT        = $base++; # POP3 server port
+$POP36PORT       = $base++; # POP3 IPv6 server port
+$IMAPPORT        = $base++; # IMAP server port
+$IMAP6PORT       = $base++; # IMAP IPv6 server port
+$SMTPPORT        = $base++; # SMTP server port
+$SMTP6PORT       = $base++; # SMTP IPv6 server port
+$RTSPPORT        = $base++; # RTSP server port
+$RTSP6PORT       = $base++; # RTSP IPv6 server port
+$GOPHERPORT      = $base++; # Gopher IPv4 server port
+$GOPHER6PORT     = $base++; # Gopher IPv6 server port
+$HTTPTLSPORT     = $base++; # HTTP TLS (non-stunnel) server port
+$HTTPTLS6PORT    = $base++; # HTTP TLS (non-stunnel) IPv6 server port
+$HTTPPROXYPORT   = $base++; # HTTP proxy port, when using CONNECT
+$HTTPPIPEPORT    = $base++; # HTTP pipelining port
 
 #######################################################################
 # clear and create logging directory:
@@ -4173,6 +4909,19 @@ if ( $TESTCASES eq "all") {
         $TESTCASES .= " $n";
     }
 }
+else {
+    my $verified="";
+    map {
+        if (-e "$TESTDIR/test$_") {
+            $verified.="$_ ";
+        }
+    } split(" ", $TESTCASES);
+    if($verified eq "") {
+        print "No existing test cases were specified\n";
+        exit;
+    }
+    $TESTCASES = $verified;
+}
 
 #######################################################################
 # Start the command line log
@@ -4261,6 +5010,12 @@ sub displaylogs {
         if(($log =~ /^file\d+\.txt/) && ($log !~ /^file$testnum\.txt/)) {
             next; # skip fileNnn.txt of other tests
         }
+        if(($log =~ /^netrc\d+/) && ($log !~ /^netrc$testnum/)) {
+            next; # skip netrcNnn of other tests
+        }
+        if(($log =~ /^trace\d+/) && ($log !~ /^trace$testnum/)) {
+            next; # skip traceNnn of other tests
+        }
         if(($log =~ /^valgrind\d+/) && ($log !~ /^valgrind$testnum(\..*|)$/)) {
             next; # skip valgrindNnn of other tests
         }
@@ -4289,7 +5044,7 @@ foreach $testnum (@at) {
     $lasttest = $testnum if($testnum > $lasttest);
     $count++;
 
-    my $error = singletest($testnum, $count, scalar(@at));
+    my $error = singletest($run_event_based, $testnum, $count, scalar(@at));
     if($error < 0) {
         # not a test we can run
         next;
@@ -4358,14 +5113,20 @@ if($skipped && !$short) {
         # now show all test case numbers that had this reason for being
         # skipped
         my $c=0;
+        my $max = 9;
         for(0 .. scalar @teststat) {
             my $t = $_;
             if($teststat[$_] && ($teststat[$_] eq $r)) {
-                logmsg ", " if($c);
-                logmsg $_;
+                if($c < $max) {
+                    logmsg ", " if($c);
+                    logmsg $_;
+                }
                 $c++;
             }
         }
+        if($c > $max) {
+            logmsg " and ".($c-$max)." more";
+        }
         logmsg ")\n";
     }
 }