Replaces SoupConnectionNTLM; now works as a SoupSession::request_started
authorDan Winship <danw@src.gnome.org>
Tue, 15 Jan 2008 22:52:36 +0000 (22:52 +0000)
committerDan Winship <danw@src.gnome.org>
Tue, 15 Jan 2008 22:52:36 +0000 (22:52 +0000)
* libsoup/soup-auth-manager-ntlm.c: Replaces SoupConnectionNTLM;
now works as a SoupSession::request_started watcher.

* libsoup/soup-connection.c: remove the no-longer-needed
"authenticate" signal

* libsoup/soup-session.c: Use a SoupAuthManagerNTLM if USE_NTLM is
set. Remove connection-authenticate-signal references.

svn path=/trunk/; revision=1043

ChangeLog
libsoup/Makefile.am
libsoup/soup-auth-manager-ntlm.c [moved from libsoup/soup-connection-ntlm.c with 81% similarity]
libsoup/soup-auth-manager-ntlm.h [new file with mode: 0644]
libsoup/soup-connection-ntlm.h [deleted file]
libsoup/soup-connection.c
libsoup/soup-connection.h
libsoup/soup-session.c

index 3f625e1..b09d002 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2008-01-15  Dan Winship  <danw@gnome.org>
 
+       * libsoup/soup-auth-manager-ntlm.c: Replaces SoupConnectionNTLM;
+       now works as a SoupSession::request_started watcher.
+
+       * libsoup/soup-connection.c: remove the no-longer-needed
+       "authenticate" signal
+
+       * libsoup/soup-session.c: Use a SoupAuthManagerNTLM if USE_NTLM is
+       set. Remove connection-authenticate-signal references.
+
+2008-01-15  Dan Winship  <danw@gnome.org>
+
        * Merge libsoup-2.4 branch to trunk
        
 2008-01-15  Dan Winship  <danw@gnome.org>
index 2979eed..571413f 100644 (file)
@@ -105,10 +105,10 @@ libsoup_2_4_la_SOURCES =          \
        soup-auth-domain-digest.c       \
        soup-auth-manager.h             \
        soup-auth-manager.c             \
+       soup-auth-manager-ntlm.h        \
+       soup-auth-manager-ntlm.c        \
        soup-connection.h               \
        soup-connection.c               \
-       soup-connection-ntlm.h          \
-       soup-connection-ntlm.c          \
        soup-date.c                     \
        soup-enum-types.c               \
        soup-dns.h                      \
similarity index 81%
rename from libsoup/soup-connection-ntlm.c
rename to libsoup/soup-auth-manager-ntlm.c
index efd1570..b8bb7a6 100644 (file)
@@ -1,8 +1,9 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * soup-connection-ntlm.c: NTLM-using Connection
+ * soup-auth-manager-ntlm.c: NTLM auth manager
  *
- * Copyright (C) 2001-2003, Ximian, Inc.
+ * Copyright (C) 2001-2007 Novell, Inc.
+ * Copyright (C) 2008 Red Hat, Inc.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <ctype.h>
 #include <string.h>
 
-#include "soup-connection-ntlm.h"
+#include "soup-auth-manager-ntlm.h"
 #include "soup-auth-ntlm.h"
 #include "soup-message.h"
-#include "soup-message-private.h"
 #include "soup-misc.h"
+#include "soup-session.h"
+#include "soup-session-private.h"
 #include "soup-uri.h"
 
