summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/ChangeLog871
-rw-r--r--tests/FTPServer.pm802
-rw-r--r--tests/FTPTest.pm61
-rw-r--r--tests/HTTPServer.pm243
-rw-r--r--tests/HTTPTest.pm57
-rw-r--r--tests/Makefile.am139
-rw-r--r--tests/Makefile.in1344
-rwxr-xr-xtests/Test--no-content-disposition-trivial.px56
-rwxr-xr-xtests/Test--no-content-disposition.px57
-rwxr-xr-xtests/Test--spider-fail.px53
-rwxr-xr-xtests/Test--spider-r--no-content-disposition-trivial.px110
-rwxr-xr-xtests/Test--spider-r--no-content-disposition.px111
-rwxr-xr-xtests/Test--spider-r-HTTP-Content-Disposition.px111
-rwxr-xr-xtests/Test--spider-r.px110
-rwxr-xr-xtests/Test--spider.px53
-rwxr-xr-xtests/Test-E-k-K.px90
-rwxr-xr-xtests/Test-E-k.px87
-rwxr-xr-xtests/Test-HTTP-Content-Disposition-1.px77
-rwxr-xr-xtests/Test-HTTP-Content-Disposition-2.px77
-rwxr-xr-xtests/Test-HTTP-Content-Disposition.px57
-rwxr-xr-xtests/Test-N--no-content-disposition-trivial.px49
-rwxr-xr-xtests/Test-N--no-content-disposition.px50
-rwxr-xr-xtests/Test-N-HTTP-Content-Disposition.px51
-rwxr-xr-xtests/Test-N-current.px66
-rwxr-xr-xtests/Test-N-no-info.px64
-rwxr-xr-xtests/Test-N-old.px64
-rwxr-xr-xtests/Test-N-smaller.px67
-rwxr-xr-xtests/Test-N.px49
-rwxr-xr-xtests/Test-O--no-content-disposition-trivial.px47
-rwxr-xr-xtests/Test-O--no-content-disposition.px48
-rwxr-xr-xtests/Test-O-HTTP-Content-Disposition.px48
-rwxr-xr-xtests/Test-O-nc.px47
-rwxr-xr-xtests/Test-O-nonexisting.px47
-rwxr-xr-xtests/Test-O.px47
-rwxr-xr-xtests/Test-Restrict-Lowercase.px56
-rwxr-xr-xtests/Test-Restrict-Uppercase.px56
-rwxr-xr-xtests/Test-auth-basic.px49
-rwxr-xr-xtests/Test-auth-no-challenge-url.px50
-rwxr-xr-xtests/Test-auth-no-challenge.px51
-rw-r--r--tests/Test-auth-retcode.px38
-rwxr-xr-xtests/Test-auth-with-content-disposition.px50
-rwxr-xr-xtests/Test-c-full.px58
-rwxr-xr-xtests/Test-c-partial.px68
-rwxr-xr-xtests/Test-c-shorter.px65
-rwxr-xr-xtests/Test-c.px55
-rwxr-xr-xtests/Test-cookies-401.px53
-rwxr-xr-xtests/Test-cookies.px59
-rwxr-xr-xtests/Test-ftp-bad-list.px69
-rwxr-xr-xtests/Test-ftp-iri-disabled.px52
-rwxr-xr-xtests/Test-ftp-iri-fallback.px48
-rwxr-xr-xtests/Test-ftp-iri-recursive.px48
-rwxr-xr-xtests/Test-ftp-iri.px49
-rwxr-xr-xtests/Test-ftp-pasv-fail.px58
-rwxr-xr-xtests/Test-ftp-recursive.px55
-rwxr-xr-xtests/Test-ftp.px45
-rwxr-xr-xtests/Test-i-ftp.px80
-rwxr-xr-xtests/Test-i-http.px92
-rwxr-xr-xtests/Test-idn-cmd-utf8.px52
-rwxr-xr-xtests/Test-idn-cmd.px52
-rwxr-xr-xtests/Test-idn-headers.px67
-rwxr-xr-xtests/Test-idn-meta.px68
-rwxr-xr-xtests/Test-idn-robots-utf8.px79
-rwxr-xr-xtests/Test-idn-robots.px79
-rwxr-xr-xtests/Test-iri-disabled.px197
-rwxr-xr-xtests/Test-iri-forced-remote.px209
-rwxr-xr-xtests/Test-iri-list.px175
-rwxr-xr-xtests/Test-iri-percent.px88
-rwxr-xr-xtests/Test-iri.px224
-rwxr-xr-xtests/Test-k.px87
-rwxr-xr-xtests/Test-meta-robots.px115
-rwxr-xr-xtests/Test-nonexisting-quiet.px44
-rwxr-xr-xtests/Test-noop.px57
-rwxr-xr-xtests/Test-np.px149
-rwxr-xr-xtests/Test-proxied-https-auth.px129
-rwxr-xr-xtests/Test-proxy-auth-basic.px49
-rwxr-xr-xtests/Test-restrict-ascii.px69
-rw-r--r--tests/WgetFeature.cfg6
-rw-r--r--tests/WgetFeature.pm29
-rw-r--r--tests/WgetTest.pm.in321
-rw-r--r--tests/certs/server-cert.pem22
-rw-r--r--tests/certs/server-key.pem18
-rwxr-xr-xtests/run-px161
82 files changed, 9160 insertions, 0 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog
new file mode 100644
index 0000000..f686c03
--- /dev/null
+++ b/tests/ChangeLog
@@ -0,0 +1,871 @@
+2011-06-03 Merinov Nikolay <kim.roader@gmail.com>
+
+ * Test-idn-cmd-utf8.px: Added test for idn with utf-8 local encoding.
+ * Test-idn-robots-utf8.px: Added test for idn with utf-8 local encoding
+ and robots.txt file.
+ * Makefile.am, run-px: Add new tests.
+2011-04-19 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am (LIBS): Add $(LIB_CLOCK_GETTIME).
+
+2011-04-04 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am (LIBS): Remove @LIBSSL@ @W32LIBS@
+
+2010-10-23 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am (LIBS): Remove @LIBGNUTLS@ and use @W32LIBS@ as last
+ component.
+
+2010-09-12 Mike Frysinger <vapier@gentoo.org>
+
+ Fix some tests failures.
+ * Test-iri-forced-remote.px: Use --trust-server-names to the cmdline
+ variable.
+ * Test-iri-list.px: Likewise.
+ * Test-iri.px: Likewise.
+
+2010-06-04 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Test--no-content-disposition-trivial.px: Use /usr/bin/env to find the
+ perl interpreter.
+ * Test--no-content-disposition.px: Likewise.
+ * Test--spider-fail.px: Likewise.
+ * Test--spider-r--no-content-disposition-trivial.px: Likewise.
+ * Test--spider-r--no-content-disposition.px: Likewise.
+ * Test--spider-r-HTTP-Content-Disposition.px: Likewise.
+ * Test--spider-r.px: Likewise.
+ * Test--spider.px: Likewise.
+ * Test-E-k-K.px: Likewise.
+ * Test-E-k.px: Likewise.
+ * Test-HTTP-Content-Disposition-1.px: Likewise.
+ * Test-HTTP-Content-Disposition-2.px: Likewise.
+ * Test-HTTP-Content-Disposition.px: Likewise.
+ * Test-N--no-content-disposition-trivial.px: Likewise.
+ * Test-N--no-content-disposition.px: Likewise.
+ * Test-N-HTTP-Content-Disposition.px: Likewise.
+ * Test-N-current.px: Likewise.
+ * Test-N-no-info.px: Likewise.
+ * Test-N-old.px: Likewise.
+ * Test-N-smaller.px: Likewise.
+ * Test-N.px: Likewise.
+ * Test-O--no-content-disposition-trivial.px: Likewise.
+ * Test-O--no-content-disposition.px: Likewise.
+ * Test-O-HTTP-Content-Disposition.px: Likewise.
+ * Test-O-nc.px: Likewise.
+ * Test-O-nonexisting.px: Likewise.
+ * Test-O.px: Likewise.
+ * Test-Restrict-Lowercase.px: Likewise.
+ * Test-Restrict-Uppercase.px: Likewise.
+ * Test-auth-basic.px: Likewise.
+ * Test-auth-no-challenge-url.px: Likewise.
+ * Test-auth-no-challenge.px: Likewise.
+ * Test-auth-retcode.px: Likewise.
+ * Test-auth-with-content-disposition.px: Likewise.
+ * Test-c-full.px: Likewise.
+ * Test-c-partial.px: Likewise.
+ * Test-c-shorter.px: Likewise.
+ * Test-c.px: Likewise.
+ * Test-cookies-401.px: Likewise.
+ * Test-cookies.px: Likewise.
+ * Test-ftp-bad-list.px: Likewise.
+ * Test-ftp-iri-disabled.px: Likewise.
+ * Test-ftp-iri-fallback.px: Likewise.
+ * Test-ftp-iri-recursive.px: Likewise.
+ * Test-ftp-iri.px: Likewise.
+ * Test-ftp-pasv-fail.px: Likewise.
+ * Test-ftp-recursive.px: Likewise.
+ * Test-ftp.px: Likewise.
+ * Test-i-ftp.px: Likewise.
+ * Test-i-http.px: Likewise.
+ * Test-idn-cmd.px: Likewise.
+ * Test-idn-headers.px: Likewise.
+ * Test-idn-meta.px: Likewise.
+ * Test-idn-robots.px: Likewise.
+ * Test-iri-disabled.px: Likewise.
+ * Test-iri-forced-remote.px: Likewise.
+ * Test-iri-list.px: Likewise.
+ * Test-iri-percent.px: Likewise.
+ * Test-iri.px: Likewise.
+ * Test-k.px: Likewise.
+ * Test-meta-robots.px: Likewise.
+ * Test-nonexisting-quiet.px: Likewise.
+ * Test-noop.px: Likewise.
+ * Test-np.px: Likewise.
+ * Test-proxied-https-auth.px: Likewise.
+ * Test-proxy-auth-basic.px: Likewise.
+ * Test-restrict-ascii.px: Likewise.
+ Reported by sci-fi@hush.ai.
+
+2010-05-29 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am (EXTRA_DIST): Add Test-auth-retcode.px.
+
+ * run-px (tests): Likewise.
+
+ * Test-auth-retcode.px: New file.
+
+2010-05-16 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am (../md5/libmd5.a): Remove rule.
+ (LDADD): Remove MD5_LDADD.
+
+2010-05-08 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am: Update copyright years.
+
+2010-05-07 Giuseppe Scrivano <gscrivano@gnu.org>
+
+ * Makefile.am (LIBS): Add definition.
+ (LDADD): Add LIBS.
+
+2010-03-01 Steven Schubiger <stsc@member.fsf.org>
+
+ * Test-i-ftp.px: Test --input-file in conjunction with FTP.
+ * run-px, Makefile.am (EXTRA_DIST): Added Test-i-ftp.px.
+
+2010-02-26 Steven Schubiger <stsc@member.fsf.org>
+
+ * Test-i-http.px: Test --input-file in conjunction with HTTP.
+ * run-px, Makefile.am (EXTRA_DIST): Added Test-i-http.px.
+
+2010-02-25 Steven Schubiger <stsc@member.fsf.org>
+
+ * FTPServer.pm (FTPServer::new): Substitute port placeholders
+ in content of files to be retrieved via FTP.
+
+2009-10-14 Steven Schubiger <stsc@member.fsf.org>
+
+ * Test-E-k-K.px, Test-cookies-401.px, Test-ftp-bad-list.px,
+ Test-iri-list.px, Test-iri.px: Removed -d from invocation.
+ Patch by Mike Frysinger.
+
+2009-09-27 Micah Cowan <micah@cowan.name>
+
+ * Test-idn-cmd.px, Test-idn-headers.px, Test-idn-meta.px,
+ Test-idn-robots.px, Test-proxy-auth-basic.px: Removed --debug from
+ invocation (in case it wasn't built with --debug support).
+
+2009-09-24 Micah Cowan <micah@cowan.name>
+
+ * Test-ftp-iri-disabled.px: Fix name "Test-ftp-iri" ->
+ "test-ftp-iri-disabled"
+
+ * Test-ftp-iri-fallback.px: Fix name "Test-ftp-iri" ->
+ "test-ftp-iri-fallback"
+
+2009-09-07 Micah Cowan <micah@cowan.name>
+
+ * run-px: Exit with a failure if there were any tests with
+ "unknown" exit statuses.
+
+ * Test-auth-with-content-disposition.px: New. Test Content-Disposition
+ support when HTTP authentication is required.
+ * run-px, Makefile.am (EXTRA_DIST): Added
+ Test-auth-with-content-disposition.px.
+
+ * FTPServer.pm (FTPServer::run): Pass "server behavior" information to
+ newly-constructed FTPPaths object.
+ (FTPPaths::initialize): Accept "server behavior" hash.
+ (FTPPaths::_format_for_list): If server behavior has "bad_list"
+ set, then always report 0 for the size.
+ * Test-ftp-bad-list.px: Added. Attempts to reproduce bug
+ 22403... but doesn't.
+ * run-px, Makefile.am (EXTRA_DIST): Added Test-ftp-bad-list.px.
+
+2009-09-06 Micah Cowan <micah@cowan.name>
+
+ * WgetTest.pm.in (_setup): Don't expect error codes from
+ _setup_server; none are returned.
+ (quotechar, _show_diff): Added facilities for expounding on where
+ output didn't match expectations.
+ (_verify_download): Use _show_diff.
+
+ * FTPTest.pm (_setup_server): Pass value of server_behavior to
+ FTPServer initialization.
+
+ * Test-ftp-pasv-fail.px: Added.
+ * run-px, Makefile.am (EXTRA_DIST): Added Test-ftp-pasv-fail.px.
+
+ * WgetTest.pm.in: Added "server_behavior" to the set of accepted
+ initialization values.
+ * FTPServer.pm (__open_data_connection): Add "server_behavior" to
+ the set of accepted initialization values.
+ (run): Honor the 'fail_on_pasv' server behavior setting, to
+ trigger the Wget getftp glitch.
+
+2009-09-05 Micah Cowan <micah@cowan.name>
+
+ * Test-ftp-recursive.px: Added.
+ * run-px, Makefile.am (EXTRA_DIST): Added Test-ftp-recursive.px.
+
+ * FTPTest.pm (_setup_server): Don't construct the "input"
+ directory's contents, just pass the URLs structure to
+ FTPServer->new.
+ * FTPServer.pm: Rewrote portions, so that the server now uses the
+ information from the %urls hash directly, rather than reading from
+ real files. Added an FTPPaths package to the file.
+
+2009-09-04 Micah Cowan <micah@cowan.name>
+
+ * WgetTest.pm.in (run): Error-checking improvements.
+
+2009-09-05 Steven Schubiger <stsc@member.fsf.org>
+
+ * run-px: Introduce two new diagnostics: Skip and Unknown.
+
+ * WgetFeature.pm (import): Parse the version output of Wget
+ and assert the availability of a feature.
+
+ * WgetFeature.cfg: Messages to be printed in absence of a
+ required feature.
+
+ * Test-ftp-iri-disabled.px, Test-ftp-iri-fallback.px,
+ Test-ftp-iri-recursive.px, Test-ftp-iri.px, Test-idn-cmd.px,
+ Test-idn-headers.px, Test-idn-meta.px, Test-idn-robots.px,
+ Test-iri-forced-remote.px, Test-iri-list.px,
+ Test-iri-percent.px, Test-iri.px: Use WgetFeature.pm to
+ check for the presence of the IDN/IRI feature.
+
+ * Test-proxied-https-auth.px: Replace grepping for a feature
+ with loading WgetFeature.pm at compile-time.
+
+ * Makefile.am: Add WgetFeature.pm and WgetFeature.cfg
+ to EXTRA_DIST.
+
+2009-09-02 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am (unit-tests): explicit dependency is
+ unnecessary (and harmful, as it overrides the automatic one).
+
+2009-09-01 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am (../src/libunittest.a): Make it a phony target,
+ so we always make sure to get up-to-date unit-test runs.
+
+2009-09-01 Steven Schubiger <stsc@member.fsf.org>
+
+ * Makefile.am: Add Test-cookies.px, Test-cookies-401.px
+ and Test-restrict-ascii.px to EXTRA_DIST.
+
+2009-08-31 Steven Schubiger <stsc@member.fsf.org>
+
+ * Makefile.am: Add Test-k.px to EXTRA_DIST.
+
+2009-08-29 Steven Schubiger <stsc@member.fsf.org>
+
+ * run-px: Add Test-k.px to the list.
+
+ * Test-k.px: Test escaping of semicolons in local file strings.
+
+2009-08-27 Micah Cowan <micah@cowan.name>
+
+ * WgetTest.pm.in (run): Shift the errcode right by 8 binary places.
+
+ * Test--spider-fail.px, Test--spider-r--no-content-disposition.px,
+ Test--spider-r--no-content-disposition-trivial.px,
+ Test--spider-r-HTTP-Content-Disposition.px, Test--spider-r.px,
+ Test-O-nonexisting.px, Test-cookies-401.px,
+ Test-nonexisting-quiet.px: Adjusted "expected error code"; Wget's
+ exit codes have changed.
+
+2009-08-27 Micah Cowan <micah@cowan.name>
+
+ * run-px: Added Test-cookies.px, Test-cookies-401.px
+
+ * Test-cookies.px: Basic testing to make sure Wget doesn't send
+ cookies; no path/domain checking.
+
+ * Test-cookies.px: Test to make sure Wget heeds cookies when they
+ are sent with a 401 response (#26775).
+
+ * HTTPServer.pm (send_response): Don't try to substitute port in
+ response body, if there isn't one.
+ (verify_request_headers): Avoid uninitialized warning when an
+ expected header isn't provided by Wget.
+
+2009-07-27 Micah Cowan <micah@cowan.name>
+
+ * Test-restrict-ascii.px: New.
+
+ * run-px: Added Test-restrict-ascii.px.
+
+2009-07-26 Micah Cowan <micah@cowan.name>
+
+ * Test-ftp-iri.px, Test-ftp-iri-fallback.px,
+ Test-ftp-iri-recursive.px, Test-ftp-iri-disabled.px,
+ Test-idn-cmd.px, Test-idn-robots.px: Adjust wget invocations,
+ replacing --locale with --local-encoding.
+
+2009-07-07 Steven Schubiger <stsc@member.fsf.org>
+
+ * Makefile.am: Add IDN/IRI test files and Test-meta-robots.px
+ to EXTRA_DIST.
+
+2009-07-05 Micah Cowan <micah@cowan.name>
+
+ * Test-meta-robots.px: Added.
+
+ * run-px: Add Test-meta-robots.px to the list.
+
+2009-07-03 Micah Cowan <micah@cowan.name>
+
+ * Test-ftp-iri-disabled.px, Test-iri-disabled.px:
+ --iri=no --> --no-iri
+
+2009-07-01 Micah Cowan <micah@cowan.name>
+
+ * HTTPServer.pm (send_response): Invocation of
+ verify_request_headers, to support testing of Wget-sent header
+ values.
+ (verify_request_headers): Added.
+
+ * Test-iri.px: Added verification checks for Referer values.
+
+2009-06-29 Micah Cowan <micah@cowan.name>
+
+ * WgetTest.pm.in (_cleanup): Allow cleanup of test directories to
+ be skipped at user discretion.
+
+ * run-px, Test-iri-percent.px, Test-ftp-iri-recursive.px: Added
+ test for percent-coded value preservation, FTP recursion when IRI
+ support's on.
+
+2008-12-04 Micah Cowan <micah@cowan.name> (not copyrightable)
+
+ * run-px, Test-idn-robots.px: Added test for robots-file
+ downloads.
+
+ * Test-idn-cmd.px, Test-idn-meta.px, Test-idn-headers.px:
+ Fix test names.
+
+2008-11-26 Micah Cowan <micah@cowan.name> (not copyrightable)
+
+ * Test-ftp-iri-disabled.px, Test-ftp-iri-fallback.px,
+ Test-ftp-iri.px, Test-idn-cmd.px, Test-idn-headers.px,
+ Test-idn-meta.px, Test-iri-disabled.px,
+ Test-iri-forced-remote.px, Test-iri-list.px, Test-iri.px: More
+ module-scope warnings.
+
+2009-06-14 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am (EXTRA_DIST): Include all the tests, run-px, and
+ certs/, to make distcheck happy.
+
+2009-06-11 Benjamin Wolsey <bwy@benjaminwolsey.de>
+
+ * Test-proxied-https-auth.px: Take an optional argument for the
+ top source directory, so we can find the cert and key.
+
+ * run-px: Provide the top source directory as an argument, so
+ scripts can find their way around.
+
+2009-04-11 Steven Schubiger <stsc@member.fsf.org>
+
+ * run-px: Skip testing with real rc files by setting
+ SYSTEM_WGETRC and WGETRC to /dev/null.
+
+2009-02-25 Benjamin Wolsey <bwy@benjaminwolsey.de>
+
+ * Makefile.am (run-px-tests): Ensure run-px is run from srcdir.
+
+ * run-px: Include modules from srcdir.
+
+2008-11-25 Steven Schubiger <stsc@members.fsf.org>
+
+ * WgetTest.pm.in: Remove the magic interpreter line;
+ replace -w with lexical warnings.
+
+2008-11-13 Steven Schubiger <stsc@members.fsf.org>
+
+ * FTPServer.pm, FTPTest.pm, HTTPServer.pm, HTTPTest.pm,
+ WgetTest.pm.in: Clean up leftover whitespace.
+
+2008-11-12 Steven Schubiger <stsc@members.fsf.org>
+
+ * Test-auth-basic.px, Test-auth-no-challenge.px,
+ Test-auth-no-challenge-url.px, Test-c-full.px,
+ Test-c-partial.px, Test-c.px, Test-c-shorter.px,
+ Test-E-k-K.px, Test-E-k.px, Test-ftp.px,
+ Test-HTTP-Content-Disposition-1.px,
+ Test-HTTP-Content-Disposition-2.px,
+ Test-HTTP-Content-Disposition.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-proxy-auth-basic.px, Test-Restrict-Lowercase.px,
+ Test-Restrict-Uppercase.px,
+ Test--spider-fail.pxm, 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: Enforce lexically scoped warnings.
+
+ * Test-proxied-https-auth.px, run-px: Place use strict
+ before use warnings.
+
+2008-11-12 Steven Schubiger <stsc@members.fsf.org>
+
+ * FTPServer.pm, FTPTest.pm, HTTPServer.pm, HTTPTest.pm:
+ Remove the magic interpreter line, because it cannot be
+ used fully. Substitute -w with use warnings.
+
+2008-11-11 Micah Cowan <micah@cowan.name>
+
+ * HTTPServer.pm (handle_auth): Allow testing of
+ --auth-no-challenge.
+
+ * Test-auth-no-challenge.px, Test-auth-no-challenge-url.px:
+ Added.
+
+ * run-px: Add Test-auth-no-challenge.px,
+ Test-auth-no-challenge-url.px.
+
+2008-11-07 Steven Schubiger <stsc@members.fsf.org>
+
+ * run-px: Use some colors for the summary part of the test
+ output to strengthen the distinction between a successful
+ or failing run.
+
+2008-11-06 Steven Schubiger <stsc@members.fsf.org>
+
+ * run-px: When executing test scripts, invoke them with the
+ current perl executable name as determined by env.
+
+2008-11-06 Micah Cowan <micah@cowan.name>
+
+ * run-px: Use strict (thanks Steven Schubiger!).
+
+2008-09-09 Micah Cowan <micah@cowan.name>
+
+ * Test-idn-cmd.px: Added.
+
+ * run-px: Added Test-idn-cmd.px.
+
+2008-08-28 Micah Cowan <micah@cowan.name>
+
+ * HTTPServer.pm (run): Allow distinguishing between hostnames,
+ when used as a proxy.
+
+ * Test-idn-headers.px, Test-idn-meta.px: Added.
+
+ * run-px: Added Test-idn-headers.px, Test-idn-meta.px.
+
+ * Test-proxy-auth-basic.px: Use the full URL, rather than just the
+ path (made necessary by the accompanying change to HTTPServer.pm).
+
+2008-08-14 Xavier Saint <wget@sxav.eu>
+
+ * Test-iri-list.px : Fetch files from a remote list.
+
+2008-08-03 Xavier Saint <wget@sxav.eu>
+
+ * Test-iri.px : HTTP recursive fetch for testing IRI support and
+ fallback.
+
+ * Test-iri-disabled.px : Same file structure as Test-iri.px but with
+ IRI support disabled
+
+ * Test-iri-forced-remote.px : There's a difference between ISO-8859-1
+ and ISO-8859-15 for character 0xA4 (respectively currency sign and
+ euro sign). So with a forced ISO-8859-1 remote encoding, wget should
+ see 0xA4 as a currency sign and transcode it correctly in UTF-8 instead
+ of using the ISO-8859-15 given by the server.
+
+ * Test-ftp-iri.px : Give a file to fetch via FTP in a specific locale
+ and expect wget to fetch the file UTF-8 encoded.
+
+ * Test-ftp-iri-fallback.px : Same as above but wget should fallback on
+ locale encoding to fetch the file.
+
+ * Test-ftp-iri.px : Same as Test-ftp-iri.px but with IRI support
+ disabled. The UTF-8 encoded file should not be retrieved.
+
+2008-06-22 Micah Cowan <micah@cowan.name>
+
+ * Test-proxied-https-auth.px: Shift exit code so it falls in the
+ lower bits, and actually fails when it should. Use dynamic port,
+ instead of static port. Only run the test if our Wget was built
+ with HTTPS support.
+
+ * certs/server-cert.pem, certs/server-key.pem: Apparently failed
+ to add these from 1.11.x repo. Fixed.
+
+2008-06-12 Micah Cowan <micah@cowan.name>
+
+ * FTPServer.pm, FTPTest.pm, HTTPServer.pm, HTTPTest.pm,
+ Test--no-content-disposition-trivial.px,
+ Test--no-content-disposition.px, Test--spider-fail.px,
+ Test--spider-r--no-content-disposition-trivial.px,
+ Test--spider-r--no-content-disposition.px,
+ Test--spider-r-HTTP-Content-Disposition.px, Test--spider-r.px,
+ Test--spider.px, Test-E-k-K.px, Test-E-k.px,
+ Test-HTTP-Content-Disposition-1.px,
+ Test-HTTP-Content-Disposition-2.px,
+ Test-HTTP-Content-Disposition.px,
+ Test-N--no-content-disposition-trivial.px,
+ Test-N--no-content-disposition.px,
+ Test-N-HTTP-Content-Disposition.px, Test-N-current.px,
+ Test-N-no-info.px, Test-N-old.px, Test-N-smaller.px, Test-N.px,
+ Test-O--no-content-disposition-trivial.px,
+ Test-O--no-content-disposition.px,
+ Test-O-HTTP-Content-Disposition.px, Test-O-nonexisting.px,
+ Test-O.px, Test-Restrict-Lowercase.px,
+ Test-Restrict-Uppercase.px, Test-auth-basic.px, Test-c-full.px,
+ Test-c-partial.px, Test-c.px, Test-ftp.px,
+ Test-nonexisting-quiet.px, Test-noop.px, Test-np.px,
+ Test-proxied-https-auth.px, Test-proxy-auth-basic.px,
+ WgetTest.pm.in: Use whatever ports are available, rather than
+ hard-coded ones.
+
+ * run-px: More summary info, explicit exit code.
+
+ * Makefile.am: Reinstate "run-px-tests" as a dependency for the
+ "check" target.
+
+ * WgetTest.pm.in: Draw more attention to the fact that
+ WgetTest.pm is a generated file.
+
+ * Test-proxied-https-auth.px: Better cleanup, so next test can
+ open the port.
+
+2008-05-31 Micah Cowan <micah@cowan.name>
+
+ * Test-N-current.px: Ensure we catch failures.
+
+ * Test-N-old.px: Make it test only the timestamp, and not the
+ content length in addition.
+
+ * Test-N-smaller.px, Test-N-no-info.px: added.
+
+ * Test-c-partial.px: Improve checking that the file was
+ partially retrieved, rather than overwritten.
+
+ * run-px: Added Test-N-smaller.px, Test-N-no-info.px.
+
+ * HTTPServer.pm: Return 416 for fully-retrieved content, rather
+ than 206 with a zero content-length.
+
+2008-05-23 Micah Cowan <micah@cowan.name>
+
+ * Test--spider.px: Make test expect 0 return code.
+
+2008-05-22 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am (run-px-tests): Replaced ugly list of tests with
+ run-px Perl script to manage running them.
+
+ * run-px: Added.
+
+ * FTPServer.pm (run): Avoid re-forking. Fixes bug #20458.
+
+2008-04-26 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am, Test-proxied-https-auth.px: Added a test for
+ accessing password-protected HTTPS URLs through a proxy (via
+ CONNECT).
+
+2008-04-10 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am, Test-proxy-auth-basic.px: Added a test for
+ accessing password-protected URLs through a proxy.
+
+2008-01-25 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am: Updated copyright year.
+
+2008-01-23 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am: Add libmd5 to unit-tests.
+
+2007-11-28 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am: Updated license exception for OpenSSL, per the
+ SFLC.
+
+2007-10-18 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am: Add dependency for unit_tests on libgnu.a.
+
+2007-10-05 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ * WgetTest.pm.in: wget is built in the build tree. Use an
+ absolute path to the binary.
+ * Makefile.in: Removed, replaced by Makefile.am.
+ * Makefile.am: Converted from Makefile.in.
+
+2007-09-25 Micah Cowan <micah@cowan.name>
+
+ * Makefile.in: Use EXEEXT instead of exeext.
+
+2007-08-21 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * WgetTest.pm.in: Added support for timestamping of pre-existing
+ files.
+
+ * Test-N-current.px: Fixed broken test logic.
+
+ * Makefile.in: Updated list of automatically run tests.
+
+ * Test-HTTP-Content-Disposition.px: Added -e contentdisposition=on
+ option, since now HTTP Content-Disposition header support is turned
+ off by default.
+
+ * Test-HTTP-Content-Disposition-1.px: Ditto.
+
+2007-08-10 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test--spider--no-content-disposition-trivial.px: Added new tests for
+ validation of HTTP Content-Disposition header support logic. In
+ particular, these tests check wget's behavior for every combination of
+ --spider [-r] and -e contentdisposition=on/off options.
+
+ * Test--spider-r-HTTP-Content-Disposition.px: Ditto.
+
+ * Test--spider-HTTP-Content-Disposition.px: Ditto.
+
+ * Test--spider--no-content-disposition.px: Ditto.
+
+ * Test--spider-r--no-content-disposition-trivial.px: Ditto.
+
+ * Test--spider-r--no-content-disposition.px: Ditto.
+
+2007-07-25 Micah Cowan <micah@cowan.name>
+
+ * HTTPServer.pm (run, send_response): Farmed out some logic from
+ the run method into a separate one named send_response, which
+ was then modified to handle simple authentication testing.
+ (handle_auth): Added to handle simple authentication testing.
+ (verify_auth_basic): Checks to make sure Basic credentials are
+ valid.
+ (verify_auth_digest): Stub added; always fails test.
+ * Makefile.in: Added Test-auth-basic.px to list of automatically
+ run tests.
+ * Test-auth-basic: Simple basic authentication test; mainly just
+ lets the server do its testing. Its current purpose is just to
+ ensure that correct basic creds are sent, but never until a
+ challenge has been sent.
+
+2007-07-10 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test--no-content-disposition.px: Added new tests for validation of
+ HTTP Content-Disposition header support logic. In particular, these
+ tests check wget's behavior for every combination of -N/-O and -e
+ contentdisposition=on/off options.
+
+ * Test--no-content-disposition-trivial.px: Ditto.
+
+ * Test-N-HTTP-Content-Disposition.px: Ditto.
+
+ * Test-N--no-content-disposition.px: Ditto.
+
+ * Test-N--no-content-disposition-trivial.px: Ditto.
+
+ * Test-O-HTTP-Content-Disposition.px: Ditto.
+
+ * Test-O--no-content-disposition.px: Ditto.
+
+ * Test-O--no-content-disposition-trivial.px: Ditto.
+
+2007-07-05 Micah Cowan <micah@cowan.name>
+
+ * Makefile.in:
+ Updated GPL reference to version 3 or later, removed FSF
+ address.
+
+2007-06-14 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * FTPServer.pm: Added FTP testing support.
+
+ * FTPTest.pm: Ditto.
+
+ * Test-ftp.px: Ditto.
+
+2006-12-22 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPTest.pm: Don't ignore initial '/' character in requested URLs.
+
+2006-11-10 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test-np.px: Added test for -np.
+
+ * HTTPTest.pm: Ignore initial '/' character in requested URLs.
+
+2006-10-12 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test1.px: Renamed to Test-noop.px.
+
+ * Test-noop.px: Ditto.
+
+ * Test2.px: Renamed to Test-N.px.
+
+ * Test-N.px: Ditto.
+
+ * Test3.px: Renamed to Test-nonexisting-quiet.px.
+
+ * Test-nonexisting-quiet.px: Ditto.
+
+ * Test4.px: Renamed to Test-O-nonexisting.px.
+
+ * Test-O-nonexisting.px: Ditto.
+
+ * Test5.px: Renamed to Test-HTTP-Content-Disposition.px.
+
+ * Test-HTTP-Content-Disposition.px: Ditto.
+
+ * Test6.px: Renamed to Test-HTTP-Content-Disposition-1.px.
+
+ * Test-HTTP-Content-Disposition-1.px: Ditto.
+
+ * Test7.px: Renamed to Test-HTTP-Content-Disposition-2.px.
+
+ * Test-HTTP-Content-Disposition-2.px: Ditto.
+
+ * Test8.px: Replaced by Test--spider-r.px.
+
+ * Test9.px: Renamed to Test-Restrict-Lowercase.px.
+
+ * Test-Restrict-Lowercase.px: Ditto.
+
+ * Test10.px: Renamed to Test-Restrict-Uppercase.px.
+
+ * Test-Restrict-Uppercase.px: Ditto.
+
+ * Test--spider.px: Added test for spider mode.
+
+ * Test--spider-fail.px: Added failing test for spider mode.
+
+ * Test--spider-r.px: Added test for recursive spider mode.
+
+ * Test-c.px: Added test for --continue mode.
+
+ * Test-c-full.px: Added test for --continue mode.
+
+ * Test-c-partial.px: Added test for --continue mode.
+
+ * Test-O.px: Added test for -O.
+
+ * Test-N-current.px: Added test for -N.
+
+ * Test-N-old.px: Added test for -N.
+
+ * Test-E-k.px: Added test for -E -k.
+
+ * Test-E-k-K.px: Added test for -E -k -K.
+
+2006-08-17 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Added support for Range header.
+
+2006-07-14 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test4.px: Fixed wrong expected behaviour.
+
+2006-06-13 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test9.px: Added test for --restrict-file-names=lowercase option.
+
+ * Test10.px: Added test for --restrict-file-names=uppercase option.
+
+2006-05-26 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Added synchronization between client and server
+ processes to prevent the test to start before the server is ready.
+
+ * HTTPTest.pm: Ditto.
+
+ * Test.pm: Ditto.
+
+ * Test1.px: Removed unneeded ../src/ from command line.
+
+ * Test2.px: Ditto.
+
+ * Test3.px: Ditto.
+
+ * Test4.px: Ditto.
+
+ * Test5.px: Ditto.
+
+ * Test6.px: Ditto.
+
+ * Test7.px: Ditto.
+
+ * Test8.px: Added test for recursive spider mode.
+
+2006-05-26 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Fixed bug when returning 404. Improved logging.
+
+ * Test.pm: Added support for command lines which use an absolute path
+ for the Wget binary.
+
+2006-04-28 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * Test5.px: Added test for HTTP Content-Disposition support.
+
+ * Test6.px: Ditto.
+
+ * Test7.px: Ditto.
+
+2006-04-27 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Serve index.html if no filename is given.
+
+ * Test.pm: Added support for pre-existing files.
+
+2006-01-24 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Enhanced logging support.
+
+ * HTTPTest.pm: Updated to new test format.
+
+ * Test.pm: Improved test setup, verification and cleanup. Major
+ refactoring.
+
+ * Test1.px: Updated to new test format.
+
+ * Test2.px: Updated to new test format.
+
+ * Test3.px: Added new test for quiet download of nonexistent URL.
+
+ * Test4.px: Added new test for quiet download of nonexistent URL with
+ --output-document option.
+
+2005-12-05 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Refactored as a subclass of HTTP::Daemon.
+ Removed the old run method and renamed the old run_daemon
+ method to run. Added support for partial
+
+ * Testing.pm: Renamed to HTTPTest.pm.
+
+ * HTTPTest.pm: Refactored as a subclass of Test. Renamed
+ Run_HTTP_Test to run, verify_download to _verify_download
+ and added support for timestamp checking.
+
+ * Test.pm: Added Test class as the super class of every
+ testcase.
+
+ * test1: Renamed to Test1.px.
+
+ * Test1.px: Refactored as an instance of the HTTPTest class.
+
+ * Test2.px: Added -N HTTP test.
+
+2005-11-02 Mauro Tortonesi <mauro@ferrara.linux.it>
+
+ * HTTPServer.pm: Added basic support for HTTP testing.
+
+ * Testing.pm: Added basic support for feature testing (only HTTP
+ testing is supported at the moment).
+
+ * test1: Added basic HTTP test.
+
diff --git a/tests/FTPServer.pm b/tests/FTPServer.pm
new file mode 100644
index 0000000..87e7983
--- /dev/null
+++ b/tests/FTPServer.pm
@@ -0,0 +1,802 @@
+# 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'};
+
+ # 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 $_;
+
+ $dir = FTPPaths::path_merge($dir, $path);
+ my $listing = $paths->get_list($dir);
+ 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;
+ }
+
+ 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);
+
+
+ # Copy data.
+ while ($buffer = substr($content, 0, 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;
+ }
+ }
+
+ # 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) = @_;
+
+ 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} = 'A';
+ } elsif ($type =~ /^([AI])\sN$/i) {
+ $conn->{type} = 'A';
+ } 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/{{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;
+ }
+
+ # 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 ($a, $b) = @_;
+
+ return $a unless $b;
+
+ if ($b =~ m.^/.) {
+ $a = '';
+ $b =~ s.^/..;
+ }
+ $a =~ s./$..;
+
+ my @components = split('/', $b);
+
+ foreach my $c (@components) {
+ if ($c =~ /^\.?$/) {
+ next;
+ } elsif ($c eq '..') {
+ next if $a eq '';
+ $a =~ s|/[^/]*$||;
+ } else {
+ $a .= "/$c";
+ }
+ }
+
+ return $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('/', $path);
+ shift @components;
+ my $x = $paths;
+ for my $c (@components) {
+ unless (exists $x->{$c}) {
+ $x->{$c} = {_type => 'd'};
+ }
+ $x = $x->{$c};
+ }
+ %$x = %{$urls->{$path}};
+ $x->{_type} = 'f';
+ }
+
+ $self->{'_paths'} = $paths;
+ $self->{'_behavior'} = $behavior;
+}
+
+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 undef;
+ }
+ }
+ return $node;
+}
+
+sub dir_exists {
+ my ($self, $path) = @_;
+ return $self->exists($path, 'd');
+}
+
+sub 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 %e %H:%M", localtime);
+ return "$mode_str 1 0 0 $size $date $name";
+}
+
+sub get_list {
+ my ($self, $path) = @_;
+ my $info = $self->get_info($path);
+ return undef unless defined $info;
+ my $list = [];
+
+ if ($info->{'_type'} eq 'd') {
+ for my $item (keys %$info) {
+ next if $item =~ /^_/;
+ push @$list, $self->_format_for_list($item, $info->{$item});
+ }
+ } else {
+ push @$list, $self->_format_for_list(final_component($path), $info);
+ }
+
+ return $list;
+}
+
+1;
+
+# vim: et ts=4 sw=4
diff --git a/tests/FTPTest.pm b/tests/FTPTest.pm
new file mode 100644
index 0000000..c1d3d26
--- /dev/null
+++ b/tests/FTPTest.pm
@@ -0,0 +1,61 @@
+package FTPTest;
+
+use strict;
+use warnings;
+
+use FTPServer;
+use WgetTest;
+
+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/{{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..627c102
--- /dev/null
+++ b/tests/HTTPServer.pm
@@ -0,0 +1,243 @@
+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";
+ $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 $rhdr = $req->header ($hdrname);
+ my $ehdr = $url_rec->{'request_headers'}{$hdrname};
+ 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/{{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..883213d
--- /dev/null
+++ b/tests/HTTPTest.pm
@@ -0,0 +1,57 @@
+package HTTPTest;
+
+use strict;
+use warnings;
+
+use HTTPServer;
+use WgetTest;
+
+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/{{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..6cdbb99
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,139 @@
+# Makefile for `wget' utility
+# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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.
+
+#
+# Version: @VERSION@
+#
+
+PERL = perl
+PERLRUN = $(PERL) -I$(srcdir)
+
+LIBS = @LIBICONV@ @LIBINTL@ @LIBS@ $(LIB_CLOCK_GETTIME)
+
+.PHONY: test run-unit-tests run-px-tests
+
+check-local: test
+
+test: ../src/wget$(EXEEXT) run-unit-tests run-px-tests
+
+../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)
+
+run-unit-tests: unit-tests$(EXEEXT) ../src/libunittest.a
+ ./unit-tests$(EXEEXT)
+
+run-px-tests: WgetTest.pm ../src/wget$(EXEEXT)
+ $(srcdir)/run-px $(top_srcdir)
+
+EXTRA_DIST = FTPServer.pm FTPTest.pm HTTPServer.pm HTTPTest.pm \
+ WgetFeature.pm WgetFeature.cfg \
+ 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-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-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-proxied-https-auth.px \
+ Test-proxy-auth-basic.px \
+ Test-restrict-ascii.px \
+ Test-Restrict-Lowercase.px \
+ Test-Restrict-Uppercase.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 \
+ run-px certs
+
+check_PROGRAMS = unit-tests
+unit_tests_SOURCES =
+LDADD = ../src/libunittest.a ../lib/libgnu.a $(LIBS)
+
+CLEANFILES = *~ *.bak core core.[0-9]*
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..7c2f192
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,1344 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+# 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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.
+
+#
+# Version: @VERSION@
+#
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@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
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/WgetTest.pm.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \
+ $(top_srcdir)/m4/alloca.m4 $(top_srcdir)/m4/arpa_inet_h.m4 \
+ $(top_srcdir)/m4/asm-underscore.m4 \
+ $(top_srcdir)/m4/clock_time.m4 $(top_srcdir)/m4/close.m4 \
+ $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/configmake.m4 \
+ $(top_srcdir)/m4/dirname.m4 \
+ $(top_srcdir)/m4/double-slash-root.m4 $(top_srcdir)/m4/dup2.m4 \
+ $(top_srcdir)/m4/environ.m4 $(top_srcdir)/m4/errno_h.m4 \
+ $(top_srcdir)/m4/error.m4 $(top_srcdir)/m4/extensions.m4 \
+ $(top_srcdir)/m4/fatal-signal.m4 $(top_srcdir)/m4/fcntl-o.m4 \
+ $(top_srcdir)/m4/fcntl.m4 $(top_srcdir)/m4/fcntl_h.m4 \
+ $(top_srcdir)/m4/float_h.m4 $(top_srcdir)/m4/fseek.m4 \
+ $(top_srcdir)/m4/fseeko.m4 $(top_srcdir)/m4/futimens.m4 \
+ $(top_srcdir)/m4/getaddrinfo.m4 $(top_srcdir)/m4/getdelim.m4 \
+ $(top_srcdir)/m4/getdtablesize.m4 $(top_srcdir)/m4/getline.m4 \
+ $(top_srcdir)/m4/getopt.m4 $(top_srcdir)/m4/getpass.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/gettime.m4 \
+ $(top_srcdir)/m4/gettimeofday.m4 $(top_srcdir)/m4/glibc21.m4 \
+ $(top_srcdir)/m4/gnulib-common.m4 \
+ $(top_srcdir)/m4/gnulib-comp.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_h.m4 \
+ $(top_srcdir)/m4/ioctl.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/localcharset.m4 $(top_srcdir)/m4/locale-fr.m4 \
+ $(top_srcdir)/m4/locale-ja.m4 $(top_srcdir)/m4/locale-zh.m4 \
+ $(top_srcdir)/m4/lock.m4 $(top_srcdir)/m4/longlong.m4 \
+ $(top_srcdir)/m4/lseek.m4 $(top_srcdir)/m4/lstat.m4 \
+ $(top_srcdir)/m4/malloc.m4 $(top_srcdir)/m4/mbrtowc.m4 \
+ $(top_srcdir)/m4/mbsinit.m4 $(top_srcdir)/m4/mbstate_t.m4 \
+ $(top_srcdir)/m4/mbtowc.m4 $(top_srcdir)/m4/md5.m4 \
+ $(top_srcdir)/m4/memchr.m4 $(top_srcdir)/m4/mkdir.m4 \
+ $(top_srcdir)/m4/mmap-anon.m4 $(top_srcdir)/m4/mode_t.m4 \
+ $(top_srcdir)/m4/multiarch.m4 $(top_srcdir)/m4/netdb_h.m4 \
+ $(top_srcdir)/m4/netinet_in_h.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/nocrash.m4 $(top_srcdir)/m4/open.m4 \
+ $(top_srcdir)/m4/pipe2.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/posix_spawn.m4 $(top_srcdir)/m4/printf.m4 \
+ $(top_srcdir)/m4/quote.m4 $(top_srcdir)/m4/quotearg.m4 \
+ $(top_srcdir)/m4/rawmemchr.m4 $(top_srcdir)/m4/realloc.m4 \
+ $(top_srcdir)/m4/sched_h.m4 $(top_srcdir)/m4/select.m4 \
+ $(top_srcdir)/m4/servent.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/stat-time.m4 $(top_srcdir)/m4/stat.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/strcase.m4 $(top_srcdir)/m4/strcasestr.m4 \
+ $(top_srcdir)/m4/strchrnul.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/sys_ioctl_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/threadlib.m4 \
+ $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/m4/timespec.m4 \
+ $(top_srcdir)/m4/unistd-safer.m4 $(top_srcdir)/m4/unistd_h.m4 \
+ $(top_srcdir)/m4/unlocked-io.m4 $(top_srcdir)/m4/utimbuf.m4 \
+ $(top_srcdir)/m4/utimens.m4 $(top_srcdir)/m4/utimes.m4 \
+ $(top_srcdir)/m4/vasnprintf.m4 $(top_srcdir)/m4/vasprintf.m4 \
+ $(top_srcdir)/m4/wait-process.m4 $(top_srcdir)/m4/waitpid.m4 \
+ $(top_srcdir)/m4/warn-on-use.m4 $(top_srcdir)/m4/wchar_h.m4 \
+ $(top_srcdir)/m4/wchar_t.m4 $(top_srcdir)/m4/wctype_h.m4 \
+ $(top_srcdir)/m4/wget.m4 $(top_srcdir)/m4/wint_t.m4 \
+ $(top_srcdir)/m4/write.m4 $(top_srcdir)/m4/xalloc.m4 \
+ $(top_srcdir)/m4/xsize.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES = WgetTest.pm
+CONFIG_CLEAN_VPATH_FILES =
+am_unit_tests_OBJECTS =
+unit_tests_OBJECTS = $(am_unit_tests_OBJECTS)
+unit_tests_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+unit_tests_DEPENDENCIES = ../src/libunittest.a ../lib/libgnu.a \
+ $(am__DEPENDENCIES_2)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(unit_tests_SOURCES)
+DIST_SOURCES = $(unit_tests_SOURCES)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+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@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+COMMENT_IF_NO_POD2MAN = @COMMENT_IF_NO_POD2MAN@
+CONFIG_INCLUDE = @CONFIG_INCLUDE@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+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@
+EXEEXT = @EXEEXT@
+FLOAT_H = @FLOAT_H@
+GETADDRINFO_LIB = @GETADDRINFO_LIB@
+GETOPT_H = @GETOPT_H@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GLIBC21 = @GLIBC21@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNULIB_ACCEPT = @GNULIB_ACCEPT@
+GNULIB_ACCEPT4 = @GNULIB_ACCEPT4@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BIND = @GNULIB_BIND@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_CONNECT = @GNULIB_CONNECT@
+GNULIB_DPRINTF = @GNULIB_DPRINTF@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHMODAT = @GNULIB_FCHMODAT@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FCLOSE = @GNULIB_FCLOSE@
+GNULIB_FCNTL = @GNULIB_FCNTL@
+GNULIB_FFLUSH = @GNULIB_FFLUSH@
+GNULIB_FFS = @GNULIB_FFS@
+GNULIB_FFSL = @GNULIB_FFSL@
+GNULIB_FFSLL = @GNULIB_FFSLL@
+GNULIB_FGETC = @GNULIB_FGETC@
+GNULIB_FGETS = @GNULIB_FGETS@
+GNULIB_FOPEN = @GNULIB_FOPEN@
+GNULIB_FPRINTF = @GNULIB_FPRINTF@
+GNULIB_FPRINTF_POSIX = @GNULIB_FPRINTF_POSIX@
+GNULIB_FPURGE = @GNULIB_FPURGE@
+GNULIB_FPUTC = @GNULIB_FPUTC@
+GNULIB_FPUTS = @GNULIB_FPUTS@
+GNULIB_FREAD = @GNULIB_FREAD@
+GNULIB_FREOPEN = @GNULIB_FREOPEN@
+GNULIB_FSCANF = @GNULIB_FSCANF@
+GNULIB_FSEEK = @GNULIB_FSEEK@
+GNULIB_FSEEKO = @GNULIB_FSEEKO@
+GNULIB_FSTATAT = @GNULIB_FSTATAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTELL = @GNULIB_FTELL@
+GNULIB_FTELLO = @GNULIB_FTELLO@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_FUTIMENS = @GNULIB_FUTIMENS@
+GNULIB_FWRITE = @GNULIB_FWRITE@
+GNULIB_GETADDRINFO = @GNULIB_GETADDRINFO@
+GNULIB_GETC = @GNULIB_GETC@
+GNULIB_GETCHAR = @GNULIB_GETCHAR@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDELIM = @GNULIB_GETDELIM@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLINE = @GNULIB_GETLINE@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETPEERNAME = @GNULIB_GETPEERNAME@
+GNULIB_GETS = @GNULIB_GETS@
+GNULIB_GETSOCKNAME = @GNULIB_GETSOCKNAME@
+GNULIB_GETSOCKOPT = @GNULIB_GETSOCKOPT@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETTIMEOFDAY = @GNULIB_GETTIMEOFDAY@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_GROUP_MEMBER = @GNULIB_GROUP_MEMBER@
+GNULIB_ICONV = @GNULIB_ICONV@
+GNULIB_INET_NTOP = @GNULIB_INET_NTOP@
+GNULIB_INET_PTON = @GNULIB_INET_PTON@
+GNULIB_IOCTL = @GNULIB_IOCTL@
+GNULIB_ISWBLANK = @GNULIB_ISWBLANK@
+GNULIB_ISWCTYPE = @GNULIB_ISWCTYPE@
+GNULIB_LCHMOD = @GNULIB_LCHMOD@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LISTEN = @GNULIB_LISTEN@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_LSTAT = @GNULIB_LSTAT@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSCASECMP = @GNULIB_MBSCASECMP@
+GNULIB_MBSCASESTR = @GNULIB_MBSCASESTR@
+GNULIB_MBSCHR = @GNULIB_MBSCHR@
+GNULIB_MBSCSPN = @GNULIB_MBSCSPN@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSLEN = @GNULIB_MBSLEN@
+GNULIB_MBSNCASECMP = @GNULIB_MBSNCASECMP@
+GNULIB_MBSNLEN = @GNULIB_MBSNLEN@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSPBRK = @GNULIB_MBSPBRK@
+GNULIB_MBSPCASECMP = @GNULIB_MBSPCASECMP@
+GNULIB_MBSRCHR = @GNULIB_MBSRCHR@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MBSSEP = @GNULIB_MBSSEP@
+GNULIB_MBSSPN = @GNULIB_MBSSPN@
+GNULIB_MBSSTR = @GNULIB_MBSSTR@
+GNULIB_MBSTOK_R = @GNULIB_MBSTOK_R@
+GNULIB_MBTOWC = @GNULIB_MBTOWC@
+GNULIB_MEMCHR = @GNULIB_MEMCHR@
+GNULIB_MEMMEM = @GNULIB_MEMMEM@
+GNULIB_MEMPCPY = @GNULIB_MEMPCPY@
+GNULIB_MEMRCHR = @GNULIB_MEMRCHR@
+GNULIB_MKDIRAT = @GNULIB_MKDIRAT@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKFIFO = @GNULIB_MKFIFO@
+GNULIB_MKFIFOAT = @GNULIB_MKFIFOAT@
+GNULIB_MKNOD = @GNULIB_MKNOD@
+GNULIB_MKNODAT = @GNULIB_MKNODAT@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_MKTIME = @GNULIB_MKTIME@
+GNULIB_NANOSLEEP = @GNULIB_NANOSLEEP@
+GNULIB_NONBLOCKING = @GNULIB_NONBLOCKING@
+GNULIB_OBSTACK_PRINTF = @GNULIB_OBSTACK_PRINTF@
+GNULIB_OBSTACK_PRINTF_POSIX = @GNULIB_OBSTACK_PRINTF_POSIX@
+GNULIB_OPEN = @GNULIB_OPEN@
+GNULIB_OPENAT = @GNULIB_OPENAT@
+GNULIB_PERROR = @GNULIB_PERROR@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_POPEN = @GNULIB_POPEN@
+GNULIB_POSIX_SPAWN = @GNULIB_POSIX_SPAWN@
+GNULIB_POSIX_SPAWNATTR_DESTROY = @GNULIB_POSIX_SPAWNATTR_DESTROY@
+GNULIB_POSIX_SPAWNATTR_GETFLAGS = @GNULIB_POSIX_SPAWNATTR_GETFLAGS@
+GNULIB_POSIX_SPAWNATTR_GETPGROUP = @GNULIB_POSIX_SPAWNATTR_GETPGROUP@
+GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM@
+GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY@
+GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT@
+GNULIB_POSIX_SPAWNATTR_GETSIGMASK = @GNULIB_POSIX_SPAWNATTR_GETSIGMASK@
+GNULIB_POSIX_SPAWNATTR_INIT = @GNULIB_POSIX_SPAWNATTR_INIT@
+GNULIB_POSIX_SPAWNATTR_SETFLAGS = @GNULIB_POSIX_SPAWNATTR_SETFLAGS@
+GNULIB_POSIX_SPAWNATTR_SETPGROUP = @GNULIB_POSIX_SPAWNATTR_SETPGROUP@
+GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM@
+GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY = @GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY@
+GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT = @GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT@
+GNULIB_POSIX_SPAWNATTR_SETSIGMASK = @GNULIB_POSIX_SPAWNATTR_SETSIGMASK@
+GNULIB_POSIX_SPAWNP = @GNULIB_POSIX_SPAWNP@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2 = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY@
+GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT = @GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PRINTF = @GNULIB_PRINTF@
+GNULIB_PRINTF_POSIX = @GNULIB_PRINTF_POSIX@
+GNULIB_PSELECT = @GNULIB_PSELECT@
+GNULIB_PTHREAD_SIGMASK = @GNULIB_PTHREAD_SIGMASK@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTC = @GNULIB_PUTC@
+GNULIB_PUTCHAR = @GNULIB_PUTCHAR@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PUTS = @GNULIB_PUTS@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
+GNULIB_READ = @GNULIB_READ@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RECV = @GNULIB_RECV@
+GNULIB_RECVFROM = @GNULIB_RECVFROM@
+GNULIB_REMOVE = @GNULIB_REMOVE@
+GNULIB_RENAME = @GNULIB_RENAME@
+GNULIB_RENAMEAT = @GNULIB_RENAMEAT@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SCANF = @GNULIB_SCANF@
+GNULIB_SELECT = @GNULIB_SELECT@
+GNULIB_SEND = @GNULIB_SEND@
+GNULIB_SENDTO = @GNULIB_SENDTO@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SETSOCKOPT = @GNULIB_SETSOCKOPT@
+GNULIB_SHUTDOWN = @GNULIB_SHUTDOWN@
+GNULIB_SIGACTION = @GNULIB_SIGACTION@
+GNULIB_SIGNAL_H_SIGPIPE = @GNULIB_SIGNAL_H_SIGPIPE@
+GNULIB_SIGPROCMASK = @GNULIB_SIGPROCMASK@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_SNPRINTF = @GNULIB_SNPRINTF@
+GNULIB_SOCKET = @GNULIB_SOCKET@
+GNULIB_SPRINTF_POSIX = @GNULIB_SPRINTF_POSIX@
+GNULIB_STAT = @GNULIB_STAT@
+GNULIB_STDIO_H_NONBLOCKING = @GNULIB_STDIO_H_NONBLOCKING@
+GNULIB_STDIO_H_SIGPIPE = @GNULIB_STDIO_H_SIGPIPE@
+GNULIB_STPCPY = @GNULIB_STPCPY@
+GNULIB_STPNCPY = @GNULIB_STPNCPY@
+GNULIB_STRCASESTR = @GNULIB_STRCASESTR@
+GNULIB_STRCHRNUL = @GNULIB_STRCHRNUL@
+GNULIB_STRDUP = @GNULIB_STRDUP@
+GNULIB_STRERROR = @GNULIB_STRERROR@
+GNULIB_STRERROR_R = @GNULIB_STRERROR_R@
+GNULIB_STRNCAT = @GNULIB_STRNCAT@
+GNULIB_STRNDUP = @GNULIB_STRNDUP@
+GNULIB_STRNLEN = @GNULIB_STRNLEN@
+GNULIB_STRPBRK = @GNULIB_STRPBRK@
+GNULIB_STRPTIME = @GNULIB_STRPTIME@
+GNULIB_STRSEP = @GNULIB_STRSEP@
+GNULIB_STRSIGNAL = @GNULIB_STRSIGNAL@
+GNULIB_STRSTR = @GNULIB_STRSTR@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOK_R = @GNULIB_STRTOK_R@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_STRVERSCMP = @GNULIB_STRVERSCMP@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TIMEGM = @GNULIB_TIMEGM@
+GNULIB_TIME_R = @GNULIB_TIME_R@
+GNULIB_TMPFILE = @GNULIB_TMPFILE@
+GNULIB_TOWCTRANS = @GNULIB_TOWCTRANS@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_NONBLOCKING = @GNULIB_UNISTD_H_NONBLOCKING@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_UTIMENSAT = @GNULIB_UTIMENSAT@
+GNULIB_VASPRINTF = @GNULIB_VASPRINTF@
+GNULIB_VDPRINTF = @GNULIB_VDPRINTF@
+GNULIB_VFPRINTF = @GNULIB_VFPRINTF@
+GNULIB_VFPRINTF_POSIX = @GNULIB_VFPRINTF_POSIX@
+GNULIB_VFSCANF = @GNULIB_VFSCANF@
+GNULIB_VPRINTF = @GNULIB_VPRINTF@
+GNULIB_VPRINTF_POSIX = @GNULIB_VPRINTF_POSIX@
+GNULIB_VSCANF = @GNULIB_VSCANF@
+GNULIB_VSNPRINTF = @GNULIB_VSNPRINTF@
+GNULIB_VSPRINTF_POSIX = @GNULIB_VSPRINTF_POSIX@
+GNULIB_WAITPID = @GNULIB_WAITPID@
+GNULIB_WCPCPY = @GNULIB_WCPCPY@
+GNULIB_WCPNCPY = @GNULIB_WCPNCPY@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSCASECMP = @GNULIB_WCSCASECMP@
+GNULIB_WCSCAT = @GNULIB_WCSCAT@
+GNULIB_WCSCHR = @GNULIB_WCSCHR@
+GNULIB_WCSCMP = @GNULIB_WCSCMP@
+GNULIB_WCSCOLL = @GNULIB_WCSCOLL@
+GNULIB_WCSCPY = @GNULIB_WCSCPY@
+GNULIB_WCSCSPN = @GNULIB_WCSCSPN@
+GNULIB_WCSDUP = @GNULIB_WCSDUP@
+GNULIB_WCSLEN = @GNULIB_WCSLEN@
+GNULIB_WCSNCASECMP = @GNULIB_WCSNCASECMP@
+GNULIB_WCSNCAT = @GNULIB_WCSNCAT@
+GNULIB_WCSNCMP = @GNULIB_WCSNCMP@
+GNULIB_WCSNCPY = @GNULIB_WCSNCPY@
+GNULIB_WCSNLEN = @GNULIB_WCSNLEN@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSPBRK = @GNULIB_WCSPBRK@
+GNULIB_WCSRCHR = @GNULIB_WCSRCHR@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCSSPN = @GNULIB_WCSSPN@
+GNULIB_WCSSTR = @GNULIB_WCSSTR@
+GNULIB_WCSTOK = @GNULIB_WCSTOK@
+GNULIB_WCSWIDTH = @GNULIB_WCSWIDTH@
+GNULIB_WCSXFRM = @GNULIB_WCSXFRM@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCTOMB = @GNULIB_WCTOMB@
+GNULIB_WCTRANS = @GNULIB_WCTRANS@
+GNULIB_WCTYPE = @GNULIB_WCTYPE@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WMEMCHR = @GNULIB_WMEMCHR@
+GNULIB_WMEMCMP = @GNULIB_WMEMCMP@
+GNULIB_WMEMCPY = @GNULIB_WMEMCPY@
+GNULIB_WMEMMOVE = @GNULIB_WMEMMOVE@
+GNULIB_WMEMSET = @GNULIB_WMEMSET@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ACCEPT4 = @HAVE_ACCEPT4@
+HAVE_ARPA_INET_H = @HAVE_ARPA_INET_H@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+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_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_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_INET_NTOP = @HAVE_DECL_INET_NTOP@
+HAVE_DECL_INET_PTON = @HAVE_DECL_INET_PTON@
+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_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_STRTOK_R = @HAVE_DECL_STRTOK_R@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_VSNPRINTF = @HAVE_DECL_VSNPRINTF@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DPRINTF = @HAVE_DPRINTF@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHMODAT = @HAVE_FCHMODAT@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FCNTL = @HAVE_FCNTL@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FFS = @HAVE_FFS@
+HAVE_FFSL = @HAVE_FFSL@
+HAVE_FFSLL = @HAVE_FFSLL@
+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_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETOPT_H = @HAVE_GETOPT_H@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GETTIMEOFDAY = @HAVE_GETTIMEOFDAY@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_GROUP_MEMBER = @HAVE_GROUP_MEMBER@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LCHMOD = @HAVE_LCHMOD@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LIBGNUTLS = @HAVE_LIBGNUTLS@
+HAVE_LIBSSL = @HAVE_LIBSSL@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_LSTAT = @HAVE_LSTAT@
+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_MEMCHR = @HAVE_MEMCHR@
+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_NANOSLEEP = @HAVE_NANOSLEEP@
+HAVE_NETDB_H = @HAVE_NETDB_H@
+HAVE_NETINET_IN_H = @HAVE_NETINET_IN_H@
+HAVE_OPENAT = @HAVE_OPENAT@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+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_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_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RENAMEAT = @HAVE_RENAMEAT@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SA_FAMILY_T = @HAVE_SA_FAMILY_T@
+HAVE_SCHED_H = @HAVE_SCHED_H@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGACTION = @HAVE_SIGACTION@
+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_STRINGS_H = @HAVE_STRINGS_H@
+HAVE_STRPBRK = @HAVE_STRPBRK@
+HAVE_STRPTIME = @HAVE_STRPTIME@
+HAVE_STRSEP = @HAVE_STRSEP@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+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_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_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_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_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
+HAVE_VASPRINTF = @HAVE_VASPRINTF@
+HAVE_VDPRINTF = @HAVE_VDPRINTF@
+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_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_WMEMSET = @HAVE_WMEMSET@
+HAVE_WS2TCPIP_H = @HAVE_WS2TCPIP_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@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+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@
+LIBINTL = @LIBINTL@
+LIBMULTITHREAD = @LIBMULTITHREAD@
+LIBOBJS = @LIBOBJS@
+LIBPTH = @LIBPTH@
+LIBPTH_PREFIX = @LIBPTH_PREFIX@
+LIBS = @LIBICONV@ @LIBINTL@ @LIBS@ $(LIB_CLOCK_GETTIME)
+LIBSOCKET = @LIBSOCKET@
+LIBSSL = @LIBSSL@
+LIBSSL_PREFIX = @LIBSSL_PREFIX@
+LIBTHREAD = @LIBTHREAD@
+LIB_CLOCK_GETTIME = @LIB_CLOCK_GETTIME@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+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@
+LTLIBPTH = @LTLIBPTH@
+LTLIBSSL = @LTLIBSSL@
+LTLIBTHREAD = @LTLIBTHREAD@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NETINET_IN_H = @NETINET_IN_H@
+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_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_GETOPT_H = @NEXT_AS_FIRST_DIRECTIVE_GETOPT_H@
+NEXT_AS_FIRST_DIRECTIVE_ICONV_H = @NEXT_AS_FIRST_DIRECTIVE_ICONV_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_IOCTL_H = @NEXT_AS_FIRST_DIRECTIVE_SYS_IOCTL_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_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_ERRNO_H = @NEXT_ERRNO_H@
+NEXT_FCNTL_H = @NEXT_FCNTL_H@
+NEXT_FLOAT_H = @NEXT_FLOAT_H@
+NEXT_GETOPT_H = @NEXT_GETOPT_H@
+NEXT_ICONV_H = @NEXT_ICONV_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_IOCTL_H = @NEXT_SYS_IOCTL_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_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+OBJEXT = @OBJEXT@
+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@
+PERL = perl
+POD2MAN = @POD2MAN@
+POSUB = @POSUB@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_H_DEFINES_STRUCT_TIMESPEC = @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DPRINTF = @REPLACE_DPRINTF@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_FCLOSE = @REPLACE_FCLOSE@
+REPLACE_FCNTL = @REPLACE_FCNTL@
+REPLACE_FFLUSH = @REPLACE_FFLUSH@
+REPLACE_FOPEN = @REPLACE_FOPEN@
+REPLACE_FPRINTF = @REPLACE_FPRINTF@
+REPLACE_FPURGE = @REPLACE_FPURGE@
+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_FUTIMENS = @REPLACE_FUTIMENS@
+REPLACE_GAI_STRERROR = @REPLACE_GAI_STRERROR@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDELIM = @REPLACE_GETDELIM@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLINE = @REPLACE_GETLINE@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@
+REPLACE_ICONV = @REPLACE_ICONV@
+REPLACE_ICONV_OPEN = @REPLACE_ICONV_OPEN@
+REPLACE_ICONV_UTF = @REPLACE_ICONV_UTF@
+REPLACE_IOCTL = @REPLACE_IOCTL@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_LSTAT = @REPLACE_LSTAT@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+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_MKNOD = @REPLACE_MKNOD@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_MKTIME = @REPLACE_MKTIME@
+REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_OBSTACK_PRINTF = @REPLACE_OBSTACK_PRINTF@
+REPLACE_OPEN = @REPLACE_OPEN@
+REPLACE_OPENAT = @REPLACE_OPENAT@
+REPLACE_PERROR = @REPLACE_PERROR@
+REPLACE_POPEN = @REPLACE_POPEN@
+REPLACE_POSIX_SPAWN = @REPLACE_POSIX_SPAWN@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PRINTF = @REPLACE_PRINTF@
+REPLACE_PSELECT = @REPLACE_PSELECT@
+REPLACE_PTHREAD_SIGMASK = @REPLACE_PTHREAD_SIGMASK@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READ = @REPLACE_READ@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_REMOVE = @REPLACE_REMOVE@
+REPLACE_RENAME = @REPLACE_RENAME@
+REPLACE_RENAMEAT = @REPLACE_RENAMEAT@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SELECT = @REPLACE_SELECT@
+REPLACE_SETENV = @REPLACE_SETENV@
+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_STRERROR_R = @REPLACE_STRERROR_R@
+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_STRTOK_R = @REPLACE_STRTOK_R@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TIMEGM = @REPLACE_TIMEGM@
+REPLACE_TMPFILE = @REPLACE_TMPFILE@
+REPLACE_TOWLOWER = @REPLACE_TOWLOWER@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+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_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCSWIDTH = @REPLACE_WCSWIDTH@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCTOMB = @REPLACE_WCTOMB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SCHED_H = @SCHED_H@
+SERVENT_LIB = @SERVENT_LIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+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@
+UNDEFINE_STRTOK_R = @UNDEFINE_STRTOK_R@
+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@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+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_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+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@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+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@
+PERLRUN = $(PERL) -I$(srcdir)
+EXTRA_DIST = FTPServer.pm FTPTest.pm HTTPServer.pm HTTPTest.pm \
+ WgetFeature.pm WgetFeature.cfg \
+ 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-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-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-proxied-https-auth.px \
+ Test-proxy-auth-basic.px \
+ Test-restrict-ascii.px \
+ Test-Restrict-Lowercase.px \
+ Test-Restrict-Uppercase.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 \
+ run-px certs
+
+unit_tests_SOURCES =
+LDADD = ../src/libunittest.a ../lib/libgnu.a $(LIBS)
+CLEANFILES = *~ *.bak core core.[0-9]*
+all: all-am
+
+.SUFFIXES:
+$(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
+.PRECIOUS: 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__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ 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):
+WgetTest.pm: $(top_builddir)/config.status $(srcdir)/WgetTest.pm.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+clean-checkPROGRAMS:
+ -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+unit-tests$(EXEEXT): $(unit_tests_OBJECTS) $(unit_tests_DEPENDENCIES)
+ @rm -f unit-tests$(EXEEXT)
+ $(LINK) $(unit_tests_OBJECTS) $(unit_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(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-local
+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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+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 Makefile
+distclean-am: clean-am distclean-compile distclean-generic
+
+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 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: all all-am check check-am check-local clean \
+ clean-checkPROGRAMS clean-generic distclean distclean-compile \
+ distclean-generic 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 \
+ uninstall uninstall-am
+
+
+.PHONY: test run-unit-tests run-px-tests
+
+check-local: test
+
+test: ../src/wget$(EXEEXT) run-unit-tests run-px-tests
+
+../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)
+
+run-unit-tests: unit-tests$(EXEEXT) ../src/libunittest.a
+ ./unit-tests$(EXEEXT)
+
+run-px-tests: WgetTest.pm ../src/wget$(EXEEXT)
+ $(srcdir)/run-px $(top_srcdir)
+
+# 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/Test--no-content-disposition-trivial.px b/tests/Test--no-content-disposition-trivial.px
new file mode 100755
index 0000000..337bc7c
--- /dev/null
+++ b/tests/Test--no-content-disposition-trivial.px
@@ -0,0 +1,56 @@
+#!/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 (name => "Test--no-content-disposition-trivial",
+ 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..27523a4
--- /dev/null
+++ b/tests/Test--no-content-disposition.px
@@ -0,0 +1,57 @@
+#!/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 (name => "Test--no-content-disposition",
+ 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-fail.px b/tests/Test--spider-fail.px
new file mode 100755
index 0000000..98c1b9c
--- /dev/null
+++ b/tests/Test--spider-fail.px
@@ -0,0 +1,53 @@
+#!/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 (name => "Test--spider-fail",
+ 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..88b53c4
--- /dev/null
+++ b/tests/Test--spider-r--no-content-disposition-trivial.px
@@ -0,0 +1,110 @@
+#!/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 (name => "Test--spider-r--no-content-disposition-trivial",
+ 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..6d7112a
--- /dev/null
+++ b/tests/Test--spider-r--no-content-disposition.px
@@ -0,0 +1,111 @@
+#!/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 (name => "Test--spider-r--no-content-disposition",
+ 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..8917b72
--- /dev/null
+++ b/tests/Test--spider-r-HTTP-Content-Disposition.px
@@ -0,0 +1,111 @@
+#!/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 (name => "Test--spider-r-HTTP-Content-Disposition",
+ 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..b84bafb
--- /dev/null
+++ b/tests/Test--spider-r.px
@@ -0,0 +1,110 @@
+#!/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 (name => "Test--spider-r",
+ 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..633c329
--- /dev/null
+++ b/tests/Test--spider.px
@@ -0,0 +1,53 @@
+#!/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 (name => "Test--spider",
+ 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..211988b
--- /dev/null
+++ b/tests/Test-E-k-K.px
@@ -0,0 +1,90 @@
+#!/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 (name => "Test-E-k-K",
+ 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..99df5b4
--- /dev/null
+++ b/tests/Test-E-k.px
@@ -0,0 +1,87 @@
+#!/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 (name => "Test-E-k",
+ 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..ef82eda
--- /dev/null
+++ b/tests/Test-HTTP-Content-Disposition-1.px
@@ -0,0 +1,77 @@
+#!/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 (name => "Test-HTTP-Content-Disposition-1",
+ 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..55b2abb
--- /dev/null
+++ b/tests/Test-HTTP-Content-Disposition-2.px
@@ -0,0 +1,77 @@
+#!/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 (name => "Test-HTTP-Content-Disposition-2",
+ 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..9b966f7
--- /dev/null
+++ b/tests/Test-HTTP-Content-Disposition.px
@@ -0,0 +1,57 @@
+#!/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 (name => "Test-HTTP-Content-Disposition",
+ 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..01e70c1
--- /dev/null
+++ b/tests/Test-N--no-content-disposition-trivial.px
@@ -0,0 +1,49 @@
+#!/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 (name => "Test-N--no-content-disposition-trivial",
+ 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..42ac7ee
--- /dev/null
+++ b/tests/Test-N--no-content-disposition.px
@@ -0,0 +1,50 @@
+#!/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 (name => "Test-N--no-content-disposition",
+ 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..ab8cea8
--- /dev/null
+++ b/tests/Test-N-HTTP-Content-Disposition.px
@@ -0,0 +1,51 @@
+#!/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 (name => "Test-N-HTTP-Content-Disposition",
+ 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..fcf4d88
--- /dev/null
+++ b/tests/Test-N-current.px
@@ -0,0 +1,66 @@
+#!/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 (name => "Test-N-current",
+ 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..698ce8b
--- /dev/null
+++ b/tests/Test-N-no-info.px
@@ -0,0 +1,64 @@
+#!/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 (name => "Test-N-current",
+ 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..0c0128c
--- /dev/null
+++ b/tests/Test-N-old.px
@@ -0,0 +1,64 @@
+#!/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 (name => "Test-N-old",
+ 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..2ea0ab8
--- /dev/null
+++ b/tests/Test-N-smaller.px
@@ -0,0 +1,67 @@
+#!/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 (name => "Test-N-current",
+ 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..91528db
--- /dev/null
+++ b/tests/Test-N.px
@@ -0,0 +1,49 @@
+#!/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 (name => "Test-N",
+ 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..a5b264b
--- /dev/null
+++ b/tests/Test-O--no-content-disposition-trivial.px
@@ -0,0 +1,47 @@
+#!/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 (name => "Test-O--no-content-disposition-trivial",
+ 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..92263ff
--- /dev/null
+++ b/tests/Test-O--no-content-disposition.px
@@ -0,0 +1,48 @@
+#!/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 (name => "Test-O--no-content-disposition",
+ 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..23ae687
--- /dev/null
+++ b/tests/Test-O-HTTP-Content-Disposition.px
@@ -0,0 +1,48 @@
+#!/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 (name => "Test-O-HTTP-Content-Disposition",
+ 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..94a7b43
--- /dev/null
+++ b/tests/Test-O-nc.px
@@ -0,0 +1,47 @@
+#!/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 (name => "Test-O-nc",
+ 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..8fde7c8
--- /dev/null
+++ b/tests/Test-O-nonexisting.px
@@ -0,0 +1,47 @@
+#!/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 (name => "Test-O-nonexisting",
+ 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..eed42de
--- /dev/null
+++ b/tests/Test-O.px
@@ -0,0 +1,47 @@
+#!/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 (name => "Test-O",
+ 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..860e8a7
--- /dev/null
+++ b/tests/Test-Restrict-Lowercase.px
@@ -0,0 +1,56 @@
+#!/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 (name => "Test-Restrict-Lowercase",
+ 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..3021347
--- /dev/null
+++ b/tests/Test-Restrict-Uppercase.px
@@ -0,0 +1,56 @@
+#!/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 (name => "Test-Restrict-Uppercase",
+ 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..008b3fc
--- /dev/null
+++ b/tests/Test-auth-basic.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_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 (name => "Test-auth-basic",
+ 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..46bb877
--- /dev/null
+++ b/tests/Test-auth-no-challenge-url.px
@@ -0,0 +1,50 @@
+#!/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 (name => "Test-auth-no-challenge-url",
+ 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..7ee2e41
--- /dev/null
+++ b/tests/Test-auth-no-challenge.px
@@ -0,0 +1,51 @@
+#!/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 (name => "Test-auth-no-challenge",
+ 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 100644
index 0000000..4d8e6d6
--- /dev/null
+++ b/tests/Test-auth-retcode.px
@@ -0,0 +1,38 @@
+#!/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 (name => "Test-auth-retcode",
+ 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..96755ad
--- /dev/null
+++ b/tests/Test-auth-with-content-disposition.px
@@ -0,0 +1,50 @@
+#!/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 (name => "Test-auth-with-content-disposition",
+ 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..4aa8d96
--- /dev/null
+++ b/tests/Test-c-full.px
@@ -0,0 +1,58 @@
+#!/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 (name => "Test-c-full",
+ 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..ccb20fd
--- /dev/null
+++ b/tests/Test-c-partial.px
@@ -0,0 +1,68 @@
+#!/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 (name => "Test-c-partial",
+ 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..c4802da
--- /dev/null
+++ b/tests/Test-c-shorter.px
@@ -0,0 +1,65 @@
+#!/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 (name => "Test-c-partial",
+ 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..0326697
--- /dev/null
+++ b/tests/Test-c.px
@@ -0,0 +1,55 @@
+#!/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 (name => "Test-c",
+ 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..1c02490
--- /dev/null
+++ b/tests/Test-cookies-401.px
@@ -0,0 +1,53 @@
+#!/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 (name => "Test-cookies-401",
+ 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..a4b9125
--- /dev/null
+++ b/tests/Test-cookies.px
@@ -0,0 +1,59 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+my $page1 = "Hello, world!\n";
+my $page2 = "Goodbye, Sam.\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|,
+ },
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " http://localhost:{{port}}/one.txt"
+ . " http://localhost:{{port}}/two.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ 'one.txt' => {
+ content => $page1,
+ },
+ 'two.txt' => {
+ content => $page2,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (name => "Test-cookies",
+ 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..8584d0a
--- /dev/null
+++ b/tests/Test-ftp-bad-list.px
@@ -0,0 +1,69 @@
+#!/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 (name => "Test-ftp-bad-list",
+ 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-iri-disabled.px b/tests/Test-ftp-iri-disabled.px
new file mode 100755
index 0000000..d8dac31
--- /dev/null
+++ b/tests/Test-ftp-iri-disabled.px
@@ -0,0 +1,52 @@
+#!/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 (name => "Test-ftp-iri-disabled",
+ 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..c78518f
--- /dev/null
+++ b/tests/Test-ftp-iri-fallback.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_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 (name => "Test-ftp-iri-fallback",
+ 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..46b6fd0
--- /dev/null
+++ b/tests/Test-ftp-iri-recursive.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_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 (name => "Test-ftp-iri-recursive",
+ 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..a4b7fe1
--- /dev/null
+++ b/tests/Test-ftp-iri.px
@@ -0,0 +1,49 @@
+#!/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 -S ftp://localhost:{{port}}/fran${ccedilla_l1}ais.txt";
+
+my $expected_error_code = 0;
+
+my %expected_downloaded_files = (
+ "fran${ccedilla_u8}ais.txt" => {
+ content => $francais,
+ },
+);
+
+###############################################################################
+
+my $the_test = FTPTest->new (name => "Test-ftp-iri",
+ 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-fail.px b/tests/Test-ftp-pasv-fail.px
new file mode 100755
index 0000000..e92f315
--- /dev/null
+++ b/tests/Test-ftp-pasv-fail.px
@@ -0,0 +1,58 @@
+#!/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 (name => "Test-ftp-pasv-fail",
+ 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-recursive.px b/tests/Test-ftp-recursive.px
new file mode 100755
index 0000000..c9d7be4
--- /dev/null
+++ b/tests/Test-ftp-recursive.px
@@ -0,0 +1,55 @@
+#!/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 (name => "Test-ftp-recursive",
+ 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..2b8e25b
--- /dev/null
+++ b/tests/Test-ftp.px
@@ -0,0 +1,45 @@
+#!/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 (name => "Test-ftp",
+ 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-ftp.px b/tests/Test-i-ftp.px
new file mode 100755
index 0000000..aa9f3de
--- /dev/null
+++ b/tests/Test-i-ftp.px
@@ -0,0 +1,80 @@
+#!/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 (name => "Test-i-ftp",
+ 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..10dabcc
--- /dev/null
+++ b/tests/Test-i-http.px
@@ -0,0 +1,92 @@
+#!/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 (name => "Test-i-http",
+ 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..f068ce4
--- /dev/null
+++ b/tests/Test-idn-cmd-utf8.px
@@ -0,0 +1,52 @@
+#!/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 -rH"
+ . " -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 (name => "Test-idn-cmd-utf8",
+ 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..e292aea
--- /dev/null
+++ b/tests/Test-idn-cmd.px
@@ -0,0 +1,52 @@
+#!/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 -rH"
+ . " -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 (name => "Test-idn-cmd",
+ 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..7808b88
--- /dev/null
+++ b/tests/Test-idn-headers.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;
+<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 (name => "Test-idn-headers",
+ 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..9fdbbd0
--- /dev/null
+++ b/tests/Test-idn-meta.px
@@ -0,0 +1,68 @@
+#!/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 => {
+ '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 (name => "Test-idn-meta",
+ 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..bcfadd1
--- /dev/null
+++ b/tests/Test-idn-robots-utf8.px
@@ -0,0 +1,79 @@
+#!/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 -rH"
+ . " -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 (name => "Test-idn-robots-utf8",
+ 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..fb060c4
--- /dev/null
+++ b/tests/Test-idn-robots.px
@@ -0,0 +1,79 @@
+#!/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/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=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/robots.txt" => {
+ code => "200",
+ msg => "Uh-huh",
+ headers => {
+ 'Content-Type' => 'text/plain',
+ },
+ content => '',
+ },
+);
+
+my $cmdline = $WgetTest::WGETPATH . " --iri -rH"
+ . " -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/robots.txt" => {
+ content => '',
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (name => "Test-idn-robots",
+ 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..c226a6e
--- /dev/null
+++ b/tests/Test-iri-disabled.px
@@ -0,0 +1,197 @@
+#!/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 (name => "Test-iri-disabled",
+ 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..d1bed72
--- /dev/null
+++ b/tests/Test-iri-forced-remote.px
@@ -0,0 +1,209 @@
+#!/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 $currency_l1 = "\xA4";
+my $currency_u8 = "\xC2\xA4";
+
+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 => "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=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,
+ },
+ '/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 --trust-server-names --remote-encoding=iso-8859-1 -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_u8}${eacute_u8}n.html" => {
+ content => $pageeen,
+ },
+ "p3_${currency_u8}${currency_u8}${currency_u8}.html" => {
+ content => $pageeuro,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (name => "Test-iri-forced-remote",
+ 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..ad88e4c
--- /dev/null
+++ b/tests/Test-iri-list.px
@@ -0,0 +1,175 @@
+#!/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 (name => "Test-iri-list",
+ 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..fcac35c
--- /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 $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_l15_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_l15}${eacute_u8}.html" => {
+ content => $pagefrancais,
+ },
+);
+
+###############################################################################
+
+my $the_test = HTTPTest->new (name => "Test-iri-percent",
+ 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..4865a1c
--- /dev/null
+++ b/tests/Test-iri.px
@@ -0,0 +1,224 @@
+#!/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
+
+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>
+ <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 => "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",
+ request_headers => {
+ "Referer" => qr|http://localhost:[0-9]+/p1_fran%E7ais.html|,
+ },
+ 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; charset=ISO-8859-1",
+ },
+ content => $pageeuro,
+ },
+ '/p3_%A4%A4%A4.html' => {
+ 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_l15}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 (name => "Test-iri",
+ 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..c853610
--- /dev/null
+++ b/tests/Test-k.px
@@ -0,0 +1,87 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use HTTPTest;
+
+
+###############################################################################
+
+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 $cmdline = $WgetTest::WGETPATH . " -k -r -nH 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 (name => "Test-k",
+ 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..10db455
--- /dev/null
+++ b/tests/Test-meta-robots.px
@@ -0,0 +1,115 @@
+#!/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 (name => "Test-meta-robots",
+ 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..62ee241
--- /dev/null
+++ b/tests/Test-nonexisting-quiet.px
@@ -0,0 +1,44 @@
+#!/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 (name => "Test-nonexisting-quiet",
+ 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..e2ebc35
--- /dev/null
+++ b/tests/Test-noop.px
@@ -0,0 +1,57 @@
+#!/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 (name => "Test-noop",
+ 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..4afc27c
--- /dev/null
+++ b/tests/Test-np.px
@@ -0,0 +1,149 @@
+#!/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 (name => "Test-np",
+ 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.px b/tests/Test-proxied-https-auth.px
new file mode 100755
index 0000000..1de5357
--- /dev/null
+++ b/tests/Test-proxied-https-auth.px
@@ -0,0 +1,129 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+
+use WgetFeature qw(https);
+use WgetTest; # For $WGETPATH.
+
+my $cert_path;
+my $key_path;
+
+if (@ARGV) {
+ my $top_srcdir = shift @ARGV;
+ $key_path = "$top_srcdir/tests/certs/server-key.pem";
+ $cert_path = "$top_srcdir/tests/certs/server-cert.pem";
+}
+
+use HTTP::Daemon;
+use HTTP::Request;
+use IO::Socket::SSL;
+
+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 $alrm = alarm 10;
+
+ my $s = $SOCKET;
+ my $conn;
+ my $rqst;
+ my $rspn;
+ for my $expect_inner_auth (0, 1) {
+ $conn = $s->accept;
+ $rqst = $conn->get_request;
+
+ # TODO: expect no auth the first time, request it, expect it the second
+ # time.
+
+ die "Method not CONNECT\n" if ($rqst->method ne 'CONNECT');
+ $rspn = HTTP::Response->new(200, 'OK');
+ $conn->send_response($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;
+
+ $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');
+
+ # TODO: handle non-persistent connection here.
+ $rspn = HTTP::Response->new(401, 'Unauthorized', [
+ 'WWW-Authenticate' => 'Basic realm="gondor"',
+ Connection => 'close'
+ ]);
+ $rspn->protocol('HTTP/1.0');
+ print $rspn->as_string;
+ print $conn $rspn->as_string;
+ } 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 "=====\n";
+ print $rspn->as_string;
+ print "\n=====\n";
+ print $conn $rspn->as_string;
+ }
+ $conn->close;
+ }
+ undef $conn;
+ undef $s;
+ alarm $alrm;
+}
+
+sub fork_server {
+ my $pid = fork;
+ die "Couldn't fork" if ($pid < 0);
+ return $pid if $pid;
+
+ &do_server;
+ exit;
+}
+
+system ('rm -f needs-auth.txt');
+my $pid = &fork_server;
+
+sleep 1;
+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/{{port}}/$SOCKET->sockport()/e;
+
+my $code = system($cmdline);
+system ('rm -f needs-auth.txt');
+
+warn "Got code: $code\n" if $code;
+kill ('TERM', $pid);
+exit ($code >> 8);
diff --git a/tests/Test-proxy-auth-basic.px b/tests/Test-proxy-auth-basic.px
new file mode 100755
index 0000000..f437678
--- /dev/null
+++ b/tests/Test-proxy-auth-basic.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 = (
+ '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 (name => "Test-auth-basic",
+ 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..48abc57
--- /dev/null
+++ b/tests/Test-restrict-ascii.px
@@ -0,0 +1,69 @@
+#!/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 (name => "Test-restrict-ascii",
+ 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/WgetFeature.cfg b/tests/WgetFeature.cfg
new file mode 100644
index 0000000..a1176e0
--- /dev/null
+++ b/tests/WgetFeature.cfg
@@ -0,0 +1,6 @@
+%skip_messages = (
+ https => "Not running test: Wget under test doesn't support HTTPS.",
+ iri => "Not running test: Wget under test doesn't support IDN/IRI.",
+);
+
+1;
diff --git a/tests/WgetFeature.pm b/tests/WgetFeature.pm
new file mode 100644
index 0000000..f58b998
--- /dev/null
+++ b/tests/WgetFeature.pm
@@ -0,0 +1,29 @@
+package WgetFeature;
+
+use strict;
+use warnings;
+
+use WgetTest;
+
+our %skip_messages;
+require 'WgetFeature.cfg';
+
+sub import
+{
+ my ($class, $feature) = @_;
+
+ my $output = `$WgetTest::WGETPATH --version`;
+ my ($list) = $output =~ /^([\+\-]\S+(?:\s+[\+\-]\S+)+)/m;
+ my %have_features = map {
+ my $feature = $_;
+ $feature =~ s/^.//;
+ ($feature, /^\+/ ? 1 : 0);
+ } split /\s+/, $list;
+
+ unless ($have_features{$feature}) {
+ print $skip_messages{$feature}, "\n";
+ exit 2; # skip
+ }
+}
+
+1;
diff --git a/tests/WgetTest.pm.in b/tests/WgetTest.pm.in
new file mode 100644
index 0000000..58ad140
--- /dev/null
+++ b/tests/WgetTest.pm.in
@@ -0,0 +1,321 @@
+# WARNING!
+# WgetTest.pm is a generated file! Do not edit! Edit WgetTest.pm.in
+# instead.
+
+package WgetTest;
+$VERSION = 0.01;
+
+use strict;
+use warnings;
+
+use Cwd;
+use File::Path;
+
+our $WGETPATH = "@abs_top_builddir@/src/wget";
+
+my @unexpected_downloads = ();
+
+{
+ my %_attr_data = ( # DEFAULT
+ _cmdline => "",
+ _workdir => Cwd::getcwd(),
+ _errcode => 0,
+ _existing => {},
+ _input => {},
+ _name => "",
+ _output => {},
+ _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;
+ #print STDERR "class = ", $class, "\n";
+ #print STDERR "_attr_data {workdir} = ", $WgetTest::_attr_data{_workdir}, "\n";
+ my $self = bless {}, $class;
+ foreach my $attrname ($self->_standard_keys()) {
+ #print STDERR "attrname = ", $attrname, " value = ";
+ my ($argname) = ($attrname =~ /^_(.*)/);
+ 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;
+
+ printf "Running test $self->{_name}\n";
+
+ # Setup
+ my $new_result = $self->_setup();
+ chdir ("$self->{_workdir}/$self->{_name}/input");
+ 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");
+ my $cmdline = $self->{_cmdline};
+ $cmdline = $self->_substitute_port($cmdline);
+ print "Calling $cmdline\n";
+ $errcode =
+ ($cmdline =~ m{^/.*})
+ ? system ($cmdline)
+ : system ("$self->{_workdir}/../src/$cmdline");
+ $errcode >>= 8; # XXX: should handle abnormal error codes.
+
+ # Shutdown server
+ # if we didn't explicitely 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
+ unless ($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;
+
+ #print $self->{_name}, "\n";
+ chdir ($self->{_workdir});
+
+ # Create temporary directory
+ mkdir ($self->{_name});
+ chdir ($self->{_name});
+ mkdir ("input");
+ mkdir ("output");
+
+ # Setup existing files
+ chdir ("output");
+ foreach my $filename (keys %{$self->{_existing}}) {
+ open (FILE, ">$filename")
+ or return "Test failed: cannot open pre-existing file $filename\n";
+
+ my $file = $self->{_existing}->{$filename};
+ print FILE $file->{content}
+ or return "Test failed: cannot write pre-existing file $filename\n";
+
+ close (FILE);
+
+ 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");
+ $self->_setup_server();
+
+ chdir ($self->{_workdir});
+ return;
+}
+
+
+sub _cleanup {
+ my $self = shift;
+
+ chdir ($self->{_workdir});
+ File::Path::rmtree ($self->{_name}) unless $ENV{WGET_TEST_NO_CLEANUP};
+}
+
+# not a method
+sub quotechar {
+ my $c = ord( shift );
+ if ($c >= 0x7 && $c <= 0xD) {
+ return '\\' . qw(a b t n v f r)[$c - 0x7];
+ } else {
+ return sprintf('\\x%02x', $c);
+ }
+}
+
+# not a method
+sub _show_diff {
+ my $SNIPPET_SIZE = 10;
+
+ my ($expected, $actual) = @_;
+
+ my $str = '';
+ 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;
+ for ($i=0; $i != $min; ++$i) {
+ last if substr($expected, $i, 1) ne substr($actual, $i, 1);
+ if (substr($expected, $i, 1) eq '\n') {
+ $line++;
+ $col = 0;
+ } else {
+ $col++;
+ }
+ }
+ 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($&) /ge;
+ $act_snip =~s/[^[:print:]]/ quotechar($&) /ge;
+ $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");
+
+ # use slurp mode to read file content
+ my $old_input_record_separator = $/;
+ undef $/;
+
+ while (my ($filename, $filedata) = each %{$self->{_output}}) {
+ open (FILE, $filename)
+ or return "Test failed: file $filename not downloaded\n";
+
+ my $content = <FILE>;
+ my $expected_content = $filedata->{'content'};
+ $expected_content = $self->_substitute_port($expected_content);
+ unless ($content eq $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 FILE;
+
+ $mtime == $filedata->{'timestamp'}
+ or return "Test failed: wrong timestamp for file $filename\n";
+ }
+
+ close (FILE);
+ }
+
+ $/ = $old_input_record_separator;
+
+ # make sure no unexpected files were downloaded
+ chdir ("$self->{_workdir}/$self->{_name}/output");
+
+ __dir_walk('.', sub { push @unexpected_downloads, $_[0] unless (exists $self->{_output}{$_[0]}) }, sub { shift; return @_ } );
+ if (@unexpected_downloads) {
+ return "Test failed: unexpected downloaded files [" . join(', ', @unexpected_downloads) . "]\n";
+ }
+
+ return "";
+}
+
+
+sub __dir_walk {
+ my ($top, $filefunc, $dirfunc) = @_;
+
+ my $DIR;
+
+ if (-d $top) {
+ my $file;
+ unless (opendir $DIR, $top) {
+ warn "Couldn't open directory $DIR: $!; skipping.\n";
+ return;
+ }
+
+ my @results;
+ while ($file = readdir $DIR) {
+ next if $file eq '.' || $file eq '..';
+ my $nextdir = $top eq '.' ? $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 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;
+ $self->_launch_server(sub { print TO_PARENT "SYNC\n"; close TO_PARENT });
+ } else {
+ # father
+ close TO_PARENT;
+ chomp(my $line = <FROM_CHILD>);
+ close FROM_CHILD;
+ }
+
+ return $pid;
+}
+
+1;
+
+# vim: et ts=4 sw=4
+
diff --git a/tests/certs/server-cert.pem b/tests/certs/server-cert.pem
new file mode 100644
index 0000000..af653c9
--- /dev/null
+++ b/tests/certs/server-cert.pem
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDnDCCAwWgAwIBAgIJAIsoR6UicPPEMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTETMBEGA1UEBxMKU2FudGEgQ2xh
+YTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDEwtN
+aWNhaCBDb3dhbjEfMB0GCSqGSIb3DQEJARYQbWljYWhAY293YW4ubmFtZTAeFw0w
+ODA0MjIwNTQxNDBaFw0wODA1MjIwNTQxNDBaMIGRMQswCQYDVQQGEwJVUzETMBEG
+A1UECBMKQ2FsaWZvcm5pYTETMBEGA1UEBxMKU2FudGEgQ2xhYTEhMB8GA1UEChMY
+SW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDEwtNaWNhaCBDb3dhbjEf
+MB0GCSqGSIb3DQEJARYQbWljYWhAY293YW4ubmFtZTCBnzANBgkqhkiG9w0BAQEF
+AAOBjQAwgYkCgYEAxgJGqBxMUjykBTWHg0jTAH59WbxV6JLMAirwskri0u9o6m9f
+Xw/ZsteKxmypgvwPcDoqZFWF5TB4sEf2l2m7N++mOLtjS9PLBaE8Y0siF1+EMXrI
+mffet9PeXXceuTMFx6bTzls7EwLMvmvSynwFK1j9EHH0mFA19MkeQwWG5zECAwEA
+AaOB+TCB9jAdBgNVHQ4EFgQU0LEi7ld7tvUls/fmbmn80+b//TAwgcYGA1UdIwSB
+vjCBu4AU0LEi7ld7tvUls/fmbmn80+b//TChgZekgZQwgZExCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQHEwpTYW50YSBDbGFhMSEwHwYD
+VQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFDASBgNVBAMTC01pY2FoIENv
+d2FuMR8wHQYJKoZIhvcNAQkBFhBtaWNhaEBjb3dhbi5uYW1lggkAiyhHpSJw88Qw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQBOSi75jsItAkhiYW0Up1d8
+OFA1saDlxBDm7ZUQTcfxIQL75iYfxMUEWeWPRLmNId96a1PgMT6U2+vKrnoNj8bu
+R45xNaFPKxOzp7axWSOp9AJcR6neug2v7lKkKOcQ14dFlKH1AoP+fDuvSAZyfMeC
+7fbIfz3XFNxaR4Rd07w/OQ==
+-----END CERTIFICATE-----
diff --git a/tests/certs/server-key.pem b/tests/certs/server-key.pem
new file mode 100644
index 0000000..f3e6007
--- /dev/null
+++ b/tests/certs/server-key.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,8B09CBCC4587B80C
+
+Yikael4jBlULlN5QU2SIN38OsTqbkcNZGVcoT5rpGf2Mh+aLRRnSvpIAOqNbIcEw
+T8pOtbic9AUh2YaCUK5xw5ou47t2dkieWB0a/amfOAFiajca+94AI+f1k73D85Y9
+bqCkal7pMzIEh22+qIHrUqJLeZdFOIq/C2j4a8Ymv2qmcQ7aKHfmtM3I1XWqg/ql
+GNDwhDxTJ1C6rMvXblDQ5gb4uqdUCw03jVOKTh7kQCNjV6RZqtzFShARiuL2yt4J
+l8H116hT6JtyVAm6kQIws0wqYPiIQxgpHQV21OibDh7WwD+i2sN77vnG06bYi7C6
+l8PkHsB2VbR2GjrZXAW1MGrCIVllbouFJ3zhPTr1DsDuCQ7G9dc8J/lviaWCi+HL
+aWq99V824sjz0CuzRqdUINx1f2XR53+ltSiyXk77NpyUOj/2nGQd2RhsjC/gLHdU
+J5152dOoYRmhftubfNr9Cend76rCkwLhZ1ZOa1LDgkT7HFD+4FIeW02opwGpRo/k
+XxOIkI7EF3em1MXfbRq1GEXr/KBkTKKeiaVUYW4klytX9crOZ+Dxv9KZRANAPzuF
+Tmx1gO4qJL2d8SXlNbUd4MRwCwK2CgUyUknL9kGkt98N2sYUyJETwSWUWbNnP31g
+R0sUKSvJN1k8DfZTpP/8znW1kz+vPa66tuRjBRd96JNUDdqSHHywT4DnR/pUNzdG
+uUD4/x4VgEwMcOYOKAFeOInn5pPINecU8EE4SehLODW3YdQW4hnxxaltuXPAkvNo
+6ST/6HVi/iSJsfvqUuEEXw/SGRMB0aZ+YEIOn4hVnu+gE8N07tuyvQ==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/run-px b/tests/run-px
new file mode 100755
index 0000000..21074cc
--- /dev/null
+++ b/tests/run-px
@@ -0,0 +1,161 @@
+#!/usr/bin/env perl
+
+use 5.006;
+use strict;
+use warnings;
+
+use Term::ANSIColor;
+
+die "Please specify the top source directory.\n" if (!@ARGV);
+my $top_srcdir = shift @ARGV;
+
+my @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-cookies.px',
+ 'Test-cookies-401.px',
+ 'Test-proxy-auth-basic.px',
+ 'Test-proxied-https-auth.px',
+ 'Test-N-HTTP-Content-Disposition.px',
+ 'Test--spider.px',
+ 'Test-c-full.px',
+ 'Test-c-partial.px',
+ 'Test-c-shorter.px',
+ 'Test-c.px',
+ 'Test-E-k-K.px',
+ 'Test-E-k.px',
+ 'Test-ftp.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-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-smaller.px',
+ 'Test-N-no-info.px',
+ 'Test-N--no-content-disposition.px',
+ 'Test-N--no-content-disposition-trivial.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-O-HTTP-Content-Disposition.px',
+ 'Test-O--no-content-disposition.px',
+ 'Test-O--no-content-disposition-trivial.px',
+ 'Test-O-nonexisting.px',
+ 'Test-O.px',
+ 'Test-O-nc.px',
+ 'Test-restrict-ascii.px',
+ 'Test-Restrict-Lowercase.px',
+ 'Test-Restrict-Uppercase.px',
+ 'Test--spider-fail.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',
+);
+
+foreach my $var (qw(SYSTEM_WGETRC WGETRC)) {
+ $ENV{$var} = '/dev/null';
+}
+
+my @tested;
+
+foreach my $test (@tests) {
+ print "Running $test\n\n";
+ system("$^X -I$top_srcdir/tests $top_srcdir/tests/$test $top_srcdir");
+ push @tested, { name => $test, result => $? >> 8 };
+}
+
+foreach my $var (qw(SYSTEM_WGETRC WGETRC)) {
+ delete $ENV{$var};
+}
+
+my %exit = (
+ pass => 0,
+ fail => 1,
+ skip => 2,
+ unknown => 3, # or greater
+);
+
+my %colors = (
+ $exit{pass} => colored('pass:', 'green' ),
+ $exit{fail} => colored('FAIL:', 'red' ),
+ $exit{skip} => colored('Skip:', 'yellow' ),
+ $exit{unknown} => colored('Unknown:', 'magenta'),
+);
+
+print "\n";
+foreach my $test (@tested) {
+ my $colored = exists $colors{$test->{result}}
+ ? $colors{$test->{result}}
+ : $colors{$exit{unknown}};
+ print "$colored $test->{name}\n";
+}
+
+my $count = sub
+{
+ return {
+ pass => sub { scalar grep $_->{result} == $exit{pass}, @tested },
+ fail => sub { scalar grep $_->{result} == $exit{fail}, @tested },
+ skip => sub { scalar grep $_->{result} == $exit{skip}, @tested },
+ unknown => sub { scalar grep $_->{result} >= $exit{unknown}, @tested },
+ }->{$_[0]}->();
+};
+
+my $summary = sub
+{
+ my @lines = (
+ "${\scalar @tested} tests were run",
+ "${\$count->('pass')} PASS, ${\$count->('fail')} FAIL",
+ "${\$count->('skip')} SKIP, ${\$count->('unknown')} UNKNOWN",
+ );
+ my $len_longest = sub
+ {
+ local $_ = 0;
+ foreach my $line (@lines) {
+ if (length $line > $_) {
+ $_ = length $line;
+ }
+ }
+ return $_;
+ }->();
+ return join "\n",
+ '=' x $len_longest,
+ @lines,
+ '=' x $len_longest;
+}->();
+
+print "\n";
+print $count->('fail') || $count->('unknown')
+ ? colored($summary, 'red')
+ : colored($summary, 'green');
+print "\n";
+
+exit $count->('fail') + $count->('unknown');