Add SoupSession:proxy-resolver
authorDan Winship <danw@gnome.org>
Sun, 17 Feb 2013 00:20:18 +0000 (19:20 -0500)
committerDan Winship <danw@gnome.org>
Thu, 7 Mar 2013 15:07:40 +0000 (10:07 -0500)
Now that GSocketClient lets you override its proxy resolver, allow
setting a GProxyResolver on a SoupSession, to eventually pass on to
the GSocketClient.

(In the interest of not breaking things this late in the release
cycle, all of the old SoupProxyURIResolver code still exists as well,
in parallel, but in 2.43 it will be removed and replaced with
GProxyResolver-based backward-compat stuff.)

https://bugzilla.gnome.org/show_bug.cgi?id=680273

libsoup/soup-connection.c
libsoup/soup-connection.h
libsoup/soup-misc-private.h
libsoup/soup-session.c
libsoup/soup-session.h
libsoup/soup-socket.c

index a3322e3..bcc5af4 100644 (file)
@@ -20,8 +20,8 @@ typedef struct {
 
        SoupAddress *local_addr;
        SoupURI *remote_uri, *proxy_uri;
-       SoupProxyURIResolver *proxy_resolver;
-       gboolean use_gproxyresolver;
+       SoupProxyURIResolver *soup_proxy_resolver;
+       GProxyResolver *g_proxy_resolver;
        GTlsDatabase *tlsdb;
        gboolean ssl, ssl_strict, ssl_fallback;
 
@@ -52,7 +52,8 @@ enum {
 
        PROP_LOCAL_ADDRESS,
        PROP_REMOTE_URI,
-       PROP_PROXY_RESOLVER,
+       PROP_SOUP_PROXY_RESOLVER,
+       PROP_G_PROXY_RESOLVER,
        PROP_SSL,
        PROP_SSL_CREDS,
        PROP_SSL_STRICT,
@@ -86,7 +87,8 @@ soup_connection_finalize (GObject *object)
        g_clear_pointer (&priv->remote_uri, soup_uri_free);
        g_clear_pointer (&priv->proxy_uri, soup_uri_free);
        g_clear_object (&priv->tlsdb);
-       g_clear_object (&priv->proxy_resolver);
+       g_clear_object (&priv->soup_proxy_resolver);
+       g_clear_object (&priv->g_proxy_resolver);
        g_clear_object (&priv->local_addr);
        g_clear_pointer (&priv->async_context, g_main_context_unref);
 
@@ -123,12 +125,15 @@ soup_connection_set_property (GObject *object, guint prop_id,
        case PROP_REMOTE_URI:
                priv->remote_uri = g_value_dup_boxed (value);
                break;
-       case PROP_PROXY_RESOLVER:
+       case PROP_SOUP_PROXY_RESOLVER:
                proxy_resolver = g_value_get_object (value);
                if (proxy_resolver && SOUP_IS_PROXY_RESOLVER_DEFAULT (proxy_resolver))
-                       priv->use_gproxyresolver = TRUE;
+                       priv->g_proxy_resolver = g_object_ref (g_proxy_resolver_get_default ());
                else if (proxy_resolver)
-                       priv->proxy_resolver = g_object_ref (proxy_resolver);
+                       priv->soup_proxy_resolver = g_object_ref (proxy_resolver);
+               break;
+       case PROP_G_PROXY_RESOLVER:
+               priv->g_proxy_resolver = g_value_dup_object (value);
                break;
        case PROP_SSL:
                priv->ssl = g_value_get_boolean (value);
@@ -262,13 +267,20 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
                                    SOUP_TYPE_URI,
                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
        g_object_class_install_property (
-               object_class, PROP_PROXY_RESOLVER,
-               g_param_spec_object (SOUP_CONNECTION_PROXY_RESOLVER,
+               object_class, PROP_SOUP_PROXY_RESOLVER,
+               g_param_spec_object (SOUP_CONNECTION_SOUP_PROXY_RESOLVER,
                                     "Proxy resolver",
-                                    "SoupProxyURIResolver to use",
+                                    "SoupProxyResolver to use",
                                     SOUP_TYPE_PROXY_URI_RESOLVER,
                                     G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
        g_object_class_install_property (
+               object_class, PROP_G_PROXY_RESOLVER,
+               g_param_spec_object (SOUP_CONNECTION_G_PROXY_RESOLVER,
+                                    "Proxy resolver",
+                                    "GProxyResolver to use",
+                                    G_TYPE_PROXY_RESOLVER,
+                                    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+       g_object_class_install_property (
                object_class, PROP_SSL,
                g_param_spec_boolean (SOUP_CONNECTION_SSL,
                                      "SSL",
@@ -507,7 +519,7 @@ socket_connect_result (SoupSocket *sock, guint status, gpointer user_data)
                return;
        }
 
-       if (priv->use_gproxyresolver)
+       if (priv->g_proxy_resolver)
                priv->proxy_uri = soup_socket_get_http_proxy_uri (priv->socket);
 
        if (priv->ssl && !priv->proxy_uri) {
@@ -540,7 +552,7 @@ connect_async_to_uri (SoupConnectionAsyncConnectData *data, SoupURI *uri)
                                 SOUP_SOCKET_SSL_FALLBACK, priv->ssl_fallback,
                                 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
                                 SOUP_SOCKET_USE_THREAD_CONTEXT, priv->use_thread_context,
-                                SOUP_SOCKET_USE_PROXY, priv->use_gproxyresolver,
+                                SOUP_SOCKET_PROXY_RESOLVER, priv->g_proxy_resolver,
                                 SOUP_SOCKET_TIMEOUT, priv->io_timeout,
                                 SOUP_SOCKET_CLEAN_DISPOSE, TRUE,
                                 SOUP_SOCKET_LOCAL_ADDRESS, priv->local_addr,
@@ -597,7 +609,7 @@ soup_connection_connect_async (SoupConnection *conn,
        data->callback_data = user_data;
        data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 
-       if (!priv->proxy_resolver) {
+       if (!priv->soup_proxy_resolver) {
                connect_async_to_uri (data, priv->remote_uri);
                return;
        }
@@ -607,7 +619,7 @@ soup_connection_connect_async (SoupConnection *conn,
        else
                async_context = priv->async_context;
 
-       soup_proxy_uri_resolver_get_proxy_uri_async (priv->proxy_resolver,
+       soup_proxy_uri_resolver_get_proxy_uri_async (priv->soup_proxy_resolver,
                                                     priv->remote_uri,
                                                     async_context,
                                                     cancellable,
@@ -629,8 +641,8 @@ soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
 
        soup_connection_set_state (conn, SOUP_CONNECTION_CONNECTING);
 
-       if (priv->proxy_resolver) {
-               status = soup_proxy_uri_resolver_get_proxy_uri_sync (priv->proxy_resolver,
+       if (priv->soup_proxy_resolver) {
+               status = soup_proxy_uri_resolver_get_proxy_uri_sync (priv->soup_proxy_resolver,
                                                                     priv->remote_uri,
                                                                     cancellable,
                                                                     &priv->proxy_uri);
@@ -647,7 +659,7 @@ soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
        remote_addr = soup_address_new (connect_uri->host, connect_uri->port);
        priv->socket =
                soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, remote_addr,
-                                SOUP_SOCKET_USE_PROXY, priv->use_gproxyresolver,
+                                SOUP_SOCKET_PROXY_RESOLVER, priv->g_proxy_resolver,
                                 SOUP_SOCKET_SSL_CREDENTIALS, priv->tlsdb,
                                 SOUP_SOCKET_SSL_STRICT, priv->ssl_strict,
                                 SOUP_SOCKET_SSL_FALLBACK, priv->ssl_fallback,
@@ -665,7 +677,7 @@ soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
        if (!SOUP_STATUS_IS_SUCCESSFUL (status))
                goto fail;
 
-       if (priv->use_gproxyresolver)
+       if (priv->g_proxy_resolver)
                priv->proxy_uri = soup_socket_get_http_proxy_uri (priv->socket);
 
        if (priv->ssl && !priv->proxy_uri) {
index 50fb701..dcfb56a 100644 (file)
@@ -41,7 +41,8 @@ typedef void  (*SoupConnectionCallback)        (SoupConnection   *conn,
 
 #define SOUP_CONNECTION_LOCAL_ADDRESS   "local-address"
 #define SOUP_CONNECTION_REMOTE_URI      "remote-uri"
-#define SOUP_CONNECTION_PROXY_RESOLVER  "proxy-resolver"
+#define SOUP_CONNECTION_SOUP_PROXY_RESOLVER  "soup-proxy-resolver"
+#define SOUP_CONNECTION_G_PROXY_RESOLVER  "g-proxy-resolver"
 #define SOUP_CONNECTION_SSL             "ssl"
 #define SOUP_CONNECTION_SSL_CREDENTIALS "ssl-creds"
 #define SOUP_CONNECTION_SSL_STRICT      "ssl-strict"
index 79e73bc..b9f0724 100644 (file)
@@ -23,7 +23,7 @@ GIOStream *soup_socket_get_connection (SoupSocket *sock);
 GIOStream *soup_socket_get_iostream   (SoupSocket *sock);
 
 #define SOUP_SOCKET_CLEAN_DISPOSE "clean-dispose"
-#define SOUP_SOCKET_USE_PROXY     "use-proxy"
+#define SOUP_SOCKET_PROXY_RESOLVER "proxy-resolver"
 SoupURI *soup_socket_get_http_proxy_uri (SoupSocket *sock);
 
 /* At some point it might be possible to mark additional methods
index a153cde..14e2be4 100644 (file)
@@ -122,6 +122,7 @@ typedef struct {
        GSList *run_queue_sources;
 
        GResolver *resolver;
+       GProxyResolver *g_proxy_resolver;
 
        char **http_aliases, **https_aliases;
 
@@ -173,6 +174,7 @@ enum {
        PROP_0,
 
        PROP_PROXY_URI,
+       PROP_PROXY_RESOLVER,
        PROP_MAX_CONNS,
        PROP_MAX_CONNS_PER_HOST,
        PROP_USE_NTLM,
@@ -335,6 +337,7 @@ soup_session_finalize (GObject *object)
        g_hash_table_destroy (priv->features_cache);
 
        g_object_unref (priv->resolver);
+       g_clear_object (&priv->g_proxy_resolver);
 
        g_free (priv->http_aliases);
        g_free (priv->https_aliases);
@@ -556,23 +559,26 @@ soup_session_set_property (GObject *object, guint prop_id,
                break;
        case PROP_PROXY_URI:
                uri = g_value_get_boxed (value);
-
                if (uri) {
-#ifdef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-#endif
+                       G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
                        soup_session_remove_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER);
-#ifdef G_GNUC_END_IGNORE_DEPRECATIONS
-G_GNUC_END_IGNORE_DEPRECATIONS
-#endif
+                       G_GNUC_END_IGNORE_DEPRECATIONS;
                        feature = SOUP_SESSION_FEATURE (soup_proxy_resolver_static_new (uri));
                        soup_session_add_feature (session, feature);
                        g_object_unref (feature);
                } else
                        soup_session_remove_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER_STATIC);
-
+               g_clear_object (&priv->g_proxy_resolver);
                soup_session_abort (session);
                break;
+       case PROP_PROXY_RESOLVER:
+               G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+               soup_session_remove_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER);
+               G_GNUC_END_IGNORE_DEPRECATIONS;
+               if (priv->g_proxy_resolver)
+                       g_object_unref (priv->g_proxy_resolver);
+               priv->g_proxy_resolver = g_value_dup_object (value);
+               break;
        case PROP_MAX_CONNS:
                priv->max_conns = g_value_get_int (value);
                break;
@@ -702,6 +708,9 @@ soup_session_get_property (GObject *object, guint prop_id,
                } else
                        g_value_set_boxed (value, NULL);
                break;
+       case PROP_PROXY_RESOLVER:
+               g_value_set_object (value, priv->g_proxy_resolver);
+               break;
        case PROP_MAX_CONNS:
                g_value_set_int (value, priv->max_conns);
                break;
@@ -1662,7 +1671,8 @@ get_connection_for_host (SoupSession *session,
        conn = g_object_new (
                SOUP_TYPE_CONNECTION,
                SOUP_CONNECTION_REMOTE_URI, host->uri,
-               SOUP_CONNECTION_PROXY_RESOLVER, soup_session_get_feature (session, SOUP_TYPE_PROXY_URI_RESOLVER),
+               SOUP_CONNECTION_SOUP_PROXY_RESOLVER, soup_session_get_feature (session, SOUP_TYPE_PROXY_URI_RESOLVER),
+               SOUP_CONNECTION_G_PROXY_RESOLVER, priv->g_proxy_resolver,
                SOUP_CONNECTION_SSL, uri_is_https (priv, soup_message_get_uri (item->msg)),
                SOUP_CONNECTION_SSL_CREDENTIALS, priv->tlsdb,
                SOUP_CONNECTION_SSL_STRICT, priv->ssl_strict && (priv->tlsdb != NULL || SOUP_IS_PLAIN_SESSION (session)),
@@ -2458,6 +2468,10 @@ soup_session_add_feature (SoupSession *session, SoupSessionFeature *feature)
        g_return_if_fail (SOUP_IS_SESSION_FEATURE (feature));
 
        priv = SOUP_SESSION_GET_PRIVATE (session);
+
+       if (SOUP_IS_PROXY_URI_RESOLVER (feature))
+               g_clear_object (&priv->g_proxy_resolver);
+
        priv->features = g_slist_prepend (priv->features, g_object_ref (feature));
        g_hash_table_remove_all (priv->features_cache);
        soup_session_feature_attach (feature, session);
@@ -2955,7 +2969,8 @@ soup_session_class_init (SoupSessionClass *session_class)
         * An http proxy to use for all http and https requests in
         * this session. Setting this will remove any
         * #SoupProxyURIResolver features that have been added to the
-        * session.
+        * session. Setting this property will also cancel all
+        * currently pending messages.
         *
         * Note that #SoupProxyResolverDefault will handle looking up
         * the user's proxy settings for you; you should only use
@@ -2975,6 +2990,35 @@ soup_session_class_init (SoupSessionClass *session_class)
                                    SOUP_TYPE_URI,
                                    G_PARAM_READWRITE));
        /**
+        * SoupSession:proxy-resolver:
+        *
+        * A #GProxyResolver to use with this session. Setting this
+        * will clear the #SoupSession:proxy-uri property, and remove
+        * any #SoupProxyURIResolver features that have been added to
+        * the session.
+        *
+        * You only need to set this if you want to manually control
+        * proxy resolution (and need to do something more complicated than
+        * #SoupSession:proxy-uri allows). If you just want to use the
+        * system proxy settings, #SoupProxyResolverDefault will do that
+        * for you, and that is automatically part of the session if you
+        * are using a plain #SoupSession.
+        *
+        * Since: 2.42
+        */
+       /**
+        * SOUP_SESSION_PROXY_RESOLVER:
+        *
+        * Alias for the #SoupSession:proxy-resolver property, qv.
+        **/
+       g_object_class_install_property (
+               object_class, PROP_PROXY_RESOLVER,
+               g_param_spec_object (SOUP_SESSION_PROXY_RESOLVER,
+                                    "Proxy Resolver",
+                                    "The GProxyResolver to use for this session",
+                                    G_TYPE_PROXY_RESOLVER,
+                                    G_PARAM_READWRITE));
+       /**
         * SOUP_SESSION_MAX_CONNS:
         *
         * Alias for the #SoupSession:max-conns property, qv.
index 9d0f232..67a59ea 100644 (file)
@@ -62,6 +62,7 @@ GType soup_session_get_type (void);
 
 #define SOUP_SESSION_LOCAL_ADDRESS          "local-address"
 #define SOUP_SESSION_PROXY_URI              "proxy-uri"
+#define SOUP_SESSION_PROXY_RESOLVER         "proxy-resolver"
 #define SOUP_SESSION_MAX_CONNS              "max-conns"
 #define SOUP_SESSION_MAX_CONNS_PER_HOST     "max-conns-per-host"
 #define SOUP_SESSION_USE_NTLM               "use-ntlm"
index 885d531..4268429 100644 (file)
@@ -58,7 +58,7 @@ enum {
        PROP_CLEAN_DISPOSE,
        PROP_TLS_CERTIFICATE,
        PROP_TLS_ERRORS,
-       PROP_USE_PROXY,
+       PROP_PROXY_RESOLVER,
 
        LAST_PROP
 };
@@ -70,6 +70,7 @@ typedef struct {
        GInputStream *istream;
        GOutputStream *ostream;
        GTlsCertificateFlags tls_errors;
+       GProxyResolver *proxy_resolver;
 
        guint non_blocking:1;
        guint is_server:1;
@@ -78,7 +79,6 @@ typedef struct {
        guint ssl_fallback:1;
        guint clean_dispose:1;
        guint use_thread_context:1;
-       guint use_proxy:1;
        gpointer ssl_creds;
 
        GMainContext   *async_context;
@@ -149,6 +149,8 @@ soup_socket_finalize (GObject *object)
        g_clear_object (&priv->local_addr);
        g_clear_object (&priv->remote_addr);
 
+       g_clear_object (&priv->proxy_resolver);
+
        if (priv->watch_src) {
                if (priv->clean_dispose && !priv->is_server)
                        g_warning ("Disposing socket %p during async op", object);
@@ -219,8 +221,8 @@ soup_socket_set_property (GObject *object, guint prop_id,
                if (priv->conn)
                        g_socket_set_timeout (priv->gsock, priv->timeout);
                break;
-       case PROP_USE_PROXY:
-               priv->use_proxy = g_value_get_boolean (value);
+       case PROP_PROXY_RESOLVER:
+               priv->proxy_resolver = g_value_dup_object (value);
                break;
        case PROP_CLEAN_DISPOSE:
                priv->clean_dispose = g_value_get_boolean (value);
@@ -280,8 +282,8 @@ soup_socket_get_property (GObject *object, guint prop_id,
        case PROP_TLS_ERRORS:
                g_value_set_flags (value, priv->tls_errors);
                break;
-       case PROP_USE_PROXY:
-               g_value_set_boolean (value, priv->use_proxy);
+       case PROP_PROXY_RESOLVER:
+               g_value_set_object (value, priv->proxy_resolver);
                break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -618,12 +620,12 @@ soup_socket_class_init (SoupSocketClass *socket_class)
                                    G_PARAM_READABLE));
 
        g_object_class_install_property (
-               object_class, PROP_USE_PROXY,
-               g_param_spec_boolean (SOUP_SOCKET_USE_PROXY,
-                                     "Use proxy",
-                                     "Use #GProxyResolver",
-                                     FALSE,
-                                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+               object_class, PROP_PROXY_RESOLVER,
+               g_param_spec_object (SOUP_SOCKET_PROXY_RESOLVER,
+                                    "Proxy resolver",
+                                    "GProxyResolver to use",
+                                    G_TYPE_PROXY_RESOLVER,
+                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 
@@ -705,9 +707,10 @@ new_socket_client (SoupSocket *sock)
 
        g_signal_connect (client, "event",
                          G_CALLBACK (re_emit_socket_client_event), sock);
-       if (priv->use_proxy)
+       if (priv->proxy_resolver) {
+               g_socket_client_set_proxy_resolver (client, priv->proxy_resolver);
                g_socket_client_add_application_proxy (client, "http");
-       else
+       else
                g_socket_client_set_enable_proxy (client, FALSE);
        if (priv->timeout)
                g_socket_client_set_timeout (client, priv->timeout);