-static void send_request (SoupConnection *conn, SoupMessage *req);
-
 typedef enum {
-       SOUP_CONNECTION_NTLM_NEW,
-       SOUP_CONNECTION_NTLM_SENT_REQUEST,
-       SOUP_CONNECTION_NTLM_RECEIVED_CHALLENGE,
-       SOUP_CONNECTION_NTLM_SENT_RESPONSE,
-       SOUP_CONNECTION_NTLM_FAILED
-} SoupConnectionNTLMState;
+       SOUP_NTLM_NEW,
+       SOUP_NTLM_SENT_REQUEST,
+       SOUP_NTLM_RECEIVED_CHALLENGE,
+       SOUP_NTLM_SENT_RESPONSE,
+       SOUP_NTLM_FAILED
+} SoupNTLMState;
 
 typedef struct {
-       guchar nt_hash[21], lm_hash[21];
-       SoupConnectionNTLMState state;
-} SoupConnectionNTLMPrivate;
-#define SOUP_CONNECTION_NTLM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_CONNECTION_NTLM, SoupConnectionNTLMPrivate))
+       SoupSocket *socket;
+       SoupNTLMState state;
+       char *response_header;
+} SoupNTLMConnection;
+
+struct SoupAuthManagerNTLM {
+       SoupSession *session;
+       GHashTable *connections_by_msg;
+       GHashTable *connections_by_id;
+};
 
