1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * Copyright (C) 2010, Igalia S.L.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
25 #include <glib/gi18n.h>
27 #define LIBSOUP_USE_UNSTABLE_REQUEST_API
29 #include "soup-requester.h"
30 #include "soup-request-data.h"
31 #include "soup-request-file.h"
32 #include "soup-request-http.h"
33 #include "soup-session-feature.h"
36 static SoupSessionFeatureInterface *soup_requester_default_feature_interface;
37 static void soup_requester_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data);
39 struct _SoupRequesterPrivate {
41 GHashTable *request_types;
44 G_DEFINE_TYPE_WITH_CODE (SoupRequester, soup_requester, G_TYPE_OBJECT,
45 G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE,
46 soup_requester_session_feature_init))
49 soup_requester_init (SoupRequester *requester)
51 SoupSessionFeature *feature;
53 requester->priv = G_TYPE_INSTANCE_GET_PRIVATE (requester,
55 SoupRequesterPrivate);
57 requester->priv->request_types = g_hash_table_new (soup_str_case_hash,
60 feature = SOUP_SESSION_FEATURE (requester);
61 soup_session_feature_add_feature (feature, SOUP_TYPE_REQUEST_HTTP);
62 soup_session_feature_add_feature (feature, SOUP_TYPE_REQUEST_FILE);
63 soup_session_feature_add_feature (feature, SOUP_TYPE_REQUEST_DATA);
67 finalize (GObject *object)
69 SoupRequester *requester = SOUP_REQUESTER (object);
71 g_hash_table_destroy (requester->priv->request_types);
73 G_OBJECT_CLASS (soup_requester_parent_class)->finalize (object);
77 soup_requester_class_init (SoupRequesterClass *requester_class)
79 GObjectClass *object_class = G_OBJECT_CLASS (requester_class);
81 g_type_class_add_private (requester_class, sizeof (SoupRequesterPrivate));
83 /* virtual method override */
84 object_class->finalize = finalize;
88 attach (SoupSessionFeature *feature, SoupSession *session)
90 SoupRequester *requester = SOUP_REQUESTER (feature);
92 requester->priv->session = session;
94 soup_requester_default_feature_interface->attach (feature, session);
98 detach (SoupSessionFeature *feature, SoupSession *session)
100 SoupRequester *requester = SOUP_REQUESTER (feature);
102 requester->priv->session = NULL;
104 soup_requester_default_feature_interface->detach (feature, session);
108 add_feature (SoupSessionFeature *feature, GType type)
110 SoupRequester *requester = SOUP_REQUESTER (feature);
111 SoupRequestClass *request_class;
114 if (!g_type_is_a (type, SOUP_TYPE_REQUEST))
117 request_class = g_type_class_ref (type);
118 for (i = 0; request_class->schemes[i]; i++) {
119 g_hash_table_insert (requester->priv->request_types,
120 (char *)request_class->schemes[i],
121 GSIZE_TO_POINTER (type));
127 remove_feature (SoupSessionFeature *feature, GType type)
129 SoupRequester *requester = SOUP_REQUESTER (feature);
130 SoupRequestClass *request_class;
133 if (!g_type_is_a (type, SOUP_TYPE_REQUEST))
136 request_class = g_type_class_peek (type);
140 orig_size = g_hash_table_size (requester->priv->request_types);
141 for (i = 0; request_class->schemes[i]; i++) {
142 g_hash_table_remove (requester->priv->request_types,
143 request_class->schemes[i]);
146 return g_hash_table_size (requester->priv->request_types) != orig_size;
150 has_feature (SoupSessionFeature *feature, GType type)
152 SoupRequester *requester = SOUP_REQUESTER (feature);
156 if (!g_type_is_a (type, SOUP_TYPE_REQUEST))
159 g_hash_table_iter_init (&iter, requester->priv->request_types);
160 while (g_hash_table_iter_next (&iter, &key, &value)) {
161 if (value == GSIZE_TO_POINTER (type))
168 soup_requester_session_feature_init (SoupSessionFeatureInterface *feature_interface,
169 gpointer interface_data)
171 soup_requester_default_feature_interface =
172 g_type_default_interface_peek (SOUP_TYPE_SESSION_FEATURE);
174 feature_interface->attach = attach;
175 feature_interface->detach = detach;
176 feature_interface->add_feature = add_feature;
177 feature_interface->remove_feature = remove_feature;
178 feature_interface->has_feature = has_feature;
182 soup_requester_new (void)
184 return g_object_new (SOUP_TYPE_REQUESTER, NULL);
188 soup_requester_request (SoupRequester *requester, const char *uri_string,
194 uri = soup_uri_new (uri_string);
196 g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI,
197 _("Could not parse URI '%s'"), uri_string);
201 req = soup_requester_request_uri (requester, uri, error);
207 soup_requester_request_uri (SoupRequester *requester, SoupURI *uri,
212 g_return_val_if_fail (SOUP_IS_REQUESTER (requester), NULL);
214 request_type = (GType)GPOINTER_TO_SIZE (g_hash_table_lookup (requester->priv->request_types, uri->scheme));
216 g_set_error (error, SOUP_REQUESTER_ERROR,
217 SOUP_REQUESTER_ERROR_UNSUPPORTED_URI_SCHEME,
218 _("Unsupported URI scheme '%s'"), uri->scheme);
222 return g_initable_new (request_type, NULL, error,
224 "session", requester->priv->session,
229 soup_requester_error_quark (void)
233 error = g_quark_from_static_string ("soup_requester_error_quark");