soup-session: add SoupMessage-based streaming APIs
authorDan Winship <danw@gnome.org>
Sat, 29 Dec 2012 02:53:02 +0000 (21:53 -0500)
committerDan Winship <danw@gnome.org>
Mon, 14 Jan 2013 22:19:39 +0000 (17:19 -0500)
SoupRequestHTTP is now implemented in terms of SoupSession SoupMessage
operations, so we might as well just expose those directly, for people
who want streaming APIs, but not SoupRequest.

docs/reference/libsoup-2.4-sections.txt
libsoup/libsoup-2.4.sym
libsoup/soup-request-http.c
libsoup/soup-session.c
libsoup/soup-session.h

index 52e505d..1b06804 100644 (file)
@@ -404,6 +404,10 @@ soup_session_requeue_message
 soup_session_send_message
 soup_session_cancel_message
 <SUBSECTION>
+soup_session_send
+soup_session_send_async
+soup_session_send_finish
+<SUBSECTION>
 soup_session_prefetch_dns
 soup_session_prepare_for_uri
 soup_session_abort
index 6b82f5a..22af160 100644 (file)
@@ -385,6 +385,9 @@ soup_session_request_http
 soup_session_request_http_uri
 soup_session_request_uri
 soup_session_requeue_message
+soup_session_send
+soup_session_send_async
+soup_session_send_finish
 soup_session_send_message
 soup_session_sync_get_type
 soup_session_sync_new
index 4e527cc..9ae2c2a 100644 (file)
@@ -107,8 +107,8 @@ soup_request_http_send (SoupRequest          *request,
 
        g_return_val_if_fail (!SOUP_IS_SESSION_ASYNC (session), NULL);
 
-       return soup_session_send_request (session, http->priv->msg,
-                                         cancellable, error);
+       return soup_session_send (session, http->priv->msg,
+                                 cancellable, error);
 }
 
 
