diff options
Diffstat (limited to 'libsoup/soup-session.c')
-rw-r--r-- | libsoup/soup-session.c | 124 |
1 files changed, 73 insertions, 51 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c index 96bf4b62..24070dfe 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -21,6 +21,7 @@ #include "soup-message-queue.h" #include "soup-proxy-resolver-wrapper.h" #include "soup-session-private.h" +#include "soup-socket-private.h" #define HOST_KEEP_ALIVE 5 * 60 * 1000 /* 5 min in msecs */ @@ -90,6 +91,16 @@ typedef struct { gboolean ssl_strict; gboolean tlsdb_use_default; + guint io_timeout, idle_timeout; + SoupAddress *local_addr; + + GResolver *resolver; + GProxyResolver *proxy_resolver; + gboolean proxy_use_default; + SoupURI *proxy_uri; + + SoupSocketProperties *socket_props; + SoupMessageQueue *queue; char *user_agent; @@ -103,9 +114,6 @@ typedef struct { GHashTable *conns; /* SoupConnection -> SoupSessionHost */ guint num_conns; guint max_conns, max_conns_per_host; - guint io_timeout, idle_timeout; - - SoupAddress *local_addr; /* Must hold the conn_lock before potentially creating a new * SoupSessionHost, adding/removing a connection, @@ -121,11 +129,6 @@ typedef struct { gboolean use_thread_context; GSList *run_queue_sources; - GResolver *resolver; - GProxyResolver *proxy_resolver; - gboolean proxy_use_default; - SoupURI *proxy_uri; - char **http_aliases, **https_aliases; GHashTable *request_types; @@ -350,9 +353,42 @@ soup_session_finalize (GObject *object) g_hash_table_destroy (priv->request_types); + g_clear_pointer (&priv->socket_props, soup_socket_properties_unref); + G_OBJECT_CLASS (soup_session_parent_class)->finalize (object); } +static void +ensure_socket_props (SoupSession *session) +{ + SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session); + gboolean ssl_strict; + + if (priv->socket_props) + return; + + if (priv->proxy_use_default) { + priv->proxy_resolver = g_object_ref (g_proxy_resolver_get_default ()); + priv->proxy_use_default = FALSE; + } + if (priv->tlsdb_use_default) { + priv->tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ()); + priv->tlsdb_use_default = FALSE; + } + + ssl_strict = priv->ssl_strict && (priv->tlsdb != NULL || + SOUP_IS_PLAIN_SESSION (priv->session)); + + priv->socket_props = soup_socket_properties_new (priv->async_context, + priv->use_thread_context, + priv->proxy_resolver, + priv->local_addr, + priv->tlsdb, + ssl_strict, + priv->io_timeout, + priv->idle_timeout); +} + /* Converts a language in POSIX format and to be RFC2616 compliant */ /* Based on code from epiphany-webkit (ephy_langs_append_languages()) */ static gchar * @@ -600,19 +636,23 @@ soup_session_set_property (GObject *object, guint prop_id, const char *user_agent; SoupSessionFeature *feature; GMainContext *async_context; + gboolean socket_props_changed = FALSE; switch (prop_id) { case PROP_LOCAL_ADDRESS: priv->local_addr = g_value_dup_object (value); + socket_props_changed = TRUE; break; case PROP_PROXY_URI: set_proxy_resolver (session, g_value_get_boxed (value), NULL, NULL); soup_session_abort (session); + socket_props_changed = TRUE; break; case PROP_PROXY_RESOLVER: set_proxy_resolver (session, NULL, NULL, g_value_get_object (value)); + socket_props_changed = TRUE; break; case PROP_MAX_CONNS: priv->max_conns = g_value_get_int (value); @@ -633,15 +673,19 @@ soup_session_set_property (GObject *object, guint prop_id, break; case PROP_SSL_CA_FILE: set_ssl_ca_file (session, g_value_get_string (value)); + socket_props_changed = TRUE; break; case PROP_SSL_USE_SYSTEM_CA_FILE: set_use_system_ca_file (session, g_value_get_boolean (value)); + socket_props_changed = TRUE; break; case PROP_TLS_DATABASE: set_tlsdb (session, g_value_get_object (value)); + socket_props_changed = TRUE; break; case PROP_SSL_STRICT: priv->ssl_strict = g_value_get_boolean (value); + socket_props_changed = TRUE; break; case PROP_ASYNC_CONTEXT: async_context = g_value_get_pointer (value); @@ -650,6 +694,7 @@ soup_session_set_property (GObject *object, guint prop_id, priv->async_context = async_context; if (priv->async_context) g_main_context_ref (priv->async_context); + socket_props_changed = TRUE; break; case PROP_USE_THREAD_CONTEXT: if (!g_value_get_boolean (value)) @@ -662,9 +707,11 @@ soup_session_set_property (GObject *object, guint prop_id, if (priv->async_context) g_main_context_ref (priv->async_context); } + socket_props_changed = TRUE; break; case PROP_TIMEOUT: priv->io_timeout = g_value_get_uint (value); + socket_props_changed = TRUE; break; case PROP_USER_AGENT: g_free (priv->user_agent); @@ -699,6 +746,7 @@ soup_session_set_property (GObject *object, guint prop_id, break; case PROP_IDLE_TIMEOUT: priv->idle_timeout = g_value_get_uint (value); + socket_props_changed = TRUE; break; case PROP_ADD_FEATURE: soup_session_add_feature (session, g_value_get_object (value)); @@ -719,30 +767,12 @@ soup_session_set_property (GObject *object, guint prop_id, G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } -} -static GProxyResolver * -get_proxy_resolver (SoupSession *session) -{ - SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session); - - if (priv->proxy_use_default) { - priv->proxy_resolver = g_object_ref (g_proxy_resolver_get_default ()); - priv->proxy_use_default = FALSE; + if (priv->socket_props && socket_props_changed) { + soup_socket_properties_unref (priv->socket_props); + priv->socket_props = NULL; + ensure_socket_props (session); } - return priv->proxy_resolver; -} - -static GTlsDatabase * -get_tls_database (SoupSession *session) -{ - SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session); - - if (priv->tlsdb_use_default) { - priv->tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ()); - priv->tlsdb_use_default = FALSE; - } - return priv->tlsdb; } static void @@ -762,7 +792,8 @@ soup_session_get_property (GObject *object, guint prop_id, g_value_set_boxed (value, priv->proxy_uri); break; case PROP_PROXY_RESOLVER: - g_value_set_object (value, get_proxy_resolver (session)); + ensure_socket_props (session); + g_value_set_object (value, priv->proxy_resolver); break; case PROP_MAX_CONNS: g_value_set_int (value, priv->max_conns); @@ -782,11 +813,13 @@ soup_session_get_property (GObject *object, guint prop_id, break; case PROP_SSL_USE_SYSTEM_CA_FILE: tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ()); - g_value_set_boolean (value, get_tls_database (session) == tlsdb); + ensure_socket_props (session); + g_value_set_boolean (value, priv->tlsdb == tlsdb); g_clear_object (&tlsdb); break; case PROP_TLS_DATABASE: - g_value_set_object (value, get_tls_database (session)); + ensure_socket_props (session); + g_value_set_object (value, priv->tlsdb); break; case PROP_SSL_STRICT: g_value_set_boolean (value, priv->ssl_strict); @@ -1739,8 +1772,6 @@ get_connection_for_host (SoupSession *session, SoupConnection *conn; GSList *conns; int num_pending = 0; - GProxyResolver *proxy_resolver; - GTlsDatabase *tlsdb; if (priv->disposed) return FALSE; @@ -1777,22 +1808,13 @@ get_connection_for_host (SoupSession *session, return NULL; } - proxy_resolver = get_proxy_resolver (session); - tlsdb = get_tls_database (session); - - conn = g_object_new ( - SOUP_TYPE_CONNECTION, - SOUP_CONNECTION_REMOTE_URI, host->uri, - SOUP_CONNECTION_PROXY_RESOLVER, proxy_resolver, - SOUP_CONNECTION_SSL_CREDENTIALS, tlsdb, - SOUP_CONNECTION_SSL_STRICT, priv->ssl_strict && (tlsdb != NULL || SOUP_IS_PLAIN_SESSION (session)), - SOUP_CONNECTION_ASYNC_CONTEXT, priv->async_context, - SOUP_CONNECTION_USE_THREAD_CONTEXT, priv->use_thread_context, - SOUP_CONNECTION_TIMEOUT, priv->io_timeout, - SOUP_CONNECTION_IDLE_TIMEOUT, priv->idle_timeout, - SOUP_CONNECTION_SSL_FALLBACK, host->ssl_fallback, - SOUP_CONNECTION_LOCAL_ADDRESS, priv->local_addr, - NULL); + ensure_socket_props (session); + conn = g_object_new (SOUP_TYPE_CONNECTION, + SOUP_CONNECTION_REMOTE_URI, host->uri, + SOUP_CONNECTION_SSL_FALLBACK, host->ssl_fallback, + SOUP_CONNECTION_SOCKET_PROPERTIES, priv->socket_props, + NULL); + g_signal_connect (conn, "disconnected", G_CALLBACK (connection_disconnected), session); |