gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-sync] branch master updated: implement sync_api_download


From: gnunet
Subject: [taler-sync] branch master updated: implement sync_api_download
Date: Sun, 24 Nov 2019 22:34:00 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository sync.

The following commit(s) were added to refs/heads/master by this push:
     new fc9d4a9  implement sync_api_download
fc9d4a9 is described below

commit fc9d4a99a1488a6313f661258e455fb8f443a4d1
Author: Christian Grothoff <address@hidden>
AuthorDate: Sun Nov 24 22:33:58 2019 +0100

    implement sync_api_download
---
 src/include/sync_service.h  |  22 ++++-
 src/lib/Makefile.am         |   1 +
 src/lib/sync_api_download.c | 221 +++++++++++++++++++++++++++++++++++++++++++-
 src/sync/sync-httpd_mhd.c   |   2 +-
 4 files changed, 238 insertions(+), 8 deletions(-)

diff --git a/src/include/sync_service.h b/src/include/sync_service.h
index 47dfdb4..e0651f2 100644
--- a/src/include/sync_service.h
+++ b/src/include/sync_service.h
@@ -262,6 +262,21 @@ void
 SYNC_upload_cancel (struct SYNC_UploadOperation *uo);
 
 
+struct SYNC_DownloadDetails
+{
+
+  struct SYNC_AccountSignatureP sig;
+
+  struct GNUNET_HashCode prev_backup_hash;
+
+  struct GNUNET_HashCode curr_backup_hash;
+
+  const void *backup;
+
+  size_t backup_size;
+
+};
+
 /**
  * Function called with the results of a #SYNC_download().
  *
@@ -278,11 +293,8 @@ SYNC_upload_cancel (struct SYNC_UploadOperation *uo);
  */
 typedef void
 (*SYNC_DownloadCallback)(void *cls,
-                         const struct SYNC_AccountPublicKeyP *sig,
-                         const struct GNUNET_HashCode *prev_backup_hash,
-                         const struct GNUNET_HashCode *curr_backup_hash,
-                         size_t backup_size,
-                         const void *backup);
+                         unsigned int http_status,
+                         const struct SYNC_DownloadDetails *dd);
 
 
 /**
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index b1b1d92..20ceab4 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -14,6 +14,7 @@ libsync_la_LDFLAGS = \
   -no-undefined
 
 libsync_la_SOURCES = \
+  sync_api_curl_defaults.c sync_api_curl_defaults.h \
   sync_api_download.c \
   sync_api_upload.c 
 
diff --git a/src/lib/sync_api_download.c b/src/lib/sync_api_download.c
index e9780e1..a8750c1 100644
--- a/src/lib/sync_api_download.c
+++ b/src/lib/sync_api_download.c
@@ -28,7 +28,9 @@
 #include <microhttpd.h> /* just for HTTP status codes */
 #include <gnunet/gnunet_util_lib.h>
 #include <gnunet/gnunet_curl_lib.h>
+#include <taler/taler_signatures.h>
 #include "sync_service.h"
+#include "sync_api_curl_defaults.h"
 
 
 /**
@@ -62,9 +64,186 @@ struct SYNC_DownloadOperation
    */
   void *cb_cls;
 
+  /**
+   * Public key of the account we are downloading from.
+   */
+  struct SYNC_AccountPublicKeyP account_pub;
+
+  /**
+   * Signature returned in the "Sync-Signature"
+   * header, or all zeros for none.
+   */
+  struct SYNC_AccountSignatureP account_sig;
+
+  /**
+   * Hash code returned by the server in the
+   * "Sync-Previous" header, or all zeros for
+   * none.
+   */
+  struct GNUNET_HashCode sync_previous;
+
 };
 
 
