[libsoup] soup-auth-manager: add soup_auth_manager_use_auth()



commit b99acd6fcc30ea537d8a758ff8ce5e2f84848781
Author: Dan Winship <danw gnome org>
Date:   Tue Jan 1 11:46:18 2013 -0500

    soup-auth-manager: add soup_auth_manager_use_auth()
    
    Add soup_auth_manager_use_auth(), for "preloading" authentication, and
    make the old automatically-request-NTLM behavior happen only for
    the legacy SoupSession subclasses.

 docs/reference/libsoup-2.4-sections.txt |    1 +
 docs/reference/session-porting.xml      |   45 +++++++++++++++++++++++++++++++
 libsoup/libsoup-2.4.sym                 |    1 +
 libsoup/soup-auth-manager.c             |   34 ++++++++++++++++++++++-
 libsoup/soup-auth-manager.h             |    4 +++
 libsoup/soup-auth.c                     |   14 ++++++---
 tests/ntlm-test.c                       |   16 ++++++++---
 7 files changed, 105 insertions(+), 10 deletions(-)
---
diff --git a/docs/reference/libsoup-2.4-sections.txt b/docs/reference/libsoup-2.4-sections.txt
index fc56dc5..52e505d 100644
--- a/docs/reference/libsoup-2.4-sections.txt
+++ b/docs/reference/libsoup-2.4-sections.txt
@@ -571,6 +571,7 @@ soup_auth_save_password
 <TITLE>SoupAuthManager</TITLE>
 SoupAuthManager
 SOUP_TYPE_AUTH_MANAGER
+soup_auth_manager_use_auth
 <SUBSECTION Standard>
 SoupAuthManagerPrivate
 SoupAuthManagerClass
diff --git a/docs/reference/session-porting.xml b/docs/reference/session-porting.xml
index 680f75a..bf1aa41 100644
--- a/docs/reference/session-porting.xml
+++ b/docs/reference/session-porting.xml
@@ -105,6 +105,51 @@ linkend="SoupSessionAsync"><type>SoupSessionAsync</type></link> and
 
 </refsect2>
 
+<refsect2 id="behavior">
+<title>Differences in feature behavior</title>
+
+<para>
+If you are using NTLM authentication, the new <type>SoupSession</type>
+behaves slightly differently from the old session types.
+</para>
+
+<para>
+First, the deprecated <link
+linkend="SOUP-SESSION-USE-NTLM:CAPS"><literal>SOUP_SESSION_USE_NTLM</literal></link>
+property is no longer supported. If you want to add support for NTLM
+to a session, call <link
+linkend="soup-session-add-feature-by-type"><function>soup_session_add_feature_by_type()</function></link>,
+passing <link
+linkend="SOUP-TYPE-AUTH-NTLM:CAPS"><literal>SOUP_TYPE_AUTH_NTLM</literal></link>.
+</para>
+
+<para>
+Second, with the old session types, enabling NTLM would cause all
+(otherwise-unauthenticated) requests to be sent with an NTLM request
+in the <literal>Authorization</literal> header. That is, libsoup would
+assume that all servers supported NTLM, and would attempt to begin
+negotiating NTLM authentication before the server ever returned a 401
+response. With the plain <type>SoupSession</type>, this no longer
+happens. If you want the old behavior, you need to call <link
+linkend="soup-auth-manager-use-auth"><function>soup_auth_manager_use_auth()</function></link>
+for each host to "preload" the NTLM authentication:
+</para>
+
+<informalexample><programlisting>
+	SoupAuthManager *auth_manager;
+	SoupAuth *auth;
+	SoupURI *uri;
+
+	auth_manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
+	auth = g_object_new (SOUP_TYPE_AUTH_NTLM, NULL);
+	uri = soup_uri_new ("http://ntlm-using-host.example.com/";);
+	soup_auth_manager_use_auth (auth_manager, uri, auth);
+	g_object_unref (auth);
+	soup_uri_free (auth);
+</programlisting></informalexample>
+
+</refsect2>
+
 <refsect2 id="apis">
 <title>Differences in SoupMessage-sending APIs</title>
 
diff --git a/libsoup/libsoup-2.4.sym b/libsoup/libsoup-2.4.sym
index d3631b2..6b82f5a 100644
--- a/libsoup/libsoup-2.4.sym
+++ b/libsoup/libsoup-2.4.sym
@@ -55,6 +55,7 @@ soup_auth_is_authenticated
 soup_auth_is_for_proxy
 soup_auth_is_ready
 soup_auth_manager_get_type
+soup_auth_manager_use_auth
 soup_auth_new
 soup_auth_ntlm_get_type
 soup_auth_save_password
diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
index c4cf783..3483a32 100644
--- a/libsoup/soup-auth-manager.c
+++ b/libsoup/soup-auth-manager.c
@@ -171,7 +171,11 @@ soup_auth_manager_add_feature (SoupSessionFeature *feature, GType type)
 	g_ptr_array_add (priv->auth_types, auth_class);
 	g_ptr_array_sort (priv->auth_types, auth_type_compare_func);
 
