[couchdb-glib: 9/21] This commit makes everything compile again - but there is still
- From: Mikkel Kamstrup Erlandsen <kamstrup src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [couchdb-glib: 9/21] This commit makes everything compile again - but there is still
- Date: Wed, 7 Oct 2009 18:56:23 +0000 (UTC)
commit 1722eface5457bf75aca0e52fa97be180c1b2a15
Author: Mikkel Kamstrup Erlandsen <mikkel kamstrup gmail com>
Date: Mon Oct 5 00:34:28 2009 +0200
This commit makes everything compile again - but there is still
quite some cleanup needed. There are some notable source
code changes:
- Make the object struct of CouchDBDocument privately declared
- Add a public method to CouchDBDocument, get_json_object(),
other code used lots of refs to the now private root_node
JSonObject member
- Make all object struct declarations private. Since lots of code
assumed access to CouchDBDocument->root_node, add a new public
accessor couchdb_document_get_json_object() and use this where
needed
- Don't make the CouchDB struct declaration depennd on whether OAUTH
is configured. We always keep the oauth members around, using stub
values when necessary.
- Add new method couchdb_is_oauth_enabled()
- Remove the method send_message_and_parse() from util.* and add a
variant of it as public method on the CouchDB class,
couchdb_send_message(). This method takes the JsonParser as param
to allow external reuse of the parser. Update all refs to the
removed util-method
- Fix some refs to private member coucdb->hostname, and use
couchdb_get_hostname() instead
NOTES.kamstrup | 8 +
couchdb-glib/couchdb-document-contact.c | 20 ++--
couchdb-glib/couchdb-document.c | 39 +++--
couchdb-glib/couchdb-document.h | 3 +
couchdb-glib/couchdb.c | 238 +++++++++++++++++++++++++-----
couchdb-glib/couchdb.h | 5 +
couchdb-glib/dbwatch.c | 14 +-
couchdb-glib/dbwatch.h | 2 +
couchdb-glib/utils.c | 144 -------------------
couchdb-glib/utils.h | 6 -
10 files changed, 257 insertions(+), 222 deletions(-)
---
diff --git a/NOTES.kamstrup b/NOTES.kamstrup
index 265fb67..d936659 100644
--- a/NOTES.kamstrup
+++ b/NOTES.kamstrup
@@ -1,3 +1,11 @@
+TODO:
+Move typedefs to couchdb-types.h
+
+In couchdb.*:
+ * Don't make API depend on whether we are configured with OAUTH
+ * Move OAUTH related functionality from util.* here
+ * New method couchdb_send_message() replacing send_message_and_parse() from util.*
+
In couchdb-document.c:
* Change refs to internal API of CouchDB object's ->hostname to method calls
* Change refs to internal API of CouchDBStructField ->json_object to use method call
diff --git a/couchdb-glib/couchdb-document-contact.c b/couchdb-glib/couchdb-document-contact.c
index 4e9857e..2950570 100644
--- a/couchdb-glib/couchdb-document-contact.c
+++ b/couchdb-glib/couchdb-document-contact.c
@@ -337,7 +337,7 @@ couchdb_document_contact_get_email_addresses (CouchDBDocument *document)
g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
addresses_json = json_object_get_object_member (
- json_node_get_object (document->root_node), "email_addresses");;
+ couchdb_document_get_json_object (document), "email_addresses");;
if (addresses_json) {
json_object_foreach_member (addresses_json,
(JsonObjectForeach) foreach_object_cb,
@@ -375,7 +375,7 @@ couchdb_document_contact_set_email_addresses (CouchDBDocument *document, GSList
}
}
- json_object_set_object_member (json_node_get_object (document->root_node), "email_addresses", addresses_json);
+ json_object_set_object_member (couchdb_document_get_json_object (document), "email_addresses", addresses_json);
}
GSList *
@@ -388,7 +388,7 @@ couchdb_document_contact_get_phone_numbers (CouchDBDocument *document)
g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
phone_numbers = json_object_get_object_member (
- json_node_get_object (document->root_node), "phone_numbers");
+ couchdb_document_get_json_object (document), "phone_numbers");
if (phone_numbers) {
json_object_foreach_member (phone_numbers,
(JsonObjectForeach) foreach_object_cb,
@@ -428,7 +428,7 @@ couchdb_document_contact_set_phone_numbers (CouchDBDocument *document, GSList *l
}
}
- json_object_set_object_member (json_node_get_object (document->root_node), "phone_numbers", phone_numbers);
+ json_object_set_object_member (couchdb_document_get_json_object (document), "phone_numbers", phone_numbers);
}
GSList *
@@ -441,7 +441,7 @@ couchdb_document_contact_get_addresses (CouchDBDocument *document)
g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
addresses = json_object_get_object_member (
- json_node_get_object (document->root_node), "addresses");
+ couchdb_document_get_json_object (document), "addresses");
if (addresses) {
json_object_foreach_member (addresses,
(JsonObjectForeach) foreach_object_cb,
@@ -489,7 +489,7 @@ couchdb_document_contact_set_addresses (CouchDBDocument *document, GSList *list)
}
}
- json_object_set_object_member (json_node_get_object (document->root_node), "addresses", addresses);
+ json_object_set_object_member (couchdb_document_get_json_object (document), "addresses", addresses);
}
GSList *
@@ -502,7 +502,7 @@ couchdb_document_contact_get_im_addresses (CouchDBDocument *document)
g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
im_addresses = json_object_get_object_member (
- json_node_get_object (document->root_node), "im_addresses");
+ couchdb_document_get_json_object (document), "im_addresses");
if (im_addresses != NULL) {
json_object_foreach_member (im_addresses,
(JsonObjectForeach) foreach_object_cb,
@@ -542,7 +542,7 @@ couchdb_document_contact_set_im_addresses (CouchDBDocument *document, GSList *li
}
}
- json_object_set_object_member (json_node_get_object (document->root_node), "im_addresses", im_addresses_json);
+ json_object_set_object_member (couchdb_document_get_json_object (document), "im_addresses", im_addresses_json);
}
GSList *
@@ -555,7 +555,7 @@ couchdb_document_contact_get_urls (CouchDBDocument *document)
g_return_val_if_fail (couchdb_document_is_contact (document), NULL);
urls = json_object_get_object_member (
- json_node_get_object (document->root_node), "urls");
+ couchdb_document_get_json_object (document), "urls");
if (urls) {
json_object_foreach_member (urls,
(JsonObjectForeach) foreach_object_cb,
@@ -593,7 +593,7 @@ couchdb_document_contact_set_urls (CouchDBDocument *document, GSList *list)
}
}
- json_object_set_object_member (json_node_get_object (document->root_node), "urls", urls_json);
+ json_object_set_object_member (couchdb_document_get_json_object (document), "urls", urls_json);
}
const char *
diff --git a/couchdb-glib/couchdb-document.c b/couchdb-glib/couchdb-document.c
index 20356e3..1a856a5 100644
--- a/couchdb-glib/couchdb-document.c
+++ b/couchdb-glib/couchdb-document.c
@@ -1,8 +1,10 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
+ * 2009 Mikkel Kamstrup Erlandsen
*
* Authors: Rodrigo Moya <rodrigo moya canonical com>
+ * Mikkel Kamstrup Erlandsen <mikkel kamstrup gmail com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU Lesser General Public
@@ -94,16 +96,15 @@ couchdb_document_get (CouchDB *couchdb,
encoded_docid = soup_uri_encode (docid, NULL);
url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (couchdb), dbname, encoded_docid);
- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
- if (parser) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
document = g_object_new (COUCHDB_TYPE_DOCUMENT, NULL);
document->couchdb = couchdb;
document->dbname = g_strdup (dbname);
- document->root_node = json_node_copy (json_parser_get_root (parser));
- g_object_unref (G_OBJECT (parser));
+ document->root_node = json_node_copy (json_parser_get_root (parser));
}
-
+ g_object_unref (G_OBJECT (parser));
g_free (encoded_docid);
g_free (url);
@@ -119,34 +120,34 @@ couchdb_document_put (CouchDBDocument *document,
const char *id;
JsonParser *parser;
gboolean result = FALSE;
+ gboolean send_ok;;
g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), FALSE);
g_return_val_if_fail (dbname != NULL, FALSE);
id = couchdb_document_get_id (document);
body = couchdb_document_to_string (document);
+ parser = json_parser_new ();
if (id) {
char *encoded_docid;
encoded_docid = soup_uri_encode (id, NULL);
- url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (document->couchdb), dbname, encoded_docid);
- parser = send_message_and_parse (document->couchdb, SOUP_METHOD_PUT, url, body, error);
+ url = g_strdup_printf ("%s/%s/%s", couchdb_get_hostname (document->couchdb), dbname, encoded_docid);
+ send_ok = couchdb_send_message (document->couchdb, SOUP_METHOD_PUT, url, body, parser, error);
g_free (encoded_docid);
} else {
url = g_strdup_printf ("%s/%s/", couchdb_get_hostname (document->couchdb), dbname);
- parser = send_message_and_parse (document->couchdb, SOUP_METHOD_POST, url, body, error);
+ send_ok = couchdb_send_message (document->couchdb, SOUP_METHOD_POST, url, body, parser, error);
}
- if (parser) {
+ if (send_ok) {
JsonObject *object;
object = json_node_get_object (json_parser_get_root (parser));
couchdb_document_set_id (document, json_object_get_string_member (object, "id"));
couchdb_document_set_revision (document, json_object_get_string_member (object, "rev"));
- g_object_unref (G_OBJECT (parser));
-
if (document->dbname) {
g_free (document->dbname);
document->dbname = g_strdup (dbname);
@@ -163,6 +164,7 @@ couchdb_document_put (CouchDBDocument *document,
/* free memory */
g_free (url);
g_free (body);
+ g_object_unref (G_OBJECT (parser));
return result;
}
@@ -183,10 +185,9 @@ couchdb_document_delete (CouchDBDocument *document, GError **error)
return FALSE;
url = g_strdup_printf ("%s/%s/%s?rev=%s", couchdb_get_hostname (document->couchdb), document->dbname, id, revision);
- parser = send_message_and_parse (document->couchdb, SOUP_METHOD_DELETE, url, NULL, error);
- if (parser) {
- g_object_unref (G_OBJECT (parser));
-
+
+ /* We don't parse the http response, therefore the parser arg is NULL */
+ if (couchdb_send_message (document->couchdb, SOUP_METHOD_DELETE, url, NULL, NULL, error)) {
g_signal_emit_by_name (document->couchdb, "document_deleted", document->dbname, id);
}
@@ -458,3 +459,11 @@ couchdb_document_to_string (CouchDBDocument *document)
return NULL;
}
+
+JsonObject *
+couchdb_document_get_json_object (CouchDBDocument *document)
+{
+ g_return_val_if_fail (COUCHDB_IS_DOCUMENT (document), NULL);
+
+ return json_node_get_object (document->root_node);
+}
diff --git a/couchdb-glib/couchdb-document.h b/couchdb-glib/couchdb-document.h
index c86c24b..cacec47 100644
--- a/couchdb-glib/couchdb-document.h
+++ b/couchdb-glib/couchdb-document.h
@@ -26,6 +26,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <json-glib/json-glib.h>
#include "couchdb-types.h"
#include "couchdb-struct-field.h"
@@ -126,6 +127,8 @@ void couchdb_document_set_application_annotations
char* couchdb_document_to_string (CouchDBDocument *document);
+JsonObject* couchdb_document_get_json_object (CouchDBDocument *document);
+
G_END_DECLS
#endif /* __COUCHDB_DOCUMENT_H__ */
diff --git a/couchdb-glib/couchdb.c b/couchdb-glib/couchdb.c
index 018591b..ced3442 100644
--- a/couchdb-glib/couchdb.c
+++ b/couchdb-glib/couchdb.c
@@ -1,8 +1,10 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2009 Canonical Services Ltd (www.canonical.com)
+ * 2009 Mikkel Kamstrup Erlandsen
*
* Authors: Rodrigo Moya <rodrigo moya canonical com>
+ * Mikkel Kamstrup Erlandsen <mikkel kamstrup gmail com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU Lesser General Public
@@ -21,12 +23,17 @@
#include <libsoup/soup-logger.h>
#include <libsoup/soup-gnome.h>
-#include <json-glib/json-glib.h>
+#include <libsoup/soup-message.h>
#include "couchdb.h"
#include "couchdb-document-info.h"
#include "couchdb-marshal.h"
#include "dbwatch.h"
#include "utils.h"
+#include <string.h>
+#ifdef HAVE_OAUTH
+#include <time.h>
+#include "oauth.h"
+#endif
struct _CouchDB {
GObject parent;
@@ -36,16 +43,11 @@ struct _CouchDB {
GHashTable *db_watchlist;
- /* COMMENT:
- * Our ABI now depends on OAUTH config - here be dragons! //kamstrup
- */
- #ifdef HAVE_OAUTH
- gboolean oauth_enabled;
- char *oauth_consumer_key;
- char *oauth_consumer_secret;
- char *oauth_token_key;
- char *oauth_token_secret;
- #endif
+ gboolean oauth_enabled;
+ char *oauth_consumer_key;
+ char *oauth_consumer_secret;
+ char *oauth_token_key;
+ char *oauth_token_secret;
};
G_DEFINE_TYPE(CouchDB, couchdb, G_TYPE_OBJECT)
@@ -70,12 +72,14 @@ couchdb_finalize (GObject *object)
g_free (couchdb->hostname);
g_object_unref (couchdb->http_session);
-#ifdef HAVE_OAUTH
- g_free (couchdb->oauth_consumer_key);
- g_free (couchdb->oauth_consumer_secret);
- g_free (couchdb->oauth_token_key);
- g_free (couchdb->oauth_token_secret);
-#endif
+ if (couchdb->oauth_consumer_key)
+ g_free (couchdb->oauth_consumer_key);
+ if (couchdb->oauth_consumer_secret)
+ g_free (couchdb->oauth_consumer_secret);
+ if (couchdb->oauth_token_key)
+ g_free (couchdb->oauth_token_key);
+ if (couchdb->oauth_token_secret)
+ g_free (couchdb->oauth_token_secret);
G_OBJECT_CLASS (couchdb_parent_class)->finalize (object);
}
@@ -156,6 +160,13 @@ couchdb_new (const char *hostname)
couchdb->http_session = soup_session_sync_new_with_options (
SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
NULL);
+
+ couchdb->oauth_consumer_key = NULL;
+ couchdb->oauth_consumer_secret = NULL;
+ couchdb->oauth_token_key = NULL;
+ couchdb->oauth_token_secret = NULL;
+ couchdb->oauth_enabled = FALSE;
+
soup_session_add_feature_by_type (couchdb->http_session, SOUP_TYPE_LOGGER);
return couchdb;
@@ -180,8 +191,8 @@ couchdb_list_databases (CouchDB *couchdb, GError **error)
/* Prepare request */
url = g_strdup_printf ("%s/_all_dbs", couchdb->hostname);
- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
- if (parser) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
JsonNode *root_node;
root_node = json_parser_get_root (parser);
@@ -194,10 +205,9 @@ couchdb_list_databases (CouchDB *couchdb, GError **error)
dblist,
g_strdup (json_node_get_string ((JsonNode *) sl->data)));
}
- }
-
- g_object_unref (G_OBJECT (parser));
+ }
}
+ g_object_unref (G_OBJECT (parser));
/* Free memory */
g_free (url);
@@ -216,8 +226,8 @@ couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error)
g_return_val_if_fail (dbname != NULL, NULL);
url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
- if (parser) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
JsonNode *root_node;
root_node = json_parser_get_root (parser);
@@ -231,9 +241,8 @@ couchdb_get_database_info (CouchDB *couchdb, const char *dbname, GError **error)
json_object_get_boolean_member (object, "compact_running"),
json_object_get_int_member (object, "disk_size"));
}
-
- g_object_unref (G_OBJECT (parser));
}
+ g_object_unref (G_OBJECT (parser));
return result;
}
@@ -249,18 +258,17 @@ couchdb_create_database (CouchDB *couchdb, const char *dbname, GError **error)
g_return_val_if_fail (dbname != NULL, FALSE);
url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
- parser = send_message_and_parse (couchdb, SOUP_METHOD_PUT, url, NULL, error);
- if (parser) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (couchdb, SOUP_METHOD_PUT, url, NULL, parser, error)) {
JsonNode *root_node;
root_node = json_parser_get_root (parser);
if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)
result = json_object_get_boolean_member (
- json_node_get_object (root_node), "ok");
-
- g_object_unref (G_OBJECT (parser));
+ json_node_get_object (root_node), "ok");
}
-
+
+ g_object_unref (G_OBJECT (parser));
g_free (url);
if (result)
@@ -280,17 +288,16 @@ couchdb_delete_database (CouchDB *couchdb, const char *dbname, GError **error)
g_return_val_if_fail (dbname != NULL, FALSE);
url = g_strdup_printf ("%s/%s/", couchdb->hostname, dbname);
- parser = send_message_and_parse (couchdb, SOUP_METHOD_DELETE, url, NULL, error);
- if (parser) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (couchdb, SOUP_METHOD_DELETE, url, NULL, parser, error)) {
JsonNode *root_node;
root_node = json_parser_get_root (parser);
if (json_node_get_node_type (root_node) == JSON_NODE_OBJECT)
result = json_object_get_boolean_member (
- json_node_get_object (root_node), "ok");
-
- g_object_unref (G_OBJECT (parser));
+ json_node_get_object (root_node), "ok");
}
+ g_object_unref (G_OBJECT (parser));
g_free (url);
@@ -325,8 +332,8 @@ couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error)
g_return_val_if_fail (dbname != NULL, NULL);
url = g_strdup_printf ("%s/%s/_all_docs", couchdb->hostname, dbname);
- parser = send_message_and_parse (couchdb, SOUP_METHOD_GET, url, NULL, error);
- if (parser) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (couchdb, SOUP_METHOD_GET, url, NULL, parser, error)) {
JsonNode *root_node;
root_node = json_parser_get_root (parser);
@@ -353,7 +360,7 @@ couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error)
}
}
}
-
+ g_object_unref (G_OBJECT (parser));
g_free (url);
return doclist;
@@ -444,3 +451,154 @@ couchdb_enable_oauth (CouchDB *couchdb,
return FALSE;
#endif
}
+
+gboolean
+couchdb_is_oauth_enabled (CouchDB *couchdb)
+{
+ g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
+
+ return couchdb->oauth_enabled;
+}
+
+
+static void
+couchdb_add_oauth_signature (CouchDB *couchdb, SoupMessage *http_message, const char *method, const char *url)
+{
+ /* This method is a no-op if we are configured without OAUTH */
+#ifdef HAVE_OAUTH
+ char *signed_url;
+
+ signed_url = oauth_sign_url2 (url, NULL, OA_HMAC, method,
+ couchdb->oauth_consumer_key,
+ couchdb->oauth_consumer_secret,
+ couchdb->oauth_token_key,
+ couchdb->oauth_token_secret);
+ if (signed_url != NULL) {
+ char **parsed_url;
+ GString *header = NULL;
+
+ /* Get the OAuth signature from the signed URL */
+ parsed_url = g_strsplit (signed_url, "?", 2);
+ if (parsed_url != NULL) {
+ gchar **params;
+ int i;
+
+ params = g_strsplit (parsed_url[1], "&", 0);
+#ifdef DEBUG_OAUTH
+ g_debug ("Parsing %s", parsed_url[1]);
+#endif
+ for (i = 0; params[i] != NULL; i++) {
+ gchar **url_param;
+
+#ifdef DEBUG_OAUTH
+ g_debug ("%s\n", params[i]);
+#endif
+ url_param = g_strsplit (params[i], "=", 2);
+ if (url_param == NULL)
+ continue;
+
+ if (header != NULL)
+ header = g_string_append (header, ", ");
+ else
+ header = g_string_new ("OAuth ");
+
+ header = g_string_append (header, url_param[0]);
+ header = g_string_append (header, "=\"");
+ header = g_string_append (header, url_param[1]);
+ header = g_string_append (header, "\"");
+
+ g_strfreev (url_param);
+ }
+
+ if (params)
+ g_strfreev (params);
+
+ g_strfreev (parsed_url);
+ }
+
+ if (header != NULL) {
+ soup_message_headers_append (http_message->request_headers, "Authorization", header->str);
+
+ g_string_free (header, TRUE);
+ }
+
+ free (signed_url);
+ }
+#endif /* HAVE_OAUTH */
+}
+
+static gboolean
+parse_json_response (CouchDB *couchdb, JsonParser *json_parser, SoupMessage *http_message, GError **error)
+{
+ SoupBuffer *buffer;
+ GString *str = NULL;
+ goffset offset = 0;
+ gboolean success = TRUE;
+
+ while ((buffer = soup_message_body_get_chunk (http_message->response_body, offset))) {
+ if (!str)
+ str = g_string_new ("");
+ g_string_append_len (str, buffer->data, buffer->length);
+
+ offset += buffer->length;
+ soup_buffer_free (buffer);
+ }
+
+ if (str && str->len > 0) {
+ g_debug ("Response body: %s", str->str);
+ if (!json_parser_load_from_data (json_parser,
+ (const gchar *) str->str,
+ str->len,
+ error)) {
+ g_object_unref (G_OBJECT (json_parser));
+ g_set_error (error, COUCHDB_ERROR, -1, "Invalid JSON response");
+ success = FALSE;
+ }
+
+ g_string_free (str, TRUE);
+ }
+
+ return success;
+}
+
+static void
+debug_print_headers (const char *name, const char *value, gpointer user_data)
+{
+ g_print ("\t%s: %s\n", name, value);
+}
+
+gboolean
+couchdb_send_message (CouchDB *couchdb, const char *method, const char *url, const char *body, JsonParser *parser, GError **error)
+{
+ SoupMessage *http_message;
+ guint status;
+
+ g_return_val_if_fail (COUCHDB_IS (couchdb), FALSE);
+ g_return_val_if_fail (method != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ http_message = soup_message_new (method, url);
+ if (body != NULL) {
+ soup_message_set_request (http_message, "application/json", SOUP_MEMORY_COPY,
+ body, strlen (body));
+ }
+
+ if (couchdb_is_oauth_enabled (couchdb))
+ couchdb_add_oauth_signature (couchdb, http_message, method, url);
+
+
+ g_debug ("Sending %s to %s... with headers\n: ", method, url);
+ soup_message_headers_foreach (http_message->request_headers,
+ (SoupMessageHeadersForeachFunc) debug_print_headers,
+ NULL);
+
+ status = soup_session_send_message (couchdb->http_session, http_message);
+ if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
+ if (parser != NULL)
+ parse_json_response (couchdb, parser, http_message, error);
+ return TRUE;
+ } else {
+ g_set_error (error, COUCHDB_ERROR, status, "%s", http_message->reason_phrase);
+ return FALSE;
+ }
+}
diff --git a/couchdb-glib/couchdb.h b/couchdb-glib/couchdb.h
index 63011eb..e87bd99 100644
--- a/couchdb-glib/couchdb.h
+++ b/couchdb-glib/couchdb.h
@@ -26,6 +26,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <json-glib/json-glib.h>
#include "couchdb-types.h"
#include "couchdb-database-info.h"
@@ -71,6 +72,10 @@ gboolean couchdb_enable_oauth (CouchDB *couchdb,
const char *token_secret);
void couchdb_disable_oauth (CouchDB *couchdb);
+gboolean couchdb_is_oauth_enabled (CouchDB *couchdb);
+
+gboolean couchdb_send_message (CouchDB *couchdb, const char *method, const char *url, const char *body, JsonParser *parser, GError **error);
+
GSList *couchdb_list_documents (CouchDB *couchdb, const char *dbname, GError **error);
void couchdb_free_document_list (GSList *doclist);
diff --git a/couchdb-glib/dbwatch.c b/couchdb-glib/dbwatch.c
index bb9adc0..dc20f50 100644
--- a/couchdb-glib/dbwatch.c
+++ b/couchdb-glib/dbwatch.c
@@ -19,7 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
-#include "couchdb-glib.h"
+#include <libsoup/soup-method.h>
+#include "couchdb-document.h"
#include "dbwatch.h"
#include "utils.h"
@@ -78,11 +79,11 @@ watch_timeout_cb (gpointer user_data)
DBWatch *watch = (DBWatch *) user_data;
url = g_strdup_printf ("%s/%s/_changes?since=%d",
- watch->couchdb->hostname,
+ couchdb_get_hostname (watch->couchdb),
watch->dbname,
watch->last_update_seq);
- parser = send_message_and_parse (watch->couchdb, SOUP_METHOD_GET, url, NULL, &error);
- if (parser != NULL) {
+ parser = json_parser_new ();
+ if (couchdb_send_message (watch->couchdb, SOUP_METHOD_GET, url, NULL, parser, &error)) {
JsonNode *root_node;
root_node = json_parser_get_root (parser);
@@ -102,12 +103,11 @@ watch_timeout_cb (gpointer user_data)
if (json_object_has_member (root_object, "last_seq"))
watch->last_update_seq = json_object_get_int_member (root_object, "last_seq");
- }
-
- g_object_unref (G_OBJECT (parser));
+ }
}
/* Free memory */
+ g_object_unref (G_OBJECT (parser));
g_free (url);
}
diff --git a/couchdb-glib/dbwatch.h b/couchdb-glib/dbwatch.h
index 7c1e056..24d59bd 100644
--- a/couchdb-glib/dbwatch.h
+++ b/couchdb-glib/dbwatch.h
@@ -22,6 +22,8 @@
#ifndef __DBWATCH_H__
#define __DBWATCH_H__
+#include <glib.h>
+#include "couchdb.h"
#include "utils.h"
typedef struct {
diff --git a/couchdb-glib/utils.c b/couchdb-glib/utils.c
index fce7aa0..296be5e 100644
--- a/couchdb-glib/utils.c
+++ b/couchdb-glib/utils.c
@@ -24,46 +24,6 @@
#include <libsoup/soup-session-async.h>
#include "couchdb-glib.h"
#include "utils.h"
-#ifdef HAVE_OAUTH
-#include <time.h>
-#include "oauth.h"
-#endif
-
-static JsonParser *
-parse_json_response (SoupMessage *http_message, GError **error)
-{
- SoupBuffer *buffer;
- GString *str = NULL;
- goffset offset = 0;
- JsonParser *json_parser = NULL;
-
- while ((buffer = soup_message_body_get_chunk (http_message->response_body, offset))) {
- if (!str)
- str = g_string_new ("");
- g_string_append_len (str, buffer->data, buffer->length);
-
- offset += buffer->length;
- soup_buffer_free (buffer);
- }
-
- if (str && str->len > 0) {
- g_debug ("Response body: %s", str->str);
- json_parser = json_parser_new ();
- if (!json_parser_load_from_data (json_parser,
- (const gchar *) str->str,
- str->len,
- error)) {
- g_object_unref (G_OBJECT (json_parser));
- json_parser = NULL;
-
- g_set_error (error, COUCHDB_ERROR, -1, "Invalid JSON response");
- }
-
- g_string_free (str, TRUE);
- }
-
- return json_parser;
-}
GQuark
couchdb_error_quark (void)
@@ -76,110 +36,6 @@ couchdb_error_quark (void)
return error;
}
-#ifdef HAVE_OAUTH
-static void
-add_oauth_signature (CouchDB *couchdb, SoupMessage *http_message, const char *method, const char *url)
-{
- char *signed_url;
-
- signed_url = oauth_sign_url2 (url, NULL, OA_HMAC, method,
- couchdb->oauth_consumer_key,
- couchdb->oauth_consumer_secret,
- couchdb->oauth_token_key,
- couchdb->oauth_token_secret);
- if (signed_url != NULL) {
- char **parsed_url;
- GString *header = NULL;
-
- /* Get the OAuth signature from the signed URL */
- parsed_url = g_strsplit (signed_url, "?", 2);
- if (parsed_url != NULL) {
- gchar **params;
- int i;
-
- params = g_strsplit (parsed_url[1], "&", 0);
-#ifdef DEBUG_OAUTH
- g_debug ("Parsing %s", parsed_url[1]);
-#endif
- for (i = 0; params[i] != NULL; i++) {
- gchar **url_param;
-
-#ifdef DEBUG_OAUTH
- g_debug ("%s\n", params[i]);
-#endif
- url_param = g_strsplit (params[i], "=", 2);
- if (url_param == NULL)
- continue;
-
- if (header != NULL)
- header = g_string_append (header, ", ");
- else
- header = g_string_new ("OAuth ");
-
- header = g_string_append (header, url_param[0]);
- header = g_string_append (header, "=\"");
- header = g_string_append (header, url_param[1]);
- header = g_string_append (header, "\"");
-
- g_strfreev (url_param);
- }
-
- if (params)
- g_strfreev (params);
-
- g_strfreev (parsed_url);
- }
-
- if (header != NULL) {
- soup_message_headers_append (http_message->request_headers, "Authorization", header->str);
-
- g_string_free (header, TRUE);
- }
-
- free (signed_url);
- }
-}
-#endif
-
-static void
-debug_print_headers (const char *name, const char *value, gpointer user_data)
-{
- g_print ("\t%s: %s\n", name, value);
-}
-
-JsonParser *
-send_message_and_parse (CouchDB *couchdb, const char *method, const char *url, const char *body, GError **error)
-{
- SoupMessage *http_message;
- guint status;
- JsonParser *parser = NULL;
-
- http_message = soup_message_new (method, url);
- if (body != NULL) {
- soup_message_set_request (http_message, "application/json", SOUP_MEMORY_COPY,
- body, strlen (body));
- }
-
-#ifdef HAVE_OAUTH
- if (couchdb->oauth_enabled)
- add_oauth_signature (couchdb, http_message, method, url);
-#endif
-
- g_debug ("Sending %s to %s... with headers\n: ", method, url);
- soup_message_headers_foreach (http_message->request_headers,
- (SoupMessageHeadersForeachFunc) debug_print_headers,
- NULL);
-
- status = soup_session_send_message (couchdb->http_session, http_message);
- if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
- parser = parse_json_response (http_message, error);
- } else {
- g_set_error (error, COUCHDB_ERROR, status, "%s", http_message->reason_phrase);
- }
-
- return parser;
-}
-
char *
generate_uuid (void)
{
diff --git a/couchdb-glib/utils.h b/couchdb-glib/utils.h
index 2b8f8f1..94e6bcd 100644
--- a/couchdb-glib/utils.h
+++ b/couchdb-glib/utils.h
@@ -30,12 +30,6 @@
#define COUCHDB_ERROR couchdb_error_quark()
GQuark couchdb_error_quark (void);
-JsonParser* send_message_and_parse (CouchDB *couchdb,
- const char *method,
- const char *url,
- const char *body,
- GError **error);
-
char* generate_uuid (void);
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]