]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Only allocate an error string on actual error.
[wget] / src / http.c
index 61819c7fc15d8e4c668c93ac57e593e54be5ecc8..17dde3979ce9009b17186c50a18056ec77c5cedf 100644 (file)
@@ -352,7 +352,7 @@ request_send (const struct request *req, int fd)
   write_error = fd_write (fd, request_string, size - 1, -1);
   if (write_error < 0)
     logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
-              strerror (errno));
+              fd_errstr (fd));
   return write_error;
 }
 
@@ -838,7 +838,7 @@ skip_short_body (int fd, wgint contlen)
          /* Don't normally report the error since this is an
             optimization that should be invisible to the user.  */
          DEBUGP (("] aborting (%s).\n",
-                  ret < 0 ? strerror (errno) : "EOF received"));
+                  ret < 0 ? fd_errstr (fd) : "EOF received"));
          return false;
        }
       contlen -= ret;
@@ -1009,11 +1009,17 @@ persistent_available_p (const char *host, int port, bool ssl,
     }
 
   /* Finally, check whether the connection is still open.  This is
-     important because most server implement a liberal (short) timeout
+     important because most servers implement liberal (short) timeout
      on persistent connections.  Wget can of course always reconnect
      if the connection doesn't work out, but it's nicer to know in
      advance.  This test is a logical followup of the first test, but
-     is "expensive" and therefore placed at the end of the list.  */
+     is "expensive" and therefore placed at the end of the list.
+
+     (Current implementation of test_socket_open has a nice side
+     effect that it treats sockets with pending data as "closed".
+     This is exactly what we want: if a broken server sends message
+     body in response to HEAD, or if it sends more than conent-length
+     data, we won't reuse the corrupted connection.)  */
 
   if (!test_socket_open (pconn.socket))
     {
@@ -1069,6 +1075,7 @@ struct http_stat
   wgint contlen;               /* expected length */
   wgint restval;               /* the restart value */
   int res;                     /* the result of last read */
+  char *rderrmsg;              /* error message from read error */
   char *newloc;                        /* new location (redirection) */
   char *remote_time;           /* remote time-stamp string */
   char *error;                 /* textual HTTP error */
@@ -1085,6 +1092,7 @@ free_hstat (struct http_stat *hs)
   xfree_null (hs->newloc);
   xfree_null (hs->remote_time);
   xfree_null (hs->error);
+  xfree_null (hs->rderrmsg);
 
   /* Guard against being called twice. */
   hs->newloc = NULL;
@@ -1206,6 +1214,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
   hs->len = 0;
   hs->contlen = -1;
   hs->res = -1;
+  hs->rderrmsg = NULL;
   hs->newloc = NULL;
   hs->remote_time = NULL;
   hs->error = NULL;
@@ -1478,7 +1487,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
          if (write_error < 0)
            {
              logprintf (LOG_VERBOSE, _("Failed writing to proxy: %s.\n"),
-                        strerror (errno));
+                        fd_errstr (sock));
              CLOSE_INVALIDATE (sock);
              return WRITEFAILED;
            }
@@ -1487,7 +1496,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
          if (!head)
            {
              logprintf (LOG_VERBOSE, _("Failed reading proxy response: %s\n"),
-                        strerror (errno));
+                        fd_errstr (sock));
              CLOSE_INVALIDATE (sock);
              return HERR;
            }
@@ -1548,7 +1557,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
   if (write_error < 0)
     {
       logprintf (LOG_VERBOSE, _("Failed writing HTTP request: %s.\n"),
-                strerror (errno));
+                fd_errstr (sock));
       CLOSE_INVALIDATE (sock);
       request_free (req);
       return WRITEFAILED;
@@ -1572,7 +1581,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
       else
        {
          logprintf (LOG_NOTQUIET, _("Read error (%s) in headers.\n"),
-                    strerror (errno));
+                    fd_errstr (sock));
          CLOSE_INVALIDATE (sock);
          request_free (req);
          return HERR;
@@ -1886,8 +1895,9 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
       xfree_null (type);
       if (head_only)
        /* Pre-1.10 Wget used CLOSE_INVALIDATE here.  Now we trust the
-          servers not to send body in response to a HEAD request.  If
-          you encounter such a server (more likely a broken CGI), use
+          servers not to send body in response to a HEAD request, and
+          those that do will likely be caught by test_socket_open.
+          If not, they can be worked around using
           `--no-http-keep-alive'.  */
        CLOSE_FINISH (sock);
       else if (keep_alive && skip_short_body (sock, contlen))
@@ -1959,20 +1969,14 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
   if (hs->res >= 0)
     CLOSE_FINISH (sock);
   else
-    CLOSE_INVALIDATE (sock);
+    {
+      if (hs->res < 0)
+       hs->rderrmsg = xstrdup (fd_errstr (sock));
+      CLOSE_INVALIDATE (sock);
+    }
 
-  {
-    /* Close or flush the file.  We have to be careful to check for
-       error here.  Checking the result of fwrite() is not enough --
-       errors could go unnoticed!  */
-    int flush_res;
-    if (!output_stream)
-      flush_res = fclose (fp);
-    else
-      flush_res = fflush (fp);
-    if (flush_res == EOF)
-      hs->res = -2;
-  }
+  if (!output_stream)
+    fclose (fp);
   if (hs->res == -2)
     return FWRITEERR;
   return RETRFINISHED;
@@ -2495,7 +2499,7 @@ The sizes do not match (local %s) -- retrieving.\n"),
              logprintf (LOG_VERBOSE,
                         _("%s (%s) - Read error at byte %s (%s)."),
                         tms, tmrate, number_to_static_string (hstat.len),
-                        strerror (errno));
+                        hstat.rderrmsg);
              printwhat (count, opt.ntry);
              free_hstat (&hstat);
              continue;
@@ -2507,7 +2511,7 @@ The sizes do not match (local %s) -- retrieving.\n"),
                         tms, tmrate,
                         number_to_static_string (hstat.len),
                         number_to_static_string (hstat.contlen),
-                        strerror (errno));
+                        hstat.rderrmsg);
              printwhat (count, opt.ntry);
              free_hstat (&hstat);
              continue;