]> sjero.net Git - wget/blobdiff - src/http.c
Use persistent connections with proxies supporting them.
[wget] / src / http.c
index 60f4f846620dc631092dacbf902dde49f7eb007b..496e64a73dc5f976c3507a4c60eef6bcaac86fe9 100644 (file)
@@ -405,18 +405,18 @@ maybe_send_basic_creds (const char *hostname, const char *user,
 
   if (opt.auth_without_challenge)
     {
-      DEBUGP(("Auth-without-challenge set, sending Basic credentials.\n"));
+      DEBUGP (("Auth-without-challenge set, sending Basic credentials.\n"));
       do_challenge = true;
     }
   else if (basic_authed_hosts
       && hash_table_contains(basic_authed_hosts, hostname))
     {
-      DEBUGP(("Found %s in basic_authed_hosts.\n", quote (hostname)));
+      DEBUGP (("Found %s in basic_authed_hosts.\n", quote (hostname)));
       do_challenge = true;
     }
   else
     {
-      DEBUGP(("Host %s has not issued a general basic challenge.\n",
+      DEBUGP (("Host %s has not issued a general basic challenge.\n",
               quote (hostname)));
     }
   if (do_challenge)
@@ -438,7 +438,7 @@ register_basic_auth_host (const char *hostname)
   if (!hash_table_contains(basic_authed_hosts, hostname))
     {
       hash_table_put (basic_authed_hosts, xstrdup(hostname), NULL);
-      DEBUGP(("Inserted %s into basic_authed_hosts\n", quote (hostname)));
+      DEBUGP (("Inserted %s into basic_authed_hosts\n", quote (hostname)));
     }
 }
 
@@ -1573,15 +1573,9 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
   /* Is the server using the chunked transfer encoding?  */
   bool chunked_transfer_encoding = false;
 
-  /* Whether keep-alive should be inhibited.
-
-     RFC 2068 requests that 1.0 clients not send keep-alive requests
-     to proxies.  This is because many 1.0 proxies do not interpret
-     the Connection header and transfer it to the remote server,
-     causing it to not close the connection and leave both the proxy
-     and the client hanging.  */
+  /* Whether keep-alive should be inhibited.  */
   bool inhibit_keep_alive =
-    !opt.http_keep_alive || opt.ignore_length || proxy != NULL;
+    !opt.http_keep_alive || opt.ignore_length;
 
   /* Headers sent when using POST. */
   wgint post_data_size = 0;
@@ -1645,7 +1639,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
   request_set_header (req, "Referer", (char *) hs->referer, rel_none);
   if (*dt & SEND_NOCACHE)
     request_set_header (req, "Pragma", "no-cache", rel_none);
-  if (hs->restval)
+  if (hs->restval && !opt.timestamping)
     request_set_header (req, "Range",
                         aprintf ("bytes=%s-",
                                  number_to_static_string (hs->restval)),
@@ -1691,20 +1685,18 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
                         rel_value);
   }
 
-  if (!inhibit_keep_alive)
-    request_set_header (req, "Connection", "Keep-Alive", rel_none);
-
-  if (opt.cookies)
-    request_set_header (req, "Cookie",
-                        cookie_header (wget_cookie_jar,
-                                       u->host, u->port, u->path,
-#ifdef HAVE_SSL
-                                       u->scheme == SCHEME_HTTPS
-#else
-                                       0
-#endif
-                                       ),
-                        rel_value);
+  if (inhibit_keep_alive)
+    request_set_header (req, "Connection", "Close", rel_none);
+  else
+    {
+      if (proxy == NULL)
+        request_set_header (req, "Connection", "Keep-Alive", rel_none);
+      else
+        {
+          request_set_header (req, "Connection", "Close", rel_none);
+          request_set_header (req, "Proxy-Connection", "Keep-Alive", rel_none);
+        }
+    }
 
   if (opt.post_data || opt.post_file_name)
     {
@@ -1727,6 +1719,23 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
                           rel_value);
     }
 
+ retry_with_auth:
+  /* We need to come back here when the initial attempt to retrieve
+     without authorization header fails.  (Expected to happen at least
+     for the Digest authorization scheme.)  */
+
+  if (opt.cookies)
+    request_set_header (req, "Cookie",
+                        cookie_header (wget_cookie_jar,
+                                       u->host, u->port, u->path,
+#ifdef HAVE_SSL
+                                       u->scheme == SCHEME_HTTPS
+#else
+                                       0
+#endif
+                                       ),
+                        rel_value);
+
   /* Add the user headers. */
   if (opt.user_headers)
     {
@@ -1735,11 +1744,6 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy,
         request_set_user_header (req, opt.user_headers[i]);
     }
 
