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



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

    initial minimal SoupServerFeature support

 libsoup/Makefile.am           |    2 +
 libsoup/libsoup-2.4.sym       |    7 ++
 libsoup/soup-auth-domain.c    |   16 +++-
 libsoup/soup-server-feature.c |  137 +++++++++++++++++++++++++++
 libsoup/soup-server-feature.h |   60 ++++++++++++
 libsoup/soup-server.c         |  206 ++++++++++++++++++++++++++++++++++++++---
 libsoup/soup-server.h         |   29 +++++-
 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      |    4 +-
 13 files changed, 449 insertions(+), 31 deletions(-)
---
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 403c1c2..24ef9e0 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -57,6 +57,7 @@ soup_headers =                        \
        soup-request-http.h     \
        soup-requester.h        \
        soup-server.h           \
+       soup-server-feature.h   \
        soup-session.h          \
        soup-session-async.h    \
        soup-session-feature.h  \
@@ -170,6 +171,7 @@ libsoup_2_4_la_SOURCES =            \
        soup-request-http.c             \
        soup-requester.c                \
        soup-server.c                   \
+       soup-server-feature.c           \
        soup-session.c                  \
        soup-session-async.c            \
        soup-session-feature.c          \
diff --git a/libsoup/libsoup-2.4.sym b/libsoup/libsoup-2.4.sym
index 5fede3a..7d66b4b 100644
--- a/libsoup/libsoup-2.4.sym
+++ b/libsoup/libsoup-2.4.sym
@@ -364,8 +364,13 @@ soup_requester_new
 soup_requester_request
 soup_requester_request_uri
 soup_server_add_auth_domain
+soup_server_add_feature
+soup_server_add_feature_by_type
 soup_server_add_handler
 soup_server_disconnect
+soup_server_feature_attach
+soup_server_feature_detach
+soup_server_feature_get_type
 soup_server_get_async_context
 soup_server_get_listener
 soup_server_get_listeners
@@ -381,6 +386,8 @@ soup_server_listen_options_get_type
 soup_server_listen_socket
 soup_server_new
 soup_server_pause_message
+soup_server_remove_feature
+soup_server_remove_feature_by_type
 soup_server_quit
 soup_server_remove_auth_domain
 soup_server_remove_handler
diff --git a/libsoup/soup-auth-domain.c b/libsoup/soup-auth-domain.c
index 3b2c035..4c395ba 100644
--- a/libsoup/soup-auth-domain.c
+++ b/libsoup/soup-auth-domain.c
@@ -14,6 +14,7 @@
 #include "soup-auth-domain.h"
 #include "soup.h"
 #include "soup-path-map.h"
