[libsoup/server-feature: 1/2] initial minimal SoupServerFeature support



commit a7514721995583c9097d3f203250798ed72fb4c4
Author: Dan Winship <danw gnome org>
Date:   Fri Oct 24 20:57:53 2008 -0400

    initial minimal SoupServerFeature support

 libsoup/Makefile.am           |    2 +
 libsoup/soup-auth-domain.c    |   16 ++++-
 libsoup/soup-server-feature.c |  137 +++++++++++++++++++++++++++++++++++
 libsoup/soup-server-feature.h |   60 +++++++++++++++
 libsoup/soup-server.c         |  160 ++++++++++++++++++++++++++++++++++++-----
 libsoup/soup-server.h         |   21 +++++-
 libsoup/soup-types.h          |    2 +
 libsoup/soup.h                |    1 +
 tests/auth-test.c             |   12 ++--
 tests/continue-test.c         |    2 +-
 tests/misc-test.c             |    2 +-
 tests/server-auth-test.c      |   10 +--
 12 files changed, 388 insertions(+), 37 deletions(-)
---
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 2d3a6ea..c7a3486 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -73,6 +73,7 @@ soup_headers =			\
 	soup-proxy-resolver.h	\
 	soup-proxy-uri-resolver.h \
 	soup-server.h		\
+	soup-server-feature.h	\
 	soup-session.h		\
 	soup-session-async.h	\
 	soup-session-feature.h	\
@@ -151,6 +152,7 @@ libsoup_2_4_la_SOURCES =		\
 	soup-proxy-resolver-static.c	\
 	soup-proxy-uri-resolver.c	\
 	soup-server.c			\
+	soup-server-feature.c		\
 	soup-session.c			\
 	soup-session-async.c		\
 	soup-session-feature.c		\
diff --git a/libsoup/soup-auth-domain.c b/libsoup/soup-auth-domain.c
index d3949d1..34886a7 100644
--- a/libsoup/soup-auth-domain.c
+++ b/libsoup/soup-auth-domain.c
@@ -14,6 +14,7 @@
 #include "soup-auth-domain.h"
 #include "soup-message.h"
 #include "soup-path-map.h"
