diff options
Diffstat (limited to 'libsoup/soup-request-http.c')
-rw-r--r-- | libsoup/soup-request-http.c | 191 |
1 files changed, 37 insertions, 154 deletions
diff --git a/libsoup/soup-request-http.c b/libsoup/soup-request-http.c index 44a1f7d5..9ae2c2a7 100644 --- a/libsoup/soup-request-http.c +++ b/libsoup/soup-request-http.c @@ -27,13 +27,23 @@ #include <glib/gi18n-lib.h> -#define LIBSOUP_USE_UNSTABLE_REQUEST_API - #include "soup-request-http.h" #include "soup.h" -#include "soup-cache-private.h" +#include "soup-message-private.h" #include "soup-session-private.h" +/** + * SECTION:soup-request-http + * @short_description: SoupRequest support for "http" and "https" URIs + * + * #SoupRequestHTTP implements #SoupRequest for "http" and "https" + * URIs. + * + * To do more complicated HTTP operations using the #SoupRequest APIs, + * call soup_request_http_get_message() to get the request's + * #SoupMessage. + */ + G_DEFINE_TYPE (SoupRequestHTTP, soup_request_http, SOUP_TYPE_REQUEST) struct _SoupRequestHTTPPrivate { @@ -63,6 +73,8 @@ soup_request_http_check_uri (SoupRequest *request, return FALSE; http->priv->msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri); + soup_message_set_soup_request (http->priv->msg, request); + g_signal_connect (http->priv->msg, "content-sniffed", G_CALLBACK (content_sniffed), http); return TRUE; @@ -91,109 +103,28 @@ soup_request_http_send (SoupRequest *request, GError **error) { SoupRequestHTTP *http = SOUP_REQUEST_HTTP (request); + SoupSession *session = soup_request_get_session (request); - return soup_session_send_request (soup_request_get_session (request), - http->priv->msg, - cancellable, error); -} - - -typedef struct { - SoupRequestHTTP *http; - GCancellable *cancellable; - GSimpleAsyncResult *simple; - - SoupMessage *original; - GInputStream *stream; -} SendAsyncData; - -static void -free_send_async_data (SendAsyncData *sadata) -{ - g_object_unref (sadata->http); - g_object_unref (sadata->simple); - - if (sadata->cancellable) - g_object_unref (sadata->cancellable); - if (sadata->stream) - g_object_unref (sadata->stream); - if (sadata->original) - g_object_unref (sadata->original); + g_return_val_if_fail (!SOUP_IS_SESSION_ASYNC (session), NULL); - g_slice_free (SendAsyncData, sadata); + return soup_session_send (session, http->priv->msg, + cancellable, error); } + static void http_input_stream_ready_cb (GObject *source, GAsyncResult *result, gpointer user_data) { - SendAsyncData *sadata = user_data; + GTask *task = user_data; GError *error = NULL; GInputStream *stream; - stream = soup_session_send_request_finish (SOUP_SESSION (source), result, &error); - if (stream) { - g_simple_async_result_set_op_res_gpointer (sadata->simple, stream, g_object_unref); - } else { - g_simple_async_result_take_error (sadata->simple, error); - } - g_simple_async_result_complete (sadata->simple); - free_send_async_data (sadata); -} - - -static void -conditional_get_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) -{ - SendAsyncData *sadata = user_data; - GInputStream *stream; - - if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) { - SoupCache *cache = (SoupCache *)soup_session_get_feature (session, SOUP_TYPE_CACHE); - - stream = soup_cache_send_response (cache, sadata->original); - if (stream) { - g_simple_async_result_set_op_res_gpointer (sadata->simple, stream, g_object_unref); - - soup_message_got_headers (sadata->original); - - sadata->http->priv->content_type = g_strdup (soup_message_headers_get_content_type (msg->response_headers, NULL)); - - g_simple_async_result_complete (sadata->simple); - - soup_message_finished (sadata->original); - free_send_async_data (sadata); - return; - } - } - - /* The resource was modified or the server returned a 200 - * OK. Either way we reload it. This is far from optimal as - * we're donwloading the resource twice, but we will change it - * once the cache is integrated in the streams stack. - */ - soup_session_send_request_async (session, sadata->original, sadata->cancellable, - http_input_stream_ready_cb, sadata); -} - -static gboolean -idle_return_from_cache_cb (gpointer data) -{ - SendAsyncData *sadata = data; - - g_simple_async_result_set_op_res_gpointer (sadata->simple, - g_object_ref (sadata->stream), g_object_unref); - - /* Issue signals */ - soup_message_got_headers (sadata->http->priv->msg); - - sadata->http->priv->content_type = g_strdup (soup_message_headers_get_content_type (sadata->http->priv->msg->response_headers, NULL)); - - g_simple_async_result_complete (sadata->simple); - - soup_message_finished (sadata->http->priv->msg); - - free_send_async_data (sadata); - return FALSE; + stream = soup_session_send_finish (SOUP_SESSION (source), result, &error); + if (stream) + g_task_return_pointer (task, stream, g_object_unref); + else + g_task_return_error (task, error); + g_object_unref (task); } static void @@ -203,57 +134,14 @@ soup_request_http_send_async (SoupRequest *request, gpointer user_data) { SoupRequestHTTP *http = SOUP_REQUEST_HTTP (request); - SendAsyncData *sadata; - GInputStream *stream; - SoupSession *session; - SoupCache *cache; - - sadata = g_slice_new0 (SendAsyncData); - sadata->http = g_object_ref (http); - sadata->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - sadata->simple = g_simple_async_result_new (G_OBJECT (request), callback, user_data, - soup_request_http_send_async); - - session = soup_request_get_session (request); - cache = (SoupCache *)soup_session_get_feature (session, SOUP_TYPE_CACHE); - - if (cache) { - SoupCacheResponse response; - - response = soup_cache_has_response (cache, http->priv->msg); - if (response == SOUP_CACHE_RESPONSE_FRESH) { - stream = soup_cache_send_response (cache, http->priv->msg); - - /* Cached resource file could have been deleted outside */ - if (stream) { - /* Do return the stream asynchronously as in - * the other cases. It's not enough to use - * g_simple_async_result_complete_in_idle as - * the signals must be also emitted - * asynchronously - */ - sadata->stream = stream; - soup_add_completion (soup_session_get_async_context (session), - idle_return_from_cache_cb, sadata); - return; - } - } else if (response == SOUP_CACHE_RESPONSE_NEEDS_VALIDATION) { - SoupMessage *conditional_msg; - - conditional_msg = soup_cache_generate_conditional_request (cache, http->priv->msg); - - if (conditional_msg) { - sadata->original = g_object_ref (http->priv->msg); - soup_session_queue_message (session, conditional_msg, - conditional_get_ready_cb, - sadata); - return; - } - } - } + SoupSession *session = soup_request_get_session (request); + GTask *task; + + g_return_if_fail (!SOUP_IS_SESSION_SYNC (session)); - soup_session_send_request_async (session, http->priv->msg, cancellable, - http_input_stream_ready_cb, sadata); + task = g_task_new (request, cancellable, callback, user_data); + soup_session_send_async (session, http->priv->msg, cancellable, + http_input_stream_ready_cb, task); } static GInputStream * @@ -261,14 +149,9 @@ soup_request_http_send_finish (SoupRequest *request, GAsyncResult *result, GError **error) { - GSimpleAsyncResult *simple; - - g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (request), soup_request_http_send_async), NULL); + g_return_val_if_fail (g_task_is_valid (result, request), NULL); - simple = G_SIMPLE_ASYNC_RESULT (result); - if (g_simple_async_result_propagate_error (simple, error)) - return NULL; - return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); + return g_task_propagate_pointer (G_TASK (result), error); } static goffset @@ -342,7 +225,7 @@ soup_request_http_class_init (SoupRequestHTTPClass *request_http_class) * * Returns: (transfer full): a new reference to the #SoupMessage * - * Since: 2.34 + * Since: 2.40 */ SoupMessage * soup_request_http_get_message (SoupRequestHTTP *http) |