summaryrefslogtreecommitdiff
path: root/libsoup/soup-request-http.c
diff options
context:
space:
mode:
Diffstat (limited to 'libsoup/soup-request-http.c')
-rw-r--r--libsoup/soup-request-http.c191
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)