+/**
+ * Function called when we're done processing the
+ * HTTP /backup request.
+ *
+ * @param cls the `struct SYNC_DownloadOperation`
+ * @param response_code HTTP response code, 0 on error
+ * @param response
+ */
+static void
+handle_download_finished (void *cls,
+                          long response_code,
+                          const void *data,
+                          size_t data_size)
+{
+  struct SYNC_DownloadOperation *download = cls;
+
+  download->job = NULL;
+  switch (response_code)
+  {
+  case 0:
+    break;
+  case MHD_HTTP_OK:
+    {
+      struct SYNC_DownloadDetails dd;
+      struct SYNC_UploadSignaturePS usp;
+
+      usp.purpose.purpose = htonl (TALER_SIGNATURE_SYNC_BACKUP_UPLOAD);
+      usp.purpose.size = htonl (sizeof (usp));
+      usp.old_backup_hash = download->sync_previous;
+      GNUNET_CRYPTO_hash (data,
+                          data_size,
+                          &usp.new_backup_hash);
+      if (GNUNET_OK !=
+          GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_SYNC_BACKUP_UPLOAD,
+                                      &usp.purpose,
+                                      &download->account_sig.eddsa_sig,
+                                      &download->account_pub.eddsa_pub))
+      {
+        GNUNET_break_op (0);
+        response_code = 0;
+        break;
+      }
+      /* Success, call callback with all details! */
+      memset (&dd, 0, sizeof (dd));
+      dd.sig = download->account_sig;
+      dd.prev_backup_hash = download->sync_previous;
+      dd.curr_backup_hash = usp.new_backup_hash;
+      dd.backup = data;
+      dd.backup_size = data_size;
+      download->cb (download->cb_cls,
+                    response_code,
+                    &dd);
+      download->cb = NULL;
+      SYNC_download_cancel (download);
+      return;
+    }
+  case MHD_HTTP_BAD_REQUEST:
+    /* This should never happen, either us or the sync server is buggy
+       (or API version conflict); just pass JSON reply to the application */
+    break;
+  case MHD_HTTP_NOT_FOUND:
+    /* Nothing really to verify */
+    break;
+  case MHD_HTTP_INTERNAL_SERVER_ERROR:
+    /* Server had an internal issue; we should retry, but this API
+       leaves this to the application */
+    break;
+  default:
+    /* unexpected response code */
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u\n",
+                (unsigned int) response_code);
+    GNUNET_break (0);
+    response_code = 0;
+    break;
+  }
+  if (NULL != download->cb)
+  {
+    download->cb (download->cb_cls,
+                  response_code,
+                  NULL);
+    download->cb = NULL;
+  }
+  SYNC_download_cancel (download);
+}
+
+
+/**
+ * Handle HTTP header received by curl.
+ *
+ * @param buffer one line of HTTP header data
+ * @param size size of an item
+ * @param nitems number of items passed
+ * @param userdata our `struct SYNC_DownloadOperation *`
+ * @return `size * nitems`
+ */
+static size_t
+handle_header (char *buffer,
+               size_t size,
+               size_t nitems,
+               void *userdata)
+{
+  struct SYNC_DownloadOperation *download = userdata;
+  size_t total = size * nitems;
+  char *ndup;
+  const char *hdr_type;
+  char *hdr_val;
+
+  ndup = GNUNET_strndup (buffer,
+                         total);
+  hdr_type = strtok (ndup,
+                     ":");
+  if (NULL == hdr_type)
+  {
+    GNUNET_free (ndup);
+    return total;
+  }
+  hdr_val = strtok (NULL,
+                    "");
+  if (NULL == hdr_val)
+  {
+    GNUNET_free (ndup);
+    return total;
+  }
+  if (' ' == *hdr_val)
+    hdr_val++;
+  if (0 == strcasecmp (hdr_type,
+                       "Sync-Signature"))
+  {
+    if (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (hdr_val,
+                                       strlen (hdr_val),
+                                       &download->account_sig,
+                                       sizeof (struct SYNC_AccountSignatureP)))
+    {
+      GNUNET_break_op (0);
+      GNUNET_free (ndup);
+      return 0;
+    }
+  }
+  if (0 == strcasecmp (hdr_type,
+                       "Sync-Previous"))
+  {
+    if (GNUNET_OK !=
+        GNUNET_STRINGS_string_to_data (hdr_val,
+                                       strlen (hdr_val),
+                                       &download->sync_previous,
+                                       sizeof (struct GNUNET_HashCode)))
+    {
+      GNUNET_break_op (0);
+      GNUNET_free (ndup);
+      return 0;
+    }
+  }
+  GNUNET_free (ndup);
+  return total;
+}
+
+
 /**
  * Download the latest version of a backup for account @a pub.
  *
@@ -82,8 +261,39 @@ SYNC_download (struct GNUNET_CURL_Context *ctx,
                SYNC_DownloadCallback cb,
                void *cb_cls)
 {
-  GNUNET_break (0);
-  return NULL;
+  struct SYNC_DownloadOperation *download;
+  char *pub_str;
+  CURL *eh;
+
+  download = GNUNET_new (struct SYNC_DownloadOperation);
+  download->account_pub = *pub;
+  pub_str = GNUNET_STRINGS_data_to_string_alloc (pub,
+                                                 sizeof (*pub));
+  GNUNET_asprintf (&download->url,
+                   "%s%sbackup/%s",
+                   base_url,
+                   '/' == base_url[strlen (base_url) - 1]
+                   ? ""
+                   : "/",
+                   pub_str);
+  GNUNET_free (pub_str);
+  eh = SYNC_curl_easy_get_ (download->url);
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_HEADERFUNCTION,
+                                   &handle_header));
+  GNUNET_assert (CURLE_OK ==
+                 curl_easy_setopt (eh,
+                                   CURLOPT_HEADERDATA,
+                                   download));
+  download->cb = cb;
+  download->cb_cls = cb_cls;
+  download->job = GNUNET_CURL_job_add_raw (ctx,
+                                           eh,
+                                           GNUNET_NO,
+                                           &handle_download_finished,
+                                           download);
+  return download;
 }
 
 
@@ -95,6 +305,13 @@ SYNC_download (struct GNUNET_CURL_Context *ctx,
 void
 SYNC_download_cancel (struct SYNC_DownloadOperation *download)
 {
+  if (NULL != download->job)
+  {
+    GNUNET_CURL_job_cancel (download->job);
+    download->job = NULL;
+  }
+  GNUNET_free (download->url);
+  GNUNET_free (download);
 }
 
 
diff --git a/src/sync/sync-httpd_mhd.c b/src/sync/sync-httpd_mhd.c
index 75f2a63..f7449a5 100644
--- a/src/sync/sync-httpd_mhd.c
+++ b/src/sync/sync-httpd_mhd.c
@@ -85,4 +85,4 @@ SH_MHD_handler_agpl_redirect (struct SH_RequestHandler *rh,
 }
 
 
-/* end of taler-exchange-httpd_mhd.c */
+/* end of sync-httpd_mhd.c */

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]