[libsoup] Add soup_message_disable_feature()
- From: Dan Winship <danw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libsoup] Add soup_message_disable_feature()
- Date: Sun, 9 Aug 2009 15:03:01 +0000 (UTC)
commit 005bf1a75397d66028454e58e4aa1d95ac88569d
Author: Dan Winship <danw gnome org>
Date: Sun Aug 2 11:35:01 2009 -0400
Add soup_message_disable_feature()
This allows you to disable specific SoupSessionFeatures for particular
messages.
Also update tests/sniffing-test to test it out.
http://bugzilla.gnome.org/show_bug.cgi?id=574773
libsoup/soup-message-private.h | 4 ++
libsoup/soup-message.c | 52 ++++++++++++++++++++++++++++++++++
libsoup/soup-message.h | 3 ++
libsoup/soup-session-async.c | 3 +-
libsoup/soup-session-feature.c | 10 ++++++
libsoup/soup-session-sync.c | 3 +-
tests/sniffing-test.c | 61 ++++++++++++++++++++++++++++++++++------
7 files changed, 125 insertions(+), 11 deletions(-)
---
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 5c88cbc..765ee3c 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -39,6 +39,8 @@ typedef struct {
SoupAddress *addr;
SoupAuth *auth, *proxy_auth;
+
+ GSList *disabled_features;
} SoupMessagePrivate;
#define SOUP_MESSAGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_MESSAGE, SoupMessagePrivate))
@@ -94,4 +96,6 @@ void soup_message_io_pause (SoupMessage *msg);
void soup_message_io_unpause (SoupMessage *msg);
gboolean soup_message_io_in_progress (SoupMessage *msg);
+gboolean soup_message_disables_feature (SoupMessage *msg,
+ gpointer feature);
#endif /* SOUP_MESSAGE_PRIVATE_H */
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index f614946..1f0c8ac 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -166,6 +166,8 @@ finalize (GObject *object)
if (priv->proxy_auth)
g_object_unref (priv->proxy_auth);
+ g_slist_free (priv->disabled_features);
+
soup_message_body_free (msg->request_body);
soup_message_headers_free (msg->request_headers);
soup_message_body_free (msg->response_body);
@@ -1601,3 +1603,53 @@ soup_message_set_chunk_allocator (SoupMessage *msg,
priv->chunk_allocator_data = user_data;
priv->chunk_allocator_dnotify = destroy_notify;
}
+
+/**
+ * soup_message_disable_feature:
+ * @msg: a #SoupMessage
+ * @feature_type: the #GType of a #SoupSessionFeature
+ *
+ * This disables the actions of #SoupSessionFeature<!-- -->s with the
+ * given @feature_type (or a subclass of that type) on @msg, so that
+ * @msg is processed as though the feature(s) hadn't been added to the
+ * session. Eg, passing #SOUP_TYPE_PROXY_RESOLVER for @feature_type
+ * will disable proxy handling and cause @msg to be sent directly to
+ * the indicated origin server, regardless of system proxy
+ * configuration.
+ *
+ * You must call this before queueing @msg on a session; calling it on
+ * a message that has already been queued is undefined. In particular,
+ * you cannot call this on a message that is being requeued after a
+ * redirect or authentication.
+ *
+ * Since: 2.28
+ **/
+void
+soup_message_disable_feature (SoupMessage *msg, GType feature_type)
+{
+ SoupMessagePrivate *priv;
+
+ g_return_if_fail (SOUP_IS_MESSAGE (msg));
+
+ priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+
+ priv->disabled_features = g_slist_prepend (priv->disabled_features,
+ GSIZE_TO_POINTER (feature_type));
+}
+
+gboolean
+soup_message_disables_feature (SoupMessage *msg, gpointer feature)
+{
+ SoupMessagePrivate *priv;
+ GSList *f;
+
+ g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
+
+ priv = SOUP_MESSAGE_GET_PRIVATE (msg);
+
+ for (f = priv->disabled_features; f; f = f->next) {
+ if (G_TYPE_CHECK_INSTANCE_TYPE (feature, (GType) GPOINTER_TO_SIZE (f->data)))
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index b940ac6..4bbcb1b 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -146,6 +146,9 @@ void soup_message_set_chunk_allocator (SoupMessage *msg,
gpointer user_data,
GDestroyNotify destroy_notify);
+void soup_message_disable_feature (SoupMessage *msg,
+ GType feature_type);
+
void soup_message_wrote_informational (SoupMessage *msg);
void soup_message_wrote_headers (SoupMessage *msg);
void soup_message_wrote_chunk (SoupMessage *msg);
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index f505710..a4e6017 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -317,7 +317,8 @@ run_queue (SoupSessionAsync *sa)
soup_message_io_in_progress (msg))
continue;
- if (proxy_resolver && !item->resolved_proxy_addr) {
+ if (proxy_resolver && !item->resolved_proxy_addr &&
+ !soup_message_disables_feature (item->msg, proxy_resolver)) {
resolve_proxy_addr (item, proxy_resolver);
continue;
}
diff --git a/libsoup/soup-session-feature.c b/libsoup/soup-session-feature.c
index 3f1ff77..f5d1239 100644
--- a/libsoup/soup-session-feature.c
+++ b/libsoup/soup-session-feature.c
@@ -10,6 +10,7 @@
#endif
#include "soup-session-feature.h"
+#include "soup-message-private.h"
/**
* SECTION:soup-session-feature
@@ -88,6 +89,9 @@ weak_notify_unref (gpointer feature, GObject *ex_object)
static void
request_queued (SoupSession *session, SoupMessage *msg, gpointer feature)
{
+ if (soup_message_disables_feature (msg, feature))
+ return;
+
SOUP_SESSION_FEATURE_GET_CLASS (feature)->
request_queued (feature, session, msg);
}
@@ -96,6 +100,9 @@ static void
request_started (SoupSession *session, SoupMessage *msg,
SoupSocket *socket, gpointer feature)
{
+ if (soup_message_disables_feature (msg, feature))
+ return;
+
SOUP_SESSION_FEATURE_GET_CLASS (feature)->
request_started (feature, session, msg, socket);
}
@@ -103,6 +110,9 @@ request_started (SoupSession *session, SoupMessage *msg,
static void
request_unqueued (SoupSession *session, SoupMessage *msg, gpointer feature)
{
+ if (soup_message_disables_feature (msg, feature))
+ return;
+
SOUP_SESSION_FEATURE_GET_CLASS (feature)->
request_unqueued (feature, session, msg);
}
diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c
index 8c2e56b..1c1c7dc 100644
--- a/libsoup/soup-session-sync.c
+++ b/libsoup/soup-session-sync.c
@@ -170,7 +170,8 @@ wait_for_connection (SoupMessageQueueItem *item)
guint status;
proxy_resolver = soup_session_get_proxy_resolver (session);
- if (proxy_resolver && !item->resolved_proxy_addr) {
+ if (proxy_resolver && !item->resolved_proxy_addr &&
+ !soup_message_disables_feature (item->msg, proxy_resolver)) {
status = soup_proxy_uri_resolver_get_proxy_uri_sync (
proxy_resolver, soup_message_get_uri (msg),
item->cancellable, &item->proxy_uri);
diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c
index a5c9587..561d2ee 100644
--- a/tests/sniffing-test.c
+++ b/tests/sniffing-test.c
@@ -343,29 +343,62 @@ do_signals_test (gboolean should_content_sniff,
}
static void
-sniffing_content_sniffed (SoupMessage *msg, char *content_type, GHashTable *params, gpointer data)
+sniffing_content_sniffed (SoupMessage *msg, const char *content_type,
+ GHashTable *params, gpointer data)
{
- char *expected_type = (char*)data;
+ char **sniffed_type = (char **)data;
- if (strcmp (content_type, expected_type)) {
+ *sniffed_type = g_strdup (content_type);
+}
+
+static void
+test_sniffing (const char *path, const char *expected_type)
+{
+ SoupURI *uri = soup_uri_new_with_base (base_uri, path);
+ SoupMessage *msg = soup_message_new_from_uri ("GET", uri);
+ GMainLoop *loop = g_main_loop_new (NULL, TRUE);
+ char *sniffed_type = NULL;
+
+ debug_printf (1, "test_sniffing(\"%s\", \"%s\")\n", path, expected_type);
+
+ g_signal_connect (msg, "content-sniffed",
+ G_CALLBACK (sniffing_content_sniffed), &sniffed_type);
+
+ g_object_ref (msg);
+
+ soup_session_queue_message (session, msg, finished, loop);
+
+ g_main_loop_run (loop);
+
+ if (!sniffed_type) {
+ debug_printf (1, " message was not sniffed!\n");
+ errors++;
+ } else if (strcmp (sniffed_type, expected_type) != 0) {
debug_printf (1, " sniffing failed! expected %s, got %s\n",
- expected_type, content_type);
+ expected_type, sniffed_type);
errors++;
}
+ g_free (sniffed_type);
+
+ soup_uri_free (uri);
+ g_object_unref (msg);
+ g_main_loop_unref (loop);
}
static void
-test_sniffing (const char *path, const char *expected_type)
+test_disabled (const char *path)
{
SoupURI *uri = soup_uri_new_with_base (base_uri, path);
SoupMessage *msg = soup_message_new_from_uri ("GET", uri);
GMainLoop *loop = g_main_loop_new (NULL, TRUE);
+ char *sniffed_type = NULL;
- debug_printf (1, "test_sniffing(\"%s\", \"%s\")\n", path, expected_type);
+ soup_message_disable_feature (msg, SOUP_TYPE_CONTENT_SNIFFER);
- g_object_connect (msg,
- "signal::content_sniffed", sniffing_content_sniffed, expected_type,
- NULL);
+ debug_printf (1, "test_disabled(\"%s\")\n", path);
+
+ g_signal_connect (msg, "content-sniffed",
+ G_CALLBACK (sniffing_content_sniffed), &sniffed_type);
g_object_ref (msg);
@@ -373,6 +406,12 @@ test_sniffing (const char *path, const char *expected_type)
g_main_loop_run (loop);
+ if (sniffed_type) {
+ debug_printf (1, " message was sniffed!\n");
+ errors++;
+ g_free (sniffed_type);
+ }
+
soup_uri_free (uri);
g_object_unref (msg);
g_main_loop_unref (loop);
@@ -474,6 +513,10 @@ main (int argc, char **argv)
test_sniffing ("/multiple_headers/home.gif", "image/gif");
+ /* Test that disabling the sniffer works correctly */
+
+ test_disabled ("/text_or_binary/home.gif");
+
soup_uri_free (base_uri);
test_cleanup ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]