+ if (pc_last_fd == fd)
+ {
+ /* The connection FD is already registered. Nothing to
+ do. */
+ return;
+ }
+ else
+ {
+ /* The old persistent connection is still active; let's
+ close it first. This situation arises whenever a
+ persistent connection exists, but we then connect to a
+ different host, and try to register a persistent
+ connection to that one. */
+#ifdef HAVE_SSL
+ /* The ssl disconnect has to take place before the closing
+ of pc_last_fd. */
+ if (pc_last_ssl)
+ shutdown_ssl(pc_last_ssl);
+#endif
+ CLOSE (pc_last_fd);
+ invalidate_persistent ();
+ }
+ }
+
+ /* This store_hostaddress may not fail, because it has the results
+ in the cache. */
+ success = store_hostaddress (pc_last_host, host);
+ assert (success);
+ pc_last_port = port;
+ pc_last_fd = fd;
+ pc_active_p = 1;
+#ifdef HAVE_SSL
+ pc_last_ssl = ssl;
+ pc_active_ssl = ssl ? 1 : 0;
+#endif
+ DEBUGP (("Registered fd %d for persistent reuse.\n", fd));
+}
+
+/* Return non-zero if a persistent connection is available for
+ connecting to HOST:PORT. */
+
+static int
+persistent_available_p (const char *host, unsigned short port
+#ifdef HAVE_SSL
+ , int ssl
+#endif
+ )
+{
+ unsigned char this_host[4];
+ /* First, check whether a persistent connection is active at all. */
+ if (!pc_active_p)
+ return 0;
+ /* Second, check if the active connection pertains to the correct
+ (HOST, PORT) ordered pair. */
+ if (port != pc_last_port)
+ return 0;
+#ifdef HAVE_SSL
+ /* Second, a): check if current connection is (not) ssl, too. This
+ test is unlikely to fail because HTTP and HTTPS typicaly use
+ different ports. Yet it is possible, or so I [Christian
+ Fraenkel] have been told, to run HTTPS and HTTP simultaneus on
+ the same port. */
+ if (ssl != pc_active_ssl)
+ return 0;
+#endif /* HAVE_SSL */
+ if (!store_hostaddress (this_host, host))
+ return 0;
+ if (memcmp (pc_last_host, this_host, 4))
+ return 0;
+ /* Third: check whether the connection is still open. This is
+ important because most server implement a 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. */
+ if (!test_socket_open (pc_last_fd))
+ {
+ /* Oops, the socket is no longer open. Now that we know that,
+ let's invalidate the persistent connection before returning
+ 0. */
+ CLOSE (pc_last_fd);
+ invalidate_persistent ();
+ return 0;