diff -up libsoup-2.56.0/libsoup/soup-auth-negotiate.c.negotiate-internals libsoup-2.56.0/libsoup/soup-auth-negotiate.c
--- libsoup-2.56.0/libsoup/soup-auth-negotiate.c.negotiate-internals 2016-09-16 17:14:27.000000000 +0200
+++ libsoup-2.56.0/libsoup/soup-auth-negotiate.c 2017-06-20 14:34:42.018592998 +0200
@@ -83,11 +83,6 @@ typedef struct {
typedef struct {
gboolean is_authenticated;
-
- gulong message_finished_signal_id;
- gulong message_got_headers_signal_id;
-
- SoupNegotiateConnectionState *conn_state;
} SoupAuthNegotiatePrivate;
#define SOUP_AUTH_NEGOTIATE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_AUTH_NEGOTIATE, SoupAuthNegotiatePrivate))
@@ -108,7 +103,6 @@ static GSList *blacklisted_uris;
static void parse_uris_from_env_variable (const gchar *env_variable, GSList **list);
static void check_server_response (SoupMessage *msg, gpointer auth);
-static void remove_server_response_handler (SoupMessage *msg, gpointer auth);
static const char spnego_OID[] = "\x2b\x06\x01\x05\x05\x02";
static const gss_OID_desc gss_mech_spnego = { sizeof (spnego_OID) - 1, (void *) &spnego_OID };
@@ -116,12 +110,10 @@ static const gss_OID_desc gss_mech_spneg
static gpointer
soup_auth_negotiate_create_connection_state (SoupConnectionAuth *auth)
{
- SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (auth);
SoupNegotiateConnectionState *conn;
conn = g_slice_new0 (SoupNegotiateConnectionState);
conn->state = SOUP_NEGOTIATE_NEW;
- priv->conn_state = conn;
return conn;
}
@@ -137,14 +129,11 @@ static void
soup_auth_negotiate_free_connection_state (SoupConnectionAuth *auth,
gpointer state)
{
- SoupAuthNegotiate *negotiate = SOUP_AUTH_NEGOTIATE (auth);
- SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (negotiate);
SoupNegotiateConnectionState *conn = state;
free_connection_state_data (conn);
g_slice_free (SoupNegotiateConnectionState, conn);
- priv->conn_state = NULL;
}
static GSList *
@@ -226,7 +215,6 @@ soup_auth_negotiate_update_connection (S
#ifdef LIBSOUP_HAVE_GSSAPI
gboolean success = TRUE;
SoupNegotiateConnectionState *conn = state;
- SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (auth);
GError *err = NULL;
if (!check_auth_trusted_uri (auth, msg)) {
@@ -245,24 +233,19 @@ soup_auth_negotiate_update_connection (S
conn->state = SOUP_NEGOTIATE_RECEIVED_CHALLENGE;
if (soup_gss_build_response (conn, SOUP_AUTH (auth), &err)) {
- /* Register the callbacks just once */
- if (priv->message_finished_signal_id == 0) {
- gulong id = 0;
- id = g_signal_connect (msg,
- "finished",
- G_CALLBACK (remove_server_response_handler),
- auth);
- priv->message_finished_signal_id = id;
- }
-
- if (priv->message_got_headers_signal_id == 0) {
- gulong id = 0;
+ /* Connect the signal only once per message */
+ if (!g_object_get_data (G_OBJECT (msg), "negotiate-got-headers-connected")) {
/* Wait for the 2xx response to verify server response */
- id = g_signal_connect (msg,
+ g_signal_connect_data (msg,
"got_headers",
G_CALLBACK (check_server_response),
- auth);
- priv->message_got_headers_signal_id = id;
+ g_object_ref (auth),
+ (GClosureNotify) g_object_unref,
+ 0);
+ /* Mark that the signal was connected */
+ g_object_set_data (G_OBJECT (msg),
+ "negotiate-got-headers-connected",
+ GINT_TO_POINTER (1));
}
goto out;
} else {
@@ -333,7 +316,11 @@ check_server_response (SoupMessage *msg,
GError *err = NULL;
SoupAuthNegotiate *negotiate = auth;
SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (negotiate);
- SoupNegotiateConnectionState *conn = priv->conn_state;
+ SoupNegotiateConnectionState *conn;
+
+ conn = soup_connection_auth_get_connection_state_for_message (SOUP_CONNECTION_AUTH (auth), msg);
+ if (!conn)
+ return;
if (auth != soup_message_get_auth (msg))
return;
@@ -365,19 +352,6 @@ check_server_response (SoupMessage *msg,
g_clear_error (&err);
}
-static void
-remove_server_response_handler (SoupMessage *msg, gpointer auth)
-{
- SoupAuthNegotiate *negotiate = auth;
- SoupAuthNegotiatePrivate *priv = SOUP_AUTH_NEGOTIATE_GET_PRIVATE (negotiate);
-
- g_signal_handler_disconnect (msg, priv->message_got_headers_signal_id);
- priv->message_got_headers_signal_id = 0;
-
- g_signal_handler_disconnect (msg, priv->message_finished_signal_id);
- priv->message_finished_signal_id = 0;
-}
-
/* Check if scheme://host:port from message matches the given URI. */
static gint
match_base_uri (SoupURI *list_uri, SoupURI *msg_uri)
diff -up libsoup-2.56.0/libsoup/soup-connection-auth.c.negotiate-internals libsoup-2.56.0/libsoup/soup-connection-auth.c
--- libsoup-2.56.0/libsoup/soup-connection-auth.c.negotiate-internals 2016-02-05 16:05:33.000000000 +0100
+++ libsoup-2.56.0/libsoup/soup-connection-auth.c 2017-06-20 14:31:00.333517935 +0200
@@ -71,12 +71,31 @@ soup_connection_auth_finalize (GObject *
G_OBJECT_CLASS (soup_connection_auth_parent_class)->finalize (object);
}
-static gpointer
-get_connection_state_for_message (SoupConnectionAuth *auth, SoupMessage *msg)
+
+/**
+ * soup_connection_auth_get_connection_state_for_message:
+ * @auth: a #SoupConnectionAuth
+ * @msg: a #SoupMessage
+ *
+ * Returns an associated connection state object for the given @auth and @msg.
+ *
+ * This function is only useful from within implementations of SoupConnectionAuth
+ * subclasses.
+ *
+ * Return value: (transfer none): the connection state
+ *
+ * Since: 2.56
+ **/
+gpointer
+soup_connection_auth_get_connection_state_for_message (SoupConnectionAuth *auth,
+ SoupMessage *msg)
{
SoupConnection *conn;
gpointer state;
+ g_return_val_if_fail (SOUP_IS_CONNECTION_AUTH (auth), NULL);
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
+
conn = soup_message_get_connection (msg);
state = g_hash_table_lookup (auth->priv->conns, conn);
if (state)
@@ -98,7 +117,7 @@ soup_connection_auth_update (SoupAuth
GHashTable *auth_params)
{
SoupConnectionAuth *cauth = SOUP_CONNECTION_AUTH (auth);
- gpointer conn = get_connection_state_for_message (cauth, msg);
+ gpointer conn = soup_connection_auth_get_connection_state_for_message (cauth, msg);
GHashTableIter iter;
GString *auth_header;
gpointer key, value;
@@ -140,7 +159,7 @@ soup_connection_auth_get_authorization (
SoupMessage *msg)
{
SoupConnectionAuth *cauth = SOUP_CONNECTION_AUTH (auth);
- gpointer conn = get_connection_state_for_message (cauth, msg);
+ gpointer conn = soup_connection_auth_get_connection_state_for_message (cauth, msg);
return SOUP_CONNECTION_AUTH_GET_CLASS (auth)->
get_connection_authorization (cauth, msg, conn);
@@ -151,7 +170,7 @@ soup_connection_auth_is_ready (SoupAuth
SoupMessage *msg)
{
SoupConnectionAuth *cauth = SOUP_CONNECTION_AUTH (auth);
- gpointer conn = get_connection_state_for_message (cauth, msg);
+ gpointer conn = soup_connection_auth_get_connection_state_for_message (cauth, msg);
return SOUP_CONNECTION_AUTH_GET_CLASS (auth)->
is_connection_ready (SOUP_CONNECTION_AUTH (auth), msg, conn);
diff -up libsoup-2.56.0/libsoup/soup-connection-auth.h.negotiate-internals libsoup-2.56.0/libsoup/soup-connection-auth.h
--- libsoup-2.56.0/libsoup/soup-connection-auth.h.negotiate-internals 2016-09-16 17:14:27.000000000 +0200
+++ libsoup-2.56.0/libsoup/soup-connection-auth.h 2017-06-20 14:31:00.333517935 +0200
@@ -46,6 +46,10 @@ typedef struct {
GType soup_connection_auth_get_type (void);
+SOUP_AVAILABLE_IN_2_56
+gpointer soup_connection_auth_get_connection_state_for_message
+ (SoupConnectionAuth *auth,
+ SoupMessage *message);
G_END_DECLS
#endif /* SOUP_CONNECTION_AUTH_H */