-G_DEFINE_TYPE (SoupConnectionNTLM, soup_connection_ntlm, SOUP_TYPE_CONNECTION)
+static void ntlm_request_started (SoupSession *session, SoupMessage *msg,
+                                 SoupSocket *socket, gpointer ntlm);
 
 static char     *soup_ntlm_request         (void);
 static gboolean  soup_ntlm_parse_challenge (const char  *challenge,
@@ -47,52 +54,129 @@ static char     *soup_ntlm_response        (const char  *nonce,
                                            const char  *host, 
                                            const char  *domain);
 
+SoupAuthManagerNTLM *
+soup_auth_manager_ntlm_new (SoupSession *session)
+{
+       SoupAuthManagerNTLM *ntlm;
+
+       ntlm = g_slice_new (SoupAuthManagerNTLM);
+       ntlm->session = session;
+       ntlm->connections_by_id = g_hash_table_new (NULL, NULL);
+       ntlm->connections_by_msg = g_hash_table_new (NULL, NULL);
+       g_signal_connect (session, "request_started",
+                         G_CALLBACK (ntlm_request_started), ntlm);
+       return ntlm;
+}
+
 static void
-soup_connection_ntlm_init (SoupConnectionNTLM *ntlm)
+free_ntlm_connection (SoupNTLMConnection *conn)
 {
+       g_free (conn->response_header);
+       g_slice_free (SoupNTLMConnection, conn);
 }
 
 static void
-finalize (GObject *object)
+free_ntlm_connection_foreach (gpointer key, gpointer value, gpointer user_data)
 {
-       SoupConnectionNTLMPrivate *priv = SOUP_CONNECTION_NTLM_GET_PRIVATE (object);
+       free_ntlm_connection (value);
+}
 
-       memset (priv->nt_hash, 0, sizeof (priv->nt_hash));
-       memset (priv->lm_hash, 0, sizeof (priv->lm_hash));
+void
+soup_auth_manager_ntlm_free (SoupAuthManagerNTLM *ntlm)
+{
+       g_hash_table_foreach (ntlm->connections_by_id,
+                             free_ntlm_connection_foreach, NULL);
+       g_hash_table_destroy (ntlm->connections_by_id);
+       g_hash_table_destroy (ntlm->connections_by_msg);
+       g_signal_handlers_disconnect_by_func (ntlm->session,
+                                             ntlm_request_started, ntlm);
+
+       g_slice_free (SoupAuthManagerNTLM, ntlm);
+}
 
-       G_OBJECT_CLASS (soup_connection_ntlm_parent_class)->finalize (object);
+static void
+delete_conn (SoupSocket *socket, gpointer user_data)
+{
+       SoupAuthManagerNTLM *ntlm = user_data;
+       SoupNTLMConnection *conn;
+
+       conn = g_hash_table_lookup (ntlm->connections_by_id, socket);
+       if (conn)
+               free_ntlm_connection (conn);
+       g_hash_table_remove (ntlm->connections_by_id, socket);
+       g_signal_handlers_disconnect_by_func (socket, delete_conn, ntlm);
+}
+
+static SoupNTLMConnection *
+get_connection (SoupAuthManagerNTLM *ntlm, SoupSocket *socket)
+{
+       SoupNTLMConnection *conn;
+
+       conn = g_hash_table_lookup (ntlm->connections_by_id, socket);
+       if (conn)
+               return conn;
+
+       conn = g_slice_new0 (SoupNTLMConnection);
+       conn->socket = socket;
+       conn->state = SOUP_NTLM_NEW;
+       g_hash_table_insert (ntlm->connections_by_id, socket, conn);
+
+       g_signal_connect (socket, "disconnected",
+                         G_CALLBACK (delete_conn), ntlm);
+       return conn;
 }
 
 static void
-soup_connection_ntlm_class_init (SoupConnectionNTLMClass *connection_ntlm_class)
+unset_conn (SoupMessage *msg, gpointer user_data)
 {
-       SoupConnectionClass *connection_class = SOUP_CONNECTION_CLASS (connection_ntlm_class);
-       GObjectClass *object_class = G_OBJECT_CLASS (connection_ntlm_class);
+       SoupAuthManagerNTLM *ntlm = user_data;
 
-       g_type_class_add_private (connection_ntlm_class, sizeof (SoupConnectionNTLMPrivate));
+       g_hash_table_remove (ntlm->connections_by_msg, msg);
+       g_signal_handlers_disconnect_by_func (msg, unset_conn, ntlm);
+}
 
-       connection_class->send_request = send_request;
-       object_class->finalize = finalize;
+static SoupNTLMConnection *
+set_connection_for_msg (SoupAuthManagerNTLM *ntlm, SoupMessage *msg,
+                       SoupNTLMConnection *conn)
+{
+       if (!g_hash_table_lookup (ntlm->connections_by_msg, msg)) {
+               g_signal_connect (msg, "finished",
+                                 G_CALLBACK (unset_conn), ntlm);
+               g_signal_connect (msg, "restarted",
+                                 G_CALLBACK (unset_conn), ntlm);
+       }
+       g_hash_table_insert (ntlm->connections_by_msg, msg, conn);
+
+       return conn;
 }
 
+static SoupNTLMConnection *
+get_connection_for_msg (SoupAuthManagerNTLM *ntlm, SoupMessage *msg)
+{
+       return g_hash_table_lookup (ntlm->connections_by_msg, msg);
+}
 
 static void
 ntlm_authorize_pre (SoupMessage *msg, gpointer user_data)
 {
-       SoupConnectionNTLM *ntlm = user_data;
-       SoupConnectionNTLMPrivate *priv = SOUP_CONNECTION_NTLM_GET_PRIVATE (ntlm);
+       SoupAuthManagerNTLM *ntlm = user_data;
+       SoupNTLMConnection *conn;
        SoupAuth *auth;
        const char *val;
-       char *nonce, *header;
+       char *nonce;
        const char *username = NULL, *password = NULL;
        char *slash, *domain;
 
-       if (priv->state > SOUP_CONNECTION_NTLM_SENT_REQUEST) {
+       conn = get_connection_for_msg (ntlm, msg);
+       if (!conn)
+               return;
+
+       if (conn->state > SOUP_NTLM_SENT_REQUEST) {
                /* We already authenticated, but then got another 401.
                 * That means "permission denied", so don't try to
                 * authenticate again.
                 */
-               priv->state = SOUP_CONNECTION_NTLM_FAILED;
+               conn->state = SOUP_NTLM_FAILED;
                goto done;
        }
 
@@ -101,17 +185,17 @@ ntlm_authorize_pre (SoupMessage *msg, gpointer user_data)
        if (val)
                val = strstr (val, "NTLM ");
        if (!val) {
-               priv->state = SOUP_CONNECTION_NTLM_FAILED;
+               conn->state = SOUP_NTLM_FAILED;
                goto done;
        }
 
        if (!soup_ntlm_parse_challenge (val, &nonce, &domain)) {
-               priv->state = SOUP_CONNECTION_NTLM_FAILED;
+               conn->state = SOUP_NTLM_FAILED;
                goto done;
        }
 
        auth = soup_auth_ntlm_new (domain, soup_message_get_uri (msg)->host);
-       soup_connection_authenticate (SOUP_CONNECTION (ntlm), msg, auth, FALSE);
+       soup_session_emit_authenticate (ntlm->session, msg, auth, FALSE);
        username = soup_auth_ntlm_get_username (auth);
        password = soup_auth_ntlm_get_password (auth);
        if (!username || !password) {
@@ -125,20 +209,19 @@ ntlm_authorize_pre (SoupMessage *msg, gpointer user_data)
        if (slash) {
                g_free (domain);
                domain = g_strdup (username);
-               slash = strpbrk (domain, "\\/");
+               slash = domain + (slash - username);
                *slash = '\0';
                username = slash + 1;
        }
 
-       header = soup_ntlm_response (nonce, username, password, NULL, domain);
+       conn->response_header =
+               soup_ntlm_response (nonce, username, password, NULL, domain);
+       conn->state = SOUP_NTLM_RECEIVED_CHALLENGE;
+
        g_free (domain);
        g_free (nonce);
        g_object_unref (auth);
 
-       soup_message_headers_replace (msg->request_headers, "Authorization", header);
-       g_free (header);
-       priv->state = SOUP_CONNECTION_NTLM_RECEIVED_CHALLENGE;
-
  done:
        /* Remove the WWW-Authenticate headers so the session won't try
         * to do Basic auth too.
@@ -147,79 +230,83 @@ ntlm_authorize_pre (SoupMessage *msg, gpointer user_data)
 }
 
 static void
-ntlm_authorize_post (SoupMessage *msg, gpointer conn)
+ntlm_authorize_post (SoupMessage *msg, gpointer user_data)
 {
-       SoupConnectionNTLMPrivate *priv = SOUP_CONNECTION_NTLM_GET_PRIVATE (conn);
-
-       if (priv->state == SOUP_CONNECTION_NTLM_RECEIVED_CHALLENGE &&
-           soup_message_headers_get (msg->request_headers, "Authorization")) {
-               /* We just added the last Auth header, so restart it. */
-               priv->state = SOUP_CONNECTION_NTLM_SENT_RESPONSE;
-
-               /* soup_message_restarted() will call soup_message_io_stop(),
-                * which will release the connection, and may cause another
-                * message to be queued on the connection before it returns.
-                * That's no good, so we stop the message first and then
-                * reclaim the connection so that soup_message_restarted()
-                * won't be able to steal it.
-                */
-               soup_message_io_stop (msg);
-               soup_connection_reserve (conn);
-               soup_message_restarted (msg);
-               soup_connection_send_request (conn, msg);
-       }
+       SoupAuthManagerNTLM *ntlm = user_data;
+       SoupNTLMConnection *conn;
+
+       conn = get_connection_for_msg (ntlm, msg);
+       if (!conn)
+               return;
+
+       if (conn->state == SOUP_NTLM_RECEIVED_CHALLENGE &&
+           conn->response_header)
+               soup_session_requeue_message (ntlm->session, msg);
 }
 
 static void
-ntlm_cleanup_msg (SoupMessage *msg, gpointer conn)
+ntlm_cleanup_msg (SoupMessage *msg, gpointer ntlm)
 {
        /* Do this when the message is restarted, in case it's
         * restarted on a different connection.
         */
-       g_signal_handlers_disconnect_by_func (msg, ntlm_authorize_pre, conn);
-       g_signal_handlers_disconnect_by_func (msg, ntlm_authorize_post, conn);
+       g_signal_handlers_disconnect_by_func (msg, ntlm_authorize_pre, ntlm);
+       g_signal_handlers_disconnect_by_func (msg, ntlm_authorize_post, ntlm);
 }
 
 static void
-send_request (SoupConnection *conn, SoupMessage *req)
+ntlm_request_started (SoupSession *session, SoupMessage *msg,
+                     SoupSocket *socket, gpointer user_data)
 {
-       SoupConnectionNTLMPrivate *priv = SOUP_CONNECTION_NTLM_GET_PRIVATE (conn);
-
-       if (priv->state == SOUP_CONNECTION_NTLM_NEW) {
-               char *header = soup_ntlm_request ();
+       SoupAuthManagerNTLM *ntlm = user_data;
+       SoupNTLMConnection *conn;
+       char *header = NULL;
+
+       conn = get_connection (ntlm, socket);
+       set_connection_for_msg (ntlm, msg, conn);
+
+       switch (conn->state) {
+       case SOUP_NTLM_NEW:
+               header = soup_ntlm_request ();
+               conn->state = SOUP_NTLM_SENT_REQUEST;
+               break;
+       case SOUP_NTLM_RECEIVED_CHALLENGE:
+               header = conn->response_header;
+               conn->response_header = NULL;
+               conn->state = SOUP_NTLM_SENT_RESPONSE;
+               break;
+       default:
+               break;
+       }
 
-               soup_message_headers_replace (req->request_headers,
+       if (header) {
+               soup_message_headers_replace (msg->request_headers,
                                              "Authorization", header);
                g_free (header);
-               priv->state = SOUP_CONNECTION_NTLM_SENT_REQUEST;
        }
 
-       soup_message_add_status_code_handler (req, "got_headers",
+       soup_message_add_status_code_handler (msg, "got_headers",
                                              SOUP_STATUS_UNAUTHORIZED,
                                              G_CALLBACK (ntlm_authorize_pre),
-                                             conn);
-
-       soup_message_add_status_code_handler (req, "got_body",
+                                             ntlm);
+       soup_message_add_status_code_handler (msg, "got_body",
                                              SOUP_STATUS_UNAUTHORIZED,
                                              G_CALLBACK (ntlm_authorize_post),
-                                             conn);
-
-       g_signal_connect (req, "restarted",
-                         G_CALLBACK (ntlm_cleanup_msg), conn);
-       g_signal_connect (req, "finished",
-                         G_CALLBACK (ntlm_cleanup_msg), conn);
+                                             ntlm);
+       g_signal_connect (msg, "restarted",
+                         G_CALLBACK (ntlm_cleanup_msg), ntlm);
+       g_signal_connect (msg, "finished",
+                         G_CALLBACK (ntlm_cleanup_msg), ntlm);
 
-       SOUP_CONNECTION_CLASS (soup_connection_ntlm_parent_class)->send_request (conn, req);
 }
 
 
+/* NTLM code */
 
-/* MD4 */
 static void md4sum                (const unsigned char *in, 
                                   int                  nbytes, 
                                   unsigned char        digest[16]);
 
-/* DES */
 typedef guint32 DES_KS[16][2]; /* Single-key DES key schedule */
 
 static void deskey                (DES_KS, unsigned char *, int);
@@ -736,9 +823,7 @@ static guint32 Spbox[8][64] = {
 }
 /* Encrypt or decrypt a block of data in ECB mode */
 static void
-des(ks,block)
-guint32 ks[16][2];     /* Key schedule */
-unsigned char block[8];                /* Data block */
+des (guint32 ks[16][2], unsigned char block[8])
 {
        guint32 left,right,work;
        
@@ -873,10 +958,7 @@ static int bytebit[] = {
  * depending on the value of "decrypt"
  */
 static void
-deskey(k,key,decrypt)
-DES_KS k;                      /* Key schedule array */
-unsigned char *key;            /* 64 bits (will use only 56) */
-int decrypt;                   /* 0 = encrypt, 1 = decrypt */
+deskey (DES_KS k, unsigned char *key, int decrypt)
 {
        unsigned char pc1m[56];         /* place to modify pc1 into */
        unsigned char pcr[56];          /* place to rotate pc1 into */
diff --git a/libsoup/soup-auth-manager-ntlm.h b/libsoup/soup-auth-manager-ntlm.h
new file mode 100644 (file)
index 0000000..0f62417
--- /dev/null
@@ -0,0 +1,20 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_AUTH_MANAGER_NTLM_H
+#define SOUP_AUTH_MANAGER_NTLM_H 1
+
+#include "soup-types.h"
+
+G_BEGIN_DECLS
+
+typedef struct SoupAuthManagerNTLM SoupAuthManagerNTLM;
+
+SoupAuthManagerNTLM *soup_auth_manager_ntlm_new  (SoupSession         *session);
+void                 soup_auth_manager_ntlm_free (SoupAuthManagerNTLM *manager);
+
+G_END_DECLS
+
+#endif /* SOUP_AUTH_MANAGER_NTLM_H */
diff --git a/libsoup/soup-connection-ntlm.h b/libsoup/soup-connection-ntlm.h
deleted file mode 100644 (file)
index 19dcd8d..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2000-2003, Ximian, Inc.
- */
-
-#ifndef SOUP_CONNECTION_NTLM_H
-#define SOUP_CONNECTION_NTLM_H 1
-
-#include "soup-connection.h"
-
-#define SOUP_TYPE_CONNECTION_NTLM            (soup_connection_ntlm_get_type ())
-#define SOUP_CONNECTION_NTLM(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_CONNECTION_NTLM, SoupConnectionNTLM))
-#define SOUP_CONNECTION_NTLM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_CONNECTION_NTLM, SoupConnectionNTLMClass))
-#define SOUP_IS_CONNECTION_NTLM(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_CONNECTION_NTLM))
-#define SOUP_IS_CONNECTION_NTLM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_CONNECTION_NTLM))
-#define SOUP_CONNECTION_NTLM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_CONNECTION_NTLM, SoupConnectionNTLMClass))
-
-typedef struct {
-       SoupConnection parent;
-
-} SoupConnectionNTLM;
-
-typedef struct {
-       SoupConnectionClass  parent_class;
-
-} SoupConnectionNTLMClass;
-
-GType soup_connection_ntlm_get_type (void);
-
-#endif /*SOUP_CONNECTION_NTLM_H*/
index 4dc6d42..bc3e23b 100644 (file)
@@ -62,7 +62,6 @@ enum {
        CONNECT_RESULT,
        DISCONNECTED,
        REQUEST_STARTED,
-       AUTHENTICATE,
        LAST_SIGNAL
 };
 
@@ -166,17 +165,6 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
                              soup_marshal_NONE__OBJECT,
                              G_TYPE_NONE, 1,
                              SOUP_TYPE_MESSAGE);
-       signals[AUTHENTICATE] =
-               g_signal_new ("authenticate",
-                             G_OBJECT_CLASS_TYPE (object_class),
-                             G_SIGNAL_RUN_FIRST,
-                             G_STRUCT_OFFSET (SoupConnectionClass, authenticate),
-                             NULL, NULL,
-                             soup_marshal_NONE__OBJECT_OBJECT_BOOLEAN,
-                             G_TYPE_NONE, 3,
-                             SOUP_TYPE_MESSAGE,
-                             SOUP_TYPE_AUTH,
-                             G_TYPE_BOOLEAN);
 
        /* properties */
        g_object_class_install_property (
@@ -776,20 +764,3 @@ soup_connection_release (SoupConnection *conn)
 
        clear_current_request (conn);
 }
-
-/**
- * soup_connection_authenticate:
- * @conn: a #SoupConnection
- * @msg: the message to authenticate
- * @auth: the #SoupAuth to authenticate
- * @retrying: %TRUE if this is the second or later try
- *
- * Emits the %authenticate signal on @conn. For use by #SoupConnection
- * subclasses.
- **/
-void
-soup_connection_authenticate (SoupConnection *conn, SoupMessage *msg,
-                             SoupAuth *auth, gboolean retrying)
-{
-       g_signal_emit (conn, signals[AUTHENTICATE], 0, msg, auth, retrying);
-}
index 98f20d6..08c21be 100644 (file)
@@ -33,9 +33,6 @@ typedef struct {
 
        void (*request_started) (SoupConnection *, SoupMessage *);
 
-       void (*authenticate)    (SoupConnection *, SoupMessage *,
-                                SoupAuth *, gboolean);
-
        /* methods */
        void (*send_request) (SoupConnection *, SoupMessage *);
 } SoupConnectionClass;
@@ -75,12 +72,6 @@ void            soup_connection_send_request   (SoupConnection   *conn,
 void            soup_connection_reserve        (SoupConnection   *conn);
 void            soup_connection_release        (SoupConnection   *conn);
 
-/* protected */
-void            soup_connection_authenticate   (SoupConnection   *conn,
-                                               SoupMessage      *msg,
-                                               SoupAuth         *auth,
-                                               gboolean          retrying);
-
 G_END_DECLS
 
 #endif /* SOUP_CONNECTION_H */
index e6e5426..88156eb 100644 (file)
@@ -17,8 +17,8 @@
 #include "soup-auth-basic.h"
 #include "soup-auth-digest.h"
 #include "soup-auth-manager.h"
+#include "soup-auth-manager-ntlm.h"
 #include "soup-connection.h"
-#include "soup-connection-ntlm.h"
 #include "soup-marshal.h"
 #include "soup-message-private.h"
 #include "soup-message-queue.h"
@@ -49,7 +49,6 @@ typedef struct {
        SoupAuth *proxy_auth;
 
        guint max_conns, max_conns_per_host;
-       gboolean use_ntlm;
 
        char *ssl_ca_file;
        SoupSSLCredentials *ssl_creds;
@@ -57,6 +56,7 @@ typedef struct {
        SoupMessageQueue *queue;
 
        SoupAuthManager *auth_manager;
+       SoupAuthManagerNTLM *ntlm_manager;
 
        GHashTable *hosts; /* SoupURI -> SoupSessionHost */
        GHashTable *conns; /* SoupConnection -> SoupSessionHost */
@@ -385,7 +385,15 @@ set_property (GObject *object, guint prop_id,
                priv->max_conns_per_host = g_value_get_int (value);
                break;
        case PROP_USE_NTLM:
-               priv->use_ntlm = g_value_get_boolean (value);
+               if (g_value_get_boolean (value)) {
+                       if (!priv->ntlm_manager)
+                               priv->ntlm_manager = soup_auth_manager_ntlm_new (session);
+               } else {
+                       if (priv->ntlm_manager) {
+                               soup_auth_manager_ntlm_free (priv->ntlm_manager);
+                               priv->ntlm_manager = NULL;
+                       }
+               }
                break;
        case PROP_SSL_CA_FILE:
                new_ca_file = g_value_get_string (value);
@@ -437,7 +445,7 @@ get_property (GObject *object, guint prop_id,
                g_value_set_int (value, priv->max_conns_per_host);
                break;
        case PROP_USE_NTLM:
-               g_value_set_boolean (value, priv->use_ntlm);
+               g_value_set_boolean (value, priv->ntlm_manager != NULL);
                break;
        case PROP_SSL_CA_FILE:
                g_value_set_string (value, priv->ssl_ca_file);
@@ -538,13 +546,6 @@ soup_session_emit_authenticate (SoupSession *session, SoupMessage *msg,
 }
 
 static void
-reemit_authenticate (SoupConnection *conn, SoupMessage *msg,
-                    SoupAuth *auth, gboolean retrying, gpointer session)
-{
-       soup_session_emit_authenticate (session, msg, auth, retrying);
-}
-
-static void
 redirect_handler (SoupMessage *msg, gpointer user_data)
 {
        SoupSession *session = user_data;
@@ -796,9 +797,7 @@ soup_session_get_connection (SoupSession *session, SoupMessage *msg,
                return NULL;
        }
 
-       conn = g_object_new (
-               (priv->use_ntlm ?
-                SOUP_TYPE_CONNECTION_NTLM : SOUP_TYPE_CONNECTION),
+       conn = soup_connection_new (
                SOUP_CONNECTION_ORIGIN_URI, host->root_uri,
                SOUP_CONNECTION_PROXY_URI, priv->proxy_uri,
                SOUP_CONNECTION_SSL_CREDENTIALS, priv->ssl_creds,
@@ -814,9 +813,6 @@ soup_session_get_connection (SoupSession *session, SoupMessage *msg,
        g_signal_connect (conn, "request_started",
                          G_CALLBACK (connection_started_request),
                          session);
-       g_signal_connect (conn, "authenticate",
-                         G_CALLBACK (reemit_authenticate),
-                         session);
 
        g_hash_table_insert (priv->conns, conn, host);