summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/FTPServer.pm998
-rw-r--r--tests/FTPTest.pm62
-rw-r--r--tests/HTTPServer.pm319
-rw-r--r--tests/HTTPTest.pm56
-rw-r--r--tests/Makefile.am164
-rw-r--r--tests/Makefile.in2422
-rw-r--r--tests/SSLServer.pm236
-rw-r--r--tests/SSLTest.pm73
-rwxr-xr-xtests/Test--httpsonly-r.px78
-rwxr-xr-xtests/Test--no-content-disposition-trivial.px54
-rwxr-xr-xtests/Test--no-content-disposition.px55
-rwxr-xr-xtests/Test--post-file.px22
-rwxr-xr-xtests/Test--spider-fail.px51
-rwxr-xr-xtests/Test--spider-r--no-content-disposition-trivial.px108
-rwxr-xr-xtests/Test--spider-r--no-content-disposition.px109
-rwxr-xr-xtests/Test--spider-r-HTTP-Content-Disposition.px109
-rwxr-xr-xtests/Test--spider-r.px108
-rwxr-xr-xtests/Test--spider.px51
-rwxr-xr-xtests/Test--start-pos--continue.px54
-rwxr-xr-xtests/Test--start-pos.px43
-rwxr-xr-xtests/Test-204.px34
-rwxr-xr-xtests/Test-E-k-K.px88
-rwxr-xr-xtests/Test-E-k.px85
-rwxr-xr-xtests/Test-HTTP-Content-Disposition-1.px75
-rwxr-xr-xtests/Test-HTTP-Content-Disposition-2.px75
-rwxr-xr-xtests/Test-HTTP-Content-Disposition.px55
-rwxr-xr-xtests/Test-N--no-content-disposition-trivial.px47
-rwxr-xr-xtests/Test-N--no-content-disposition.px48
-rwxr-xr-xtests/Test-N-HTTP-Content-Disposition.px49
-rwxr-xr-xtests/Test-N-current.px64
-rwxr-xr-xtests/Test-N-no-info.px62
-rwxr-xr-xtests/Test-N-old.px62
-rwxr-xr-xtests/Test-N-smaller.px65
-rwxr-xr-xtests/Test-N.px47
-rwxr-xr-xtests/Test-O--no-content-disposition-trivial.px45
-rwxr-xr-xtests/Test-O--no-content-disposition.px46
-rwxr-xr-xtests/Test-O-HTTP-Content-Disposition.px46
-rwxr-xr-xtests/Test-O-nc.px45
-rwxr-xr-xtests/Test-O-nonexisting.px45
-rwxr-xr-xtests/Test-O.px45
-rwxr-xr-xtests/Test-Restrict-Lowercase.px54
-rwxr-xr-xtests/Test-Restrict-Uppercase.px54
-rwxr-xr-xtests/Test-auth-basic.px47
-rwxr-xr-xtests/Test-auth-no-challenge-url.px48
-rwxr-xr-xtests/Test-auth-no-challenge.px49
-rwxr-xr-xtests/Test-auth-retcode.px37
-rwxr-xr-xtests/Test-auth-with-content-disposition.px48
-rwxr-xr-xtests/Test-c-full.px56
-rwxr-xr-xtests/Test-c-partial.px66
-rwxr-xr-xtests/Test-c-shorter.px63
-rwxr-xr-xtests/Test-c.px53
-rwxr-xr-xtests/Test-cookies-401.px51
-rwxr-xr-xtests/Test-cookies.px112
-rwxr-xr-xtests/Test-ftp--start-pos.px39
-rwxr-xr-xtests/Test-ftp-bad-list.px68
-rwxr-xr-xtests/Test-ftp-dir.px44
-rwxr-xr-xtests/Test-ftp-iri-disabled.px51
-rwxr-xr-xtests/Test-ftp-iri-fallback.px47
-rwxr-xr-xtests/Test-ftp-iri-recursive.px47
-rwxr-xr-xtests/Test-ftp-iri.px48
-rwxr-xr-xtests/Test-ftp-list-Multinet.px66
-rwxr-xr-xtests/Test-ftp-list-UNIX-hidden.px64
-rwxr-xr-xtests/Test-ftp-list-Unknown-a.px76
-rwxr-xr-xtests/Test-ftp-list-Unknown-hidden.px68
-rwxr-xr-xtests/Test-ftp-list-Unknown-list-a-fails.px61
-rwxr-xr-xtests/Test-ftp-list-Unknown.px64
-rwxr-xr-xtests/Test-ftp-pasv-fail.px57
-rwxr-xr-xtests/Test-ftp-pasv-not-supported.px56
-rwxr-xr-xtests/Test-ftp-recursive.px54
-rwxr-xr-xtests/Test-ftp.px44
-rw-r--r--tests/Test-https-badcerts.px103
-rwxr-xr-xtests/Test-https-clientcert.px107
-rwxr-xr-xtests/Test-https-crl.px101
-rwxr-xr-xtests/Test-https-pfs.px71
-rwxr-xr-xtests/Test-https-selfsigned.px97
-rwxr-xr-xtests/Test-https-tlsv1.px71
-rwxr-xr-xtests/Test-https-tlsv1x.px72
-rwxr-xr-xtests/Test-https-weboftrust.px128
-rwxr-xr-xtests/Test-i-ftp.px79
-rwxr-xr-xtests/Test-i-http.px90
-rwxr-xr-xtests/Test-idn-cmd-utf8.px50
-rwxr-xr-xtests/Test-idn-cmd.px50
-rwxr-xr-xtests/Test-idn-headers.px65
-rwxr-xr-xtests/Test-idn-meta.px67
-rwxr-xr-xtests/Test-idn-robots-utf8.px77
-rwxr-xr-xtests/Test-idn-robots.px102
-rwxr-xr-xtests/Test-iri-disabled.px195
-rwxr-xr-xtests/Test-iri-forced-remote.px182
-rwxr-xr-xtests/Test-iri-list.px173
-rwxr-xr-xtests/Test-iri-percent.px88
-rwxr-xr-xtests/Test-iri.px208
-rwxr-xr-xtests/Test-k.px92
-rwxr-xr-xtests/Test-meta-robots.px113
-rwxr-xr-xtests/Test-nonexisting-quiet.px42
-rwxr-xr-xtests/Test-noop.px55
-rwxr-xr-xtests/Test-np.px147
-rwxr-xr-xtests/Test-proxied-https-auth-keepalive.px181
-rwxr-xr-xtests/Test-proxied-https-auth.px180
-rwxr-xr-xtests/Test-proxy-auth-basic.px47
-rwxr-xr-xtests/Test-restrict-ascii.px67
-rwxr-xr-xtests/Test-stdouterr.px46
-rw-r--r--tests/WgetFeature.pm41
-rw-r--r--tests/WgetTests.pm447
-rw-r--r--tests/certs/README1
-rw-r--r--tests/certs/client-cert.pem27
-rw-r--r--tests/certs/client-key.pem182
-rw-r--r--tests/certs/client-template.txt23
-rwxr-xr-xtests/certs/create-certs.sh28
-rw-r--r--tests/certs/expired-template.txt20
-rw-r--r--tests/certs/expired.pem28
-rw-r--r--tests/certs/interca.conf64
-rw-r--r--tests/certs/interca.conf.in64
-rw-r--r--tests/certs/interca.crt41
-rw-r--r--tests/certs/interca.key51
-rw-r--r--tests/certs/invalid-template.txt20
-rw-r--r--tests/certs/invalid.pem28
-rw-r--r--tests/certs/revoked-crl.pem16
-rw-r--r--tests/certs/revoked-template.txt5
-rw-r--r--tests/certs/rootca.conf64
-rw-r--r--tests/certs/rootca.conf.in64
-rw-r--r--tests/certs/selfsigned.crt33
-rw-r--r--tests/certs/selfsigned.key52
-rw-r--r--tests/certs/server-cert.pem29
-rw-r--r--tests/certs/server-key.pem182
-rw-r--r--tests/certs/server-template.txt23
-rw-r--r--tests/certs/test-ca-cert.pem26
-rw-r--r--tests/certs/test-ca-key.pem182
-rw-r--r--tests/certs/test-ca-template.txt20
-rw-r--r--tests/certs/user.crt148
-rw-r--r--tests/certs/user.key51
-rw-r--r--tests/certs/wgethosts1
-rw-r--r--tests/certs/wotca.pem78
-rw-r--r--tests/unit-tests.c109
-rw-r--r--tests/unit-tests.h70
-rw-r--r--tests/valgrind-suppressions246
-rw-r--r--tests/valgrind-suppressions-ssl187
136 files changed, 13789 insertions, 0 deletions
diff --git a/tests/FTPServer.pm b/tests/FTPServer.pm
new file mode 100644
index 0000000..cac8094
--- /dev/null
+++ b/tests/FTPServer.pm
@@ -0,0 +1,998 @@
+# Part of this code was borrowed from Richard Jones's Net::FTPServer
+# http://www.annexia.org/freeware/netftpserver
+
+package FTPServer;
+
+use strict;
+use warnings;
+
+use Cwd;
+use Socket;
+use IO::Socket::INET;
+use IO::Seekable;
+use POSIX qw(strftime);
+
+my $log = undef;
+my $GOT_SIGURG = 0;
+
+# CONSTANTS
+
+# connection states
+my %_connection_states = (
+ 'NEWCONN' => 0x01,
+ 'WAIT4PWD' => 0x02,
+ 'LOGGEDIN' => 0x04,
+ 'TWOSOCKS' => 0x08,
+ );
+
+# subset of FTP commands supported by these server and the respective
+# connection states in which they are allowed
+my %_commands = (
+
+ # Standard commands from RFC 959.
+ 'CWD' => $_connection_states{LOGGEDIN} | $_connection_states{TWOSOCKS},
+
+ # 'EPRT' => $_connection_states{LOGGEDIN},
+ # 'EPSV' => $_connection_states{LOGGEDIN},
+ 'LIST' => $_connection_states{TWOSOCKS},
+
+ # 'LPRT' => $_connection_states{LOGGEDIN},
+ # 'LPSV' => $_connection_states{LOGGEDIN},
+ 'PASS' => $_connection_states{WAIT4PWD},
+ 'PASV' => $_connection_states{LOGGEDIN},
+ 'PORT' => $_connection_states{LOGGEDIN},
+ 'PWD' => $_connection_states{LOGGEDIN} | $_connection_states{TWOSOCKS},
+ 'QUIT' => $_connection_states{LOGGEDIN} | $_connection_states{TWOSOCKS},
+ 'REST' => $_connection_states{TWOSOCKS},
+ 'RETR' => $_connection_states{TWOSOCKS},
+ 'SYST' => $_connection_states{LOGGEDIN},
+ 'TYPE' => $_connection_states{LOGGEDIN} | $_connection_states{TWOSOCKS},
+ 'USER' => $_connection_states{NEWCONN},
+
+ # From ftpexts Internet Draft.
+ 'SIZE' => $_connection_states{LOGGEDIN} | $_connection_states{TWOSOCKS},
+);
+
+# COMMAND-HANDLING ROUTINES
+
+sub _CWD_command
+{
+ my ($conn, $cmd, $path) = @_;
+ my $paths = $conn->{'paths'};
+
+ local $_;
+ my $new_path = FTPPaths::path_merge($conn->{'dir'}, $path);
+
+ # Split the path into its component parts and process each separately.
+ if (!$paths->dir_exists($new_path))
+ {
+ print {$conn->{socket}} "550 Directory not found.\r\n";
+ return;
+ }
+
+ $conn->{'dir'} = $new_path;
+ print {$conn->{socket}} "200 directory changed to $new_path.\r\n";
+}
+
+sub _LIST_command
+{
+ my ($conn, $cmd, $path) = @_;
+ my $paths = $conn->{'paths'};
+
+ my $ReturnEmptyList =
+ ($paths->GetBehavior('list_empty_if_list_a') && $path eq '-a');
+ my $SkipHiddenFiles =
+ ($paths->GetBehavior('list_no_hidden_if_list') && (!$path));
+
+ if ($paths->GetBehavior('list_fails_if_list_a') && $path eq '-a')
+ {
+ print {$conn->{socket}} "500 Unknown command\r\n";
+ return;
+ }
+
+ if (!$paths->GetBehavior('list_dont_clean_path'))
+ {
+ # This is something of a hack. Some clients expect a Unix server
+ # to respond to flags on the 'ls command line'. Remove these flags
+ # and ignore them. This is particularly an issue with ncftp 2.4.3.
+ $path =~ s/^-[a-zA-Z0-9]+\s?//;
+ }
+
+ my $dir = $conn->{'dir'};
+
+ print STDERR "_LIST_command - dir is: $dir\n";
+
+ # Parse the first elements of the path until we find the appropriate
+ # working directory.
+ local $_;
+
+ my $listing;
+ if (!$ReturnEmptyList)
+ {
+ $dir = FTPPaths::path_merge($dir, $path);
+ $listing = $paths->get_list($dir, $SkipHiddenFiles);
+ unless ($listing)
+ {
+ print {$conn->{socket}} "550 File or directory not found.\r\n";
+ return;
+ }
+ }
+
+ print STDERR "_LIST_command - dir is: $dir\n" if $log;
+
+ print {$conn->{socket}} "150 Opening data connection for file listing.\r\n";
+
+ # Open a path back to the client.
+ my $sock = __open_data_connection($conn);
+ unless ($sock)
+ {
+ print {$conn->{socket}} "425 Can't open data connection.\r\n";
+ return;
+ }
+
+ if (!$ReturnEmptyList)
+ {
+ for my $item (@$listing)
+ {
+ print $sock "$item\r\n";
+ }
+ }
+
+ unless ($sock->close)
+ {
+ print {$conn->{socket}} "550 Error closing data connection: $!\r\n";
+ return;
+ }
+
+ print {$conn->{socket}}
+ "226 Listing complete. Data connection has been closed.\r\n";
+}
+
+sub _PASS_command
+{
+ my ($conn, $cmd, $pass) = @_;
+
+ # TODO: implement authentication?
+
+ print STDERR "switching to LOGGEDIN state\n" if $log;
+ $conn->{state} = $_connection_states{LOGGEDIN};
+
+ if ($conn->{username} eq "anonymous")
+ {
+ print {$conn->{socket}}
+ "202 Anonymous user access is always granted.\r\n";
+ }
+ else
+ {
+ print {$conn->{socket}}
+ "230 Authentication not implemented yet, access is always granted.\r\n";
+ }
+}
+
+sub _PASV_command
+{
+ my ($conn, $cmd, $rest) = @_;
+
+ # Open a listening socket - but don't actually accept on it yet.
+ "0" =~ /(0)/; # Perl 5.7 / IO::Socket::INET bug workaround.
+ my $sock = IO::Socket::INET->new(
+ LocalHost => '127.0.0.1',
+ LocalPort => '0',
+ Listen => 1,
+ Reuse => 1,
+ Proto => 'tcp',
+ Type => SOCK_STREAM
+ );
+
+ unless ($sock)
+ {
+ # Return a code 550 here, even though this is not in the RFC. XXX
+ print {$conn->{socket}} "550 Can't open a listening socket.\r\n";
+ return;
+ }
+
+ $conn->{passive} = 1;
+ $conn->{passive_socket} = $sock;
+
+ # Get our port number.
+ my $sockport = $sock->sockport;
+
+ # Split the port number into high and low components.
+ my $p1 = int($sockport / 256);
+ my $p2 = $sockport % 256;
+
+ $conn->{state} = $_connection_states{TWOSOCKS};
+
+ # We only accept connections from localhost.
+ print {$conn->{socket}} "227 Entering Passive Mode (127,0,0,1,$p1,$p2)\r\n";
+}
+
+sub _PORT_command
+{
+ my ($conn, $cmd, $rest) = @_;
+
+ # The arguments to PORT are a1,a2,a3,a4,p1,p2 where a1 is the
+ # most significant part of the address (eg. 127,0,0,1) and
+ # p1 is the most significant part of the port.
+ unless ($rest =~
+ /^\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})/
+ )
+ {
+ print {$conn->{socket}} "501 Syntax error in PORT command.\r\n";
+ return;
+ }
+
+ # Check host address.
+ unless ( $1 > 0
+ && $1 < 224
+ && $2 >= 0
+ && $2 < 256
+ && $3 >= 0
+ && $3 < 256
+ && $4 >= 0
+ && $4 < 256)
+ {
+ print {$conn->{socket}} "501 Invalid host address.\r\n";
+ return;
+ }
+
+ # Construct host address and port number.
+ my $peeraddrstring = "$1.$2.$3.$4";
+ my $peerport = $5 * 256 + $6;
+
+ # Check port number.
+ unless ($peerport > 0 && $peerport < 65536)
+ {
+ print {$conn->{socket}} "501 Invalid port number.\r\n";
+ }
+
+ $conn->{peeraddrstring} = $peeraddrstring;
+ $conn->{peeraddr} = inet_aton($peeraddrstring);
+ $conn->{peerport} = $peerport;
+ $conn->{passive} = 0;
+
+ $conn->{state} = $_connection_states{TWOSOCKS};
+
+ print {$conn->{socket}} "200 PORT command OK.\r\n";
+}
+
+sub _PWD_command
+{
+ my ($conn, $cmd, $rest) = @_;
+
+ # See RFC 959 Appendix II and draft-ietf-ftpext-mlst-11.txt section 6.2.1.
+ my $pathname = $conn->{dir};
+ $pathname =~ s,/+$,, unless $pathname eq "/";
+ $pathname =~ tr,/,/,s;
+
+ print {$conn->{socket}} "257 \"$pathname\"\r\n";
+}
+
+sub _REST_command
+{
+ my ($conn, $cmd, $restart_from) = @_;
+
+ unless ($restart_from =~ /^([1-9][0-9]*|0)$/)
+ {
+ print {$conn->{socket}}
+ "501 REST command needs a numeric argument.\r\n";
+ return;
+ }
+
+ $conn->{restart} = $1;
+
+ print {$conn->{socket}} "350 Restarting next transfer at $1.\r\n";
+}
+
+sub _RETR_command
+{
+ my ($conn, $cmd, $path) = @_;
+
+ $path = FTPPaths::path_merge($conn->{dir}, $path);
+ my $info = $conn->{'paths'}->get_info($path);
+
+ unless ($info->{'_type'} eq 'f')
+ {
+ print {$conn->{socket}} "550 File not found.\r\n";
+ return;
+ }
+
+ print {$conn->{socket}} "150 Opening "
+ . ($conn->{type} eq 'A' ? "ASCII mode" : "BINARY mode")
+ . " data connection.\r\n";
+
+ # Open a path back to the client.
+ my $sock = __open_data_connection($conn);
+
+ unless ($sock)
+ {
+ print {$conn->{socket}} "425 Can't open data connection.\r\n";
+ return;
+ }
+
+ my $content = $info->{'content'};
+
+ # Restart the connection from previous point?
+ if ($conn->{restart})
+ {
+ $content = substr($content, $conn->{restart});
+ $conn->{restart} = 0;
+ }
+
+ # What mode are we sending this file in?
+ unless ($conn->{type} eq 'A') # Binary type.
+ {
+ my ($r, $buffer, $n, $w, $sent);
+
+ # Copy data.
+ $sent = 0;
+ while ($sent < length($content))
+ {
+ $buffer = substr($content, $sent, 65536);
+ $r = length $buffer;
+
+ # Restart alarm clock timer.
+ alarm $conn->{idle_timeout};
+
+ for ($n = 0 ; $n < $r ;)
+ {
+ $w = syswrite($sock, $buffer, $r - $n, $n);
+
+ # Cleanup and exit if there was an error.
+ unless (defined $w)
+ {
+ close $sock;
+ print {$conn->{socket}}
+ "426 File retrieval error: $!. Data connection has been closed.\r\n";
+ return;
+ }
+
+ $n += $w;
+ }
+
+ # Transfer aborted by client?
+ if ($GOT_SIGURG)
+ {
+ $GOT_SIGURG = 0;
+ close $sock;
+ print {$conn->{socket}}
+ "426 Transfer aborted. Data connection closed.\r\n";
+ return;
+ }
+ $sent += $r;
+ }
+
+ # Cleanup and exit if there was an error.
+ unless (defined $r)
+ {
+ close $sock;
+ print {$conn->{socket}}
+ "426 File retrieval error: $!. Data connection has been closed.\r\n";
+ return;
+ }
+ }
+ else
+ { # ASCII type.
+ # Copy data.
+ my @lines = split /\r\n?|\n/, $content;
+ for (@lines)
+ {
+ # Remove any native line endings.
+ s/[\n\r]+$//;
+
+ # Restart alarm clock timer.
+ alarm $conn->{idle_timeout};
+
+ # Write the line with telnet-format line endings.
+ print $sock "$_\r\n";
+
+ # Transfer aborted by client?
+ if ($GOT_SIGURG)
+ {
+ $GOT_SIGURG = 0;
+ close $sock;
+ print {$conn->{socket}}
+ "426 Transfer aborted. Data connection closed.\r\n";
+ return;
+ }
+ }
+ }
+
+ unless (close($sock))
+ {
+ print {$conn->{socket}} "550 File retrieval error: $!.\r\n";
+ return;
+ }
+
+ print {$conn->{socket}}
+ "226 File retrieval complete. Data connection has been closed.\r\n";
+}
+
+sub _SIZE_command
+{
+ my ($conn, $cmd, $path) = @_;
+
+ $path = FTPPaths::path_merge($conn->{dir}, $path);
+ my $info = $conn->{'paths'}->get_info($path);
+ unless ($info)
+ {
+ print {$conn->{socket}} "550 File or directory not found.\r\n";
+ return;
+ }
+
+ if ($info->{'_type'} eq 'd')
+ {
+ print {$conn->{socket}}
+ "550 SIZE command is not supported on directories.\r\n";
+ return;
+ }
+
+ my $size = length $info->{'content'};
+
+ print {$conn->{socket}} "213 $size\r\n";
+}
+
+sub _SYST_command
+{
+ my ($conn, $cmd, $dummy) = @_;
+
+ if ($conn->{'paths'}->GetBehavior('syst_response'))
+ {
+ print {$conn->{socket}} $conn->{'paths'}->GetBehavior('syst_response')
+ . "\r\n";
+ }
+ else
+ {
+ print {$conn->{socket}} "215 UNIX Type: L8\r\n";
+ }
+}
+
+sub _TYPE_command
+{
+ my ($conn, $cmd, $type) = @_;
+
+ # See RFC 959 section 5.3.2.
+ if ($type =~ /^([AI])$/i)
+ {
+ $conn->{type} = $1;
+ }
+ elsif ($type =~ /^([AI])\sN$/i)
+ {
+ $conn->{type} = $1;
+ }
+ elsif ($type =~ /^L\s8$/i)
+ {
+ $conn->{type} = 'L8';
+ }
+ else
+ {
+ print {$conn->{socket}}
+ "504 This server does not support TYPE $type.\r\n";
+ return;
+ }
+
+ print {$conn->{socket}} "200 TYPE changed to $type.\r\n";
+}
+
+sub _USER_command
+{
+ my ($conn, $cmd, $username) = @_;
+
+ print STDERR "username: $username\n" if $log;
+ $conn->{username} = $username;
+
+ print STDERR "switching to WAIT4PWD state\n" if $log;
+ $conn->{state} = $_connection_states{WAIT4PWD};
+
+ if ($conn->{username} eq "anonymous")
+ {
+ print {$conn->{socket}} "230 Anonymous user access granted.\r\n";
+ }
+ else
+ {
+ print {$conn->{socket}} "331 Password required.\r\n";
+ }
+}
+
+# HELPER ROUTINES
+
+sub __open_data_connection
+{
+ my $conn = shift;
+
+ my $sock;
+
+ if ($conn->{passive})
+ {
+ # Passive mode - wait for a connection from the client.
+ accept($sock, $conn->{passive_socket}) or return undef;
+ }
+ else
+ {
+ # Active mode - connect back to the client.
+ "0" =~ /(0)/; # Perl 5.7 / IO::Socket::INET bug workaround.
+ $sock = IO::Socket::INET->new(
+ LocalAddr => '127.0.0.1',
+ PeerAddr => $conn->{peeraddrstring},
+ PeerPort => $conn->{peerport},
+ Proto => 'tcp',
+ Type => SOCK_STREAM
+ )
+ or return undef;
+ }
+
+ return $sock;
+}
+
+###########################################################################
+# FTPSERVER CLASS
+###########################################################################
+
+{
+ my %_attr_data = ( # DEFAULT
+ _input => undef,
+ _localAddr => 'localhost',
+ _localPort => undef,
+ _reuseAddr => 1,
+ _rootDir => Cwd::getcwd(),
+ _server_behavior => {},
+ );
+
+ sub _default_for
+ {
+ my ($self, $attr) = @_;
+ $_attr_data{$attr};
+ }
+
+ sub _standard_keys
+ {
+ keys %_attr_data;
+ }
+}
+
+sub new
+{
+ my ($caller, %args) = @_;
+ my $caller_is_obj = ref($caller);
+ my $class = $caller_is_obj || $caller;
+ my $self = bless {}, $class;
+ foreach my $attrname ($self->_standard_keys())
+ {
+ my ($argname) = ($attrname =~ /^_(.*)/);
+ if (exists $args{$argname})
+ {
+ $self->{$attrname} = $args{$argname};
+ }
+ elsif ($caller_is_obj)
+ {
+ $self->{$attrname} = $caller->{$attrname};
+ }
+ else
+ {
+ $self->{$attrname} = $self->_default_for($attrname);
+ }
+ }
+
+ # create server socket
+ "0" =~ /(0)/; # Perl 5.7 / IO::Socket::INET bug workaround.
+ $self->{_server_sock} =
+ IO::Socket::INET->new(
+ LocalHost => $self->{_localAddr},
+ LocalPort => $self->{_localPort},
+ Listen => 1,
+ Reuse => $self->{_reuseAddr},
+ Proto => 'tcp',
+ Type => SOCK_STREAM
+ )
+ or die "bind: $!";
+
+ foreach my $file (keys %{$self->{_input}})
+ {
+ my $ref = \$self->{_input}{$file}{content};
+ $$ref =~ s/\Q{{port}}/$self->sockport/eg;
+ }
+
+ return $self;
+}
+
+sub run
+{
+ my ($self, $synch_callback) = @_;
+ my $initialized = 0;
+
+ # turn buffering off on STDERR
+ select((select(STDERR), $| = 1)[0]);
+
+ # initialize command table
+ my $command_table = {};
+ foreach (keys %_commands)
+ {
+ my $subname = "_${_}_command";
+ $command_table->{$_} = \&$subname;
+ }
+
+ my $old_ils = $/;
+ $/ = "\r\n";
+
+ if (!$initialized)
+ {
+ $synch_callback->();
+ $initialized = 1;
+ }
+
+ $SIG{CHLD} = sub { wait };
+ my $server_sock = $self->{_server_sock};
+
+ # the accept loop
+ while (my $client_addr = accept(my $socket, $server_sock))
+ {
+ # turn buffering off on $socket
+ select((select($socket), $| = 1)[0]);
+
+ # find out who connected
+ my ($client_port, $client_ip) = sockaddr_in($client_addr);
+ my $client_ipnum = inet_ntoa($client_ip);
+
+ # print who connected
+ print STDERR "got a connection from: $client_ipnum\n" if $log;
+
+ # fork off a process to handle this connection.
+ # my $pid = fork();
+ # unless (defined $pid) {
+ # warn "fork: $!";
+ # sleep 5; # Back off in case system is overloaded.
+ # next;
+ # }
+
+ if (1)
+ { # Child process.
+
+ # install signals
+ $SIG{URG} = sub {
+ $GOT_SIGURG = 1;
+ };
+
+ $SIG{PIPE} = sub {
+ print STDERR "Client closed connection abruptly.\n";
+ exit;
+ };
+
+ $SIG{ALRM} = sub {
+ print STDERR
+ "Connection idle timeout expired. Closing server.\n";
+ exit;
+ };
+
+ #$SIG{CHLD} = 'IGNORE';
+
+ print STDERR "in child\n" if $log;
+
+ my $conn = {
+ 'paths' =>
+ FTPPaths->new($self->{'_input'}, $self->{'_server_behavior'}),
+ 'socket' => $socket,
+ 'state' => $_connection_states{NEWCONN},
+ 'dir' => '/',
+ 'restart' => 0,
+ 'idle_timeout' => 60, # 1 minute timeout
+ 'rootdir' => $self->{_rootDir},
+ };
+
+ print {$conn->{socket}}
+ "220 GNU Wget Testing FTP Server ready.\r\n";
+
+ # command handling loop
+ for (; ;)
+ {
+ print STDERR "waiting for request\n" if $log;
+
+ last unless defined(my $req = <$socket>);
+
+ # Remove trailing CRLF.
+ $req =~ s/[\n\r]+$//;
+
+ print STDERR "received request $req\n" if $log;
+
+ # Get the command.
+ # See also RFC 2640 section 3.1.
+ unless ($req =~ m/^([A-Z]{3,4})\s?(.*)/i)
+ {
+ # badly formed command
+ exit 0;
+ }
+
+ # The following strange 'eval' is necessary to work around a
+ # very odd bug in Perl 5.6.0. The following assignment to
+ # $cmd will fail in some cases unless you use $1 in some sort
+ # of an expression beforehand.
+ # - RWMJ 2002-07-05.
+ eval '$1 eq $1';
+
+ my ($cmd, $rest) = (uc $1, $2);
+
+ # Got a command which matches in the table?
+ unless (exists $command_table->{$cmd})
+ {
+ print {$conn->{socket}} "500 Unrecognized command.\r\n";
+ next;
+ }
+
+ # Command requires user to be authenticated?
+ unless ($_commands{$cmd} | $conn->{state})
+ {
+ print {$conn->{socket}} "530 Not logged in.\r\n";
+ next;
+ }
+
+ # Handle the QUIT command specially.
+ if ($cmd eq "QUIT")
+ {
+ print {$conn->{socket}}
+ "221 Goodbye. Service closing connection.\r\n";
+ last;
+ }
+
+ if (defined($self->{_server_behavior}{fail_on_pasv})
+ && $cmd eq 'PASV')
+ {
+ undef $self->{_server_behavior}{fail_on_pasv};
+ close $socket;
+ last;
+ }
+
+ if (defined($self->{_server_behavior}{pasv_not_supported})
+ && $cmd eq 'PASV')
+ {
+ print {$conn->{socket}}
+ "500 PASV not supported.\r\n";
+ next;
+ }
+
+ # Run the command.
+ &{$command_table->{$cmd}}($conn, $cmd, $rest);
+ }
+ }
+ else
+ { # Father
+ close $socket;
+ }
+ }
+
+ $/ = $old_ils;
+}
+
+sub sockport
+{
+ my $self = shift;
+ return $self->{_server_sock}->sockport;
+}
+
+package FTPPaths;
+
+use POSIX qw(strftime);
+
+# not a method
+sub final_component
+{
+ my $path = shift;
+
+ $path =~ s|.*/||;
+ return $path;
+}
+
+# not a method
+sub path_merge
+{
+ my ($path_a, $path_b) = @_;
+
+ if (!$path_b)
+ {
+ return $path_a;
+ }
+
+ if ($path_b =~ m.^/.)
+ {
+ $path_a = '';
+ $path_b =~ s.^/..;
+ }
+ $path_a =~ s./$..;
+
+ my @components = split m{/}msx, $path_b;
+
+ foreach my $c (@components)
+ {
+ if ($c =~ /^\.?$/)
+ {
+ next;
+ }
+ elsif ($c eq '..')
+ {
+ if (!$path_a)
+ {
+ next;
+ }
+ $path_a =~ s|/[^/]*$||;
+ }
+ else
+ {
+ $path_a .= "/$c";
+ }
+ }
+
+ return $path_a;
+}
+
+sub new
+{
+ my ($this, @args) = @_;
+ my $class = ref($this) || $this;
+ my $self = {};
+ bless $self, $class;
+ $self->initialize(@args);
+ return $self;
+}
+
+sub initialize
+{
+ my ($self, $urls, $behavior) = @_;
+ my $paths = {_type => 'd'};
+
+ # From a path like '/foo/bar/baz.txt', construct $paths such that
+ # $paths->{'foo'}->{'bar'}->{'baz.txt'} is
+ # $urls->{'/foo/bar/baz.txt'}.
+ for my $path (keys %$urls)
+ {
+ my @components = split m{/}msx, $path;
+ shift @components;
+ my $x = $paths;
+ for my $c (@components)
+ {
+ if (!exists $x->{$c})
+ {
+ $x->{$c} = {_type => 'd'};
+ }
+ $x = $x->{$c};
+ }
+ %$x = %{$urls->{$path}};
+ $x->{_type} = 'f';
+ }
+
+ $self->{'_paths'} = $paths;
+ $self->{'_behavior'} = $behavior;
+ return 1;
+}
+
+sub get_info
+{
+ my ($self, $path, $node) = @_;
+ $node = $self->{'_paths'} unless $node;
+ my @components = split('/', $path);
+ shift @components if @components && $components[0] eq '';
+
+ for my $c (@components)
+ {
+ if ($node->{'_type'} eq 'd')
+ {
+ $node = $node->{$c};
+ }
+ else
+ {
+ return;
+ }
+ }
+ return $node;
+}
+
+sub dir_exists
+{
+ my ($self, $path) = @_;
+ return $self->path_exists($path, 'd');
+}
+
+sub path_exists
+{
+ # type is optional, in which case we don't check it.
+ my ($self, $path, $type) = @_;
+ my $paths = $self->{'_paths'};
+
+ die "Invalid path $path (not absolute).\n" unless $path =~ m.^/.;
+ my $info = $self->get_info($path);
+ return 0 unless defined($info);
+ return $info->{'_type'} eq $type if defined($type);
+ return 1;
+}
+
+sub _format_for_list
+{
+ my ($self, $name, $info) = @_;
+
+ # XXX: mode should be specifyable as part of the node info.
+ my $mode_str;
+ if ($info->{'_type'} eq 'd')
+ {
+ $mode_str = 'dr-xr-xr-x';
+ }
+ else
+ {
+ $mode_str = '-r--r--r--';
+ }
+
+ my $size = 0;
+ if ($info->{'_type'} eq 'f')
+ {
+ $size = length $info->{'content'};
+ if ($self->{'_behavior'}{'bad_list'})
+ {
+ $size = 0;
+ }
+ }
+ my $date = strftime("%b %d %H:%M", localtime);
+ return "$mode_str 1 0 0 $size $date $name";
+}
+
+sub get_list
+{
+ my ($self, $path, $no_hidden) = @_;
+ my $info = $self->get_info($path);
+ if (!defined $info)
+ {
+ return;
+ }
+ my $list = [];
+
+ if ($info->{'_type'} eq 'd')
+ {
+ for my $item (keys %$info)
+ {
+ next if $item =~ /^_/;
+
+ # 2013-10-17 Andrea Urbani (matfanjol)
+ # I skip the hidden files if requested
+ if ( ($no_hidden)
+ && (defined($info->{$item}->{'attr'}))
+ && (index($info->{$item}->{'attr'}, "H") >= 0))
+ {
+ # This is an hidden file and I don't want to see it!
+ print STDERR "get_list: Skipped hidden file [$item]\n";
+ }
+ else
+ {
+ push @$list, $self->_format_for_list($item, $info->{$item});
+ }
+ }
+ }
+ else
+ {
+ push @$list, $self->_format_for_list(final_component($path), $info);
+ }
+
+ return $list;
+}
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# It returns the behavior of the given name.
+# In this file I handle also the following behaviors:
+# list_dont_clean_path : if defined, the command
+# $path =~ s/^-[a-zA-Z0-9]+\s?//;
+# is not runt and the given path
+# remains the original one
+# list_empty_if_list_a : if defined, "LIST -a" returns an
+# empty content
+# list_fails_if_list_a : if defined, "LIST -a" returns an
+# error
+# list_no_hidden_if_list: if defined, "LIST" doesn't return
+# hidden files.
+# To define an hidden file add
+# attr => "H"
+# to the url files
+# syst_response : if defined, its content is printed
+# out as SYST response
+sub GetBehavior
+{
+ my ($self, $name) = @_;
+ return $self->{'_behavior'}{$name};
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/FTPTest.pm b/tests/FTPTest.pm
new file mode 100644
index 0000000..0a1c768
--- /dev/null
+++ b/tests/FTPTest.pm
@@ -0,0 +1,62 @@
+package FTPTest;
+
+use strict;
+use warnings;
+
+use FTPServer;
+use WgetTests;
+
+our @ISA = qw(WgetTest);
+my $VERSION = 0.01;
+
+{
+ my %_attr_data = ( # DEFAULT
+ );
+
+ sub _default_for
+ {
+ my ($self, $attr) = @_;
+ return $_attr_data{$attr} if exists $_attr_data{$attr};
+ return $self->SUPER::_default_for($attr);
+ }
+
+ sub _standard_keys
+ {
+ my ($self) = @_;
+ ($self->SUPER::_standard_keys(), keys %_attr_data);
+ }
+}
+
+sub _setup_server
+{
+ my $self = shift;
+
+ $self->{_server} = FTPServer->new(
+ input => $self->{_input},
+ server_behavior => $self->{_server_behavior},
+ LocalAddr => 'localhost',
+ ReuseAddr => 1,
+ rootDir => "$self->{_workdir}/$self->{_name}/input"
+ )
+ or die "Cannot create server!!!";
+}
+
+sub _launch_server
+{
+ my $self = shift;
+ my $synch_func = shift;
+
+ $self->{_server}->run($synch_func);
+}
+
+sub _substitute_port
+{
+ my $self = shift;
+ my $ret = shift;
+ $ret =~ s/\Q{{port}}/$self->{_server}->sockport/eg;
+ return $ret;
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/HTTPServer.pm b/tests/HTTPServer.pm
new file mode 100644
index 0000000..78609f6
--- /dev/null
+++ b/tests/HTTPServer.pm
@@ -0,0 +1,319 @@
+package HTTPServer;
+
+use strict;
+use warnings;
+
+use HTTP::Daemon;
+use HTTP::Status;
+use HTTP::Headers;
+use HTTP::Response;
+
+our @ISA = qw(HTTP::Daemon);
+my $VERSION = 0.01;
+
+my $CRLF = "\015\012"; # "\r\n" is not portable
+my $log = undef;
+
+sub run
+{
+ my ($self, $urls, $synch_callback) = @_;
+ my $initialized = 0;
+
+ while (1)
+ {
+ if (!$initialized)
+ {
+ $synch_callback->();
+ $initialized = 1;
+ }
+ my $con = $self->accept();
+ print STDERR "Accepted a new connection\n" if $log;
+ while (my $req = $con->get_request)
+ {
+ #my $url_path = $req->url->path;
+ my $url_path = $req->url->as_string;
+ if ($url_path =~ m{/$})
+ { # append 'index.html'
+ $url_path .= 'index.html';
+ }
+
+ #if ($url_path =~ m{^/}) { # remove trailing '/'
+ # $url_path = substr ($url_path, 1);
+ #}
+ if ($log)
+ {
+ print STDERR "Method: ", $req->method, "\n";
+ print STDERR "Path: ", $url_path, "\n";
+ print STDERR "Available URLs: ", "\n";
+ foreach my $key (keys %$urls)
+ {
+ print STDERR $key, "\n";
+ }
+ }
+ if (exists($urls->{$url_path}))
+ {
+ print STDERR "Serving requested URL: ", $url_path, "\n" if $log;
+ next unless ($req->method eq "HEAD" || $req->method eq "GET");
+
+ my $url_rec = $urls->{$url_path};
+ $self->send_response($req, $url_rec, $con);
+ }
+ else
+ {
+ print STDERR "Requested wrong URL: ", $url_path, "\n" if $log;
+ $con->send_error($HTTP::Status::RC_FORBIDDEN);
+ last;
+ }
+ }
+ print STDERR "Closing connection\n" if $log;
+ $con->close;
+ }
+}
+
+sub send_response
+{
+ my ($self, $req, $url_rec, $con) = @_;
+
+ # create response
+ my ($code, $msg, $headers);
+ my $send_content = ($req->method eq "GET");
+ if (exists $url_rec->{'auth_method'})
+ {
+ ($send_content, $code, $msg, $headers) =
+ $self->handle_auth($req, $url_rec);
+ }
+ elsif (!$self->verify_request_headers($req, $url_rec))
+ {
+ ($send_content, $code, $msg, $headers) =
+ ('', 400, 'Mismatch on expected headers', {});
+ }
+ else
+ {
+ ($code, $msg) = @{$url_rec}{'code', 'msg'};
+ $headers = $url_rec->{headers};
+ }
+ my $resp = HTTP::Response->new($code, $msg);
+ print STDERR "HTTP::Response: \n", $resp->as_string if $log;
+
+ while (my ($name, $value) = each %{$headers})
+ {
+ # print STDERR "setting header: $name = $value\n";
+ $value = $self->_substitute_port($value);
+ $resp->header($name => $value);
+ }
+ print STDERR "HTTP::Response with headers: \n", $resp->as_string if $log;
+
+ if ($send_content)
+ {
+ my $content = $url_rec->{content};
+ if (exists($url_rec->{headers}{"Content-Length"}))
+ {
+ # Content-Length and length($content) don't match
+ # manually prepare the HTTP response
+ $con->send_basic_header($url_rec->{code}, $resp->message,
+ $resp->protocol);
+ print $con $resp->headers_as_string($CRLF);
+ print $con $CRLF;
+ print $con $content;
+ next;
+ }
+ if ($req->header("Range") && !$url_rec->{'force_code'})
+ {
+ $req->header("Range") =~ m/bytes=(\d*)-(\d*)/;
+ my $content_len = length($content);
+ my $start = $1 ? $1 : 0;
+ my $end = $2 ? $2 : ($content_len - 1);
+ my $len = $2 ? ($2 - $start) : ($content_len - $start);
+ if ($len > 0)
+ {
+ $resp->header("Accept-Ranges" => "bytes");
+ $resp->header("Content-Length" => $len);
+ $resp->header(
+ "Content-Range" => "bytes $start-$end/$content_len");
+ $resp->header("Keep-Alive" => "timeout=15, max=100");
+ $resp->header("Connection" => "Keep-Alive");
+ $con->send_basic_header(206,
+ "Partial Content", $resp->protocol);
+ print $con $resp->headers_as_string($CRLF);
+ print $con $CRLF;
+ print $con substr($content, $start, $len);
+ }
+ else
+ {
+ $con->send_basic_header(416, "Range Not Satisfiable",
+ $resp->protocol);
+ $resp->header("Keep-Alive" => "timeout=15, max=100");
+ $resp->header("Connection" => "Keep-Alive");
+ print $con $CRLF;
+ }
+ next;
+ }
+
+ # fill in content
+ $content = $self->_substitute_port($content) if defined $content;
+ $resp->content($content);
+ print STDERR "HTTP::Response with content: \n", $resp->as_string
+ if $log;
+ }
+
+ $con->send_response($resp);
+ print STDERR "HTTP::Response sent: \n", $resp->as_string if $log;
+}
+
+# Generates appropriate response content based on the authentication
+# status of the URL.
+sub handle_auth
+{
+ my ($self, $req, $url_rec) = @_;
+ my ($send_content, $code, $msg, $headers);
+
+ # Catch failure to set code, msg:
+ $code = 500;
+ $msg = "Didn't set response code in handle_auth";
+
+ # Most cases, we don't want to send content.
+ $send_content = 0;
+
+ # Initialize headers
+ $headers = {};
+ my $authhdr = $req->header('Authorization');
+
+ # Have we sent the challenge yet?
+ unless ($url_rec->{auth_challenged} || $url_rec->{auth_no_challenge})
+ {
+ # Since we haven't challenged yet, we'd better not
+ # have received authentication (for our testing purposes).
+ if ($authhdr)
+ {
+ $code = 400;
+ $msg = "You sent auth before I sent challenge";
+ }
+ else
+ {
+ # Send challenge
+ $code = 401;
+ $msg = "Authorization Required";
+ $headers->{'WWW-Authenticate'} =
+ $url_rec->{'auth_method'} . " realm=\"wget-test\"";
+ $url_rec->{auth_challenged} = 1;
+ }
+ }
+ elsif (!defined($authhdr))
+ {
+ # We've sent the challenge; we should have received valid
+ # authentication with this one. A normal server would just
+ # resend the challenge; but since this is a test, wget just
+ # failed it.
+ $code = 400;
+ $msg = "You didn't send auth after I sent challenge";
+ if ($url_rec->{auth_no_challenge})
+ {
+ $msg = "--auth-no-challenge but no auth sent.";
+ }
+ }
+ else
+ {
+ my ($sent_method) = ($authhdr =~ /^(\S+)/g);
+ unless ($sent_method eq $url_rec->{'auth_method'})
+ {
+ # Not the authorization type we were expecting.
+ $code = 400;
+ $msg = "Expected auth type $url_rec->{'auth_method'} but got "
+ . "$sent_method";
+ }
+ elsif (
+ (
+ $sent_method eq 'Digest'
+ && &verify_auth_digest($authhdr, $url_rec, \$msg)
+ )
+ || ( $sent_method eq 'Basic'
+ && &verify_auth_basic($authhdr, $url_rec, \$msg))
+ )
+ {
+ # SUCCESSFUL AUTH: send expected message, headers, content.
+ ($code, $msg) = @{$url_rec}{'code', 'msg'};
+ $headers = $url_rec->{headers};
+ $send_content = 1;
+ }
+ else
+ {
+ $code = 400;
+ }
+ }
+
+ return ($send_content, $code, $msg, $headers);
+}
+
+sub verify_auth_digest
+{
+ return undef; # Not yet implemented.
+}
+
+sub verify_auth_basic
+{
+ require MIME::Base64;
+ my ($authhdr, $url_rec, $msgref) = @_;
+ my $expected =
+ MIME::Base64::encode_base64(
+ $url_rec->{'user'} . ':' . $url_rec->{'passwd'},
+ '');
+ my ($got) = $authhdr =~ /^Basic (.*)$/;
+ if ($got eq $expected)
+ {
+ return 1;
+ }
+ else
+ {
+ $$msgref = "Wanted ${expected} got ${got}";
+ return undef;
+ }
+}
+
+sub verify_request_headers
+{
+ my ($self, $req, $url_rec) = @_;
+
+ return 1 unless exists $url_rec->{'request_headers'};
+ for my $hdrname (keys %{$url_rec->{'request_headers'}})
+ {
+ my $must_not_match;
+ my $ehdr = $url_rec->{'request_headers'}{$hdrname};
+ if ($must_not_match = ($hdrname =~ /^!(\w+)/))
+ {
+ $hdrname = $1;
+ }
+ my $rhdr = $req->header($hdrname);
+ if ($must_not_match)
+ {
+ if (defined $rhdr && $rhdr =~ $ehdr)
+ {
+ $rhdr = '' unless defined $rhdr;
+ print STDERR "\n*** Match forbidden $hdrname: $rhdr =~ $ehdr\n";
+ return undef;
+ }
+ }
+ else
+ {
+ unless (defined $rhdr && $rhdr =~ $ehdr)
+ {
+ $rhdr = '' unless defined $rhdr;
+ print STDERR "\n*** Mismatch on $hdrname: $rhdr =~ $ehdr\n";
+ return undef;
+ }
+ }
+ }
+
+ return 1;
+}
+
+sub _substitute_port
+{
+ my $self = shift;
+ my $ret = shift;
+ $ret =~ s/\Q{{port}}/$self->sockport/eg;
+ return $ret;
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/HTTPTest.pm b/tests/HTTPTest.pm
new file mode 100644
index 0000000..6225c7f
--- /dev/null
+++ b/tests/HTTPTest.pm
@@ -0,0 +1,56 @@
+package HTTPTest;
+
+use strict;
+use warnings;
+
+use HTTPServer;
+use WgetTests;
+
+our @ISA = qw(WgetTest);
+my $VERSION = 0.01;
+
+{
+ my %_attr_data = ( # DEFAULT
+ );
+
+ sub _default_for
+ {
+ my ($self, $attr) = @_;
+ return $_attr_data{$attr} if exists $_attr_data{$attr};
+ return $self->SUPER::_default_for($attr);
+ }
+
+ sub _standard_keys
+ {
+ my ($self) = @_;
+ ($self->SUPER::_standard_keys(), keys %_attr_data);
+ }
+}
+
+sub _setup_server
+{
+ my $self = shift;
+ $self->{_server} = HTTPServer->new(LocalAddr => 'localhost',
+ ReuseAddr => 1)
+ or die "Cannot create server!!!";
+}
+
+sub _launch_server
+{
+ my $self = shift;
+ my $synch_func = shift;
+
+ $self->{_server}->run($self->{_input}, $synch_func);
+}
+
+sub _substitute_port
+{
+ my $self = shift;
+ my $ret = shift;
+ $ret =~ s/\Q{{port}}/$self->{_server}->sockport/eg;
+ return $ret;
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..66dc28f
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,164 @@
+# Makefile for `wget' utility
+# Copyright (C) 1995-2011, 2015, 2018-2022 Free Software Foundation,
+# Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Wget. If not, see <http://www.gnu.org/licenses/>.
+
+# Additional permission under GNU GPL version 3 section 7
+
+# If you modify this program, or any covered work, by linking or
+# combining it with the OpenSSL project's OpenSSL library (or a
+# modified version of that library), containing parts covered by the
+# terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+# grants you additional permission to convey the resulting work.
+# Corresponding Source for a non-source form of such a combination
+# shall include the source code for the parts of OpenSSL used as well
+# as that of the covered work.
+
+# see http://www.gnu.org/software/automake/manual/html_node/Parallel-Test-Harness.html#Parallel-Test-Harness
+
+#
+# Version: @VERSION@
+#
+
+../src/wget$(EXEEXT):
+ cd ../src && $(MAKE) $(AM_MAKEFLAGS)
+
+# Make libunittest "PHONY" so we're always sure we're up-to-date.
+.PHONY: ../src/libunittest.a
+../src/libunittest.a:
+ cd ../src && $(MAKE) $(AM_MAKEFLAGS) libunittest.a
+
+../lib/libgnu.a:
+ cd ../lib && $(MAKE) $(AM_MAKEFLAGS)
+
+PX_TESTS = \
+ Test-auth-basic.px \
+ Test-auth-no-challenge.px \
+ Test-auth-no-challenge-url.px \
+ Test-auth-with-content-disposition.px \
+ Test-auth-retcode.px \
+ Test-c-full.px \
+ Test-c-partial.px \
+ Test-c.px \
+ Test-c-shorter.px \
+ Test-cookies.px \
+ Test-cookies-401.px \
+ Test-E-k-K.px \
+ Test-E-k.px \
+ Test-ftp.px \
+ Test-ftp-dir.px \
+ Test-ftp-pasv-fail.px \
+ Test-ftp-bad-list.px \
+ Test-ftp-recursive.px \
+ Test-ftp-iri.px \
+ Test-ftp-iri-fallback.px \
+ Test-ftp-iri-recursive.px \
+ Test-ftp-iri-disabled.px \
+ Test-ftp-list-Multinet.px \
+ Test-ftp-list-Unknown.px \
+ Test-ftp-list-Unknown-a.px \
+ Test-ftp-list-Unknown-hidden.px \
+ Test-ftp-list-Unknown-list-a-fails.px \
+ Test-ftp-list-UNIX-hidden.px \
+ Test-ftp--start-pos.px \
+ Test-HTTP-Content-Disposition-1.px \
+ Test-HTTP-Content-Disposition-2.px \
+ Test-HTTP-Content-Disposition.px \
+ Test-i-ftp.px \
+ Test-i-http.px \
+ Test-idn-headers.px \
+ Test-idn-meta.px \
+ Test-idn-cmd.px \
+ Test-idn-cmd-utf8.px \
+ Test-idn-robots.px \
+ Test-idn-robots-utf8.px \
+ Test-iri.px \
+ Test-iri-percent.px \
+ Test-iri-disabled.px \
+ Test-iri-forced-remote.px \
+ Test-iri-list.px \
+ Test-k.px \
+ Test-meta-robots.px \
+ Test-N-current.px \
+ Test-N-HTTP-Content-Disposition.px \
+ Test-N--no-content-disposition.px \
+ Test-N--no-content-disposition-trivial.px \
+ Test-N-no-info.px \
+ Test--no-content-disposition.px \
+ Test--no-content-disposition-trivial.px \
+ Test-N-old.px \
+ Test-nonexisting-quiet.px \
+ Test-noop.px \
+ Test-np.px \
+ Test-N.px \
+ Test-N-smaller.px \
+ Test-O-HTTP-Content-Disposition.px \
+ Test-O-nc.px \
+ Test-O--no-content-disposition.px \
+ Test-O--no-content-disposition-trivial.px \
+ Test-O-nonexisting.px \
+ Test-O.px \
+ Test--post-file.px \
+ Test-proxied-https-auth.px \
+ Test-proxied-https-auth-keepalive.px \
+ Test-proxy-auth-basic.px \
+ Test-restrict-ascii.px \
+ Test-Restrict-Lowercase.px \
+ Test-Restrict-Uppercase.px \
+ Test-stdouterr.px \
+ Test--spider-fail.px \
+ Test--spider.px \
+ Test--spider-r-HTTP-Content-Disposition.px \
+ Test--spider-r--no-content-disposition.px \
+ Test--spider-r--no-content-disposition-trivial.px \
+ Test--spider-r.px \
+ Test--start-pos.px \
+ Test--start-pos--continue.px \
+ Test--httpsonly-r.px \
+ Test-204.px \
+ Test-ftp-pasv-not-supported.px \
+ Test-https-pfs.px \
+ Test-https-tlsv1.px \
+ Test-https-tlsv1x.px \
+ Test-https-selfsigned.px \
+ Test-https-weboftrust.px \
+ Test-https-clientcert.px \
+ Test-https-crl.px \
+ Test-https-badcerts.px
+
+EXTRA_DIST = FTPServer.pm FTPTest.pm HTTPServer.pm HTTPTest.pm \
+ SSLTest.pm SSLServer.pm \
+ WgetTests.pm WgetFeature.pm $(PX_TESTS) \
+ certs valgrind-suppressions valgrind-suppressions-ssl
+
+check_PROGRAMS = unit-tests
+unit_tests_SOURCES = unit-tests.c unit-tests.h
+LDADD = ../src/libunittest.a ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB)\
+ $(INET_NTOP_LIB) $(LIBSOCKET) $(LIB_CLOCK_GETTIME) $(LIB_CRYPTO)\
+ $(LIB_NANOSLEEP) $(LIB_POSIX_SPAWN) $(LIB_SELECT) $(LIBICONV) $(LIBINTL)\
+ $(LIBTHREAD) $(LIBUNISTRING) $(SERVENT_LIB)
+AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src -DLOCALEDIR=\"$(localedir)\"
+AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS)
+
+
+CLEANFILES = *~ *.bak core core.[0-9]*
+
+TESTS = ./unit-tests$(EXEEXT) $(PX_TESTS)
+TEST_EXTENSIONS = .px
+PX_LOG_COMPILER = $(PERL)
+AM_PX_LOG_FLAGS = -I$(srcdir)
+AM_TESTS_ENVIRONMENT = export WGETRC=; export SYSTEM_WGETRC=;\
+ export VALGRIND_TESTS="@VALGRIND_TESTS@";
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..d2a25e7
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,2422 @@
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for `wget' utility
+# Copyright (C) 1995-2011, 2015, 2018-2022 Free Software Foundation,
+# Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with Wget. If not, see <http://www.gnu.org/licenses/>.
+
+# Additional permission under GNU GPL version 3 section 7
+
+# If you modify this program, or any covered work, by linking or
+# combining it with the OpenSSL project's OpenSSL library (or a
+# modified version of that library), containing parts covered by the
+# terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+# grants you additional permission to convey the resulting work.
+# Corresponding Source for a non-source form of such a combination
+# shall include the source code for the parts of OpenSSL used as well
+# as that of the covered work.
+
+# see http://www.gnu.org/software/automake/manual/html_node/Parallel-Test-Harness.html#Parallel-Test-Harness
+
+#
+# Version: @VERSION@
+#
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = unit-tests$(EXEEXT)
+subdir = tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
+ $(top_srcdir)/m4/__inline.m4 \
+ $(top_srcdir)/m4/absolute-header.m4 $(top_srcdir)/m4/access.m4 \
+ $(top_srcdir)/m4/af_alg.m4 $(top_srcdir)/m4/alloca.m4 \
+ $(top_srcdir)/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/m4/asm-underscore.m4 $(top_srcdir)/m4/base32.m4 \
+ $(top_srcdir)/m4/btowc.m4 $(top_srcdir)/m4/builtin-expect.m4 \
+ $(top_srcdir)/m4/byteswap.m4 $(top_srcdir)/m4/calloc.m4 \
+ $(top_srcdir)/m4/canonicalize.m4 \
+ $(top_srcdir)/m4/chdir-long.m4 $(top_srcdir)/m4/clock_time.m4 \
+ $(top_srcdir)/m4/close.m4 $(top_srcdir)/m4/closedir.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/ctype_h.m4 \
+ $(top_srcdir)/m4/d-ino.m4 $(top_srcdir)/m4/dirent_h.m4 \
+ $(top_srcdir)/m4/dirfd.m4 \
+ $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup.m4 \
+ $(top_srcdir)/m4/dup2.m4 $(top_srcdir)/m4/eaccess.m4 \
+ $(top_srcdir)/m4/eealloc.m4 $(top_srcdir)/m4/environ.m4 \
+ $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/error.m4 \
+ $(top_srcdir)/m4/exponentd.m4 $(top_srcdir)/m4/extensions.m4 \
+ $(top_srcdir)/m4/extern-inline.m4 \
+ $(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fchdir.m4 \
+ $(top_srcdir)/m4/fcntl-o.m4 $(top_srcdir)/m4/fcntl.m4 \
+ $(top_srcdir)/m4/fcntl_h.m4 $(top_srcdir)/m4/fdopendir.m4 \
+ $(top_srcdir)/m4/fflush.m4 $(top_srcdir)/m4/filenamecat.m4 \
+ $(top_srcdir)/m4/findprog-in.m4 $(top_srcdir)/m4/flexmember.m4 \
+ $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/flock.m4 \
+ $(top_srcdir)/m4/fnmatch.m4 $(top_srcdir)/m4/fnmatch_h.m4 \
+ $(top_srcdir)/m4/fopen.m4 $(top_srcdir)/m4/fpurge.m4 \
+ $(top_srcdir)/m4/freading.m4 $(top_srcdir)/m4/free.m4 \
+ $(top_srcdir)/m4/fseek.m4 $(top_srcdir)/m4/fseeko.m4 \
+ $(top_srcdir)/m4/fstat.m4 $(top_srcdir)/m4/fstatat.m4 \
+ $(top_srcdir)/m4/ftell.m4 $(top_srcdir)/m4/ftello.m4 \
+ $(top_srcdir)/m4/futimens.m4 $(top_srcdir)/m4/getaddrinfo.m4 \
+ $(top_srcdir)/m4/getcwd-abort-bug.m4 \
+ $(top_srcdir)/m4/getcwd-path-max.m4 $(top_srcdir)/m4/getcwd.m4 \
+ $(top_srcdir)/m4/getdelim.m4 $(top_srcdir)/m4/getdtablesize.m4 \
+ $(top_srcdir)/m4/getgroups.m4 $(top_srcdir)/m4/getline.m4 \
+ $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpagesize.m4 \
+ $(top_srcdir)/m4/getpass.m4 $(top_srcdir)/m4/getprogname.m4 \
+ $(top_srcdir)/m4/getrandom.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/gettime.m4 $(top_srcdir)/m4/gettimeofday.m4 \
+ $(top_srcdir)/m4/gl-openssl.m4 \
+ $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.m4 \
+ $(top_srcdir)/m4/group-member.m4 \
+ $(top_srcdir)/m4/host-cpu-c-abi.m4 $(top_srcdir)/m4/hostent.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/iconv_h.m4 \
+ $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/inet_ntop.m4 \
+ $(top_srcdir)/m4/inline.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/intmax_t.m4 $(top_srcdir)/m4/inttypes.m4 \
+ $(top_srcdir)/m4/inttypes_h.m4 $(top_srcdir)/m4/ioctl.m4 \
+ $(top_srcdir)/m4/isblank.m4 $(top_srcdir)/m4/iswblank.m4 \
+ $(top_srcdir)/m4/iswdigit.m4 $(top_srcdir)/m4/iswxdigit.m4 \
+ $(top_srcdir)/m4/langinfo_h.m4 $(top_srcdir)/m4/largefile.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libunistring-base.m4 \
+ $(top_srcdir)/m4/libunistring-optional.m4 \
+ $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/limits-h.m4 \
+ $(top_srcdir)/m4/link.m4 $(top_srcdir)/m4/localcharset.m4 \
+ $(top_srcdir)/m4/locale-fr.m4 $(top_srcdir)/m4/locale-ja.m4 \
+ $(top_srcdir)/m4/locale-zh.m4 $(top_srcdir)/m4/locale_h.m4 \
+ $(top_srcdir)/m4/localeconv.m4 $(top_srcdir)/m4/lock.m4 \
+ $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \
+ $(top_srcdir)/m4/malloc.m4 $(top_srcdir)/m4/malloca.m4 \
+ $(top_srcdir)/m4/mbchar.m4 $(top_srcdir)/m4/mbiter.m4 \
+ $(top_srcdir)/m4/mbrtowc.m4 $(top_srcdir)/m4/mbsinit.m4 \
+ $(top_srcdir)/m4/mbsrtowcs.m4 $(top_srcdir)/m4/mbstate_t.m4 \
+ $(top_srcdir)/m4/mbtowc.m4 $(top_srcdir)/m4/md4.m4 \
+ $(top_srcdir)/m4/md5.m4 $(top_srcdir)/m4/memchr.m4 \
+ $(top_srcdir)/m4/mempcpy.m4 $(top_srcdir)/m4/memrchr.m4 \
+ $(top_srcdir)/m4/minmax.m4 $(top_srcdir)/m4/mkdir.m4 \
+ $(top_srcdir)/m4/mkostemp.m4 $(top_srcdir)/m4/mkstemp.m4 \
+ $(top_srcdir)/m4/mktime.m4 $(top_srcdir)/m4/mmap-anon.m4 \
+ $(top_srcdir)/m4/mode_t.m4 $(top_srcdir)/m4/msvc-inval.m4 \
+ $(top_srcdir)/m4/msvc-nothrow.m4 $(top_srcdir)/m4/multiarch.m4 \
+ $(top_srcdir)/m4/nanosleep.m4 $(top_srcdir)/m4/netdb_h.m4 \
+ $(top_srcdir)/m4/netinet_in_h.m4 \
+ $(top_srcdir)/m4/nl_langinfo.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/off_t.m4 \
+ $(top_srcdir)/m4/open-cloexec.m4 \
+ $(top_srcdir)/m4/open-slash.m4 $(top_srcdir)/m4/open.m4 \
+ $(top_srcdir)/m4/openat.m4 $(top_srcdir)/m4/opendir.m4 \
+ $(top_srcdir)/m4/pathmax.m4 $(top_srcdir)/m4/pipe.m4 \
+ $(top_srcdir)/m4/pipe2.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/posix_spawn.m4 \
+ $(top_srcdir)/m4/posix_spawn_faction_addchdir.m4 \
+ $(top_srcdir)/m4/printf.m4 $(top_srcdir)/m4/pselect.m4 \
+ $(top_srcdir)/m4/pthread_rwlock_rdlock.m4 \
+ $(top_srcdir)/m4/pthread_sigmask.m4 $(top_srcdir)/m4/quote.m4 \
+ $(top_srcdir)/m4/quotearg.m4 $(top_srcdir)/m4/raise.m4 \
+ $(top_srcdir)/m4/rawmemchr.m4 $(top_srcdir)/m4/readdir.m4 \
+ $(top_srcdir)/m4/readlink.m4 $(top_srcdir)/m4/realloc.m4 \
+ $(top_srcdir)/m4/reallocarray.m4 $(top_srcdir)/m4/regex.m4 \
+ $(top_srcdir)/m4/rename.m4 $(top_srcdir)/m4/rewinddir.m4 \
+ $(top_srcdir)/m4/rmdir.m4 $(top_srcdir)/m4/save-cwd.m4 \
+ $(top_srcdir)/m4/sched_h.m4 $(top_srcdir)/m4/secure_getenv.m4 \
+ $(top_srcdir)/m4/select.m4 $(top_srcdir)/m4/servent.m4 \
+ $(top_srcdir)/m4/setlocale_null.m4 \
+ $(top_srcdir)/m4/sh-filename.m4 $(top_srcdir)/m4/sha1.m4 \
+ $(top_srcdir)/m4/sha256.m4 $(top_srcdir)/m4/sha512.m4 \
+ $(top_srcdir)/m4/sig_atomic_t.m4 $(top_srcdir)/m4/sigaction.m4 \
+ $(top_srcdir)/m4/signal_h.m4 \
+ $(top_srcdir)/m4/signalblocking.m4 $(top_srcdir)/m4/sigpipe.m4 \
+ $(top_srcdir)/m4/size_max.m4 $(top_srcdir)/m4/snprintf.m4 \
+ $(top_srcdir)/m4/socketlib.m4 $(top_srcdir)/m4/sockets.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sockpfaf.m4 \
+ $(top_srcdir)/m4/spawn-pipe.m4 $(top_srcdir)/m4/spawn_h.m4 \
+ $(top_srcdir)/m4/ssize_t.m4 $(top_srcdir)/m4/stat-time.m4 \
+ $(top_srcdir)/m4/stat.m4 $(top_srcdir)/m4/stdalign.m4 \
+ $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/stddef_h.m4 \
+ $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/m4/stdint_h.m4 \
+ $(top_srcdir)/m4/stdio_h.m4 $(top_srcdir)/m4/stdlib_h.m4 \
+ $(top_srcdir)/m4/stpcpy.m4 $(top_srcdir)/m4/strcase.m4 \
+ $(top_srcdir)/m4/strchrnul.m4 $(top_srcdir)/m4/strdup.m4 \
+ $(top_srcdir)/m4/strerror.m4 $(top_srcdir)/m4/strerror_r.m4 \
+ $(top_srcdir)/m4/string_h.m4 $(top_srcdir)/m4/strings_h.m4 \
+ $(top_srcdir)/m4/strndup.m4 $(top_srcdir)/m4/strnlen.m4 \
+ $(top_srcdir)/m4/strpbrk.m4 $(top_srcdir)/m4/strptime.m4 \
+ $(top_srcdir)/m4/strtok_r.m4 $(top_srcdir)/m4/strtol.m4 \
+ $(top_srcdir)/m4/strtoll.m4 $(top_srcdir)/m4/symlink.m4 \
+ $(top_srcdir)/m4/sys_file_h.m4 $(top_srcdir)/m4/sys_ioctl_h.m4 \
+ $(top_srcdir)/m4/sys_random_h.m4 \
+ $(top_srcdir)/m4/sys_select_h.m4 \
+ $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/m4/sys_stat_h.m4 $(top_srcdir)/m4/sys_time_h.m4 \
+ $(top_srcdir)/m4/sys_types_h.m4 $(top_srcdir)/m4/sys_uio_h.m4 \
+ $(top_srcdir)/m4/sys_wait_h.m4 $(top_srcdir)/m4/tempname.m4 \
+ $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/m4/time_h.m4 \
+ $(top_srcdir)/m4/time_r.m4 $(top_srcdir)/m4/timegm.m4 \
+ $(top_srcdir)/m4/timespec.m4 $(top_srcdir)/m4/tm_gmtoff.m4 \
+ $(top_srcdir)/m4/tmpdir.m4 $(top_srcdir)/m4/ungetc.m4 \
+ $(top_srcdir)/m4/unistd-safer.m4 $(top_srcdir)/m4/unistd_h.m4 \
+ $(top_srcdir)/m4/unlink.m4 $(top_srcdir)/m4/unlocked-io.m4 \
+ $(top_srcdir)/m4/utime.m4 $(top_srcdir)/m4/utime_h.m4 \
+ $(top_srcdir)/m4/utimens.m4 $(top_srcdir)/m4/utimes.m4 \
+ $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vasprintf.m4 \
+ $(top_srcdir)/m4/visibility.m4 $(top_srcdir)/m4/vsnprintf.m4 \
+ $(top_srcdir)/m4/wait-process.m4 $(top_srcdir)/m4/waitpid.m4 \
+ $(top_srcdir)/m4/warn-on-use.m4 $(top_srcdir)/m4/warnings.m4 \
+ $(top_srcdir)/m4/wchar_h.m4 $(top_srcdir)/m4/wchar_t.m4 \
+ $(top_srcdir)/m4/wcrtomb.m4 $(top_srcdir)/m4/wctype_h.m4 \
+ $(top_srcdir)/m4/wcwidth.m4 $(top_srcdir)/m4/wget.m4 \
+ $(top_srcdir)/m4/wget_manywarnings.m4 \
+ $(top_srcdir)/m4/wint_t.m4 $(top_srcdir)/m4/wmemchr.m4 \
+ $(top_srcdir)/m4/wmempcpy.m4 $(top_srcdir)/m4/write.m4 \
+ $(top_srcdir)/m4/xalloc.m4 $(top_srcdir)/m4/xsize.m4 \
+ $(top_srcdir)/m4/xstrndup.m4 $(top_srcdir)/m4/year2038.m4 \
+ $(top_srcdir)/m4/zzgnulib.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am_unit_tests_OBJECTS = unit-tests.$(OBJEXT)
+unit_tests_OBJECTS = $(am_unit_tests_OBJECTS)
+unit_tests_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+unit_tests_DEPENDENCIES = ../src/libunittest.a ../lib/libgnu.a \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/unit-tests.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(unit_tests_SOURCES)
+DIST_SOURCES = $(unit_tests_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.px.log=.log)
+PX_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+PX_LOG_COMPILE = $(PX_LOG_COMPILER) $(AM_PX_LOG_FLAGS) $(PX_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+ARFLAGS = @ARFLAGS@
+ASM_SYMBOL_PREFIX = @ASM_SYMBOL_PREFIX@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+BYTESWAP_H = @BYTESWAP_H@
+CARES_CFLAGS = @CARES_CFLAGS@
+CARES_LIBS = @CARES_LIBS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAG_VISIBILITY = @CFLAG_VISIBILITY@
+CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@
+CODE_COVERAGE_CPPFLAGS = @CODE_COVERAGE_CPPFLAGS@
+CODE_COVERAGE_CXXFLAGS = @CODE_COVERAGE_CXXFLAGS@
+CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@
+CODE_COVERAGE_LIBS = @CODE_COVERAGE_LIBS@
+COMMENT_IF_NO_POD2MAN = @COMMENT_IF_NO_POD2MAN@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
+CTAGS = @CTAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@
+EMULTIHOP_VALUE = @EMULTIHOP_VALUE@
+ENOLINK_HIDDEN = @ENOLINK_HIDDEN@
+ENOLINK_VALUE = @ENOLINK_VALUE@
+EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@
+EOVERFLOW_VALUE = @EOVERFLOW_VALUE@
+ERRNO_H = @ERRNO_H@
+ETAGS = @ETAGS@
+EXEEXT = @EXEEXT@
+FLOAT_H = @FLOAT_H@
+FNMATCH_H = @FNMATCH_H@
+FUZZ_LIBS = @FUZZ_LIBS@
+GCOV = @GCOV@
+GENHTML = @GENHTML@
+GETADDRINFO_LIB = @GETADDRINFO_LIB@
+GETOPT_CDEFS_H = @GETOPT_CDEFS_H@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GL_CFLAG_ALLOW_WARNINGS = @GL_CFLAG_ALLOW_WARNINGS@
+GL_CFLAG_GNULIB_WARNINGS = @GL_CFLAG_GNULIB_WARNINGS@
+GL_GNULIB_ACCEPT = @GL_GNULIB_ACCEPT@
+GL_GNULIB_ACCEPT4 = @GL_GNULIB_ACCEPT4@
+GL_GNULIB_ACCESS = @GL_GNULIB_ACCESS@
+GL_GNULIB_ALIGNED_ALLOC = @GL_GNULIB_ALIGNED_ALLOC@
+GL_GNULIB_ALPHASORT = @GL_GNULIB_ALPHASORT@
+GL_GNULIB_ATOLL = @GL_GNULIB_ATOLL@
+GL_GNULIB_BIND = @GL_GNULIB_BIND@
+GL_GNULIB_BTOWC = @GL_GNULIB_BTOWC@
+GL_GNULIB_CALLOC_GNU = @GL_GNULIB_CALLOC_GNU@
+GL_GNULIB_CALLOC_POSIX = @GL_GNULIB_CALLOC_POSIX@
+GL_GNULIB_CANONICALIZE_FILE_NAME = @GL_GNULIB_CANONICALIZE_FILE_NAME@
+GL_GNULIB_CHDIR = @GL_GNULIB_CHDIR@
+GL_GNULIB_CHOWN = @GL_GNULIB_CHOWN@
+GL_GNULIB_CLOSE = @GL_GNULIB_CLOSE@
+GL_GNULIB_CLOSEDIR = @GL_GNULIB_CLOSEDIR@
+GL_GNULIB_CONNECT = @GL_GNULIB_CONNECT@
+GL_GNULIB_COPY_FILE_RANGE = @GL_GNULIB_COPY_FILE_RANGE@
+GL_GNULIB_CREAT = @GL_GNULIB_CREAT@
+GL_GNULIB_CTIME = @GL_GNULIB_CTIME@
+GL_GNULIB_DIRFD = @GL_GNULIB_DIRFD@
+GL_GNULIB_DPRINTF = @GL_GNULIB_DPRINTF@
+GL_GNULIB_DUP = @GL_GNULIB_DUP@
+GL_GNULIB_DUP2 = @GL_GNULIB_DUP2@
+GL_GNULIB_DUP3 = @GL_GNULIB_DUP3@
+GL_GNULIB_DUPLOCALE = @GL_GNULIB_DUPLOCALE@
+GL_GNULIB_ENVIRON = @GL_GNULIB_ENVIRON@
+GL_GNULIB_EUIDACCESS = @GL_GNULIB_EUIDACCESS@
+GL_GNULIB_EXECL = @GL_GNULIB_EXECL@
+GL_GNULIB_EXECLE = @GL_GNULIB_EXECLE@
+GL_GNULIB_EXECLP = @GL_GNULIB_EXECLP@
+GL_GNULIB_EXECV = @GL_GNULIB_EXECV@
+GL_GNULIB_EXECVE = @GL_GNULIB_EXECVE@
+GL_GNULIB_EXECVP = @GL_GNULIB_EXECVP@
+GL_GNULIB_EXECVPE = @GL_GNULIB_EXECVPE@
+GL_GNULIB_EXPLICIT_BZERO = @GL_GNULIB_EXPLICIT_BZERO@
+GL_GNULIB_FACCESSAT = @GL_GNULIB_FACCESSAT@
+GL_GNULIB_FCHDIR = @GL_GNULIB_FCHDIR@
+GL_GNULIB_FCHMODAT = @GL_GNULIB_FCHMODAT@
+GL_GNULIB_FCHOWNAT = @GL_GNULIB_FCHOWNAT@
+GL_GNULIB_FCLOSE = @GL_GNULIB_FCLOSE@
+GL_GNULIB_FCNTL = @GL_GNULIB_FCNTL@
+GL_GNULIB_FDATASYNC = @GL_GNULIB_FDATASYNC@
+GL_GNULIB_FDOPEN = @GL_GNULIB_FDOPEN@
+GL_GNULIB_FDOPENDIR = @GL_GNULIB_FDOPENDIR@
+GL_GNULIB_FFLUSH = @GL_GNULIB_FFLUSH@
+GL_GNULIB_FFS = @GL_GNULIB_FFS@
+GL_GNULIB_FFSL = @GL_GNULIB_FFSL@
+GL_GNULIB_FFSLL = @GL_GNULIB_FFSLL@
+GL_GNULIB_FGETC = @GL_GNULIB_FGETC@
+GL_GNULIB_FGETS = @GL_GNULIB_FGETS@
+GL_GNULIB_FLOCK = @GL_GNULIB_FLOCK@
+GL_GNULIB_FNMATCH = @GL_GNULIB_FNMATCH@
+GL_GNULIB_FOPEN = @GL_GNULIB_FOPEN@
+GL_GNULIB_FOPEN_GNU = @GL_GNULIB_FOPEN_GNU@
+GL_GNULIB_FPRINTF = @GL_GNULIB_FPRINTF@
+GL_GNULIB_FPRINTF_POSIX = @GL_GNULIB_FPRINTF_POSIX@
+GL_GNULIB_FPURGE = @GL_GNULIB_FPURGE@
+GL_GNULIB_FPUTC = @GL_GNULIB_FPUTC@
+GL_GNULIB_FPUTS = @GL_GNULIB_FPUTS@
+GL_GNULIB_FREAD = @GL_GNULIB_FREAD@
+GL_GNULIB_FREE_POSIX = @GL_GNULIB_FREE_POSIX@
+GL_GNULIB_FREOPEN = @GL_GNULIB_FREOPEN@
+GL_GNULIB_FSCANF = @GL_GNULIB_FSCANF@
+GL_GNULIB_FSEEK = @GL_GNULIB_FSEEK@
+GL_GNULIB_FSEEKO = @GL_GNULIB_FSEEKO@
+GL_GNULIB_FSTAT = @GL_GNULIB_FSTAT@
+GL_GNULIB_FSTATAT = @GL_GNULIB_FSTATAT@
+GL_GNULIB_FSYNC = @GL_GNULIB_FSYNC@
+GL_GNULIB_FTELL = @GL_GNULIB_FTELL@
+GL_GNULIB_FTELLO = @GL_GNULIB_FTELLO@
+GL_GNULIB_FTRUNCATE = @GL_GNULIB_FTRUNCATE@
+GL_GNULIB_FUTIMENS = @GL_GNULIB_FUTIMENS@
+GL_GNULIB_FWRITE = @GL_GNULIB_FWRITE@
+GL_GNULIB_GETADDRINFO = @GL_GNULIB_GETADDRINFO@
+GL_GNULIB_GETC = @GL_GNULIB_GETC@
+GL_GNULIB_GETCHAR = @GL_GNULIB_GETCHAR@
+GL_GNULIB_GETCWD = @GL_GNULIB_GETCWD@
+GL_GNULIB_GETDELIM = @GL_GNULIB_GETDELIM@
+GL_GNULIB_GETDOMAINNAME = @GL_GNULIB_GETDOMAINNAME@
+GL_GNULIB_GETDTABLESIZE = @GL_GNULIB_GETDTABLESIZE@
+GL_GNULIB_GETENTROPY = @GL_GNULIB_GETENTROPY@
+GL_GNULIB_GETGROUPS = @GL_GNULIB_GETGROUPS@
+GL_GNULIB_GETHOSTNAME = @GL_GNULIB_GETHOSTNAME@
+GL_GNULIB_GETLINE = @GL_GNULIB_GETLINE@
+GL_GNULIB_GETLOADAVG = @GL_GNULIB_GETLOADAVG@
+GL_GNULIB_GETLOGIN = @GL_GNULIB_GETLOGIN@
+GL_GNULIB_GETLOGIN_R = @GL_GNULIB_GETLOGIN_R@
+GL_GNULIB_GETOPT_POSIX = @GL_GNULIB_GETOPT_POSIX@
+GL_GNULIB_GETPAGESIZE = @GL_GNULIB_GETPAGESIZE@
+GL_GNULIB_GETPASS = @GL_GNULIB_GETPASS@
+GL_GNULIB_GETPASS_GNU = @GL_GNULIB_GETPASS_GNU@
+GL_GNULIB_GETPEERNAME = @GL_GNULIB_GETPEERNAME@
+GL_GNULIB_GETRANDOM = @GL_GNULIB_GETRANDOM@
+GL_GNULIB_GETSOCKNAME = @GL_GNULIB_GETSOCKNAME@
+GL_GNULIB_GETSOCKOPT = @GL_GNULIB_GETSOCKOPT@
+GL_GNULIB_GETSUBOPT = @GL_GNULIB_GETSUBOPT@
+GL_GNULIB_GETTIMEOFDAY = @GL_GNULIB_GETTIMEOFDAY@
+GL_GNULIB_GETUMASK = @GL_GNULIB_GETUMASK@
+GL_GNULIB_GETUSERSHELL = @GL_GNULIB_GETUSERSHELL@
+GL_GNULIB_GRANTPT = @GL_GNULIB_GRANTPT@
+GL_GNULIB_GROUP_MEMBER = @GL_GNULIB_GROUP_MEMBER@
+GL_GNULIB_ICONV = @GL_GNULIB_ICONV@
+GL_GNULIB_IMAXABS = @GL_GNULIB_IMAXABS@
+GL_GNULIB_IMAXDIV = @GL_GNULIB_IMAXDIV@
+GL_GNULIB_INET_NTOP = @GL_GNULIB_INET_NTOP@
+GL_GNULIB_INET_PTON = @GL_GNULIB_INET_PTON@
+GL_GNULIB_IOCTL = @GL_GNULIB_IOCTL@
+GL_GNULIB_ISATTY = @GL_GNULIB_ISATTY@
+GL_GNULIB_ISBLANK = @GL_GNULIB_ISBLANK@
+GL_GNULIB_ISWBLANK = @GL_GNULIB_ISWBLANK@
+GL_GNULIB_ISWCTYPE = @GL_GNULIB_ISWCTYPE@
+GL_GNULIB_ISWDIGIT = @GL_GNULIB_ISWDIGIT@
+GL_GNULIB_ISWXDIGIT = @GL_GNULIB_ISWXDIGIT@
+GL_GNULIB_LCHMOD = @GL_GNULIB_LCHMOD@
+GL_GNULIB_LCHOWN = @GL_GNULIB_LCHOWN@
+GL_GNULIB_LINK = @GL_GNULIB_LINK@
+GL_GNULIB_LINKAT = @GL_GNULIB_LINKAT@
+GL_GNULIB_LISTEN = @GL_GNULIB_LISTEN@
+GL_GNULIB_LOCALECONV = @GL_GNULIB_LOCALECONV@
+GL_GNULIB_LOCALENAME = @GL_GNULIB_LOCALENAME@
+GL_GNULIB_LOCALTIME = @GL_GNULIB_LOCALTIME@
+GL_GNULIB_LSEEK = @GL_GNULIB_LSEEK@
+GL_GNULIB_LSTAT = @GL_GNULIB_LSTAT@
+GL_GNULIB_MALLOC_GNU = @GL_GNULIB_MALLOC_GNU@
+GL_GNULIB_MALLOC_POSIX = @GL_GNULIB_MALLOC_POSIX@
+GL_GNULIB_MBRLEN = @GL_GNULIB_MBRLEN@
+GL_GNULIB_MBRTOWC = @GL_GNULIB_MBRTOWC@
+GL_GNULIB_MBSCASECMP = @GL_GNULIB_MBSCASECMP@
+GL_GNULIB_MBSCASESTR = @GL_GNULIB_MBSCASESTR@
+GL_GNULIB_MBSCHR = @GL_GNULIB_MBSCHR@
+GL_GNULIB_MBSCSPN = @GL_GNULIB_MBSCSPN@
+GL_GNULIB_MBSINIT = @GL_GNULIB_MBSINIT@
+GL_GNULIB_MBSLEN = @GL_GNULIB_MBSLEN@
+GL_GNULIB_MBSNCASECMP = @GL_GNULIB_MBSNCASECMP@
+GL_GNULIB_MBSNLEN = @GL_GNULIB_MBSNLEN@
+GL_GNULIB_MBSNRTOWCS = @GL_GNULIB_MBSNRTOWCS@
+GL_GNULIB_MBSPBRK = @GL_GNULIB_MBSPBRK@
+GL_GNULIB_MBSPCASECMP = @GL_GNULIB_MBSPCASECMP@
+GL_GNULIB_MBSRCHR = @GL_GNULIB_MBSRCHR@
+GL_GNULIB_MBSRTOWCS = @GL_GNULIB_MBSRTOWCS@
+GL_GNULIB_MBSSEP = @GL_GNULIB_MBSSEP@
+GL_GNULIB_MBSSPN = @GL_GNULIB_MBSSPN@
+GL_GNULIB_MBSSTR = @GL_GNULIB_MBSSTR@
+GL_GNULIB_MBSTOK_R = @GL_GNULIB_MBSTOK_R@
+GL_GNULIB_MBTOWC = @GL_GNULIB_MBTOWC@
+GL_GNULIB_MDA_ACCESS = @GL_GNULIB_MDA_ACCESS@
+GL_GNULIB_MDA_CHDIR = @GL_GNULIB_MDA_CHDIR@
+GL_GNULIB_MDA_CHMOD = @GL_GNULIB_MDA_CHMOD@
+GL_GNULIB_MDA_CLOSE = @GL_GNULIB_MDA_CLOSE@
+GL_GNULIB_MDA_CREAT = @GL_GNULIB_MDA_CREAT@
+GL_GNULIB_MDA_DUP = @GL_GNULIB_MDA_DUP@
+GL_GNULIB_MDA_DUP2 = @GL_GNULIB_MDA_DUP2@
+GL_GNULIB_MDA_ECVT = @GL_GNULIB_MDA_ECVT@
+GL_GNULIB_MDA_EXECL = @GL_GNULIB_MDA_EXECL@
+GL_GNULIB_MDA_EXECLE = @GL_GNULIB_MDA_EXECLE@
+GL_GNULIB_MDA_EXECLP = @GL_GNULIB_MDA_EXECLP@
+GL_GNULIB_MDA_EXECV = @GL_GNULIB_MDA_EXECV@
+GL_GNULIB_MDA_EXECVE = @GL_GNULIB_MDA_EXECVE@
+GL_GNULIB_MDA_EXECVP = @GL_GNULIB_MDA_EXECVP@
+GL_GNULIB_MDA_EXECVPE = @GL_GNULIB_MDA_EXECVPE@
+GL_GNULIB_MDA_FCLOSEALL = @GL_GNULIB_MDA_FCLOSEALL@
+GL_GNULIB_MDA_FCVT = @GL_GNULIB_MDA_FCVT@
+GL_GNULIB_MDA_FDOPEN = @GL_GNULIB_MDA_FDOPEN@
+GL_GNULIB_MDA_FILENO = @GL_GNULIB_MDA_FILENO@
+GL_GNULIB_MDA_GCVT = @GL_GNULIB_MDA_GCVT@
+GL_GNULIB_MDA_GETCWD = @GL_GNULIB_MDA_GETCWD@
+GL_GNULIB_MDA_GETPID = @GL_GNULIB_MDA_GETPID@
+GL_GNULIB_MDA_GETW = @GL_GNULIB_MDA_GETW@
+GL_GNULIB_MDA_ISATTY = @GL_GNULIB_MDA_ISATTY@
+GL_GNULIB_MDA_LSEEK = @GL_GNULIB_MDA_LSEEK@
+GL_GNULIB_MDA_MEMCCPY = @GL_GNULIB_MDA_MEMCCPY@
+GL_GNULIB_MDA_MKDIR = @GL_GNULIB_MDA_MKDIR@
+GL_GNULIB_MDA_MKTEMP = @GL_GNULIB_MDA_MKTEMP@
+GL_GNULIB_MDA_OPEN = @GL_GNULIB_MDA_OPEN@
+GL_GNULIB_MDA_PUTENV = @GL_GNULIB_MDA_PUTENV@
+GL_GNULIB_MDA_PUTW = @GL_GNULIB_MDA_PUTW@
+GL_GNULIB_MDA_READ = @GL_GNULIB_MDA_READ@
+GL_GNULIB_MDA_RMDIR = @GL_GNULIB_MDA_RMDIR@
+GL_GNULIB_MDA_STRDUP = @GL_GNULIB_MDA_STRDUP@
+GL_GNULIB_MDA_SWAB = @GL_GNULIB_MDA_SWAB@
+GL_GNULIB_MDA_TEMPNAM = @GL_GNULIB_MDA_TEMPNAM@
+GL_GNULIB_MDA_TZSET = @GL_GNULIB_MDA_TZSET@
+GL_GNULIB_MDA_UMASK = @GL_GNULIB_MDA_UMASK@
+GL_GNULIB_MDA_UNLINK = @GL_GNULIB_MDA_UNLINK@
+GL_GNULIB_MDA_UTIME = @GL_GNULIB_MDA_UTIME@
+GL_GNULIB_MDA_WCSDUP = @GL_GNULIB_MDA_WCSDUP@
+GL_GNULIB_MDA_WRITE = @GL_GNULIB_MDA_WRITE@
+GL_GNULIB_MEMCHR = @GL_GNULIB_MEMCHR@
+GL_GNULIB_MEMMEM = @GL_GNULIB_MEMMEM@
+GL_GNULIB_MEMPCPY = @GL_GNULIB_MEMPCPY@
+GL_GNULIB_MEMRCHR = @GL_GNULIB_MEMRCHR@
+GL_GNULIB_MKDIR = @GL_GNULIB_MKDIR@
+GL_GNULIB_MKDIRAT = @GL_GNULIB_MKDIRAT@
+GL_GNULIB_MKDTEMP = @GL_GNULIB_MKDTEMP@
+GL_GNULIB_MKFIFO = @GL_GNULIB_MKFIFO@
+GL_GNULIB_MKFIFOAT = @GL_GNULIB_MKFIFOAT@
+GL_GNULIB_MKNOD = @GL_GNULIB_MKNOD@
+GL_GNULIB_MKNODAT = @GL_GNULIB_MKNODAT@
+GL_GNULIB_MKOSTEMP = @GL_GNULIB_MKOSTEMP@
+GL_GNULIB_MKOSTEMPS = @GL_GNULIB_MKOSTEMPS@
+GL_GNULIB_MKSTEMP = @GL_GNULIB_MKSTEMP@
+GL_GNULIB_MKSTEMPS = @GL_GNULIB_MKSTEMPS@
+GL_GNULIB_MKTIME = @GL_GNULIB_MKTIME@
+GL_GNULIB_NANOSLEEP = @GL_GNULIB_NANOSLEEP@
+GL_GNULIB_NL_LANGINFO = @GL_GNULIB_NL_LANGINFO@
+GL_GNULIB_NONBLOCKING = @GL_GNULIB_NONBLOCKING@
+GL_GNULIB_OBSTACK_PRINTF = @GL_GNULIB_OBSTACK_PRINTF@
+GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@
+GL_GNULIB_OPEN = @GL_GNULIB_OPEN@
+GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@
+GL_GNULIB_OPENDIR = @GL_GNULIB_OPENDIR@
+GL_GNULIB_OVERRIDES_STRUCT_STAT = @GL_GNULIB_OVERRIDES_STRUCT_STAT@
+GL_GNULIB_PCLOSE = @GL_GNULIB_PCLOSE@
+GL_GNULIB_PERROR = @GL_GNULIB_PERROR@
+GL_GNULIB_PIPE = @GL_GNULIB_PIPE@
+GL_GNULIB_PIPE2 = @GL_GNULIB_PIPE2@
+GL_GNULIB_POPEN = @GL_GNULIB_POPEN@
+GL_GNULIB_POSIX_MEMALIGN = @GL_GNULIB_POSIX_MEMALIGN@
+GL_GNULIB_POSIX_OPENPT = @GL_GNULIB_POSIX_OPENPT@
+GL_GNULIB_POSIX_SPAWN = @GL_GNULIB_POSIX_SPAWN@
+GL_GNULIB_POSIX_SPAWNATTR_DESTROY = @GL_GNULIB_POSIX_SPAWNATTR_DESTROY@
+GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS = @GL_GNULIB_POSIX_SPAWNATTR_GETFLAGS@
+GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP = @GL_GNULIB_POSIX_SPAWNATTR_GETPGROUP@
+GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM = @GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@
+GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY = @GL_GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@
+GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT = @GL_GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@
+GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK = @GL_GNULIB_POSIX_SPAWNATTR_GETSIGMASK@
+GL_GNULIB_POSIX_SPAWNATTR_INIT = @GL_GNULIB_POSIX_SPAWNATTR_INIT@
+GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS = @GL_GNULIB_POSIX_SPAWNATTR_SETFLAGS@
+GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP = @GL_GNULIB_POSIX_SPAWNATTR_SETPGROUP@
+GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM = @GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@
+GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY = @GL_GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@
+GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT = @GL_GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@
+GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK = @GL_GNULIB_POSIX_SPAWNATTR_SETSIGMASK@
+GL_GNULIB_POSIX_SPAWNP = @GL_GNULIB_POSIX_SPAWNP@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@
+GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT = @GL_GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@
+GL_GNULIB_PREAD = @GL_GNULIB_PREAD@
+GL_GNULIB_PRINTF = @GL_GNULIB_PRINTF@
+GL_GNULIB_PRINTF_POSIX = @GL_GNULIB_PRINTF_POSIX@
+GL_GNULIB_PSELECT = @GL_GNULIB_PSELECT@
+GL_GNULIB_PTHREAD_SIGMASK = @GL_GNULIB_PTHREAD_SIGMASK@
+GL_GNULIB_PTSNAME = @GL_GNULIB_PTSNAME@
+GL_GNULIB_PTSNAME_R = @GL_GNULIB_PTSNAME_R@
+GL_GNULIB_PUTC = @GL_GNULIB_PUTC@
+GL_GNULIB_PUTCHAR = @GL_GNULIB_PUTCHAR@
+GL_GNULIB_PUTENV = @GL_GNULIB_PUTENV@
+GL_GNULIB_PUTS = @GL_GNULIB_PUTS@
+GL_GNULIB_PWRITE = @GL_GNULIB_PWRITE@
+GL_GNULIB_QSORT_R = @GL_GNULIB_QSORT_R@
+GL_GNULIB_RAISE = @GL_GNULIB_RAISE@
+GL_GNULIB_RANDOM = @GL_GNULIB_RANDOM@
+GL_GNULIB_RANDOM_R = @GL_GNULIB_RANDOM_R@
+GL_GNULIB_RAWMEMCHR = @GL_GNULIB_RAWMEMCHR@
+GL_GNULIB_READ = @GL_GNULIB_READ@
+GL_GNULIB_READDIR = @GL_GNULIB_READDIR@
+GL_GNULIB_READLINK = @GL_GNULIB_READLINK@
+GL_GNULIB_READLINKAT = @GL_GNULIB_READLINKAT@
+GL_GNULIB_REALLOCARRAY = @GL_GNULIB_REALLOCARRAY@
+GL_GNULIB_REALLOC_GNU = @GL_GNULIB_REALLOC_GNU@
+GL_GNULIB_REALLOC_POSIX = @GL_GNULIB_REALLOC_POSIX@
+GL_GNULIB_REALPATH = @GL_GNULIB_REALPATH@
+GL_GNULIB_RECV = @GL_GNULIB_RECV@
+GL_GNULIB_RECVFROM = @GL_GNULIB_RECVFROM@
+GL_GNULIB_REMOVE = @GL_GNULIB_REMOVE@
+GL_GNULIB_RENAME = @GL_GNULIB_RENAME@
+GL_GNULIB_RENAMEAT = @GL_GNULIB_RENAMEAT@
+GL_GNULIB_REWINDDIR = @GL_GNULIB_REWINDDIR@
+GL_GNULIB_RMDIR = @GL_GNULIB_RMDIR@
+GL_GNULIB_RPMATCH = @GL_GNULIB_RPMATCH@
+GL_GNULIB_SCANDIR = @GL_GNULIB_SCANDIR@
+GL_GNULIB_SCANF = @GL_GNULIB_SCANF@
+GL_GNULIB_SCHED_YIELD = @GL_GNULIB_SCHED_YIELD@
+GL_GNULIB_SECURE_GETENV = @GL_GNULIB_SECURE_GETENV@
+GL_GNULIB_SELECT = @GL_GNULIB_SELECT@
+GL_GNULIB_SEND = @GL_GNULIB_SEND@
+GL_GNULIB_SENDTO = @GL_GNULIB_SENDTO@
+GL_GNULIB_SETENV = @GL_GNULIB_SETENV@
+GL_GNULIB_SETHOSTNAME = @GL_GNULIB_SETHOSTNAME@
+GL_GNULIB_SETLOCALE = @GL_GNULIB_SETLOCALE@
+GL_GNULIB_SETLOCALE_NULL = @GL_GNULIB_SETLOCALE_NULL@
+GL_GNULIB_SETSOCKOPT = @GL_GNULIB_SETSOCKOPT@
+GL_GNULIB_SHUTDOWN = @GL_GNULIB_SHUTDOWN@
+GL_GNULIB_SIGABBREV_NP = @GL_GNULIB_SIGABBREV_NP@
+GL_GNULIB_SIGACTION = @GL_GNULIB_SIGACTION@
+GL_GNULIB_SIGDESCR_NP = @GL_GNULIB_SIGDESCR_NP@
+GL_GNULIB_SIGNAL_H_SIGPIPE = @GL_GNULIB_SIGNAL_H_SIGPIPE@
+GL_GNULIB_SIGPROCMASK = @GL_GNULIB_SIGPROCMASK@
+GL_GNULIB_SLEEP = @GL_GNULIB_SLEEP@
+GL_GNULIB_SNPRINTF = @GL_GNULIB_SNPRINTF@
+GL_GNULIB_SOCKET = @GL_GNULIB_SOCKET@
+GL_GNULIB_SPRINTF_POSIX = @GL_GNULIB_SPRINTF_POSIX@
+GL_GNULIB_STAT = @GL_GNULIB_STAT@
+GL_GNULIB_STDIO_H_NONBLOCKING = @GL_GNULIB_STDIO_H_NONBLOCKING@
+GL_GNULIB_STDIO_H_SIGPIPE = @GL_GNULIB_STDIO_H_SIGPIPE@
+GL_GNULIB_STPCPY = @GL_GNULIB_STPCPY@
+GL_GNULIB_STPNCPY = @GL_GNULIB_STPNCPY@
+GL_GNULIB_STRCASESTR = @GL_GNULIB_STRCASESTR@
+GL_GNULIB_STRCHRNUL = @GL_GNULIB_STRCHRNUL@
+GL_GNULIB_STRDUP = @GL_GNULIB_STRDUP@
+GL_GNULIB_STRERROR = @GL_GNULIB_STRERROR@
+GL_GNULIB_STRERRORNAME_NP = @GL_GNULIB_STRERRORNAME_NP@
+GL_GNULIB_STRERROR_R = @GL_GNULIB_STRERROR_R@
+GL_GNULIB_STRFTIME = @GL_GNULIB_STRFTIME@
+GL_GNULIB_STRNCAT = @GL_GNULIB_STRNCAT@
+GL_GNULIB_STRNDUP = @GL_GNULIB_STRNDUP@
+GL_GNULIB_STRNLEN = @GL_GNULIB_STRNLEN@
+GL_GNULIB_STRPBRK = @GL_GNULIB_STRPBRK@
+GL_GNULIB_STRPTIME = @GL_GNULIB_STRPTIME@
+GL_GNULIB_STRSEP = @GL_GNULIB_STRSEP@
+GL_GNULIB_STRSIGNAL = @GL_GNULIB_STRSIGNAL@
+GL_GNULIB_STRSTR = @GL_GNULIB_STRSTR@
+GL_GNULIB_STRTOD = @GL_GNULIB_STRTOD@
+GL_GNULIB_STRTOIMAX = @GL_GNULIB_STRTOIMAX@
+GL_GNULIB_STRTOK_R = @GL_GNULIB_STRTOK_R@
+GL_GNULIB_STRTOL = @GL_GNULIB_STRTOL@
+GL_GNULIB_STRTOLD = @GL_GNULIB_STRTOLD@
+GL_GNULIB_STRTOLL = @GL_GNULIB_STRTOLL@
+GL_GNULIB_STRTOUL = @GL_GNULIB_STRTOUL@
+GL_GNULIB_STRTOULL = @GL_GNULIB_STRTOULL@
+GL_GNULIB_STRTOUMAX = @GL_GNULIB_STRTOUMAX@
+GL_GNULIB_STRVERSCMP = @GL_GNULIB_STRVERSCMP@
+GL_GNULIB_SYMLINK = @GL_GNULIB_SYMLINK@
+GL_GNULIB_SYMLINKAT = @GL_GNULIB_SYMLINKAT@
+GL_GNULIB_SYSTEM_POSIX = @GL_GNULIB_SYSTEM_POSIX@
+GL_GNULIB_TIMEGM = @GL_GNULIB_TIMEGM@
+GL_GNULIB_TIMESPEC_GET = @GL_GNULIB_TIMESPEC_GET@
+GL_GNULIB_TIMESPEC_GETRES = @GL_GNULIB_TIMESPEC_GETRES@
+GL_GNULIB_TIME_R = @GL_GNULIB_TIME_R@
+GL_GNULIB_TIME_RZ = @GL_GNULIB_TIME_RZ@
+GL_GNULIB_TMPFILE = @GL_GNULIB_TMPFILE@
+GL_GNULIB_TOWCTRANS = @GL_GNULIB_TOWCTRANS@
+GL_GNULIB_TRUNCATE = @GL_GNULIB_TRUNCATE@
+GL_GNULIB_TTYNAME_R = @GL_GNULIB_TTYNAME_R@
+GL_GNULIB_TZSET = @GL_GNULIB_TZSET@
+GL_GNULIB_UNISTD_H_GETOPT = @GL_GNULIB_UNISTD_H_GETOPT@
+GL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GNULIB_UNISTD_H_NONBLOCKING@
+GL_GNULIB_UNISTD_H_SIGPIPE = @GL_GNULIB_UNISTD_H_SIGPIPE@
+GL_GNULIB_UNLINK = @GL_GNULIB_UNLINK@
+GL_GNULIB_UNLINKAT = @GL_GNULIB_UNLINKAT@
+GL_GNULIB_UNLOCKPT = @GL_GNULIB_UNLOCKPT@
+GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@
+GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@
+GL_GNULIB_UTIME = @GL_GNULIB_UTIME@
+GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@
+GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@
+GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@
+GL_GNULIB_VFPRINTF = @GL_GNULIB_VFPRINTF@
+GL_GNULIB_VFPRINTF_POSIX = @GL_GNULIB_VFPRINTF_POSIX@
+GL_GNULIB_VFSCANF = @GL_GNULIB_VFSCANF@
+GL_GNULIB_VPRINTF = @GL_GNULIB_VPRINTF@
+GL_GNULIB_VPRINTF_POSIX = @GL_GNULIB_VPRINTF_POSIX@
+GL_GNULIB_VSCANF = @GL_GNULIB_VSCANF@
+GL_GNULIB_VSNPRINTF = @GL_GNULIB_VSNPRINTF@
+GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@
+GL_GNULIB_WAITPID = @GL_GNULIB_WAITPID@
+GL_GNULIB_WCPCPY = @GL_GNULIB_WCPCPY@
+GL_GNULIB_WCPNCPY = @GL_GNULIB_WCPNCPY@
+GL_GNULIB_WCRTOMB = @GL_GNULIB_WCRTOMB@
+GL_GNULIB_WCSCASECMP = @GL_GNULIB_WCSCASECMP@
+GL_GNULIB_WCSCAT = @GL_GNULIB_WCSCAT@
+GL_GNULIB_WCSCHR = @GL_GNULIB_WCSCHR@
+GL_GNULIB_WCSCMP = @GL_GNULIB_WCSCMP@
+GL_GNULIB_WCSCOLL = @GL_GNULIB_WCSCOLL@
+GL_GNULIB_WCSCPY = @GL_GNULIB_WCSCPY@
+GL_GNULIB_WCSCSPN = @GL_GNULIB_WCSCSPN@
+GL_GNULIB_WCSDUP = @GL_GNULIB_WCSDUP@
+GL_GNULIB_WCSFTIME = @GL_GNULIB_WCSFTIME@
+GL_GNULIB_WCSLEN = @GL_GNULIB_WCSLEN@
+GL_GNULIB_WCSNCASECMP = @GL_GNULIB_WCSNCASECMP@
+GL_GNULIB_WCSNCAT = @GL_GNULIB_WCSNCAT@
+GL_GNULIB_WCSNCMP = @GL_GNULIB_WCSNCMP@
+GL_GNULIB_WCSNCPY = @GL_GNULIB_WCSNCPY@
+GL_GNULIB_WCSNLEN = @GL_GNULIB_WCSNLEN@
+GL_GNULIB_WCSNRTOMBS = @GL_GNULIB_WCSNRTOMBS@
+GL_GNULIB_WCSPBRK = @GL_GNULIB_WCSPBRK@
+GL_GNULIB_WCSRCHR = @GL_GNULIB_WCSRCHR@
+GL_GNULIB_WCSRTOMBS = @GL_GNULIB_WCSRTOMBS@
+GL_GNULIB_WCSSPN = @GL_GNULIB_WCSSPN@
+GL_GNULIB_WCSSTR = @GL_GNULIB_WCSSTR@
+GL_GNULIB_WCSTOK = @GL_GNULIB_WCSTOK@
+GL_GNULIB_WCSWIDTH = @GL_GNULIB_WCSWIDTH@
+GL_GNULIB_WCSXFRM = @GL_GNULIB_WCSXFRM@
+GL_GNULIB_WCTOB = @GL_GNULIB_WCTOB@
+GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@
+GL_GNULIB_WCTRANS = @GL_GNULIB_WCTRANS@
+GL_GNULIB_WCTYPE = @GL_GNULIB_WCTYPE@
+GL_GNULIB_WCWIDTH = @GL_GNULIB_WCWIDTH@
+GL_GNULIB_WMEMCHR = @GL_GNULIB_WMEMCHR@
+GL_GNULIB_WMEMCMP = @GL_GNULIB_WMEMCMP@
+GL_GNULIB_WMEMCPY = @GL_GNULIB_WMEMCPY@
+GL_GNULIB_WMEMMOVE = @GL_GNULIB_WMEMMOVE@
+GL_GNULIB_WMEMPCPY = @GL_GNULIB_WMEMPCPY@
+GL_GNULIB_WMEMSET = @GL_GNULIB_WMEMSET@
+GL_GNULIB_WRITE = @GL_GNULIB_WRITE@
+GL_GNULIB__EXIT = @GL_GNULIB__EXIT@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIBHEADERS_OVERRIDE_WINT_T = @GNULIBHEADERS_OVERRIDE_WINT_T@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNULIB_WARN_CFLAGS = @GNULIB_WARN_CFLAGS@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GPGME_CFLAGS = @GPGME_CFLAGS@
+GPGME_CONFIG = @GPGME_CONFIG@
+GPGME_LIBS = @GPGME_LIBS@
+GREP = @GREP@
+HAVE_ACCEPT4 = @HAVE_ACCEPT4@
+HAVE_ALIGNED_ALLOC = @HAVE_ALIGNED_ALLOC@
+HAVE_ALLOCA_H = @HAVE_ALLOCA_H@
+HAVE_ALPHASORT = @HAVE_ALPHASORT@
+HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_C99_STDINT_H = @HAVE_C99_STDINT_H@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_CLOSEDIR = @HAVE_CLOSEDIR@
+HAVE_COPY_FILE_RANGE = @HAVE_COPY_FILE_RANGE@
+HAVE_CRTDEFS_H = @HAVE_CRTDEFS_H@
+HAVE_DECL_DIRFD = @HAVE_DECL_DIRFD@
+HAVE_DECL_ECVT = @HAVE_DECL_ECVT@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_EXECVPE = @HAVE_DECL_EXECVPE@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_FCLOSEALL = @HAVE_DECL_FCLOSEALL@
+HAVE_DECL_FCVT = @HAVE_DECL_FCVT@
+HAVE_DECL_FDATASYNC = @HAVE_DECL_FDATASYNC@
+HAVE_DECL_FDOPENDIR = @HAVE_DECL_FDOPENDIR@
+HAVE_DECL_FPURGE = @HAVE_DECL_FPURGE@
+HAVE_DECL_FREEADDRINFO = @HAVE_DECL_FREEADDRINFO@
+HAVE_DECL_FSEEKO = @HAVE_DECL_FSEEKO@
+HAVE_DECL_FTELLO = @HAVE_DECL_FTELLO@
+HAVE_DECL_GAI_STRERROR = @HAVE_DECL_GAI_STRERROR@
+HAVE_DECL_GCVT = @HAVE_DECL_GCVT@
+HAVE_DECL_GETADDRINFO = @HAVE_DECL_GETADDRINFO@
+HAVE_DECL_GETDELIM = @HAVE_DECL_GETDELIM@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLINE = @HAVE_DECL_GETLINE@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN = @HAVE_DECL_GETLOGIN@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETNAMEINFO = @HAVE_DECL_GETNAMEINFO@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_IMAXABS = @HAVE_DECL_IMAXABS@
+HAVE_DECL_IMAXDIV = @HAVE_DECL_IMAXDIV@
+HAVE_DECL_INET_NTOP = @HAVE_DECL_INET_NTOP@
+HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@
+HAVE_DECL_INITSTATE = @HAVE_DECL_INITSTATE@
+HAVE_DECL_LOCALTIME_R = @HAVE_DECL_LOCALTIME_R@
+HAVE_DECL_MEMMEM = @HAVE_DECL_MEMMEM@
+HAVE_DECL_MEMRCHR = @HAVE_DECL_MEMRCHR@
+HAVE_DECL_OBSTACK_PRINTF = @HAVE_DECL_OBSTACK_PRINTF@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_SETHOSTNAME = @HAVE_DECL_SETHOSTNAME@
+HAVE_DECL_SETSTATE = @HAVE_DECL_SETSTATE@
+HAVE_DECL_SNPRINTF = @HAVE_DECL_SNPRINTF@
+HAVE_DECL_STRDUP = @HAVE_DECL_STRDUP@
+HAVE_DECL_STRERROR_R = @HAVE_DECL_STRERROR_R@
+HAVE_DECL_STRNCASECMP = @HAVE_DECL_STRNCASECMP@
+HAVE_DECL_STRNDUP = @HAVE_DECL_STRNDUP@
+HAVE_DECL_STRNLEN = @HAVE_DECL_STRNLEN@
+HAVE_DECL_STRSIGNAL = @HAVE_DECL_STRSIGNAL@
+HAVE_DECL_STRTOIMAX = @HAVE_DECL_STRTOIMAX@
+HAVE_DECL_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_STRTOUMAX = @HAVE_DECL_STRTOUMAX@
+HAVE_DECL_TRUNCATE = @HAVE_DECL_TRUNCATE@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCSDUP = @HAVE_DECL_WCSDUP@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DIRENT_H = @HAVE_DIRENT_H@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_DUPLOCALE = @HAVE_DUPLOCALE@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_EXECVPE = @HAVE_EXECVPE@
+HAVE_EXPLICIT_BZERO = @HAVE_EXPLICIT_BZERO@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FDATASYNC = @HAVE_FDATASYNC@
+HAVE_FDOPENDIR = @HAVE_FDOPENDIR@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FFS = @HAVE_FFS@
+HAVE_FFSL = @HAVE_FFSL@
+HAVE_FFSLL = @HAVE_FFSLL@
+HAVE_FLOCK = @HAVE_FLOCK@
+HAVE_FNMATCH = @HAVE_FNMATCH@
+HAVE_FNMATCH_H = @HAVE_FNMATCH_H@
+HAVE_FREELOCALE = @HAVE_FREELOCALE@
+HAVE_FSEEKO = @HAVE_FSEEKO@
+HAVE_FSTATAT = @HAVE_FSTATAT@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTELLO = @HAVE_FTELLO@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_FUTIMENS = @HAVE_FUTIMENS@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETENTROPY = @HAVE_GETENTROPY@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETPASS = @HAVE_GETPASS@
+HAVE_GETRANDOM = @HAVE_GETRANDOM@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GETUMASK = @HAVE_GETUMASK@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_IMAXDIV_T = @HAVE_IMAXDIV_T@
+HAVE_INITSTATE = @HAVE_INITSTATE@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISBLANK = @HAVE_ISBLANK@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_ALTMON = @HAVE_LANGINFO_ALTMON@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LIBGNUTLS = @HAVE_LIBGNUTLS@
+HAVE_LIBSSL = @HAVE_LIBSSL@
+HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LSTAT = @HAVE_LSTAT@
+HAVE_MAX_ALIGN_T = @HAVE_MAX_ALIGN_T@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSLEN = @HAVE_MBSLEN@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MBTOWC = @HAVE_MBTOWC@
+HAVE_MEMPCPY = @HAVE_MEMPCPY@
+HAVE_MKDIRAT = @HAVE_MKDIRAT@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKFIFO = @HAVE_MKFIFO@
+HAVE_MKFIFOAT = @HAVE_MKFIFOAT@
+HAVE_MKNOD = @HAVE_MKNOD@
+HAVE_MKNODAT = @HAVE_MKNODAT@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_MSVC_INVALID_PARAMETER_HANDLER = @HAVE_MSVC_INVALID_PARAMETER_HANDLER@
+HAVE_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NETDB_H = @HAVE_NETDB_H@
+HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_NEWLOCALE = @HAVE_NEWLOCALE@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OPENDIR = @HAVE_OPENDIR@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PCLOSE = @HAVE_PCLOSE@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_POPEN = @HAVE_POPEN@
+HAVE_POSIX_MEMALIGN = @HAVE_POSIX_MEMALIGN@
+HAVE_POSIX_OPENPT = @HAVE_POSIX_OPENPT@
+HAVE_POSIX_SIGNALBLOCKING = @HAVE_POSIX_SIGNALBLOCKING@
+HAVE_POSIX_SPAWN = @HAVE_POSIX_SPAWN@
+HAVE_POSIX_SPAWNATTR_T = @HAVE_POSIX_SPAWNATTR_T@
+HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@
+HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+HAVE_POSIX_SPAWN_FILE_ACTIONS_T = @HAVE_POSIX_SPAWN_FILE_ACTIONS_T@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PSELECT = @HAVE_PSELECT@
+HAVE_PTHREAD_SIGMASK = @HAVE_PTHREAD_SIGMASK@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PTSNAME_R = @HAVE_PTSNAME_R@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_QSORT_R = @HAVE_QSORT_R@
+HAVE_RAISE = @HAVE_RAISE@
+HAVE_RANDOM = @HAVE_RANDOM@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READDIR = @HAVE_READDIR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALLOCARRAY = @HAVE_REALLOCARRAY@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_REWINDDIR = @HAVE_REWINDDIR@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@
+HAVE_SCANDIR = @HAVE_SCANDIR@
+HAVE_SCHED_H = @HAVE_SCHED_H@
+HAVE_SCHED_YIELD = @HAVE_SCHED_YIELD@
+HAVE_SECURE_GETENV = @HAVE_SECURE_GETENV@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SETHOSTNAME = @HAVE_SETHOSTNAME@
+HAVE_SETSTATE = @HAVE_SETSTATE@
+HAVE_SIGABBREV_NP = @HAVE_SIGABBREV_NP@
+HAVE_SIGACTION = @HAVE_SIGACTION@
+HAVE_SIGDESCR_NP = @HAVE_SIGDESCR_NP@
+HAVE_SIGHANDLER_T = @HAVE_SIGHANDLER_T@
+HAVE_SIGINFO_T = @HAVE_SIGINFO_T@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SIGSET_T = @HAVE_SIGSET_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_SPAWN_H = @HAVE_SPAWN_H@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STPCPY = @HAVE_STPCPY@
+HAVE_STPNCPY = @HAVE_STPNCPY@
+HAVE_STRCASECMP = @HAVE_STRCASECMP@
+HAVE_STRCASESTR = @HAVE_STRCASESTR@
+HAVE_STRCHRNUL = @HAVE_STRCHRNUL@
+HAVE_STRERRORNAME_NP = @HAVE_STRERRORNAME_NP@
+HAVE_STRINGS_H = @HAVE_STRINGS_H@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOL = @HAVE_STRTOL@
+HAVE_STRTOLD = @HAVE_STRTOLD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOUL = @HAVE_STRTOUL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_ADDRINFO = @HAVE_STRUCT_ADDRINFO@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_STRUCT_SCHED_PARAM = @HAVE_STRUCT_SCHED_PARAM@
+HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
+HAVE_STRUCT_SOCKADDR_STORAGE = @HAVE_STRUCT_SOCKADDR_STORAGE@
+HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY = @HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY@
+HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
+HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_CDEFS_H = @HAVE_SYS_CDEFS_H@
+HAVE_SYS_FILE_H = @HAVE_SYS_FILE_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_IOCTL_H = @HAVE_SYS_IOCTL_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_RANDOM_H = @HAVE_SYS_RANDOM_H@
+HAVE_SYS_SELECT_H = @HAVE_SYS_SELECT_H@
+HAVE_SYS_SOCKET_H = @HAVE_SYS_SOCKET_H@
+HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_SYS_UIO_H = @HAVE_SYS_UIO_H@
+HAVE_TIMEGM = @HAVE_TIMEGM@
+HAVE_TIMESPEC_GET = @HAVE_TIMESPEC_GET@
+HAVE_TIMESPEC_GETRES = @HAVE_TIMESPEC_GETRES@
+HAVE_TIMEZONE_T = @HAVE_TIMEZONE_T@
+HAVE_TYPE_VOLATILE_SIG_ATOMIC_T = @HAVE_TYPE_VOLATILE_SIG_ATOMIC_T@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIME = @HAVE_UTIME@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_UTIME_H = @HAVE_UTIME_H@
+HAVE_VALGRIND = @HAVE_VALGRIND@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+HAVE_VISIBILITY = @HAVE_VISIBILITY@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCPCPY = @HAVE_WCPCPY@
+HAVE_WCPNCPY = @HAVE_WCPNCPY@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSCASECMP = @HAVE_WCSCASECMP@
+HAVE_WCSCAT = @HAVE_WCSCAT@
+HAVE_WCSCHR = @HAVE_WCSCHR@
+HAVE_WCSCMP = @HAVE_WCSCMP@
+HAVE_WCSCOLL = @HAVE_WCSCOLL@
+HAVE_WCSCPY = @HAVE_WCSCPY@
+HAVE_WCSCSPN = @HAVE_WCSCSPN@
+HAVE_WCSDUP = @HAVE_WCSDUP@
+HAVE_WCSFTIME = @HAVE_WCSFTIME@
+HAVE_WCSLEN = @HAVE_WCSLEN@
+HAVE_WCSNCASECMP = @HAVE_WCSNCASECMP@
+HAVE_WCSNCAT = @HAVE_WCSNCAT@
+HAVE_WCSNCMP = @HAVE_WCSNCMP@
+HAVE_WCSNCPY = @HAVE_WCSNCPY@
+HAVE_WCSNLEN = @HAVE_WCSNLEN@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSPBRK = @HAVE_WCSPBRK@
+HAVE_WCSRCHR = @HAVE_WCSRCHR@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCSSPN = @HAVE_WCSSPN@
+HAVE_WCSSTR = @HAVE_WCSSTR@
+HAVE_WCSTOK = @HAVE_WCSTOK@
+HAVE_WCSWIDTH = @HAVE_WCSWIDTH@
+HAVE_WCSXFRM = @HAVE_WCSXFRM@
+HAVE_WCTRANS_T = @HAVE_WCTRANS_T@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WCTYPE_T = @HAVE_WCTYPE_T@
+HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE_WMEMCHR = @HAVE_WMEMCHR@
+HAVE_WMEMCMP = @HAVE_WMEMCMP@
+HAVE_WMEMCPY = @HAVE_WMEMCPY@
+HAVE_WMEMMOVE = @HAVE_WMEMMOVE@
+HAVE_WMEMPCPY = @HAVE_WMEMPCPY@
+HAVE_WMEMSET = @HAVE_WMEMSET@
+HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_H@
+HAVE_XLOCALE_H = @HAVE_XLOCALE_H@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+HOSTENT_LIB = @HOSTENT_LIB@
+ICONV_CONST = @ICONV_CONST@
+ICONV_H = @ICONV_H@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INET_NTOP_LIB = @INET_NTOP_LIB@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INT32_MAX_LT_INTMAX_MAX = @INT32_MAX_LT_INTMAX_MAX@
+INT64_MAX_EQ_LONG_MAX = @INT64_MAX_EQ_LONG_MAX@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LCOV = @LCOV@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBGNUTLS = @LIBGNUTLS@
+LIBGNUTLS_PREFIX = @LIBGNUTLS_PREFIX@
+LIBGNU_LIBDEPS = @LIBGNU_LIBDEPS@
+LIBGNU_LTLIBDEPS = @LIBGNU_LTLIBDEPS@
+LIBICONV = @LIBICONV@
+LIBIDN2_CFLAGS = @LIBIDN2_CFLAGS@
+LIBIDN2_LIBS = @LIBIDN2_LIBS@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPMULTITHREAD = @LIBPMULTITHREAD@
+LIBPSL_CFLAGS = @LIBPSL_CFLAGS@
+LIBPSL_LIBS = @LIBPSL_LIBS@
+LIBPTHREAD = @LIBPTHREAD@
+LIBS = @LIBS@
+LIBSOCKET = @LIBSOCKET@
+LIBSSL = @LIBSSL@
+LIBSSL_PREFIX = @LIBSSL_PREFIX@
+LIBSTDTHREAD = @LIBSTDTHREAD@
+LIBTHREAD = @LIBTHREAD@
+LIBUNISTRING = @LIBUNISTRING@
+LIBUNISTRING_PREFIX = @LIBUNISTRING_PREFIX@
+LIBUNISTRING_UNICASE_H = @LIBUNISTRING_UNICASE_H@
+LIBUNISTRING_UNICTYPE_H = @LIBUNISTRING_UNICTYPE_H@
+LIBUNISTRING_UNINORM_H = @LIBUNISTRING_UNINORM_H@
+LIBUNISTRING_UNISTR_H = @LIBUNISTRING_UNISTR_H@
+LIBUNISTRING_UNITYPES_H = @LIBUNISTRING_UNITYPES_H@
+LIBUNISTRING_UNIWIDTH_H = @LIBUNISTRING_UNIWIDTH_H@
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
+LIB_CRYPTO = @LIB_CRYPTO@
+LIB_FUZZING_ENGINE = @LIB_FUZZING_ENGINE@
+LIB_GETRANDOM = @LIB_GETRANDOM@
+LIB_HARD_LOCALE = @LIB_HARD_LOCALE@
+LIB_MBRTOWC = @LIB_MBRTOWC@
+LIB_NANOSLEEP = @LIB_NANOSLEEP@
+LIB_NL_LANGINFO = @LIB_NL_LANGINFO@
+LIB_POSIX_SPAWN = @LIB_POSIX_SPAWN@
+LIB_PTHREAD_SIGMASK = @LIB_PTHREAD_SIGMASK@
+LIB_SCHED_YIELD = @LIB_SCHED_YIELD@
+LIB_SELECT = @LIB_SELECT@
+LIB_SETLOCALE_NULL = @LIB_SETLOCALE_NULL@
+LIMITS_H = @LIMITS_H@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALENAME_ENHANCE_LOCALE_FUNCS = @LOCALENAME_ENHANCE_LOCALE_FUNCS@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBGNUTLS = @LTLIBGNUTLS@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBMULTITHREAD = @LTLIBMULTITHREAD@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBSSL = @LTLIBSSL@
+LTLIBTHREAD = @LTLIBTHREAD@
+LTLIBUNISTRING = @LTLIBUNISTRING@
+MAKEINFO = @MAKEINFO@
+METALINK_CFLAGS = @METALINK_CFLAGS@
+METALINK_LIBS = @METALINK_LIBS@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGMERGE = @MSGMERGE@
+MSGMERGE_FOR_MSGFMT_OPTION = @MSGMERGE_FOR_MSGFMT_OPTION@
+NETINET_IN_H = @NETINET_IN_H@
+NETTLE_CFLAGS = @NETTLE_CFLAGS@
+NETTLE_LIBS = @NETTLE_LIBS@
+NEXT_ARPA_INET_H = @NEXT_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H = @NEXT_AS_FIRST_DIRECTIVE_ARPA_INET_H@
+NEXT_AS_FIRST_DIRECTIVE_CTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_CTYPE_H@
+NEXT_AS_FIRST_DIRECTIVE_DIRENT_H = @NEXT_AS_FIRST_DIRECTIVE_DIRENT_H@
+NEXT_AS_FIRST_DIRECTIVE_ERRNO_H = @NEXT_AS_FIRST_DIRECTIVE_ERRNO_H@
+NEXT_AS_FIRST_DIRECTIVE_FCNTL_H = @NEXT_AS_FIRST_DIRECTIVE_FCNTL_H@
+NEXT_AS_FIRST_DIRECTIVE_FLOAT_H = @NEXT_AS_FIRST_DIRECTIVE_FLOAT_H@
+NEXT_AS_FIRST_DIRECTIVE_FNMATCH_H = @NEXT_AS_FIRST_DIRECTIVE_FNMATCH_H@
+NEXT_AS_FIRST_DIRECTIVE_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_ICONV_H = @NEXT_AS_FIRST_DIRECTIVE_ICONV_H@
+NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H = @NEXT_AS_FIRST_DIRECTIVE_INTTYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_LIMITS_H = @NEXT_AS_FIRST_DIRECTIVE_LIMITS_H@
+NEXT_AS_FIRST_DIRECTIVE_LOCALE_H = @NEXT_AS_FIRST_DIRECTIVE_LOCALE_H@
+NEXT_AS_FIRST_DIRECTIVE_NETDB_H = @NEXT_AS_FIRST_DIRECTIVE_NETDB_H@
+NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H = @NEXT_AS_FIRST_DIRECTIVE_NETINET_IN_H@
+NEXT_AS_FIRST_DIRECTIVE_SCHED_H = @NEXT_AS_FIRST_DIRECTIVE_SCHED_H@
+NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H = @NEXT_AS_FIRST_DIRECTIVE_SIGNAL_H@
+NEXT_AS_FIRST_DIRECTIVE_SPAWN_H = @NEXT_AS_FIRST_DIRECTIVE_SPAWN_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDIO_H = @NEXT_AS_FIRST_DIRECTIVE_STDIO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_STRINGS_H = @NEXT_AS_FIRST_DIRECTIVE_STRINGS_H@
+NEXT_AS_FIRST_DIRECTIVE_STRING_H = @NEXT_AS_FIRST_DIRECTIVE_STRING_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_FILE_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_RANDOM_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SELECT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_SOCKET_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_STAT_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_TYPES_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_UIO_H@
+NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_WAIT_H@
+NEXT_AS_FIRST_DIRECTIVE_TIME_H = @NEXT_AS_FIRST_DIRECTIVE_TIME_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_UTIME_H = @NEXT_AS_FIRST_DIRECTIVE_UTIME_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_CTYPE_H = @NEXT_CTYPE_H@
+NEXT_DIRENT_H = @NEXT_DIRENT_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_FNMATCH_H = @NEXT_FNMATCH_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_ICONV_H = @NEXT_ICONV_H@
+NEXT_INTTYPES_H = @NEXT_INTTYPES_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_LIMITS_H = @NEXT_LIMITS_H@
+NEXT_LOCALE_H = @NEXT_LOCALE_H@
+NEXT_NETDB_H = @NEXT_NETDB_H@
+NEXT_NETINET_IN_H = @NEXT_NETINET_IN_H@
+NEXT_SCHED_H = @NEXT_SCHED_H@
+NEXT_SIGNAL_H = @NEXT_SIGNAL_H@
+NEXT_SPAWN_H = @NEXT_SPAWN_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDIO_H = @NEXT_STDIO_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_STRINGS_H = @NEXT_STRINGS_H@
+NEXT_STRING_H = @NEXT_STRING_H@
+NEXT_SYS_FILE_H = @NEXT_SYS_FILE_H@
+NEXT_SYS_IOCTL_H = @NEXT_SYS_IOCTL_H@
+NEXT_SYS_RANDOM_H = @NEXT_SYS_RANDOM_H@
+NEXT_SYS_SELECT_H = @NEXT_SYS_SELECT_H@
+NEXT_SYS_SOCKET_H = @NEXT_SYS_SOCKET_H@
+NEXT_SYS_STAT_H = @NEXT_SYS_STAT_H@
+NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@
+NEXT_SYS_TYPES_H = @NEXT_SYS_TYPES_H@
+NEXT_SYS_UIO_H = @NEXT_SYS_UIO_H@
+NEXT_SYS_WAIT_H = @NEXT_SYS_WAIT_H@
+NEXT_TIME_H = @NEXT_TIME_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_UTIME_H = @NEXT_UTIME_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+OBJEXT = @OBJEXT@
+OPENSSL_CFLAGS = @OPENSSL_CFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCRE2_CFLAGS = @PCRE2_CFLAGS@
+PCRE2_LIBS = @PCRE2_LIBS@
+PCRE_CFLAGS = @PCRE_CFLAGS@
+PCRE_LIBS = @PCRE_LIBS@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POD2MAN = @POD2MAN@
+POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PRIPTR_PREFIX = @PRIPTR_PREFIX@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+REPLACE_ACCESS = @REPLACE_ACCESS@
+REPLACE_ALIGNED_ALLOC = @REPLACE_ALIGNED_ALLOC@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC_FOR_CALLOC_GNU = @REPLACE_CALLOC_FOR_CALLOC_GNU@
+REPLACE_CALLOC_FOR_CALLOC_POSIX = @REPLACE_CALLOC_FOR_CALLOC_POSIX@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_CLOSEDIR = @REPLACE_CLOSEDIR@
+REPLACE_COPY_FILE_RANGE = @REPLACE_COPY_FILE_RANGE@
+REPLACE_CREAT = @REPLACE_CREAT@
+REPLACE_CTIME = @REPLACE_CTIME@
+REPLACE_DIRFD = @REPLACE_DIRFD@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_DUPLOCALE = @REPLACE_DUPLOCALE@
+REPLACE_EXECL = @REPLACE_EXECL@
+REPLACE_EXECLE = @REPLACE_EXECLE@
+REPLACE_EXECLP = @REPLACE_EXECLP@
+REPLACE_EXECV = @REPLACE_EXECV@
+REPLACE_EXECVE = @REPLACE_EXECVE@
+REPLACE_EXECVP = @REPLACE_EXECVP@
+REPLACE_EXECVPE = @REPLACE_EXECVPE@
+REPLACE_FACCESSAT = @REPLACE_FACCESSAT@
+REPLACE_FCHMODAT = @REPLACE_FCHMODAT@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FDOPEN = @REPLACE_FDOPEN@
+REPLACE_FDOPENDIR = @REPLACE_FDOPENDIR@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FFSLL = @REPLACE_FFSLL@
+REPLACE_FNMATCH = @REPLACE_FNMATCH@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FOPEN_FOR_FOPEN_GNU = @REPLACE_FOPEN_FOR_FOPEN_GNU@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+REPLACE_FREE = @REPLACE_FREE@
+REPLACE_FREELOCALE = @REPLACE_FREELOCALE@
+REPLACE_FREOPEN = @REPLACE_FREOPEN@
+REPLACE_FSEEK = @REPLACE_FSEEK@
+REPLACE_FSEEKO = @REPLACE_FSEEKO@
+REPLACE_FSTAT = @REPLACE_FSTAT@
+REPLACE_FSTATAT = @REPLACE_FSTATAT@
+REPLACE_FTELL = @REPLACE_FTELL@
+REPLACE_FTELLO = @REPLACE_FTELLO@
+REPLACE_FTRUNCATE = @REPLACE_FTRUNCATE@
+REPLACE_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GAI_STRERROR = @REPLACE_GAI_STRERROR@
+REPLACE_GETADDRINFO = @REPLACE_GETADDRINFO@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETDTABLESIZE = @REPLACE_GETDTABLESIZE@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETPASS = @REPLACE_GETPASS@
+REPLACE_GETPASS_FOR_GETPASS_GNU = @REPLACE_GETPASS_FOR_GETPASS_GNU@
+REPLACE_GETRANDOM = @REPLACE_GETRANDOM@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_GMTIME = @REPLACE_GMTIME@
+REPLACE_ICONV = @REPLACE_ICONV@
+REPLACE_ICONV_OPEN = @REPLACE_ICONV_OPEN@
+REPLACE_ICONV_UTF = @REPLACE_ICONV_UTF@
+REPLACE_INET_NTOP = @REPLACE_INET_NTOP@
+REPLACE_INET_PTON = @REPLACE_INET_PTON@
+REPLACE_INITSTATE = @REPLACE_INITSTATE@
+REPLACE_IOCTL = @REPLACE_IOCTL@
+REPLACE_ISATTY = @REPLACE_ISATTY@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_ISWDIGIT = @REPLACE_ISWDIGIT@
+REPLACE_ISWXDIGIT = @REPLACE_ISWXDIGIT@
+REPLACE_ITOLD = @REPLACE_ITOLD@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALECONV = @REPLACE_LOCALECONV@
+REPLACE_LOCALTIME = @REPLACE_LOCALTIME@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC_FOR_MALLOC_GNU = @REPLACE_MALLOC_FOR_MALLOC_GNU@
+REPLACE_MALLOC_FOR_MALLOC_POSIX = @REPLACE_MALLOC_FOR_MALLOC_POSIX@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MBTOWC = @REPLACE_MBTOWC@
+REPLACE_MEMCHR = @REPLACE_MEMCHR@
+REPLACE_MEMMEM = @REPLACE_MEMMEM@
+REPLACE_MKDIR = @REPLACE_MKDIR@
+REPLACE_MKFIFO = @REPLACE_MKFIFO@
+REPLACE_MKFIFOAT = @REPLACE_MKFIFOAT@
+REPLACE_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKNODAT = @REPLACE_MKNODAT@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NEWLOCALE = @REPLACE_NEWLOCALE@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_OPENDIR = @REPLACE_OPENDIR@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_POSIX_MEMALIGN = @REPLACE_POSIX_MEMALIGN@
+REPLACE_POSIX_SPAWN = @REPLACE_POSIX_SPAWN@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PSELECT = @REPLACE_PSELECT@
+REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@
+REPLACE_PTSNAME = @REPLACE_PTSNAME@
+REPLACE_PTSNAME_R = @REPLACE_PTSNAME_R@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_QSORT_R = @REPLACE_QSORT_R@
+REPLACE_RAISE = @REPLACE_RAISE@
+REPLACE_RANDOM = @REPLACE_RANDOM@
+REPLACE_RANDOM_R = @REPLACE_RANDOM_R@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_READLINKAT = @REPLACE_READLINKAT@
+REPLACE_REALLOCARRAY = @REPLACE_REALLOCARRAY@
+REPLACE_REALLOC_FOR_REALLOC_GNU = @REPLACE_REALLOC_FOR_REALLOC_GNU@
+REPLACE_REALLOC_FOR_REALLOC_POSIX = @REPLACE_REALLOC_FOR_REALLOC_POSIX@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SCHED_YIELD = @REPLACE_SCHED_YIELD@
+REPLACE_SELECT = @REPLACE_SELECT@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SETLOCALE = @REPLACE_SETLOCALE@
+REPLACE_SETSTATE = @REPLACE_SETSTATE@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_SNPRINTF = @REPLACE_SNPRINTF@
+REPLACE_SPRINTF = @REPLACE_SPRINTF@
+REPLACE_STAT = @REPLACE_STAT@
+REPLACE_STDIO_READ_FUNCS = @REPLACE_STDIO_READ_FUNCS@
+REPLACE_STDIO_WRITE_FUNCS = @REPLACE_STDIO_WRITE_FUNCS@
+REPLACE_STPNCPY = @REPLACE_STPNCPY@
+REPLACE_STRCASESTR = @REPLACE_STRCASESTR@
+REPLACE_STRCHRNUL = @REPLACE_STRCHRNUL@
+REPLACE_STRDUP = @REPLACE_STRDUP@
+REPLACE_STRERROR = @REPLACE_STRERROR@
+REPLACE_STRERRORNAME_NP = @REPLACE_STRERRORNAME_NP@
+REPLACE_STRERROR_R = @REPLACE_STRERROR_R@
+REPLACE_STRFTIME = @REPLACE_STRFTIME@
+REPLACE_STRNCAT = @REPLACE_STRNCAT@
+REPLACE_STRNDUP = @REPLACE_STRNDUP@
+REPLACE_STRNLEN = @REPLACE_STRNLEN@
+REPLACE_STRSIGNAL = @REPLACE_STRSIGNAL@
+REPLACE_STRSTR = @REPLACE_STRSTR@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_STRTOIMAX = @REPLACE_STRTOIMAX@
+REPLACE_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_STRTOL = @REPLACE_STRTOL@
+REPLACE_STRTOLD = @REPLACE_STRTOLD@
+REPLACE_STRTOLL = @REPLACE_STRTOLL@
+REPLACE_STRTOUL = @REPLACE_STRTOUL@
+REPLACE_STRTOULL = @REPLACE_STRTOULL@
+REPLACE_STRTOUMAX = @REPLACE_STRTOUMAX@
+REPLACE_STRUCT_LCONV = @REPLACE_STRUCT_LCONV@
+REPLACE_STRUCT_TIMEVAL = @REPLACE_STRUCT_TIMEVAL@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_SYMLINKAT = @REPLACE_SYMLINKAT@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TOWLOWER = @REPLACE_TOWLOWER@
+REPLACE_TRUNCATE = @REPLACE_TRUNCATE@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_TZSET = @REPLACE_TZSET@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_UTIME = @REPLACE_UTIME@
+REPLACE_UTIMENSAT = @REPLACE_UTIMENSAT@
+REPLACE_VASPRINTF = @REPLACE_VASPRINTF@
+REPLACE_VDPRINTF = @REPLACE_VDPRINTF@
+REPLACE_VFPRINTF = @REPLACE_VFPRINTF@
+REPLACE_VPRINTF = @REPLACE_VPRINTF@
+REPLACE_VSNPRINTF = @REPLACE_VSNPRINTF@
+REPLACE_VSPRINTF = @REPLACE_VSPRINTF@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSFTIME = @REPLACE_WCSFTIME@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSTOK = @REPLACE_WCSTOK@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVENT_LIB = @SERVENT_LIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDALIGN_H = @STDALIGN_H@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+SYS_IOCTL_H_HAVE_WINSOCK2_H = @SYS_IOCTL_H_HAVE_WINSOCK2_H@
+SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@
+TIME_H_DEFINES_TIME_UTC = @TIME_H_DEFINES_TIME_UTC@
+UINT32_MAX_LT_UINTMAX_MAX = @UINT32_MAX_LT_UINTMAX_MAX@
+UINT64_MAX_EQ_ULONG_MAX = @UINT64_MAX_EQ_ULONG_MAX@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+UNISTD_H_DEFINES_STRUCT_TIMESPEC = @UNISTD_H_DEFINES_STRUCT_TIMESPEC@
+UNISTD_H_HAVE_SYS_RANDOM_H = @UNISTD_H_HAVE_SYS_RANDOM_H@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+USE_NLS = @USE_NLS@
+UUID_CFLAGS = @UUID_CFLAGS@
+UUID_LIBS = @UUID_LIBS@
+VALGRIND_TESTS = @VALGRIND_TESTS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINDOWS_64_BIT_OFF_T = @WINDOWS_64_BIT_OFF_T@
+WINDOWS_64_BIT_ST_SIZE = @WINDOWS_64_BIT_ST_SIZE@
+WINDOWS_STAT_INODES = @WINDOWS_STAT_INODES@
+WINDOWS_STAT_TIMESPEC = @WINDOWS_STAT_TIMESPEC@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJDEPS = @gl_LIBOBJDEPS@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJDEPS = @gltests_LIBOBJDEPS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+ifGNUmake = @ifGNUmake@
+ifnGNUmake = @ifnGNUmake@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+PX_TESTS = \
+ Test-auth-basic.px \
+ Test-auth-no-challenge.px \
+ Test-auth-no-challenge-url.px \
+ Test-auth-with-content-disposition.px \
+ Test-auth-retcode.px \
+ Test-c-full.px \
+ Test-c-partial.px \
+ Test-c.px \
+ Test-c-shorter.px \
+ Test-cookies.px \
+ Test-cookies-401.px \
+ Test-E-k-K.px \
+ Test-E-k.px \
+ Test-ftp.px \
+ Test-ftp-dir.px \
+ Test-ftp-pasv-fail.px \
+ Test-ftp-bad-list.px \
+ Test-ftp-recursive.px \
+ Test-ftp-iri.px \
+ Test-ftp-iri-fallback.px \
+ Test-ftp-iri-recursive.px \
+ Test-ftp-iri-disabled.px \
+ Test-ftp-list-Multinet.px \
+ Test-ftp-list-Unknown.px \
+ Test-ftp-list-Unknown-a.px \
+ Test-ftp-list-Unknown-hidden.px \
+ Test-ftp-list-Unknown-list-a-fails.px \
+ Test-ftp-list-UNIX-hidden.px \
+ Test-ftp--start-pos.px \
+ Test-HTTP-Content-Disposition-1.px \
+ Test-HTTP-Content-Disposition-2.px \
+ Test-HTTP-Content-Disposition.px \
+ Test-i-ftp.px \
+ Test-i-http.px \
+ Test-idn-headers.px \
+ Test-idn-meta.px \
+ Test-idn-cmd.px \
+ Test-idn-cmd-utf8.px \
+ Test-idn-robots.px \
+ Test-idn-robots-utf8.px \
+ Test-iri.px \
+ Test-iri-percent.px \
+ Test-iri-disabled.px \
+ Test-iri-forced-remote.px \
+ Test-iri-list.px \
+ Test-k.px \
+ Test-meta-robots.px \
+ Test-N-current.px \
+ Test-N-HTTP-Content-Disposition.px \
+ Test-N--no-content-disposition.px \
+ Test-N--no-content-disposition-trivial.px \
+ Test-N-no-info.px \
+ Test--no-content-disposition.px \
+ Test--no-content-disposition-trivial.px \
+ Test-N-old.px \
+ Test-nonexisting-quiet.px \
+ Test-noop.px \
+ Test-np.px \
+ Test-N.px \
+ Test-N-smaller.px \
+ Test-O-HTTP-Content-Disposition.px \
+ Test-O-nc.px \
+ Test-O--no-content-disposition.px \
+ Test-O--no-content-disposition-trivial.px \
+ Test-O-nonexisting.px \
+ Test-O.px \
+ Test--post-file.px \
+ Test-proxied-https-auth.px \
+ Test-proxied-https-auth-keepalive.px \
+ Test-proxy-auth-basic.px \
+ Test-restrict-ascii.px \
+ Test-Restrict-Lowercase.px \
+ Test-Restrict-Uppercase.px \
+ Test-stdouterr.px \
+ Test--spider-fail.px \
+ Test--spider.px \
+ Test--spider-r-HTTP-Content-Disposition.px \
+ Test--spider-r--no-content-disposition.px \
+ Test--spider-r--no-content-disposition-trivial.px \
+ Test--spider-r.px \
+ Test--start-pos.px \
+ Test--start-pos--continue.px \
+ Test--httpsonly-r.px \
+ Test-204.px \
+ Test-ftp-pasv-not-supported.px \
+ Test-https-pfs.px \
+ Test-https-tlsv1.px \
+ Test-https-tlsv1x.px \
+ Test-https-selfsigned.px \
+ Test-https-weboftrust.px \
+ Test-https-clientcert.px \
+ Test-https-crl.px \
+ Test-https-badcerts.px
+
+EXTRA_DIST = FTPServer.pm FTPTest.pm HTTPServer.pm HTTPTest.pm \
+ SSLTest.pm SSLServer.pm \
+ WgetTests.pm WgetFeature.pm $(PX_TESTS) \
+ certs valgrind-suppressions valgrind-suppressions-ssl
+
+unit_tests_SOURCES = unit-tests.c unit-tests.h
+LDADD = ../src/libunittest.a ../lib/libgnu.a $(GETADDRINFO_LIB) $(HOSTENT_LIB)\
+ $(INET_NTOP_LIB) $(LIBSOCKET) $(LIB_CLOCK_GETTIME) $(LIB_CRYPTO)\
+ $(LIB_NANOSLEEP) $(LIB_POSIX_SPAWN) $(LIB_SELECT) $(LIBICONV) $(LIBINTL)\
+ $(LIBTHREAD) $(LIBUNISTRING) $(SERVENT_LIB)
+
+AM_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/src -DLOCALEDIR=\"$(localedir)\"
+
+AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS)
+CLEANFILES = *~ *.bak core core.[0-9]*
+TESTS = ./unit-tests$(EXEEXT) $(PX_TESTS)
+TEST_EXTENSIONS = .px
+PX_LOG_COMPILER = $(PERL)
+AM_PX_LOG_FLAGS = -I$(srcdir)
+AM_TESTS_ENVIRONMENT = export WGETRC=; export SYSTEM_WGETRC=;\
+ export VALGRIND_TESTS="@VALGRIND_TESTS@";
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .log .o .obj .px .px$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+
+unit-tests$(EXEEXT): $(unit_tests_OBJECTS) $(unit_tests_DEPENDENCIES) $(EXTRA_unit_tests_DEPENDENCIES)
+ @rm -f unit-tests$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(unit_tests_OBJECTS) $(unit_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit-tests.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+./unit-tests.log: ./unit-tests$(EXEEXT)
+ @p='./unit-tests$(EXEEXT)'; \
+ b='./unit-tests'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.px.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(PX_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_PX_LOG_DRIVER_FLAGS) $(PX_LOG_DRIVER_FLAGS) -- $(PX_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.px$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(PX_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_PX_LOG_DRIVER_FLAGS) $(PX_LOG_DRIVER_FLAGS) -- $(PX_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/unit-tests.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/unit-tests.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+../src/wget$(EXEEXT):
+ cd ../src && $(MAKE) $(AM_MAKEFLAGS)
+
+# Make libunittest "PHONY" so we're always sure we're up-to-date.
+.PHONY: ../src/libunittest.a
+../src/libunittest.a:
+ cd ../src && $(MAKE) $(AM_MAKEFLAGS) libunittest.a
+
+../lib/libgnu.a:
+ cd ../lib && $(MAKE) $(AM_MAKEFLAGS)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/SSLServer.pm b/tests/SSLServer.pm
new file mode 100644
index 0000000..37a8bfa
--- /dev/null
+++ b/tests/SSLServer.pm
@@ -0,0 +1,236 @@
+package SSLServer;
+
+# This is only HTTPS server for now.
+# But it is named SSLServer to easily distinguish from HTTPServer
+
+use strict;
+use warnings;
+use lib '.';
+
+use HTTP::Daemon;
+use HTTP::Status;
+use HTTP::Headers;
+use HTTP::Response;
+
+# Skip this test rather than fail it when the module isn't installed
+if (!eval {require IO::Socket::SSL;1;}) {
+ print STDERR "This test needs the perl module \"IO::Socket::SSL\".\n";
+ print STDERR "Install e.g. on Debian with 'apt-get install libio-socket-ssl-perl'\n";
+ print STDERR " or if using cpanminus 'cpanm IO::Socket::SSL' could be used to install it.\n";
+ exit 77; # skip
+}
+
+#use IO::Socket::SSLX; # 'debug4';
+use HTTPServer;
+
+our @ISA = qw(IO::Socket::SSL HTTP::Daemon::ClientConn HTTP::Daemon HTTPServer);
+
+my $VERSION = 0.01;
+
+my $CRLF = "\015\012"; # "\r\n" is not portable
+
+# Config options for server
+my $log = undef;
+my $DEBUG = undef;
+
+my %ssl_params;
+
+my $sslsock;
+my $plaincon;
+my %args;
+
+#$HTTP::Daemon::DEBUG=5;
+#*DEBUG = \$HTTP::Daemon::DEBUG;
+
+$args{SSL_error_trap} ||= \&ssl_error;
+
+my $class = 'SSLServer';
+my $self = {};
+$self = bless $self, $class;
+
+sub init
+{
+ my $self = shift;
+ my %sargs = @_;
+
+ %ssl_params = %sargs;
+ unless (exists($ssl_params{'lhostname'}) &&
+ exists($ssl_params{'sslport'}) &&
+ exists($ssl_params{'ciphers'}) &&
+ exists($ssl_params{'cafile'}) &&
+ exists($ssl_params{'certfile'}) &&
+ exists($ssl_params{'keyfile'})) {
+ die "Required parameters for SSL tests are missing";
+ }
+}
+
+sub ssl_setup_conn
+{
+ $sslsock = IO::Socket::SSL->new(LocalAddr => $ssl_params{'lhostname'},
+ LocalPort => $ssl_params{'sslport'},
+ Listen => 10,
+ Timeout => 30,
+ ReuseAddr => 1,
+ SSL_cipher_list => $ssl_params{'ciphers'},
+ SSL_verify_mode => 0x00,
+ SSL_ca_file => $ssl_params{'cafile'},
+ SSL_cert_file => $ssl_params{'certfile'},
+ SSL_key_file => $ssl_params{'keyfile'});
+
+ $sslsock || warn $IO::Socket::SSL::ERROR;
+ return $sslsock;
+}
+
+sub fileno
+{
+ my $self = shift;
+ my $fn = ${*$self}{'_SSL_fileno'};
+ return defined($fn) ? $fn : $self->SUPER::fileno();
+}
+
+sub accept
+{
+ my $self = shift;
+ my $pkg = shift || "SSLServer";
+ my ($sock, $peer) = $sslsock->accept($pkg);
+ if ($sock) {
+ ${*$sock}{'httpd_daemon'} = $self;
+ ${*$self}{'httpd_daemon'} = $sock;
+ my $fileno = ${*$self}{'_SSL_fileno'} = &fileno($self);
+ my $f = $sock->fileno;
+ return wantarray ? ($sock, $peer) : $sock;
+ }
+ else {
+ print STDERR "Failed to get socket from SSL\n" if $DEBUG;
+ return;
+ }
+
+}
+
+sub _default_port { 443; }
+sub _default_scheme { "https"; }
+
+sub url
+{
+ my $self = shift;
+ my $url = $self->SUPER::url;
+ return $url if ($self->can("HTTP::Daemon::_default_port"));
+
+ # Workaround for old versions of HTTP::Daemon
+ $url =~ s!^http:!https:!;
+ $url =~ s!/$!:80/! unless ($url =~ m!:(?:\d+)/$!);
+ $url =~ s!:443/$!/!;
+ return $url;
+}
+
+sub _need_more
+{
+ my $self = shift;
+ if ($_[1]) {
+ my($timeout, $fdset) = @_[1,2];
+ print STDERR "select(,,,$timeout)\n" if $DEBUG;
+ my $n = select($fdset,undef,undef,$timeout);
+ unless ($n) {
+ $self->reason(defined($n) ? "Timeout" : "select: $!");
+ return;
+ }
+ }
+ my $total = 0;
+ while (1){
+ print STDERR sprintf("sysread() already %d\n",$total) if $DEBUG;
+ my $n = sysread(${*$self}{'httpd_daemon'}, $_[0], 2048, length($_[0]));
+ print STDERR sprintf("sysread() just \$n=%s\n",(defined $n?$n:'undef')) if $DEBUG;
+ $total += $n if defined $n;
+ last if $! =~ 'Resource temporarily unavailable';
+ #SSL_Error because of aggressive reading
+
+ $self->reason(defined($n) ? "Client closed" : "sysread: $!") unless $n;
+ last unless $n;
+ last unless $n == 2048;
+ }
+ $total;
+}
+
+sub daemon
+{
+ my $self = shift;
+ ${*$self}{'httpd_daemon'};
+}
+
+sub conn
+{
+ my $self = shift;
+ ${*$self}{'sslcon'};
+}
+
+sub run
+{
+ my ($self, $urls, $synch_callback) = @_;
+ my $initialized = 0;
+ my $sslsock;
+
+ while (1)
+ {
+ if (!$initialized)
+ {
+ $sslsock = $self->ssl_setup_conn();
+ $sslsock || warn "Failed to get ssl sock";
+
+ $initialized = 1;
+ open (LOGFILE, '>', "/tmp/wgetserver.log");
+ LOGFILE->autoflush(1);
+ print LOGFILE "Starting logging";
+ $synch_callback->() if $synch_callback;
+ }
+
+ my $con = $self->accept();
+ ${*$self}{'sslcon'} = $con;
+
+ while (my $req = $self->get_request)
+ {
+ #my $url_path = $req->url->path;
+ my $url_path = $req->url->as_string;
+ if ($url_path =~ m{/$})
+ { # append 'index.html'
+ $url_path .= 'index.html';
+ }
+
+ #if ($url_path =~ m{^/}) { # remove trailing '/'
+ # $url_path = substr ($url_path, 1);
+ #}
+ if ($log)
+ {
+ print LOGFILE "Method: ", $req->method, "\n";
+ print LOGFILE "Path: ", $url_path, "\n";
+ print LOGFILE "Available URLs: ", "\n";
+ foreach my $key (keys %$urls)
+ {
+ print LOGFILE $key, "\n";
+ }
+ }
+ if (exists($urls->{$url_path}))
+ {
+ print LOGFILE "Serving requested URL: ", $url_path, "\n" if $log;
+ next unless ($req->method eq "HEAD" || $req->method eq "GET");
+
+ my $url_rec = $urls->{$url_path};
+ HTTPServer::send_response($self, $req, $url_rec, $con);
+ last;
+ }
+ else
+ {
+ print LOGFILE "Requested wrong URL: ", $url_path, "\n" if $log;
+ $con->send_error($HTTP::Status::RC_FORBIDDEN);
+ last;
+ }
+ last;
+ }
+ print LOGFILE "Closing connection\n" if $log;
+ close(LOGFILE);
+ $con->close();
+ }
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/SSLTest.pm b/tests/SSLTest.pm
new file mode 100644
index 0000000..60f8188
--- /dev/null
+++ b/tests/SSLTest.pm
@@ -0,0 +1,73 @@
+package SSLTest;
+
+use strict;
+use warnings;
+
+use SSLServer;
+use WgetTests;
+use HTTPTest;
+
+our @ISA = qw(WgetTest HTTPTest);
+my $VERSION = 0.01;
+
+my $srcdir;
+if (defined $ENV{srcdir}) {
+ $srcdir = Cwd::abs_path($ENV{srcdir});
+} else {
+ $srcdir = ".";
+}
+
+my %ssl_defaults = (
+ _certfile => "$srcdir/certs/server-cert.pem",
+ _keyfile => "$srcdir/certs/server-key.pem",
+ _cafile => "$srcdir/certs/test-ca-cert.pem",
+ _ciphers => 'ALL',
+ _lhostname => 'wgettestingserver',
+ _sslport => 55443,
+);
+
+{
+ my %_attr_data = %ssl_defaults;
+
+ sub _default_for
+ {
+ my ($self, $attr) = @_;
+ return $_attr_data{$attr} if exists $_attr_data{$attr};
+ return $self->SUPER::_default_for($attr);
+ }
+
+ sub _standard_keys
+ {
+ my ($self) = @_;
+ ($self->SUPER::_standard_keys(), keys %_attr_data);
+ }
+}
+
+sub _setup_server
+{
+ my $self = shift;
+ my %ssl_config = %ssl_defaults;
+
+ $self->{_server} = SSLServer->new()
+ or die "Cannot create SSL server!!!";
+
+ for my $attrname ($self->_standard_keys())
+ {
+ my ($argname) = ($attrname =~ m/^_(.*)/msx);
+ $ssl_config{$argname} = $self->{$attrname};
+ }
+# for my $attrname (keys %ssl_config)
+# {
+# if ($attrname =~ m/file$/ && !$attrname =~ m/^\//)
+# {
+# my $cwd = $self->SUPER::_default_for('_workdir');
+# my $cfile = $ssl_config{$attrname};
+# $ssl_config{$attrname} = "$cwd/$cfile";
+# }
+# }
+ $self->{_server}->init(%ssl_config);
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--httpsonly-r.px b/tests/Test--httpsonly-r.px
new file mode 100755
index 0000000..69d8c60
--- /dev/null
+++ b/tests/Test--httpsonly-r.px
@@ -0,0 +1,78 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(https);
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/secondpage.html">second page</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $secondpage = <<EOF;
+<html>
+<head>
+ <title>Second Page</title>
+</head>
+<body>
+ <p>
+ Anything.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/secondpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $secondpage,
+ }
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --https-only -r -nH http://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $mainpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--no-content-disposition-trivial.px b/tests/Test--no-content-disposition-trivial.px
new file mode 100755
index 0000000..cf89b4a
--- /dev/null
+++ b/tests/Test--no-content-disposition-trivial.px
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+<html>
+<head>
+ <title>Page Title</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $dummyfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-content-disposition http://localhost:{{port}}/dummy.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.html' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--no-content-disposition.px b/tests/Test--no-content-disposition.px
new file mode 100755
index 0000000..94f4d50
--- /dev/null
+++ b/tests/Test--no-content-disposition.px
@@ -0,0 +1,55 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+<html>
+<head>
+ <title>Page Title</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ "Content-Disposition" => "attachment; filename=\"filename.html\"",
+ },
+ content => $dummyfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-content-disposition http://localhost:{{port}}/dummy.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.html' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--post-file.px b/tests/Test--post-file.px
new file mode 100755
index 0000000..9c866b6
--- /dev/null
+++ b/tests/Test--post-file.px
@@ -0,0 +1,22 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $cmdline = $WgetTest::WGETPATH . " --post-file=nofile http://localhost:{{port}}/";
+
+my $expected_error_code = 3;
+
+
+###############################################################################
+
+my $the_test = HTTPTest->new (cmdline => $cmdline,
+ errcode => $expected_error_code);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--spider-fail.px b/tests/Test--spider-fail.px
new file mode 100755
index 0000000..d0dfad6
--- /dev/null
+++ b/tests/Test--spider-fail.px
@@ -0,0 +1,51 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --spider http://localhost:{{port}}/nonexistent";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--spider-r--no-content-disposition-trivial.px b/tests/Test--spider-r--no-content-disposition-trivial.px
new file mode 100755
index 0000000..0f28685
--- /dev/null
+++ b/tests/Test--spider-r--no-content-disposition-trivial.px
@@ -0,0 +1,108 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/secondpage.html">second page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $secondpage = <<EOF;
+<html>
+<head>
+ <title>Second Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/thirdpage.html">third page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $thirdpage = <<EOF;
+<html>
+<head>
+ <title>Third Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/dummy.txt">text file</a>.
+ Also, another <a href="http://localhost:{{port}}/againnonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/secondpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $secondpage,
+ },
+ '/thirdpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $thirdpage,
+ },
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --spider -r --no-content-disposition http://localhost:{{port}}/";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--spider-r--no-content-disposition.px b/tests/Test--spider-r--no-content-disposition.px
new file mode 100755
index 0000000..53fb7a2
--- /dev/null
+++ b/tests/Test--spider-r--no-content-disposition.px
@@ -0,0 +1,109 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/secondpage.html">second page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $secondpage = <<EOF;
+<html>
+<head>
+ <title>Second Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/thirdpage.html">third page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $thirdpage = <<EOF;
+<html>
+<head>
+ <title>Third Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/dummy.txt">text file</a>.
+ Also, another <a href="http://localhost:{{port}}/againnonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/secondpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ "Content-Disposition" => "attachment; filename=\"filename.html\"",
+ },
+ content => $secondpage,
+ },
+ '/thirdpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $thirdpage,
+ },
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --spider -r --no-content-disposition http://localhost:{{port}}/";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--spider-r-HTTP-Content-Disposition.px b/tests/Test--spider-r-HTTP-Content-Disposition.px
new file mode 100755
index 0000000..963003e
--- /dev/null
+++ b/tests/Test--spider-r-HTTP-Content-Disposition.px
@@ -0,0 +1,109 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/secondpage.html">second page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $secondpage = <<EOF;
+<html>
+<head>
+ <title>Second Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/thirdpage.html">third page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $thirdpage = <<EOF;
+<html>
+<head>
+ <title>Third Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/dummy.txt">text file</a>.
+ Also, another <a href="http://localhost:{{port}}/againnonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/secondpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ "Content-Disposition" => "attachment; filename=\"filename.html\"",
+ },
+ content => $secondpage,
+ },
+ '/thirdpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $thirdpage,
+ },
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --spider -r http://localhost:{{port}}/";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--spider-r.px b/tests/Test--spider-r.px
new file mode 100755
index 0000000..dbafe2e
--- /dev/null
+++ b/tests/Test--spider-r.px
@@ -0,0 +1,108 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/secondpage.html">second page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $secondpage = <<EOF;
+<html>
+<head>
+ <title>Second Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/thirdpage.html">third page</a>.
+ Also, a <a href="http://localhost:{{port}}/nonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $thirdpage = <<EOF;
+<html>
+<head>
+ <title>Third Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/dummy.txt">text file</a>.
+ Also, another <a href="http://localhost:{{port}}/againnonexistent">broken link</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/secondpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $secondpage,
+ },
+ '/thirdpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $thirdpage,
+ },
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --spider -r http://localhost:{{port}}/";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--spider.px b/tests/Test--spider.px
new file mode 100755
index 0000000..2443c95
--- /dev/null
+++ b/tests/Test--spider.px
@@ -0,0 +1,51 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --spider http://localhost:{{port}}/index.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--start-pos--continue.px b/tests/Test--start-pos--continue.px
new file mode 100755
index 0000000..a821a78
--- /dev/null
+++ b/tests/Test--start-pos--continue.px
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $existingfile = <<EOF;
+content should be preserved.
+EOF
+
+my $wholefile = "1234";
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "206",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --start-pos=1 --continue --debug http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $existingfile,
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt.1' => {
+ content => substr($wholefile, 1),
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test--start-pos.px b/tests/Test--start-pos.px
new file mode 100755
index 0000000..5c887ab
--- /dev/null
+++ b/tests/Test--start-pos.px
@@ -0,0 +1,43 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = "1234";
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "206",
+ msg => "Dontcare",
+ headers => {
+ "Content-Type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --start-pos=1 http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.txt' => {
+ content => substr($dummyfile, 1),
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-204.px b/tests/Test-204.px
new file mode 100755
index 0000000..e9eea1a
--- /dev/null
+++ b/tests/Test-204.px
@@ -0,0 +1,34 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy' => {
+ code => "204",
+ msg => "Dontcare",
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " http://localhost:{{port}}/dummy";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-E-k-K.px b/tests/Test-E-k-K.px
new file mode 100755
index 0000000..aaae6fe
--- /dev/null
+++ b/tests/Test-E-k-K.px
@@ -0,0 +1,88 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page Title</title>
+</head>
+<body>
+ <a href="http://localhost:{{port}}/subpage.php">Secondary Page</a>
+</body>
+</html>
+EOF
+
+my $mainpagemangled = <<EOF;
+<html>
+<head>
+ <title>Main Page Title</title>
+</head>
+<body>
+ <a href="subpage.php.html">Secondary Page</a>
+</body>
+</html>
+EOF
+
+my $subpage = <<EOF;
+<html>
+<head>
+ <title>Secondary Page Title</title>
+</head>
+<body>
+ <p>Some text</p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.php' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/subpage.php' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $subpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -r -nd -E -k -K http://localhost:{{port}}/index.php";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.php.orig' => {
+ content => $mainpage,
+ },
+ 'index.php.html' => {
+ content => $mainpagemangled,
+ },
+ 'subpage.php.html' => {
+ content => $subpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-E-k.px b/tests/Test-E-k.px
new file mode 100755
index 0000000..dc1031b
--- /dev/null
+++ b/tests/Test-E-k.px
@@ -0,0 +1,85 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page Title</title>
+</head>
+<body>
+ <a href="http://localhost:{{port}}/subpage.php">Secondary Page</a>
+</body>
+</html>
+EOF
+
+my $mainpagemangled = <<EOF;
+<html>
+<head>
+ <title>Main Page Title</title>
+</head>
+<body>
+ <a href="subpage.php.html">Secondary Page</a>
+</body>
+</html>
+EOF
+
+my $subpage = <<EOF;
+<html>
+<head>
+ <title>Secondary Page Title</title>
+</head>
+<body>
+ <p>Some text</p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.php' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/subpage.php' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $subpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -r -nd -E -k http://localhost:{{port}}/index.php";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.php.html' => {
+ content => $mainpagemangled,
+ },
+ 'subpage.php.html' => {
+ content => $subpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-HTTP-Content-Disposition-1.px b/tests/Test-HTTP-Content-Disposition-1.px
new file mode 100755
index 0000000..343258c
--- /dev/null
+++ b/tests/Test-HTTP-Content-Disposition-1.px
@@ -0,0 +1,75 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dontcare = <<EOF;
+Don't care.
+EOF
+
+my $dummyfile = <<EOF;
+<html>
+<head>
+ <title>Page Title</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ "Content-Disposition" => "attachment; filename=\"filename.html\"",
+ },
+ content => $dummyfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -e contentdisposition=on http://localhost:{{port}}/dummy.html";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'filename.html' => {
+ content => $dontcare,
+ },
+ 'filename.html.1' => {
+ content => $dontcare,
+ },
+);
+
+my %expected_downloaded_files = (
+ 'filename.html' => {
+ content => $dontcare,
+ },
+ 'filename.html.1' => {
+ content => $dontcare,
+ },
+ 'filename.html.2' => {
+ content => $dummyfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-HTTP-Content-Disposition-2.px b/tests/Test-HTTP-Content-Disposition-2.px
new file mode 100755
index 0000000..e7a2703
--- /dev/null
+++ b/tests/Test-HTTP-Content-Disposition-2.px
@@ -0,0 +1,75 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dontcare = <<EOF;
+Don't care.
+EOF
+
+my $dummyfile = <<EOF;
+<html>
+<head>
+ <title>Page Title</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ "Content-Disposition" => "attachment; filename=\"filename.html\"",
+ },
+ content => $dummyfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-content-disposition http://localhost:{{port}}/dummy.html";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'filename.html' => {
+ content => $dontcare,
+ },
+ 'filename.html.1' => {
+ content => $dontcare,
+ },
+);
+
+my %expected_downloaded_files = (
+ 'filename.html' => {
+ content => $dontcare,
+ },
+ 'filename.html.1' => {
+ content => $dontcare,
+ },
+ 'dummy.html' => {
+ content => $dummyfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-HTTP-Content-Disposition.px b/tests/Test-HTTP-Content-Disposition.px
new file mode 100755
index 0000000..29f56d1
--- /dev/null
+++ b/tests/Test-HTTP-Content-Disposition.px
@@ -0,0 +1,55 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+<html>
+<head>
+ <title>Page Title</title>
+</head>
+<body>
+ <p>
+ Some text.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ "Content-Disposition" => "attachment; filename=\"filename.html\"",
+ },
+ content => $dummyfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -e contentdisposition=on http://localhost:{{port}}/dummy.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'filename.html' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N--no-content-disposition-trivial.px b/tests/Test-N--no-content-disposition-trivial.px
new file mode 100755
index 0000000..8abff7b
--- /dev/null
+++ b/tests/Test-N--no-content-disposition-trivial.px
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Content
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N --no-content-disposition http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.txt' => {
+ content => $dummyfile,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N--no-content-disposition.px b/tests/Test-N--no-content-disposition.px
new file mode 100755
index 0000000..7ece995
--- /dev/null
+++ b/tests/Test-N--no-content-disposition.px
@@ -0,0 +1,48 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Content
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ "Content-Disposition" => "attachment; filename=\"filename.txt\"",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N --no-content-disposition http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.txt' => {
+ content => $dummyfile,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N-HTTP-Content-Disposition.px b/tests/Test-N-HTTP-Content-Disposition.px
new file mode 100755
index 0000000..de4609b
--- /dev/null
+++ b/tests/Test-N-HTTP-Content-Disposition.px
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ "Content-Disposition" => "attachment; filename=\"filename.txt\"",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N --content-disposition "
+ . "http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'filename.txt' => {
+ content => $dummyfile,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N-current.px b/tests/Test-N-current.px
new file mode 100755
index 0000000..a8decdb
--- /dev/null
+++ b/tests/Test-N-current.px
@@ -0,0 +1,64 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $currentversion = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+# The server should serve a slightly different content, but with the
+# same length, so we can test which version was downloaded.
+my $modifiedversion = $currentversion;
+$modifiedversion =~ s/^(.{20}).(.*)$/$1x$2/s;
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ },
+ content => $modifiedversion,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $currentversion,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $currentversion,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N-no-info.px b/tests/Test-N-no-info.px
new file mode 100755
index 0000000..3c772a5
--- /dev/null
+++ b/tests/Test-N-no-info.px
@@ -0,0 +1,62 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $currentversion = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+my $newversion = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $newversion,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $currentversion,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $newversion,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N-old.px b/tests/Test-N-old.px
new file mode 100755
index 0000000..6bb18cb
--- /dev/null
+++ b/tests/Test-N-old.px
@@ -0,0 +1,62 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $oldversion = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+my $newversion = $oldversion;
+$newversion =~ s/^(.{20}).(.*)$/$1x$2/s;
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ },
+ content => $newversion,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $oldversion,
+ timestamp => 1097310000, # Earlier timestamp
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $newversion,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N-smaller.px b/tests/Test-N-smaller.px
new file mode 100755
index 0000000..34d4cd9
--- /dev/null
+++ b/tests/Test-N-smaller.px
@@ -0,0 +1,65 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $currentversion = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+my $newversion = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Content-Length" => length $newversion,
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ },
+ content => $newversion,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $currentversion,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $newversion,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-N.px b/tests/Test-N.px
new file mode 100755
index 0000000..65cc33f
--- /dev/null
+++ b/tests/Test-N.px
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Content
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.txt' => {
+ content => $dummyfile,
+ timestamp => 1097310600, # "Sat, 09 Oct 2004 08:30:00 GMT"
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-O--no-content-disposition-trivial.px b/tests/Test-O--no-content-disposition-trivial.px
new file mode 100755
index 0000000..cef3caa
--- /dev/null
+++ b/tests/Test-O--no-content-disposition-trivial.px
@@ -0,0 +1,45 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -O out --no-content-disposition http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'out' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-O--no-content-disposition.px b/tests/Test-O--no-content-disposition.px
new file mode 100755
index 0000000..9d2bf41
--- /dev/null
+++ b/tests/Test-O--no-content-disposition.px
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Content-Disposition" => "attachment; filename=\"filename.txt\"",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -O out --no-content-disposition http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'out' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-O-HTTP-Content-Disposition.px b/tests/Test-O-HTTP-Content-Disposition.px
new file mode 100755
index 0000000..d7a7f76
--- /dev/null
+++ b/tests/Test-O-HTTP-Content-Disposition.px
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Content-Disposition" => "attachment; filename=\"filename.txt\"",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -O out http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'out' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-O-nc.px b/tests/Test-O-nc.px
new file mode 100755
index 0000000..171bf16
--- /dev/null
+++ b/tests/Test-O-nc.px
@@ -0,0 +1,45 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -nc -O out http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'out' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-O-nonexisting.px b/tests/Test-O-nonexisting.px
new file mode 100755
index 0000000..d663b65
--- /dev/null
+++ b/tests/Test-O-nonexisting.px
@@ -0,0 +1,45 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --quiet -O out http://localhost:{{port}}/nonexistent";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+ 'out' => {
+ content => "",
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-O.px b/tests/Test-O.px
new file mode 100755
index 0000000..7e4024c
--- /dev/null
+++ b/tests/Test-O.px
@@ -0,0 +1,45 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -O out http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'out' => {
+ content => $dummyfile,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-Restrict-Lowercase.px b/tests/Test-Restrict-Lowercase.px
new file mode 100755
index 0000000..a675989
--- /dev/null
+++ b/tests/Test-Restrict-Lowercase.px
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Some Page Title</title>
+</head>
+<body>
+ <p>
+ Some text...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/SomePage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --restrict-file-names=lowercase http://localhost:{{port}}/SomePage.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'somepage.html' => {
+ content => $mainpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-Restrict-Uppercase.px b/tests/Test-Restrict-Uppercase.px
new file mode 100755
index 0000000..64e8a47
--- /dev/null
+++ b/tests/Test-Restrict-Uppercase.px
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Some Page Title</title>
+</head>
+<body>
+ <p>
+ Some text...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/SomePage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --restrict-file-names=uppercase http://localhost:{{port}}/SomePage.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'SOMEPAGE.HTML' => {
+ content => $mainpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-auth-basic.px b/tests/Test-auth-basic.px
new file mode 100755
index 0000000..ce9100d
--- /dev/null
+++ b/tests/Test-auth-basic.px
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = "You're all authenticated.\n";
+
+# code, msg, headers, content
+my %urls = (
+ '/needs-auth.txt' => {
+ auth_method => 'Basic',
+ user => 'fiddle-dee-dee',
+ passwd => 'Dodgson',
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --user=fiddle-dee-dee --password=Dodgson"
+ . " http://localhost:{{port}}/needs-auth.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'needs-auth.txt' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-auth-no-challenge-url.px b/tests/Test-auth-no-challenge-url.px
new file mode 100755
index 0000000..204e9a0
--- /dev/null
+++ b/tests/Test-auth-no-challenge-url.px
@@ -0,0 +1,48 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = "You're all authenticated.\n";
+
+# code, msg, headers, content
+my %urls = (
+ '/needs-auth.txt' => {
+ auth_no_challenge => 1,
+ auth_method => 'Basic',
+ user => 'fiddle-dee-dee',
+ passwd => 'Dodgson',
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --auth-no-challenge "
+ . "http://fiddle-dee-dee:Dodgson\@localhost:{{port}}/needs-auth.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'needs-auth.txt' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-auth-no-challenge.px b/tests/Test-auth-no-challenge.px
new file mode 100755
index 0000000..0794ece
--- /dev/null
+++ b/tests/Test-auth-no-challenge.px
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = "You're all authenticated.\n";
+
+# code, msg, headers, content
+my %urls = (
+ '/needs-auth.txt' => {
+ auth_no_challenge => 1,
+ auth_method => 'Basic',
+ user => 'fiddle-dee-dee',
+ passwd => 'Dodgson',
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --auth-no-challenge"
+ . " --user=fiddle-dee-dee --password=Dodgson"
+ . " http://localhost:{{port}}/needs-auth.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'needs-auth.txt' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-auth-retcode.px b/tests/Test-auth-retcode.px
new file mode 100755
index 0000000..bc1ea8f
--- /dev/null
+++ b/tests/Test-auth-retcode.px
@@ -0,0 +1,37 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ code => "403",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Last-Modified" => "Sat, 09 Oct 2004 08:30:00 GMT",
+ },
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -N http://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = ();
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-auth-with-content-disposition.px b/tests/Test-auth-with-content-disposition.px
new file mode 100755
index 0000000..7e252a3
--- /dev/null
+++ b/tests/Test-auth-with-content-disposition.px
@@ -0,0 +1,48 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = "You're all authenticated.\n";
+
+# code, msg, headers, content
+my %urls = (
+ '/needs-auth.txt' => {
+ auth_method => 'Basic',
+ user => 'fiddle-dee-dee',
+ passwd => 'Dodgson',
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ "Content-type" => "text/plain",
+ "Content-Disposition" => "attachment; filename=\"Flubber\"",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --user=fiddle-dee-dee --password=Dodgson"
+ . " --content-disposition http://localhost:{{port}}/needs-auth.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'Flubber' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-c-full.px b/tests/Test-c-full.px
new file mode 100755
index 0000000..973f885
--- /dev/null
+++ b/tests/Test-c-full.px
@@ -0,0 +1,56 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -c http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $wholefile,
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-c-partial.px b/tests/Test-c-partial.px
new file mode 100755
index 0000000..2aca247
--- /dev/null
+++ b/tests/Test-c-partial.px
@@ -0,0 +1,66 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $partiallydownloaded = <<EOF;
+11111111111111111111111111111111111111111111111111
+22222222x222222222222222222222222222222222222222222222222222
+EOF
+
+my $rest = <<EOF;
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+my $wholefile = <<EOF . $rest;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+EOF
+
+my $downloadedfile = $partiallydownloaded . $rest;
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -c http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $partiallydownloaded,
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $downloadedfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-c-shorter.px b/tests/Test-c-shorter.px
new file mode 100755
index 0000000..888ead0
--- /dev/null
+++ b/tests/Test-c-shorter.px
@@ -0,0 +1,63 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $partiallydownloaded = <<EOF;
+11111111111111111111111111111111111111111111111111
+22222222x222222222222222222222222222222222222222222222222222
+EOF
+
+my $rest = <<EOF;
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+my $downloadedfile = $partiallydownloaded . $rest;
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ force_code => 1,
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ "Content-Length" => 0,
+ },
+ content => '',
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -c http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+ 'somefile.txt' => {
+ content => $downloadedfile,
+ },
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $downloadedfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-c.px b/tests/Test-c.px
new file mode 100755
index 0000000..48d55ae
--- /dev/null
+++ b/tests/Test-c.px
@@ -0,0 +1,53 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = <<EOF;
+11111111111111111111111111111111111111111111111111
+222222222222222222222222222222222222222222222222222222222222
+3333333333333333333333333333333333333333333333333333333333333333333333
+444444444444444444444444444444444444444444444444444444444444
+55555555555555555555555555555555555555555555555555
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -c http://localhost:{{port}}/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-cookies-401.px b/tests/Test-cookies-401.px
new file mode 100755
index 0000000..7226c2f
--- /dev/null
+++ b/tests/Test-cookies-401.px
@@ -0,0 +1,51 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $content = "You got it.\n";
+
+# code, msg, headers, content
+my %urls = (
+ '/one.txt' => {
+ code => "401",
+ msg => "Forbidden",
+ headers => {
+ "Set-Cookie" => "foo=bar",
+ },
+ },
+ '/two.txt' => {
+ code => "200",
+ msg => "Ok",
+ content => $content,
+ request_headers => {
+ "Cookie" => qr|foo=bar|,
+ },
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " http://localhost:{{port}}/one.txt"
+ . " http://localhost:{{port}}/two.txt";
+
+my $expected_error_code = 6;
+
+my %expected_downloaded_files = (
+ 'two.txt' => {
+ content => $content,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-cookies.px b/tests/Test-cookies.px
new file mode 100755
index 0000000..99fda8f
--- /dev/null
+++ b/tests/Test-cookies.px
@@ -0,0 +1,112 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $page1 = "Hello, world!\n";
+my $page2 = "Goodbye, Sam.\n";
+my $page3 = "Page three.\n";
+my $page4 = "Page four.\n";
+my $page5 = "Page five.\n";
+my $page6 = "Page six.\n";
+
+# code, msg, headers, content
+my %urls = (
+ '/one.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ "Set-Cookie" => "foo=bar",
+ },
+ content => $page1,
+ },
+ '/two.txt' => {
+ code => "200",
+ msg => "Ok",
+ content => $page2,
+ request_headers => {
+ "Cookie" => qr|foo=bar|,
+ },
+ },
+# remove the cookie 'foo'
+ '/three.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ "Set-Cookie" => "foo=; Expires=Sun, 06 Nov 1994 08:49:37 GMT",
+ },
+ content => $page3,
+ },
+ '/four.txt' => {
+ code => "200",
+ msg => "Ok",
+ content => $page4,
+ request_headers => {
+ "!Cookie" => qr|foo=|,
+ },
+ },
+# try to set a cookie 'foo' with mismatching domain
+# see RFC 6265 5.3.6: ignore the cookie if it doesn't domain-match
+ '/five.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ "Set-Cookie" => "foo=bar; domain=.example.com",
+ },
+ content => $page5,
+ },
+ '/six.txt' => {
+ code => "200",
+ msg => "Ok",
+ content => $page6,
+ request_headers => {
+ "!Cookie" => qr|foo=bar|,
+ },
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " http://localhost:{{port}}/one.txt"
+ . " http://localhost:{{port}}/two.txt" . " http://localhost:{{port}}/three.txt"
+ . " http://localhost:{{port}}/four.txt" . " http://localhost:{{port}}/five.txt"
+ . " http://localhost:{{port}}/six.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'one.txt' => {
+ content => $page1,
+ },
+ 'two.txt' => {
+ content => $page2,
+ },
+ 'three.txt' => {
+ content => $page3,
+ },
+ 'four.txt' => {
+ content => $page4,
+ },
+ 'five.txt' => {
+ content => $page5,
+ },
+ 'six.txt' => {
+ content => $page6,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp--start-pos.px b/tests/Test-ftp--start-pos.px
new file mode 100755
index 0000000..00a9a00
--- /dev/null
+++ b/tests/Test-ftp--start-pos.px
@@ -0,0 +1,39 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $dummyfile = "1234";
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.txt' => {
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --start-pos=1 ftp://localhost:{{port}}/dummy.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'dummy.txt' => {
+ content => substr($dummyfile, 1),
+ }
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-bad-list.px b/tests/Test-ftp-bad-list.px
new file mode 100755
index 0000000..78afd77
--- /dev/null
+++ b/tests/Test-ftp-bad-list.px
@@ -0,0 +1,68 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+my $bfile = <<EOF;
+Some more text.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+$bfile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+ '/bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -nH -Nc -r ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+# Don't need to worry about timestamps, the "bad_list" setting will
+# ensure the sizes don't match expectations, and so they'll always be
+# re-downloaded.
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+ 'bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+my %preexisting_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+ 'bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ existing => \%preexisting_files,
+ server_behavior => {bad_list => 1});
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-dir.px b/tests/Test-ftp-dir.px
new file mode 100755
index 0000000..8a3beec
--- /dev/null
+++ b/tests/Test-ftp-dir.px
@@ -0,0 +1,44 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+$afile =~ s/\n/\r\n/;
+
+
+# code, msg, headers, content
+my %urls = (
+ '/dir/afile.txt' => {
+ content => $afile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -S ftp://localhost:{{port}}//dir/afile.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-iri-disabled.px b/tests/Test-ftp-iri-disabled.px
new file mode 100755
index 0000000..4b4772f
--- /dev/null
+++ b/tests/Test-ftp-iri-disabled.px
@@ -0,0 +1,51 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use FTPTest;
+
+
+###############################################################################
+
+my $ccedilla_l1 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+
+my $francais = <<EOF;
+Some text.
+EOF
+
+$francais =~ s/\n/\r\n/;
+
+
+# code, msg, headers, content
+my %urls = (
+ "/fran${ccedilla_u8}ais.txt" => {
+ content => $francais,
+ },
+ "/fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-iri --local-encoding=iso-8859-1 -S ftp://localhost:{{port}}/fran${ccedilla_l1}ais.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-iri-fallback.px b/tests/Test-ftp-iri-fallback.px
new file mode 100755
index 0000000..36c22c7
--- /dev/null
+++ b/tests/Test-ftp-iri-fallback.px
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use FTPTest;
+
+
+###############################################################################
+
+my $ccedilla_l1 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+
+my $francais = <<EOF;
+Some text.
+EOF
+
+$francais =~ s/\n/\r\n/;
+
+# code, msg, headers, content
+my %urls = (
+ "/fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --local-encoding=iso-8859-1 -S ftp://localhost:{{port}}/fran${ccedilla_l1}ais.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-iri-recursive.px b/tests/Test-ftp-iri-recursive.px
new file mode 100755
index 0000000..b487f70
--- /dev/null
+++ b/tests/Test-ftp-iri-recursive.px
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use FTPTest;
+
+
+###############################################################################
+
+my $ccedilla_l1 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+
+my $francais = <<EOF;
+Some text.
+EOF
+
+$francais =~ s/\n/\r\n/;
+
+# code, msg, headers, content
+my %urls = (
+ "/fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --local-encoding=iso-8859-1 -r -nH -S ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-iri.px b/tests/Test-ftp-iri.px
new file mode 100755
index 0000000..42e0eca
--- /dev/null
+++ b/tests/Test-ftp-iri.px
@@ -0,0 +1,48 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use FTPTest;
+
+
+###############################################################################
+
+my $ccedilla_l1 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+
+my $francais = <<EOF;
+Some text.
+EOF
+
+$francais =~ s/\n/\r\n/;
+
+
+# code, msg, headers, content
+my %urls = (
+ "/fran${ccedilla_u8}ais.txt" => {
+ content => $francais,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --local-encoding=iso-8859-1 --remote-encoding=utf-8 -S ftp://localhost:{{port}}/fran${ccedilla_l1}ais.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "fran${ccedilla_l1}ais.txt" => {
+ content => $francais,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-list-Multinet.px b/tests/Test-ftp-list-Multinet.px
new file mode 100755
index 0000000..e21b2a4
--- /dev/null
+++ b/tests/Test-ftp-list-Multinet.px
@@ -0,0 +1,66 @@
+#!/usr/bin/env perl
+
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# In this ftp test:
+# - the response of SYST command is
+# 215 UNIX MultiNet Unix Emulation V5.3(93)
+# - the response of "LIST -a" command is an empty
+# directory.
+# wget should use directly the "LIST" command to get
+# the right content, but it will be ok also "LIST -a"
+# if followed by "LIST" (in the case of future changes).
+
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+my $bfile = <<EOF;
+Some more text.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+$bfile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+ '/bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-directories --recursive --level=1 --accept \"?file.txt\" ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+ 'bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ server_behavior => {list_empty_if_list_a => 1,
+ syst_response => "215 UNIX MultiNet Unix Emulation V5.3(93)"});
+exit $the_test->run();
diff --git a/tests/Test-ftp-list-UNIX-hidden.px b/tests/Test-ftp-list-UNIX-hidden.px
new file mode 100755
index 0000000..d90d9f8
--- /dev/null
+++ b/tests/Test-ftp-list-UNIX-hidden.px
@@ -0,0 +1,64 @@
+#!/usr/bin/env perl
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# In this ftp test:
+# - the response of "LIST -a" command contains
+# all the files
+# - the response of "LIST" command contains
+# the normal files (hidden files are not present)
+# wget should use only "LIST -a" because it recognise
+# the system as "UNIX Type: L8" and so it should see
+# and download the hidden file too.
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $normalfile = <<EOF;
+I'm a normal file
+EOF
+
+my $hiddenfile = <<EOF;
+I'm an hidden file
+EOF
+
+$normalfile =~ s/\n/\r\n/g;
+$hiddenfile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/normalfile.txt' => {
+ content => $normalfile,
+ },
+ '/hiddenfile.txt' => {
+ content => $hiddenfile,
+ attr => "H",
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-directories --recursive --level=1 ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'normalfile.txt' => {
+ content => $normalfile,
+ },
+ 'hiddenfile.txt' => {
+ content => $hiddenfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ server_behavior => {list_no_hidden_if_list => 1});
+exit $the_test->run();
diff --git a/tests/Test-ftp-list-Unknown-a.px b/tests/Test-ftp-list-Unknown-a.px
new file mode 100755
index 0000000..5360122
--- /dev/null
+++ b/tests/Test-ftp-list-Unknown-a.px
@@ -0,0 +1,76 @@
+#!/usr/bin/env perl
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# In this ftp test:
+# - the response of SYST command is
+# 215 Unknown ftp service
+# - the response of "LIST -a" command is a file
+# called "-a".
+# wget should use "LIST -a", but also "LIST".
+# After "LIST", wget will see more data is available.
+# (See also Test-ftp-list-Unknown-b.px)
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+my $bfile = <<EOF;
+Some more text.
+EOF
+
+
+my $minusafile = <<EOF;
+The strange situation.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+$bfile =~ s/\n/\r\n/g;
+$minusafile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+ '/bfile.txt' => {
+ content => $bfile,
+ },
+ '/-a' => {
+ content => $minusafile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-directories --recursive --level=1 ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+ 'bfile.txt' => {
+ content => $bfile,
+ },
+ '-a' => {
+ content => $minusafile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ server_behavior => {list_dont_clean_path => 1,
+ syst_response => "215 Unknown ftp service"});
+exit $the_test->run();
diff --git a/tests/Test-ftp-list-Unknown-hidden.px b/tests/Test-ftp-list-Unknown-hidden.px
new file mode 100755
index 0000000..c300761
--- /dev/null
+++ b/tests/Test-ftp-list-Unknown-hidden.px
@@ -0,0 +1,68 @@
+#!/usr/bin/env perl
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# In this ftp test:
+# - the response of SYST command is
+# 215 Unknown ftp service
+# - the response of "LIST -a" command contains
+# all the files
+# - the response of "LIST" command contains
+# the normal files (hidden files are not present)
+# wget should use "LIST -a", but also "LIST".
+# After "LIST", wget will see more data is available
+# on "LIST -a", so it should go back to "LIST -a".
+# (See also Test-ftp-list-Unknown-a.px)
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $normalfile = <<EOF;
+I'm a normal file
+EOF
+
+my $hiddenfile = <<EOF;
+I'm an hidden file
+EOF
+
+$normalfile =~ s/\n/\r\n/g;
+$hiddenfile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/normalfile.txt' => {
+ content => $normalfile,
+ },
+ '/hiddenfile.txt' => {
+ content => $hiddenfile,
+ attr => "H",
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-directories --recursive --level=1 ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'normalfile.txt' => {
+ content => $normalfile,
+ },
+ 'hiddenfile.txt' => {
+ content => $hiddenfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ server_behavior => {list_no_hidden_if_list => 1,
+ syst_response => "215 Unknown ftp service"});
+exit $the_test->run();
diff --git a/tests/Test-ftp-list-Unknown-list-a-fails.px b/tests/Test-ftp-list-Unknown-list-a-fails.px
new file mode 100755
index 0000000..e52b36a
--- /dev/null
+++ b/tests/Test-ftp-list-Unknown-list-a-fails.px
@@ -0,0 +1,61 @@
+#!/usr/bin/env perl
+
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# In this ftp test:
+# - the response of "LIST -a" command is a failure
+# wget should use "LIST -a" then "LIST" to get the right
+# content.
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+my $bfile = <<EOF;
+Some more text.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+$bfile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+ '/bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-directories --recursive --level=1 --accept \"?file.txt\" ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+ 'bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ server_behavior => {list_fails_if_list_a => 1,
+ syst_response => "215 Unknown ftp service"});
+exit $the_test->run();
diff --git a/tests/Test-ftp-list-Unknown.px b/tests/Test-ftp-list-Unknown.px
new file mode 100755
index 0000000..71e4362
--- /dev/null
+++ b/tests/Test-ftp-list-Unknown.px
@@ -0,0 +1,64 @@
+#!/usr/bin/env perl
+
+
+# 2013-10-17 Andrea Urbani (matfanjol)
+# In this ftp test:
+# - the response of SYST command is
+# 215 Unknown ftp service
+# - the response of "LIST -a" command is an empty
+# directory.
+# wget should use "LIST -a" then "LIST" to get the right
+# content.
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+my $bfile = <<EOF;
+Some more text.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+$bfile =~ s/\n/\r\n/g;
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+ '/bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-directories --recursive --level=1 --accept \"?file.txt\" ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+ 'bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files,
+ server_behavior => {list_empty_if_list_a => 1,
+ syst_response => "215 Unknown ftp service"});
+exit $the_test->run();
diff --git a/tests/Test-ftp-pasv-fail.px b/tests/Test-ftp-pasv-fail.px
new file mode 100755
index 0000000..f050fdd
--- /dev/null
+++ b/tests/Test-ftp-pasv-fail.px
@@ -0,0 +1,57 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+# This file exercises a problem in Wget, where if an error was
+# encountered in ftp.c:getftp before the actual file download
+# had started, Wget would believe that it had already downloaded the
+# full contents of the file, and would send a corresponding (erroneous)
+# REST value.
+
+###############################################################################
+
+# From bug report. :)
+my $afile = <<EOF;
+I've included log output (using the -d switch) from when this happens
+below. You'll see that for the retry wget sends a REST command to
+reset the start position before starting the RETR command. I'm
+confused about the argument to REST: 51132. It's the full length in
+bytes of the file to be retrieved. The RETR then shows the entire
+contents of the file being skipped, and wget announces that it
+successfully retrieved and saved 0 bytes.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -S ftp://localhost:{{port}}/afile.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ server_behavior => {fail_on_pasv => 1},
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-pasv-not-supported.px b/tests/Test-ftp-pasv-not-supported.px
new file mode 100755
index 0000000..1a473ad
--- /dev/null
+++ b/tests/Test-ftp-pasv-not-supported.px
@@ -0,0 +1,56 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+# This test checks whether Wget *does not* fall back from passive mode to
+# active mode using a PORT command. Wget <= 1.16.3 made a fallback exposing
+# the client's real IP address to the remote FTP server.
+#
+# This behavior circumvents expected privacy when using a proxy / proxy network (e.g. Tor).
+#
+# Wget >= 1.16.4 does it right. This test checks it.
+
+###############################################################################
+
+# From bug report 10.08.2015 from tomtidaly@sigaint.org
+my $afile = <<EOF;
+FTP PORT command code in v1.16.3?
+
+In the past it could be possible for a site over http connection to
+redirect wget to FPT using FTP PORT command so the site gets the real IP
+of the computer even when wget proxy command is in use I believe:
+https://lists.torproject.org/pipermail/tor-talk/2012-April/024040.html
+
+Is that code still present in wget v1.16.3? It was present in v1.13.4.
+EOF
+
+$afile =~ s/\n/\r\n/g;
+
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -S ftp://localhost:{{port}}/afile.txt";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = ();
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ server_behavior => {pasv_not_supported => 1},
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp-recursive.px b/tests/Test-ftp-recursive.px
new file mode 100755
index 0000000..88fb85e
--- /dev/null
+++ b/tests/Test-ftp-recursive.px
@@ -0,0 +1,54 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+my $bfile = <<EOF;
+Some more text.
+EOF
+
+$afile =~ s/\n/\r\n/;
+$bfile =~ s/\n/\r\n/;
+
+# code, msg, headers, content
+my %urls = (
+ '/foo/afile.txt' => {
+ content => $afile,
+ },
+ '/bar/baz/bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -S -nH -r ftp://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'foo/afile.txt' => {
+ content => $afile,
+ },
+ 'bar/baz/bfile.txt' => {
+ content => $bfile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-ftp.px b/tests/Test-ftp.px
new file mode 100755
index 0000000..fdedfbc
--- /dev/null
+++ b/tests/Test-ftp.px
@@ -0,0 +1,44 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $afile = <<EOF;
+Some text.
+EOF
+
+$afile =~ s/\n/\r\n/;
+
+
+# code, msg, headers, content
+my %urls = (
+ '/afile.txt' => {
+ content => $afile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -S ftp://localhost:{{port}}/afile.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'afile.txt' => {
+ content => $afile,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-badcerts.px b/tests/Test-https-badcerts.px
new file mode 100644
index 0000000..4ea91d7
--- /dev/null
+++ b/tests/Test-https-badcerts.px
@@ -0,0 +1,103 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use POSIX;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+my $cacrt = "$srcdir/certs/test-ca-cert.pem";
+
+# Use expired server certificate
+my $servercrt = "$srcdir/certs/expired.pem";
+my $serverkey = "$srcdir/certs/server-key.pem";
+
+# Try Wget using SSL with expired cert. Expect Failure.
+my $port = 30443;
+my $cmdline = $WgetTest::WGETPATH . " --ca-certificate=$cacrt".
+ " https://$testhostname:$port/somefile.txt";
+my $expected_error_code = 5;
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $servercrt,
+ keyfile => $serverkey,
+ lhostname => $testhostname,
+ sslport => $port);
+if ($sslsock->run() == 0)
+{
+ exit -1;
+}
+print "Test successful.\n";
+
+# Use certificate that is not yet valid
+$servercrt = "$srcdir/certs/invalid.pem";
+$serverkey = "$srcdir/certs/server-key.pem";
+
+# Retry the test with --no-check-certificate. expect success
+$port = 20443;
+$cmdline = $WgetTest::WGETPATH . " --ca-certificate=$cacrt".
+ " https://$testhostname:$port/somefile.txt";
+
+$expected_error_code = 5;
+
+my $retryssl = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ certfile => $servercrt,
+ keyfile => $serverkey,
+ lhostname => $testhostname,
+ sslport => $port);
+exit $retryssl->run();
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-clientcert.px b/tests/Test-https-clientcert.px
new file mode 100755
index 0000000..77dd3e9
--- /dev/null
+++ b/tests/Test-https-clientcert.px
@@ -0,0 +1,107 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+my $cacrt = "$srcdir/certs/test-ca-cert.pem";
+#my $cakey = "$srcdir/certs/test-ca-key.pem";
+
+# Prepare server certificate
+my $servercrt = "$srcdir/certs/server-cert.pem";
+my $serverkey = "$srcdir/certs/server-key.pem";
+
+# Use client certificate
+my $clientcert = "$srcdir/certs/client-cert.pem";
+my $clientkey = "$srcdir/certs/client-key.pem";
+
+# Try Wget using SSL with mismatched client cert & key . Expect error
+my $port = 21443;
+my $cmdline = $WgetTest::WGETPATH . " --certificate=$clientcert ".
+ " --private-key=$serverkey ".
+ " --ca-certificate=$cacrt".
+ " https://$testhostname:$port/somefile.txt";
+my $expected_error_code = 5;
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $servercrt,
+ keyfile => $serverkey,
+ lhostname => $testhostname,
+ sslport => $port);
+if ($sslsock->run() == 0)
+{
+ exit 0;
+}
+
+# Retry wget using SSL with client certificate. Expect success
+$port = 22443;
+$cmdline = $WgetTest::WGETPATH . " --certificate=$clientcert".
+ " --private-key=$clientkey ".
+ " --ca-certificate=$cacrt".
+ " https://$testhostname:$port/somefile.txt";
+
+$expected_error_code = 0;
+
+my $retryssl = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $servercrt,
+ keyfile => $serverkey,
+ lhostname => $testhostname,
+ sslport => $port);
+exit $retryssl->run();
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-crl.px b/tests/Test-https-crl.px
new file mode 100755
index 0000000..655b3a8
--- /dev/null
+++ b/tests/Test-https-crl.px
@@ -0,0 +1,101 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+my $cacrt = "$srcdir/certs/test-ca-cert.pem";
+
+# Use a revoked certificate
+my $servercrt = "$srcdir/certs/server-cert.pem";
+my $serverkey = "$srcdir/certs/server-key.pem";
+
+# Try Wget using SSL first without --no-check-certificate. Expect Success.
+my $port = 32443;
+my $cmdline = $WgetTest::WGETPATH . " --ca-certificate=$cacrt".
+ " https://$testhostname:$port/somefile.txt";
+my $expected_error_code = 0;
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $servercrt,
+ keyfile => $serverkey,
+ lhostname => $testhostname,
+ sslport => $port);
+if ($sslsock->run() != 0)
+{
+ exit -1;
+}
+
+# Revoke the certificate
+my $crlfile = "$srcdir/certs/revoked-crl.pem";
+
+# Retry the test with CRL. Expect Failure.
+$port = 23443;
+$cmdline = $WgetTest::WGETPATH . " --crl-file=$crlfile ".
+ " --ca-certificate=$cacrt".
+ " https://$testhostname:$port/somefile.txt";
+
+$expected_error_code = 5;
+
+my $retryssl = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ certfile => $servercrt,
+ keyfile => $serverkey,
+ lhostname => $testhostname,
+ sslport => $port);
+exit $retryssl->run();
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-pfs.px b/tests/Test-https-pfs.px
new file mode 100755
index 0000000..0a3bb96
--- /dev/null
+++ b/tests/Test-https-pfs.px
@@ -0,0 +1,71 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+my $port = 24443;
+my $cmdline = $WgetTest::WGETPATH . " --secure-protocol=PFS".
+ " --ca-certificate=$srcdir/certs/test-ca-cert.pem".
+ " https://$testhostname:$port/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ sslport => $port);
+exit $sslsock->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-selfsigned.px b/tests/Test-https-selfsigned.px
new file mode 100755
index 0000000..0586c63
--- /dev/null
+++ b/tests/Test-https-selfsigned.px
@@ -0,0 +1,97 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+# Prepare self-signed certificates
+my $certfile="$srcdir/certs/selfsigned.crt";
+my $keyfile="$srcdir/certs/selfsigned.key";
+
+# Try Wget using SSL first without --no-check-certificate. expect error
+my $port = 26443;
+my $cmdline = $WgetTest::WGETPATH . " --ca-certificate=$srcdir/certs/test-ca-cert.pem".
+ " https://$testhostname:$port/somefile.txt";
+my $expected_error_code = 5;
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $certfile,
+ keyfile => $keyfile,
+ lhostname => $testhostname,
+ sslport => $port);
+if ($sslsock->run() == 0)
+{
+ exit 0;
+}
+
+# Retry the test with --no-check-certificate. expect success
+$port = 27443;
+$cmdline = $WgetTest::WGETPATH . " --no-check-certificate ".
+ " --ca-certificate=$srcdir/certs/test-ca-cert.pem".
+ " https://$testhostname:$port/somefile.txt";
+
+$expected_error_code = 0;
+
+my $retryssl = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $certfile,
+ keyfile => $keyfile,
+ lhostname => $testhostname,
+ sslport => $port);
+exit $retryssl->run();
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-tlsv1.px b/tests/Test-https-tlsv1.px
new file mode 100755
index 0000000..e19b135
--- /dev/null
+++ b/tests/Test-https-tlsv1.px
@@ -0,0 +1,71 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+my $port = 28443;
+my $cmdline = $WgetTest::WGETPATH . " --secure-protocol=TLSv1".
+ " --ca-certificate=$srcdir/certs/test-ca-cert.pem".
+ " https://$testhostname:$port/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ sslport => $port);
+exit $sslsock->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-tlsv1x.px b/tests/Test-https-tlsv1x.px
new file mode 100755
index 0000000..2a24c44
--- /dev/null
+++ b/tests/Test-https-tlsv1x.px
@@ -0,0 +1,72 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use Cwd;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+my $port = 29443;
+my $cmdline = $WgetTest::WGETPATH . " --secure-protocol=TLSv1_1".
+ " --ca-certificate=$srcdir/certs/test-ca-cert.pem".
+ " https://$testhostname:$port/somefile.txt";
+
+my $expected_error_code = 0;
+
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ sslport => $port);
+exit $sslsock->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-https-weboftrust.px b/tests/Test-https-weboftrust.px
new file mode 100755
index 0000000..d792ca2
--- /dev/null
+++ b/tests/Test-https-weboftrust.px
@@ -0,0 +1,128 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use Socket;
+use WgetFeature qw(https);
+use SSLTest;
+
+###############################################################################
+
+# TODO: regenerate the certs with endless lifetime
+exit 77;
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+# Skip the test if openssl is not available
+my $ossl = `openssl version`;
+unless ($ossl =~ m/OpenSSL 1/)
+{
+ exit 77;
+}
+
+my $srcdir;
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+$srcdir = Cwd::abs_path("$srcdir");
+
+# HOSTALIASES env variable allows us to create hosts file alias.
+my $testhostname = "WgetTestingServer";
+$ENV{'HOSTALIASES'} = "$srcdir/certs/wgethosts";
+
+my $addr = gethostbyname($testhostname);
+unless ($addr)
+{
+ warn "Failed to resolve $testhostname, using $srcdir/certs/wgethosts\n";
+ exit 77;
+}
+unless (inet_ntoa($addr) =~ "127.0.0.1")
+{
+ warn "Unexpected IP for localhost: ".inet_ntoa($addr)."\n";
+ exit 77;
+}
+
+# Use Intermediate CA
+my $caconf = "$srcdir/certs/rootca.conf";
+my $icrtfile = "$srcdir/certs/interca.crt";
+my $ikeyfile = "$srcdir/certs/interca.key";
+
+my $icacheck=`(openssl x509 -noout -modulus -in $icrtfile | openssl md5 ;
+ openssl rsa -noout -modulus -in $ikeyfile | openssl md5) |
+ uniq | wc -l`;
+# Check if certificate and key are correct.
+unless(-e $icrtfile && -e $ikeyfile && $icacheck == 1)
+{
+ exit 77; # skip
+}
+
+# User certificate using intermediate CA
+my $usrcrt = "$srcdir/certs/user.crt";
+my $usrkey = "$srcdir/certs/user.key";
+
+my $usrcheck=`(openssl x509 -noout -modulus -in $usrcrt | openssl md5 ;
+ openssl rsa -noout -modulus -in $usrkey | openssl md5) |
+ uniq | wc -l`;
+# Check if certificate and key are made correctly.
+unless(-e $usrcrt && -e $ikeyfile && $usrcheck == 1)
+{
+ exit 77; # skip
+}
+
+# Try Wget using SSL using certificate signed by intermediate CA. Expect error.
+my $port = 30443;
+my $cmdline = $WgetTest::WGETPATH . " --ca-certificate=$srcdir/certs/".
+ "test-ca-cert.pem https://$testhostname:$port/somefile.txt";
+my $expected_error_code = 5;
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+ 'somefile.txt' => {
+ content => "blabla",
+ },
+);
+
+my $sslsock = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ certfile => $usrcrt,
+ keyfile => $usrkey,
+ lhostname => $testhostname,
+ sslport => $port);
+if ($sslsock->run() == 0)
+{
+ exit 0;
+}
+
+# Retry the test with --no-check-certificate. expect success
+$port = 31443;
+$cmdline = $WgetTest::WGETPATH . " --ca-certificate=$srcdir/certs/wotca.pem".
+ " https://$testhostname:$port/somefile.txt";
+
+$expected_error_code = 0;
+
+my $retryssl = SSLTest->new(cmdline => $cmdline,
+ input => \%urls,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files,
+ certfile => $usrcrt,
+ keyfile => $usrkey,
+ lhostname => $testhostname,
+ sslport => $port);
+exit $retryssl->run();
+# vim: et ts=4 sw=4
diff --git a/tests/Test-i-ftp.px b/tests/Test-i-ftp.px
new file mode 100755
index 0000000..6fd2c05
--- /dev/null
+++ b/tests/Test-i-ftp.px
@@ -0,0 +1,79 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use FTPTest;
+
+
+###############################################################################
+
+my $urls = <<EOF;
+ftp://localhost:{{port}}/site1.html
+ftp://localhost:{{port}}/site2.html
+EOF
+
+my $site1 = <<EOF;
+<html>
+ <head>
+ <title>Site 1</title>
+ </head>
+ <body>
+ <p>Nunc eu ligula sed mauris sollicitudin scelerisque. Suspendisse viverra, dolor.</p>
+ </body>
+</html>
+EOF
+
+my $site2 = <<EOF;
+<html>
+ <head>
+ <title>Site 2</title>
+ </head>
+ <body>
+ <p>Suspendisse potenti. Phasellus et magna est, quis consectetur ligula. Integer.</p>
+ </body>
+</html>
+EOF
+
+foreach ($urls, $site1, $site2) {
+ s/\n/\r\n/g;
+}
+
+my %urls = (
+ '/urls.txt' => {
+ content => $urls,
+ },
+ '/site1.html' => {
+ content => $site1,
+ },
+ '/site2.html' => {
+ content => $site2,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -i ftp://localhost:{{port}}/urls.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'urls.txt' => {
+ content => $urls,
+ },
+ 'site1.html' => {
+ content => $site1,
+ },
+ 'site2.html' => {
+ content => $site2,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (
+ input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-i-http.px b/tests/Test-i-http.px
new file mode 100755
index 0000000..a076973
--- /dev/null
+++ b/tests/Test-i-http.px
@@ -0,0 +1,90 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $urls = <<EOF;
+http://localhost:{{port}}/site1.html
+http://localhost:{{port}}/site2.html
+EOF
+
+my $site1 = <<EOF;
+<html>
+ <head>
+ <title>Site 1</title>
+ </head>
+ <body>
+ <p>In orci diam, iaculis a hendrerit accumsan, mollis a nibh.</p>
+ </body>
+</html>
+EOF
+
+my $site2 = <<EOF;
+<html>
+ <head>
+ <title>Site 2</title>
+ </head>
+ <body>
+ <p>Sed vehicula ultrices orci a congue. Sed convallis semper urna.</p>
+ </body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/urls.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $urls,
+ },
+ '/site1.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $site1,
+ },
+ '/site2.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $site2,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -i http://localhost:{{port}}/urls.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'urls.txt' => {
+ content => $urls,
+ },
+ 'site1.html' => {
+ content => $site1,
+ },
+ 'site2.html' => {
+ content => $site2,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-idn-cmd-utf8.px b/tests/Test-idn-cmd-utf8.px
new file mode 100755
index 0000000..42e4318
--- /dev/null
+++ b/tests/Test-idn-cmd-utf8.px
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# " Kon'nichiwa <dot> Japan
+my $utf8_hostname = "\344\273\212\346\227\245\343\201\257.\346\227\245\346\234\254";
+my $punycoded_hostname = 'xn--v9ju72g90p.xn--wgv71a';
+
+###############################################################################
+
+my $result_file = <<EOF;
+Found me!
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ "http://$punycoded_hostname/index.html" => {
+ code => "200",
+ msg => "Yes, please",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -r"
+ . " -e http_proxy=localhost:{{port}} --local-encoding=UTF-8 $utf8_hostname";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "$punycoded_hostname/index.html" => {
+ content => $result_file,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-idn-cmd.px b/tests/Test-idn-cmd.px
new file mode 100755
index 0000000..3098419
--- /dev/null
+++ b/tests/Test-idn-cmd.px
@@ -0,0 +1,50 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# " Kon'nichiwa <dot> Japan
+my $euc_jp_hostname = "\272\243\306\374\244\317.\306\374\313\334";
+my $punycoded_hostname = 'xn--v9ju72g90p.xn--wgv71a';
+
+###############################################################################
+
+my $result_file = <<EOF;
+Found me!
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ "http://$punycoded_hostname/index.html" => {
+ code => "200",
+ msg => "Yes, please",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -r"
+ . " -e http_proxy=localhost:{{port}} --local-encoding=EUC-JP $euc_jp_hostname";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "$punycoded_hostname/index.html" => {
+ content => $result_file,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-idn-headers.px b/tests/Test-idn-headers.px
new file mode 100755
index 0000000..6b0c614
--- /dev/null
+++ b/tests/Test-idn-headers.px
@@ -0,0 +1,65 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# " Kon'nichiwa <dot> Japan
+my $euc_jp_hostname = "\272\243\306\374\244\317.\306\374\313\334";
+my $punycoded_hostname = 'xn--v9ju72g90p.xn--wgv71a';
+
+###############################################################################
+
+my $starter_file = <<EOF;
+<a href="http://$euc_jp_hostname/">The link</a>
+EOF
+
+my $result_file = <<EOF;
+Found me!
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ 'http://start-here.com/start.html' => {
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ 'Content-Type' => 'text/html; charset=EUC-JP',
+ },
+ content => $starter_file,
+ },
+ "http://$punycoded_hostname/index.html" => {
+ code => "200",
+ msg => "Yes, please",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -rH"
+ . " -e http_proxy=localhost:{{port}} http://start-here.com/start.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'start-here.com/start.html' => {
+ content => $starter_file,
+ },
+ "$punycoded_hostname/index.html" => {
+ content => $result_file,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-idn-meta.px b/tests/Test-idn-meta.px
new file mode 100755
index 0000000..db5c016
--- /dev/null
+++ b/tests/Test-idn-meta.px
@@ -0,0 +1,67 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# " Kon'nichiwa <dot> Japan
+my $euc_jp_hostname = "\272\243\306\374\244\317.\306\374\313\334";
+my $punycoded_hostname = 'xn--v9ju72g90p.xn--wgv71a';
+
+###############################################################################
+
+my $starter_file = <<EOF;
+<meta http-equiv="Content-Type" content="text/html; charset=EUC-JP" />
+<a href="http://$euc_jp_hostname/">The link</a>
+EOF
+
+my $result_file = <<EOF;
+Found me!
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ 'http://start-here.com/start.html' => {
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ # HTTP header precedes http-equiv, simply just omit it here
+ #'Content-Type' => 'text/html; charset=UTF-8',
+ },
+ content => $starter_file,
+ },
+ "http://$punycoded_hostname/index.html" => {
+ code => "200",
+ msg => "Yes, please",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -rH"
+ . " -e http_proxy=localhost:{{port}} http://start-here.com/start.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'start-here.com/start.html' => {
+ content => $starter_file,
+ },
+ "$punycoded_hostname/index.html" => {
+ content => $result_file,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-idn-robots-utf8.px b/tests/Test-idn-robots-utf8.px
new file mode 100755
index 0000000..1d1bfac
--- /dev/null
+++ b/tests/Test-idn-robots-utf8.px
@@ -0,0 +1,77 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# " Kon'nichiwa <dot> Japan
+my $utf8_hostname = "\344\273\212\346\227\245\343\201\257.\346\227\245\346\234\254";
+my $punycoded_hostname = 'xn--v9ju72g90p.xn--wgv71a';
+
+###############################################################################
+
+my $starter_file = <<EOF;
+<a href="http://$utf8_hostname/foo.txt">The link</a>
+EOF
+
+my $result_file = <<EOF;
+Found me!
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ "http://$punycoded_hostname/index.html" => {
+ code => "200",
+ msg => "Yes, please",
+ headers => {
+ 'Content-Type' => 'text/html; charset=UTF-8',
+ },
+ content => $starter_file,
+ },
+ "http://$punycoded_hostname/foo.txt" => {
+ code => "200",
+ msg => "Uh-huh",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+ "http://$punycoded_hostname/robots.txt" => {
+ code => "200",
+ msg => "Uh-huh",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => '',
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -r"
+ . " -e http_proxy=localhost:{{port}} --local-encoding=UTF-8"
+ . " http://$utf8_hostname/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "$punycoded_hostname/index.html" => {
+ content => $starter_file,
+ },
+ "$punycoded_hostname/foo.txt" => {
+ content => $result_file,
+ },
+ "$punycoded_hostname/robots.txt" => {
+ content => '',
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-idn-robots.px b/tests/Test-idn-robots.px
new file mode 100755
index 0000000..888fcdf
--- /dev/null
+++ b/tests/Test-idn-robots.px
@@ -0,0 +1,102 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# " Kon'nichiwa <dot> Japan
+my $euc_jp_hostname = "\272\243\306\374\244\317.\306\374\313\334";
+my $punycoded_hostname = 'xn--v9ju72g90p.xn--wgv71a';
+my $escaped_hostname = "%ba%a3%c6%fc%a4%cf.%c6%fc%cb%dc";
+
+###############################################################################
+
+my $starter_file = <<EOF;
+<a href="http://$euc_jp_hostname/foo.txt">The link</a>
+<a href="http://$punycoded_hostname/foo2.txt">The second link</a>
+<a href="http://$escaped_hostname/foo3.txt">The third link</a>
+EOF
+
+my $result_file = <<EOF;
+Found me!
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ "http://$punycoded_hostname/index.html" => {
+ code => "200",
+ msg => "Yes, please",
+ headers => {
+ 'Content-Type' => 'text/html; charset=EUC-JP',
+ },
+ content => $starter_file,
+ },
+ "http://$punycoded_hostname/foo.txt" => {
+ code => "200",
+ msg => "Uh-huh",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+ "http://$punycoded_hostname/foo2.txt" => {
+ code => "200",
+ msg => "Uh-huh2",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+ "http://$punycoded_hostname/foo3.txt" => {
+ code => "200",
+ msg => "Uh-huh3",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => $result_file,
+ },
+ "http://$punycoded_hostname/robots.txt" => {
+ code => "200",
+ msg => "Uh-huh",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => '',
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -r"
+ . " -e http_proxy=localhost:{{port}} --local-encoding=EUC-JP"
+ . " http://$euc_jp_hostname/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "$punycoded_hostname/index.html" => {
+ content => $starter_file,
+ },
+ "$punycoded_hostname/foo.txt" => {
+ content => $result_file,
+ },
+ "$punycoded_hostname/foo2.txt" => {
+ content => $result_file,
+ },
+ "$punycoded_hostname/foo3.txt" => {
+ content => $result_file,
+ },
+ "$punycoded_hostname/robots.txt" => {
+ content => '',
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-iri-disabled.px b/tests/Test-iri-disabled.px
new file mode 100755
index 0000000..e019d4f
--- /dev/null
+++ b/tests/Test-iri-disabled.px
@@ -0,0 +1,195 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+# cf. http://en.wikipedia.org/wiki/Latin1
+# http://en.wikipedia.org/wiki/ISO-8859-15
+
+###############################################################################
+#
+# mime : charset found in Content-Type HTTP MIME header
+# meta : charset found in Content-Type meta tag
+#
+# index.html mime + file = iso-8859-15
+# p1_français.html meta + file = iso-8859-1, mime = utf-8
+# p2_één.html mime + file = iso-8859-1
+# p3_€€€.html meta + file = utf-8, mime = iso-8859-1
+#
+
+my $ccedilla_l15 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+my $eacute_l1 = "\xE9";
+my $eacute_u8 = "\xC3\xA9";
+my $eurosign_l15 = "\xA4";
+my $eurosign_u8 = "\xE2\x82\xAC";
+
+my $pageindex = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Link to page 1 <a href="http://localhost:{{port}}/p1_fran${ccedilla_l15}ais.html">La seule page en fran&ccedil;ais</a>.
+ Link to page 3 <a href="http://localhost:{{port}}/p3_${eurosign_l15}${eurosign_l15}${eurosign_l15}.html">My tailor is rich</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $pagefrancais = <<EOF;
+<html>
+<head>
+ <title>La seule page en français</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+</head>
+<body>
+ <p>
+ Link to page 2 <a href="http://localhost:{{port}}/p2_${eacute_l1}${eacute_l1}n.html">Die enkele nerderlangstalige pagina</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeen = <<EOF;
+<html>
+<head>
+ <title>Die enkele nederlandstalige pagina</title>
+</head>
+<body>
+ <p>
+ &Eacute;&eacute;n is niet veel maar toch meer dan nul.<br/>
+ Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeuro = <<EOF;
+<html>
+<head>
+ <title>Euro page</title>
+</head>
+<body>
+ <p>
+ My tailor isn't rich anymore.
+ </p>
+</body>
+</html>
+EOF
+
+my $page404 = <<EOF;
+<html>
+<head>
+ <title>404</title>
+</head>
+<body>
+ <p>
+ Nop nop nop...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-15",
+ },
+ content => $pageindex,
+ },
+ '/robots.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "",
+ },
+ '/p1_fran%C3%A7ais.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "File not found",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pagefrancais,
+ },
+ '/p1_fran%E7ais.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pagefrancais,
+ },
+ '/p2_%C3%A9%C3%A9n.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pageeen,
+ },
+ '/p2_%E9%E9n.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-1",
+ },
+ content => $pageeen,
+ },
+ '/p3_%E2%82%AC%E2%82%AC%E2%82%AC.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $pageeuro,
+ },
+ '/p3_%A4%A4%A4.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $pageeuro,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --no-iri -nH -r http://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $pageindex,
+ },
+ 'robots.txt' => {
+ content => "",
+ },
+ "p1_fran${ccedilla_l15}ais.html" => {
+ content => $pagefrancais,
+ },
+ "p2_${eacute_l1}${eacute_l1}n.html" => {
+ content => $pageeen,
+ },
+ "p3_${eurosign_l15}${eurosign_l15}${eurosign_l15}.html" => {
+ content => $pageeuro,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-iri-forced-remote.px b/tests/Test-iri-forced-remote.px
new file mode 100755
index 0000000..7908de8
--- /dev/null
+++ b/tests/Test-iri-forced-remote.px
@@ -0,0 +1,182 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# cf. http://en.wikipedia.org/wiki/Latin1
+# http://en.wikipedia.org/wiki/ISO-8859-15
+
+###############################################################################
+# Force remote encoding to ISO-8859-1
+#
+# mime : charset found in Content-Type HTTP MIME header
+# meta : charset found in Content-Type meta tag
+#
+# index.html mime + file = iso-8859-15
+# p1_français.html meta + file = iso-8859-1, mime = utf-8
+# p2_één.html mime + file = iso-8859-1
+# p3_€€€.html meta + file = utf-8, mime = iso-8859-1
+#
+
+my $ccedilla_l15 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+my $eacute_l1 = "\xE9";
+my $eacute_u8 = "\xC3\xA9";
+my $eurosign_l15 = "\xA4";
+my $eurosign_u8 = "\xE2\x82\xAC";
+
+my $pageindex = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Link to page 1 <a href="http://localhost:{{port}}/p1_fran${ccedilla_l15}ais.html">La seule page en fran&ccedil;ais</a>.
+ Link to page 3 <a href="http://localhost:{{port}}/p3_${eurosign_l15}${eurosign_l15}${eurosign_l15}.html">My tailor is rich</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $pagefrancais = <<EOF;
+<html>
+<head>
+ <title>La seule page en français</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <p>
+ Link to page 2 <a href="http://localhost:{{port}}/p2_${eacute_l1}${eacute_l1}n.html">Die enkele nerderlangstalige pagina</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeen = <<EOF;
+<html>
+<head>
+ <title>Die enkele nederlandstalige pagina</title>
+</head>
+<body>
+ <p>
+ &Eacute;&eacute;n is niet veel maar toch meer dan nul.<br/>
+ Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeuro = <<EOF;
+<html>
+<head>
+ <title>Euro page</title>
+</head>
+<body>
+ <p>
+ My tailor isn't rich anymore.
+ </p>
+</body>
+</html>
+EOF
+
+my $page404 = <<EOF;
+<html>
+<head>
+ <title>404</title>
+</head>
+<body>
+ <p>
+ Nop nop nop...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-15",
+ },
+ content => $pageindex,
+ },
+ '/robots.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "",
+ },
+ '/p1_fran%C3%A7ais.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ # wrong charset specified by meta tag in $pagefrancais, overridden by HTTP Content-Type
+ "Content-type" => "text/html; charset=iso-8859-1",
+ },
+ content => $pagefrancais,
+ },
+ '/p2_%C3%A9%C3%A9n.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pageeen,
+ },
+ '/p3_%E2%82%AC%E2%82%AC%E2%82%AC.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $pageeuro,
+ },
+ '/p3_%C2%A4%C2%A4%C2%A4.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $pageeuro,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -e robots=on --trust-server-names --local-encoding=utf-8 -nH -r http://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $pageindex,
+ },
+ 'robots.txt' => {
+ content => "",
+ },
+ "p1_fran${ccedilla_u8}ais.html" => {
+ content => $pagefrancais,
+ },
+ "p2_${eacute_u8}${eacute_u8}n.html" => {
+ content => $pageeen,
+ },
+ "p3_${eurosign_u8}${eurosign_u8}${eurosign_u8}.html" => {
+ content => $pageeuro,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-iri-list.px b/tests/Test-iri-list.px
new file mode 100755
index 0000000..5e56072
--- /dev/null
+++ b/tests/Test-iri-list.px
@@ -0,0 +1,173 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# cf. http://en.wikipedia.org/wiki/Latin1
+# http://en.wikipedia.org/wiki/ISO-8859-15
+###############################################################################
+#
+# mime : charset found in Content-Type HTTP MIME header
+# meta : charset found in Content-Type meta tag
+#
+# index.html mime + file = iso-8859-15
+# p1_français.html meta + file = iso-8859-1, mime = utf-8
+# p2_één.html meta + file = utf-8, mime =iso-8859-1
+#
+
+my $ccedilla_l1 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+my $eacute_l1 = "\xE9";
+my $eacute_u8 = "\xC3\xA9";
+
+my $urllist = <<EOF;
+http://localhost:{{port}}/
+http://localhost:{{port}}/p1_fran${ccedilla_l1}ais.html
+http://localhost:{{port}}/p2_${eacute_l1}${eacute_l1}n.html
+EOF
+
+my $pageindex = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Main page.
+ </p>
+</body>
+</html>
+EOF
+
+my $pagefrancais = <<EOF;
+<html>
+<head>
+ <title>La seule page en français</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+</head>
+<body>
+ <p>
+ French page.
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeen = <<EOF;
+<html>
+<head>
+ <title>Die enkele nederlandstalige pagina</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <p>
+ Dutch page.
+ </p>
+</body>
+</html>
+EOF
+
+my $page404 = <<EOF;
+<html>
+<head>
+ <title>404</title>
+</head>
+<body>
+ <p>
+ Nop nop nop...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-15",
+ },
+ content => $pageindex,
+ },
+ '/robots.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "",
+ },
+ '/p1_fran%C3%A7ais.html' => { # UTF-8 encoded
+ code => "404",
+ msg => "File not found",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $page404,
+ },
+ '/p1_fran%E7ais.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pagefrancais,
+ },
+ '/p2_%C3%A9%C3%A9n.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-1",
+ },
+ content => $pageeen,
+ },
+ '/p2_%E9%E9n.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-1",
+ },
+ content => $pageeen,
+ },
+ '/url_list.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain; charset=ISO-8859-1",
+ },
+ content => $urllist,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri --trust-server-names -i http://localhost:{{port}}/url_list.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'url_list.txt' => {
+ content => $urllist,
+ },
+ 'index.html' => {
+ content => $pageindex,
+ },
+ "p1_fran${ccedilla_l1}ais.html" => {
+ content => $pagefrancais,
+ },
+ "p2_${eacute_u8}${eacute_u8}n.html" => {
+ content => $pageeen,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-iri-percent.px b/tests/Test-iri-percent.px
new file mode 100755
index 0000000..7c4f4c8
--- /dev/null
+++ b/tests/Test-iri-percent.px
@@ -0,0 +1,88 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# Just a sanity check to verify that %-encoded values are always left
+# untouched.
+
+my $ccedilla_l15 = "\xE7";
+my $ccedilla_l15_pct = "%E7";
+my $ccedilla_u8 = "\xC3\xA7";
+my $ccedilla_u8_pct = "%C3%A7";
+my $eacute_l1 = "\xE9";
+my $eacute_u8 = "\xC3\xA9";
+my $eacute_u8_pct = "%C3%A9";
+
+my $pageindex = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Link to page 1 <a
+ href="http://localhost:{{port}}/hello_${ccedilla_l15_pct}${eacute_l1}.html">La seule page en fran&ccedil;ais</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $pagefrancais = <<EOF;
+<html>
+<head>
+ <title>La seule page en français</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+</head>
+<body>
+ <p>
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-15",
+ },
+ content => $pageindex,
+ },
+ "/hello_${ccedilla_u8_pct}${eacute_u8_pct}.html" => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pagefrancais,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -e robots=off --restrict-file-names=nocontrol -nH -r http://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $pageindex,
+ },
+ "hello_${ccedilla_u8}${eacute_u8}.html" => {
+ content => $pagefrancais,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-iri.px b/tests/Test-iri.px
new file mode 100755
index 0000000..eb23b63
--- /dev/null
+++ b/tests/Test-iri.px
@@ -0,0 +1,208 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(iri);
+use HTTPTest;
+
+# cf. http://en.wikipedia.org/wiki/Latin1
+# http://en.wikipedia.org/wiki/ISO-8859-15
+
+###############################################################################
+#
+# mime : charset found in Content-Type HTTP MIME header
+# meta : charset found in Content-Type meta tag
+#
+# index.html mime + file = iso-8859-15
+# p1_français.html meta + file = iso-8859-1, mime = utf-8
+# p2_één.html meta + file = utf-8, mime =iso-8859-1
+# p3_€€€.html meta + file = utf-8, mime = iso-8859-1
+# p4_méér.html mime + file = utf-8
+#
+
+my $ccedilla_l15 = "\xE7";
+my $ccedilla_u8 = "\xC3\xA7";
+my $eacute_l1 = "\xE9";
+my $eacute_u8 = "\xC3\xA9";
+my $eurosign_l15 = "\xA4";
+my $eurosign_u8 = "\xE2\x82\xAC";
+
+my $pageindex = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Link to page 1 <a href="http://localhost:{{port}}/p1_fran${ccedilla_l15}ais.html">La seule page en fran&ccedil;ais</a>.
+ Link to page 3 <a href="http://localhost:{{port}}/p3_${eurosign_l15}${eurosign_l15}${eurosign_l15}.html">My tailor is rich</a>.
+ </p>
+</body>
+</html>
+EOF
+
+# specifying a wrong charset in http-equiv - it will be overridden by Content-Type HTTP header
+my $pagefrancais = <<EOF;
+<html>
+<head>
+ <title>La seule page en français</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <p>
+ Link to page 2 <a href="http://localhost:{{port}}/p2_${eacute_l1}${eacute_l1}n.html">Die enkele nerderlangstalige pagina</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeen = <<EOF;
+<html>
+<head>
+ <title>Die enkele nederlandstalige pagina</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <p>
+ &Eacute;&eacute;n is niet veel maar toch meer dan nul.<br/>
+ Nerdelands is een mooie taal... dit zin stuckje spreekt vanzelf, of niet :)<br/>
+ <a href="http://localhost:{{port}}/p4_m${eacute_u8}${eacute_u8}r.html">M&eacute&eacute;r</a>
+ </p>
+</body>
+</html>
+EOF
+
+my $pageeuro = <<EOF;
+<html>
+<head>
+ <title>Euro page</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+ <p>
+ My tailor isn't rich anymore.
+ </p>
+</body>
+</html>
+EOF
+
+my $pagemeer = <<EOF;
+<html>
+<head>
+ <title>Bekende supermarkt</title>
+</head>
+<body>
+ <p>
+ Ik ben toch niet gek !
+ </p>
+</body>
+</html>
+EOF
+
+my $page404 = <<EOF;
+<html>
+<head>
+ <title>404</title>
+</head>
+<body>
+ <p>
+ Nop nop nop...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html; charset=ISO-8859-15",
+ },
+ content => $pageindex,
+ },
+ '/robots.txt' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "",
+ },
+ '/p1_fran%C3%A7ais.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ # Content-Type header overrides http-equiv Content-Type
+ "Content-type" => "text/html; charset=ISO-8859-15",
+ },
+ content => $pagefrancais,
+ },
+ '/p2_%C3%A9%C3%A9n.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ request_headers => {
+ "Referer" => qr|http://localhost:[0-9]+/p1_fran%C3%A7ais.html|,
+ },
+ headers => {
+ "Content-type" => "text/html; charset=UTF-8",
+ },
+ content => $pageeen,
+ },
+ '/p3_%E2%82%AC%E2%82%AC%E2%82%AC.html' => { # UTF-8 encoded
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/plain; charset=ISO-8859-1",
+ },
+ content => $pageeuro,
+ },
+ '/p4_m%C3%A9%C3%A9r.html' => {
+ code => "200",
+ msg => "Ok",
+ request_headers => {
+ "Referer" => qr|http://localhost:[0-9]+/p2_%C3%A9%C3%A9n.html|,
+ },
+ headers => {
+ "Content-type" => "text/plain; charset=UTF-8",
+ },
+ content => $pagemeer,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri --trust-server-names --restrict-file-names=nocontrol -nH -r http://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $pageindex,
+ },
+ 'robots.txt' => {
+ content => "",
+ },
+ "p1_fran${ccedilla_u8}ais.html" => {
+ content => $pagefrancais,
+ },
+ "p2_${eacute_u8}${eacute_u8}n.html" => {
+ content => $pageeen,
+ },
+ "p3_${eurosign_u8}${eurosign_u8}${eurosign_u8}.html" => {
+ content => $pageeuro,
+ },
+ "p4_m${eacute_u8}${eacute_u8}r.html" => {
+ content => $pagemeer,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-k.px b/tests/Test-k.px
new file mode 100755
index 0000000..ce114d7
--- /dev/null
+++ b/tests/Test-k.px
@@ -0,0 +1,92 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+my $osname = $^O;
+print "OS=$osname\n";
+
+my $index = <<EOF;
+<html>
+ <head>
+ <title>Index</title>
+ </head>
+ <body>
+ <a href="site;sub:.html">Site</a>
+ </body>
+</html>
+EOF
+
+my $converted = <<EOF;
+<html>
+ <head>
+ <title>Index</title>
+ </head>
+ <body>
+ <a href="./site%3Bsub:.html">Site</a>
+ </body>
+</html>
+EOF
+
+my $site = <<EOF;
+<html>
+ <head>
+ <title>Site</title>
+ </head>
+ <body>
+ Subsite
+ </body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $index,
+ },
+ '/site;sub:.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $site,
+ },
+);
+
+my $restrict = "unix";
+if ($osname eq "MSWin32") {
+ $restrict = "windows";
+}
+
+my $cmdline = $WgetTest::WGETPATH . " -k -r -nH --restrict-file-names=$restrict http://localhost:{{port}}/index.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $converted,
+ },
+ 'site;sub:.html' => {
+ content => $site,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-meta-robots.px b/tests/Test-meta-robots.px
new file mode 100755
index 0000000..4a90338
--- /dev/null
+++ b/tests/Test-meta-robots.px
@@ -0,0 +1,113 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+# This test checks that Wget parses "nofollow" when it appears in <meta
+# name="robots"> tags, regardless of where in a list of comma-separated
+# values it appears, and regardless of spelling.
+#
+# Three different files contain links to the file "bombshell.html", each
+# with "nofollow" set, at various positions in a list of values for a
+# <meta name="robots"> tag, and with various degrees of separating
+# whitesspace. If bombshell.html is downloaded, the test
+# has failed.
+
+###############################################################################
+
+my $nofollow_start = <<EOF;
+<meta name="roBoTS" content="noFolLow , foo, bar ">
+<a href="/bombshell.html">Don't follow me!</a>
+EOF
+
+my $nofollow_mid = <<EOF;
+<meta name="rObOts" content=" foo , NOfOllow , bar ">
+<a href="/bombshell.html">Don't follow me!</a>
+EOF
+
+my $nofollow_end = <<EOF;
+<meta name="RoBotS" content="foo,BAr, nofOLLOw ">
+<a href="/bombshell.html">Don't follow me!</a>
+EOF
+
+my $nofollow_solo = <<EOF;
+<meta name="robots" content="nofollow">
+<a href="/bombshell.html">Don't follow me!</a>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/start.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $nofollow_start,
+ },
+ '/mid.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $nofollow_mid,
+ },
+ '/end.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $nofollow_end,
+ },
+ '/solo.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $nofollow_solo,
+ },
+ '/bombshell.html' => {
+ code => "200",
+ msg => "Ok",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => 'Hello',
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -r -nd "
+ . join(' ',(map "http://localhost:{{port}}/$_.html",
+ qw(start mid end solo)));
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'start.html' => {
+ content => $nofollow_start,
+ },
+ 'mid.html' => {
+ content => $nofollow_mid,
+ },
+ 'end.html' => {
+ content => $nofollow_end,
+ },
+ 'solo.html' => {
+ content => $nofollow_solo,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-nonexisting-quiet.px b/tests/Test-nonexisting-quiet.px
new file mode 100755
index 0000000..9f68081
--- /dev/null
+++ b/tests/Test-nonexisting-quiet.px
@@ -0,0 +1,42 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $dummyfile = <<EOF;
+Don't care.
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/dummy.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $dummyfile
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --quiet http://localhost:{{port}}/nonexistent";
+
+my $expected_error_code = 8;
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-noop.px b/tests/Test-noop.px
new file mode 100755
index 0000000..d08cbcd
--- /dev/null
+++ b/tests/Test-noop.px
@@ -0,0 +1,55 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $index = <<EOF;
+<html>
+<head>
+ <title>Page Title</title>
+</head>
+<body>
+ <h1>Page Title</h1>
+ <p>
+ Some text here.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $index
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " http://localhost:{{port}}/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'index.html' => {
+ content => $index,
+ }
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-np.px b/tests/Test-np.px
new file mode 100755
index 0000000..1253c5d
--- /dev/null
+++ b/tests/Test-np.px
@@ -0,0 +1,147 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Main Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/firstlevel/secondpage.html">second page</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $secondpage = <<EOF;
+<html>
+<head>
+ <title>Second Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/firstlevel/lowerlevel/thirdpage.html">third page</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $thirdpage = <<EOF;
+<html>
+<head>
+ <title>Third Page</title>
+</head>
+<body>
+ <p>
+ Some text and a link to a <a href="http://localhost:{{port}}/higherlevelpage.html">higher level page</a>.
+ </p>
+</body>
+</html>
+EOF
+
+my $fourthpage = <<EOF;
+<html>
+<head>
+ <title>Fourth Page</title>
+</head>
+<body>
+ <p>
+ This page is only linked by the higher level page. Therefore, it should not
+ be downloaded.
+ </p>
+</body>
+</html>
+EOF
+
+my $higherlevelpage = <<EOF;
+<html>
+<head>
+ <title>Higher Level Page</title>
+</head>
+<body>
+ <p>
+ This page is on a higher level in the URL path hierarchy. Therefore, it
+ should not be downloaded. Wget should not visit the following link to a
+ <a href="http://localhost:{{port}}/firstlevel/fourthpage.html">fourth page</a>.
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ '/firstlevel/index.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+ '/firstlevel/secondpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $secondpage,
+ },
+ '/firstlevel/lowerlevel/thirdpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $thirdpage,
+ },
+ '/firstlevel/fourthpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $fourthpage,
+ },
+ '/higherlevelpage.html' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $higherlevelpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " -np -nH -r http://localhost:{{port}}/firstlevel/";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'firstlevel/index.html' => {
+ content => $mainpage,
+ },
+ 'firstlevel/secondpage.html' => {
+ content => $secondpage,
+ },
+ 'firstlevel/lowerlevel/thirdpage.html' => {
+ content => $thirdpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-proxied-https-auth-keepalive.px b/tests/Test-proxied-https-auth-keepalive.px
new file mode 100755
index 0000000..2a18ccf
--- /dev/null
+++ b/tests/Test-proxied-https-auth-keepalive.px
@@ -0,0 +1,181 @@
+#!/usr/bin/env perl
+# Simulate a tunneling proxy to a HTTPS URL that needs authentication.
+# Use a persistent connection (Connection: keep-alive)
+
+use strict;
+use warnings;
+
+use WgetFeature qw(https);
+use WgetTests; # For $WGETPATH.
+
+my $cert_path;
+my $key_path;
+my $srcdir;
+
+our $VALGRIND_SUPP_FILE;
+
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+
+if (defined $srcdir) {
+ $key_path = "$srcdir/certs/server-key.pem";
+ $cert_path = "$srcdir/certs/server-cert.pem";
+} else {
+ $key_path = "certs/server-key.pem";
+ $cert_path = "certs/server-cert.pem";
+}
+
+
+use HTTP::Daemon;
+use HTTP::Request;
+# Skip this test rather than fail it when the module isn't installed
+if (!eval {require IO::Socket::SSL;1;}) {
+ print STDERR "This test needs the perl module \"IO::Socket::SSL\".\n";
+ print STDERR "Install e.g. on Debian with 'apt-get install libio-socket-ssl-perl'\n";
+ print STDERR " or if using cpanminus 'cpanm IO::Socket::SSL' could be used to install it.\n";
+ exit 77; # skip
+}
+IO::Socket::SSL->import();
+
+my $SOCKET = HTTP::Daemon->new (LocalAddr => 'localhost',
+ ReuseAddr => 1) or die "Cannot create server!!!";
+
+sub get_request {
+ my $conn = shift;
+ my $content = '';
+ my $line;
+
+ while (defined ($line = <$conn>)) {
+ $content .= $line;
+ last if $line eq "\r\n";
+ }
+
+ my $rqst = HTTP::Request->parse($content)
+ or die "Couldn't parse request:\n$content\n";
+
+ return $rqst;
+}
+
+sub do_server {
+ my ($synch_callback) = @_;
+ my $s = $SOCKET;
+ my $conn;
+ my $rqst;
+ my $rspn;
+
+ # sync with the parent
+ $synch_callback->();
+
+ # Simulate a HTTPS proxy server with tunneling.
+
+ $conn = $s->accept;
+ $rqst = $conn->get_request;
+ die "Method not CONNECT\n" if ($rqst->method ne 'CONNECT');
+ $rspn = HTTP::Response->new(200, 'OK');
+ $conn->send_response($rspn);
+
+ # Now switch from plain to SSL (for simulating a transparent tunnel
+ # to an HTTPS server).
+
+ my %options = (
+ SSL_server => 1,
+ SSL_passwd_cb => sub { return "Hello"; });
+ $options{SSL_cert_file} = $cert_path if ($cert_path);
+ $options{SSL_key_file} = $key_path if ($key_path);
+ my @options = %options;
+ $conn = IO::Socket::SSL->new_from_fd($conn->fileno, @options)
+ or die "Couldn't initiate SSL";
+
+ for my $expect_inner_auth (0, 1) {
+ # TODO: expect no auth the first time, request it, expect it the second
+ # time.
+
+ $rqst = &get_request($conn)
+ or die "Didn't get proxied request\n";
+
+ unless ($expect_inner_auth) {
+ die "Early proxied auth\n" if $rqst->header('Authorization');
+
+ $rspn = HTTP::Response->new(401, 'Unauthorized', [
+ 'WWW-Authenticate' => 'Basic realm="gondor"',
+ Connection => 'keep-alive'
+ ]);
+ } else {
+ die "No proxied auth\n" unless $rqst->header('Authorization');
+
+ $rspn = HTTP::Response->new(200, 'OK', [
+ 'Content-Type' => 'text/plain',
+ 'Connection' => 'close',
+ ], "foobarbaz\n");
+ }
+
+ $rspn->protocol('HTTP/1.0');
+ print STDERR "=====\n";
+ print STDERR $rspn->as_string;
+ print STDERR "\n=====\n";
+ print $conn $rspn->as_string;
+ }
+
+ $conn->close;
+ undef $conn;
+ undef $s;
+}
+
+sub fork_server {
+ pipe(FROM_CHILD, TO_PARENT) or die "Cannot create pipe!";
+ select((select(TO_PARENT), $| = 1)[0]);
+
+ my $pid = fork();
+ if ($pid < 0) {
+ die "Cannot fork";
+ } elsif ($pid == 0) {
+ # child
+ close FROM_CHILD;
+ do_server(sub { print TO_PARENT "SYNC\n"; close TO_PARENT });
+ exit 0;
+ } else {
+ # parent
+ close TO_PARENT;
+ chomp(my $line = <FROM_CHILD>);
+ close FROM_CHILD;
+ }
+
+ return $pid;
+}
+
+unlink "needs-auth.txt";
+my $pid = &fork_server;
+
+my $cmdline = $WgetTest::WGETPATH . " --user=fiddle-dee-dee"
+ . " --password=Dodgson -e https_proxy=localhost:{{port}}"
+ . " --no-check-certificate"
+ . " https://no.such.domain/needs-auth.txt";
+$cmdline =~ s/\Q{{port}}/$SOCKET->sockport()/e;
+
+if (defined $srcdir) {
+ $VALGRIND_SUPP_FILE = $srcdir . '/valgrind-suppressions-ssl';
+} else {
+ $VALGRIND_SUPP_FILE = './valgrind-suppressions-ssl';
+}
+
+my $valgrind = $ENV{VALGRIND_TESTS};
+if (!defined $valgrind || $valgrind eq "" || $valgrind == 0) {
+ # Valgrind not requested - leave $cmdline as it is
+} elsif ($valgrind == 1) {
+ $cmdline =
+ 'valgrind --suppressions=' . $VALGRIND_SUPP_FILE
+ . ' --error-exitcode=301 --leak-check=yes --track-origins=yes '
+ . $cmdline;
+} else {
+ $cmdline = $valgrind . " " . $cmdline;
+}
+
+my $code = system($cmdline . " 2>&1") >> 8;
+unlink "needs-auth.txt";
+
+warn "Got code: $code\n" if $code;
+kill ('TERM', $pid);
+exit ($code != 0);
diff --git a/tests/Test-proxied-https-auth.px b/tests/Test-proxied-https-auth.px
new file mode 100755
index 0000000..81c93c1
--- /dev/null
+++ b/tests/Test-proxied-https-auth.px
@@ -0,0 +1,180 @@
+#!/usr/bin/env perl
+# Simulate a tunneling proxy to a HTTPS URL that needs authentication.
+# Use two connections (Connection: close)
+
+use strict;
+use warnings;
+
+use WgetFeature qw(https);
+use WgetTests; # For $WGETPATH.
+
+my $cert_path;
+my $key_path;
+my $srcdir;
+
+our $VALGRIND_SUPP_FILE;
+
+if (@ARGV) {
+ $srcdir = shift @ARGV;
+} elsif (defined $ENV{srcdir}) {
+ $srcdir = $ENV{srcdir};
+}
+
+if (defined $srcdir) {
+ $key_path = "$srcdir/certs/server-key.pem";
+ $cert_path = "$srcdir/certs/server-cert.pem";
+} else {
+ $key_path = "certs/server-key.pem";
+ $cert_path = "certs/server-cert.pem";
+}
+
+
+use HTTP::Daemon;
+use HTTP::Request;
+# Skip this test rather than fail it when the module isn't installed
+if (!eval {require IO::Socket::SSL;1;}) {
+ print STDERR "This test needs the perl module \"IO::Socket::SSL\".\n";
+ print STDERR "Install e.g. on Debian with 'apt-get install libio-socket-ssl-perl'\n";
+ print STDERR " or if using cpanminus 'cpanm IO::Socket::SSL' could be used to install it.\n";
+ exit 77; # skip
+}
+IO::Socket::SSL->import();
+
+my $SOCKET = HTTP::Daemon->new (LocalAddr => 'localhost',
+ ReuseAddr => 1) or die "Cannot create server!!!";
+
+sub get_request {
+ my $conn = shift;
+ my $content = '';
+ my $line;
+
+ while (defined ($line = <$conn>)) {
+ $content .= $line;
+ last if $line eq "\r\n";
+ }
+
+ my $rqst = HTTP::Request->parse($content)
+ or die "Couldn't parse request:\n$content\n";
+
+ return $rqst;
+}
+
+sub do_server {
+ my ($synch_callback) = @_;
+ my $s = $SOCKET;
+ my $conn;
+ my $rqst;
+ my $rspn;
+
+ my %options = (
+ SSL_server => 1,
+ SSL_passwd_cb => sub { return "Hello"; });
+ $options{SSL_cert_file} = $cert_path if ($cert_path);
+ $options{SSL_key_file} = $key_path if ($key_path);
+ my @options = %options;
+
+ # sync with the parent
+ $synch_callback->();
+
+ # Simulate a HTTPS proxy server with tunneling.
+
+ for my $expect_inner_auth (0, 1) {
+ $conn = $s->accept;
+ $rqst = $conn->get_request;
+ die "Method not CONNECT\n" if ($rqst->method ne 'CONNECT');
+ $rspn = HTTP::Response->new(200, 'OK');
+ $conn->send_response($rspn);
+
+ # Now switch from plain to SSL (for simulating a transparent tunnel
+ # to an HTTPS server).
+
+ $conn = IO::Socket::SSL->new_from_fd($conn->fileno, @options)
+ or die "Couldn't initiate SSL";
+
+ $rqst = &get_request($conn)
+ or die "Didn't get proxied request\n";
+
+ unless ($expect_inner_auth) {
+ die "Early proxied auth\n" if $rqst->header('Authorization');
+
+ $rspn = HTTP::Response->new(401, 'Unauthorized', [
+ 'WWW-Authenticate' => 'Basic realm="gondor"',
+ Connection => 'close'
+ ]);
+ } else {
+ die "No proxied auth\n" unless $rqst->header('Authorization');
+
+ $rspn = HTTP::Response->new(200, 'OK', [
+ 'Content-Type' => 'text/plain',
+ 'Connection' => 'close',
+ ], "foobarbaz\n");
+ }
+
+ $rspn->protocol('HTTP/1.0');
+ print STDERR "=====\n";
+ print STDERR $rspn->as_string;
+ print STDERR "\n=====\n";
+ print $conn $rspn->as_string;
+
+ $conn->close;
+ }
+
+ undef $conn;
+ undef $s;
+}
+
+sub fork_server {
+ pipe(FROM_CHILD, TO_PARENT) or die "Cannot create pipe!";
+ select((select(TO_PARENT), $| = 1)[0]);
+
+ my $pid = fork();
+ if ($pid < 0) {
+ die "Cannot fork";
+ } elsif ($pid == 0) {
+ # child
+ close FROM_CHILD;
+ do_server(sub { print TO_PARENT "SYNC\n"; close TO_PARENT });
+ exit 0;
+ } else {
+ # parent
+ close TO_PARENT;
+ chomp(my $line = <FROM_CHILD>);
+ close FROM_CHILD;
+ }
+
+ return $pid;
+}
+
+unlink "needs-auth.txt";
+my $pid = &fork_server;
+
+my $cmdline = $WgetTest::WGETPATH . " --user=fiddle-dee-dee"
+ . " --password=Dodgson -e https_proxy=localhost:{{port}}"
+ . " --no-check-certificate"
+ . " https://no.such.domain/needs-auth.txt";
+$cmdline =~ s/\Q{{port}}/$SOCKET->sockport()/e;
+
+if (defined $srcdir) {
+ $VALGRIND_SUPP_FILE = $srcdir . '/valgrind-suppressions-ssl';
+} else {
+ $VALGRIND_SUPP_FILE = './valgrind-suppressions-ssl';
+}
+
+my $valgrind = $ENV{VALGRIND_TESTS};
+if (!defined $valgrind || $valgrind eq "" || $valgrind == 0) {
+ # Valgrind not requested - leave $cmdline as it is
+} elsif ($valgrind == 1) {
+ $cmdline =
+ 'valgrind --suppressions=' . $VALGRIND_SUPP_FILE
+ . ' --error-exitcode=301 --leak-check=yes --track-origins=yes --gen-suppressions=all '
+ . $cmdline;
+} else {
+ $cmdline = $valgrind . " " . $cmdline;
+}
+
+my $code = system($cmdline . " 2>&1") >> 8;
+unlink "needs-auth.txt";
+
+warn "Got code: $code\n" if $code;
+kill ('TERM', $pid);
+exit ($code != 0);
diff --git a/tests/Test-proxy-auth-basic.px b/tests/Test-proxy-auth-basic.px
new file mode 100755
index 0000000..4c2dee8
--- /dev/null
+++ b/tests/Test-proxy-auth-basic.px
@@ -0,0 +1,47 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $wholefile = "You're all authenticated.\n";
+
+# code, msg, headers, content
+my %urls = (
+ 'http://no.such.domain/needs-auth.txt' => {
+ auth_method => 'Basic',
+ user => 'fiddle-dee-dee',
+ passwd => 'Dodgson',
+ code => "200",
+ msg => "You want fries with that?",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => $wholefile,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --user=fiddle-dee-dee --password=Dodgson"
+ . " -e http_proxy=localhost:{{port}} http://no.such.domain/needs-auth.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'needs-auth.txt' => {
+ content => $wholefile,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-restrict-ascii.px b/tests/Test-restrict-ascii.px
new file mode 100755
index 0000000..ecde384
--- /dev/null
+++ b/tests/Test-restrict-ascii.px
@@ -0,0 +1,67 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+# This program tests that --restrict-file-names=ascii can be used to
+# ensure that all high-valued bytes are escaped. The sample filename was
+# chosen because in former versions of Wget, one could either choose not
+# to escape any portion of the UTF-8 filename via
+# --restrict-file-names=nocontrol (which would only be helpful if one
+# was _on_ a UTF-8 system), or else Wget would escape _portions_ of
+# characters, leaving irrelevant "latin1"-looking characters combined
+# with percent-encoded "control" characters, instead of encoding all the
+# bytes of an entire non-ASCII UTF-8 character.
+
+###############################################################################
+
+# "gnosis" in UTF-8 greek.
+my $gnosis = '%CE%B3%CE%BD%CF%89%CF%83%CE%B9%CF%82';
+
+my $mainpage = <<EOF;
+<html>
+<head>
+ <title>Some Page Title</title>
+</head>
+<body>
+ <p>
+ Some text...
+ </p>
+</body>
+</html>
+EOF
+
+# code, msg, headers, content
+my %urls = (
+ "/$gnosis.html" => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/html",
+ },
+ content => $mainpage,
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --restrict-file-names=ascii "
+ . "http://localhost:{{port}}/${gnosis}.html";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "${gnosis}.html" => {
+ content => $mainpage,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/Test-stdouterr.px b/tests/Test-stdouterr.px
new file mode 100755
index 0000000..7bcfed9
--- /dev/null
+++ b/tests/Test-stdouterr.px
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+# code, msg, headers, content
+my %urls = (
+ '/somefile.txt' => {
+ code => "200",
+ msg => "Dontcare",
+ headers => {
+ "Content-type" => "text/plain",
+ },
+ content => "blabla",
+ },
+);
+
+unless(-e "/dev/full") {
+ exit 77; # skip
+}
+
+my $cmdline = $WgetTest::WGETPATH . " -c http://localhost:{{port}}/somefile.txt -O /dev/full";
+
+my $expected_error_code = 3;
+
+my %existing_files = (
+);
+
+my %expected_downloaded_files = (
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (input => \%urls,
+ cmdline => $cmdline,
+ errcode => $expected_error_code,
+ existing => \%existing_files,
+ output => \%expected_downloaded_files);
+exit $the_test->run();
+
+# vim: et ts=4 sw=4
diff --git a/tests/WgetFeature.pm b/tests/WgetFeature.pm
new file mode 100644
index 0000000..0d59573
--- /dev/null
+++ b/tests/WgetFeature.pm
@@ -0,0 +1,41 @@
+package WgetFeature;
+
+use strict;
+use warnings;
+
+our $VERSION = 0.01;
+
+use English qw(-no_match_vars);
+use WgetTests;
+
+sub import
+{
+ my ($class, @required_feature) = @_;
+
+ # create a list of available features from 'wget --version' output
+ my $output = `$WgetTest::WGETPATH --version`;
+ my ($list) = $output =~ m/^([+-]\S+(?:\s+[+-]\S+)+)/msx;
+ my %have_features;
+ for my $f (split m/\s+/msx, $list)
+ {
+ my $feat = $f;
+ $feat =~ s/^.//msx;
+ $have_features{$feat} = $f =~ m/^[+]/msx ? 1 : 0;
+ }
+
+ foreach (@required_feature)
+ {
+ if (!$have_features{$_})
+ {
+ print "Skipped test: Wget misses feature '$_'\n";
+ print "Features available from 'wget --version' output:\n";
+ foreach (keys %have_features)
+ {
+ print " $_=$have_features{$_}\n";
+ }
+ exit 77; # skip
+ }
+ }
+}
+
+1;
diff --git a/tests/WgetTests.pm b/tests/WgetTests.pm
new file mode 100644
index 0000000..0bb8848
--- /dev/null
+++ b/tests/WgetTests.pm
@@ -0,0 +1,447 @@
+package WgetTest;
+
+use strict;
+use warnings;
+
+our $VERSION = 0.01;
+
+use Carp;
+use Cwd;
+use English qw(-no_match_vars);
+use File::Path;
+use IO::Handle;
+use POSIX qw(locale_h);
+use locale;
+
+if (defined $ENV{'WGET_PATH'}) {
+ our $WGETPATH = $ENV{'WGET_PATH'} . ' -d --no-config';
+} else {
+ our $WGETPATH = '../src/wget -d --no-config';
+}
+
+
+our $VALGRIND_SUPP_FILE = Cwd::getcwd();
+if (defined $ENV{'srcdir'}) {
+ $VALGRIND_SUPP_FILE = $VALGRIND_SUPP_FILE
+ . "/" . $ENV{'srcdir'};
+}
+$VALGRIND_SUPP_FILE = $VALGRIND_SUPP_FILE . '/valgrind-suppressions';
+
+my @unexpected_downloads = ();
+
+{
+ my %_attr_data = ( # DEFAULT
+ _cmdline => q{},
+ _workdir => Cwd::getcwd(),
+ _errcode => 0,
+ _existing => {},
+ _input => {},
+ _name => $PROGRAM_NAME,
+ _output => {},
+ _server_behavior => {},
+ );
+
+ sub _default_for
+ {
+ my ($self, $attr) = @_;
+ return $_attr_data{$attr};
+ }
+
+ sub _standard_keys
+ {
+ return keys %_attr_data;
+ }
+}
+
+sub new
+{
+ my ($caller, %args) = @_;
+ my $caller_is_obj = ref $caller;
+ my $class = $caller_is_obj || $caller;
+
+ #print STDERR "class = ", $class, "\n";
+ #print STDERR "_attr_data {workdir} = ", $WgetTest::_attr_data{_workdir}, "\n";
+ my $self = bless {}, $class;
+ for my $attrname ($self->_standard_keys())
+ {
+
+ #print STDERR "attrname = ", $attrname, " value = ";
+ my ($argname) = ($attrname =~ m/^_(.*)/msx);
+ if (exists $args{$argname})
+ {
+
+ #printf STDERR "Setting up $attrname\n";
+ $self->{$attrname} = $args{$argname};
+ }
+ elsif ($caller_is_obj)
+ {
+
+ #printf STDERR "Copying $attrname\n";
+ $self->{$attrname} = $caller->{$attrname};
+ }
+ else
+ {
+ #printf STDERR "Using default for $attrname\n";
+ $self->{$attrname} = $self->_default_for($attrname);
+ }
+
+ #print STDERR $attrname, '=', $self->{$attrname}, "\n";
+ }
+
+ #printf STDERR "_workdir default = ", $self->_default_for("_workdir");
+ return $self;
+}
+
+sub run
+{
+ my $self = shift;
+ my $result_message = "Test successful.\n";
+ my $errcode;
+
+ $self->{_name} =~ s{.*/}{}msx; # remove path
+ $self->{_name} =~ s{[.][^.]+$}{}msx; # remove extension
+ printf "Running test $self->{_name}\n";
+
+ # Setup
+ my $new_result = $self->_setup();
+ chdir "$self->{_workdir}/$self->{_name}/input"
+ or carp "Could not chdir to input directory: $ERRNO";
+ if (defined $new_result)
+ {
+ $result_message = $new_result;
+ $errcode = 1;
+ goto cleanup;
+ }
+
+ # Launch server
+ my $pid = $self->_fork_and_launch_server();
+
+ # Call wget
+ chdir "$self->{_workdir}/$self->{_name}/output"
+ or carp "Could not chdir to output directory: $ERRNO";
+
+ my $cmdline = $self->{_cmdline};
+ $cmdline = $self->_substitute_port($cmdline);
+ $cmdline =
+ ($cmdline =~ m{^/.*}msx) ? $cmdline : "$self->{_workdir}/$cmdline";
+
+ my $valgrind = $ENV{VALGRIND_TESTS};
+ if (!defined $valgrind)
+ {
+ $valgrind = 0;
+ }
+
+ my $gdb = $ENV{GDB_TESTS};
+ if (!defined $gdb)
+ {
+ $gdb = 0;
+ }
+
+ if ($gdb == 1)
+ {
+ $cmdline = 'gdb --args ' . $cmdline;
+ }
+ elsif ($valgrind eq "1")
+ {
+ $cmdline =
+ 'valgrind --suppressions=' . $VALGRIND_SUPP_FILE
+ . ' --error-exitcode=301 --leak-check=full --track-origins=yes --show-leak-kinds=all --gen-suppressions=all '
+ . $cmdline;
+ }
+ elsif ($valgrind ne q{} && $valgrind ne "0")
+ {
+ $cmdline = "$valgrind $cmdline";
+ }
+
+ print "Calling $cmdline\n";
+ $errcode = system $cmdline;
+ $errcode >>= 8; # XXX: should handle abnormal error codes.
+
+ # Shutdown server
+ # if we didn't explicitly kill the server, we would have to call
+ # waitpid ($pid, 0) here in order to wait for the child process to
+ # terminate
+ kill 'TERM', $pid;
+
+ # Verify download
+ if ($errcode != $self->{_errcode})
+ {
+ $result_message =
+ "Test failed: wrong code returned (was: $errcode, expected: $self->{_errcode})\n";
+ goto CLEANUP;
+ }
+ my $error_str;
+ if ($error_str = $self->_verify_download())
+ {
+ $result_message = $error_str;
+ }
+
+ CLEANUP:
+ $self->_cleanup();
+
+ print $result_message;
+ return $errcode != $self->{_errcode} || ($error_str ? 1 : 0);
+}
+
+sub _setup
+{
+ my $self = shift;
+
+ chdir $self->{_workdir}
+ or carp "Could not chdir into $self->{_workdir}: $ERRNO";
+
+ # Create temporary directory
+ mkdir $self->{_name} or carp "Could not mkdir '$self->{_name}': $ERRNO";
+ chdir $self->{_name}
+ or carp "Could not chdir into '$self->{_name}': $ERRNO";
+ mkdir 'input' or carp "Could not mkdir 'input' $ERRNO";
+ mkdir 'output' or carp "Could not mkdir 'output': $ERRNO";
+
+ # Setup existing files
+ chdir 'output' or carp "Could not chdir into 'output': $ERRNO";
+ for my $filename (keys %{$self->{_existing}})
+ {
+ open my $fh, '>', $filename
+ or return "Test failed: cannot open pre-existing file $filename\n";
+
+ my $file = $self->{_existing}->{$filename};
+ print {$fh} $file->{content}
+ or return "Test failed: cannot write pre-existing file $filename\n";
+
+ close $fh or carp $ERRNO;
+
+ if (exists($file->{timestamp}))
+ {
+ utime $file->{timestamp}, $file->{timestamp}, $filename
+ or return
+ "Test failed: cannot set timestamp on pre-existing file $filename\n";
+ }
+ }
+
+ chdir '../input' or carp "Cannot chdir into '../input': $ERRNO";
+ $self->_setup_server();
+
+ chdir $self->{_workdir}
+ or carp "Cannot chdir into '$self->{_workdir}': $ERRNO";
+ return;
+}
+
+sub _cleanup
+{
+ my $self = shift;
+
+ chdir $self->{_workdir}
+ or carp "Could not chdir into '$self->{_workdir}': $ERRNO";
+ if (!$ENV{WGET_TEST_NO_CLEANUP})
+ {
+ File::Path::rmtree($self->{_name});
+ }
+ return 1;
+}
+
+# not a method
+sub quotechar
+{
+ my $c = ord shift;
+ if ($c >= 0x7 && $c <= 0xD)
+ {
+ return q{\\} . qw(a b t n v f r) [$c - 0x7];
+ }
+ else
+ {
+ return sprintf '\\x%02x', $c;
+ }
+}
+
+# not a method
+sub _show_diff
+{
+ my ($expected, $actual) = @_;
+ my $SNIPPET_SIZE = 10;
+
+ my $str = q{};
+ my $explen = length $expected;
+ my $actlen = length $actual;
+
+ if ($explen != $actlen)
+ {
+ $str .= "Sizes don't match: expected = $explen, actual = $actlen\n";
+ }
+
+ my $min = $explen <= $actlen ? $explen : $actlen;
+ my $line = 1;
+ my $col = 1;
+ my $i = 0;
+
+ while ( $i < $min )
+ {
+ last if substr($expected, $i, 1) ne substr $actual, $i, 1;
+ if (substr($expected, $i, 1) eq "\n")
+ {
+ $line++;
+ $col = 0;
+ }
+ else
+ {
+ $col++;
+ }
+ $i++;
+ }
+ my $snip_start = $i - ($SNIPPET_SIZE / 2);
+ if ($snip_start < 0)
+ {
+ $SNIPPET_SIZE += $snip_start; # Take it from the end.
+ $snip_start = 0;
+ }
+ my $exp_snip = substr $expected, $snip_start, $SNIPPET_SIZE;
+ my $act_snip = substr $actual, $snip_start, $SNIPPET_SIZE;
+ $exp_snip =~ s/[^[:print:]]/ quotechar($&) /gemsx;
+ $act_snip =~ s/[^[:print:]]/ quotechar($&) /gemsx;
+ $str .= "Mismatch at line $line, col $col:\n";
+ $str .= " $exp_snip\n";
+ $str .= " $act_snip\n";
+
+ return $str;
+}
+
+sub _verify_download
+{
+ my $self = shift;
+
+ chdir "$self->{_workdir}/$self->{_name}/output"
+ or carp "Could not chdir into output directory: $ERRNO";
+
+ # use slurp mode to read file content
+ my $old_input_record_separator = $INPUT_RECORD_SEPARATOR;
+ local $INPUT_RECORD_SEPARATOR = undef;
+
+ while (my ($filename, $filedata) = each %{$self->{_output}})
+ {
+ open my $fh, '<', $filename
+ or return "Test failed: file $filename not downloaded\n";
+
+ my $content = <$fh>;
+
+ close $fh or carp $ERRNO;
+
+ my $expected_content = $filedata->{'content'};
+ $expected_content = $self->_substitute_port($expected_content);
+ if ($content ne $expected_content)
+ {
+ return "Test failed: wrong content for file $filename\n"
+ . _show_diff($expected_content, $content);
+ }
+
+ if (exists($filedata->{'timestamp'}))
+ {
+ my (
+ $dev, $ino, $mode, $nlink, $uid,
+ $gid, $rdev, $size, $atime, $mtime,
+ $ctime, $blksize, $blocks
+ )
+ = stat $filename;
+
+ $mtime == $filedata->{'timestamp'}
+ or return "Test failed: wrong timestamp for file $filename: expected = $filedata->{'timestamp'}, actual = $mtime\n";
+ }
+
+ }
+
+ local $INPUT_RECORD_SEPARATOR = $old_input_record_separator;
+
+ # make sure no unexpected files were downloaded
+ chdir "$self->{_workdir}/$self->{_name}/output"
+ or carp "Could not change into output directory: $ERRNO";
+
+ __dir_walk(
+ q{.},
+ sub {
+ if (!(exists $self->{_output}{$_[0]} || $self->{_existing}{$_[0]}))
+ {
+ push @unexpected_downloads, $_[0];
+ }
+ },
+ sub { shift; return @_ }
+ );
+ if (@unexpected_downloads)
+ {
+ return 'Test failed: unexpected downloaded files [' .
+ (join ', ', @unexpected_downloads) . "]\n";
+
+ }
+
+ return q{};
+}
+
+sub __dir_walk
+{
+ my ($top, $filefunc, $dirfunc) = @_;
+
+ my $DIR;
+
+ if (-d $top)
+ {
+ my $file;
+ if (!opendir $DIR, $top)
+ {
+ warn "Couldn't open directory $DIR: $ERRNO; skipping.\n";
+ return;
+ }
+
+ my @results;
+ while ($file = readdir $DIR)
+ {
+ next if $file eq q{.} || $file eq q{..};
+ my $nextdir = $top eq q{.} ? $file : "$top/$file";
+ push @results, __dir_walk($nextdir, $filefunc, $dirfunc);
+ }
+
+ return $dirfunc ? $dirfunc->($top, @results) : ();
+ }
+ else
+ {
+ return $filefunc ? $filefunc->($top) : ();
+ }
+}
+
+sub _fork_and_launch_server
+{
+ my $self = shift;
+
+ pipe FROM_CHILD, TO_PARENT or croak 'Cannot create pipe!';
+ TO_PARENT->autoflush();
+
+ my $pid = fork;
+ if ($pid < 0)
+ {
+ carp 'Cannot fork';
+ }
+ elsif ($pid == 0)
+ {
+
+ # child
+ close FROM_CHILD or carp $ERRNO;
+
+ # FTP Server has to start with english locale due to use of strftime month names in LIST command
+ setlocale(LC_ALL, 'C');
+ $self->_launch_server(
+ sub {
+ print {*TO_PARENT} "SYNC\n";
+ close TO_PARENT or carp $ERRNO;
+ }
+ );
+ }
+ else
+ {
+ # father
+ close TO_PARENT or carp $ERRNO;
+ chomp(my $line = <FROM_CHILD>);
+ close FROM_CHILD or carp $ERRNO;
+ }
+
+ return $pid;
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/certs/README b/tests/certs/README
new file mode 100644
index 0000000..bf77991
--- /dev/null
+++ b/tests/certs/README
@@ -0,0 +1 @@
+If ever needed, 'create-certs.sh' generates all keys, certs and crls.
diff --git a/tests/certs/client-cert.pem b/tests/certs/client-cert.pem
new file mode 100644
index 0000000..b82364b
--- /dev/null
+++ b/tests/certs/client-cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEojCCAwqgAwIBAgIMW+WWpC75FINCVgviMA0GCSqGSIb3DQEBCwUAMFIxDTAL
+BgNVBAMTBFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UE
+CBMIU3Vuc2hpbmUxETAPBgNVBAYTCEZyZWVsYW5kMCAXDTE4MTEwOTE0MTYwNFoY
+Dzk5OTkxMjMxMjM1OTU5WjBSMQ0wCwYDVQQDEwRXZ2V0MQ0wCwYDVQQLEwRXZ2V0
+MQwwCgYDVQQKEwNHTlUxETAPBgNVBAgTCFN1bnNoaW5lMREwDwYDVQQGEwhGcmVl
+bGFuZDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAM9Y7Xzh1QnHbO1q
+7kc/4mK0xhsldkMMD4Zg15dXUww6w1wso4gUv7F3IbJywyd6nTK+5rt+mMPiQaGI
+3pFGS3o2/AvFemrbyw9unifeAWEvioHH0Hsfxk2+M1sToWAgHwSCzEkYt9Vs/LIe
+efQxFTJPsEw4B3Sk+iySZPujsOP6he5kHKSw4QHHJqM4sbaOE3XejFb/IX/eOkH6
++VvW5o0fILIyw0eTFs5sGf6dBj0DMdSyHzo8v3svjSLil5ryE97CYlSHQJLCGKUm
+BVMBhyhBGCzCmL2TdfMy7JY6t+9nvpmpPJ4QEyHMIvnebKFGTpDn+9niJDj6ZWcb
+P2m0yRMB7a6kWAFP8Fk9dCLP0FZQz+qJH/JkKRt7+Kjs5ZMtLJor1UlSJpBVouyz
+Ig0nf1qy92Uv3QoOCqCU3yIxsa3MsV32RSO0S6Ii3MlpF/3Wufgmdd7vRRgsHnq5
+WD9fdNPRxUPin7SmJMJQg4SY4XBPBHNEKVp8d2OlpTw3miZZAQIDAQABo3YwdDAM
+BgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA8GA1UdDwEB/wQFAwMH
+oAAwHQYDVR0OBBYEFG1jBA//1vnWiPseRPqA50QHSGbpMB8GA1UdIwQYMBaAFJ4O
+WyKM+9KPJ1PV1goMyw1ZD2SYMA0GCSqGSIb3DQEBCwUAA4IBgQBovKzuJjbQD7Mk
+GOKj9HQhJeGEvn6MEi1c0o3KWgOm8D2PA78Uq++JJKBxowD7WSCmSNVDltJzDWQO
+FFpIiWkvaOH11JeXhmf4kYsRsSRVlgUEj5SEqZn5lMxX7sIHHr9QmNdFqQgKVM2V
+4qIg233MiOA3RUV6IsP0XgGdhFjqZ61bDyEZ48pdiRhg/iuI0yIiFRnJsthUl3LU
+D0fVgP2/4gTWvUTvVNrR8yH6Ou4bcOovWp+8y5J2KKwMD+6QKKP5DVhZOighdKI+
+v5F3aS1/DbazHs8NFcuuHntDq/gEdjn7IHGcyIhe5NWzExOejTx0yOGX8Q6dTqLw
+UUltfqZk1QsgsBilR9Dk9A7AGy5VonknFvwS+HqUSruR6OwKTsqq6KIlfbpgpkj3
+YiO8BlhhfwG2K9rpdToywZDNS2RKAY1rjjFw3lwiK+qcE6KanJbMKZO9kpstMYlS
+z4E2sTUOL5pfVRPngJrOJwQSUe+JWS55zFpv6bt80VGWNcPkJLY=
+-----END CERTIFICATE-----
diff --git a/tests/certs/client-key.pem b/tests/certs/client-key.pem
new file mode 100644
index 0000000..891082d
--- /dev/null
+++ b/tests/certs/client-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:cf:58:ed:7c:e1:d5:09:c7:6c:ed:6a:ee:47:3f:e2
+ 62:b4:c6:1b:25:76:43:0c:0f:86:60:d7:97:57:53:0c
+ 3a:c3:5c:2c:a3:88:14:bf:b1:77:21:b2:72:c3:27:7a
+ 9d:32:be:e6:bb:7e:98:c3:e2:41:a1:88:de:91:46:4b
+ 7a:36:fc:0b:c5:7a:6a:db:cb:0f:6e:9e:27:de:01:61
+ 2f:8a:81:c7:d0:7b:1f:c6:4d:be:33:5b:13:a1:60:20
+ 1f:04:82:cc:49:18:b7:d5:6c:fc:b2:1e:79:f4:31:15
+ 32:4f:b0:4c:38:07:74:a4:fa:2c:92:64:fb:a3:b0:e3
+ fa:85:ee:64:1c:a4:b0:e1:01:c7:26:a3:38:b1:b6:8e
+ 13:75:de:8c:56:ff:21:7f:de:3a:41:fa:f9:5b:d6:e6
+ 8d:1f:20:b2:32:c3:47:93:16:ce:6c:19:fe:9d:06:3d
+ 03:31:d4:b2:1f:3a:3c:bf:7b:2f:8d:22:e2:97:9a:f2
+ 13:de:c2:62:54:87:40:92:c2:18:a5:26:05:53:01:87
+ 28:41:18:2c:c2:98:bd:93:75:f3:32:ec:96:3a:b7:ef
+ 67:be:99:a9:3c:9e:10:13:21:cc:22:f9:de:6c:a1:46
+ 4e:90:e7:fb:d9:e2:24:38:fa:65:67:1b:3f:69:b4:c9
+ 13:01:ed:ae:a4:58:01:4f:f0:59:3d:74:22:cf:d0:56
+ 50:cf:ea:89:1f:f2:64:29:1b:7b:f8:a8:ec:e5:93:2d
+ 2c:9a:2b:d5:49:52:26:90:55:a2:ec:b3:22:0d:27:7f
+ 5a:b2:f7:65:2f:dd:0a:0e:0a:a0:94:df:22:31:b1:ad
+ cc:b1:5d:f6:45:23:b4:4b:a2:22:dc:c9:69:17:fd:d6
+ b9:f8:26:75:de:ef:45:18:2c:1e:7a:b9:58:3f:5f:74
+ d3:d1:c5:43:e2:9f:b4:a6:24:c2:50:83:84:98:e1:70
+ 4f:04:73:44:29:5a:7c:77:63:a5:a5:3c:37:9a:26:59
+ 01:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 15:5e:52:cb:45:f2:d0:99:2e:ce:a0:f0:81:83:41:ef
+ 6e:35:e4:62:4d:f7:c6:ec:6a:aa:dc:4d:0a:80:d2:87
+ d3:ce:52:03:60:68:d3:00:95:08:71:fd:85:c3:31:cd
+ b5:87:1a:fc:43:a5:b6:ba:40:8d:47:2f:b8:c5:07:ce
+ 46:90:5f:1e:30:e9:86:51:3c:fb:e7:6c:b0:62:70:03
+ 98:40:9b:b9:0e:97:4d:b6:81:5d:85:8b:56:5c:33:b3
+ 3e:a1:c4:2f:dc:4e:45:be:7f:a4:53:a3:b9:d8:bd:18
+ 7c:41:ec:f8:f1:3b:c2:2c:ce:1f:20:2d:16:c7:8a:17
+ 2d:6a:4e:02:ed:ae:14:e2:3c:05:ed:58:50:68:41:e8
+ 1b:83:9d:ee:f1:48:20:87:64:75:9c:49:ca:7f:31:2f
+ 65:ff:d6:9d:88:a6:7d:b0:22:01:de:03:f1:66:cd:2e
+ e1:19:cc:69:8f:74:e7:3e:e8:bd:a0:d4:bd:4f:08:97
+ 77:f8:13:76:1c:c6:2e:2b:3d:93:f0:78:1b:f6:ff:c7
+ 2f:59:8c:57:46:63:93:00:6f:c8:6e:5d:61:7e:f2:78
+ 1a:de:42:2b:61:0c:77:33:a9:ca:57:1b:fa:57:fb:a1
+ 11:fc:62:d1:6d:0b:b4:88:17:4b:b6:df:22:72:52:f0
+ 29:fe:57:07:ed:ab:b3:b1:ce:94:aa:ed:7e:55:56:e2
+ 1c:5b:cd:ce:bd:92:30:a0:29:af:45:13:28:1d:4d:0e
+ 6b:2e:8c:30:04:55:70:d0:af:a0:69:63:38:1b:24:7a
+ 02:e7:7e:a9:05:ee:82:01:23:7c:9d:4a:ef:16:8f:82
+ e5:e3:c8:0e:4e:9b:d0:58:66:9d:3a:e7:f3:68:68:0d
+ 57:f4:a0:26:b0:84:fa:61:60:3b:3c:a7:aa:15:67:7a
+ 5c:dc:ca:9a:18:fc:c3:a9:be:ff:f5:a5:58:9f:75:d4
+ 93:08:f8:23:fd:6e:25:05:23:b6:e2:29:f5:74:d7:81
+
+
+prime1:
+ 00:d3:13:55:70:ff:9d:91:c0:9f:6e:0b:2b:dc:b7:87
+ 94:30:56:4d:01:0d:dc:48:db:39:7d:ec:45:b8:e8:65
+ 76:1c:6c:04:25:f4:42:d0:9b:98:a9:ea:c4:45:05:e9
+ 6f:7e:14:91:76:d5:3a:23:50:e6:77:d3:78:7d:0d:eb
+ b8:f2:bf:b8:14:61:e1:94:f2:1b:f7:cc:67:9b:7b:2c
+ ea:c6:06:fc:b6:9c:ac:c0:4f:be:2e:49:d7:eb:6a:58
+ 4b:16:b5:36:d2:68:06:40:69:6d:3a:71:3e:ec:0d:ac
+ 40:b2:14:ce:09:3e:64:a8:8e:dc:77:ad:c6:b4:6f:7c
+ 69:ab:22:5a:06:fa:8c:b7:37:c2:ed:bd:40:14:98:83
+ 23:50:cd:0d:49:4b:48:70:c5:57:7f:0f:01:ae:5c:6a
+ 98:08:19:56:cc:02:87:d8:d5:17:77:00:67:9e:4d:8d
+ a5:a5:84:d7:31:78:a7:ca:3d:82:0d:d2:c5:48:33:b6
+ d9:
+
+prime2:
+ 00:fb:7a:76:40:d6:d8:08:74:ef:e2:59:d7:da:8a:24
+ 08:d7:57:fb:c5:fc:c9:21:d1:e2:14:48:f1:d4:5a:1d
+ 80:06:27:63:ae:4e:89:40:65:91:04:bc:b0:1f:1e:34
+ e1:96:fa:59:90:9d:96:42:17:b9:c4:ab:a8:8d:3b:3d
+ fc:b4:a5:9f:9a:04:63:c0:d9:4f:99:70:c3:df:da:28
+ 21:76:4b:c6:d6:85:36:4d:7d:f3:a2:8b:42:df:00:d6
+ 41:8d:48:18:f2:75:c8:7b:f6:33:13:c8:4e:91:21:3b
+ 4a:d8:b9:e6:0b:d6:61:c7:70:7d:78:a9:87:4a:90:19
+ 87:34:fa:df:8e:56:dc:92:0e:b0:13:60:90:7a:52:c6
+ 37:d1:a6:93:71:00:1a:dd:e4:ab:5d:b9:d8:2b:16:3c
+ 59:cb:5f:14:04:f7:6d:ab:06:f1:83:4b:92:b2:61:00
+ 73:d1:7e:2f:d4:e0:28:6d:0b:1f:b9:74:2d:e1:7e:ea
+ 69:
+
+coefficient:
+ 00:c0:04:52:12:3b:e6:a3:0a:1a:95:d7:ad:7b:97:af
+ 68:4e:ee:38:4e:88:c3:45:05:d5:bd:5d:69:70:d3:20
+ 90:cd:d3:d9:c3:49:ff:84:dd:36:c0:a0:6b:73:11:f0
+ cb:55:6b:e2:11:76:7c:a3:4a:7e:9c:ac:0f:c9:aa:85
+ 2e:95:f0:cc:07:20:b2:1f:54:2c:e8:20:a6:98:ac:e1
+ 44:ec:e0:00:eb:aa:21:48:bb:45:45:39:6e:66:0c:91
+ 29:32:25:83:f9:c6:34:d1:1b:b2:ac:49:ef:00:c6:19
+ e2:d6:72:50:f8:ac:ff:2c:90:35:0f:1c:ec:35:fe:de
+ 3a:65:12:a0:3e:bd:94:c5:29:95:dd:0d:0e:4d:94:61
+ ff:c3:68:01:6a:89:3c:03:fe:3e:31:80:3a:30:31:9b
+ 01:0f:30:30:97:48:fe:e7:fa:b2:da:02:e1:37:ca:18
+ 34:a3:f8:4d:e8:ac:1b:a0:bb:e2:5d:73:3f:7d:81:79
+ d6:
+
+exp1:
+ 00:98:4f:7c:39:25:0a:d3:d1:16:7a:76:ef:38:be:ea
+ c3:a1:39:b5:29:4c:92:27:b4:a1:c0:df:0c:d4:c8:45
+ e6:bb:cd:aa:14:a5:34:cd:89:69:d9:3b:02:53:f8:57
+ 21:4f:ee:91:a5:19:6a:71:6f:80:4e:f9:37:19:ae:40
+ e9:dd:a9:40:b0:dc:8c:c6:49:0a:ab:7e:41:49:2d:d2
+ 14:bb:be:f0:fe:e9:01:b3:68:17:89:19:5a:08:93:5d
+ 91:19:9a:bc:2b:8a:4a:f0:91:e2:f2:e8:23:0a:7d:37
+ 4e:1b:f2:ed:56:38:42:b4:6b:1a:65:f5:ec:cb:e9:22
+ f2:b1:3e:01:8e:c5:9f:62:da:86:fb:bc:b3:8f:e9:19
+ c0:13:1f:54:36:0e:70:00:88:36:82:06:17:25:75:a4
+ a9:7e:36:a2:ae:66:29:16:eb:75:9a:36:9d:8e:da:d1
+ 9a:b5:5c:ad:58:12:83:a9:69:46:fe:a8:98:19:68:cf
+ c9:
+
+exp2:
+ 00:cd:0f:4e:de:10:52:98:92:c2:09:10:b9:b2:ba:72
+ 27:c3:71:3b:1c:76:c4:8b:8f:59:8a:b0:f0:80:f7:fa
+ 96:2a:6e:74:19:ee:70:7c:d2:55:2e:47:ae:55:b1:8b
+ ed:67:ef:3c:99:6f:e6:d6:7e:02:3d:1c:bc:94:6d:7a
+ 5e:55:ef:b7:f5:1f:1f:38:61:fb:46:63:6d:55:5b:ce
+ dd:7a:58:d0:0a:9d:15:6a:9b:09:cf:c1:3f:06:18:e8
+ 9d:0b:57:7f:00:36:8b:04:89:fd:9c:63:f9:ac:de:2c
+ 3b:1b:fe:7a:57:ac:b8:8e:a8:6b:a7:b8:95:59:77:a7
+ 59:59:1a:38:b1:18:a3:43:76:36:9d:96:60:39:5e:c5
+ c3:3e:71:56:49:0e:8c:d9:e3:5c:d9:50:71:b4:b0:ad
+ 05:8b:90:3c:02:d0:bf:dc:76:0c:f9:c2:e6:1c:0e:7d
+ 0f:f4:03:b1:7d:24:4b:d2:9e:ff:7f:79:fc:ef:a3:4e
+ 01:
+
+
+Public Key PIN:
+ pin-sha256:WiIaPbDgZ234tiqBvORGWeUdOMl96+Vkd/bTbTgWXPU=
+Public Key ID:
+ sha256:5a221a3db0e0676df8b62a81bce44659e51d38c97debe56477f6d36d38165cf5
+ sha1:6d63040fffd6f9d688fb1e44fa80e744074866e9
+
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certs/client-template.txt b/tests/certs/client-template.txt
new file mode 100644
index 0000000..092f367
--- /dev/null
+++ b/tests/certs/client-template.txt
@@ -0,0 +1,23 @@
+# Template file to generate server-cert.pem for certtool (GnuTLS)
+# see 'man certtool' for more options
+
+organization = "GNU"
+unit = "Wget"
+# locality =
+state = "Sunshine"
+country = Freeland
+cn = "Wget"
+#uid = "wget"
+#dc = "name"
+#dc = "domain"
+expiration_days = -1
+#dns_name="127.0.0.1"
+#dns_name="::1"
+#dns_name="localhost"
+#dns_name = "WgetTestingServer"
+#ca
+
+# key options
+signing_key
+encryption_key
+tls_www_client
diff --git a/tests/certs/create-certs.sh b/tests/certs/create-certs.sh
new file mode 100755
index 0000000..8e5f409
--- /dev/null
+++ b/tests/certs/create-certs.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+#create key for CA self-signed certificate
+certtool --generate-privkey --outfile test-ca-key.pem --rsa
+
+#create CA self-signed certificate
+certtool --generate-self-signed --load-privkey test-ca-key.pem --template test-ca-template.txt --outfile test-ca-cert.pem
+
+# create server key
+certtool --generate-privkey --outfile server-key.pem --rsa
+
+# create server certificate
+certtool --generate-certificate --load-privkey server-key.pem --template server-template.txt --outfile server-cert.pem --load-ca-certificate test-ca-cert.pem --load-ca-privkey test-ca-key.pem
+
+# create expired server certificate
+certtool --generate-certificate --load-privkey server-key.pem --template expired-template.txt --outfile expired.pem --load-ca-certificate test-ca-cert.pem --load-ca-privkey test-ca-key.pem
+
+# create not activated server cert
+certtool --generate-certificate --load-privkey server-key.pem --template invalid-template.txt --outfile invalid.pem --load-ca-certificate test-ca-cert.pem --load-ca-privkey test-ca-key.pem
+
+# create client key
+certtool --generate-privkey --outfile client-key.pem --rsa
+
+# create client certificate
+certtool --generate-certificate --load-privkey client-key.pem --template client-template.txt --outfile client-cert.pem --load-ca-certificate test-ca-cert.pem --load-ca-privkey test-ca-key.pem
+
+# create CRL for the server certificate
+certtool --generate-crl --load-ca-privkey test-ca-key.pem --load-ca-certificate test-ca-cert.pem --load-certificate server-cert.pem --outfile revoked-crl.pem --template revoked-template.txt
diff --git a/tests/certs/expired-template.txt b/tests/certs/expired-template.txt
new file mode 100644
index 0000000..ffdef72
--- /dev/null
+++ b/tests/certs/expired-template.txt
@@ -0,0 +1,20 @@
+# Template file to generate expired.pem for certtool (GnuTLS)
+# see 'man certtool' for more options
+
+organization = "GNU"
+unit = "Wget"
+# locality =
+state = "Sunshine"
+country = Freeland
+cn = "WgetTestingServer"
+dns_name = "WgetTestingServer"
+#uid = "wget"
+#dc = "name"
+#dc = "domain"
+activation_date = "2004-02-28 16:21:42"
+expiration_date = "2005-02-28 16:24:41"
+#ca
+
+# key options
+encryption_key
+tls_www_server
diff --git a/tests/certs/expired.pem b/tests/certs/expired.pem
new file mode 100644
index 0000000..4d62237
--- /dev/null
+++ b/tests/certs/expired.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEzTCCAzWgAwIBAgIMW+WWpBQQ7rn1JYOGMA0GCSqGSIb3DQEBCwUAMFIxDTAL
+BgNVBAMTBFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UE
+CBMIU3Vuc2hpbmUxETAPBgNVBAYTCEZyZWVsYW5kMB4XDTA0MDIyODE1MjE0MloX
+DTA1MDIyODE1MjQ0MVowXzEaMBgGA1UEAxMRV2dldFRlc3RpbmdTZXJ2ZXIxDTAL
+BgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UECBMIU3Vuc2hpbmUxETAP
+BgNVBAYTCEZyZWVsYW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA
+sNRnU60QudO+MD8QbYbKtD09cxTCqT7ozRAk5yt5ETwMlGLHBBsEcFDStuwdgXci
+ddoXXulLEvuHSobTCdR0GK0ifCxDRwddvE2heudxZtp5xKUHEb0LFob7boRt1Emu
+HeXLk9U81oUdDmEEyEW0xmKeaPI4cKJ/n4vczLIpH8+rQD/2AJwWSC+OFnUpt78p
+vQzfObKIakr81ckw0G49A6p9OFO7l28AUzwB7UUpnRKllC44FZ5LvsXdK5SQQ44r
+f4do1PjTflC9L9iccSdqq4z+FCL0rwK3Wpw+Ly5HeBGtsfMk88Eg00KeF9Fym5ho
+bcrky5EPFBLhRJ/k4BGnlGnxboFdKK8Gyna7ivAIhvXJ+9sbnfg7FPQ+MEnpqJzq
+i/ziJzC339ruJqYWted/tGlYbPm8M02MmIejGYnMp85v6tnhkToaDKeElAp7E6wC
++/fl3LQyW9vvWdSiVl29sAG1QlVq2IFfprRkRwy7SwsBPTtgIHwm7JyG2kYA/2vB
+AgMBAAGjgZUwgZIwDAYDVR0TAQH/BAIwADAcBgNVHREEFTATghFXZ2V0VGVzdGlu
+Z1NlcnZlcjATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDByAAMB0G
+A1UdDgQWBBSxiQDjENGd3WwSbMM3SdgZqkgNajAfBgNVHSMEGDAWgBSeDlsijPvS
+jydT1dYKDMsNWQ9kmDANBgkqhkiG9w0BAQsFAAOCAYEAMHNHe6JsrZu3J/6Lw6wL
+wh0U7X+er01qPq4Csp4Zrk66eLWt9475TNXGYzDaOv8Yrczx3Lv+Liny73R4/HLi
+P5lMjXwfijFnj6cCzMziLbpxo11cHj7Km7nDequtiUFt80Ug3PEuYoMkY6HpNMHo
+rh5dgTOHjX1q8j/T6s/b46SKr4nEtdX9IdNvWzdxiLTR2EMH5mE0q3Pu+A25N0GG
+ij+L09Fh+qq3BlhqeRYvROO4LqE5VvbS7cpqXnxL/jSLm87CV2/0z7E1ApWSDDvK
+205ORvoE3oc+gOMbpMbKP4dPbXLves+iTQWabWjlMdleTD2eEE7aewH71r7Y8lEn
+LH/lpxIcteasOUNFxet9nBB26L4yVG29t4dhrwqd/lf8tvLV4h79DGJCESocu3Z/
+xkZIZZLWywGuDxrGSvJrcaA6BlSV/8oiGttyaP4XTQ+K4ZHFMCmC3jceXQFPkatq
+bqeIKABNlxsYVk9vDLiPL+8HbBoN0LtHb+KfORGUc9Qi
+-----END CERTIFICATE-----
diff --git a/tests/certs/interca.conf b/tests/certs/interca.conf
new file mode 100644
index 0000000..ec90858
--- /dev/null
+++ b/tests/certs/interca.conf
@@ -0,0 +1,64 @@
+[ ca ]
+default_ca = myca
+
+[ crl_ext ]
+issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+ [ myca ]
+ dir = /home/rincewind/Programming/wget/tests/certs
+ new_certs_dir = ./
+ unique_subject = no
+ certificate = interca.crt
+ database = certindex
+ private_key = interca.key
+ serial = certserial
+ default_days = 730
+ default_md = sha1
+ policy = myca_policy
+ x509_extensions = myca_extensions
+ crlnumber = crlnumber
+ default_crl_days = 730
+
+ [ myca_policy ]
+ commonName = supplied
+ stateOrProvinceName = supplied
+ countryName = optional
+ emailAddress = optional
+ organizationName = supplied
+ organizationalUnitName = optional
+
+ [ myca_extensions ]
+ basicConstraints = critical,CA:TRUE
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [ v3_ca ]
+ basicConstraints = critical,CA:TRUE,pathlen:0
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [alt_names]
+ DNS.0 = WgetTestingServer
+
+ [crl_section]
+ URI.0 = http://intertest.wgettest.org/Bogus.crl
+ URI.1 = http://intertest.wgettest.org/Bogus.crl
+
+ [ocsp_section]
+ caIssuers;URI.0 = http://intertest.wgettest.com/Bogus.crt
+ caIssuers;URI.1 = http://intertest.wgettest.com/Bogus.crt
+ OCSP;URI.0 = http://intertest.wgettest.com/ocsp/
+ OCSP;URI.1 = http://intertest.wgettest.com/ocsp/
diff --git a/tests/certs/interca.conf.in b/tests/certs/interca.conf.in
new file mode 100644
index 0000000..5bf28fd
--- /dev/null
+++ b/tests/certs/interca.conf.in
@@ -0,0 +1,64 @@
+[ ca ]
+default_ca = myca
+
+[ crl_ext ]
+issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+ [ myca ]
+ dir = @abs_srcdir@
+ new_certs_dir = ./
+ unique_subject = no
+ certificate = interca.crt
+ database = certindex
+ private_key = interca.key
+ serial = certserial
+ default_days = 730
+ default_md = sha1
+ policy = myca_policy
+ x509_extensions = myca_extensions
+ crlnumber = crlnumber
+ default_crl_days = 730
+
+ [ myca_policy ]
+ commonName = supplied
+ stateOrProvinceName = supplied
+ countryName = optional
+ emailAddress = optional
+ organizationName = supplied
+ organizationalUnitName = optional
+
+ [ myca_extensions ]
+ basicConstraints = critical,CA:TRUE
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [ v3_ca ]
+ basicConstraints = critical,CA:TRUE,pathlen:0
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [alt_names]
+ DNS.0 = WgetTestingServer
+
+ [crl_section]
+ URI.0 = http://intertest.wgettest.org/Bogus.crl
+ URI.1 = http://intertest.wgettest.org/Bogus.crl
+
+ [ocsp_section]
+ caIssuers;URI.0 = http://intertest.wgettest.com/Bogus.crt
+ caIssuers;URI.1 = http://intertest.wgettest.com/Bogus.crt
+ OCSP;URI.0 = http://intertest.wgettest.com/ocsp/
+ OCSP;URI.1 = http://intertest.wgettest.com/ocsp/
diff --git a/tests/certs/interca.crt b/tests/certs/interca.crt
new file mode 100644
index 0000000..6cbf0ce
--- /dev/null
+++ b/tests/certs/interca.crt
@@ -0,0 +1,41 @@
+-----BEGIN CERTIFICATE-----
+MIIHOTCCBSGgAwIBAgICESMwDQYJKoZIhvcNAQEFBQAwgZkxCzAJBgNVBAYTAlVT
+MQswCQYDVQQIDAJDQTERMA8GA1UEBwwIU2FuIEpvc2UxIDAeBgNVBAoMF1dnZXQg
+VGVzdGluZyBEZXBhcnRtZW50MRAwDgYDVQQLDAdUZXN0aW5nMRQwEgYDVQQDDAtX
+Z2V0VGVzdGluZzEgMB4GCSqGSIb3DQEJARYRYnVncy13Z2V0QGdudS5vcmcwHhcN
+MTcwNTA5MjEyNDMwWhcNMTkwNTA5MjEyNDMwWjBiMR4wHAYDVQQDDBVpY2Etd2dl
+dFRlc3RpbmdTZXJ2ZXIxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzEYMBYGCSqG
+SIb3DQEJARYJaWNhdGVzdGVyMQwwCgYDVQQKDANJbnQwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCpFc5lZraIIP8PVVbnwSrE11p2kjVgzDPwIJ/bDYGd
+60VEMc2ehVOMtj3lFbAUu4nb6j7IbAGB4bUqg4BUVfRodvd2f1WsfAfhf3AUnpI0
+c+ytK8HuXSfv3s44+/iQJftLE0kTADZf9iV/GxdEbhwQXBWku0xU/mxRH4zxDGwZ
+6gurQ96Md6DVUgnZsnRgrukQikr9C5e8cbKj7FHLZgq9E+NlGppmKi8qGTUXK17L
+cLBEP04glOnMuRQKB6SCIoX+VCiw33hWYfzIiXDKFqcj0liYANyLbM9TiFITGyTj
+Jr+Ne1Lac0HlNd8vNeP6IPBjViNZ8Iw3GYly1i8li4THzo8VpXBkJlwOLEYSq9Hr
+ZJ0QzUbyzVTLdhlCBhFme17Z9PxQyBr+2A0Lp+r/oKdr+KfMYZN3tzV3YozSw5d6
+4uV2Nz9pVCmLjR8UAV6cJqJILAxCQRVs4Qs7Ko3mGWKWi3T5xxvFy8gQrNHg7+IN
+g+0OhsIkfHTGsfW7WGukGhfmispi6sjrbNABRws8Vlr7JcVNFS4uu4H3cVCZ3Rde
+9IduNYs0gqss4SYMAxKAz0/M7OCY8Z9obh7zIdsG1A2S07cv9OMsjgPhLiO/i4HF
+RriQtYR5sWZKkmZgmS68aJuh/JLijlF/m2HLbI5gSlgwuSAtKUj2C68mTrXZJ3Xl
+IwIDAQABo4IBvzCCAbswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJNB884gq
+c/+HoMtp4GsuFr1O1eYwHwYDVR0jBBgwFoAUF+2TQ4+npgB11Oi2gg2IN37AbQgw
+CwYDVR0PBAQDAgGmMBMGA1UdJQQMMAoGCCsGAQUFBwMBMF0GA1UdHwRWMFQwKKAm
+oCSGImh0dHA6Ly90ZXN0LndnZXR0ZXN0Lm9yZy9Cb2d1cy5jcmwwKKAmoCSGImh0
+dHA6Ly90ZXN0LndnZXR0ZXN0Lm9yZy9Cb2d1cy5jcmwwHAYDVR0RBBUwE4IRV2dl
+dFRlc3RpbmdTZXJ2ZXIwgcgGCCsGAQUFBwEBBIG7MIG4MC4GCCsGAQUFBzAChiJo
+dHRwOi8vdGVzdC53Z2V0dGVzdC5jb20vQm9ndXMuY3J0MC4GCCsGAQUFBzAChiJo
+dHRwOi8vdGVzdC53Z2V0dGVzdC5jb20vQm9ndXMuY3J0MCoGCCsGAQUFBzABhh5o
+dHRwOi8vdGVzdC53Z2V0dGVzdC5jb20vb2NzcC8wKgYIKwYBBQUHMAGGHmh0dHA6
+Ly90ZXN0LndnZXR0ZXN0LmNvbS9vY3NwLzANBgkqhkiG9w0BAQUFAAOCAgEAqUa7
+cQLhjXCAHiMT9V5+hzB/ngriEKC456htspq9RC/FWnYXZ+au89FehFunjy5qzbSz
+q7N97rCD2drSwn4B6uBymmIxU6iARmtcsPrfhgXHdvhuVop6yuXspoaU7+g1WMXi
+t0RGBx0FahYlggt8a7HnMu3Qz6v8llDeA3U2BCe5ui7mWTauj3bFv/pLW3sigvm0
+Cr3aBHpkIzfHU5D6EC3fKNXQNQruXCCIcBayNiaX+FJcK18sU8tRewiWo/VvffHi
+J89/oHvZnXkteT/mEyeAbjkPkNrmNQTmG69t/x4NdxNDe5ZrEpbEPE/6S5z+YP1T
+bXG7OeES2/+K3Fprwv/oCoeQdv3bBh4IcRhhE7KpEGnJOLfV1a5aRpVCz/0C30xk
+x5GYo0a+AkPAW3zYTaKQXIKDJLpAU6QJ13WaEjVS1EYnUE2o3XEjyZPJVL1y7VSd
+1gdk5MEto6RsVH6EmJBBaSiiAj6d1GbkmNku73FiUvRGk39WbGN9qfjrMPvGhAcL
+0GrIg5oQLOf0f6sdIU3TJkARNSmgSoLV+RatIEgKI+/i6FxlRdBPoGopPJkrh/gS
+stf93A7rFKWmYNKZOMhWXxyv14lwWhBi0bW9QfzavJse047v9X3UvRki06uWXH2t
+H51/0uT9gISqZ1CKDpnez4wrjACuKmfI9D2p6J4=
+-----END CERTIFICATE-----
diff --git a/tests/certs/interca.key b/tests/certs/interca.key
new file mode 100644
index 0000000..7a27172
--- /dev/null
+++ b/tests/certs/interca.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certs/invalid-template.txt b/tests/certs/invalid-template.txt
new file mode 100644
index 0000000..9a8d538
--- /dev/null
+++ b/tests/certs/invalid-template.txt
@@ -0,0 +1,20 @@
+# Template file to generate expired.pem for certtool (GnuTLS)
+# see 'man certtool' for more options
+
+organization = "GNU"
+unit = "Wget"
+# locality =
+state = "Sunshine"
+country = Freeland
+cn = "WgetTestingServer"
+dns_name = "WgetTestingServer"
+#uid = "wget"
+#dc = "name"
+#dc = "domain"
+activation_date = "2035-02-28 16:21:42"
+expiration_date = "2005-02-28 16:24:41"
+#ca
+
+# key options
+encryption_key
+tls_www_server
diff --git a/tests/certs/invalid.pem b/tests/certs/invalid.pem
new file mode 100644
index 0000000..138f816
--- /dev/null
+++ b/tests/certs/invalid.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEzTCCAzWgAwIBAgIMW+WWpBUMPLiaHr/bMA0GCSqGSIb3DQEBCwUAMFIxDTAL
+BgNVBAMTBFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UE
+CBMIU3Vuc2hpbmUxETAPBgNVBAYTCEZyZWVsYW5kMB4XDTM1MDIyODE1MjE0MloX
+DTA1MDIyODE1MjQ0MVowXzEaMBgGA1UEAxMRV2dldFRlc3RpbmdTZXJ2ZXIxDTAL
+BgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UECBMIU3Vuc2hpbmUxETAP
+BgNVBAYTCEZyZWVsYW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA
+sNRnU60QudO+MD8QbYbKtD09cxTCqT7ozRAk5yt5ETwMlGLHBBsEcFDStuwdgXci
+ddoXXulLEvuHSobTCdR0GK0ifCxDRwddvE2heudxZtp5xKUHEb0LFob7boRt1Emu
+HeXLk9U81oUdDmEEyEW0xmKeaPI4cKJ/n4vczLIpH8+rQD/2AJwWSC+OFnUpt78p
+vQzfObKIakr81ckw0G49A6p9OFO7l28AUzwB7UUpnRKllC44FZ5LvsXdK5SQQ44r
+f4do1PjTflC9L9iccSdqq4z+FCL0rwK3Wpw+Ly5HeBGtsfMk88Eg00KeF9Fym5ho
+bcrky5EPFBLhRJ/k4BGnlGnxboFdKK8Gyna7ivAIhvXJ+9sbnfg7FPQ+MEnpqJzq
+i/ziJzC339ruJqYWted/tGlYbPm8M02MmIejGYnMp85v6tnhkToaDKeElAp7E6wC
++/fl3LQyW9vvWdSiVl29sAG1QlVq2IFfprRkRwy7SwsBPTtgIHwm7JyG2kYA/2vB
+AgMBAAGjgZUwgZIwDAYDVR0TAQH/BAIwADAcBgNVHREEFTATghFXZ2V0VGVzdGlu
+Z1NlcnZlcjATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDByAAMB0G
+A1UdDgQWBBSxiQDjENGd3WwSbMM3SdgZqkgNajAfBgNVHSMEGDAWgBSeDlsijPvS
+jydT1dYKDMsNWQ9kmDANBgkqhkiG9w0BAQsFAAOCAYEABiAwqOoIbbA5q3IvEU3X
+qZ9WYemx1AVvUpJY1ft+hYqc6Z/XJfXzHb6xzN6duzpjC5/fER+FTqGk7PpIp17q
+9WAABo+LGM1fEDNvTJ4+v054Yi2qbV151T8xwv5xvMsI6VOx2+fMFBsKYrvoee1i
+NBlyUIoeBjWmauHouXslQY1BKxhNgH7qYVr+LN9cicJEJNgsVcjfGGXOvf8PHMNZ
+YxCEVZDhQ7F7Zqpy+84z8gaEhthZ19tdfuVEW40GX1mOVk6MAWTolKd5EK1CYOS6
+Dtth4yJivopbG4UwMAOQvHq6t1jXAubYXyrVoxMVw0BOCimiGuPWqHYR3rmTgQWS
+ABwsxcc9RtDbF+PcXpqLRSUwTZLjo39xvy2mIAdssE+dKqWPqgIk8+3InJJI/9Fq
+NZaY4p+olmPQUHw8GFrB/jrm8GjGzt0Z+IACcNEr+SD5BSmNKlCe70xyBVfdmwHZ
+o62bYy40zCW8+3lzLQoi+t5PYXIF/ioUJP67EBYkWGf7
+-----END CERTIFICATE-----
diff --git a/tests/certs/revoked-crl.pem b/tests/certs/revoked-crl.pem
new file mode 100644
index 0000000..5b928e2
--- /dev/null
+++ b/tests/certs/revoked-crl.pem
@@ -0,0 +1,16 @@
+-----BEGIN X509 CRL-----
+MIICejCB4wIBATANBgkqhkiG9w0BAQsFADBSMQ0wCwYDVQQDEwRXZ2V0MQ0wCwYD
+VQQLEwRXZ2V0MQwwCgYDVQQKEwNHTlUxETAPBgNVBAgTCFN1bnNoaW5lMREwDwYD
+VQQGEwhGcmVlbGFuZBcNMTgxMTA5MTQxNjA0WhgPOTk5OTEyMzEyMzU5NTlaMB8w
+HQIMW+WWpBMQnOLkjLG8Fw0xODExMDkxNDE2MDRaoDowODAfBgNVHSMEGDAWgBSe
+DlsijPvSjydT1dYKDMsNWQ9kmDAVBgNVHRQEDgIMW+WWpDAhS8Dvbk2wMA0GCSqG
+SIb3DQEBCwUAA4IBgQCNblPk62TVxX2dFmY5IqMGnrBNwIgMehX1q6p5MYEkRGne
+qJ76ZhvNPZMXh+gM5SHzp9zKicRiGQu2RL5lPOJ7FDnmoQrTXxAORFqJUGDa681p
+DMT5bkYkkwNT0+goyinDc+8Zw8DsXPYNO7bi4JcwDtBky5tSt/BPXjfT0Pi5I4Ki
+Gf/sdIIGCYd+s4IlHDtnBn1cz33TDZZ4efEYVKI2uqSihtchDbCLR/TouQB+f9G/
+FL67qeNdE7h+D5MEYyHLwlZ0yMl7Om1kDevKyODWL+wh2+QK8rkdC2YYkDqy20Gc
+jNqUHvGZDGnjh6iwoC2WcStlin45KNaSWEvU9WirYvqxLap4CRDfBXlcI8vuWUZl
+HCovBQBTeuNNVkMShyTWlK82qC3idWWmsGk0UdvUmkR/TOu+RACdeFhyqlu1RXwK
+TC9I7yBCVATs7NGdTCK98PGuqt08IKuqNhZ5qAEk2JR2iF4HoIeIC0hpjJEF3DWi
+PwayMhMirDuyo8yMTHY=
+-----END X509 CRL-----
diff --git a/tests/certs/revoked-template.txt b/tests/certs/revoked-template.txt
new file mode 100644
index 0000000..86cb377
--- /dev/null
+++ b/tests/certs/revoked-template.txt
@@ -0,0 +1,5 @@
+# Template file to generate revoked.crl for certtool (GnuTLS)
+# see 'man certtool' for more options
+
+crl_next_update = -1
+
diff --git a/tests/certs/rootca.conf b/tests/certs/rootca.conf
new file mode 100644
index 0000000..e59c006
--- /dev/null
+++ b/tests/certs/rootca.conf
@@ -0,0 +1,64 @@
+[ ca ]
+default_ca = myca
+
+[ crl_ext ]
+issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+ [ myca ]
+ dir = /home/rincewind/Programming/wget/tests/certs
+ new_certs_dir = ./
+ unique_subject = no
+ certificate = $dir/test-ca-cert.pem
+ database = certindex
+ private_key = $dir/test-ca-key.pem
+ serial = certserial
+ default_days = 730
+ default_md = sha1
+ policy = myca_policy
+ x509_extensions = myca_extensions
+ crlnumber = crlnumber
+ default_crl_days = 730
+
+ [ myca_policy ]
+ commonName = supplied
+ stateOrProvinceName = supplied
+ countryName = optional
+ emailAddress = optional
+ organizationName = supplied
+ organizationalUnitName = optional
+
+ [ myca_extensions ]
+ basicConstraints = critical,CA:TRUE
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [ v3_ca ]
+ basicConstraints = critical,CA:TRUE,pathlen:0
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [alt_names]
+ DNS.0 = WgetTestingServer
+
+ [crl_section]
+ URI.0 = http://test.wgettest.org/Bogus.crl
+ URI.1 = http://test.wgettest.org/Bogus.crl
+
+ [ocsp_section]
+ caIssuers;URI.0 = http://test.wgettest.com/Bogus.crt
+ caIssuers;URI.1 = http://test.wgettest.com/Bogus.crt
+ OCSP;URI.0 = http://test.wgettest.com/ocsp/
+ OCSP;URI.1 = http://test.wgettest.com/ocsp/
diff --git a/tests/certs/rootca.conf.in b/tests/certs/rootca.conf.in
new file mode 100644
index 0000000..ab6e8af
--- /dev/null
+++ b/tests/certs/rootca.conf.in
@@ -0,0 +1,64 @@
+[ ca ]
+default_ca = myca
+
+[ crl_ext ]
+issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+ [ myca ]
+ dir = @abs_srcdir@
+ new_certs_dir = ./
+ unique_subject = no
+ certificate = $dir/test-ca-cert.pem
+ database = certindex
+ private_key = $dir/test-ca-key.pem
+ serial = certserial
+ default_days = 730
+ default_md = sha1
+ policy = myca_policy
+ x509_extensions = myca_extensions
+ crlnumber = crlnumber
+ default_crl_days = 730
+
+ [ myca_policy ]
+ commonName = supplied
+ stateOrProvinceName = supplied
+ countryName = optional
+ emailAddress = optional
+ organizationName = supplied
+ organizationalUnitName = optional
+
+ [ myca_extensions ]
+ basicConstraints = critical,CA:TRUE
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [ v3_ca ]
+ basicConstraints = critical,CA:TRUE,pathlen:0
+ keyUsage = critical,any
+ subjectKeyIdentifier = hash
+ authorityKeyIdentifier = keyid:always,issuer
+ keyUsage = digitalSignature,keyEncipherment,cRLSign,keyCertSign
+ extendedKeyUsage = serverAuth
+ crlDistributionPoints = @crl_section
+ subjectAltName = @alt_names
+ authorityInfoAccess = @ocsp_section
+
+ [alt_names]
+ DNS.0 = WgetTestingServer
+
+ [crl_section]
+ URI.0 = http://test.wgettest.org/Bogus.crl
+ URI.1 = http://test.wgettest.org/Bogus.crl
+
+ [ocsp_section]
+ caIssuers;URI.0 = http://test.wgettest.com/Bogus.crt
+ caIssuers;URI.1 = http://test.wgettest.com/Bogus.crt
+ OCSP;URI.0 = http://test.wgettest.com/ocsp/
+ OCSP;URI.1 = http://test.wgettest.com/ocsp/
diff --git a/tests/certs/selfsigned.crt b/tests/certs/selfsigned.crt
new file mode 100644
index 0000000..41e24e9
--- /dev/null
+++ b/tests/certs/selfsigned.crt
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgIJANAKYgHn6Nk9MA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIDAJDQTEVMBMGA1UEBwwMTXlzdGVyeSBTcG90MQwwCgYD
+VQQKDANEaXMxGjAYBgNVBAMMEVdnZXRUZXN0aW5nU2VydmVyMRUwEwYJKoZIhvcN
+AQkBFgZ0ZXN0ZXIwHhcNMTcwNTA5MjI0OTQ0WhcNMTgwNTA5MjI0OTQ0WjByMQsw
+CQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFTATBgNVBAcMDE15c3RlcnkgU3BvdDEM
+MAoGA1UECgwDRGlzMRowGAYDVQQDDBFXZ2V0VGVzdGluZ1NlcnZlcjEVMBMGCSqG
+SIb3DQEJARYGdGVzdGVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
+2Zc7ZtsoPrlnQLTfMTrfuH7ghL6OrNVPAGpHQ4N+ddJwkF52lQXbeo9JO+09HF7s
+VFnxTG2+0Ld98kcvY3Ylco1Sxl18Bdjzv13sIJtgh7HyuRJ6Ryq2LZGWLKPBaGq1
+G2bBO4nUmsJLjj/1KqKxjk38iJ3Sf02nh8MhRGr8OHFSTMf9pPKW6hibXbsMUVyQ
+2u2RUXbvEtR1rkInWAVhEo97Row0+Z1+ZiqINOcBgpQl0sWh204dZqqi/y3uBbLQ
+3MkenioCb/udLdPRsileVhhwnrq6/0M/YhghMyI9Y+ajQ90h6tM10iyrILYzMCLx
+FB+3iReEJVX7Sy9qaqLJmTttxD7yqReCAxsrdDp1ZmrkQWLRAqBRdZo8RahkfdTu
+wa/fNuwuFFnMC8w/UgCWgDOEH85n4asRNlufYz+GXTsYybiH3klkAe9o09/Cm+zk
+pcX+zcHUkw6aZLC4VbKHNfyKDbWqTMzS66C2Ln4g9p8Zk0KJIvcmVG9uz/zjVIwM
+BWrbEawjMuejy+HUNcaV9CoaBFquwRJd4hlsE6FEryo3k1hEtDancobXl0XLsylU
+SMKMPr6PHjdxt+PdUhL79VNUJT2k35LqLKvtWZAuTOOcfjm0uXSDUC4GvW+onD7L
+n0XB/m4Gqm55EPLnDJgFYdEylvozglg+hSuoywab6NkCAwEAAaNQME4wHQYDVR0O
+BBYEFJF+Iyz8/pwx50cqFXckWIXoat/AMB8GA1UdIwQYMBaAFJF+Iyz8/pwx50cq
+FXckWIXoat/AMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAGRKLYCQ
+W+pdPOF0ojwrufYNbF2qryjJU7OzT7HbdrQOFZ+vcegi5rpZXOsFENTh0gdbI+M3
+FwxDIdyF7CvaRS1uMoTboqaqAzTy+gVVW/6d+UdOdHhJTpduhtQi3gtNvqzdkUpl
+01rX+Da6/jy4kPZfJap3mFPQLVvqVmcvJEcgHVOyB5/23RWS6TSEX35O3De9pnha
+XLqliFBQ/Sqj/2vZmkHBEXdNRfwfw1dHIcxmg25YTb6tyvrKURpXN6suDJEO+M6h
+9IVRv9qCNtvVHpo/xUxwjf7ZBHnGdcGl8AaAoIhRF7JTTGoRX7VAR+DLa5jHMAE2
+BmXzt+HHPMXZiQtzcUUcWc7+a740F8kM03CUMcz8sB4xzovGsZTLJ64afRFP1yaf
++1H7efbrogVjtpGzreWhJ8I5UXO/AoMjwUgyjjHb51KVRn6VrQfDHtw/hrIZVryI
+y8wOH0qzMK2JhB2oh1JvmjhtGxkWlqDztttfglYJENuMf8m/DxsmkSPksSnm8GkA
+El/GdocnZhl8vl8PcqzJ0nNn6EOTiZe+urGxG0r50ckVD+km/J7b56i+Gow46UH3
+Kkp69X9FHDfh3akaeU5chRfH99A/ehtdalD/W5Dy/hA9giA19foPUo6wKBE5unqz
+bfjzK+eNfIkER5JDL6hZQICdjiqa2+IzUnG8
+-----END CERTIFICATE-----
diff --git a/tests/certs/selfsigned.key b/tests/certs/selfsigned.key
new file mode 100644
index 0000000..d6d4a59
--- /dev/null
+++ b/tests/certs/selfsigned.key
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+qNaPYEH/kYsrfWzp/w1WMUpPdbl5iQ==
+-----END PRIVATE KEY-----
diff --git a/tests/certs/server-cert.pem b/tests/certs/server-cert.pem
new file mode 100644
index 0000000..0088749
--- /dev/null
+++ b/tests/certs/server-cert.pem
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE-----
+MIIE3TCCA0WgAwIBAgIMW+WWpBMQnOLkjLG8MA0GCSqGSIb3DQEBCwUAMFIxDTAL
+BgNVBAMTBFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UE
+CBMIU3Vuc2hpbmUxETAPBgNVBAYTCEZyZWVsYW5kMCAXDTE4MTEwOTE0MTYwNFoY
+Dzk5OTkxMjMxMjM1OTU5WjBSMQ0wCwYDVQQDEwRXZ2V0MQ0wCwYDVQQLEwRXZ2V0
+MQwwCgYDVQQKEwNHTlUxETAPBgNVBAgTCFN1bnNoaW5lMREwDwYDVQQGEwhGcmVl
+bGFuZDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALDUZ1OtELnTvjA/
+EG2GyrQ9PXMUwqk+6M0QJOcreRE8DJRixwQbBHBQ0rbsHYF3InXaF17pSxL7h0qG
+0wnUdBitInwsQ0cHXbxNoXrncWbaecSlBxG9CxaG+26EbdRJrh3ly5PVPNaFHQ5h
+BMhFtMZinmjyOHCif5+L3MyyKR/Pq0A/9gCcFkgvjhZ1Kbe/Kb0M3zmyiGpK/NXJ
+MNBuPQOqfThTu5dvAFM8Ae1FKZ0SpZQuOBWeS77F3SuUkEOOK3+HaNT4035QvS/Y
+nHEnaquM/hQi9K8Ct1qcPi8uR3gRrbHzJPPBINNCnhfRcpuYaG3K5MuRDxQS4USf
+5OARp5Rp8W6BXSivBsp2u4rwCIb1yfvbG534OxT0PjBJ6aic6ov84icwt9/a7iam
+FrXnf7RpWGz5vDNNjJiHoxmJzKfOb+rZ4ZE6GgynhJQKexOsAvv35dy0Mlvb71nU
+olZdvbABtUJVatiBX6a0ZEcMu0sLAT07YCB8JuychtpGAP9rwQIDAQABo4GwMIGt
+MAwGA1UdEwEB/wQCMAAwNwYDVR0RBDAwLoIJMTI3LjAuMC4xggM6OjGCCWxvY2Fs
+aG9zdIIRV2dldFRlc3RpbmdTZXJ2ZXIwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYD
+VR0PAQH/BAUDAwegADAdBgNVHQ4EFgQUsYkA4xDRnd1sEmzDN0nYGapIDWowHwYD
+VR0jBBgwFoAUng5bIoz70o8nU9XWCgzLDVkPZJgwDQYJKoZIhvcNAQELBQADggGB
+AKEexGBDmeETUgumcxjYszaDSX3YdAJiKvmzy/9KVn6riOvmjy5x9ilpdOZ0+JHn
+PQhgjkxFNQsq+G6j5RKQGBBklIz/JaUpCWZWCVbnPEMmdsEMWKwAvRRpSbxRt55w
+UChuprPu1A+RWOqggbkB74GaT8BmMacPIMDKo1frSzPmX1a9xaWgiYQiSatJpOOE
+ElcZd4sN1NyrIYNqIj0krxbQ64O8tMg2pPRtVFq1BQT1Kf5mAxusE+pilStGrGAk
+F9J+lDfwKxuIQ3p0uaR6isLGpEtdEe02+vm1zlYh4ER+7xGOuoXPTIS/foIngih+
+JoM8URUVgwyuhdsh7gPGAv8q5OlL3tmur0TZA6dWYMQKRRnw1oZGsw3/I/o4cfXD
+xHHCBTN+V6/A4ZeRKA8qMcLhfr3QrD7/BStLf4/Ylm3V02ZDniOCxBPxkvhSxwYG
+b/+9mPMDVrF5Ls8V+VwdMnPuDLIv7DfGncDvqJXF+iM/t79lrF2D8DfcIqBkbS3M
+JQ==
+-----END CERTIFICATE-----
diff --git a/tests/certs/server-key.pem b/tests/certs/server-key.pem
new file mode 100644
index 0000000..4c26c3a
--- /dev/null
+++ b/tests/certs/server-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:b0:d4:67:53:ad:10:b9:d3:be:30:3f:10:6d:86:ca
+ b4:3d:3d:73:14:c2:a9:3e:e8:cd:10:24:e7:2b:79:11
+ 3c:0c:94:62:c7:04:1b:04:70:50:d2:b6:ec:1d:81:77
+ 22:75:da:17:5e:e9:4b:12:fb:87:4a:86:d3:09:d4:74
+ 18:ad:22:7c:2c:43:47:07:5d:bc:4d:a1:7a:e7:71:66
+ da:79:c4:a5:07:11:bd:0b:16:86:fb:6e:84:6d:d4:49
+ ae:1d:e5:cb:93:d5:3c:d6:85:1d:0e:61:04:c8:45:b4
+ c6:62:9e:68:f2:38:70:a2:7f:9f:8b:dc:cc:b2:29:1f
+ cf:ab:40:3f:f6:00:9c:16:48:2f:8e:16:75:29:b7:bf
+ 29:bd:0c:df:39:b2:88:6a:4a:fc:d5:c9:30:d0:6e:3d
+ 03:aa:7d:38:53:bb:97:6f:00:53:3c:01:ed:45:29:9d
+ 12:a5:94:2e:38:15:9e:4b:be:c5:dd:2b:94:90:43:8e
+ 2b:7f:87:68:d4:f8:d3:7e:50:bd:2f:d8:9c:71:27:6a
+ ab:8c:fe:14:22:f4:af:02:b7:5a:9c:3e:2f:2e:47:78
+ 11:ad:b1:f3:24:f3:c1:20:d3:42:9e:17:d1:72:9b:98
+ 68:6d:ca:e4:cb:91:0f:14:12:e1:44:9f:e4:e0:11:a7
+ 94:69:f1:6e:81:5d:28:af:06:ca:76:bb:8a:f0:08:86
+ f5:c9:fb:db:1b:9d:f8:3b:14:f4:3e:30:49:e9:a8:9c
+ ea:8b:fc:e2:27:30:b7:df:da:ee:26:a6:16:b5:e7:7f
+ b4:69:58:6c:f9:bc:33:4d:8c:98:87:a3:19:89:cc:a7
+ ce:6f:ea:d9:e1:91:3a:1a:0c:a7:84:94:0a:7b:13:ac
+ 02:fb:f7:e5:dc:b4:32:5b:db:ef:59:d4:a2:56:5d:bd
+ b0:01:b5:42:55:6a:d8:81:5f:a6:b4:64:47:0c:bb:4b
+ 0b:01:3d:3b:60:20:7c:26:ec:9c:86:da:46:00:ff:6b
+ c1:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 00:80:07:29:50:a2:2b:4c:00:0c:e1:ad:a7:5d:45:8c
+ 99:f7:04:f8:bf:7d:39:40:bd:19:4b:a9:0c:5e:a3:67
+ 61:0c:d2:9a:b9:f1:35:06:7f:b3:64:fc:df:f3:74:fb
+ 26:ce:21:3b:6e:92:86:b2:95:be:9c:ad:05:3b:46:c1
+ 4f:e4:7a:e5:60:be:cd:3c:7e:17:8a:35:72:61:03:f0
+ 2e:1a:9f:cf:c4:50:89:88:ef:a4:87:82:bb:0b:31:fa
+ ae:c0:22:d2:c4:94:4d:5a:1c:42:af:58:7b:37:ed:90
+ 37:5a:cb:ca:bc:25:35:17:d2:43:57:e6:63:a6:52:b4
+ 1f:8d:a4:15:2b:2d:c1:d5:38:2a:86:3b:a8:54:ae:1f
+ 10:3f:3a:84:9c:a7:b0:b1:14:dd:fe:83:8e:7e:3a:72
+ 9e:a6:df:c6:da:89:25:d9:4e:68:f5:37:87:ec:dd:76
+ 46:3b:f0:0f:8e:b7:c8:46:9b:37:73:2c:cc:81:af:07
+ cd:2d:cd:f5:c8:12:72:55:05:90:d1:bc:2c:bb:c3:5f
+ 60:dd:5f:cf:bc:ff:23:b5:ca:a3:86:29:08:6a:93:ce
+ d2:83:c6:cc:57:bc:18:5a:ce:48:b4:16:f3:55:d2:8a
+ ef:14:d5:14:1d:8b:55:b1:07:9f:f0:29:93:a1:66:85
+ 05:1c:1b:ff:35:ee:fe:c9:6c:40:68:5a:6a:f3:9a:60
+ 5c:7e:fa:f9:ed:24:05:c3:e7:ba:67:9f:f4:f3:a4:35
+ 3c:3c:cb:d9:d1:d0:02:ec:c7:40:fe:e9:33:62:4d:b2
+ 8f:51:1b:a7:da:d7:27:14:18:a8:10:ba:6c:f8:68:73
+ 22:38:34:a3:49:fe:e5:5b:7a:1f:97:87:0b:c4:11:84
+ 5c:19:2a:49:23:fa:e5:15:dc:a6:d2:fd:e4:36:4d:5d
+ ad:b5:fa:7b:ef:84:d6:9c:02:ce:98:e4:fe:12:b4:e3
+ 9d:09:c5:d1:52:93:fb:31:9f:cb:7a:38:96:2e:39:c5
+ e1:
+
+prime1:
+ 00:e4:26:db:d4:9f:04:12:81:66:e6:1c:4e:a3:af:69
+ f6:73:63:87:04:1f:52:53:87:0b:ea:73:7a:e5:b1:43
+ c2:3d:63:c6:f0:57:91:0d:5d:02:e4:02:48:fb:20:d6
+ 2b:38:a9:c1:9c:06:5a:a1:33:2b:c4:74:bb:b5:29:21
+ 15:85:fc:72:f6:e4:96:4b:40:c5:2b:98:c9:00:a7:09
+ dc:60:d9:4d:ae:f4:c1:62:6f:02:49:7a:72:29:e3:ee
+ 61:81:0a:5a:15:99:7d:08:f0:c1:cd:ae:9d:88:df:8f
+ e3:29:ba:18:eb:74:d3:fe:85:9b:71:9f:28:26:9b:d3
+ a1:2c:99:ab:ac:c5:d7:f0:b9:ae:eb:f9:fc:43:e0:04
+ e7:01:7e:82:48:08:45:ef:ed:05:1e:a1:7c:db:be:a3
+ ce:01:48:a9:fc:92:0e:d5:db:1b:81:f1:36:81:8b:85
+ a6:91:4d:e6:05:3b:38:1a:46:4b:4c:05:a0:c2:96:3f
+ dd:
+
+prime2:
+ 00:c6:69:dd:74:26:b1:c2:ee:6f:82:3d:31:0b:f9:f7
+ 40:fb:41:fa:79:d0:04:5c:53:fb:dd:22:2a:d6:b7:26
+ 7f:39:c9:20:a8:31:89:32:f7:56:04:84:7b:6a:c4:ea
+ 9b:8f:29:b3:28:4b:2f:bc:9e:56:0a:3b:b1:53:40:a0
+ 3e:4b:29:07:24:0f:20:05:62:96:c3:df:f5:62:15:dc
+ 0f:5e:53:70:3c:6d:b8:ef:41:b3:97:67:93:db:d1:1b
+ 83:d7:77:63:a4:78:23:95:07:36:0e:d3:50:3d:7a:fa
+ 76:41:72:94:49:ac:8a:ea:97:b2:4f:ff:f6:82:23:f5
+ 5d:3a:bb:f4:0b:06:31:b0:79:b9:5d:e6:29:d2:6f:5a
+ 6c:b6:cb:99:42:d6:74:02:2d:cc:13:03:48:ef:54:ea
+ f8:b7:93:ea:5a:76:11:0b:14:70:a2:08:c3:9c:45:f4
+ 46:cf:74:f4:64:28:4b:e2:a3:3f:35:bc:be:27:7b:4f
+ 35:
+
+coefficient:
+ 4a:53:30:b7:56:5a:d3:2b:40:f0:70:f7:32:54:9b:1a
+ b2:15:40:35:f0:62:65:21:7a:16:6a:2e:ae:81:7e:94
+ 19:58:19:57:d4:b5:c4:84:e1:65:5f:84:3b:50:e0:7f
+ 4e:01:97:74:9f:6c:ed:e4:fa:85:96:17:b3:c4:79:df
+ c4:20:bf:ea:9e:de:b5:aa:99:e4:2f:58:e0:0b:d3:aa
+ 86:e8:5c:1e:8a:8b:69:bb:9d:62:a4:32:63:48:53:cc
+ 19:32:62:2e:30:9a:9f:58:f2:3e:c1:ef:d2:50:a7:cd
+ 89:2b:98:3d:4e:6d:c1:4b:1d:f1:3f:fe:ff:87:fe:5c
+ 16:88:ca:dc:9e:1c:ae:2b:2e:b1:86:ff:90:ee:c1:29
+ d9:12:b3:a8:02:ac:2f:81:85:49:6e:4a:27:10:14:40
+ 27:46:e1:49:b4:31:3a:b5:84:24:45:63:f4:9c:60:a6
+ bc:0f:4a:6d:7a:87:22:e8:9c:bc:10:bb:ad:8d:e9:9a
+
+
+exp1:
+ 32:3d:dc:6b:16:19:6f:79:cf:8f:1c:ec:b4:5f:0c:96
+ 99:12:71:c9:16:9c:aa:88:32:b7:8e:76:a1:de:47:6d
+ 9e:d7:3a:17:f3:30:9e:20:bd:62:38:9e:99:ae:c1:7b
+ 03:1f:5e:e3:5d:02:d8:3c:cc:86:96:ae:3f:56:af:52
+ 6e:0f:09:c2:14:d4:83:fd:df:6d:9a:57:a9:2d:1f:9e
+ c8:35:12:46:54:df:c1:2d:70:f3:7d:63:66:96:2b:08
+ 8d:c2:19:d4:67:d8:80:ff:83:ae:27:a5:c9:5e:71:f1
+ 34:5f:26:dd:b2:fc:7c:30:2f:ea:f5:81:81:ff:0e:bb
+ 8f:76:c7:b7:64:5a:09:48:da:9c:5c:90:90:e1:e4:32
+ 7a:c1:c1:2e:db:a3:8b:12:46:ee:57:e1:87:02:94:4f
+ e9:38:77:36:87:73:7c:e4:a3:4a:1a:34:46:92:d2:fb
+ bb:43:cc:43:9a:a6:e0:22:5a:b2:83:0a:c3:cf:12:81
+
+
+exp2:
+ 00:a9:b9:93:7b:31:42:6c:6a:44:2e:d7:a3:66:08:4c
+ 8e:64:a0:1a:e0:2a:a6:20:48:a3:31:95:71:a9:bc:80
+ 0c:e2:e4:7e:b0:01:b7:c8:46:35:69:a5:de:61:05:d3
+ 5e:80:47:7e:7e:e0:5a:14:72:29:4d:95:a4:69:7f:e5
+ d3:83:bd:b3:e3:0f:a1:27:9a:1f:37:ad:13:9d:f4:ef
+ 0a:a2:78:a3:90:bd:97:2d:eb:38:f2:31:e3:14:6d:3a
+ a9:3c:1e:5f:b9:28:1f:df:f2:8c:36:80:62:aa:44:d1
+ 8d:69:0c:d7:76:72:47:5e:c7:a6:fb:b2:0c:2f:65:0d
+ 15:d4:11:45:80:4c:ab:22:b7:ed:6e:3a:5d:da:29:f0
+ e3:00:37:07:82:5a:2a:60:56:c6:b4:18:e2:42:00:95
+ 03:6f:1d:f3:a1:b0:4f:81:f7:d9:25:72:73:c9:f1:39
+ 35:7d:6f:21:43:b0:08:c1:f5:3d:33:fd:a1:77:ea:8e
+ 65:
+
+
+Public Key PIN:
+ pin-sha256:wBv5do0qlKwMzOKVUIb13Gdlv7BAhyWaX/jgaxcqy2U=
+Public Key ID:
+ sha256:c01bf9768d2a94ac0ccce2955086f5dc6765bfb04087259a5ff8e06b172acb65
+ sha1:b18900e310d19ddd6c126cc33749d819aa480d6a
+
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certs/server-template.txt b/tests/certs/server-template.txt
new file mode 100644
index 0000000..d214e67
--- /dev/null
+++ b/tests/certs/server-template.txt
@@ -0,0 +1,23 @@
+# Template file to generate server-cert.pem for certtool (GnuTLS)
+# see 'man certtool' for more options
+
+organization = "GNU"
+unit = "Wget"
+# locality =
+state = "Sunshine"
+country = Freeland
+cn = "Wget"
+#uid = "wget"
+#dc = "name"
+#dc = "domain"
+expiration_days = -1
+dns_name="127.0.0.1"
+dns_name="::1"
+dns_name="localhost"
+dns_name = "WgetTestingServer"
+#ca
+
+# key options
+signing_key
+encryption_key
+tls_www_server
diff --git a/tests/certs/test-ca-cert.pem b/tests/certs/test-ca-cert.pem
new file mode 100644
index 0000000..ca04457
--- /dev/null
+++ b/tests/certs/test-ca-cert.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEbzCCAtegAwIBAgIMW+WWpAgbVfvBnwynMA0GCSqGSIb3DQEBCwUAMFIxDTAL
+BgNVBAMTBFdnZXQxDTALBgNVBAsTBFdnZXQxDDAKBgNVBAoTA0dOVTERMA8GA1UE
+CBMIU3Vuc2hpbmUxETAPBgNVBAYTCEZyZWVsYW5kMCAXDTE4MTEwOTE0MTYwNFoY
+Dzk5OTkxMjMxMjM1OTU5WjBSMQ0wCwYDVQQDEwRXZ2V0MQ0wCwYDVQQLEwRXZ2V0
+MQwwCgYDVQQKEwNHTlUxETAPBgNVBAgTCFN1bnNoaW5lMREwDwYDVQQGEwhGcmVl
+bGFuZDCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAMUMCfmwSzYFSrbQ
+7C/CbcKVkirAWjFmSVCndYbb4Wbi4kr7+VHU02w6NFRXoQsB7dLwXlpKEuuuVPSc
+FgGUIy450JbQ9QCvqn0Ln+OR25tzAXPFH4975cNTWdv5ZNunh/K688VJ3xtQRZYv
+7YcqW3mrP81VZUKSsPGrlQN3GiwzCRRVPt5db3eG4t/oWfYlLxP3wnRGUaMuTj3g
+Cf1tQAtL0EBr9k2HwrPyIylJEI2u5iDA3XL66uAkWhj0jWyYbydE/BcGpsRnIjpl
+4igvFdEjiJb8dGL9pHVO7i/kAxoTYc45KbI3SUTMMNA1nAVMKrTCX2IbRUh7VrIs
+ohYTxXPOB5dy3lWU/sypdiHFyPt9PO24G3oeXjOQv7oE93bMbYmBisk50zt2csdU
+B89cqAKo7oMXjaZZ3F5ELIaLRsdh7R7qKHVYzqRLuLqitjEr+sY11znfzFpuje6l
+d9PzZHmsiSie8iS2apkqr1KLpkM3zry6+fv3BbjdhRAbyq3LRQIDAQABo0MwQTAP
+BgNVHRMBAf8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBgAwHQYDVR0OBBYEFJ4OWyKM
++9KPJ1PV1goMyw1ZD2SYMA0GCSqGSIb3DQEBCwUAA4IBgQBZvCyOAWWB+/sAyK4y
+Lv34sv2DJijSYsxOWOEJEG8OurbWSl74cmI5YXIswvVI455nnZ4jPQUKZobPL8rO
+uGWrdhJItE7lN8YioswZhJk9VmCxHdk1G2+slHwVddfHIrvrYD7F5MijxAvvijJ8
+tdWprACJGrsoaKu/t129oumjfVy4/1sAVw6S+Jj+vr21Q/3SVnIv0gyTIWhu4cYA
+bzzcDu6+wo4TwjfL/EbgHwFvu0H9PuwgP71xQSFz8+KHvNwxIb65xCgfEVycmuFm
+oDyDMGUu95XG14QKeKOmQlqHd+nkWqcT+NvrcbDkEvnOgaQM3qX5YDokiOpGhY2q
+f7PBiTbYLqP4L5o5qGhWyD3iQvDfTPZKIQA6AX8ZR3T0fVdwUOyiMPkgfYSZ3ZYG
+1kH3TFQk0IkRp5H56ZOfeFd7p3lTpqYMYofYpbG1p763VFuZTIaZJFeCtFaA4ZoY
+lPut92lZl8Igo6iW/tB0JNama558N/T0BJ8QWYSwaRkjyJM=
+-----END CERTIFICATE-----
diff --git a/tests/certs/test-ca-key.pem b/tests/certs/test-ca-key.pem
new file mode 100644
index 0000000..1e64dd6
--- /dev/null
+++ b/tests/certs/test-ca-key.pem
@@ -0,0 +1,182 @@
+Public Key Info:
+ Public Key Algorithm: RSA
+ Key Security Level: High (3072 bits)
+
+modulus:
+ 00:c5:0c:09:f9:b0:4b:36:05:4a:b6:d0:ec:2f:c2:6d
+ c2:95:92:2a:c0:5a:31:66:49:50:a7:75:86:db:e1:66
+ e2:e2:4a:fb:f9:51:d4:d3:6c:3a:34:54:57:a1:0b:01
+ ed:d2:f0:5e:5a:4a:12:eb:ae:54:f4:9c:16:01:94:23
+ 2e:39:d0:96:d0:f5:00:af:aa:7d:0b:9f:e3:91:db:9b
+ 73:01:73:c5:1f:8f:7b:e5:c3:53:59:db:f9:64:db:a7
+ 87:f2:ba:f3:c5:49:df:1b:50:45:96:2f:ed:87:2a:5b
+ 79:ab:3f:cd:55:65:42:92:b0:f1:ab:95:03:77:1a:2c
+ 33:09:14:55:3e:de:5d:6f:77:86:e2:df:e8:59:f6:25
+ 2f:13:f7:c2:74:46:51:a3:2e:4e:3d:e0:09:fd:6d:40
+ 0b:4b:d0:40:6b:f6:4d:87:c2:b3:f2:23:29:49:10:8d
+ ae:e6:20:c0:dd:72:fa:ea:e0:24:5a:18:f4:8d:6c:98
+ 6f:27:44:fc:17:06:a6:c4:67:22:3a:65:e2:28:2f:15
+ d1:23:88:96:fc:74:62:fd:a4:75:4e:ee:2f:e4:03:1a
+ 13:61:ce:39:29:b2:37:49:44:cc:30:d0:35:9c:05:4c
+ 2a:b4:c2:5f:62:1b:45:48:7b:56:b2:2c:a2:16:13:c5
+ 73:ce:07:97:72:de:55:94:fe:cc:a9:76:21:c5:c8:fb
+ 7d:3c:ed:b8:1b:7a:1e:5e:33:90:bf:ba:04:f7:76:cc
+ 6d:89:81:8a:c9:39:d3:3b:76:72:c7:54:07:cf:5c:a8
+ 02:a8:ee:83:17:8d:a6:59:dc:5e:44:2c:86:8b:46:c7
+ 61:ed:1e:ea:28:75:58:ce:a4:4b:b8:ba:a2:b6:31:2b
+ fa:c6:35:d7:39:df:cc:5a:6e:8d:ee:a5:77:d3:f3:64
+ 79:ac:89:28:9e:f2:24:b6:6a:99:2a:af:52:8b:a6:43
+ 37:ce:bc:ba:f9:fb:f7:05:b8:dd:85:10:1b:ca:ad:cb
+ 45:
+
+public exponent:
+ 01:00:01:
+
+private exponent:
+ 5a:0b:d7:5f:28:46:26:88:a2:8d:0a:ca:74:44:d8:9d
+ cc:76:40:5d:28:9a:5c:90:f2:6f:a4:50:9d:98:d2:c8
+ a9:fa:f4:4d:0a:2d:44:f4:b7:60:84:8e:8b:04:99:bc
+ 11:e2:50:6b:d8:5f:ef:1d:fa:aa:d1:cd:68:a9:46:ae
+ 70:33:37:48:84:3d:ed:08:ef:1d:e9:d2:38:2c:70:4c
+ 4d:04:97:b7:85:7d:6c:11:27:bc:ef:be:77:6d:bd:90
+ 6d:c7:2b:71:24:01:f5:dc:68:00:6b:24:93:d9:32:76
+ 56:60:d0:b7:ce:8f:6e:b3:b7:ac:de:6a:f7:f9:98:eb
+ 35:a1:fa:16:c1:cd:57:0b:fb:33:20:79:70:eb:00:31
+ 14:61:eb:95:f1:30:8b:6e:b4:c8:a7:e2:48:d2:ad:2a
+ bc:59:8d:a7:08:a6:83:7c:e1:78:ac:c2:c8:25:ed:69
+ 58:b6:ed:0c:05:e8:4e:7f:61:7d:5e:dc:1a:e8:de:7b
+ 57:d3:ac:05:9b:44:f1:fb:3b:ff:86:15:ae:e4:19:cf
+ 82:cd:2d:ba:59:a8:2a:23:1a:a9:ad:30:55:c8:de:15
+ f4:16:cd:14:17:c3:8b:1b:93:dd:10:8a:6b:72:78:3e
+ fc:73:2e:2f:b9:a5:3c:5e:fc:4e:90:bd:3a:12:79:9d
+ 95:83:87:49:6d:c4:51:ab:d6:15:7f:d2:a5:6b:c0:76
+ d6:0b:75:5c:83:d1:63:14:33:ad:26:43:97:d5:7e:08
+ b8:80:b5:58:ff:b5:1d:eb:7a:1b:2c:e1:54:c9:86:37
+ e9:fc:df:64:83:47:38:02:4c:43:78:93:4f:84:33:35
+ a8:1d:3a:0a:17:63:79:fd:91:be:1c:8c:c6:d9:40:16
+ fa:13:4c:d3:6d:f3:3a:39:65:e9:97:12:5d:6e:eb:9d
+ 07:64:3a:b1:4d:47:9b:82:fb:ff:e1:92:96:9a:f7:a7
+ ec:5a:8a:91:e8:1d:87:21:db:7f:e9:23:53:a8:bc:61
+
+
+prime1:
+ 00:e6:1e:8d:ca:3e:ea:2f:43:8d:71:47:88:e1:5e:57
+ e3:6b:9d:61:45:d6:15:79:b1:ee:21:06:8d:da:66:b7
+ ba:de:b6:0d:68:4e:14:ec:97:30:ec:30:61:2f:ff:6a
+ 49:3d:33:3c:af:30:2e:a3:19:f1:7c:07:49:83:bf:34
+ b3:f8:46:e0:e8:3b:35:46:69:19:c8:05:c4:f5:b7:90
+ 97:01:80:bc:9a:ed:06:ca:a8:e7:c9:55:76:fa:b8:d7
+ b7:38:ec:c2:80:d4:19:77:db:d7:6f:f4:c9:31:21:2d
+ 57:3a:2e:cd:b3:15:bb:1c:07:ae:9f:a8:a8:57:14:8c
+ 2b:5d:2b:84:2f:62:c8:7b:80:04:59:59:08:02:fc:86
+ ef:4d:8f:5a:22:88:71:7b:83:4a:3b:31:11:e3:0d:ae
+ 53:9c:c1:41:d9:1c:66:d4:d9:8c:96:cb:96:ea:42:a0
+ ed:c5:d6:e7:56:c2:40:22:9a:da:8e:1f:87:c7:73:b8
+ 1d:
+
+prime2:
+ 00:db:35:49:d0:b4:9a:10:6c:5d:ce:cd:5b:1f:88:00
+ 8b:a0:5f:40:48:54:9d:a5:15:cc:59:bb:21:f7:11:9e
+ 86:35:1d:45:c6:aa:a1:ae:fe:38:bf:99:58:aa:84:71
+ d4:d8:2c:99:4f:54:1d:cc:e9:95:2b:3a:d8:7b:c4:3a
+ 96:1c:9a:e6:25:1d:1f:9c:60:a7:1d:aa:ff:e9:98:dc
+ 06:7a:97:87:bd:18:19:2a:c8:53:8e:c8:dd:b4:2d:af
+ a9:23:4e:da:82:64:e7:70:41:d6:45:f3:9d:36:2b:ff
+ bb:03:7b:c8:b2:e3:ac:f3:66:6e:f4:51:c0:f3:ca:d0
+ 22:a0:3c:46:af:5e:81:b6:96:51:71:d7:97:67:db:21
+ ca:57:fc:91:04:c0:64:e0:fb:73:f4:2b:b2:f1:c4:49
+ f9:d3:8f:17:74:f6:bc:bc:cc:13:89:6c:0f:0e:5a:45
+ 94:7a:60:0f:d3:ec:e1:ea:3e:2b:fa:af:d3:79:43:87
+ 49:
+
+coefficient:
+ 00:8d:93:8a:53:c5:d3:ad:67:1c:8e:ef:bb:27:db:2c
+ 99:83:7c:a8:9f:a1:a8:23:ce:0e:7e:44:31:03:fd:23
+ 8a:bc:1c:32:85:f3:3b:27:7a:66:5b:a2:38:13:26:4f
+ 11:ed:f4:c3:ce:ad:89:5e:db:ce:a1:2b:3a:69:f6:77
+ 18:57:97:27:d3:2c:cd:9d:21:69:3c:40:ca:e4:df:82
+ 62:d3:aa:88:e2:fe:e9:a8:ca:b3:c9:9d:b4:eb:9a:dc
+ 57:80:62:92:5b:94:76:10:a8:55:44:bf:4e:71:42:84
+ 21:04:f8:d5:ff:aa:85:0f:e9:43:3e:04:33:c2:ef:00
+ 46:e5:62:db:93:89:82:ff:fc:63:0e:09:6d:be:1b:23
+ 6f:52:b9:9e:d5:71:7d:5f:b0:e2:a6:9c:d1:e2:c7:5f
+ 1a:63:a5:9b:54:f7:ff:ae:ae:d0:fc:a1:56:4a:d2:1a
+ 7e:19:3c:a6:40:98:c0:fe:54:2b:ea:50:99:3e:88:f4
+
+
+exp1:
+ 00:ba:89:87:fc:aa:f5:60:ec:cc:8a:48:27:90:30:ce
+ e3:be:47:6c:23:95:40:01:4f:17:ae:53:c6:c7:84:be
+ 68:cf:c2:19:aa:34:a9:47:83:e3:97:82:3c:36:11:40
+ 92:2f:f7:09:b9:25:40:98:dc:1d:e1:a1:72:99:46:74
+ ad:72:93:da:1a:c6:6c:10:30:80:42:a1:52:a0:b0:75
+ 97:c3:13:1d:50:24:d5:7d:90:5f:9b:d8:18:c3:72:f5
+ 02:44:35:c0:11:78:5d:50:c8:b7:a1:bc:77:1e:c9:3b
+ 1c:db:40:37:64:75:38:20:a7:a5:89:2c:c9:91:15:49
+ ee:98:ee:fe:8e:fe:ef:6f:15:3d:f1:43:77:78:1c:46
+ 31:53:d8:e1:82:de:c1:c7:12:8d:28:e0:45:14:9d:f1
+ 73:3b:bd:78:e8:4a:da:9c:ad:e1:06:17:f0:b4:e2:df
+ da:fe:a5:8f:0f:c8:14:ff:38:31:f4:45:60:e6:70:4a
+ 8d:
+
+exp2:
+ 00:a4:06:90:d0:61:83:72:cc:93:b9:1e:02:94:6a:80
+ f5:f9:af:ac:7b:33:0d:af:2c:cb:77:4d:46:92:08:96
+ 15:18:83:69:e5:c9:62:28:7e:43:da:62:95:6d:2a:a3
+ be:bf:6f:47:dc:8b:35:ad:52:0f:73:84:99:de:aa:ab
+ a8:0d:89:7e:b2:c0:c3:19:91:5d:1b:1f:0c:55:30:33
+ 5b:89:b9:ff:30:e8:6a:54:90:07:ae:2c:f1:70:54:4b
+ 40:05:92:88:80:cf:9e:3a:6a:99:3a:48:9b:17:a0:fe
+ bf:62:50:ea:91:a9:39:8d:fb:d5:04:6e:74:32:38:4d
+ 5b:cb:88:ae:df:a4:98:ed:16:37:a5:36:cc:2d:43:54
+ 5a:83:52:12:f5:7a:3d:41:f8:06:00:eb:fd:ff:58:80
+ 7e:36:e6:b8:87:a5:e4:fe:64:ba:2d:b7:34:e0:e9:7d
+ 6d:27:d0:df:a7:15:76:ca:7f:71:0b:29:2b:d5:6e:49
+ 39:
+
+
+Public Key PIN:
+ pin-sha256:JJoOmvj7dwVzA9NdhmQGGH7pyIfyklw0jEoNpxXnfTk=
+Public Key ID:
+ sha256:249a0e9af8fb77057303d35d866406187ee9c887f2925c348c4a0da715e77d39
+ sha1:9e0e5b228cfbd28f2753d5d60a0ccb0d590f6498
+
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certs/test-ca-template.txt b/tests/certs/test-ca-template.txt
new file mode 100644
index 0000000..8f729d7
--- /dev/null
+++ b/tests/certs/test-ca-template.txt
@@ -0,0 +1,20 @@
+# Template file to generate server-cert.pem for certtool (GnuTLS)
+# see 'man certtool' for more options
+
+organization = "GNU"
+unit = "Wget"
+# locality =
+state = "Sunshine"
+country = Freeland
+cn = "Wget"
+#uid = "wget"
+#dc = "name"
+#dc = "domain"
+expiration_days = -1
+ca
+
+# key options
+signing_key
+encryption_key
+cert_signing_key
+crl_signing_key
diff --git a/tests/certs/user.crt b/tests/certs/user.crt
new file mode 100644
index 0000000..f1a6d8c
--- /dev/null
+++ b/tests/certs/user.crt
@@ -0,0 +1,148 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 4388 (0x1124)
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: CN=ica-wgetTestingServer, ST=CA, C=US/emailAddress=icatester, O=Int
+ Validity
+ Not Before: May 9 21:30:44 2017 GMT
+ Not After : May 9 21:30:44 2019 GMT
+ Subject: CN=WgetTestingServer, ST=CA, C=US/emailAddress=usertester, O=Int
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (4096 bit)
+ Modulus:
+ 00:b9:ed:5a:89:c5:8e:20:a2:8d:c6:ee:0c:62:f6:
+ 9a:65:4d:da:3a:04:27:b8:23:cf:8c:1a:5f:1c:79:
+ 09:1a:e5:eb:57:82:f3:48:66:b2:74:bb:95:a4:00:
+ 87:5a:27:88:57:7e:ee:80:87:ec:d2:ca:89:86:53:
+ 0d:79:f6:9c:66:e0:19:ad:78:61:8b:20:9b:3e:da:
+ b4:42:3b:bd:b8:62:f1:0e:40:26:73:f2:e5:eb:6e:
+ 89:de:d7:26:63:11:cf:bc:30:8a:7d:ea:e1:a1:9c:
+ 9e:bc:e8:5c:8a:50:7f:c8:cf:8c:8c:09:e2:ae:1b:
+ 3f:18:1d:54:7e:6a:a8:ed:a9:04:9e:fc:fc:48:47:
+ a7:d5:a3:de:f3:ac:63:4f:40:ee:27:de:02:0d:f8:
+ 6c:fb:98:dc:73:f1:c6:bc:48:7f:fb:f4:3c:8f:7a:
+ 57:7d:ac:76:51:d7:8a:c7:7b:81:65:37:ed:cb:99:
+ f2:c8:6b:8d:88:10:9f:ea:e1:23:58:14:40:0a:bf:
+ 67:f7:8b:e9:cf:56:dd:f8:5c:2e:35:86:a7:fb:20:
+ e0:8f:3c:bb:20:f6:c3:c3:e9:9d:91:67:15:65:50:
+ ba:d9:6a:75:1e:93:a2:cd:66:ed:d0:58:bf:bd:1a:
+ 7f:ed:de:25:ff:03:fa:82:ab:41:52:34:8c:3d:6b:
+ ae:9b:6a:3e:05:2b:3f:87:88:0d:8c:a4:04:0a:cc:
+ b1:f6:0c:02:3b:0c:98:47:6c:1f:a4:0e:d3:ce:ef:
+ 5f:e8:e0:23:64:84:04:64:ad:d0:18:44:b0:93:7c:
+ 43:f5:5a:2f:8d:d6:43:ed:fa:a1:e8:da:42:e2:cb:
+ 56:c5:28:e7:c6:1c:b0:04:3b:23:57:76:7d:20:b4:
+ 30:b1:9c:69:54:7c:45:db:1b:7f:8e:83:a9:89:7c:
+ 59:32:30:9b:70:7e:bc:b3:33:96:89:33:c9:6c:fe:
+ 79:b9:06:ed:6b:e5:70:65:9f:ad:35:e0:13:0c:27:
+ 17:4b:70:67:e3:95:f3:a0:90:b6:fb:06:4a:33:21:
+ 4f:7b:c4:ba:a2:b3:47:bd:cb:3d:88:3e:46:31:27:
+ e3:83:f8:8f:25:54:83:a9:63:a3:1b:33:82:7c:ea:
+ 78:2d:60:10:fe:54:a8:d5:cf:a1:c4:e6:8b:0e:a5:
+ 98:5d:f7:1d:6c:36:35:58:72:9a:81:06:a7:ed:7d:
+ 3a:ae:99:62:4f:af:d2:88:c9:ad:32:b0:55:aa:ce:
+ ee:0e:5d:70:2a:84:a8:ef:66:a5:a4:3c:c4:f1:96:
+ e7:e4:05:7c:8d:c1:a5:ac:7f:54:3c:bd:b3:7e:1d:
+ 31:ad:d5:c2:73:60:db:23:c6:29:9b:d3:f9:4f:d6:
+ 7d:f7:ed
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints: critical
+ CA:TRUE
+ X509v3 Subject Key Identifier:
+ 6F:00:AE:EF:A0:15:4C:5C:1E:A7:B4:6C:8F:5F:1F:DD:EE:C6:6C:11
+ X509v3 Authority Key Identifier:
+ keyid:24:D0:7C:F3:88:2A:73:FF:87:A0:CB:69:E0:6B:2E:16:BD:4E:D5:E6
+
+ X509v3 Key Usage:
+ Digital Signature, Key Encipherment
+ X509v3 Extended Key Usage:
+ TLS Web Server Authentication
+ X509v3 CRL Distribution Points:
+
+ Full Name:
+ URI:http://intertest.wgettest.org/Bogus.crl
+
+ Full Name:
+ URI:http://intertest.wgettest.org/Bogus.crl
+
+ X509v3 Subject Alternative Name:
+ DNS:WgetTestingServer
+ Authority Information Access:
+ CA Issuers - URI:http://intertest.wgettest.com/Bogus.crt
+ CA Issuers - URI:http://intertest.wgettest.com/Bogus.crt
+ OCSP - URI:http://intertest.wgettest.com/ocsp/
+ OCSP - URI:http://intertest.wgettest.com/ocsp/
+
+ Signature Algorithm: sha1WithRSAEncryption
+ 4b:e0:19:75:65:2d:0c:fe:d4:b6:3d:a1:02:8f:3d:89:a6:6b:
+ 12:c6:ee:e3:79:a0:b4:af:fa:15:97:be:35:f7:06:00:39:ba:
+ f9:30:e4:55:d9:98:fc:a5:b7:54:22:52:71:3a:35:d4:3b:9e:
+ 00:1e:5e:bb:8b:4f:21:bd:c7:df:7d:65:4c:cc:32:4e:ab:51:
+ 95:e2:59:b4:09:c2:78:8d:bf:ac:3b:d9:ca:9e:dc:39:ac:95:
+ d2:91:f9:28:31:cd:93:54:db:7a:f3:c8:a2:76:df:a0:b3:8a:
+ e1:00:31:a5:ba:f3:3e:3f:2e:b8:7b:cb:bb:a3:61:83:5f:6a:
+ ee:37:88:2f:89:a5:b6:79:ef:3c:c1:e7:cd:0b:5f:51:d4:de:
+ ab:85:97:f5:8c:8d:d6:59:1e:e6:db:a3:ab:1d:1d:5f:fd:ba:
+ 70:39:97:a1:0f:b4:6d:cc:1d:5d:49:41:9c:12:9e:b3:19:de:
+ 64:ab:83:2f:f3:bf:6f:26:14:e4:be:1a:50:9a:78:22:99:c0:
+ 39:35:ff:b1:45:ea:d3:8f:0d:ed:3d:c2:b0:77:71:26:12:4a:
+ f0:81:83:d7:c9:f2:0c:e8:c2:7b:9b:96:7b:06:ab:e5:ef:ac:
+ e6:34:58:ed:d3:9b:a3:b9:9e:7e:78:16:6e:ba:21:d3:48:01:
+ bc:3e:5f:6e:56:63:cc:4a:f4:e0:12:5e:8b:68:73:b7:3a:0e:
+ 1d:cd:44:15:6e:5c:f4:fd:8e:02:f2:a4:37:ce:08:da:5c:86:
+ 26:57:65:30:5a:13:29:08:ab:0f:f6:a6:ab:99:de:f0:c5:bf:
+ 15:a1:30:ea:23:ca:af:0a:8b:a4:58:8d:12:4f:52:27:fc:52:
+ dc:6d:9a:66:0f:43:c7:28:29:92:92:da:e7:9c:5c:fb:29:e6:
+ 31:06:81:a9:8c:51:86:d2:a2:08:bd:76:fb:61:4b:8e:49:48:
+ 9a:ca:a3:04:6c:dd:59:32:e1:41:f3:09:0b:9b:c0:60:64:34:
+ 87:21:cf:33:bf:17:14:c2:d5:05:0c:4d:21:8a:4d:5e:13:bf:
+ 32:c7:59:bb:48:de:82:15:8e:24:93:4c:c8:8e:e7:12:86:af:
+ 69:5c:5c:d8:a0:90:80:64:74:84:bb:ce:2e:e9:11:06:96:ed:
+ 52:3a:ba:1f:48:a2:13:14:d1:26:e8:a2:13:6d:2e:ec:ad:28:
+ f5:74:da:d7:7e:5e:eb:eb:4b:8d:3d:73:c1:ac:38:20:52:e6:
+ c5:72:fa:7e:e0:6c:fa:21:25:42:f8:fe:3a:1d:0a:4b:c1:ee:
+ 3b:36:61:b9:58:ec:09:4a:4d:4f:51:e5:7c:af:b4:1b:8d:28:
+ 45:e1:67:d1:2c:72:47:7d
+-----BEGIN CERTIFICATE-----
+MIIHHDCCBQSgAwIBAgICESQwDQYJKoZIhvcNAQEFBQAwYjEeMBwGA1UEAwwVaWNh
+LXdnZXRUZXN0aW5nU2VydmVyMQswCQYDVQQIDAJDQTELMAkGA1UEBhMCVVMxGDAW
+BgkqhkiG9w0BCQEWCWljYXRlc3RlcjEMMAoGA1UECgwDSW50MB4XDTE3MDUwOTIx
+MzA0NFoXDTE5MDUwOTIxMzA0NFowXzEaMBgGA1UEAwwRV2dldFRlc3RpbmdTZXJ2
+ZXIxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzEZMBcGCSqGSIb3DQEJARYKdXNl
+cnRlc3RlcjEMMAoGA1UECgwDSW50MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAue1aicWOIKKNxu4MYvaaZU3aOgQnuCPPjBpfHHkJGuXrV4LzSGaydLuV
+pACHWieIV37ugIfs0sqJhlMNefacZuAZrXhhiyCbPtq0Qju9uGLxDkAmc/Ll626J
+3tcmYxHPvDCKferhoZyevOhcilB/yM+MjAnirhs/GB1Ufmqo7akEnvz8SEen1aPe
+86xjT0DuJ94CDfhs+5jcc/HGvEh/+/Q8j3pXfax2UdeKx3uBZTfty5nyyGuNiBCf
+6uEjWBRACr9n94vpz1bd+FwuNYan+yDgjzy7IPbDw+mdkWcVZVC62Wp1HpOizWbt
+0Fi/vRp/7d4l/wP6gqtBUjSMPWuum2o+BSs/h4gNjKQECsyx9gwCOwyYR2wfpA7T
+zu9f6OAjZIQEZK3QGESwk3xD9VovjdZD7fqh6NpC4stWxSjnxhywBDsjV3Z9ILQw
+sZxpVHxF2xt/joOpiXxZMjCbcH68szOWiTPJbP55uQbta+VwZZ+tNeATDCcXS3Bn
+45XzoJC2+wZKMyFPe8S6orNHvcs9iD5GMSfjg/iPJVSDqWOjGzOCfOp4LWAQ/lSo
+1c+hxOaLDqWYXfcdbDY1WHKagQan7X06rpliT6/SiMmtMrBVqs7uDl1wKoSo72al
+pDzE8Zbn5AV8jcGlrH9UPL2zfh0xrdXCc2DbI8Ypm9P5T9Z99+0CAwEAAaOCAd0w
+ggHZMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFG8Aru+gFUxcHqe0bI9fH93u
+xmwRMB8GA1UdIwQYMBaAFCTQfPOIKnP/h6DLaeBrLha9TtXmMAsGA1UdDwQEAwIF
+oDATBgNVHSUEDDAKBggrBgEFBQcDATBnBgNVHR8EYDBeMC2gK6AphidodHRwOi8v
+aW50ZXJ0ZXN0LndnZXR0ZXN0Lm9yZy9Cb2d1cy5jcmwwLaAroCmGJ2h0dHA6Ly9p
+bnRlcnRlc3Qud2dldHRlc3Qub3JnL0JvZ3VzLmNybDAcBgNVHREEFTATghFXZ2V0
+VGVzdGluZ1NlcnZlcjCB3AYIKwYBBQUHAQEEgc8wgcwwMwYIKwYBBQUHMAKGJ2h0
+dHA6Ly9pbnRlcnRlc3Qud2dldHRlc3QuY29tL0JvZ3VzLmNydDAzBggrBgEFBQcw
+AoYnaHR0cDovL2ludGVydGVzdC53Z2V0dGVzdC5jb20vQm9ndXMuY3J0MC8GCCsG
+AQUFBzABhiNodHRwOi8vaW50ZXJ0ZXN0LndnZXR0ZXN0LmNvbS9vY3NwLzAvBggr
+BgEFBQcwAYYjaHR0cDovL2ludGVydGVzdC53Z2V0dGVzdC5jb20vb2NzcC8wDQYJ
+KoZIhvcNAQEFBQADggIBAEvgGXVlLQz+1LY9oQKPPYmmaxLG7uN5oLSv+hWXvjX3
+BgA5uvkw5FXZmPylt1QiUnE6NdQ7ngAeXruLTyG9x999ZUzMMk6rUZXiWbQJwniN
+v6w72cqe3DmsldKR+SgxzZNU23rzyKJ236CziuEAMaW68z4/Lrh7y7ujYYNfau43
+iC+JpbZ57zzB580LX1HU3quFl/WMjdZZHubbo6sdHV/9unA5l6EPtG3MHV1JQZwS
+nrMZ3mSrgy/zv28mFOS+GlCaeCKZwDk1/7FF6tOPDe09wrB3cSYSSvCBg9fJ8gzo
+wnublnsGq+XvrOY0WO3Tm6O5nn54Fm66IdNIAbw+X25WY8xK9OASXotoc7c6Dh3N
+RBVuXPT9jgLypDfOCNpchiZXZTBaEykIqw/2pquZ3vDFvxWhMOojyq8Ki6RYjRJP
+Uif8UtxtmmYPQ8coKZKS2uecXPsp5jEGgamMUYbSogi9dvthS45JSJrKowRs3Vky
+4UHzCQubwGBkNIchzzO/FxTC1QUMTSGKTV4TvzLHWbtI3oIVjiSTTMiO5xKGr2lc
+XNigkIBkdIS7zi7pEQaW7VI6uh9IohMU0SboohNtLuytKPV02td+XuvrS409c8Gs
+OCBS5sVy+n7gbPohJUL4/jodCkvB7js2YblY7AlKTU9R5XyvtBuNKEXhZ9Esckd9
+-----END CERTIFICATE-----
diff --git a/tests/certs/user.key b/tests/certs/user.key
new file mode 100644
index 0000000..5980ffe
--- /dev/null
+++ b/tests/certs/user.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/certs/wgethosts b/tests/certs/wgethosts
new file mode 100644
index 0000000..04b5215
--- /dev/null
+++ b/tests/certs/wgethosts
@@ -0,0 +1 @@
+WgetTestingServer localhost
diff --git a/tests/certs/wotca.pem b/tests/certs/wotca.pem
new file mode 100644
index 0000000..a968cd0
--- /dev/null
+++ b/tests/certs/wotca.pem
@@ -0,0 +1,78 @@
+-----BEGIN CERTIFICATE-----
+MIIHOTCCBSGgAwIBAgICESMwDQYJKoZIhvcNAQEFBQAwgZkxCzAJBgNVBAYTAlVT
+MQswCQYDVQQIDAJDQTERMA8GA1UEBwwIU2FuIEpvc2UxIDAeBgNVBAoMF1dnZXQg
+VGVzdGluZyBEZXBhcnRtZW50MRAwDgYDVQQLDAdUZXN0aW5nMRQwEgYDVQQDDAtX
+Z2V0VGVzdGluZzEgMB4GCSqGSIb3DQEJARYRYnVncy13Z2V0QGdudS5vcmcwHhcN
+MTcwNTA5MjEyNDMwWhcNMTkwNTA5MjEyNDMwWjBiMR4wHAYDVQQDDBVpY2Etd2dl
+dFRlc3RpbmdTZXJ2ZXIxCzAJBgNVBAgMAkNBMQswCQYDVQQGEwJVUzEYMBYGCSqG
+SIb3DQEJARYJaWNhdGVzdGVyMQwwCgYDVQQKDANJbnQwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCpFc5lZraIIP8PVVbnwSrE11p2kjVgzDPwIJ/bDYGd
+60VEMc2ehVOMtj3lFbAUu4nb6j7IbAGB4bUqg4BUVfRodvd2f1WsfAfhf3AUnpI0
+c+ytK8HuXSfv3s44+/iQJftLE0kTADZf9iV/GxdEbhwQXBWku0xU/mxRH4zxDGwZ
+6gurQ96Md6DVUgnZsnRgrukQikr9C5e8cbKj7FHLZgq9E+NlGppmKi8qGTUXK17L
+cLBEP04glOnMuRQKB6SCIoX+VCiw33hWYfzIiXDKFqcj0liYANyLbM9TiFITGyTj
+Jr+Ne1Lac0HlNd8vNeP6IPBjViNZ8Iw3GYly1i8li4THzo8VpXBkJlwOLEYSq9Hr
+ZJ0QzUbyzVTLdhlCBhFme17Z9PxQyBr+2A0Lp+r/oKdr+KfMYZN3tzV3YozSw5d6
+4uV2Nz9pVCmLjR8UAV6cJqJILAxCQRVs4Qs7Ko3mGWKWi3T5xxvFy8gQrNHg7+IN
+g+0OhsIkfHTGsfW7WGukGhfmispi6sjrbNABRws8Vlr7JcVNFS4uu4H3cVCZ3Rde
+9IduNYs0gqss4SYMAxKAz0/M7OCY8Z9obh7zIdsG1A2S07cv9OMsjgPhLiO/i4HF
+RriQtYR5sWZKkmZgmS68aJuh/JLijlF/m2HLbI5gSlgwuSAtKUj2C68mTrXZJ3Xl
+IwIDAQABo4IBvzCCAbswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUJNB884gq
+c/+HoMtp4GsuFr1O1eYwHwYDVR0jBBgwFoAUF+2TQ4+npgB11Oi2gg2IN37AbQgw
+CwYDVR0PBAQDAgGmMBMGA1UdJQQMMAoGCCsGAQUFBwMBMF0GA1UdHwRWMFQwKKAm
+oCSGImh0dHA6Ly90ZXN0LndnZXR0ZXN0Lm9yZy9Cb2d1cy5jcmwwKKAmoCSGImh0
+dHA6Ly90ZXN0LndnZXR0ZXN0Lm9yZy9Cb2d1cy5jcmwwHAYDVR0RBBUwE4IRV2dl
+dFRlc3RpbmdTZXJ2ZXIwgcgGCCsGAQUFBwEBBIG7MIG4MC4GCCsGAQUFBzAChiJo
+dHRwOi8vdGVzdC53Z2V0dGVzdC5jb20vQm9ndXMuY3J0MC4GCCsGAQUFBzAChiJo
+dHRwOi8vdGVzdC53Z2V0dGVzdC5jb20vQm9ndXMuY3J0MCoGCCsGAQUFBzABhh5o
+dHRwOi8vdGVzdC53Z2V0dGVzdC5jb20vb2NzcC8wKgYIKwYBBQUHMAGGHmh0dHA6
+Ly90ZXN0LndnZXR0ZXN0LmNvbS9vY3NwLzANBgkqhkiG9w0BAQUFAAOCAgEAqUa7
+cQLhjXCAHiMT9V5+hzB/ngriEKC456htspq9RC/FWnYXZ+au89FehFunjy5qzbSz
+q7N97rCD2drSwn4B6uBymmIxU6iARmtcsPrfhgXHdvhuVop6yuXspoaU7+g1WMXi
+t0RGBx0FahYlggt8a7HnMu3Qz6v8llDeA3U2BCe5ui7mWTauj3bFv/pLW3sigvm0
+Cr3aBHpkIzfHU5D6EC3fKNXQNQruXCCIcBayNiaX+FJcK18sU8tRewiWo/VvffHi
+J89/oHvZnXkteT/mEyeAbjkPkNrmNQTmG69t/x4NdxNDe5ZrEpbEPE/6S5z+YP1T
+bXG7OeES2/+K3Fprwv/oCoeQdv3bBh4IcRhhE7KpEGnJOLfV1a5aRpVCz/0C30xk
+x5GYo0a+AkPAW3zYTaKQXIKDJLpAU6QJ13WaEjVS1EYnUE2o3XEjyZPJVL1y7VSd
+1gdk5MEto6RsVH6EmJBBaSiiAj6d1GbkmNku73FiUvRGk39WbGN9qfjrMPvGhAcL
+0GrIg5oQLOf0f6sdIU3TJkARNSmgSoLV+RatIEgKI+/i6FxlRdBPoGopPJkrh/gS
+stf93A7rFKWmYNKZOMhWXxyv14lwWhBi0bW9QfzavJse047v9X3UvRki06uWXH2t
+H51/0uT9gISqZ1CKDpnez4wrjACuKmfI9D2p6J4=
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIGBzCCA++gAwIBAgIJAJlGYwAp0+gKMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYD
+VQQGEwJVUzELMAkGA1UECAwCQ0ExETAPBgNVBAcMCFNhbiBKb3NlMSAwHgYDVQQK
+DBdXZ2V0IFRlc3RpbmcgRGVwYXJ0bWVudDEQMA4GA1UECwwHVGVzdGluZzEUMBIG
+A1UEAwwLV2dldFRlc3RpbmcxIDAeBgkqhkiG9w0BCQEWEWJ1Z3Mtd2dldEBnbnUu
+b3JnMB4XDTE3MDQwNjIxMDEyOFoXDTE4MDQwNjIxMDEyOFowgZkxCzAJBgNVBAYT
+AlVTMQswCQYDVQQIDAJDQTERMA8GA1UEBwwIU2FuIEpvc2UxIDAeBgNVBAoMF1dn
+ZXQgVGVzdGluZyBEZXBhcnRtZW50MRAwDgYDVQQLDAdUZXN0aW5nMRQwEgYDVQQD
+DAtXZ2V0VGVzdGluZzEgMB4GCSqGSIb3DQEJARYRYnVncy13Z2V0QGdudS5vcmcw
+ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvHmnQlY58T/PcZeR3ntBp
+6YYELxmYTjrdiHLpa1HvDDkwYyVCaWxhi8R5mP/cUt7aZ0BrNMCVTy5/cEzl/w9R
+VqERKDB68ZU0ku2A4YmDFenlyyUuVZhn5reovUUlhWo8p+Ir+1vwGyDPM/IQKaUJ
+6tfDWVD7fgVzfpvDm8XDqKB6BvzLPk3n3K9mndv2KihTUnnJFMZOkSYaFStQ11Rz
+YwR7ZvAuISB99WZf2hzaYiovB9G0WMky81vpmvjbKWVYLlpV5Inzq2QiG4tFBEP+
+ebLc1H9PGd7vrgGE2cn78g1XXpR8nPUDYF4UGFs90ftPqNDHcHFENB7DrpB7wRIa
+5ZrpKyNbCGIKX+UnVR5Ra32mMM2pPiR95ZDNkqdsygLuHAsyaaj1+wvrmM81H2Jy
+V/kVcFqnf3+C1aX2+hu5OL7rIskEYG8HgWwWxE0NW7Q8zTrBR7D932hM/7f8Yojx
+SeqJP7vpGULeVzJF0CTksoWh+D1s+Q2b93DpoMW18VMTig2NFetQr3DdJmySed7a
+g694qgY5iDv1P/CWBSj75TDBrw3Ji6PJxWES+ox29frxrCWtAjEwVI5zJ5qIZW5n
++BYir/tVloMkYSmeby9eSmTLGENZrepBwuocpvJ1yQRosdzYG42MjfI2JhlTFWvw
+wdGCsFqsRcsfPTJqu801QQIDAQABo1AwTjAdBgNVHQ4EFgQUF+2TQ4+npgB11Oi2
+gg2IN37AbQgwHwYDVR0jBBgwFoAUF+2TQ4+npgB11Oi2gg2IN37AbQgwDAYDVR0T
+BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAewaQ/hmPbjNI7FFNM63M1qnWHK+t
+Zsm5qHWMk5WkcdavsqpexGDc3VxBYFzqqEjlCTseMgsNZ76FENZeNGNFtKScUHuR
+J6Fp+pqEZJ9AoQy8WbkDuFjsKs+En3cMvqy4QUqVOFrKg1PKJEWlqvonMs+apzvJ
+0bjj5Aj2w906XvpKYTnfR6QHJC5ZP5xTorJWLvAwWl0ZuqxQKT0fXKcPeAlE0c4b
+3eJ5jFXPIFkYt0fJcUnZp6QJv608/METl9x+rTYfRsD6kQGC+281C19PxBacTzxH
+fAjsesvP7t7pPlh+Chdd7w1QqFg4UUH9NfIkiq06UtIUoQHfCgT1FvXoFoPiRR5f
+5m67jGE8Sn04nnGhvHnN03kOuwK/VIniLuHdWw0nwLBWIEpzZPbIQQSezoJd7ViY
+2zBJQCtp1ewEDOXecBL+8CNIUXTiFoOxP/YMuLruoYB5dkLpIFbscHp3dZJMScoz
+XJQHh68KH0oRm+/FnK3MLxn56nbwoV4uhdIr5FgLglh7PUfUa2wavFjhi3MY50qD
+SsvoCmBny/N2KJK2tEBIGWbdYy1XBF/l8xaORdT/M4ILYV52Wf2AYy9NTYJxiB0V
+LwVGbG5plMbJiBFDOZcram4pQrG6k21t2Xv2lkVf1AvOlx4qKfUN04TGWXwu5dAP
+pnv5yEwOelBLq7Q=
+-----END CERTIFICATE-----
+
diff --git a/tests/unit-tests.c b/tests/unit-tests.c
new file mode 100644
index 0000000..5f818c7
--- /dev/null
+++ b/tests/unit-tests.c
@@ -0,0 +1,109 @@
+/* Unit testing.
+ Copyright (C) 2005-2011, 2015, 2018-2022 Free Software Foundation,
+ Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget. If not, see <http://www.gnu.org/licenses/>.
+
+Additional permission under GNU GPL version 3 section 7
+
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work. */
+
+#include "wget.h"
+
+#include <stdio.h>
+#ifdef ENABLE_NLS
+# include <locale.h>
+#endif
+
+#include "unit-tests.h"
+
+extern const char *program_argstring;
+
+static int tests_run;
+
+static const char *
+all_tests(void)
+{
+#ifdef HAVE_METALINK
+ mu_run_test (test_find_key_value);
+ mu_run_test (test_find_key_values);
+ mu_run_test (test_has_key);
+#endif
+ mu_run_test (test_parse_content_disposition);
+ mu_run_test (test_parse_range_header);
+ mu_run_test (test_subdir_p);
+ mu_run_test (test_dir_matches_p);
+ mu_run_test (test_commands_sorted);
+ mu_run_test (test_cmd_spec_restrict_file_names);
+ mu_run_test (test_path_simplify);
+ mu_run_test (test_append_uri_pathel);
+ mu_run_test (test_are_urls_equal);
+ mu_run_test (test_is_robots_txt_url);
+#ifdef HAVE_HSTS
+ mu_run_test (test_hsts_new_entry);
+ mu_run_test (test_hsts_url_rewrite_superdomain);
+ mu_run_test (test_hsts_url_rewrite_congruent);
+ mu_run_test (test_hsts_read_database);
+#endif
+ mu_run_test (test_parse_netrc);
+
+ return NULL;
+}
+
+extern const char *program_name; /* Needed by lib/error.c. */
+
+int
+main (int argc _GL_UNUSED, const char *argv[])
+{
+ const char *result;
+
+ printf ("[DEBUG] Testing...\n\n");
+#ifdef ENABLE_NLS
+ /* Set the current locale. */
+ setlocale (LC_ALL, "");
+ /* Set the text message domain. */
+ bindtextdomain ("wget", LOCALEDIR);
+ textdomain ("wget");
+#endif /* ENABLE_NLS */
+
+ program_name = argv[0];
+
+ result = all_tests();
+
+ if (result != NULL)
+ {
+ puts (result);
+ }
+ else
+ {
+ printf ("ALL TESTS PASSED\n");
+ }
+
+ printf ("Tests run: %d\n", tests_run);
+
+ return result != 0;
+}
+
+/*
+ * vim: et ts=2 sw=2
+ */
diff --git a/tests/unit-tests.h b/tests/unit-tests.h
new file mode 100644
index 0000000..8dfe165
--- /dev/null
+++ b/tests/unit-tests.h
@@ -0,0 +1,70 @@
+/* Unit testing declarations.
+ Copyright (C) 2005-2011, 2015, 2018-2022 Free Software Foundation,
+ Inc.
+
+This file is part of GNU Wget.
+
+GNU Wget is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+GNU Wget is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Wget. If not, see <http://www.gnu.org/licenses/>.
+
+Additional permission under GNU GPL version 3 section 7
+
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work. */
+
+#ifndef TEST_H
+#define TEST_H
+
+/* from MinUnit */
+#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
+#define mu_run_test(test) \
+do { \
+ const char *message; \
+ puts("RUNNING TEST " #test "..."); \
+ message = test(); \
+ tests_run++; \
+ if (message) return message; \
+ puts("PASSED\n"); \
+} while (0)
+
+
+const char *test_has_key (void);
+const char *test_find_key_value (void);
+const char *test_find_key_values (void);
+const char *test_parse_content_disposition(void);
+const char *test_parse_range_header(void);
+const char *test_commands_sorted(void);
+const char *test_cmd_spec_restrict_file_names(void);
+const char *test_is_robots_txt_url(void);
+const char *test_path_simplify (void);
+const char *test_append_uri_pathel(void);
+const char *test_are_urls_equal(void);
+const char *test_subdir_p(void);
+const char *test_dir_matches_p(void);
+const char *test_hsts_new_entry(void);
+const char *test_hsts_url_rewrite_superdomain(void);
+const char *test_hsts_url_rewrite_congruent(void);
+const char *test_hsts_read_database(void);
+const char *test_parse_netrc(void);
+
+#endif /* TEST_H */
+
+/*
+ * vim: et ts=2 sw=2
+ */
diff --git a/tests/valgrind-suppressions b/tests/valgrind-suppressions
new file mode 100644
index 0000000..6048a74
--- /dev/null
+++ b/tests/valgrind-suppressions
@@ -0,0 +1,246 @@
+{
+ False positive in libidn.so. More info: https://bugzilla.redhat.com/show_bug.cgi?id=678518
+ Memcheck:Addr4
+ fun:idna_to_ascii_4z
+ fun:idna_to_ascii_8z
+ fun:idn_encode
+ fun:url_parse
+}
+
+{
+ False positive in libidn.so
+ Memcheck:Addr8
+ fun:strncmp
+ fun:is_dst
+ ...
+ fun:fillin_rpath.isra.0
+ fun:decompose_rpath
+ ...
+ fun:openaux
+ fun:_dl_catch_exception
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+}
+
+{
+ False positive in libidn.so
+ Memcheck:Addr16
+ fun:strncmp
+ ...
+ fun:fillin_rpath.isra.0
+ fun:decompose_rpath
+ ...
+ fun:_dl_map_object
+ fun:openaux
+ fun:_dl_catch_exception
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+ fun:_dl_catch_exception
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:modify_param_name
+ fun:extract_param
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:modify_param_name
+ fun:extract_param
+ fun:parse_set_cookie
+ fun:cookie_handle_set_cookie
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:modify_param_name
+ fun:extract_param
+ fun:parse_set_cookie
+ fun:cookie_handle_set_cookie
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Cond
+ fun:memrchr
+ fun:extract_param
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Cond
+ fun:memrchr
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Cond
+ fun:memrchr
+ fun:extract_param
+ fun:parse_set_cookie.constprop.4
+ fun:cookie_handle_set_cookie
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ gnutls-false-positive
+ Memcheck:Cond
+ fun:decode_complex_string.isra.0
+ fun:_gnutls_x509_dn_to_string
+ ...
+}
+
+{
+ gnutls-false-positive
+ Memcheck:Cond
+ ...
+ fun:gnutls_x509_ext_import_subject_alt_names
+ fun:gnutls_x509_crt_import
+ fun:gnutls_x509_crt_list_import
+ fun:gnutls_x509_crt_list_import2
+ fun:gnutls_x509_trust_list_add_trust_mem
+ fun:gnutls_x509_trust_list_add_trust_file
+ fun:gnutls_x509_trust_list_add_system_trust
+}
+
+{
+ gnutls-false-positive
+ Memcheck:Cond
+ ...
+ fun:gnutls_x509_crt_get_dn_by_oid
+ fun:gnutls_x509_crt_check_hostname2
+ fun:ssl_check_certificate
+ fun:establish_connection
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
diff --git a/tests/valgrind-suppressions-ssl b/tests/valgrind-suppressions-ssl
new file mode 100644
index 0000000..48906b5
--- /dev/null
+++ b/tests/valgrind-suppressions-ssl
@@ -0,0 +1,187 @@
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Cond
+ ...
+ obj:*/libcrypto.so.*
+}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Cond
+ ...
+ obj:*/libssl.so.*
+}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Value8
+ ...
+ obj:*/libcrypto.so.*
+}
+
+{
+ <insert_a_suppression_name_here>
+ Memcheck:Param
+ write(buf)
+ ...
+ obj:*/libcrypto.so.*
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:modify_param_name
+ fun:extract_param
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ ...
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:modify_param_name
+ fun:extract_param
+ fun:parse_set_cookie
+ fun:cookie_handle_set_cookie
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ ...
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:modify_param_name
+ fun:extract_param
+ fun:parse_set_cookie
+ fun:cookie_handle_set_cookie
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ ...
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ Valgrind 3.4 bug suppression
+ Memcheck:Cond
+ fun:memrchr
+ fun:parse_content_disposition
+ fun:check_file_output
+ fun:gethttp
+ fun:http_loop
+ fun:retrieve_url
+ fun:main
+}
+
+{
+ gnutls-false-positive
+ Memcheck:Cond
+ fun:decode_complex_string.isra.0
+ fun:_gnutls_x509_dn_to_string
+ ...
+}
+
+{
+ gnutls-false-positive
+ Memcheck:Cond
+ ...
+ fun:gnutls_x509_ext_import_subject_alt_names
+ fun:gnutls_x509_crt_import
+ fun:gnutls_x509_crt_list_import
+ fun:gnutls_x509_crt_list_import2
+ fun:gnutls_x509_trust_list_add_trust_mem
+ fun:gnutls_x509_trust_list_add_trust_file
+ fun:gnutls_x509_trust_list_add_system_trust
+}