]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Don't complain about "unknown authentication scheme" if the scheme
[wget] / src / http.c
index 97a773a1e2d720abe45ac5041c3245e0477d49a7..d046eaea5f65261f5d302dc4790a181fcf986b5c 100644 (file)
@@ -1113,13 +1113,13 @@ time_t http_atotm PARAMS ((const char *));
    && (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 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
            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 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
               ++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 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
              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;
     }
@@ -2627,36 +2622,35 @@ http_atotm (const char *time_string)
      implementations I've tested.  */
 
   static const char *time_formats[] = {
-    "%a, %d %b %Y %T",         /* RFC1123: Thu, 29 Jan 1998 22:12:57 */
-    "%A, %d-%b-%y %T",         /* RFC850:  Thursday, 29-Jan-98 22:12:57 */
-    "%a, %d-%b-%Y %T",         /* pseudo-RFC850:  Thu, 29-Jan-1998 22:12:57
-                                  (google.com uses this for their cookies.) */
+    "%a, %d %b %Y %T",         /* rfc1123: Thu, 29 Jan 1998 22:12:57 */
+    "%A, %d-%b-%y %T",         /* rfc850:  Thursday, 29-Jan-98 22:12:57 */
+    "%a, %d-%b-%Y %T",         /* rfc850+: Thu, 29-Jan-1998 22:12:57
+                                  (post-y2k-rfc850; apparently google
+                                  uses this for their cookies.) */
     "%a %b %d %T %Y"           /* asctime: Thu Jan 29 22:12:57 1998 */
   };
-
   int i;
-  struct tm t;
-
-  /* According to Roger Beeman, we need to initialize tm_isdst, since
-     strptime won't do it.  */
-  t.tm_isdst = 0;
-
-  /* Note that under foreign locales Solaris strptime() fails to
-     recognize English dates, which renders this function useless.  We
-     solve this by being careful not to affect LC_TIME when
-     initializing locale.
-
-     Another solution would be to temporarily set locale to C, invoke
-     strptime(), and restore it back.  This is slow and dirty,
-     however, and locale support other than LC_MESSAGES can mess other
-     things, so I rather chose to stick with just setting LC_MESSAGES.
-
-     GNU strptime does not have this problem because it recognizes
-     both international and local dates.  */
 
   for (i = 0; i < countof (time_formats); i++)
-    if (check_end (strptime (time_string, time_formats[i], &t)))
-      return mktime_from_utc (&t);
+    {
+      struct tm t;
+
+      /* Some versions of strptime use the existing contents of struct
+        tm to recalculate the date according to format.  Zero it out
+        to prevent garbage from the stack influencing strptime.  */
+      xzero (t);
+
+      /* Note that Solaris strptime fails to recognize English month
+        names under non-English locales.  We work around this by not
+        setting the LC_TIME category.  Another way would be to
+        temporarily set locale to C before invoking strptime, but
+        that's slow and messy.  GNU strptime does not have this
+        problem because it recognizes English names along with the
+        local ones.  */
+
+      if (check_end (strptime (time_string, time_formats[i], &t)))
+       return mktime_from_utc (&t);
+    }
 
   /* All formats have failed.  */
   return -1;