[gnome-online-accounts/wip/owncloud: 2/3] Add GoaHttpClient
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-online-accounts/wip/owncloud: 2/3] Add GoaHttpClient
- Date: Wed, 3 Oct 2012 23:12:42 +0000 (UTC)
commit 2bcd66c077e8a1e87fe7895034c94b2249269b64
Author: Debarshi Ray <debarshir gnome org>
Date: Thu Oct 4 00:26:21 2012 +0200
Add GoaHttpClient
Performs HTTP authentication to verify a username / password
combination. This will be used to check a user's ownCloud credentials.
Fixes: https://bugzilla.gnome.org/660573
src/goabackend/Makefile.am | 1 +
src/goabackend/goabackendtypes.h | 3 +
src/goabackend/goahttpclient.c | 277 ++++++++++++++++++++++++++++++++++++++
src/goabackend/goahttpclient.h | 59 ++++++++
4 files changed, 340 insertions(+), 0 deletions(-)
---
diff --git a/src/goabackend/Makefile.am b/src/goabackend/Makefile.am
index a000dc7..c10a4e6 100644
--- a/src/goabackend/Makefile.am
+++ b/src/goabackend/Makefile.am
@@ -70,6 +70,7 @@ libgoa_backend_1_0_la_SOURCES = \
goabackendenumtypes.h goabackendenumtypes.c \
goaeditablelabel.h goaeditablelabel.c \
goaewsclient.h goaewsclient.c \
+ goahttpclient.h goahttpclient.c \
goaprovider.h goaprovider.c \
goaexchangeprovider.h goaexchangeprovider.c \
goalogging.h goalogging.c \
diff --git a/src/goabackend/goabackendtypes.h b/src/goabackend/goabackendtypes.h
index af2cc7c..cc0460f 100644
--- a/src/goabackend/goabackendtypes.h
+++ b/src/goabackend/goabackendtypes.h
@@ -36,6 +36,9 @@ G_BEGIN_DECLS
struct _GoaEwsClient;
typedef struct _GoaEwsClient GoaEwsClient;
+struct _GoaHttpClient;
+typedef struct _GoaHttpClient GoaHttpClient;
+
struct _GoaProvider;
typedef struct _GoaProvider GoaProvider;
diff --git a/src/goabackend/goahttpclient.c b/src/goabackend/goahttpclient.c
new file mode 100644
index 0000000..21140f1
--- /dev/null
+++ b/src/goabackend/goahttpclient.c
@@ -0,0 +1,277 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#include "config.h"
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+
+#include <libsoup/soup.h>
+
+#include "goalogging.h"
+#include "goahttpclient.h"
+
+struct _GoaHttpClient
+{
+ GObject parent_instance;
+};
+
+typedef struct _GoaHttpClientClass GoaHttpClientClass;
+
+struct _GoaHttpClientClass
+{
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (GoaHttpClient, goa_http_client, G_TYPE_OBJECT);
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+goa_http_client_init (GoaHttpClient *client)
+{
+}
+
+static void
+goa_http_client_class_init (GoaHttpClientClass *klass)
+{
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+GoaHttpClient *
+goa_http_client_new (void)
+{
+ return GOA_HTTP_CLIENT (g_object_new (GOA_TYPE_HTTP_CLIENT, NULL));
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+ GCancellable *cancellable;
+ GSimpleAsyncResult *res;
+ SoupMessage *msg;
+ SoupSession *session;
+ gulong cancellable_id;
+} CheckData;
+
+typedef struct
+{
+ gchar *password;
+ gchar *username;
+} CheckAuthData;
+
+static void
+http_client_check_data_free (CheckData *data)
+{
+ if (data->cancellable_id > 0)
+ {
+ g_cancellable_disconnect (data->cancellable, data->cancellable_id);
+ g_object_unref (data->cancellable);
+ }
+
+ /* soup_session_queue_message stole the references to data->msg */
+ g_object_unref (data->res);
+ g_object_unref (data->session);
+ g_slice_free (CheckData, data);
+}
+
+static void
+http_client_check_auth_data_free (gpointer data, GClosure *closure)
+{
+ CheckAuthData *auth = data;
+
+ g_free (auth->password);
+ g_free (auth->username);
+ g_slice_free (CheckAuthData, auth);
+}
+
+static void
+http_client_authenticate (SoupSession *session,
+ SoupMessage *msg,
+ SoupAuth *auth,
+ gboolean retrying,
+ gpointer user_data)
+{
+ CheckAuthData *data = user_data;
+
+ if (retrying)
+ return;
+
+ soup_auth_authenticate (auth, data->username, data->password);
+}
+
+static void
+http_client_check_cancelled_cb (GCancellable *cancellable, gpointer user_data)
+{
+ CheckData *data = user_data;
+ soup_session_abort (data->session);
+}
+
+static void
+http_client_check_response_cb (SoupSession *session, SoupMessage *msg, gpointer user_data)
+{
+ GError *error;
+ CheckData *data = user_data;
+ gboolean op_res;
+
+ error = NULL;
+ op_res = FALSE;
+
+ if (msg->status_code == SOUP_STATUS_CANCELLED)
+ goto out;
+ else if (msg->status_code != SOUP_STATUS_OK)
+ {
+ g_set_error (&error,
+ GOA_ERROR,
+ GOA_ERROR_FAILED, /* TODO: more specific */
+ _("Code: %u - Unexpected response from server"),
+ msg->status_code);
+ goto out;
+ }
+
+ op_res = TRUE;
+
+ out:
+ g_simple_async_result_set_op_res_gboolean (data->res, op_res);
+ if (error != NULL)
+ g_simple_async_result_take_error (data->res, error);
+
+ g_simple_async_result_complete_in_idle (data->res);
+ http_client_check_data_free (data);
+}
+
+void
+goa_http_client_check (GoaHttpClient *client,
+ const gchar *uri,
+ const gchar *username,
+ const gchar *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ CheckData *data;
+ CheckAuthData *auth;
+
+ g_return_if_fail (GOA_IS_HTTP_CLIENT (client));
+ g_return_if_fail (uri != NULL || uri[0] != '\0');
+ g_return_if_fail (username != NULL || username[0] != '\0');
+ g_return_if_fail (password != NULL || password[0] != '\0');
+ g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+ data = g_slice_new0 (CheckData);
+ data->res = g_simple_async_result_new (G_OBJECT (client), callback, user_data, goa_http_client_check);
+ data->session = soup_session_async_new_with_options (SOUP_SESSION_USE_THREAD_CONTEXT, TRUE,
+ NULL);
+
+ data->msg = soup_message_new (SOUP_METHOD_GET, uri);
+ soup_message_headers_append (data->msg->request_headers, "Connection", "close");
+
+ if (cancellable != NULL)
+ {
+ data->cancellable = g_object_ref (cancellable);
+ data->cancellable_id = g_cancellable_connect (data->cancellable,
+ G_CALLBACK (http_client_check_cancelled_cb),
+ data,
+ NULL);
+ g_simple_async_result_set_check_cancellable (data->res, data->cancellable);
+ }
+
+ auth = g_slice_new0 (CheckAuthData);
+ auth->username = g_strdup (username);
+ auth->password = g_strdup (password);
+ g_signal_connect_data (data->session,
+ "authenticate",
+ G_CALLBACK (http_client_authenticate),
+ auth,
+ http_client_check_auth_data_free,
+ 0);
+
+ soup_session_queue_message (data->session, data->msg, http_client_check_response_cb, data);
+}
+
+gboolean
+goa_http_client_check_finish (GoaHttpClient *client, GAsyncResult *res, GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (res, G_OBJECT (client), goa_http_client_check), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (res);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ return g_simple_async_result_get_op_res_gboolean (simple);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+ GError **error;
+ GMainLoop *loop;
+ gboolean op_res;
+} CheckSyncData;
+
+static void
+http_client_check_sync_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ CheckSyncData *data = user_data;
+
+ data->op_res = goa_http_client_check_finish (GOA_HTTP_CLIENT (source_object), res, data->error);
+ g_main_loop_quit (data->loop);
+}
+
+gboolean
+goa_http_client_check_sync (GoaHttpClient *client,
+ const gchar *uri,
+ const gchar *username,
+ const gchar *password,
+ GCancellable *cancellable,
+ GError **error)
+{
+ CheckSyncData data;
+ GMainContext *context = NULL;
+
+ data.error = error;
+
+ context = g_main_context_new ();
+ g_main_context_push_thread_default (context);
+ data.loop = g_main_loop_new (context, FALSE);
+
+ goa_http_client_check (client,
+ uri,
+ username,
+ password,
+ cancellable,
+ http_client_check_sync_cb,
+ &data);
+ g_main_loop_run (data.loop);
+ g_main_loop_unref (data.loop);
+
+ g_main_context_pop_thread_default (context);
+ g_main_context_unref (context);
+
+ return data.op_res;
+}
diff --git a/src/goabackend/goahttpclient.h b/src/goabackend/goahttpclient.h
new file mode 100644
index 0000000..0e46f94
--- /dev/null
+++ b/src/goabackend/goahttpclient.h
@@ -0,0 +1,59 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Debarshi Ray <debarshir gnome org>
+ */
+
+#if !defined (__GOA_BACKEND_INSIDE_GOA_BACKEND_H__) && !defined (GOA_BACKEND_COMPILATION)
+#error "Only <goabackend/goabackend.h> can be included directly."
+#endif
+
+#ifndef __GOA_HTTP_CLIENT_H__
+#define __GOA_HTTP_CLIENT_H__
+
+#include <goabackend/goabackendtypes.h>
+
+G_BEGIN_DECLS
+
+#define GOA_TYPE_HTTP_CLIENT (goa_http_client_get_type ())
+#define GOA_HTTP_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GOA_TYPE_HTTP_CLIENT, GoaHttpClient))
+#define GOA_IS_HTTP_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GOA_TYPE_HTTP_CLIENT))
+
+GType goa_http_client_get_type (void) G_GNUC_CONST;
+GoaHttpClient *goa_http_client_new (void);
+void goa_http_client_check (GoaHttpClient *client,
+ const gchar *uri,
+ const gchar *username,
+ const gchar *password,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer gpointer);
+gboolean goa_http_client_check_finish (GoaHttpClient *client,
+ GAsyncResult *res,
+ GError **error);
+gboolean goa_http_client_check_sync (GoaHttpClient *client,
+ const gchar *uri,
+ const gchar *username,
+ const gchar *password,
+ GCancellable *cancellable,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __GOA_EWS_CLIENT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]