+#include "soup-server-feature.h"
 #include "soup-uri.h"
 
 /**
@@ -70,7 +71,11 @@ typedef struct {
 
 #define SOUP_AUTH_DOMAIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_AUTH_DOMAIN, SoupAuthDomainPrivate))
 
-G_DEFINE_TYPE (SoupAuthDomain, soup_auth_domain, G_TYPE_OBJECT)
+static void soup_auth_domain_server_feature_init (SoupServerFeatureInterface *feature_interface, gpointer interface_data);
+
+G_DEFINE_TYPE_WITH_CODE (SoupAuthDomain, soup_auth_domain, G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (SOUP_TYPE_SERVER_FEATURE,
+						soup_auth_domain_server_feature_init))
 
 static void set_property (GObject *object, guint prop_id,
 			  const GValue *value, GParamSpec *pspec);
@@ -215,6 +220,15 @@ soup_auth_domain_class_init (SoupAuthDomainClass *auth_domain_class)
 }
 
 static void
+soup_auth_domain_server_feature_init (SoupServerFeatureInterface *feature_interface,
+				      gpointer interface_data)
+{
+	/* SoupAuthDomain is actually handled specially by SoupServer,
+	 * so there's nothing to do here.
+	 */
+}
+
+static void
 set_property (GObject *object, guint prop_id,
 	      const GValue *value, GParamSpec *pspec)
 {
diff --git a/libsoup/soup-server-feature.c b/libsoup/soup-server-feature.c
new file mode 100644
index 0000000..69e9754
--- /dev/null
+++ b/libsoup/soup-server-feature.c
@@ -0,0 +1,137 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-server-feature.c: Miscellaneous server feature-provider interface
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-server-feature.h"
+
+/**
+ * SECTION:soup-server-feature
+ * @short_description: Interface for miscellaneous server features
+ *
+ * #SoupServerFeature is the interface used by classes that extend
+ * the functionality of a #SoupServer.
+ *
+ * See soup_server_add_feature(), etc, to add a feature to a server.
+ **/
+
+/**
+ * SoupServerFeature:
+ *
+ * The interface implemented by objects that implement features for
+ * #SoupServer.
+ **/
+
+static void soup_server_feature_interface_init (SoupServerFeatureInterface *interface);
+
+static void attach (SoupServerFeature *feature, SoupServer *server);
+static void detach (SoupServerFeature *feature, SoupServer *server);
+
+GType
+soup_server_feature_get_type (void)
+{
+  static volatile gsize g_define_type_id__volatile = 0;
+  if (g_once_init_enter (&g_define_type_id__volatile))
+    {
+      GType g_define_type_id =
+        g_type_register_static_simple (G_TYPE_INTERFACE,
+                                       g_intern_static_string ("SoupServerFeature"),
+                                       sizeof (SoupServerFeatureInterface),
+                                       (GClassInitFunc)soup_server_feature_interface_init,
+                                       0,
+                                       (GInstanceInitFunc)NULL,
+                                       (GTypeFlags) 0);
+      g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
+      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+    }
+  return g_define_type_id__volatile;
+}
+
+static void
+soup_server_feature_interface_init (SoupServerFeatureInterface *interface)
+{
+	interface->attach = attach;
+	interface->detach = detach;
+}
+
+static void
+request_started (SoupServer *server, SoupMessage *msg,
+		 SoupClientContext *context, gpointer feature)
+{
+	SOUP_SERVER_FEATURE_GET_CLASS (feature)->
+		request_started (feature, server, msg, context);
+}
+
+static void
+request_read (SoupServer *server, SoupMessage *msg,
+	      SoupClientContext *context, gpointer feature)
+{
+	SOUP_SERVER_FEATURE_GET_CLASS (feature)->
+		request_started (feature, server, msg, context);
+}
+
+static void
+request_finished (SoupServer *server, SoupMessage *msg,
+		  SoupClientContext *context, gpointer feature)
+{
+	SOUP_SERVER_FEATURE_GET_CLASS (feature)->
+		request_started (feature, server, msg, context);
+}
+
+static void
+request_aborted (SoupServer *server, SoupMessage *msg,
+		 SoupClientContext *context, gpointer feature)
+{
+	SOUP_SERVER_FEATURE_GET_CLASS (feature)->
+		request_started (feature, server, msg, context);
+}
+
+static void
+attach (SoupServerFeature *feature, SoupServer *server)
+{
+	if (SOUP_SERVER_FEATURE_GET_CLASS (feature)->request_started) {
+		g_signal_connect (server, "request_started",
+				  G_CALLBACK (request_started), feature);
+	}
+	if (SOUP_SERVER_FEATURE_GET_CLASS (feature)->request_read) {
+		g_signal_connect (server, "request_read",
+				  G_CALLBACK (request_read), feature);
+	}
+	if (SOUP_SERVER_FEATURE_GET_CLASS (feature)->request_finished) {
+		g_signal_connect (server, "request_finished",
+				  G_CALLBACK (request_finished), feature);
+	}
+	if (SOUP_SERVER_FEATURE_GET_CLASS (feature)->request_aborted) {
+		g_signal_connect (server, "request_aborted",
+				  G_CALLBACK (request_aborted), feature);
+	}
+}
+
+void
+soup_server_feature_attach (SoupServerFeature *feature,
+			    SoupServer        *server)
+{
+	SOUP_SERVER_FEATURE_GET_CLASS (feature)->attach (feature, server);
+}
+
+static void
+detach (SoupServerFeature *feature, SoupServer *server)
+{
+	g_signal_handlers_disconnect_by_func (server, request_started, feature);
+	g_signal_handlers_disconnect_by_func (server, request_read, feature);
+	g_signal_handlers_disconnect_by_func (server, request_finished, feature);
+	g_signal_handlers_disconnect_by_func (server, request_aborted, feature);
+}
+
+void
+soup_server_feature_detach (SoupServerFeature *feature,
+			    SoupServer        *server)
+{
+	SOUP_SERVER_FEATURE_GET_CLASS (feature)->detach (feature, server);
+}
diff --git a/libsoup/soup-server-feature.h b/libsoup/soup-server-feature.h
new file mode 100644
index 0000000..4f50bf3
--- /dev/null
+++ b/libsoup/soup-server-feature.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_SERVER_FEATURE_H
+#define SOUP_SERVER_FEATURE_H 1
+
+#include <libsoup/soup-types.h>
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_SERVER_FEATURE            (soup_server_feature_get_type ())
+#define SOUP_SERVER_FEATURE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_SERVER_FEATURE, SoupServerFeature))
+#define SOUP_SERVER_FEATURE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_SERVER_FEATURE, SoupServerFeatureInterface))
+#define SOUP_IS_SERVER_FEATURE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUP_TYPE_SERVER_FEATURE))
+#define SOUP_IS_SERVER_FEATURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_SERVER_FEATURE))
+#define SOUP_SERVER_FEATURE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SOUP_TYPE_SERVER_FEATURE, SoupServerFeatureInterface))
+
+/* dummy struct for gtk-doc */
+struct _SoupServerFeature {};
+
+typedef struct {
+	GTypeInterface parent;
+
+	/* methods */
+	void (*attach) (SoupServerFeature *feature,
+			SoupServer        *server);
+	void (*detach) (SoupServerFeature *feature,
+			SoupServer        *server);
+
+	void (*request_started)  (SoupServerFeature *feature,
+				  SoupServer        *server,
+				  SoupMessage       *msg,
+				  SoupClientContext *context);
+	void (*request_read)     (SoupServerFeature *feature,
+				  SoupServer        *server,
+				  SoupMessage       *msg,
+				  SoupClientContext *context);
+	void (*request_finished) (SoupServerFeature *feature,
+				  SoupServer        *server,
+				  SoupMessage       *msg,
+				  SoupClientContext *context);
+	void (*request_aborted)  (SoupServerFeature *feature,
+				  SoupServer        *server,
+				  SoupMessage       *msg,
+				  SoupClientContext *context);
+
+} SoupServerFeatureInterface;
+
+GType soup_server_feature_get_type (void);
+
+void soup_server_feature_attach (SoupServerFeature *feature,
+				 SoupServer        *server);
+void soup_server_feature_detach (SoupServerFeature *feature,
+				 SoupServer        *server);
+
+G_END_DECLS
+
+#endif /* SOUP_SERVER_FEATURE_H */
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index e34fffb..d8b4d1a 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -23,6 +23,7 @@
 #include "soup-message-private.h"
 #include "soup-marshal.h"
 #include "soup-path-map.h" 
+#include "soup-server-feature.h"
 #include "soup-socket.h"
 #include "soup-ssl.h"
 
@@ -106,7 +107,7 @@ typedef struct {
 	SoupPathMap       *handlers;
 	SoupServerHandler *default_handler;
 	
-	GSList            *auth_domains;
+	GSList            *features;
 
 	GMainContext      *async_context;
 } SoupServerPrivate;
@@ -124,6 +125,9 @@ enum {
 	PROP_ASYNC_CONTEXT,
 	PROP_RAW_PATHS,
 	PROP_SERVER_HEADER,
+	PROP_ADD_FEATURE,
+	PROP_ADD_FEATURE_BY_TYPE,
+	PROP_REMOVE_FEATURE_BY_TYPE,
 
 	LAST_PROP
 };
@@ -156,7 +160,6 @@ finalize (GObject *object)
 {
 	SoupServer *server = SOUP_SERVER (object);
 	SoupServerPrivate *priv = SOUP_SERVER_GET_PRIVATE (server);
-	GSList *iter;
 
 	if (priv->interface)
 		g_object_unref (priv->interface);
@@ -183,9 +186,8 @@ finalize (GObject *object)
 		free_handler (priv->default_handler);
 	soup_path_map_free (priv->handlers);
 
-	for (iter = priv->auth_domains; iter; iter = iter->next)
-		g_object_unref (iter->data);
-	g_slist_free (priv->auth_domains);
+	while (priv->features)
+		soup_server_remove_feature (server, priv->features->data);
 
 	if (priv->loop)
 		g_main_loop_unref (priv->loop);
@@ -433,6 +435,28 @@ soup_server_class_init (SoupServerClass *server_class)
 				     "Server header",
 				     NULL,
 				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class, PROP_ADD_FEATURE,
+		g_param_spec_object (SOUP_SERVER_ADD_FEATURE,
+				     "Add Feature",
+				     "Add a feature object to the server",
+				     SOUP_TYPE_SERVER_FEATURE,
+				     G_PARAM_READWRITE));
+	g_object_class_install_property (
+		object_class, PROP_ADD_FEATURE_BY_TYPE,
+		g_param_spec_gtype (SOUP_SERVER_ADD_FEATURE_BY_TYPE,
+				    "Add Feature By Type",
+				    "Add a feature object of the given type to the server",
+				    SOUP_TYPE_SERVER_FEATURE,
+				    G_PARAM_READWRITE));
+	g_object_class_install_property (
+		object_class, PROP_REMOVE_FEATURE_BY_TYPE,
+		g_param_spec_gtype (SOUP_SERVER_REMOVE_FEATURE_BY_TYPE,
+				    "Remove Feature By Type",
+				    "Remove features of the given type from the server",
+				    SOUP_TYPE_SERVER_FEATURE,
+				    G_PARAM_READWRITE));
 }
 
 static GObject *
