Fix error message for failed authorization; allow no user-agent

Hrvoje Niksic <[email protected]> Fri, 06 May 2005 19:15:10 +0200
Newsgroups gmane.comp.web.wget.patches
Message-ID <[email protected]>
Current Wget can bogusly complains about "unknown authentication
scheme" for basic authentication.

This patch fixes this problem and adds the feature of specifying -U ""
to send no User-Agent header.  (This might be useful in some cases.)
The latter is technically a new feature, but there should be no loss
of stability.  Mauro, if you disagree with this, please let me know
and I'll back it out.

2005-05-06  Hrvoje Niksic  <[email protected]>

	* init.c (cmd_spec_useragent): Allow empty User-Agent.

	* http.c (gethttp): Don't print "unknown authentication scheme"
	for failed Basic authentication.
	(SET_USER_AGENT): Don't set user-agent if opt.useragent is empty.
	(gethttp): Use alloca for allocation of www_authenticate.

Index: src/http.c
===================================================================
RCS file: /pack/anoncvs/wget/src/http.c,v
retrieving revision 1.177
diff -u -r1.177 http.c
--- src/http.c	2005/05/06 13:56:16	1.177
+++ src/http.c	2005/05/06 17:13:00
@@ -1113,13 +1113,13 @@
    && (ISSPACE (line[sizeof (string_constant) - 1])			\
        || !line[sizeof (string_constant) - 1]))
 
-#define SET_USER_AGENT(req)						\
-  if (opt.useragent)							\
-    request_set_header (req, "User-Agent", opt.useragent, rel_none);	\
-  else									\
+#define SET_USER_AGENT(req) do {					\
+  if (!opt.useragent)							\
     request_set_header (req, "User-Agent",				\
-			aprintf ("Wget/%s", version_string), rel_value);
-
+			aprintf ("Wget/%s", version_string), rel_value); \
+  else if (*opt.useragent)						\
+    request_set_header (req, "User-Agent", opt.useragent, rel_none);	\
+} while (0)
 
 /* Retrieve a document through HTTP protocol.  It recognizes status
    code, and correctly handles redirections.  It closes the network
@@ -1622,18 +1622,11 @@
 	    CLOSE_INVALIDATE (sock);
 	}
       pconn.authorized = 0;
-      if (auth_finished || !(user && passwd))
+      if (!auth_finished && (user && passwd))
 	{
-	  /* If we have tried it already, then there is not point
-	     retrying it.  */
-	  logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
-	}
-      else
-	{
-	  /* IIS sometimes sends two instances of WWW-Authenticate
-	     header, one with the keyword "negotiate", and other with
-	     useful data.  Loop over all occurrences of this header
-	     and use the one we recognize.  */
+	  /* IIS sends multiple copies of WWW-Authenticate, one with
+	     the value "negotiate", and other(s) with data.  Loop over
+	     all the occurrences and pick the one we recognize.  */
 	  int wapos;
 	  const char *wabeg, *waend;
 	  char *www_authenticate = NULL;
@@ -1643,18 +1636,20 @@
 	       ++wapos)
 	    if (known_authentication_scheme_p (wabeg, waend))
 	      {
-		www_authenticate = strdupdelim (wabeg, waend);
+		BOUNDED_TO_ALLOCA (wabeg, waend, www_authenticate);
 		break;
 	      }
-	  /* If the authentication header is missing or recognized, or
-	     if the authentication scheme is "Basic" (which we send by
-	     default), there's no sense in retrying.  */
-	  if (!www_authenticate
-	      || BEGINS_WITH (www_authenticate, "Basic"))
-	    {
-	      xfree_null (www_authenticate);
-	      logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
-	    }
+
+	  if (!www_authenticate)
+	    /* If the authentication header is missing or
+	       unrecognized, there's no sense in retrying.  */
+	    logputs (LOG_NOTQUIET, _("Unknown authentication scheme.\n"));
+	  else if (BEGINS_WITH (www_authenticate, "Basic"))
+	    /* If the authentication scheme is "Basic", which we send
+	       by default, there's no sense in retrying either.  (This
+	       should be changed when we stop sending "Basic" data by
+	       default.)  */
+	    ;
 	  else
 	    {
 	      char *pth;
@@ -1669,10 +1664,10 @@
 	      if (BEGINS_WITH (www_authenticate, "NTLM"))
 		ntlm_seen = 1;
 	      xfree (pth);
-	      xfree (www_authenticate);
 	      goto retry_with_auth;
 	    }
 	}
+      logputs (LOG_NOTQUIET, _("Authorization failed.\n"));
       request_free (req);
       return AUTHFAILED;
     }
Index: src/init.c
===================================================================
RCS file: /pack/anoncvs/wget/src/init.c,v
retrieving revision 1.112
diff -u -r1.112 init.c
--- src/init.c	2005/05/05 18:45:04	1.112
+++ src/init.c	2005/05/06 17:13:02
@@ -1292,9 +1292,8 @@
 static int
 cmd_spec_useragent (const char *com, const char *val, void *place_ignored)
 {
-  /* Just check for empty string and newline, so we don't throw total
-     junk to the server.  */
-  if (!*val || strchr (val, '\n'))
+  /* Disallow embedded newlines.  */
+  if (strchr (val, '\n'))
     {
       fprintf (stderr, _("%s: %s: Invalid value `%s'.\n"),
 	       exec_name, com, val);