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 #include "soup-request.h"
32 #include "soup-requester.h"
35 * SECTION:soup-request
36 * @short_description: Protocol-independent streaming request interface
38 * A #SoupRequest is created by #SoupSession, and represents a request
39 * to retrieve a particular URI.
45 * A request to retrieve a particular URI.
50 static void soup_request_initable_interface_init (GInitableIface *initable_interface);
52 G_DEFINE_TYPE_WITH_CODE (SoupRequest, soup_request, G_TYPE_OBJECT,
53 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
54 soup_request_initable_interface_init))
62 struct _SoupRequestPrivate {
68 soup_request_init (SoupRequest *request)
70 request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, SOUP_TYPE_REQUEST, SoupRequestPrivate);
74 soup_request_finalize (GObject *object)
76 SoupRequest *request = SOUP_REQUEST (object);
78 g_clear_pointer (&request->priv->uri, soup_uri_free);
79 g_clear_object (&request->priv->session);
81 G_OBJECT_CLASS (soup_request_parent_class)->finalize (object);
85 soup_request_set_property (GObject *object,
90 SoupRequest *request = SOUP_REQUEST (object);
94 if (request->priv->uri)
95 soup_uri_free (request->priv->uri);
96 request->priv->uri = g_value_dup_boxed (value);
99 if (request->priv->session)
100 g_object_unref (request->priv->session);
101 request->priv->session = g_value_dup_object (value);
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
110 soup_request_get_property (GObject *object,
115 SoupRequest *request = SOUP_REQUEST (object);
119 g_value_set_boxed (value, request->priv->uri);
122 g_value_set_object (value, request->priv->session);
125 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
131 soup_request_initable_init (GInitable *initable,
132 GCancellable *cancellable,
135 SoupRequest *request = SOUP_REQUEST (initable);
138 if (!request->priv->uri) {
139 g_set_error (error, SOUP_REQUEST_ERROR, SOUP_REQUEST_ERROR_BAD_URI,
140 _("No URI provided"));
144 ok = SOUP_REQUEST_GET_CLASS (initable)->
145 check_uri (request, request->priv->uri, error);
147 if (!ok && error && !*error) {
148 char *uri_string = soup_uri_to_string (request->priv->uri, FALSE);
149 g_set_error (error, SOUP_REQUEST_ERROR, SOUP_REQUEST_ERROR_BAD_URI,
150 _("Invalid '%s' URI: %s"),
151 request->priv->uri->scheme,
160 soup_request_default_check_uri (SoupRequest *request,
167 /* Default implementation: assume the sync implementation doesn't block */
169 soup_request_default_send_async (SoupRequest *request,
170 GCancellable *cancellable,
171 GAsyncReadyCallback callback,
175 GInputStream *stream;
176 GError *error = NULL;
178 task = g_task_new (request, cancellable, callback, user_data);
180 stream = soup_request_send (request, cancellable, &error);
182 g_task_return_pointer (task, stream, g_object_unref);
184 g_task_return_error (task, error);
185 g_object_unref (task);
188 static GInputStream *
189 soup_request_default_send_finish (SoupRequest *request,
190 GAsyncResult *result,
193 return g_task_propagate_pointer (G_TASK (result), error);
198 * @request: a #SoupRequest
199 * @cancellable: a #GCancellable or %NULL
200 * @error: return location for a #GError, or %NULL
202 * Synchronously requests the URI pointed to by @request, and returns
203 * a #GInputStream that can be used to read its contents.
205 * Note that you cannot use this method with #SoupRequests attached to
206 * a #SoupSessionAsync.
208 * Return value: (transfer full): a #GInputStream that can be used to
209 * read from the URI pointed to by @request.
214 soup_request_send (SoupRequest *request,
215 GCancellable *cancellable,
218 return SOUP_REQUEST_GET_CLASS (request)->
219 send (request, cancellable, error);
223 * soup_request_send_async:
224 * @request: a #SoupRequest
225 * @cancellable: a #GCancellable or %NULL
226 * @callback: a #GAsyncReadyCallback
227 * @user_data: user data passed to @callback
229 * Begins an asynchronously request for the URI pointed to by
232 * Note that you cannot use this method with #SoupRequests attached to
233 * a #SoupSessionSync.
238 soup_request_send_async (SoupRequest *request,
239 GCancellable *cancellable,
240 GAsyncReadyCallback callback,
243 SOUP_REQUEST_GET_CLASS (request)->
244 send_async (request, cancellable, callback, user_data);
248 * soup_request_send_finish:
249 * @request: a #SoupRequest
250 * @result: the #GAsyncResult
251 * @error: return location for a #GError, or %NULL
253 * Gets the result of a soup_request_send_async().
255 * Return value: (transfer full): a #GInputStream that can be used to
256 * read from the URI pointed to by @request.
261 soup_request_send_finish (SoupRequest *request,
262 GAsyncResult *result,
265 return SOUP_REQUEST_GET_CLASS (request)->
266 send_finish (request, result, error);
270 soup_request_class_init (SoupRequestClass *request_class)
272 GObjectClass *object_class = G_OBJECT_CLASS (request_class);
274 g_type_class_add_private (request_class, sizeof (SoupRequestPrivate));
276 request_class->check_uri = soup_request_default_check_uri;
277 request_class->send_async = soup_request_default_send_async;
278 request_class->send_finish = soup_request_default_send_finish;
280 object_class->finalize = soup_request_finalize;
281 object_class->set_property = soup_request_set_property;
282 object_class->get_property = soup_request_get_property;
287 * Alias for the #SoupRequest:uri property, qv.
298 g_object_class_install_property (
299 object_class, PROP_URI,
300 g_param_spec_boxed (SOUP_REQUEST_URI,
304 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
306 * SOUP_REQUEST_SESSION:
308 * Alias for the #SoupRequest:session property, qv.
313 * SoupRequest:session:
315 * The request's #SoupSession.
319 g_object_class_install_property (
320 object_class, PROP_SESSION,
321 g_param_spec_object (SOUP_REQUEST_SESSION,
323 "The request's session",
325 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
329 soup_request_initable_interface_init (GInitableIface *initable_interface)
331 initable_interface->init = soup_request_initable_init;
335 * soup_request_get_uri:
336 * @request: a #SoupRequest
338 * Gets @request's URI
340 * Return value: (transfer none): @request's URI
345 soup_request_get_uri (SoupRequest *request)
347 return request->priv->uri;
351 * soup_request_get_session:
352 * @request: a #SoupRequest
354 * Gets @request's #SoupSession
356 * Return value: (transfer none): @request's #SoupSession
361 soup_request_get_session (SoupRequest *request)
363 return request->priv->session;
367 * soup_request_get_content_length:
368 * @request: a #SoupRequest
370 * Gets the length of the data represented by @request. For most
371 * request types, this will not be known until after you call
372 * soup_request_send() or soup_request_send_finish().
374 * Return value: the length of the data represented by @request,
375 * or -1 if not known.
380 soup_request_get_content_length (SoupRequest *request)
382 return SOUP_REQUEST_GET_CLASS (request)->get_content_length (request);
386 * soup_request_get_content_type:
387 * @request: a #SoupRequest
389 * Gets the type of the data represented by @request. For most request
390 * types, this will not be known until after you call
391 * soup_request_send() or soup_request_send_finish().
393 * As in the HTTP Content-Type header, this may include parameters
394 * after the MIME type.
396 * Return value: the type of the data represented by @request,
397 * or %NULL if not known.
402 soup_request_get_content_type (SoupRequest *request)
404 return SOUP_REQUEST_GET_CLASS (request)->get_content_type (request);