diff options
author | Sergio Villar Senin <svillar@igalia.com> | 2011-08-26 19:03:30 +0200 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2011-09-19 17:59:57 -0400 |
commit | 5b272126556b18bbe6614a71ff552946e32b3a40 (patch) | |
tree | 924223656835940b5aab94a16c531416d8b8cdb0 | |
parent | af5f30cd0eb98f24cd0416d9ee2a12c3b60fe63e (diff) | |
download | libsoup-5b272126556b18bbe6614a71ff552946e32b3a40.tar.gz |
SoupSession: forget about SoupHosts if not used
Free SoupHosts with 0 connections after some time. Host IP addresses will
this way be re-resolved, protecting clients against server IP changes.
https://bugzilla.gnome.org/show_bug.cgi?id=646959
-rw-r--r-- | libsoup/soup-session.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 8c2b3544..abb4ea51 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -32,6 +32,8 @@ #include "soup-ssl.h" #include "soup-uri.h" +#define HOST_KEEP_ALIVE 5 * 60 * 1000 /* 5 min in msecs */ + /** * SECTION:soup-session * @short_description: Soup session state object @@ -68,6 +70,9 @@ typedef struct { guint num_messages; gboolean ssl_fallback; + + GSource *keep_alive_src; + SoupSession *session; } SoupSessionHost; typedef struct { @@ -1041,6 +1046,8 @@ soup_session_host_new (SoupSession *session, SoupURI *uri) host = g_slice_new0 (SoupSessionHost); host->uri = soup_uri_copy_host (uri); host->addr = soup_address_new (host->uri->host, host->uri->port); + host->keep_alive_src = NULL; + host->session = session; return host; } @@ -1082,10 +1089,15 @@ free_host (SoupSessionHost *host) soup_connection_disconnect (conn); } + if (host->keep_alive_src) { + g_source_destroy (host->keep_alive_src); + g_source_unref (host->keep_alive_src); + } + soup_uri_free (host->uri); g_object_unref (host->addr); g_slice_free (SoupSessionHost, host); -} +} static void auth_required (SoupSession *session, SoupMessage *msg, @@ -1258,6 +1270,22 @@ soup_session_cleanup_connections (SoupSession *session, return TRUE; } +static gboolean +free_unused_host (gpointer user_data) +{ + SoupSessionHost *host = (SoupSessionHost *) user_data; + SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (host->session); + + g_mutex_lock (priv->host_lock); + /* This will free the host in addition to removing it from the + * hash table + */ + g_hash_table_remove (priv->hosts, host->uri); + g_mutex_unlock (priv->host_lock); + + return FALSE; +} + static void connection_disconnected (SoupConnection *conn, gpointer user_data) { @@ -1273,6 +1301,19 @@ connection_disconnected (SoupConnection *conn, gpointer user_data) host->connections = g_slist_remove (host->connections, conn); host->num_conns--; + /* Free the SoupHost (and its SoupAddress) if there + * has not been any new connection to the host during + * the last HOST_KEEP_ALIVE msecs. + */ + if (host->num_conns == 0) { + g_assert (host->keep_alive_src == NULL); + host->keep_alive_src = soup_add_timeout (priv->async_context, + HOST_KEEP_ALIVE, + free_unused_host, + host); + host->keep_alive_src = g_source_ref (host->keep_alive_src); + } + if (soup_connection_get_ssl_fallback (conn)) host->ssl_fallback = TRUE; } @@ -1409,6 +1450,12 @@ soup_session_get_connection (SoupSession *session, host->num_conns++; host->connections = g_slist_prepend (host->connections, conn); + if (host->keep_alive_src) { + g_source_destroy (host->keep_alive_src); + g_source_unref (host->keep_alive_src); + host->keep_alive_src = NULL; + } + g_mutex_unlock (priv->host_lock); item->conn = g_object_ref (conn); return TRUE; |