summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2013-09-29 16:23:53 -0400
committerDan Winship <danw@gnome.org>2013-09-29 16:25:53 -0400
commitd1cb3455a7278a7a5d8ac770852ae489a54e6452 (patch)
tree03158821cf17c7e9e7db89bde07e425343302e11
parent96da2df64c9dd8cc52e97ce73e54615d6b520664 (diff)
downloadlibsoup-d1cb3455a7278a7a5d8ac770852ae489a54e6452.tar.gz
soup-session: don't resolve default proxy-resolver/tlsdb if not needed
If the user overrides the proxy or TLS configuration of a session at construct time, we should avoid ever trying to resolve the default extensions. https://bugzilla.gnome.org/show_bug.cgi?id=708696
-rw-r--r--libsoup/soup-session.c62
-rw-r--r--tests/session-test.c130
2 files changed, 182 insertions, 10 deletions
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index a9258ef7..bd586cd3 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -88,6 +88,7 @@ typedef struct {
GTlsDatabase *tlsdb;
char *ssl_ca_file;
gboolean ssl_strict;
+ gboolean tlsdb_use_default;
SoupMessageQueue *queue;
@@ -122,6 +123,7 @@ typedef struct {
GResolver *resolver;
GProxyResolver *proxy_resolver;
+ gboolean proxy_use_default;
SoupURI *proxy_uri;
char **http_aliases, **https_aliases;
@@ -268,9 +270,6 @@ soup_session_constructor (GType type,
SoupSession *session = SOUP_SESSION (object);
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
- g_clear_object (&priv->tlsdb);
- priv->tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ());
-
g_clear_pointer (&priv->async_context, g_main_context_unref);
priv->async_context = g_main_context_ref_thread_default ();
priv->use_thread_context = TRUE;
@@ -279,7 +278,12 @@ soup_session_constructor (GType type,
priv->http_aliases[0] = NULL;
- priv->proxy_resolver = g_object_ref (g_proxy_resolver_get_default ());
+ /* If the user overrides the proxy or tlsdb during construction,
+ * we don't want to needlessly resolve the extension point. So
+ * we just set flags saying to do it later.
+ */
+ priv->proxy_use_default = TRUE;
+ priv->tlsdb_use_default = TRUE;
soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
}
@@ -435,6 +439,7 @@ set_tlsdb (SoupSession *session, GTlsDatabase *tlsdb)
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
GTlsDatabase *system_default;
+ priv->tlsdb_use_default = FALSE;
if (tlsdb == priv->tlsdb)
return;
@@ -470,6 +475,8 @@ set_use_system_ca_file (SoupSession *session, gboolean use_system_ca_file)
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
GTlsDatabase *system_default;
+ priv->tlsdb_use_default = FALSE;
+
system_default = g_tls_backend_get_default_database (g_tls_backend_get_default ());
if (use_system_ca_file)
@@ -487,6 +494,7 @@ set_ssl_ca_file (SoupSession *session, const char *ssl_ca_file)
GTlsDatabase *tlsdb;
GError *error = NULL;
+ priv->tlsdb_use_default = FALSE;
if (!g_strcmp0 (priv->ssl_ca_file, ssl_ca_file))
return;
@@ -562,6 +570,7 @@ set_proxy_resolver (SoupSession *session, SoupURI *uri,
G_GNUC_END_IGNORE_DEPRECATIONS;
g_clear_object (&priv->proxy_resolver);
g_clear_pointer (&priv->proxy_uri, soup_uri_free);
+ priv->proxy_use_default = FALSE;
if (uri) {
char *uri_string;
@@ -711,6 +720,30 @@ soup_session_set_property (GObject *object, guint prop_id,
}
}
+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;
+ }
+ 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
soup_session_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -728,7 +761,7 @@ 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, priv->proxy_resolver);
+ g_value_set_object (value, get_proxy_resolver (session));
break;
case PROP_MAX_CONNS:
g_value_set_int (value, priv->max_conns);
@@ -748,11 +781,11 @@ 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, priv->tlsdb == tlsdb);
+ g_value_set_boolean (value, get_tls_database (session) == tlsdb);
g_clear_object (&tlsdb);
break;
case PROP_TLS_DATABASE:
- g_value_set_object (value, priv->tlsdb);
+ g_value_set_object (value, get_tls_database (session));
break;
case PROP_SSL_STRICT:
g_value_set_boolean (value, priv->ssl_strict);
@@ -1609,6 +1642,8 @@ get_connection_for_host (SoupSession *session,
SoupConnection *conn;
GSList *conns;
int num_pending = 0;
+ GProxyResolver *proxy_resolver;
+ GTlsDatabase *tlsdb;
if (priv->disposed)
return FALSE;
@@ -1645,13 +1680,16 @@ 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, priv->proxy_resolver,
+ SOUP_CONNECTION_PROXY_RESOLVER, proxy_resolver,
SOUP_CONNECTION_SSL, soup_uri_is_https (soup_message_get_uri (item->msg), priv->https_aliases),
- SOUP_CONNECTION_SSL_CREDENTIALS, priv->tlsdb,
- SOUP_CONNECTION_SSL_STRICT, priv->ssl_strict && (priv->tlsdb != NULL || SOUP_IS_PLAIN_SESSION (session)),
+ 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,
@@ -2593,6 +2631,10 @@ soup_session_remove_feature_by_type (SoupSession *session, GType feature_type)
goto restart;
}
}
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ if (g_type_is_a (feature_type, SOUP_TYPE_PROXY_URI_RESOLVER))
+ priv->proxy_use_default = FALSE;
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
} else if (g_type_is_a (feature_type, SOUP_TYPE_REQUEST)) {
SoupRequestClass *request_class;
int i;
diff --git a/tests/session-test.c b/tests/session-test.c
index b8e224ea..d40e7766 100644
--- a/tests/session-test.c
+++ b/tests/session-test.c
@@ -263,6 +263,135 @@ do_priority_tests (char *uri)
soup_test_session_abort_unref (session);
}
+static void
+test_session_properties (const char *name,
+ SoupSession *session,
+ GProxyResolver *expected_proxy_resolver,
+ GTlsDatabase *expected_tls_database)
+{
+ GProxyResolver *proxy_resolver = NULL;
+ GTlsDatabase *tlsdb = NULL;
+
+ g_object_get (G_OBJECT (session),
+ SOUP_SESSION_PROXY_RESOLVER, &proxy_resolver,
+ SOUP_SESSION_TLS_DATABASE, &tlsdb,
+ NULL);
+ if (proxy_resolver != expected_proxy_resolver) {
+ debug_printf (1, " %s has %s proxy resolver!\n",
+ name, proxy_resolver ? (expected_proxy_resolver ? "wrong" : "a") : "no");
+ errors++;
+ }
+ if (tlsdb != expected_tls_database) {
+ debug_printf (1, " %s has %s TLS database!\n",
+ name, tlsdb ? (expected_tls_database ? "wrong" : "a") : "no");
+ errors++;
+ }
+ g_clear_object (&proxy_resolver);
+ g_clear_object (&tlsdb);
+}
+
+static void
+do_property_tests (void)
+{
+ SoupSession *session;
+ GProxyResolver *proxy_resolver, *default_proxy_resolver;
+ GTlsDatabase *tlsdb, *default_tlsdb;
+ SoupURI *uri;
+
+ debug_printf (1, "\nTesting session init properties\n");
+
+ default_proxy_resolver = g_proxy_resolver_get_default ();
+ default_tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ());
+
+ /* NOTE: We intentionally do not use soup_test_session_new() here */
+
+ session = g_object_new (SOUP_TYPE_SESSION,
+ NULL);
+ test_session_properties ("Base plain session", session,
+ default_proxy_resolver, default_tlsdb);
+ g_object_unref (session);
+
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_PROXY_RESOLVER, NULL,
+ NULL);
+ test_session_properties ("Session with NULL :proxy-resolver", session,
+ NULL, default_tlsdb);
+ g_object_unref (session);
+
+ proxy_resolver = g_simple_proxy_resolver_new (NULL, NULL);
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_PROXY_RESOLVER, proxy_resolver,
+ NULL);
+ test_session_properties ("Session with non-NULL :proxy-resolver", session,
+ proxy_resolver, default_tlsdb);
+ g_object_unref (proxy_resolver);
+ g_object_unref (session);
+
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_PROXY_URI, NULL,
+ NULL);
+ test_session_properties ("Session with NULL :proxy-uri", session,
+ NULL, default_tlsdb);
+ g_object_unref (session);
+
+ uri = soup_uri_new ("http://example.com/");
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_PROXY_URI, uri,
+ NULL);
+ g_object_get (G_OBJECT (session),
+ SOUP_SESSION_PROXY_RESOLVER, &proxy_resolver,
+ NULL);
+ test_session_properties ("Session with non-NULL :proxy-uri", session,
+ proxy_resolver, default_tlsdb);
+ if (!G_IS_SIMPLE_PROXY_RESOLVER (proxy_resolver)) {
+ debug_printf (1, " proxy resolver had wrong type (%s)\n",
+ G_OBJECT_TYPE_NAME (proxy_resolver));
+ errors++;
+ }
+ g_object_unref (proxy_resolver);
+ g_object_unref (session);
+ soup_uri_free (uri);
+
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_REMOVE_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_URI_RESOLVER,
+ NULL);
+ test_session_properties ("Session with removed proxy resolver feature", session,
+ NULL, default_tlsdb);
+ g_object_unref (session);
+ G_GNUC_END_IGNORE_DEPRECATIONS;
+
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_TLS_DATABASE, NULL,
+ NULL);
+ test_session_properties ("Session with NULL :tls-database", session,
+ default_proxy_resolver, NULL);
+ g_object_unref (session);
+
+ tlsdb = g_tls_file_database_new (SRCDIR "/test-cert.pem", NULL);
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_TLS_DATABASE, tlsdb,
+ NULL);
+ test_session_properties ("Session with non-NULL :tls-database", session,
+ default_proxy_resolver, tlsdb);
+ g_object_unref (tlsdb);
+ g_object_unref (session);
+
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, FALSE,
+ NULL);
+ test_session_properties ("Session with :ssl-use-system-ca-file FALSE", session,
+ default_proxy_resolver, NULL);
+ g_object_unref (session);
+
+ session = g_object_new (SOUP_TYPE_SESSION,
+ SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE, TRUE,
+ NULL);
+ test_session_properties ("Session with :ssl-use-system-ca-file TRUE", session,
+ default_proxy_resolver, default_tlsdb);
+ g_object_unref (session);
+}
+
int
main (int argc, char **argv)
{
@@ -281,6 +410,7 @@ main (int argc, char **argv)
do_async_tests (uri, timeout_uri);
do_sync_tests (uri, timeout_uri);
do_priority_tests (uri);
+ do_property_tests ();
g_free (uri);
g_free (timeout_uri);