Reapplying patch to disable attempts to use gtk-doc
[profile/ivi/libsoup2.4.git] / libsoup / soup-request.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-request.c: Protocol-independent streaming request interface
4  *
5  * Copyright (C) 2009, 2010 Red Hat, Inc.
6  * Copyright (C) 2010, Igalia S.L.
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <glib/gi18n-lib.h>
29
30 #define LIBSOUP_USE_UNSTABLE_REQUEST_API
31
32 #include "soup-request.h"
33 #include "soup-requester.h"
34 #include "soup-session.h"
35 #include "soup-uri.h"
36
37 /**
38  * SECTION:soup-request
39  * @short_description: Protocol-independent streaming request interface
40  *
41  * A #SoupRequest is created by #SoupRequester, and represents a
42  * request to retrieve a particular URI.
43  */
44
45 /**
46  * SoupRequest:
47  *
48  * A request to retrieve a particular URI.
49  *
50  * Since: 2.34
51  */
52
53 static void soup_request_initable_interface_init (GInitableIface *initable_interface);
54
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))
58
59 enum {
60         PROP_0,
61         PROP_URI,
62         PROP_SESSION
63 };
64
65 struct _SoupRequestPrivate {
66         SoupURI *uri;
67         SoupSession *session;
68 };
69
70 static void
71 soup_request_init (SoupRequest *request)
72 {
73         request->priv = G_TYPE_INSTANCE_GET_PRIVATE (request, SOUP_TYPE_REQUEST, SoupRequestPrivate);
74 }
75
76 static void
77 soup_request_finalize (GObject *object)
78 {
79         SoupRequest *request = SOUP_REQUEST (object);
80
81         if (request->priv->uri)
82                 soup_uri_free (request->priv->uri);
83         if (request->priv->session)
84                 g_object_unref (request->priv->session);
85
86         G_OBJECT_CLASS (soup_request_parent_class)->finalize (object);
87 }
88
89 static void
90 soup_request_set_property (GObject      *object,
91                            guint prop_id,
92                            const GValue *value,
93                            GParamSpec   *pspec)
94 {
95         SoupRequest *request = SOUP_REQUEST (object);
96
97         switch (prop_id) {
98         case PROP_URI:
99                 if (request->priv->uri)
100                         soup_uri_free (request->priv->uri);
101                 request->priv->uri = g_value_dup_boxed (value);
102                 break;
103         case PROP_SESSION:
104                 if (request->priv->session)
105                         g_object_unref (request->priv->session);
106                 request->priv->session = g_value_dup_object (value);
107                 break;
108         default:
109                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
110                 break;
111         }
112 }
113
114 static void
115 soup_request_get_property (GObject    *object,
116                            guint prop_id,
117                            GValue     *value,
118                            GParamSpec *pspec)
119 {
120         SoupRequest *request = SOUP_REQUEST (object);
121
122         switch (prop_id) {
123         case PROP_URI:
124                 g_value_set_boxed (value, request->priv->uri);
125                 break;
126         case PROP_SESSION:
127                 g_value_set_object (value, request->priv->session);
128                 break;
129         default:
130                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
131                 break;
132         }
133 }
134
135 static gboolean
136 soup_request_initable_init (GInitable     *initable,
137                             GCancellable  *cancellable,
138                             GError       **error)
139 {
140         SoupRequest *request = SOUP_REQUEST (initable);
141         gboolean ok;
142
143         if (!request->priv->uri) {
144                 g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI,
145                              _("No URI provided"));
146                 return FALSE;
147         }
148
149         ok = SOUP_REQUEST_GET_CLASS (initable)->
150                 check_uri (request, request->priv->uri, error);
151
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,
157                              uri_string);
158                 g_free (uri_string);
159         }
160
161         return ok;
162 }
163
164 static gboolean
165 soup_request_default_check_uri (SoupRequest  *request,
166                                 SoupURI      *uri,
167                                 GError      **error)
168 {
169         return TRUE;
170 }
171
172 /* Default implementation: assume the sync implementation doesn't block */
173 static void
174 soup_request_default_send_async (SoupRequest          *request,
175                                  GCancellable         *cancellable,
176                                  GAsyncReadyCallback   callback,
177                                  gpointer              user_data)
178 {
179         GSimpleAsyncResult *simple;
180
181         simple = g_simple_async_result_new (G_OBJECT (request),
182                                             callback, user_data,
183                                             soup_request_default_send_async);
184         g_simple_async_result_complete_in_idle (simple);
185         g_object_unref (simple);
186 }
187
188 static GInputStream *
189 soup_request_default_send_finish (SoupRequest          *request,
190                                   GAsyncResult         *result,
191                                   GError              **error)
192 {
193         g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_default_send_async), NULL);
194
195         return soup_request_send (request, NULL, error);
196 }
197
198 /**
199  * soup_request_send:
200  * @request: a #SoupRequest
201  * @cancellable: a #GCancellable or %NULL
202  * @error: return location for a #GError, or %NULL
203  *
204  * Synchronously requests the URI pointed to by @request, and returns
205  * a #GInputStream that can be used to read its contents.
206  *
207  * Return value: (transfer full): a #GInputStream that can be used to
208  *   read from the URI pointed to by @request.
209  *
210  * Since: 2.34
211  */
212 GInputStream *
213 soup_request_send (SoupRequest          *request,
214                    GCancellable         *cancellable,
215                    GError              **error)
216 {
217         return SOUP_REQUEST_GET_CLASS (request)->
218                 send (request, cancellable, error);
219 }
220
221 /**
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
227  *
228  * Begins an asynchronously request for the URI pointed to by
229  * @request.
230  *
231  * Since: 2.34
232  */
233 void
234 soup_request_send_async (SoupRequest         *request,
235                          GCancellable        *cancellable,
236                          GAsyncReadyCallback  callback,
237                          gpointer             user_data)
238 {
239         SOUP_REQUEST_GET_CLASS (request)->
240                 send_async (request, cancellable, callback, user_data);
241 }
242
243 /**
244  * soup_request_send_finish:
245  * @request: a #SoupRequest
246  * @result: the #GAsyncResult
247  * @error: return location for a #GError, or %NULL
248  *
249  * Gets the result of a soup_request_send_async().
250  *
251  * Return value: (transfer full): a #GInputStream that can be used to
252  *   read from the URI pointed to by @request.
253  *
254  * Since: 2.34
255  */
256 GInputStream *
257 soup_request_send_finish (SoupRequest          *request,
258                           GAsyncResult         *result,
259                           GError              **error)
260 {
261         return SOUP_REQUEST_GET_CLASS (request)->
262                 send_finish (request, result, error);
263 }
264
265 static void
266 soup_request_class_init (SoupRequestClass *request_class)
267 {
268         GObjectClass *object_class = G_OBJECT_CLASS (request_class);
269
270         g_type_class_add_private (request_class, sizeof (SoupRequestPrivate));
271
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;
275
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;
279
280         g_object_class_install_property (
281                  object_class, PROP_URI,
282                  g_param_spec_boxed (SOUP_REQUEST_URI,
283                                      "URI",
284                                      "The request URI",
285                                      SOUP_TYPE_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,
290                                       "Session",
291                                       "The request's session",
292                                       SOUP_TYPE_SESSION,
293                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
294 }
295
296 static void
297 soup_request_initable_interface_init (GInitableIface *initable_interface)
298 {
299         initable_interface->init = soup_request_initable_init;
300 }
301
302 /**
303  * soup_request_get_uri:
304  * @request: a #SoupRequest
305  *
306  * Gets @request's URI
307  *
308  * Return value: (transfer none): @request's URI
309  *
310  * Since: 2.34
311  */
312 SoupURI *
313 soup_request_get_uri (SoupRequest *request)
314 {
315         return request->priv->uri;
316 }
317
318 /**
319  * soup_request_get_session:
320  * @request: a #SoupRequest
321  *
322  * Gets @request's #SoupSession
323  *
324  * Return value: (transfer none): @request's #SoupSession
325  *
326  * Since: 2.34
327  */
328 SoupSession *
329 soup_request_get_session (SoupRequest *request)
330 {
331         return request->priv->session;
332 }
333
334 /**
335  * soup_request_get_content_length:
336  * @request: a #SoupRequest
337  *
338  * Gets the length of the data represented by @request.
339  *
340  * Return value: the length of the data represented by @request,
341  *   or -1 if not known.
342  *
343  * Since: 2.34
344  */
345 goffset
346 soup_request_get_content_length (SoupRequest *request)
347 {
348         return SOUP_REQUEST_GET_CLASS (request)->get_content_length (request);
349 }
350
351 /**
352  * soup_request_get_content_type:
353  * @request: a #SoupRequest
354  *
355  * Gets the type of the data represented by @request. As in the
356  * HTTP Content-Type header, this may include parameters after
357  * the MIME type.
358  *
359  * Return value: the type of the data represented by @request,
360  *   or %NULL if not known.
361  *
362  * Since: 2.34
363  */
364 const char *
365 soup_request_get_content_type (SoupRequest  *request)
366 {
367         return SOUP_REQUEST_GET_CLASS (request)->get_content_type (request);
368 }