]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Fix #20747: Wget was returning error for non-recursive --spider when file exists.
[wget] / src / http.c
index 26342593ac582c381c37a3988da34046e8204ca9..0e292918612a0fa861c9b8365b637303dfa2678a 100644 (file)
@@ -2305,6 +2305,7 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
 {
   int count;
   bool got_head = false;         /* used for time-stamping and filename detection */
+  bool time_came_from_head = false;
   bool got_name = false;
   char *tms;
   const char *tmrate;
@@ -2313,6 +2314,7 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
   wgint local_size = 0;          /* the size of the local file */
   struct http_stat hstat;        /* HTTP status */
   struct_stat st;  
+  bool send_head_first = true;
 
   /* Assert that no value for *LOCAL_FILE was passed. */
   assert (local_file == NULL || *local_file == NULL);
@@ -2350,6 +2352,19 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
   /* Reset the document type. */
   *dt = 0;
   
+  /* Skip preliminary HEAD request if we're not in spider mode AND
+   * if -O was given or HTTP Content-Disposition support is disabled. */
+  if (!opt.spider
+      && (got_name || !opt.content_disposition))
+    send_head_first = false;
+
+  /* Send preliminary HEAD request if -N is given and we have an existing 
+   * destination file. */
+  if (opt.timestamping 
+      && !opt.content_disposition
+      && file_exists_p (url_file_name (u)))
+    send_head_first = true;
+  
   /* THE loop */
   do
     {
@@ -2391,8 +2406,7 @@ Spider mode enabled. Check if remote file exists.\n"));
       /* Default document type is empty.  However, if spider mode is
          on or time-stamping is employed, HEAD_ONLY commands is
          encoded within *dt.  */
-      if (((opt.spider || opt.timestamping) && !got_head)
-          || (opt.always_rest && !got_name))
+      if (send_head_first && !got_head) 
         *dt |= HEAD_ONLY;
       else
         *dt &= ~HEAD_ONLY;
@@ -2433,7 +2447,7 @@ Spider mode enabled. Check if remote file exists.\n"));
       /* Get the new location (with or without the redirection).  */
       if (hstat.newloc)
         *newloc = xstrdup (hstat.newloc);
-      
+
       switch (err)
         {
         case HERR: case HEOF: case CONSOCKERR: case CONCLOSED:
@@ -2484,7 +2498,7 @@ Spider mode enabled. Check if remote file exists.\n"));
           /* All possibilities should have been exhausted.  */
           abort ();
         }
-     
+      
       if (!(*dt & RETROKF))
         {
           char *hurl = NULL;
@@ -2494,9 +2508,17 @@ Spider mode enabled. Check if remote file exists.\n"));
               hurl = url_string (u, URL_AUTH_HIDE_PASSWD);
               logprintf (LOG_NONVERBOSE, "%s:\n", hurl);
             }
+
+          /* Fall back to GET if HEAD fails with a 500 or 501 error code. */
+          if (*dt & HEAD_ONLY
+              && (hstat.statcode == 500 || hstat.statcode == 501))
+            {
+              got_head = true;
+              continue;
+            }
           /* Maybe we should always keep track of broken links, not just in
            * spider mode.  */
-          if (opt.spider)
+          else if (opt.spider)
             {
               /* #### Again: ugly ugly ugly! */
               if (!hurl) 
@@ -2517,7 +2539,7 @@ Remote file does not exist -- broken link!!!\n"));
         }
 
       /* Did we get the time-stamp? */
-      if (!got_head)
+      if (send_head_first && !got_head)
         {
           bool restart_loop = false;
 
@@ -2533,6 +2555,8 @@ Last-modified header missing -- time-stamps turned off.\n"));
               if (tmr == (time_t) (-1))
                 logputs (LOG_VERBOSE, _("\
 Last-modified header invalid -- time-stamp ignored.\n"));
+              if (*dt & HEAD_ONLY)
+                time_came_from_head = true;
             }
       
           /* The time-stamping section.  */
@@ -2581,12 +2605,6 @@ The sizes do not match (local %s) -- retrieving.\n"),
               restart_loop = true;
             }
           
-          if (opt.always_rest)
-            {
-              got_name = true;
-              restart_loop = true;
-            }
-          
           if (opt.spider)
             {
               if (opt.recursive)
@@ -2601,7 +2619,7 @@ Remote file exists and could contain links to other resources -- retrieving.\n\n
                     {
                       logprintf (LOG_VERBOSE, _("\
 Remote file exists but does not contain any link -- not retrieving.\n\n"));
-                      ret = RETRUNNEEDED;
+                      ret = RETROK; /* RETRUNNEEDED is not for caller. */
                       goto exit;
                     }
                 }
@@ -2609,11 +2627,17 @@ Remote file exists but does not contain any link -- not retrieving.\n\n"));
                 {
                   logprintf (LOG_VERBOSE, _("\
 Remote file exists but recursion is disabled -- not retrieving.\n\n"));
-                  ret = RETRUNNEEDED;
+                  ret = RETROK; /* RETRUNNEEDED is not for caller. */
                   goto exit;
                 }
             }
 
+          if (send_head_first)
+            {
+              got_name = true;
+              restart_loop = true;
+            }
+          
           got_head = true;    /* no more time-stamping */
           *dt &= ~HEAD_ONLY;
           count = 0;          /* the retrieve count for HEAD is reset */
@@ -2637,7 +2661,18 @@ Remote file exists but recursion is disabled -- not retrieving.\n\n"));
           else
             fl = hstat.local_file;
           if (fl)
-            touch (fl, tmr);
+            {
+              time_t newtmr = -1;
+              /* Reparse time header, in case it's changed. */
+              if (time_came_from_head
+                  && hstat.remote_time && hstat.remote_time[0])
+                {
+                  newtmr = http_atotm (hstat.remote_time);
+                  if (newtmr != -1)
+                    tmr = newtmr;
+                }
+              touch (fl, tmr);
+            }
         }
       /* End of time-stamping section. */