+2008-05-12 Micah Cowan <micah@cowan.name>
+
+ * NEWS: Translations and -N/-O.
+
+2008-04-30 Micah Cowan <micah@cowan.name>
+
+ * NEWS: Added documentation for changes made in 1.11.2.
+
2008-04-14 Micah Cowan <micah@cowan.name>
* GNUmakefile, lib/Makefile.am, lib/error.c, lib/error.h,
Please send GNU Wget bug reports to <bug-wget@gnu.org>.
\f
-* Changes in Wget (MAINLINE).
+* Changes in Wget 1.11.3
-** Gnulib is now used to provide code for certain portability aspects in
-GNU Wget.
+** Downgraded -N with -O to a warning, rather than an error.
-** Wget uses Automake now as part of its build infrastructure.
+** Translation updates
+\f
+* Changes in Wget 1.11.2
+
+** Fixed a problem in authenticating over HTTPS through a proxy.
+(Regression in 1.11 over 1.10.2.)
+
+** The combination of -r or -p with -O, which was disallowed in 1.11,
+has been downgraded to a warning in 1.11.2. (-O and -N, which was never
+meaningful, is still an error.)
+
+** Further improvements to progress bar displays in non-English locales
+(too many spaces could be inserted, causing the display to scroll).
+
+** Successive invocations of Wget on FTP URLS, with --no-remove-listing
+and --continue, was causing Wget to append, rather than replace,
+information in the .listing file, and thereby download the same files
+multiple times. This has been fixed in 1.11.2.
+
+** Wget 1.11 no longer allowed ".." to persist at the beginning of URLs,
+for improved conformance with RFC 3986. However, this behavior presents
+problems for some FTP setups, and so they are now preserved again, for
+FTP URLs only.
\f
* Changes in Wget 1.11.1.
+2008-05-12 Micah Cowan <micah@cowan.name>
+
+ * wget.texi (Download Options): -N with -O downgraded to a
+ warning.
+
+2008-04-27 Micah Cowan <micah@cowan.name>
+
+ * wget.texi (Download Options) <-O>: Elaborate on why certain
+ options make poor combinations with -O.
+
+2008-04-22 Mike Frysinger <vapier@gentoo.org>
+
+ * sample.wgetrc: Added prefer_family example. Resolves bug
+ #22142.
+
2008-04-11 Micah Cowan <micah@cowan.name>
* wget.texi <Contributors>: Added Julien Buty, Alexander
# To have Wget follow FTP links from HTML files by default, set this
# to on:
#follow_ftp = off
+
+# To try ipv6 addresses first:
+#prefer-family = IPv6
@samp{wget -O - http://foo > file}; @file{file} will be truncated
immediately, and @emph{all} downloaded content will be written there.
+For this reason, @samp{-N} (for timestamp-checking) is not supported
+in combination with @samp{-O}: since @var{file} is always newly
+created, it will always have a very new timestamp. A warning will be
+issued if this combination is used.
+
+Similarly, using @samp{-r} or @samp{-p} with @samp{-O} may not work as
+you expect: Wget won't just download the first file to @var{file} and
+then download the rest to their normal names: @emph{all} downloaded
+content will be placed in @var{file}. This was disabled in version
+1.11, but has been reinstated (with a warning) in 1.11.2, as there are
+some cases where this behavior can actually have some use.
+
Note that a combination with @samp{-k} is only permitted when
-downloading a single document, and combination with any of @samp{-r},
-@samp{-p}, or @samp{-N} is not allowed.
+downloading a single document, as in that case it will just convert
+all relative URIs to external ones; @samp{-k} makes no sense for
+multiple URIs when they're all being downloaded to a single file.
@cindex clobbering, file
@cindex downloading multiple times
* ftp.c (ftp_retrieve_list): Symlinks and other filenames
should be fully quoted.
+2008-05-12 Micah Cowan <micah@cowan.name>
+
+ * main.c (main): Downgrade "-N with -O" to a warning, and switch
+ it off to avoid confusing messages.
+
+2008-04-30 Micah Cowan <micah@cowan.name>
+
+ * progress.c (create_image): Fix glitch where too many spaces are
+ printed on lines that don't display the ETA, in multibyte
+ locales.
+
+2008-04-27 Rabin Vincent <rabin@rab.in>
+
+ * http.c (http_loop): Fix return for the case where we don't
+ download a file because of -nc.
+
+2008-04-27 Micah Cowan <micah@cowan.name>
+
+ * url.c (path_simplify): Go back to allowing leading ".." in
+ paths, but only for FTP URLs.
+ (test_path_simplify): Add scheme-specificness to tests, adapt for
+ mu_run_test.
+
+ * test.c (all_tests): Add test_path_simplify.
+
+ * main.c (main): Downgrade -r, -p with -O to a warning rather than
+ an error; elaborate just a bit more for other -O combination
+ cases.
+
+2008-04-26 Micah Cowan <micah@cowan.name>
+
+ * http.c (gethttp): Move proxy CONNECT handling to below the
+ retry_with_auth label, to deal with properly reconnecting to
+ proxies when we need to authenticate.
+
+2008-04-25 Micah Cowan <micah@cowan.name>
+
+ * Makefile.am: -I foo -> -Ifoo.
+
+2008-04-23 Micah Cowan <micah@cowan.name>
+
+ * utils.c (test_dir_matches_p): Added a test for the case
+ described in issue #20518.
+
+2008-04-22 Jim Paris <jim@jtan.com>
+
+ * openssl.c (ssl_init): Enable combined certificate/key in
+ single file (apparent regression from ~1.9). Resolves issue
+ #22767.
+
+2008-04-22 Steven Schubiger <schubiger@gmail.com>
+
+ * http.c (print_response_line): Changed to make responses always
+ be logged, even in --quiet mode, if --server-response was
+ specified. This is to bring http.c's handling of the situation
+ in line with ftp.c's.
+
+2008-04-22 Pranab Shenoy <pranab.loosinit.shenoy@gmail.com>
+
+ * init.c: Added test_commands_sorted unit test to check is
+ commands are sorted. Fixes bug #21245.
+
+ * test.c: Added test_commands_sorted to the test suite.
+
+2008-04-22 Rabin Vincent <rabin@rab.in>
+
+ * ftp.c (ftp_get_listing): Only remove .listing if it has been
+ created.
+
+2008-04-22 Alain Guibert <alguibert+bts@free.fr>
+
+ * test.h (mu_run_test): Move declaration before statements, for
+ C90 conformance. Fixes bug #22789.
+
+2008-04-22 Mike Frysinger <vapier@gentoo.org>
+
+ * Makefile.am: Move @LIBS@ after other libraries, for better
+ static-linking support. Fixes bug #22143.
+
2008-04-16 Steven Schubiger <schubiger@gmail.com>
* ftp.c: Use Gnulib's quote function for printing filenames and
# The following line is losing on some versions of make!
DEFS = @DEFS@ -DSYSTEM_WGETRC=\"$(sysconfdir)/wgetrc\" -DLOCALEDIR=\"$(localedir)\"
-LIBS = @LIBS@ @LIBSSL@ @LIBGNUTLS@ @LIBINTL@
+LIBS = @LIBSSL@ @LIBGNUTLS@ @LIBINTL@ @LIBS@
bin_PROGRAMS = wget
wget_SOURCES = cmpt.c connect.c convert.c cookies.c ftp.c ftp-basic.c \
nodist_wget_SOURCES = version.c
EXTRA_wget_SOURCES = mswindows.c
LDADD = $(LIBOBJS) ../lib/libgnu.a @MD5_LDADD@
-AM_CPPFLAGS = -I $(top_srcdir)/lib @MD5_CPPFLAGS@
+AM_CPPFLAGS = -I$(top_srcdir)/lib @MD5_CPPFLAGS@
version.c: $(wget_SOURCES) $(LDADD) $(srcdir)/Makefile.am
echo 'const char *version_string = "@VERSION@"' > $@
con->target = old_target;
if (err == RETROK)
- *f = ftp_parse_ls (lf, con->rs);
- else
- *f = NULL;
- if (opt.remove_listing)
{
- if (unlink (lf))
- logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
- else
- logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
+ *f = ftp_parse_ls (lf, con->rs);
+ if (opt.remove_listing)
+ {
+ if (unlink (lf))
+ logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
+ else
+ logprintf (LOG_VERBOSE, _("Removed %s.\n"), quote (lf));
+ }
}
+ else
+ *f = NULL;
xfree (lf);
con->cmd &= ~DO_LIST;
return err;
{
char *copy;
BOUNDED_TO_ALLOCA(b, e, copy);
- logprintf (LOG_VERBOSE, "%s%s\n", prefix,
+ logprintf (LOG_ALWAYS, "%s%s\n", prefix,
quotearg_style (escape_quoting_style, copy));
}
basic_auth_finished = maybe_send_basic_creds(u->host, user, passwd, req);
}
- proxyauth = NULL;
- if (proxy)
- {
- char *proxy_user, *proxy_passwd;
- /* For normal username and password, URL components override
- command-line/wgetrc parameters. With proxy
- authentication, it's the reverse, because proxy URLs are
- normally the "permanent" ones, so command-line args
- should take precedence. */
- if (opt.proxy_user && opt.proxy_passwd)
- {
- proxy_user = opt.proxy_user;
- proxy_passwd = opt.proxy_passwd;
- }
- else
- {
- proxy_user = proxy->user;
- proxy_passwd = proxy->passwd;
- }
- /* #### This does not appear right. Can't the proxy request,
- say, `Digest' authentication? */
- if (proxy_user && proxy_passwd)
- proxyauth = basic_authentication_encode (proxy_user, proxy_passwd);
-
- /* If we're using a proxy, we will be connecting to the proxy
- server. */
- conn = proxy;
-
- /* Proxy authorization over SSL is handled below. */
-#ifdef HAVE_SSL
- if (u->scheme != SCHEME_HTTPS)
-#endif
- request_set_header (req, "Proxy-Authorization", proxyauth, rel_value);
- }
-
/* Generate the Host header, HOST:PORT. Take into account that:
- Broken server-side software often doesn't recognize the PORT
without authorization header fails. (Expected to happen at least
for the Digest authorization scheme.) */
+ proxyauth = NULL;
+ if (proxy)
+ {
+ char *proxy_user, *proxy_passwd;
+ /* For normal username and password, URL components override
+ command-line/wgetrc parameters. With proxy
+ authentication, it's the reverse, because proxy URLs are
+ normally the "permanent" ones, so command-line args
+ should take precedence. */
+ if (opt.proxy_user && opt.proxy_passwd)
+ {
+ proxy_user = opt.proxy_user;
+ proxy_passwd = opt.proxy_passwd;
+ }
+ else
+ {
+ proxy_user = proxy->user;
+ proxy_passwd = proxy->passwd;
+ }
+ /* #### This does not appear right. Can't the proxy request,
+ say, `Digest' authentication? */
+ if (proxy_user && proxy_passwd)
+ proxyauth = basic_authentication_encode (proxy_user, proxy_passwd);
+
+ /* If we're using a proxy, we will be connecting to the proxy
+ server. */
+ conn = proxy;
+
+ /* Proxy authorization over SSL is handled below. */
+#ifdef HAVE_SSL
+ if (u->scheme != SCHEME_HTTPS)
+#endif
+ request_set_header (req, "Proxy-Authorization", proxyauth, rel_value);
+ }
+
keep_alive = false;
/* Establish the connection. */
if (has_html_suffix_p (hstat.local_file))
*dt |= TEXTHTML;
- return RETRUNNEEDED;
+ ret = RETROK;
+ goto exit;
}
/* Reset the counter. */
#ifdef TESTING
+const char *
+test_commands_sorted()
+{
+ int prev_idx = 0, next_idx = 1;
+ int command_count = countof (commands) - 1;
+ int cmp = 0;
+ while (next_idx <= command_count)
+ {
+ cmp = strcasecmp (commands[prev_idx].name, commands[next_idx].name);
+ if (cmp > 0)
+ {
+ mu_assert ("FAILED", false);
+ break;
+ }
+ else
+ {
+ prev_idx ++;
+ next_idx ++;
+ }
+ }
+ return NULL;
+}
+
const char *
test_cmd_spec_restrict_file_names()
{
exit (1);
}
#endif
- if (opt.output_document
- && (opt.page_requisites
- || opt.recursive
- || opt.timestamping))
- {
- printf (_("Cannot specify -r, -p or -N if -O is given.\n"));
- print_usage ();
- exit (1);
- }
- if (opt.output_document
- && opt.convert_links
- && nurl > 1)
+ if (opt.output_document)
{
- printf (_("Cannot specify both -k and -O if multiple URLs are given.\n"));
+ if (opt.convert_links
+ && (nurl > 1 || opt.page_requisites || opt.recursive))
+ {
+ fputs (_("\
+Cannot specify both -k and -O if multiple URLs are given, or in combination\n\
+with -p or -r. See the manual for details.\n\n"), stdout);
print_usage ();
exit (1);
+ }
+ if (opt.page_requisites
+ || opt.recursive)
+ {
+ logprintf (LOG_NOTQUIET, "%s", _("\
+WARNING: combining -O with -r or -p will mean that all downloaded content\n\
+will be placed in the single file you specified.\n\n"));
+ }
+ if (opt.timestamping)
+ {
+ logprintf (LOG_NOTQUIET, "%s", _("\
+WARNING: timestamping does nothing in combination with -O. See the manual\n\
+for details.\n\n"));
+ opt.timestamping = false;
+ }
}
if (!nurl && !opt.input_filename)
than examining the error stack after a failed SSL_connect. */
SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);
+ /* Use the private key from the cert file unless otherwise specified. */
+ if (opt.cert_file && !opt.private_key)
+ {
+ opt.private_key = opt.cert_file;
+ opt.private_key_type = opt.cert_type;
+ }
+
if (opt.cert_file)
if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
key_type_to_ssl_type (opt.cert_type))
# define count_cols(mbs) ((int)(strlen(mbs)))
#endif
-/* Translation note: "ETA" is English-centric, but this must
- be short, ideally 3 chars. Abbreviate if necessary. */
-static const char eta_str[] = N_(" eta %s");
-static const char *eta_trans;
-static int bytes_cols_diff;
-
const char *
-get_eta (void)
+get_eta (int *bcd)
{
+ /* Translation note: "ETA" is English-centric, but this must
+ be short, ideally 3 chars. Abbreviate if necessary. */
+ static const char eta_str[] = N_(" eta %s");
+ static const char *eta_trans;
+ static int bytes_cols_diff;
if (eta_trans == NULL)
{
int nbytes;
bytes_cols_diff = nbytes - ncols;
}
+ if (bcd != NULL)
+ *bcd = bytes_cols_diff;
+
return eta_trans;
}
int dlbytes_size = 1 + MAX (size_grouped_len, 11);
int progress_size = bp->width - (4 + 2 + dlbytes_size + 8 + 14);
+ /* The difference between the number of bytes used,
+ and the number of columns used. */
+ int bytes_cols_diff = 0;
+
if (progress_size < 5)
progress_size = 0;
bp->last_eta_time = dl_total_time;
}
- sprintf (p, get_eta(), eta_to_human_short (eta, false));
+ sprintf (p, get_eta(&bytes_cols_diff),
+ eta_to_human_short (eta, false));
move_to_end (p);
}
else if (bp->total_length > 0)
else
{
/* When the download is done, print the elapsed time. */
+ int nbytes;
+ int ncols;
/* Note to translators: this should not take up more room than
available here. Abbreviate if necessary. */
strcpy (p, _(" in "));
- move_to_end (p); /* not p+=6, think translations! */
+ nbytes = strlen (p);
+ ncols = count_cols (p);
+ bytes_cols_diff = nbytes - ncols;
+ p += nbytes;
if (dl_total_time >= 10)
strcpy (p, eta_to_human_short ((int) (dl_total_time + 0.5), false));
else
const char *test_parse_content_disposition();
const char *test_subdir_p();
const char *test_dir_matches_p();
+const char *test_commands_sorted();
const char *test_cmd_spec_restrict_file_names();
+const char *test_path_simplify ();
const char *test_append_uri_pathel();
const char *test_are_urls_equal();
const char *test_is_robots_txt_url();
mu_run_test (test_parse_content_disposition);
mu_run_test (test_subdir_p);
mu_run_test (test_dir_matches_p);
+ mu_run_test (test_commands_sorted);
mu_run_test (test_cmd_spec_restrict_file_names);
+ mu_run_test (test_path_simplify);
mu_run_test (test_append_uri_pathel);
mu_run_test (test_are_urls_equal);
mu_run_test (test_is_robots_txt_url);
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) \
do { \
+ const char *message; \
puts("RUNNING TEST " #test "..."); \
- const char *message = test(); \
+ message = test(); \
tests_run++; \
if (message) return message; \
puts("PASSED\n"); \
/* Forward declarations: */
-static bool path_simplify (char *);
+static bool path_simplify (enum url_scheme, char *);
\f
/* Support for escaping and unescaping of URL strings. */
u->passwd = passwd;
u->path = strdupdelim (path_b, path_e);
- path_modified = path_simplify (u->path);
+ path_modified = path_simplify (scheme, u->path);
split_path (u->path, &u->dir, &u->file);
host_modified = lowercase_str (u->host);
test case. */
static bool
-path_simplify (char *path)
+path_simplify (enum url_scheme scheme, char *path)
{
char *h = path; /* hare */
char *t = path; /* tortoise */
+ char *beg = path;
char *end = strchr (path, '\0');
while (h < end)
{
/* Handle "../" by retreating the tortoise by one path
element -- but not past beggining. */
- if (t > path)
+ if (t > beg)
{
/* Move backwards until T hits the beginning of the
previous path element or the beginning of path. */
- for (--t; t > path && t[-1] != '/'; t--)
+ for (--t; t > beg && t[-1] != '/'; t--)
;
}
+ else if (scheme == SCHEME_FTP)
+ {
+ /* If we're at the beginning, copy the "../" literally
+ and move the beginning so a later ".." doesn't remove
+ it. This violates RFC 3986; but we do it for FTP
+ anyway because there is otherwise no way to get at a
+ parent directory, when the FTP server drops us in a
+ non-root directory (which is not uncommon). */
+ beg = t + 3;
+ goto regular;
+ }
h += 3;
}
else
{
+ regular:
/* A regular path element. If H hasn't advanced past T,
simply skip to the next path element. Otherwise, copy
the path element until the next slash. */
return (*p == 0 && *q == 0 ? true : false);
}
\f
-#if 0
+#ifdef TESTING
/* Debugging and testing support for path_simplify. */
+#if 0
/* Debug: run path_simplify on PATH and return the result in a new
string. Useful for calling from the debugger. */
static char *
path_simplify (copy);
return copy;
}
+#endif
-static void
-run_test (char *test, char *expected_result, bool expected_change)
+static const char *
+run_test (char *test, char *expected_result, enum url_scheme scheme,
+ bool expected_change)
{
char *test_copy = xstrdup (test);
- bool modified = path_simplify (test_copy);
+ bool modified = path_simplify (scheme, test_copy);
if (0 != strcmp (test_copy, expected_result))
{
printf ("Failed path_simplify(\"%s\"): expected \"%s\", got \"%s\".\n",
test, expected_result, test_copy);
+ mu_assert ("", 0);
}
if (modified != expected_change)
{
test);
}
xfree (test_copy);
+ mu_assert ("", modified == expected_change);
+ return NULL;
}
-static void
+const char *
test_path_simplify (void)
{
static struct {
char *test, *result;
+ enum url_scheme scheme;
bool should_modify;
} tests[] = {
- { "", "", false },
- { ".", "", true },
- { "./", "", true },
- { "..", "", true },
- { "../", "", true },
- { "foo", "foo", false },
- { "foo/bar", "foo/bar", false },
- { "foo///bar", "foo///bar", false },
- { "foo/.", "foo/", true },
- { "foo/./", "foo/", true },
- { "foo./", "foo./", false },
- { "foo/../bar", "bar", true },
- { "foo/../bar/", "bar/", true },
- { "foo/bar/..", "foo/", true },
- { "foo/bar/../x", "foo/x", true },
- { "foo/bar/../x/", "foo/x/", true },
- { "foo/..", "", true },
- { "foo/../..", "", true },
- { "foo/../../..", "", true },
- { "foo/../../bar/../../baz", "baz", true },
- { "a/b/../../c", "c", true },
- { "./a/../b", "b", true }
+ { "", "", SCHEME_HTTP, false },
+ { ".", "", SCHEME_HTTP, true },
+ { "./", "", SCHEME_HTTP, true },
+ { "..", "", SCHEME_HTTP, true },
+ { "../", "", SCHEME_HTTP, true },
+ { "..", "..", SCHEME_FTP, false },
+ { "../", "../", SCHEME_FTP, false },
+ { "foo", "foo", SCHEME_HTTP, false },
+ { "foo/bar", "foo/bar", SCHEME_HTTP, false },
+ { "foo///bar", "foo///bar", SCHEME_HTTP, false },
+ { "foo/.", "foo/", SCHEME_HTTP, true },
+ { "foo/./", "foo/", SCHEME_HTTP, true },
+ { "foo./", "foo./", SCHEME_HTTP, false },
+ { "foo/../bar", "bar", SCHEME_HTTP, true },
+ { "foo/../bar/", "bar/", SCHEME_HTTP, true },
+ { "foo/bar/..", "foo/", SCHEME_HTTP, true },
+ { "foo/bar/../x", "foo/x", SCHEME_HTTP, true },
+ { "foo/bar/../x/", "foo/x/", SCHEME_HTTP, true },
+ { "foo/..", "", SCHEME_HTTP, true },
+ { "foo/../..", "", SCHEME_HTTP, true },
+ { "foo/../../..", "", SCHEME_HTTP, true },
+ { "foo/../../bar/../../baz", "baz", SCHEME_HTTP, true },
+ { "foo/../..", "..", SCHEME_FTP, true },
+ { "foo/../../..", "../..", SCHEME_FTP, true },
+ { "foo/../../bar/../../baz", "../../baz", SCHEME_FTP, true },
+ { "a/b/../../c", "c", SCHEME_HTTP, true },
+ { "./a/../b", "b", SCHEME_HTTP, true }
};
int i;
for (i = 0; i < countof (tests); i++)
{
+ const char *message;
char *test = tests[i].test;
char *expected_result = tests[i].result;
+ enum url_scheme scheme = tests[i].scheme;
bool expected_change = tests[i].should_modify;
- run_test (test, expected_result, expected_change);
+ message = run_test (test, expected_result, scheme, expected_change);
+ if (message) return message;
}
+ return NULL;
}
-#endif
-\f
-#ifdef TESTING
const char *
test_append_uri_pathel()
{ { "*/*COMPLETE", NULL, NULL }, "foo/!COMPLETE", true },
{ { "/dir with spaces", NULL, NULL }, "dir with spaces", true },
{ { "/dir*with*spaces", NULL, NULL }, "dir with spaces", true },
+ { { "/Tmp/has", NULL, NULL }, "/Tmp/has space", false },
+ { { "/Tmp/has", NULL, NULL }, "/Tmp/has,comma", false },
};
for (i = 0; i < countof(test_array); ++i)
+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.in, Test-proxy-auth-basic.px: Added a test for
+ * 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>
./unit-tests$(EXEEXT)
run-px-tests: WgetTest.pm
+ $(PERLRUN) $(srcdir)/Test-proxied-https-auth.px && echo && echo
$(PERLRUN) $(srcdir)/Test-proxy-auth-basic.px && echo && echo
$(PERLRUN) $(srcdir)/Test-auth-basic.px && echo && echo
$(PERLRUN) $(srcdir)/Test-c-full.px && echo && echo
--- /dev/null
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use WgetTest; # For $WGETPATH.
+use HTTP::Daemon;
+use HTTP::Request;
+use IO::Socket::SSL 'debug4';
+
+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 = HTTP::Daemon->new (LocalAddr => 'localhost',
+ LocalPort => '8080',
+ ReuseAddr => 1) or die "Cannot create server!!!";
+ 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);
+
+ $conn = IO::Socket::SSL->new_from_fd($conn->fileno, SSL_server => 1,
+ SSL_passwd_cb => sub { return "Hello"; })
+ 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");
+ 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');
+&fork_server;
+
+sleep 1;
+my $cmdline = $WgetTest::WGETPATH . " --user=fiddle-dee-dee"
+ . " --password=Dodgson -e https_proxy=localhost:8080"
+ . " --no-check-certificate"
+ . " https://no.such.domain/needs-auth.txt";
+
+my $code = system($cmdline);
+
+warn "Got code: $code\n" if $code;
+exit $code;