summaryrefslogtreecommitdiff
path: root/src/sync
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-11-15 09:39:31 +0100
committerChristian Grothoff <christian@grothoff.org>2019-11-15 09:39:31 +0100
commit9badf80eb4228a9c009839a4856710127efe8601 (patch)
treeec62e28f2ab3b90ca374537a9b2730b1fecdbb93 /src/sync
parentd0e22221b9fd3627d63e484b8957337d2638a871 (diff)
downloadsync-9badf80eb4228a9c009839a4856710127efe8601.tar.gz
sync-9badf80eb4228a9c009839a4856710127efe8601.tar.bz2
sync-9badf80eb4228a9c009839a4856710127efe8601.zip
implement GET logic
Diffstat (limited to 'src/sync')
-rw-r--r--src/sync/sync-httpd.c27
-rw-r--r--src/sync/sync-httpd_backup.c170
-rw-r--r--src/sync/sync-httpd_backup.h10
3 files changed, 185 insertions, 22 deletions
diff --git a/src/sync/sync-httpd.c b/src/sync/sync-httpd.c
index d7f6eb5..98a2b24 100644
--- a/src/sync/sync-httpd.c
+++ b/src/sync/sync-httpd.c
@@ -175,7 +175,10 @@ url_handler (void *cls,
struct TM_HandlerContext *hc;
struct GNUNET_AsyncScopeId aid;
const char *correlation_id = NULL;
+ struct SYNC_AccountPublicKeyP account_pub;
+ (void) cls;
+ (void) version;
hc = *con_cls;
if (NULL == hc)
@@ -197,7 +200,6 @@ url_handler (void *cls,
{
aid = hc->async_scope_id;
}
-
GNUNET_SCHEDULER_begin_async_scope (&aid);
if (NULL != correlation_id)
@@ -211,22 +213,25 @@ url_handler (void *cls,
"Handling request (%s) for URL '%s'\n",
method,
url);
- if (0 == strncmp (url,
- "/backup/",
- strlen ("/backup/")))
+
+ if (GNUNET_OK ==
+ GNUNET_CRYPTO_eddsa_public_key_from_string (url,
+ strlen (url),
+ &account_pub.eddsa_pub))
{
- // return handle_policy (...);
- if (0 == strcmp (method, MHD_HTTP_METHOD_GET))
+ if (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_GET))
{
return sync_handler_backup_get (connection,
- url,
+ &account_pub,
con_cls);
}
- if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
+ if (0 == strcasecmp (method,
+ MHD_HTTP_METHOD_POST))
{
return sync_handler_backup_post (connection,
con_cls,
- url,
+ &account_pub,
upload_data,
upload_data_size);
}
@@ -238,8 +243,8 @@ url_handler (void *cls,
if ( (0 == strcmp (url,
rh->url)) &&
( (NULL == rh->method) ||
- (0 == strcmp (method,
- rh->method)) ) )
+ (0 == strcasecmp (method,
+ rh->method)) ) )
{
int ret;
diff --git a/src/sync/sync-httpd_backup.c b/src/sync/sync-httpd_backup.c
index 86ba955..61d9151 100644
--- a/src/sync/sync-httpd_backup.c
+++ b/src/sync/sync-httpd_backup.c
@@ -21,26 +21,182 @@
#include "platform.h"
#include "sync-httpd.h"
#include <gnunet/gnunet_util_lib.h>
+#include "sync-httpd_backup.h"
+#include "sync-httpd_responses.h"
/**
* @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @param account public key of the account the request is for
+ * @param[in,out] con_cls the connection's closure (can be updated)
* @return MHD result code
*/
int
sync_handler_backup_get (struct MHD_Connection *connection,
- const char *url,
+ const struct SYNC_AccountPublicKeyP *account,
void **con_cls)
{
- return MHD_NO;
+ struct SYNC_AccountSignatureP account_sig;
+ struct GNUNET_HashCode backup_hash;
+ struct GNUNET_HashCode prev_hash;
+ size_t backup_size;
+ void *backup;
+ enum SYNC_DB_QueryStatus qs;
+ struct MHD_Response *resp;
+ const char *inm;
+ struct GNUNET_HashCode inm_h;
+ int ret;
+
+ inm = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_IF_NONE_MATCH);
+ qs = db->lookup_account_TR (db->cls,
+ account,
+ &backup_hash);
+ switch (qs)
+ {
+ case SYNC_DB_OLD_BACKUP_MISSMATCH:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_INTERNAL_INVARIANT_FAILURE,
+ "unexpected return status (backup missmatch)");
+ case SYNC_DB_PAYMENT_REQUIRED:
+ return SH_RESPONSE_reply_not_found (connection,
+ TALER_EC_SYNC_ACCOUNT_UNKNOWN,
+ "account");
+ case SYNC_DB_HARD_ERROR:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_SYNC_DB_FETCH_ERROR,
+ "hard database failure");
+ case SYNC_DB_SOFT_ERROR:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_SYNC_DB_FETCH_ERROR,
+ "soft database failure");
+ case SYNC_DB_NO_RESULTS:
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ case SYNC_DB_ONE_RESULT:
+ if (NULL != inm)
+ {
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (inm,
+ strlen (inm),
+ &inm_h,
+ sizeof (inm_h)))
+ {
+ GNUNET_break_op (0);
+ return SH_RESPONSE_reply_bad_request (connection,
+ TALER_EC_SYNC_BAD_ETAG,
+ "Etag is not a base32-encoded SHA-512 hash");
+ }
+ if (0 == GNUNET_memcmp (&inm_h,
+ &backup_hash))
+ {
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NOT_MODIFIED,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ }
+ /* We have a result, should fetch and return it! */
+ break;
+ }
+
+ qs = db->lookup_backup_TR (db->cls,
+ account,
+ &account_sig,
+ &prev_hash,
+ &backup_hash,
+ &backup_size,
+ &backup);
+ switch (qs)
+ {
+ case SYNC_DB_OLD_BACKUP_MISSMATCH:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_INTERNAL_INVARIANT_FAILURE,
+ "unexpected return status (backup missmatch)");
+ case SYNC_DB_PAYMENT_REQUIRED:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_INTERNAL_INVARIANT_FAILURE,
+ "unexpected return status (payment required)");
+ case SYNC_DB_HARD_ERROR:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_SYNC_DB_FETCH_ERROR,
+ "hard database failure");
+ case SYNC_DB_SOFT_ERROR:
+ GNUNET_break (0);
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_SYNC_DB_FETCH_ERROR,
+ "soft database failure");
+ case SYNC_DB_NO_RESULTS:
+ GNUNET_break (0);
+ /* Note: can theoretically happen due to non-transactional nature if
+ the backup expired / was gc'ed JUST between the two SQL calls.
+ But too rare to handle properly, as doing a transaction would be
+ expensive. Just admit to failure ;-) */
+ return SH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_SYNC_DB_FETCH_ERROR,
+ "unexpected empty result set (try again?)");
+ case SYNC_DB_ONE_RESULT:
+ /* interesting case below */
+ break;
+ }
+ resp = MHD_create_response_from_buffer (backup_size,
+ backup,
+ MHD_RESPMEM_MUST_FREE);
+ {
+ char *sig_s;
+ char *prev_s;
+ char *etag;
+
+ sig_s = GNUNET_STRINGS_data_to_string_alloc (&account_sig,
+ sizeof (account_sig));
+ prev_s = GNUNET_STRINGS_data_to_string_alloc (&prev_hash,
+ sizeof (prev_hash));
+ etag = GNUNET_STRINGS_data_to_string_alloc (&backup_hash,
+ sizeof (backup_hash));
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ "X-Sync-Signature",
+ sig_s));
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ "X-Sync-Previous",
+ prev_s));
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+ MHD_HTTP_HEADER_ETAG,
+ etag));
+ GNUNET_free (etag);
+ GNUNET_free (prev_s);
+ GNUNET_free (sig_s);
+ }
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NOT_MODIFIED,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
}
/**
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param account public key of the account the request is for
* @param upload_data upload data
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
@@ -48,9 +204,11 @@ sync_handler_backup_get (struct MHD_Connection *connection,
int
sync_handler_backup_post (struct MHD_Connection *connection,
void **con_cls,
- const char *url,
+ const struct SYNC_AccountPublicKeyP *account,
const char *upload_data,
size_t *upload_data_size)
{
+ struct SYNC_AccountSignatureP account_sig;
+
return MHD_NO;
}
diff --git a/src/sync/sync-httpd_backup.h b/src/sync/sync-httpd_backup.h
index 1ba7408..02f31be 100644
--- a/src/sync/sync-httpd_backup.h
+++ b/src/sync/sync-httpd_backup.h
@@ -24,20 +24,20 @@
/**
* @param connection the MHD connection to handle
- * @param[in,out] connection_cls the connection's closure (can be updated)
- * @param upload_data upload data
- * @param[in,out] upload_data_size number of bytes (left) in @a upload_data
+ * @param account public key of the account the request is for
+ * @param[in,out] con_cls the connection's closure (can be updated)
* @return MHD result code
*/
int
sync_handler_backup_get (struct MHD_Connection *connection,
- const char *url,
+ const struct SYNC_AccountPublicKeyP *account,
void **con_cls);
/**
* @param connection the MHD connection to handle
* @param[in,out] connection_cls the connection's closure (can be updated)
+ * @param account public key of the account the request is for
* @param upload_data upload data
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
* @return MHD result code
@@ -45,7 +45,7 @@ sync_handler_backup_get (struct MHD_Connection *connection,
int
sync_handler_backup_post (struct MHD_Connection *connection,
void **con_cls,
- const char *url,
+ const struct SYNC_AccountPublicKeyP *account,
const char *upload_data,
size_t *upload_data_size);