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);
{
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);
}
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;
}
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
if (pconn_active && (fd) == pconn.socket) \
invalidate_persistent (); \
else \
- xclose (fd); \
+ fd_close (fd); \
} \
} while (0)
if (pconn_active && (fd) == pconn.socket) \
invalidate_persistent (); \
else \
- xclose (fd); \
+ fd_close (fd); \
} while (0)
\f
struct http_stat
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. */
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)
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET,
_("Unable to establish SSL connection.\n"));
- xclose (sock);
+ fd_close (sock);
return CONSSLERR;
}
using_ssl = 1;
}
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));
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);