@@ -490,6 +514,7 @@ static void
 set_property (GObject *object, guint prop_id,
 	      const GValue *value, GParamSpec *pspec)
 {
+	SoupServer *server = SOUP_SERVER (object);
 	SoupServerPrivate *priv = SOUP_SERVER_GET_PRIVATE (object);
 	const char *header;
 
@@ -535,6 +560,15 @@ set_property (GObject *object, guint prop_id,
 		} else
 			priv->server_header = g_strdup (header);
 		break;
+	case PROP_ADD_FEATURE:
+		soup_server_add_feature (server, g_value_get_object (value));
+		break;
+	case PROP_ADD_FEATURE_BY_TYPE:
+		soup_server_add_feature_by_type (server, g_value_get_gtype (value));
+		break;
+	case PROP_REMOVE_FEATURE_BY_TYPE:
+		soup_server_remove_feature_by_type (server, g_value_get_gtype (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -778,9 +812,11 @@ got_headers (SoupMessage *req, SoupClientContext *client)
 	 * immediately rather than waiting for the request body to
 	 * be sent.
 	 */
-	for (iter = priv->auth_domains; iter; iter = iter->next) {
-		domain = iter->data;
+	for (iter = priv->features; iter; iter = iter->next) {
+		if (!SOUP_IS_AUTH_DOMAIN (iter->data))
+			continue;
 
+		domain = iter->data;
 		if (soup_auth_domain_covers (domain, req)) {
 			auth_user = soup_auth_domain_accepts (domain, req);
 			if (auth_user) {
@@ -797,9 +833,11 @@ got_headers (SoupMessage *req, SoupClientContext *client)
 	if (!rejected)
 		return;
 
-	for (iter = priv->auth_domains; iter; iter = iter->next) {
-		domain = iter->data;
+	for (iter = priv->features; iter; iter = iter->next) {
+		if (!SOUP_IS_AUTH_DOMAIN (iter->data))
+			continue;
 
+		domain = iter->data;
 		if (soup_auth_domain_covers (domain, req))
 			soup_auth_domain_challenge (domain, req);
 	}
@@ -1282,36 +1320,124 @@ soup_server_remove_handler (SoupServer *server, const char *path)
  * Proxy Authentication Required). If the request used the
  * "100-continue" Expectation, @server will reject it before the
  * request body is sent.
+ *
+ * Deprecated: use soup_server_add_feature()
  **/
 void
 soup_server_add_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain)
 {
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (auth_domain));
+}
+
+/**
+ * soup_server_remove_auth_domain:
+ * @server: a #SoupServer
+ * @auth_domain: a #SoupAuthDomain
+ *
+ * Removes @auth_domain from @server.
+ *
+ * Deprecated: use soup_server_remove_feature()
+ **/
+void
+soup_server_remove_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain)
+{
+	soup_server_remove_feature (server, SOUP_SERVER_FEATURE (auth_domain));
+}
+
+/**
+ * soup_server_add_feature:
+ * @server: a #SoupServer
+ * @feature: an object that implements #SoupServerFeature
+ *
+ * Adds @feature's functionality to @server. You can also add a
+ * feature to the server at construct time by using the
+ * %SOUP_SERVER_ADD_FEATURE property.
+ **/
+void
+soup_server_add_feature (SoupServer *server, SoupServerFeature *feature)
+{
 	SoupServerPrivate *priv;
 
 	g_return_if_fail (SOUP_IS_SERVER (server));
+	g_return_if_fail (SOUP_IS_SERVER_FEATURE (feature));
+
 	priv = SOUP_SERVER_GET_PRIVATE (server);
+	priv->features = g_slist_append (priv->features, g_object_ref (feature));
+	soup_server_feature_attach (feature, server);
+}
 
-	priv->auth_domains = g_slist_append (priv->auth_domains, auth_domain);
-	g_object_ref (auth_domain);
+/**
+ * soup_server_add_feature_by_type:
+ * @server: a #SoupServer
+ * @feature_type: the #GType of a class that implements #SoupServerFeature
+ *
+ * Creates a new feature of type @feature_type and adds it to
+ * @server. You can use this instead of soup_server_add_feature() in
+ * the case wher you don't need to customize the new feature in any
+ * way. You can also add a feature to the server at construct time by
+ * using the %SOUP_SERVER_ADD_FEATURE_BY_TYPE property.
+ **/
+void
+soup_server_add_feature_by_type (SoupServer *server, GType feature_type)
+{
+	SoupServerFeature *feature;
+
+	g_return_if_fail (SOUP_IS_SERVER (server));
+	g_return_if_fail (g_type_is_a (feature_type, SOUP_TYPE_SERVER_FEATURE));
+
+	feature = g_object_new (feature_type, NULL);
+	soup_server_add_feature (server, feature);
+	g_object_unref (feature);
 }
 
 /**
- * soup_server_remove_auth_domain:
+ * soup_server_remove_feature:
  * @server: a #SoupServer
- * @auth_domain: a #SoupAuthDomain
+ * @feature: a feature that has previously been added to @server
  *
- * Removes @auth_domain from @server.
+ * Removes @feature's functionality from @server.
  **/
 void
-soup_server_remove_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain)
+soup_server_remove_feature (SoupServer *server, SoupServerFeature *feature)
 {
 	SoupServerPrivate *priv;
 
 	g_return_if_fail (SOUP_IS_SERVER (server));
+
 	priv = SOUP_SERVER_GET_PRIVATE (server);
+	if (g_slist_find (priv->features, feature)) {
+		priv->features = g_slist_remove (priv->features, feature);
+		soup_server_feature_detach (feature, server);
+		g_object_unref (feature);
+	}
+}
+
+/**
+ * soup_server_remove_feature_by_type:
+ * @server: a #SoupServer
+ * @feature_type: the #GType of a class that implements #SoupServerFeature
+ *
+ * Removes all features of type @feature_type (or any subclass of
+ * @feature_type) from @server. You can also remove standard features
+ * from the server at construct time by using the
+ * %SOUP_SERVER_REMOVE_FEATURE_BY_TYPE property.
+ **/
+void
+soup_server_remove_feature_by_type (SoupServer *server, GType feature_type)
+{
+	SoupServerPrivate *priv;
+	GSList *f;
+
+	g_return_if_fail (SOUP_IS_SERVER (server));
 
-	priv->auth_domains = g_slist_remove (priv->auth_domains, auth_domain);
-	g_object_unref (auth_domain);
+	priv = SOUP_SERVER_GET_PRIVATE (server);
+restart:
+	for (f = priv->features; f; f = f->next) {
+		if (G_TYPE_CHECK_INSTANCE_TYPE (f->data, feature_type)) {
+			soup_server_remove_feature (server, f->data);
+			goto restart;
+		}
+	}
 }
 
 /**
diff --git a/libsoup/soup-server.h b/libsoup/soup-server.h
index 88c1570..e81fb5a 100644
--- a/libsoup/soup-server.h
+++ b/libsoup/soup-server.h
@@ -18,10 +18,6 @@ G_BEGIN_DECLS
 #define SOUP_IS_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SOUP_TYPE_SERVER))
 #define SOUP_SERVER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_SERVER, SoupServerClass))
 
-typedef struct SoupClientContext SoupClientContext;
-GType soup_client_context_get_type (void);
-#define SOUP_TYPE_CLIENT_CONTEXT (soup_client_context_get_type ())
-
 struct _SoupServer {
 	GObject parent;
 
@@ -63,6 +59,9 @@ typedef void (*SoupServerCallback) (SoupServer        *server,
 #define SOUP_SERVER_ASYNC_CONTEXT "async-context"
 #define SOUP_SERVER_RAW_PATHS     "raw-paths"
 #define SOUP_SERVER_SERVER_HEADER "server-header"
+#define SOUP_SERVER_ADD_FEATURE            "add-feature"
+#define SOUP_SERVER_ADD_FEATURE_BY_TYPE    "add-feature-by-type"
+#define SOUP_SERVER_REMOVE_FEATURE_BY_TYPE "remove-feature-by-type"
 
 SoupServer        *soup_server_new            (const char            *optname1,
 					       ...) G_GNUC_NULL_TERMINATED;
@@ -88,10 +87,21 @@ void               soup_server_add_handler    (SoupServer            *server,
 void               soup_server_remove_handler (SoupServer            *server,
 					       const char            *path);
 
+#ifndef LIBSOUP_DISABLE_DEPRECATED
 void               soup_server_add_auth_domain    (SoupServer     *server,
 						   SoupAuthDomain *auth_domain);
 void               soup_server_remove_auth_domain (SoupServer     *server,
 						   SoupAuthDomain *auth_domain);
+#endif
+
+void               soup_server_add_feature            (SoupServer        *server,
+						       SoupServerFeature *feature);
+void               soup_server_add_feature_by_type    (SoupServer        *server,
+						       GType               feature_type);
+void               soup_server_remove_feature         (SoupServer        *server,
+						       SoupServerFeature *feature);
+void               soup_server_remove_feature_by_type (SoupServer        *server,
+						       GType               feature_type);
 
 /* I/O */
 
@@ -102,6 +112,9 @@ void               soup_server_unpause_message (SoupServer           *server,
 
 /* Client context */
 
+GType soup_client_context_get_type (void);
+#define SOUP_TYPE_CLIENT_CONTEXT (soup_client_context_get_type ())
+
 SoupSocket     *soup_client_context_get_socket      (SoupClientContext *client);
 SoupAddress    *soup_client_context_get_address     (SoupClientContext *client);
 const char     *soup_client_context_get_host        (SoupClientContext *client);
diff --git a/libsoup/soup-types.h b/libsoup/soup-types.h
index 8b485bf..35f3c3a 100644
--- a/libsoup/soup-types.h
+++ b/libsoup/soup-types.h
@@ -16,10 +16,12 @@ G_BEGIN_DECLS
 typedef struct _SoupAddress           SoupAddress;
 typedef struct _SoupAuth              SoupAuth;
 typedef struct _SoupAuthDomain        SoupAuthDomain;
+typedef struct  SoupClientContext     SoupClientContext;
 typedef struct _SoupCookie            SoupCookie;
 typedef struct _SoupDate              SoupDate;
 typedef struct _SoupMessage           SoupMessage;
 typedef struct _SoupServer            SoupServer;
+typedef struct _SoupServerFeature     SoupServerFeature;
 typedef struct _SoupSession           SoupSession;
 typedef struct _SoupSessionAsync      SoupSessionAsync;
 typedef struct _SoupSessionFeature    SoupSessionFeature;
diff --git a/libsoup/soup.h b/libsoup/soup.h
index c761e00..273f919 100644
--- a/libsoup/soup.h
+++ b/libsoup/soup.h
@@ -31,6 +31,7 @@ extern "C" {
 #include <libsoup/soup-proxy-resolver.h>
 #include <libsoup/soup-proxy-uri-resolver.h>
 #include <libsoup/soup-server.h>
+#include <libsoup/soup-server-feature.h>
 #include <libsoup/soup-session-async.h>
 #include <libsoup/soup-session-feature.h>
 #include <libsoup/soup-session-sync.h>
diff --git a/tests/auth-test.c b/tests/auth-test.c
index b090e23..99e2a2f 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -737,14 +737,14 @@ do_select_auth_test (void)
 		SOUP_AUTH_DOMAIN_ADD_PATH, "/",
 		SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, server_basic_auth_callback,
 		NULL);
-	soup_server_add_auth_domain (server, basic_auth_domain);
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (basic_auth_domain));
 
 	digest_auth_domain = soup_auth_domain_digest_new (
 		SOUP_AUTH_DOMAIN_REALM, "auth-test",
 		SOUP_AUTH_DOMAIN_ADD_PATH, "/",
 		SOUP_AUTH_DOMAIN_DIGEST_AUTH_CALLBACK, server_digest_auth_callback,
 		NULL);
-	soup_server_add_auth_domain (server, digest_auth_domain);
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (digest_auth_domain));
 
 	/* FIXME: when we support disabling auth types in the session,
 	 * test that too.
@@ -773,10 +773,10 @@ do_select_auth_test (void)
 	 * *still* gets used.
 	 */
 
-	soup_server_remove_auth_domain (server, basic_auth_domain);
-	soup_server_remove_auth_domain (server, digest_auth_domain);
-	soup_server_add_auth_domain (server, digest_auth_domain);
-	soup_server_add_auth_domain (server, basic_auth_domain);
+	soup_server_remove_feature (server, SOUP_SERVER_FEATURE (basic_auth_domain));
+	soup_server_remove_feature (server, SOUP_SERVER_FEATURE (digest_auth_domain));
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (digest_auth_domain));
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (basic_auth_domain));
 
 	debug_printf (1, "  Testing flipped with no auth\n");
 	select_auth_test_one (uri, NULL,
diff --git a/tests/continue-test.c b/tests/continue-test.c
index d9a94a2..cf82f28 100644
--- a/tests/continue-test.c
+++ b/tests/continue-test.c
@@ -431,7 +431,7 @@ setup_server (void)
 		SOUP_AUTH_DOMAIN_ADD_PATH, "/auth",
 		SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, auth_callback,
 		NULL);
