1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-session-feature.c: Miscellaneous session feature-provider interface
5 * Copyright (C) 2008 Red Hat, Inc.
12 #include "soup-session-feature.h"
14 #include "soup-message-private.h"
17 * SECTION:soup-session-feature
18 * @short_description: Interface for miscellaneous session features
20 * #SoupSessionFeature is the interface used by classes that extend
21 * the functionality of a #SoupSession. Some features like HTTP
22 * authentication handling are implemented internally via
23 * #SoupSessionFeature<!-- -->s. Other features can be added to the session
24 * by the application. (Eg, #SoupLogger, #SoupCookieJar.)
26 * See soup_session_add_feature(), etc, to add a feature to a session.
32 * An object that implement some sort of optional feature for
39 * SoupSessionFeatureInterface:
40 * @parent: The parent interface.
41 * @attach: Perform setup when a feature is added to a session
42 * @detach: Perform cleanup when a feature is removed from a session
43 * @request_queued: Proxies the session's #SoupSession::request_queued signal
44 * @request_started: Proxies the session's #SoupSession::request_started signal
45 * @request_unqueued: Proxies the session's #SoupSession::request_unqueued signal
46 * @add_feature: adds a sub-feature to the main feature
47 * @remove_feature: removes a sub-feature from the main feature
48 * @has_feature: tests if the feature includes a sub-feature
50 * The interface implemented by #SoupSessionFeature<!-- -->s.
55 static void soup_session_feature_default_init (SoupSessionFeatureInterface *iface);
57 G_DEFINE_INTERFACE (SoupSessionFeature, soup_session_feature, G_TYPE_OBJECT)
60 weak_notify_unref (gpointer feature, GObject *ex_object)
62 g_object_unref (feature);
66 request_queued (SoupSession *session, SoupMessage *msg, gpointer feature)
68 if (soup_message_disables_feature (msg, feature))
71 SOUP_SESSION_FEATURE_GET_CLASS (feature)->
72 request_queued (feature, session, msg);
76 request_started (SoupSession *session, SoupMessage *msg,
77 SoupSocket *socket, gpointer feature)
79 if (soup_message_disables_feature (msg, feature))
82 SOUP_SESSION_FEATURE_GET_CLASS (feature)->
83 request_started (feature, session, msg, socket);
87 request_unqueued (SoupSession *session, SoupMessage *msg, gpointer feature)
89 if (soup_message_disables_feature (msg, feature))
92 SOUP_SESSION_FEATURE_GET_CLASS (feature)->
93 request_unqueued (feature, session, msg);
97 soup_session_feature_real_attach (SoupSessionFeature *feature, SoupSession *session)
99 g_object_weak_ref (G_OBJECT (session),
100 weak_notify_unref, g_object_ref (feature));
102 if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_queued) {
103 g_signal_connect (session, "request_queued",
104 G_CALLBACK (request_queued), feature);
107 if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_started) {
108 g_signal_connect (session, "request_started",
109 G_CALLBACK (request_started), feature);
112 if (SOUP_SESSION_FEATURE_GET_CLASS (feature)->request_unqueued) {
113 g_signal_connect (session, "request_unqueued",
114 G_CALLBACK (request_unqueued), feature);
119 soup_session_feature_attach (SoupSessionFeature *feature,
120 SoupSession *session)
122 SOUP_SESSION_FEATURE_GET_CLASS (feature)->attach (feature, session);
126 soup_session_feature_real_detach (SoupSessionFeature *feature, SoupSession *session)
128 g_object_weak_unref (G_OBJECT (session), weak_notify_unref, feature);
130 g_signal_handlers_disconnect_by_func (session, request_queued, feature);
131 g_signal_handlers_disconnect_by_func (session, request_started, feature);
132 g_signal_handlers_disconnect_by_func (session, request_unqueued, feature);
134 g_object_unref (feature);
138 soup_session_feature_detach (SoupSessionFeature *feature,
139 SoupSession *session)
141 SOUP_SESSION_FEATURE_GET_CLASS (feature)->detach (feature, session);
145 soup_session_feature_default_init (SoupSessionFeatureInterface *iface)
147 iface->attach = soup_session_feature_real_attach;
148 iface->detach = soup_session_feature_real_detach;
152 * soup_session_feature_add_feature:
153 * @feature: the "base" feature
154 * @type: the #GType of a "sub-feature"
156 * Adds a "sub-feature" of type @type to the base feature @feature.
157 * This is used for features that can be extended with multiple
158 * different types. Eg, the authentication manager can be extended
159 * with subtypes of #SoupAuth.
161 * Return value: %TRUE if @feature accepted @type as a subfeature.
166 soup_session_feature_add_feature (SoupSessionFeature *feature,
169 SoupSessionFeatureInterface *feature_iface =
170 SOUP_SESSION_FEATURE_GET_CLASS (feature);
172 if (feature_iface->add_feature)
173 return feature_iface->add_feature (feature, type);
179 * soup_session_feature_remove_feature:
180 * @feature: the "base" feature
181 * @type: the #GType of a "sub-feature"
183 * Removes the "sub-feature" of type @type from the base feature
184 * @feature. See soup_session_feature_add_feature().
186 * Return value: %TRUE if @type was removed from @feature
191 soup_session_feature_remove_feature (SoupSessionFeature *feature,
194 SoupSessionFeatureInterface *feature_iface =
195 SOUP_SESSION_FEATURE_GET_CLASS (feature);
197 if (feature_iface->remove_feature)
198 return feature_iface->remove_feature (feature, type);
204 * soup_session_feature_has_feature:
205 * @feature: the "base" feature
206 * @type: the #GType of a "sub-feature"
208 * Tests if @feature has a "sub-feature" of type @type. See
209 * soup_session_feature_add_feature().
211 * Return value: %TRUE if @feature has a subfeature of type @type
216 soup_session_feature_has_feature (SoupSessionFeature *feature,
219 SoupSessionFeatureInterface *feature_iface =
220 SOUP_SESSION_FEATURE_GET_CLASS (feature);
222 if (feature_iface->has_feature)
223 return feature_iface->has_feature (feature, type);