+#include "soup-server-feature.h"
 
 /**
  * SECTION:soup-auth-domain
@@ -71,7 +72,11 @@ typedef struct {
 
 #define SOUP_AUTH_DOMAIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_AUTH_DOMAIN, 
SoupAuthDomainPrivate))
 
-G_DEFINE_ABSTRACT_TYPE (SoupAuthDomain, soup_auth_domain, G_TYPE_OBJECT)
+static void soup_auth_domain_server_feature_init (SoupServerFeatureInterface *feature_interface, gpointer 
interface_data);
+
+G_DEFINE_ABSTRACT_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
 soup_auth_domain_init (SoupAuthDomain *domain)
@@ -290,6 +295,15 @@ soup_auth_domain_class_init (SoupAuthDomainClass *auth_domain_class)
                                      G_PARAM_READWRITE));
 }
 
+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.
+        */
+}
+
 /**
  * soup_auth_domain_add_path:
  * @domain: a #SoupAuthDomain
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..5d70d56
--- /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))
+
+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;
+
+SOUP_AVAILABLE_IN_2_46
+GType soup_server_feature_get_type (void);
+
+SOUP_AVAILABLE_IN_2_46
+void soup_server_feature_attach (SoupServerFeature *feature,
+                                SoupServer        *server);
+SOUP_AVAILABLE_IN_2_46
+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 30dc4f9..9758901 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -19,6 +19,7 @@
 #include "soup-misc-private.h"
 #include "soup-path-map.h" 
 #include "soup-socket-private.h"
+#include "soup-server-feature.h"
 
 /**
  * SECTION:soup-server
@@ -125,7 +126,7 @@ typedef struct {
        SoupPathMap       *handlers;
        SoupServerHandler *default_handler;
        
-       GSList            *auth_domains;
+       GSList            *features;
 
        char             **http_aliases, **https_aliases;
 
@@ -154,6 +155,9 @@ enum {
        PROP_SERVER_HEADER,
        PROP_HTTP_ALIASES,
        PROP_HTTPS_ALIASES,
+       PROP_ADD_FEATURE,
+       PROP_ADD_FEATURE_BY_TYPE,
+       PROP_REMOVE_FEATURE_BY_TYPE,
 
        LAST_PROP
 };
@@ -235,7 +239,8 @@ soup_server_finalize (GObject *object)
        g_clear_pointer (&priv->default_handler, free_handler);
        soup_path_map_free (priv->handlers);
 
-       g_slist_free_full (priv->auth_domains, g_object_unref);
+       while (priv->features)
+               soup_server_remove_feature (server, priv->features->data);
 
        g_clear_pointer (&priv->loop, g_main_loop_unref);
        g_clear_pointer (&priv->async_context, g_main_context_unref);
@@ -430,6 +435,18 @@ soup_server_set_property (GObject *object, guint prop_id,
        case PROP_HTTPS_ALIASES:
                set_aliases (&priv->https_aliases, g_value_get_boxed (value));
                break;
+       case PROP_ADD_FEATURE:
+               soup_server_add_feature (SOUP_SERVER (object),
+                                        g_value_get_object (value));
+               break;
+       case PROP_ADD_FEATURE_BY_TYPE:
+               soup_server_add_feature_by_type (SOUP_SERVER (object),
+                                                g_value_get_gtype (value));
+               break;
+       case PROP_REMOVE_FEATURE_BY_TYPE:
+               soup_server_remove_feature_by_type (SOUP_SERVER (object),
+                                                   g_value_get_gtype (value));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -854,7 +871,7 @@ soup_server_class_init (SoupServerClass *server_class)
         * Since: 2.44
         */
        /**
-        * SOUP_SERVERI_HTTP_ALIASES:
+        * SOUP_SERVER_HTTP_ALIASES:
         *
         * Alias for the #SoupServer:http-aliases property, qv.
         *
@@ -893,6 +910,73 @@ soup_server_class_init (SoupServerClass *server_class)
                                    "URI schemes that are considered aliases for 'https'",
                                    G_TYPE_STRV,
                                    G_PARAM_READWRITE));
+       /**
+        * SoupServer:add-feature: (skip)
+        *
+        * Add a feature object to the server. (Shortcut for calling
+        * soup_server_add_feature().)
+        *
+        * Since: 2.46
+        */
+       /**
+        * SOUP_SERVER_ADD_FEATURE: (skip)
+        *
+        * Alias for the #SoupServer:add-feature property, qv.
+        *
+        * Since: 2.46
+        */
+       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));
+       /**
+        * SoupServer:add-feature-by-type: (skip)
+        *
+        * Add a feature object of the given type to the server.
+        * (Shortcut for calling soup_server_add_feature_by_type().)
+        *
+        * Since: 2.46
+        */
+       /**
+        * SOUP_SERVER_ADD_FEATURE_BY_TYPE: (skip)
+        *
+        * Alias for the #SoupServer:add-feature-by-type property, qv.
+        *
+        * Since: 2.46
+        */
+       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));
+       /**
+        * SoupServer:remove-feature-by-type: (skip)
+        *
+        * Remove feature objects from the server. (Shortcut for
+        * calling soup_server_remove_feature_by_type().)
+        *
+        * Since: 2.46
+        */
+       /**
+        * SOUP_SERVER_REMOVE_FEATURE_BY_TYPE: (skip)
+        *
+        * Alias for the #SoupServer:remove-feature-by-type property,
+        * qv.
+        *
+        * Since: 2.46
+        */
+       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));
 }
 
 /**
@@ -1218,9 +1302,11 @@ got_headers (SoupMessage *msg, 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, msg)) {
                        auth_user = soup_auth_domain_accepts (domain, msg);
                        if (auth_user) {
@@ -1237,9 +1323,11 @@ got_headers (SoupMessage *msg, 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, msg))
                        soup_auth_domain_challenge (domain, msg);
        }
@@ -2342,36 +2430,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);
+       }
+}
 
-       priv->auth_domains = g_slist_remove (priv->auth_domains, auth_domain);
-       g_object_unref (auth_domain);
+/**
+ * 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 = 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 2cbd7d1..16b58e3 100644
--- a/libsoup/soup-server.h
+++ b/libsoup/soup-server.h
@@ -62,11 +62,14 @@ typedef void (*SoupServerCallback) (SoupServer        *server,
                                    SoupClientContext *client,
                                    gpointer           user_data);
 
-#define SOUP_SERVER_TLS_CERTIFICATE "tls-certificate"
-#define SOUP_SERVER_RAW_PATHS       "raw-paths"
-#define SOUP_SERVER_SERVER_HEADER   "server-header"
-#define SOUP_SERVER_HTTP_ALIASES    "http-aliases"
-#define SOUP_SERVER_HTTPS_ALIASES   "https-aliases"
+#define SOUP_SERVER_TLS_CERTIFICATE        "tls-certificate"
+#define SOUP_SERVER_RAW_PATHS              "raw-paths"
+#define SOUP_SERVER_SERVER_HEADER          "server-header"
+#define SOUP_SERVER_HTTP_ALIASES           "http-aliases"
+#define SOUP_SERVER_HTTPS_ALIASES          "https-aliases"
+#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;
@@ -121,11 +124,27 @@ void            soup_server_add_handler        (SoupServer         *server,
 void            soup_server_remove_handler     (SoupServer         *server,
                                                const char         *path);
 
+
+SOUP_DEPRECATED_IN_2_50
 void            soup_server_add_auth_domain    (SoupServer         *server,
                                                SoupAuthDomain     *auth_domain);
+SOUP_DEPRECATED_IN_2_50
 void            soup_server_remove_auth_domain (SoupServer         *server,
                                                SoupAuthDomain     *auth_domain);
 
+SOUP_AVAILABLE_IN_2_50
+void            soup_server_add_feature            (SoupServer        *server,
+                                                   SoupServerFeature *feature);
+SOUP_AVAILABLE_IN_2_50
+void            soup_server_add_feature_by_type    (SoupServer        *server,
+                                                   GType              feature_type);
+SOUP_AVAILABLE_IN_2_50
+void            soup_server_remove_feature         (SoupServer        *server,
+                                                   SoupServerFeature *feature);
+SOUP_AVAILABLE_IN_2_50
+void            soup_server_remove_feature_by_type (SoupServer        *server,
+                                                   GType              feature_type);
+
 /* I/O */
 
 void            soup_server_pause_message   (SoupServer  *server,
diff --git a/libsoup/soup-types.h b/libsoup/soup-types.h
index 0776bdb..9b9c547 100644
--- a/libsoup/soup-types.h
+++ b/libsoup/soup-types.h
@@ -16,6 +16,7 @@ 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 _SoupCookieJar         SoupCookieJar;
 typedef struct _SoupDate              SoupDate;
@@ -23,6 +24,7 @@ typedef struct _SoupMessage           SoupMessage;
 typedef struct _SoupRequest           SoupRequest;
 typedef struct _SoupRequestHTTP       SoupRequestHTTP;
 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 82a2632..941bfd2 100644
--- a/libsoup/soup.h
+++ b/libsoup/soup.h
@@ -41,6 +41,7 @@ extern "C" {
 #include <libsoup/soup-request-file.h>
 #include <libsoup/soup-request-http.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 f69501e..b828b36 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -874,14 +874,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));
 
        debug_printf (1, "  Testing with no auth\n");
        select_auth_test_one (uri, FALSE, NULL,
@@ -925,10 +925,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, FALSE, NULL,
diff --git a/tests/continue-test.c b/tests/continue-test.c
index 1bf0774..07431d5 100644
--- a/tests/continue-test.c
+++ b/tests/continue-test.c
@@ -434,7 +434,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 acf42c3..8d3b6d0 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -917,7 +917,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);
 
        if (tls_available) {
diff --git a/tests/server-auth-test.c b/tests/server-auth-test.c
index ee3f57b..c3bc136 100644
--- a/tests/server-auth-test.c
+++ b/tests/server-auth-test.c
@@ -295,7 +295,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 (
@@ -305,7 +305,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]