- retry_with_auth:
-  /* We need to come back here when the initial attempt to retrieve
-     without authorization header fails.  (Expected to happen at least
-     for the Digest authorization scheme.)  */
-
   proxyauth = NULL;
   if (proxy)
     {
@@ -2376,9 +2380,8 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
     }
 
   if (statcode == HTTP_STATUS_RANGE_NOT_SATISFIABLE
-      || (hs->restval > 0 && statcode == HTTP_STATUS_OK
-          && contrange == 0 && hs->restval >= contlen)
-     )
+      || (!opt.timestamping && hs->restval > 0 && statcode == HTTP_STATUS_OK
+          && contrange == 0 && contlen >= 0 && hs->restval >= contlen))
     {
       /* If `-c' is in use and the file has been fully downloaded (or
          the remote file has shrunk), Wget effectively requests bytes
@@ -2594,8 +2597,9 @@ File %s already there; not retrieving.\n\n"), quote (hs->local_file));
 /* The genuine HTTP loop!  This is the part where the retrieval is
    retried, and retried, and retried, and...  */
 uerr_t
-http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
-           int *dt, struct url *proxy, struct iri *iri)
+http_loop (struct url *u, struct url *original_url, char **newloc,
+           char **local_file, const char *referer, int *dt, struct url *proxy,
+           struct iri *iri)
 {
   int count;
   bool got_head = false;         /* used for time-stamping and filename detection */
@@ -2609,6 +2613,7 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
   struct_stat st;
   bool send_head_first = true;
   char *file_name;
+  bool force_full_retrieve = false;
 
   /* Assert that no value for *LOCAL_FILE was passed. */
   assert (local_file == NULL || *local_file == NULL);
@@ -2624,7 +2629,7 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
      here so that we don't go through the hoops if we're just using
      FTP or whatever. */
   if (opt.cookies)
-    load_cookies();
+    load_cookies ();
 
   /* Warn on (likely bogus) wildcard usage in HTTP. */
   if (opt.ftp_glob && has_wildcards_p (u->path))
@@ -2641,7 +2646,8 @@ http_loop (struct url *u, char **newloc, char **local_file, const char *referer,
     }
   else if (!opt.content_disposition)
     {
-      hstat.local_file = url_file_name (u);
+      hstat.local_file =
+        url_file_name (opt.trustservernames ? u : original_url);
       got_name = true;
     }
 
@@ -2673,18 +2679,15 @@ File %s already there; not retrieving.\n\n"),
   /* 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))
+  /* Skip preliminary HEAD request if we're not in spider mode.  */
+  if (!opt.spider)
     send_head_first = false;
 
   /* Send preliminary HEAD request if -N is given and we have an existing
    * destination file. */
-  file_name = url_file_name (u);
-  if (opt.timestamping
-      && !opt.content_disposition
-      && file_exists_p (file_name))
+  file_name = url_file_name (opt.trustservernames ? u : original_url);
+  if (opt.timestamping && (file_exists_p (file_name)
+                           || opt.content_disposition))
     send_head_first = true;
   xfree (file_name);
 
@@ -2735,7 +2738,9 @@ Spider mode enabled. Check if remote file exists.\n"));
         *dt &= ~HEAD_ONLY;
 
       /* Decide whether or not to restart.  */
-      if (opt.always_rest
+      if (force_full_retrieve)
+        hstat.restval = hstat.len;
+      else if (opt.always_rest
           && got_name
           && stat (hstat.local_file, &st) == 0
           && S_ISREG (st.st_mode))
@@ -2923,8 +2928,11 @@ The sizes do not match (local %s) -- retrieving.\n"),
                                 }
                             }
                           else
-                            logputs (LOG_VERBOSE,
-                                     _("Remote file is newer, retrieving.\n"));
+                            {
+                              force_full_retrieve = true;
+                              logputs (LOG_VERBOSE,
+                                       _("Remote file is newer, retrieving.\n"));
+                            }
 
                           logputs (LOG_VERBOSE, "\n");
                         }
@@ -3033,13 +3041,13 @@ Remote file exists.\n\n"));
                          hstat.local_file, count);
             }
           ++numurls;
-          total_downloaded_bytes += hstat.len;
+          total_downloaded_bytes += hstat.rd_size;
 
           /* Remember that we downloaded the file for later ".orig" code. */
           if (*dt & ADDED_HTML_EXTENSION)
-            downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, hstat.local_file);
+            downloaded_file (FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, hstat.local_file);
           else
-            downloaded_file(FILE_DOWNLOADED_NORMALLY, hstat.local_file);
+            downloaded_file (FILE_DOWNLOADED_NORMALLY, hstat.local_file);
 
           ret = RETROK;
           goto exit;
@@ -3066,13 +3074,13 @@ Remote file exists.\n\n"));
                              hstat.local_file, count);
                 }
               ++numurls;
-              total_downloaded_bytes += hstat.len;
+              total_downloaded_bytes += hstat.rd_size;
 
               /* Remember that we downloaded the file for later ".orig" code. */
               if (*dt & ADDED_HTML_EXTENSION)
-                downloaded_file(FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, hstat.local_file);
+                downloaded_file (FILE_DOWNLOADED_AND_HTML_EXTENSION_ADDED, hstat.local_file);
               else
-                downloaded_file(FILE_DOWNLOADED_NORMALLY, hstat.local_file);
+                downloaded_file (FILE_DOWNLOADED_NORMALLY, hstat.local_file);
 
               ret = RETROK;
               goto exit;