@@ -119,7 +119,7 @@ http_input_stream_ready_cb (GObject *source, GAsyncResult *result, gpointer user
        GError *error = NULL;
        GInputStream *stream;
 
-       stream = soup_session_send_request_finish (SOUP_SESSION (source), result, &error);
+       stream = soup_session_send_finish (SOUP_SESSION (source), result, &error);
        if (stream)
                g_task_return_pointer (task, stream, g_object_unref);
        else
@@ -140,8 +140,8 @@ soup_request_http_send_async (SoupRequest          *request,
        g_return_if_fail (!SOUP_IS_SESSION_SYNC (session));
 
        task = g_task_new (request, cancellable, callback, user_data);
-       soup_session_send_request_async (session, http->priv->msg, cancellable,
-                                        http_input_stream_ready_cb, task);
+       soup_session_send_async (session, http->priv->msg, cancellable,
+                                http_input_stream_ready_cb, task);
 }
 
 static GInputStream *
index c4abe1d..bfc71fc 100644 (file)
@@ -1972,6 +1972,11 @@ soup_session_real_queue_message (SoupSession *session, SoupMessage *msg,
  * and #SoupSession:use-thread-context, and for #SoupSessionSync, the
  * message will actually be sent and processed in another thread, with
  * only the final callback occurring in the indicated #GMainContext.)
+ *
+ * Contrast this method with soup_session_send_async(), which also
+ * asynchronously sends a message, but returns before reading the
+ * response body, and allows you to read the response via a
+ * #GInputStream.
  */
 void
 soup_session_queue_message (SoupSession *session, SoupMessage *msg,
@@ -2048,6 +2053,11 @@ soup_session_real_send_message (SoupSession *session, SoupMessage *msg)
  * to process the message, which may also cause other events to be
  * processed.)
  *
+ * Contrast this method with soup_session_send(), which also
+ * synchronously sends a message, but returns before reading the
+ * response body, and allows you to read the response via a
+ * #GInputStream.
+ *
  * Return value: the HTTP status code of the response
  */
 guint
@@ -3831,12 +3841,39 @@ async_respond_from_cache (SoupSession          *session,
                return FALSE;
 }
 
+/**
+ * soup_session_send_async:
+ * @session: a #SoupSession
+ * @msg: a #SoupMessage
+ * @cancellable: a #GCancellable
+ * @callback: the callback to invoke
+ * @user_data: data for @callback
+ *
+ * Asynchronously sends @msg and waits for the beginning of a
+ * response. When @callback is called, then either @msg has been sent,
+ * and its response headers received, or else an error has occurred.
+ * Call soup_session_send_finish() to get a #GInputStream for reading
+ * the response body.
+ *
+ * See soup_session_send() for more details on the general semantics.
+ *
+ * Contrast this method with soup_session_queue_message(), which also
+ * asynchronously sends a #SoupMessage, but doesn't invoke its
+ * callback until the response has been completely read.
+ *
+ * (Note that this method cannot be called on the deprecated
+ * #SoupSessionSync subclass, and can only be called on
+ * #SoupSessionAsync if you have set the
+ * #SoupSession:use-thread-context property.)
+ *
+ * Since: 2.42
+ */
 void
-soup_session_send_request_async (SoupSession         *session,
-                                SoupMessage         *msg,
-                                GCancellable        *cancellable,
-                                GAsyncReadyCallback  callback,
-                                gpointer             user_data)
+soup_session_send_async (SoupSession         *session,
+                        SoupMessage         *msg,
+                        GCancellable        *cancellable,
+                        GAsyncReadyCallback  callback,
+                        gpointer             user_data)
 {
        SoupMessageQueueItem *item;
        gboolean use_thread_context;
@@ -3871,10 +3908,25 @@ soup_session_send_request_async (SoupSession         *session,
                soup_session_kick_queue (session);
 }
 
+/**
+ * soup_session_send_finish:
+ * @session: a #SoupSession
+ * @result: the #GAsyncResult passed to your callback
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the response to a soup_session_send_async() call and (if
+ * successful), returns a #GInputStream that can be used to read the
+ * response body.
+ *
+ * Return value: a #GInputStream for reading the response body, or
+ *   %NULL on error.
+ *
+ * Since: 2.42
+ */
 GInputStream *
-soup_session_send_request_finish (SoupSession   *session,
-                                 GAsyncResult  *result,
-                                 GError       **error)
+soup_session_send_finish (SoupSession   *session,
+                         GAsyncResult  *result,
+                         GError       **error)
 {
        GTask *task;
 
@@ -3898,11 +3950,49 @@ soup_session_send_request_finish (SoupSession   *session,
        return g_task_propagate_pointer (task, error);
 }
 
+/**
+ * soup_session_send:
+ * @session: a #SoupSession
+ * @msg: a #SoupMessage
+ * @cancellable: a #GCancellable
+ * @error: return location for a #GError, or %NULL
+ *
+ * Synchronously sends @msg and waits for the beginning of a response.
+ * On success, a #GInputStream will be returned which you can use to
+ * read the response body. ("Success" here means only that an HTTP
+ * response was received and understood; it does not necessarily mean
+ * that a 2xx class status code was received.)
+ *
+ * If non-%NULL, @cancellable can be used to cancel the request;
+ * soup_session_send() will return a %G_IO_ERROR_CANCELLED error. Note
+ * that with requests that have side effects (eg,
+ * <literal>POST</literal>, <literal>PUT</literal>,
+ * <literal>DELETE</literal>) it is possible that you might cancel the
+ * request after the server acts on it, but before it returns a
+ * response, leaving the remote resource in an unknown state.
+ *
+ * If @msg is requeued due to a redirect or authentication, the
+ * initial (3xx/401/407) response body will be suppressed, and
+ * soup_session_send() will only return once a final response has been
+ * received.
+ *
+ * Contrast this method with soup_session_send_message(), which also
+ * synchronously sends a #SoupMessage, but doesn't return until the
+ * response has been completely read.
+ *
+ * (Note that this method cannot be called on the deprecated
+ * #SoupSessionAsync subclass.)
+ *
+ * Return value: a #GInputStream for reading the response body, or
+ *   %NULL on error.
+ *
+ * Since: 2.42
+ */
 GInputStream *
-soup_session_send_request (SoupSession   *session,
-                          SoupMessage   *msg,
-                          GCancellable  *cancellable,
-                          GError       **error)
+soup_session_send (SoupSession   *session,
+                  SoupMessage   *msg,
+                  GCancellable  *cancellable,
+                  GError       **error)
 {
        SoupMessageQueueItem *item;
        GInputStream *stream = NULL;
index 5d62667..90cf12c 100644 (file)
@@ -110,6 +110,22 @@ void            soup_session_abort            (SoupSession           *session);
 
 GMainContext   *soup_session_get_async_context(SoupSession           *session);
 
+SOUP_AVAILABLE_IN_2_42
+void            soup_session_send_async       (SoupSession           *session,
+                                              SoupMessage           *msg,
+                                              GCancellable          *cancellable,
+                                              GAsyncReadyCallback    callback,
+                                              gpointer               user_data);
+SOUP_AVAILABLE_IN_2_42
+GInputStream   *soup_session_send_finish      (SoupSession           *session,
+                                              GAsyncResult          *result,
+                                              GError               **error);
+SOUP_AVAILABLE_IN_2_42
+GInputStream   *soup_session_send             (SoupSession           *session,
+                                              SoupMessage           *msg,
+                                              GCancellable          *cancellable,
+                                              GError               **error);
+
 #ifndef SOUP_DISABLE_DEPRECATED
 /* SOUP_AVAILABLE_IN_2_30 -- this trips up gtkdoc-scan */
 SOUP_DEPRECATED_IN_2_38_FOR (soup_session_prefetch_dns)