-	if (type == SOUP_TYPE_AUTH_NTLM)
+	/* Plain SoupSession does not get the backward-compat
+	 * auto-NTLM behavior; SoupSession subclasses do.
+	 */
+	if (type == SOUP_TYPE_AUTH_NTLM &&
+	    G_TYPE_FROM_INSTANCE (priv->session) != SOUP_TYPE_SESSION)
 		priv->auto_ntlm = TRUE;
 
 	return TRUE;
@@ -675,6 +679,34 @@ soup_auth_manager_request_unqueued (SoupSessionFeature *manager,
 					      0, 0, NULL, NULL, manager);
 }
 
+/**
+ * soup_auth_manager_use_auth:
+ * @manager: a #SoupAuthManager
+ * @uri: the #SoupURI under which @auth is to be used
+ * @auth: the #SoupAuth to use
+ *
+ * Records that @auth is to be used under @uri, as though a
+ * WWW-Authenticate header had been received at that URI. This can be
+ * used to "preload" @manager's auth cache, to avoid an extra HTTP
+ * round trip in the case where you know ahead of time that a 401
+ * response will be returned.
+ *
+ * This is only useful for authentication types where the initial
+ * Authorization header does not depend on any additional information
+ * from the server. (Eg, Basic or NTLM, but not Digest.)
+ *
+ * Since: 2.42
+ */
+void
+soup_auth_manager_use_auth (SoupAuthManager *manager,
+			    SoupURI         *uri,
+			    SoupAuth        *auth)
+{
+	SoupAuthManagerPrivate *priv = manager->priv;
+
+	record_auth_for_uri (priv, uri, auth);
+}
+
 static void
 soup_auth_manager_session_feature_init (SoupSessionFeatureInterface *feature_interface,
 					gpointer interface_data)
diff --git a/libsoup/soup-auth-manager.h b/libsoup/soup-auth-manager.h
index a9436bd..c1fcc6e 100644
--- a/libsoup/soup-auth-manager.h
+++ b/libsoup/soup-auth-manager.h
@@ -35,6 +35,10 @@ typedef struct {
 
 GType soup_auth_manager_get_type (void);
 
+void  soup_auth_manager_use_auth (SoupAuthManager *manager,
+				  SoupURI         *uri,
+				  SoupAuth        *auth);
+
 G_END_DECLS
 
 #endif /* SOUP_AUTH_MANAGER_H */
diff --git a/libsoup/soup-auth.c b/libsoup/soup-auth.c
index 5ce92d5..8f1e218 100644
--- a/libsoup/soup-auth.c
+++ b/libsoup/soup-auth.c
@@ -12,9 +12,9 @@
 #include <string.h>
 
 #include "soup-auth.h"
-#include "soup-headers.h"
+#include "soup.h"
+#include "soup-connection-auth.h"
 #include "soup-marshal.h"
-#include "soup-uri.h"
 
 /**
  * SECTION:soup-auth
@@ -417,9 +417,13 @@ soup_auth_get_info (SoupAuth *auth)
 {
 	g_return_val_if_fail (SOUP_IS_AUTH (auth), NULL);
 
-	return g_strdup_printf ("%s:%s",
-				SOUP_AUTH_GET_CLASS (auth)->scheme_name,
-				auth->realm);
+	if (SOUP_IS_CONNECTION_AUTH (auth))
+		return g_strdup (SOUP_AUTH_GET_CLASS (auth)->scheme_name);
+	else {
+		return g_strdup_printf ("%s:%s",
+					SOUP_AUTH_GET_CLASS (auth)->scheme_name,
+					auth->realm);
+	}
 }
 
 /**
diff --git a/tests/ntlm-test.c b/tests/ntlm-test.c
index 3184ffc..fa31280 100644
--- a/tests/ntlm-test.c
+++ b/tests/ntlm-test.c
@@ -333,9 +333,7 @@ do_ntlm_round (SoupURI *base_uri, gboolean use_ntlm,
 	gboolean bob_via_ntlm = use_ntlm && bob;
 	gboolean alice_via_basic = !use_ntlm && alice;
 
-	session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
-	if (use_ntlm)
-		soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
+	session = soup_test_session_new (SOUP_TYPE_SESSION, NULL);
 
 	if (user) {
 		g_signal_connect (session, "authenticate",
@@ -343,6 +341,16 @@ do_ntlm_round (SoupURI *base_uri, gboolean use_ntlm,
 		if (use_ntlm && !use_builtin_ntlm)
 			g_setenv ("NTLMUSER", user, TRUE);
 	}
+	if (use_ntlm) {
+		SoupAuthManager *auth_manager;
+		SoupAuth *ntlm;
+
+		soup_session_add_feature_by_type (session, SOUP_TYPE_AUTH_NTLM);
+		auth_manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
+		ntlm = g_object_new (SOUP_TYPE_AUTH_NTLM, NULL);
+		soup_auth_manager_use_auth (auth_manager, base_uri, ntlm);
+		g_object_unref (ntlm);
+	}
 
 	/* 1. Server doesn't request auth, so both get_ntlm_prompt and
 	 * get_basic_prompt are both FALSE, and likewise do_basic. But
@@ -464,7 +472,7 @@ main (int argc, char **argv)
 
 	test_init (argc, argv, NULL);
 
-	server = soup_test_server_new (FALSE);
+	server = soup_test_server_new (TRUE);
 	connections = g_hash_table_new (NULL, NULL);
 	soup_server_add_handler (server, NULL,
 				 server_callback, connections, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]