-	soup_server_add_auth_domain (server, auth_domain);
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (auth_domain));
 	g_object_unref (auth_domain);
 
 	return server;
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 70415d3..7b8b262 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -301,7 +301,7 @@ main (int argc, char **argv)
 		SOUP_AUTH_DOMAIN_ADD_PATH, "/auth",
 		SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, auth_callback,
 		NULL);
-	soup_server_add_auth_domain (server, auth_domain);
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (auth_domain));
 	g_object_unref (auth_domain);
 
 	do_host_test ();
diff --git a/tests/server-auth-test.c b/tests/server-auth-test.c
index e4c84bd..82603b5 100644
--- a/tests/server-auth-test.c
+++ b/tests/server-auth-test.c
@@ -17,11 +17,7 @@
 #include <unistd.h>
 
 #include <glib.h>
-#include <libsoup/soup-address.h>
-#include <libsoup/soup-auth-domain-basic.h>
-#include <libsoup/soup-auth-domain-digest.h>
-#include <libsoup/soup-message.h>
-#include <libsoup/soup-server.h>
+#include <libsoup/soup.h>
 
 #include "test-utils.h"
 
@@ -349,7 +345,7 @@ main (int argc, char **argv)
 		SOUP_AUTH_DOMAIN_REMOVE_PATH, "/Any/Not",
 		SOUP_AUTH_DOMAIN_BASIC_AUTH_CALLBACK, basic_auth_callback,
 		NULL);
-	soup_server_add_auth_domain (server, auth_domain);
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (auth_domain));
 	g_object_unref (auth_domain);
 
 	auth_domain = soup_auth_domain_digest_new (
@@ -359,7 +355,7 @@ main (int argc, char **argv)
 		SOUP_AUTH_DOMAIN_REMOVE_PATH, "/Any/Not",
 		SOUP_AUTH_DOMAIN_DIGEST_AUTH_CALLBACK, digest_auth_callback,
 		NULL);
-	soup_server_add_auth_domain (server, auth_domain);
+	soup_server_add_feature (server, SOUP_SERVER_FEATURE (auth_domain));
 	g_object_unref (auth_domain);
 
 	loop = g_main_loop_new (NULL, TRUE);



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