1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-request.c: Protocol-independent streaming request interface
5 * Copyright (C) 2009, 2010 Red Hat, Inc.
6 * Copyright (C) 2010, Igalia S.L.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
28 #include <glib/gi18n-lib.h>
30 #define LIBSOUP_USE_UNSTABLE_REQUEST_API
32 #include "soup-request.h"
33 #include "soup-requester.h"
34 #include "soup-session.h"
38 * SECTION:soup-request
39 * @short_description: Protocol-independent streaming request interface
41 * A #SoupRequest is created by #SoupRequester, and represents a
42 * request to retrieve a particular URI.
48 * A request to retrieve a particular URI.
53 static void soup_request_initable_interface_init (GInitableIface *initable_interface);
55 G_DEFINE_TYPE_WITH_CODE (SoupRequest, soup_request, G_TYPE_OBJECT,
56 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
57 soup_request_initable_interface_init))
65 struct _SoupRequestPrivate {
71 soup_request_init (SoupRequest *request)
73 request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, SOUP_TYPE_REQUEST, SoupRequestPrivate);
77 soup_request_finalize (GObject *object)
79 SoupRequest *request = SOUP_REQUEST (object);
81 if (request->priv->uri)
82 soup_uri_free (request->priv->uri);
83 if (request->priv->session)
84 g_object_unref (request->priv->session);
86 G_OBJECT_CLASS (soup_request_parent_class)->finalize (object);
90 soup_request_set_property (GObject *object,
95 SoupRequest *request = SOUP_REQUEST (object);
99 if (request->priv->uri)
100 soup_uri_free (request->priv->uri);
101 request->priv->uri = g_value_dup_boxed (value);
104 if (request->priv->session)
105 g_object_unref (request->priv->session);
106 request->priv->session = g_value_dup_object (value);
109 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
115 soup_request_get_property (GObject *object,
120 SoupRequest *request = SOUP_REQUEST (object);
124 g_value_set_boxed (value, request->priv->uri);
127 g_value_set_object (value, request->priv->session);
130 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
136 soup_request_initable_init (GInitable *initable,
137 GCancellable *cancellable,
140 SoupRequest *request = SOUP_REQUEST (initable);
143 if (!request->priv->uri) {
144 g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI,
145 _("No URI provided"));
149 ok = SOUP_REQUEST_GET_CLASS (initable)->
150 check_uri (request, request->priv->uri, error);
152 if (!ok && error && !*error) {
153 char *uri_string = soup_uri_to_string (request->priv->uri, FALSE);
154 g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI,
155 _("Invalid '%s' URI: %s"),
156 request->priv->uri->scheme,
165 soup_request_default_check_uri (SoupRequest *request,
172 /* Default implementation: assume the sync implementation doesn't block */
174 soup_request_default_send_async (SoupRequest *request,
175 GCancellable *cancellable,
176 GAsyncReadyCallback callback,
179 GSimpleAsyncResult *simple;
181 simple = g_simple_async_result_new (G_OBJECT (request),
183 soup_request_default_send_async);
184 g_simple_async_result_complete_in_idle (simple);
185 g_object_unref (simple);
188 static GInputStream *
189 soup_request_default_send_finish (SoupRequest *request,
190 GAsyncResult *result,
193 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_default_send_async), NULL);
195 return soup_request_send (request, NULL, error);
200 * @request: a #SoupRequest
201 * @cancellable: a #GCancellable or %NULL
202 * @error: return location for a #GError, or %NULL
204 * Synchronously requests the URI pointed to by @request, and returns
205 * a #GInputStream that can be used to read its contents.
207 * Return value: (transfer full): a #GInputStream that can be used to
208 * read from the URI pointed to by @request.
213 soup_request_send (SoupRequest *request,
214 GCancellable *cancellable,
217 return SOUP_REQUEST_GET_CLASS (request)->
218 send (request, cancellable, error);
222 * soup_request_send_async:
223 * @request: a #SoupRequest
224 * @cancellable: a #GCancellable or %NULL
225 * @callback: a #GAsyncReadyCallback
226 * @user_data: user data passed to @callback
228 * Begins an asynchronously request for the URI pointed to by
234 soup_request_send_async (SoupRequest *request,
235 GCancellable *cancellable,
236 GAsyncReadyCallback callback,
239 SOUP_REQUEST_GET_CLASS (request)->
240 send_async (request, cancellable, callback, user_data);
244 * soup_request_send_finish:
245 * @request: a #SoupRequest
246 * @result: the #GAsyncResult
247 * @error: return location for a #GError, or %NULL
249 * Gets the result of a soup_request_send_async().
251 * Return value: (transfer full): a #GInputStream that can be used to
252 * read from the URI pointed to by @request.
257 soup_request_send_finish (SoupRequest *request,
258 GAsyncResult *result,
261 return SOUP_REQUEST_GET_CLASS (request)->
262 send_finish (request, result, error);
266 soup_request_class_init (SoupRequestClass *request_class)
268 GObjectClass *object_class = G_OBJECT_CLASS (request_class);
270 g_type_class_add_private (request_class, sizeof (SoupRequestPrivate));
272 request_class->check_uri = soup_request_default_check_uri;
273 request_class->send_async = soup_request_default_send_async;
274 request_class->send_finish = soup_request_default_send_finish;
276 object_class->finalize = soup_request_finalize;
277 object_class->set_property = soup_request_set_property;
278 object_class->get_property = soup_request_get_property;
280 g_object_class_install_property (
281 object_class, PROP_URI,
282 g_param_spec_boxed (SOUP_REQUEST_URI,
286 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
287 g_object_class_install_property (
288 object_class, PROP_SESSION,
289 g_param_spec_object (SOUP_REQUEST_SESSION,
291 "The request's session",
293 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
297 soup_request_initable_interface_init (GInitableIface *initable_interface)
299 initable_interface->init = soup_request_initable_init;
303 * soup_request_get_uri:
304 * @request: a #SoupRequest
306 * Gets @request's URI
308 * Return value: (transfer none): @request's URI
313 soup_request_get_uri (SoupRequest *request)
315 return request->priv->uri;
319 * soup_request_get_session:
320 * @request: a #SoupRequest
322 * Gets @request's #SoupSession
324 * Return value: (transfer none): @request's #SoupSession
329 soup_request_get_session (SoupRequest *request)
331 return request->priv->session;
335 * soup_request_get_content_length:
336 * @request: a #SoupRequest
338 * Gets the length of the data represented by @request.
340 * Return value: the length of the data represented by @request,
341 * or -1 if not known.
346 soup_request_get_content_length (SoupRequest *request)
348 return SOUP_REQUEST_GET_CLASS (request)->get_content_length (request);
352 * soup_request_get_content_type:
353 * @request: a #SoupRequest
355 * Gets the type of the data represented by @request. As in the
356 * HTTP Content-Type header, this may include parameters after
359 * Return value: the type of the data represented by @request,
360 * or %NULL if not known.
365 soup_request_get_content_type (SoupRequest *request)
367 return SOUP_REQUEST_GET_CLASS (request)->get_content_type (request);