]> sjero.net Git - wget/commitdiff
Merge quote module stuff with current mainline.
authorMicah Cowan <micah@cowan.name>
Fri, 16 May 2008 02:13:08 +0000 (19:13 -0700)
committerMicah Cowan <micah@cowan.name>
Fri, 16 May 2008 02:13:08 +0000 (19:13 -0700)
20 files changed:
ChangeLog
NEWS
doc/ChangeLog
doc/sample.wgetrc
doc/wget.texi
src/ChangeLog
src/Makefile.am
src/ftp.c
src/http.c
src/init.c
src/main.c
src/openssl.c
src/progress.c
src/test.c
src/test.h
src/url.c
src/utils.c
tests/ChangeLog
tests/Makefile.am
tests/Test-proxied-https-auth.px [new file with mode: 0755]

index f5b5d371647cca02e3c2c2dd847aff140f72cb00..a0a295d85ad6e83cd7811af2fc7b8c59db20eb78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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,
diff --git a/NEWS b/NEWS
index b87f9d98cb4ac40337d1de416b124d6ceb2aa140..24a097c482bf6e7be6fdf7325b104411a9c5d145 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,12 +6,33 @@ See the end for copying conditions.
 
 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.
 
index c5614d4ae2a27b5b7a8588f559237c5c7848796c..44c5cd89cd828fa20460aa2e4df42565f29aa76e 100644 (file)
@@ -1,3 +1,18 @@
+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
index 7aeacc74e1dc087f2859d955ce38a986d1d223ef..c69596bf1c9f1f32bebb25d17561227ddb32b217 100644 (file)
@@ -110,3 +110,6 @@ waitretry = 10
 # 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
index 583c7fcf2ab370df8583ab45f17d202cef2a8b98..3c29f005d27ab054852eb7587b6baac9502c761d 100644 (file)
@@ -551,9 +551,22 @@ analogous to shell redirection:
 @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
index c2db9da9a881daa0204c6c2ffd20845881e3c62d..f223d3593557a42dae456ceae2bfcd5b7108c689 100644 (file)
@@ -3,6 +3,85 @@
        * 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
index 4b351204dfb93b8190ca19b30892fdeea9d8176a..451754914cb07dc09c58183c7c383ac621e09b04 100644 (file)
@@ -32,7 +32,7 @@
 
 # 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  \
@@ -48,7 +48,7 @@ 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@"' > $@
index 59ba1c1669a6907a130e325e3ead32e30e9e77ae..0ecc6bcb1dafbb417ed12922f75b3f433e83a812 100644 (file)
--- a/src/ftp.c
+++ b/src/ftp.c
@@ -1330,16 +1330,18 @@ ftp_get_listing (struct url *u, ccon *con, struct fileinfo **f)
   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;
index 5b04fe4a59ef82db67996c9d8c95bfc0ba85cbcc..0252d3421f07f491a59c443f50ab08aa6480d2af 100644 (file)
@@ -810,7 +810,7 @@ print_response_line(const char *prefix, const char *b, const char *e)
 {
   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));
 }
 
@@ -1498,41 +1498,6 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
       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
@@ -1603,6 +1568,41 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
      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.  */
@@ -2391,7 +2391,8 @@ File %s already there; not retrieving.\n\n"),
       if (has_html_suffix_p (hstat.local_file))
         *dt |= TEXTHTML;
 
-      return RETRUNNEEDED;
+      ret = RETROK;
+      goto exit;
     }
 
   /* Reset the counter. */
index e079df95d12d1b2ac4afd24fb98df1a035260a51..fcb7c2ccbd8254c9a680ff8d536a13d891cb2a75 100644 (file)
@@ -1530,6 +1530,29 @@ cleanup (void)
 
 #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()
 {
index b1e99695f19f124bc45af691a145be5b9324bc98..421a5501b6e34e4795a9a62e779289e42aff1a2f 100644 (file)
@@ -880,22 +880,31 @@ Can't timestamp and not clobber old files at the same time.\n"));
       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)
index 8a5cc0edd6f77a6b43179e491e696c9d2eb5a6d4..f5239ede6e8f0b478a81625261a805165e13403c 100644 (file)
@@ -210,6 +210,13 @@ ssl_init ()
      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))
index 8b9b1013a255668de285219819bbefc088a118e7..de108e76be44bb72e29bcdeef9a2a8e800472f54 100644 (file)
@@ -797,15 +797,14 @@ count_cols (const char *mbs)
 # 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;
@@ -829,6 +828,9 @@ get_eta (void)
       bytes_cols_diff = nbytes - ncols;
     }
 
+  if (bcd != NULL)
+    *bcd = bytes_cols_diff;
+
   return eta_trans;
 }
 
@@ -881,6 +883,10 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
   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;
 
@@ -1023,7 +1029,8 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
               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)
@@ -1035,11 +1042,16 @@ create_image (struct bar_progress *bp, double dl_total_time, bool done)
   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
index 04658bc75e79a49ca5a2c359c16f361dcbcaf34a..3187900db44c5da3c3f01746dcf69adb012b4434 100644 (file)
@@ -38,7 +38,9 @@ as that of the covered work.  */
 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();
@@ -51,7 +53,9 @@ all_tests()
   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);
index 496954e20697aa2a425014aebc8741b8cc9e933c..91baf589ac6651d3638885406f5f702d73b4bf4c 100644 (file)
@@ -34,8 +34,9 @@ as that of the covered work.  */
 #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"); \
index a561725a200db5bebc75d5284bdbdb21130c7ff9..87ba3cc9dc3e848b6617bb2680f9f90d99d14a5a 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -81,7 +81,7 @@ static struct scheme_data supported_schemes[] =
 
 /* Forward declarations: */
 
-static bool path_simplify (char *);
+static bool path_simplify (enum url_scheme, char *);
 \f
 /* Support for escaping and unescaping of URL strings.  */
 
@@ -829,7 +829,7 @@ url_parse (const char *url, int *error)
   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);
@@ -1526,10 +1526,11 @@ url_file_name (const struct url *u)
    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)
@@ -1545,17 +1546,29 @@ path_simplify (char *path)
         {
           /* 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.  */
@@ -1991,9 +2004,10 @@ are_urls_equal (const char *u1, const char *u2)
   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 *
@@ -2003,17 +2017,20 @@ ps (char *path)
   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)
     {
@@ -2025,51 +2042,60 @@ run_test (char *test, char *expected_result, bool 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()
index c4f78fe4b766c05b8b1def56b22650ff8bfb0737..a6c84491605517a8f0af7637ff681c70e943340f 100644 (file)
@@ -2231,6 +2231,8 @@ test_dir_matches_p()
     { { "*/*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) 
index e6972b500c7fcba3b1b515cb84fa2a0ad5282eb9..f485f93c20cdb0b147cada02e93c2a05c8940bae 100644 (file)
@@ -1,6 +1,12 @@
+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>
index 224cb9cc56fbdb8d4c7b44c03003f5628e388be0..fefdbf1d1d590169e7826a923181e25ad37e0391 100644 (file)
@@ -46,6 +46,7 @@ run-unit-tests: unit-tests$(EXEEXT)
        ./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
diff --git a/tests/Test-proxied-https-auth.px b/tests/Test-proxied-https-auth.px
new file mode 100755 (executable)
index 0000000..2260658
--- /dev/null
@@ -0,0 +1,101 @@
+#!/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;