]> sjero.net Git - wget/blobdiff - src/http.c
[svn] Renamed xread/xwrite/xclose to fd_read/fd_write/fd_close. The "x" prefix is
[wget] / src / http.c
index ee8d4defc25dbc864c3de48b5b0e62b9e6047fd5..ea4ccf2477afe8ec832c52df39f19b8112a04659 100644 (file)
@@ -211,7 +211,7 @@ post_file (int sock, const char *file_name, long promised_size)
       if (length == 0)
        break;
       towrite = WMIN (promised_size - written, length);
-      write_error = xwrite (sock, chunk, towrite, -1);
+      write_error = fd_write (sock, chunk, towrite, -1);
       if (write_error < 0)
        {
          fclose (fp);
@@ -370,7 +370,7 @@ invalidate_persistent (void)
 {
   DEBUGP (("Disabling further reuse of socket %d.\n", pconn.socket));
   pconn_active = 0;
-  xclose (pconn.socket);
+  fd_close (pconn.socket);
   xfree (pconn.host);
   xzero (pconn);
 }
@@ -438,18 +438,32 @@ persistent_available_p (const char *host, int port, int ssl,
      still hope -- read below.  */
   if (0 != strcasecmp (host, pconn.host))
     {
-      /* This is somewhat evil, but works in practice: if the address
-        that pconn.socket is connected to is one of the IP addresses
-        HOST resolves to, we don't need to reconnect.  #### Is it
-        correct to do this by default?  */
+      /* If pconn.socket is already talking to HOST, we needn't
+        reconnect.  This happens often when both sites are virtual
+        hosts distinguished only by name and served by the same
+        network interface, and hence the same web server (possibly
+        set up by the ISP and serving many different web sites).
+        This admittedly non-standard optimization does not contradict
+        HTTP and works well with popular server software.  */
+
       int found;
       ip_address ip;
       struct address_list *al;
 
-      if (!socket_ip_address (pconn.socket, &ip, 0))
+      if (ssl)
+       /* Don't try to talk to two different SSL sites over the same
+          secure connection!  (Besides, it's not clear if name-based
+          virtual hosting is even possible with SSL.)  */
+       return 0;
+
+      /* If pconn.socket's peer is one of the IP addresses HOST
+        resolves to, pconn.socket is for all intents and purposes
+        already talking to HOST.  */
+
+      if (!socket_ip_address (pconn.socket, &ip, ENDPOINT_PEER))
        {
-         /* Can't get the peer's address -- something must be wrong
-            with the connection.  */
+         /* Can't get the peer's address -- something must be very
+            wrong with the connection.  */
          invalidate_persistent ();
          return 0;
        }
@@ -460,14 +474,15 @@ persistent_available_p (const char *host, int port, int ssl,
          return 0;
        }
 
-      found = address_list_find (al, &ip);
+      found = address_list_contains (al, &ip);
       address_list_release (al);
 
       if (!found)
        return 0;
 
-      /* HOST resolves to an address pconn.sock is connected to -- no
-        need to reconnect.  */
+      /* The persistent connection's peer address was found among the
+        addresses HOST resolved to; therefore, pconn.sock is in fact
+        already talking to HOST -- no need to reconnect.  */
     }
 
   /* Finally, check whether the connection is still open.  This is
@@ -510,7 +525,7 @@ persistent_available_p (const char *host, int port, int ssl,
       if (pconn_active && (fd) == pconn.socket)        \
        invalidate_persistent ();               \
       else                                     \
-       xclose (fd);                            \
+       fd_close (fd);                          \
     }                                          \
 } while (0)
 
@@ -518,7 +533,7 @@ persistent_available_p (const char *host, int port, int ssl,
   if (pconn_active && (fd) == pconn.socket)    \
     invalidate_persistent ();                  \
   else                                         \
-    xclose (fd);                               \
+    fd_close (fd);                             \
 } while (0)
 \f
 struct http_stat
@@ -571,9 +586,7 @@ time_t http_atotm PARAMS ((const char *));
    will print it if there is enough information to do so (almost
    always), returning the error to the caller (i.e. http_loop).
 
-   Various HTTP parameters are stored to hs.  Although it parses the
-   response code correctly, it is not used in a sane way.  The caller
-   can do that, though.
+   Various HTTP parameters are stored to hs.
 
    If PROXY is non-NULL, the connection will be made to the proxy
    server, and u->url will be requested.  */
@@ -704,7 +717,8 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
       if (sock == E_HOST)
        return HOSTERR;
       else if (sock < 0)
-       return CONNECT_ERROR (errno);
+       return (retryable_socket_connect_error (errno)
+               ? CONERROR : CONIMPOSSIBLE);
 
 #ifdef HAVE_SSL
      if (conn->scheme == SCHEME_HTTPS)
@@ -714,7 +728,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
             logputs (LOG_VERBOSE, "\n");
             logprintf (LOG_NOTQUIET,
                        _("Unable to establish SSL connection.\n"));
-            xclose (sock);
+            fd_close (sock);
             return CONSSLERR;
           }
         using_ssl = 1;
@@ -723,10 +737,8 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy)
     }
   else
     {
-      logprintf (LOG_VERBOSE, _("Reusing connection to %s:%hu.\n"),
-                conn->host, conn->port);
-      /* #### pc_last_fd should be accessed through an accessor
-         function.  */
+      logprintf (LOG_VERBOSE, _("Reusing existing connection to %s:%d.\n"),
+                pconn.host, pconn.port);
       sock = pconn.socket;
       using_ssl = pconn.ssl;
       DEBUGP (("Reusing fd %d.\n", sock));
@@ -949,14 +961,14 @@ Accept: %s\r\n\
   xfree (full_path);
 
   /* Send the request to server.  */
-  write_error = xwrite (sock, request, strlen (request), -1);
+  write_error = fd_write (sock, request, strlen (request), -1);
 
   if (write_error >= 0)
     {
       if (opt.post_data)
        {
          DEBUGP (("[POST data: %s]\n", opt.post_data));
-         write_error = xwrite (sock, opt.post_data, post_data_size, -1);
+         write_error = fd_write (sock, opt.post_data, post_data_size, -1);
        }
       else if (opt.post_file_name && post_data_size != 0)
        write_error = post_file (sock, opt.post_file_name, post_data_size);