if apicall failed - retry

This commit is contained in:
josch
2014-12-06 11:04:04 +01:00
parent dd3291a9c4
commit 8468a39c0a
20 changed files with 579 additions and 211 deletions

View File

@@ -280,7 +280,7 @@ static void connect_mf(struct mediafirefs_user_options *options,
ctx->conn = mfconn_create(options->server, options->username, ctx->conn = mfconn_create(options->server, options->username,
options->password, options->app_id, options->password, options->app_id,
options->api_key); options->api_key, 3);
if (ctx->conn == NULL) { if (ctx->conn == NULL) {
fprintf(stderr, "Cannot establish connection\n"); fprintf(stderr, "Cannot establish connection\n");

View File

@@ -426,6 +426,7 @@ int mediafirefs_release(const char *path, struct fuse_file_info *file_info)
folder_key = folder_tree_path_get_key(ctx->tree, ctx->conn, dir_name); folder_key = folder_tree_path_get_key(ctx->tree, ctx->conn, dir_name);
upload_key = NULL;
retval = mfconn_api_upload_simple(ctx->conn, folder_key, retval = mfconn_api_upload_simple(ctx->conn, folder_key,
fh, file_name, &upload_key); fh, file_name, &upload_key);

View File

@@ -19,7 +19,6 @@
#include <jansson.h> #include <jansson.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include "../utils/http.h" #include "../utils/http.h"

View File

@@ -61,7 +61,7 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
int mfconn_api_folder_create(mfconn * conn, const char *parent, int mfconn_api_folder_create(mfconn * conn, const char *parent,
const char *name); const char *name);
long mfconn_api_folder_get_content(mfconn * conn, int mode, long mfconn_api_folder_get_content(mfconn * conn, const int mode,
const char *folderkey, const char *folderkey,
mffolder *** folder_result, mffolder *** folder_result,
mffile *** file_result); mffile *** file_result);

View File

@@ -43,22 +43,46 @@ int mfconn_api_device_get_changes(mfconn * conn, uint64_t revision,
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "device/get_changes.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?revision=%" PRIu64 if (*changes != NULL) {
"&response_format=json", revision); free(*changes);
*changes = NULL;
}
http = http_create(); api_call = mfconn_create_signed_get(conn, 0, "device/get_changes.php",
retval = "?revision=%" PRIu64
http_get_buf(http, api_call, _decode_device_get_changes, "&response_format=json", revision);
(void *)changes);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call); http = http_create();
retval =
http_get_buf(http, api_call, _decode_device_get_changes,
(void *)changes);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -38,6 +38,7 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
int len; int len;
mfhttp *http; mfhttp *http;
int retval; int retval;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -53,20 +54,38 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
if (len != 15) if (len != 15)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "device/get_patch.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?quick_key=%s" api_call = mfconn_create_signed_get(conn, 0, "device/get_patch.php",
"&source_revision=%" PRIu64 "?quick_key=%s"
"&target_revision=%" PRIu64 "&source_revision=%" PRIu64
"&response_format=json", quickkey, "&target_revision=%" PRIu64
source_revision, target_revision); "&response_format=json", quickkey,
source_revision, target_revision);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, _decode_device_get_patch, retval = http_get_buf(http, api_call, _decode_device_get_patch,
(void *)patch); (void *)patch);
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -33,23 +33,40 @@ int mfconn_api_device_get_status(mfconn * conn, uint64_t * revision)
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i;
// char *rx_buffer;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?response_format=json"); api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php",
"?response_format=json");
http = http_create(); http = http_create();
retval = retval =
http_get_buf(http, api_call, _decode_device_get_status, http_get_buf(http, api_call, _decode_device_get_status,
(void *)revision); (void *)revision);
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -39,6 +39,8 @@ int mfconn_api_device_get_updates(mfconn * conn, const char *quickkey,
int len; int len;
mfhttp *http; mfhttp *http;
int retval; int retval;
int i,
j;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -54,27 +56,56 @@ int mfconn_api_device_get_updates(mfconn * conn, const char *quickkey,
if (len != 15) if (len != 15)
return -1; return -1;
if (target_revision == 0) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "device/get_updates.php", if (*patches != NULL) {
"?quick_key=%s" for (j = 0; (*patches)[j] != NULL; j++) {
"&revision=%" PRIu64 patch_free((*patches)[j]);
"&response_format=json", quickkey, }
revision); free(*patches);
} else { *patches = NULL;
api_call = mfconn_create_signed_get(conn, 0, "device/get_updates.php", }
"?quick_key=%s"
"&revision=%" PRIu64
"&target_revision=%" PRIu64
"&response_format=json", quickkey,
revision, target_revision);
}
http = http_create();
retval = http_get_buf(http, api_call, _decode_device_get_updates,
(void *)patches);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call); if (target_revision == 0) {
api_call = mfconn_create_signed_get(conn, 0,
"device/get_updates.php",
"?quick_key=%s"
"&revision=%" PRIu64
"&response_format=json",
quickkey, revision);
} else {
api_call = mfconn_create_signed_get(conn, 0,
"device/get_updates.php",
"?quick_key=%s"
"&revision=%" PRIu64
"&target_revision=%" PRIu64
"&response_format=json",
quickkey, revision,
target_revision);
}
http = http_create();
retval = http_get_buf(http, api_call, _decode_device_get_updates,
(void *)patches);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -30,6 +30,7 @@ int mfconn_api_file_delete(mfconn * conn, const char *quickkey)
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -40,16 +41,35 @@ int mfconn_api_file_delete(mfconn * conn, const char *quickkey)
if (strlen(quickkey) != 15) if (strlen(quickkey) != 15)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "file/delete.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?quick_key=%s&response_format=json", api_call = mfconn_create_signed_get(conn, 0, "file/delete.php",
quickkey); "?quick_key=%s"
"&response_format=json", quickkey);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common, "file/delete"); retval =
http_destroy(http); http_get_buf(http, api_call, mfapi_decode_common, "file/delete");
mfconn_update_secret_key(conn); http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -38,6 +38,7 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file,
int retval; int retval;
int len; int len;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -53,16 +54,34 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file,
if (len != 11 && len != 15) if (len != 11 && len != 15)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "file/get_info.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?quick_key=%s&response_format=json", api_call = mfconn_create_signed_get(conn, 0, "file/get_info.php",
quickkey); "?quick_key=%s"
"&response_format=json", quickkey);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, _decode_file_get_info, file); retval = http_get_buf(http, api_call, _decode_file_get_info, file);
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -36,6 +36,7 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
int retval; int retval;
int len; int len;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -51,16 +52,34 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
if (len != 11 && len != 15) if (len != 11 && len != 15)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?quick_key=%s&response_format=json", api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php",
quickkey); "?quick_key=%s"
"&response_format=json", quickkey);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, _decode_file_get_links, file); retval = http_get_buf(http, api_call, _decode_file_get_links, file);
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -31,6 +31,7 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -45,25 +46,44 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
return -1; return -1;
} }
if (parent != NULL) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = if (parent != NULL) {
mfconn_create_signed_get(conn, 0, "folder/create.php", api_call =
"?parent_key=%s&foldername=%s" mfconn_create_signed_get(conn, 0, "folder/create.php",
"&response_format=json", parent, name); "?parent_key=%s&foldername=%s"
} else { "&response_format=json", parent,
api_call = name);
mfconn_create_signed_get(conn, 0, "folder/create.php", } else {
"?foldername=%s&response_format=json", api_call =
name); mfconn_create_signed_get(conn, 0, "folder/create.php",
"?foldername=%s&response_format=json",
name);
}
http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common,
"folder/create");
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
} }
http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common,
"folder/create");
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
return retval; return retval;
} }

View File

@@ -30,6 +30,7 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -40,17 +41,36 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
if (strlen(folderkey) != 13) if (strlen(folderkey) != 13)
return -1; return -1;
api_call = mfconn_create_signed_get(conn, 0, "folder/delete.php", for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
"?folder_key=%s&response_format=json", api_call = mfconn_create_signed_get(conn, 0, "folder/delete.php",
folderkey); "?folder_key=%s"
"&response_format=json",
folderkey);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common, retval = http_get_buf(http, api_call, mfapi_decode_common,
"folder/delete"); "folder/delete");
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
return retval; return retval;
} }

View File

@@ -46,7 +46,8 @@ static int _decode_folder_get_content_files(mfhttp * conn, void *data);
* pointers to them. * pointers to them.
*/ */
long long
mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey, mfconn_api_folder_get_content(mfconn * conn, const int mode,
const char *folderkey,
mffolder *** mffolder_result, mffolder *** mffolder_result,
mffile *** mffile_result) mffile *** mffile_result)
{ {
@@ -54,6 +55,8 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
int retval; int retval;
char *content_type; char *content_type;
mfhttp *http; mfhttp *http;
int i,
j;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -63,35 +66,71 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
else else
content_type = "files"; content_type = "files";
if (folderkey == NULL) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_content.php", if (mode == 0) {
"?content_type=%s" if (*mffolder_result != NULL) {
"&response_format=json", for (j = 0; (*mffolder_result)[j] != NULL; j++) {
content_type); folder_free((*mffolder_result)[j]);
} else { }
api_call = mfconn_create_signed_get(conn, 0, "folder/get_content.php", free(*mffolder_result);
"?folder_key=%s" *mffolder_result = NULL;
"&content_type=%s" }
"&response_format=json", } else {
folderkey, content_type); if (*mffile_result != NULL) {
for (j = 0; (*mffile_result)[j] != NULL; j++) {
file_free((*mffile_result)[j]);
}
free(*mffile_result);
*mffile_result = NULL;
}
}
if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0,
"folder/get_content.php",
"?content_type=%s"
"&response_format=json",
content_type);
} else {
api_call = mfconn_create_signed_get(conn, 0,
"folder/get_content.php",
"?folder_key=%s"
"&content_type=%s"
"&response_format=json",
folderkey, content_type);
}
http = http_create();
if (mode == 0)
retval = http_get_buf(http, api_call,
_decode_folder_get_content_folders,
(void *)mffolder_result);
else
retval = http_get_buf(http, api_call,
_decode_folder_get_content_files,
(void *)mffile_result);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
} }
http = http_create();
if (mode == 0)
retval =
http_get_buf(http, api_call,
_decode_folder_get_content_folders,
(void *)mffolder_result);
else
retval =
http_get_buf(http, api_call,
_decode_folder_get_content_files,
(void *)mffile_result);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
return retval; return retval;
} }

View File

@@ -38,6 +38,7 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
const char *api_call; const char *api_call;
int retval; int retval;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -50,23 +51,41 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
return -1; return -1;
} }
if (folderkey == NULL) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php", if (folderkey == NULL) {
"?response_format=json"); api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
} else { "?response_format=json");
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php", } else {
"?folder_key=%s" api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
"&response_format=json", "?folder_key=%s"
folderkey); "&response_format=json",
folderkey);
}
http = http_create();
retval = http_get_buf(http, api_call, _decode_folder_get_info, folder);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
} }
http = http_create();
retval = http_get_buf(http, api_call, _decode_folder_get_info, folder);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
return retval; return retval;
} }

View File

@@ -42,6 +42,7 @@ mfconn_api_upload_poll_upload(mfconn * conn, const char *upload_key,
int retval; int retval;
mfhttp *http; mfhttp *http;
struct upload_poll_upload_response response; struct upload_poll_upload_response response;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -49,18 +50,36 @@ mfconn_api_upload_poll_upload(mfconn * conn, const char *upload_key,
if (upload_key == NULL) if (upload_key == NULL)
return -1; return -1;
// make an UNSIGNED get for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_unsigned_get(conn, 0, // make an UNSIGNED get
"upload/poll_upload.php", api_call = mfconn_create_unsigned_get(conn, 0,
"?response_format=json" "upload/poll_upload.php",
"&key=%s", upload_key); "?response_format=json"
"&key=%s", upload_key);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, _decode_upload_poll_upload, retval = http_get_buf(http, api_call, _decode_upload_poll_upload,
&response); &response);
http_destroy(http); http_destroy(http);
free((void *)api_call); free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
*status = response.status; *status = response.status;
*fileerror = response.fileerror; *fileerror = response.fileerror;

View File

@@ -44,6 +44,7 @@ mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
unsigned char hash[SHA256_DIGEST_LENGTH]; unsigned char hash[SHA256_DIGEST_LENGTH];
char *file_hash; char *file_hash;
uint64_t file_size; uint64_t file_size;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
@@ -64,29 +65,53 @@ mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
file_hash = binary2hex(hash, SHA256_DIGEST_LENGTH); file_hash = binary2hex(hash, SHA256_DIGEST_LENGTH);
if (folderkey == NULL) { for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, if (*upload_key != NULL) {
"upload/simple.php", free(*upload_key);
"?response_format=json"); *upload_key = NULL;
} else { }
api_call = mfconn_create_signed_get(conn, 0,
"upload/simple.php", if (folderkey == NULL) {
"?response_format=json" api_call = mfconn_create_signed_get(conn, 0,
"&folder_key=%s", folderkey); "upload/simple.php",
"?response_format=json");
} else {
api_call = mfconn_create_signed_get(conn, 0,
"upload/simple.php",
"?response_format=json"
"&folder_key=%s", folderkey);
}
// make sure that we are at the beginning of the file
rewind(fh);
http = http_create();
retval = http_post_file(http, api_call, fh, file_name,
file_size, file_hash,
_decode_upload_simple, upload_key);
http_destroy(http);
mfconn_update_secret_key(conn);
free((void *)api_call);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
} }
// make sure that we are at the beginning of the file
rewind(fh);
http = http_create();
retval = http_post_file(http, api_call, fh, file_name,
file_size, file_hash,
_decode_upload_simple, upload_key);
http_destroy(http);
mfconn_update_secret_key(conn);
free(file_hash); free(file_hash);
free((void *)api_call);
return retval; return retval;
} }

View File

@@ -51,38 +51,65 @@ mfconn_api_user_get_session_token(mfconn * conn, const char *server,
int retval; int retval;
struct user_get_session_token_response response; struct user_get_session_token_response response;
mfhttp *http; mfhttp *http;
int i;
if (conn == NULL) if (conn == NULL)
return -1; return -1;
// configure url for operation for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
login_url = strdup_printf("https://%s/api/user/get_session_token.php", if (*secret_time != NULL) {
server); free(*secret_time);
*secret_time = NULL;
}
if (*session_token != NULL) {
free(*session_token);
*session_token = NULL;
}
// configure url for operation
login_url = strdup_printf("https://%s/api/user/get_session_token.php",
server);
// create user signature // create user signature
user_signature = user_signature =
mfconn_create_user_signature(conn, username, password, app_id, mfconn_create_user_signature(conn, username, password, app_id,
app_key); app_key);
// FIXME: username and password have to be urlencoded (maybe using // FIXME: username and password have to be urlencoded (maybe using
// curl_easy_escape) // curl_easy_escape)
post_args = strdup_printf("email=%s" post_args = strdup_printf("email=%s"
"&password=%s" "&password=%s"
"&application_id=%d" "&application_id=%d"
"&signature=%s" "&signature=%s"
"&token_version=2" "&token_version=2"
"&response_format=json", "&response_format=json",
username, password, app_id, user_signature); username, password, app_id, user_signature);
free((void *)user_signature); free((void *)user_signature);
http = http_create(); http = http_create();
retval = retval =
http_post_buf(http, login_url, post_args, http_post_buf(http, login_url, post_args,
_decode_get_session_token, (void *)(&response)); _decode_get_session_token, (void *)(&response));
http_destroy(http); http_destroy(http);
free(login_url); free(login_url);
free(post_args); free(post_args);
if (retval != 127 && retval != 28)
break;
// if there was either a curl timeout or a token error, get a new
// token and try again
//
// on a curl timeout we get a new token because it is likely that we
// lost signature synchronization (we don't know whether the server
// accepted or rejected the last call)
fprintf(stderr, "got error %d - negotiate a new token\n", retval);
retval = mfconn_refresh_token(conn);
if (retval != 0) {
fprintf(stderr, "failed to get a new token\n");
break;
}
}
*secret_key = response.secret_key; *secret_key = response.secret_key;
*secret_time = response.secret_time; *secret_time = response.secret_time;

View File

@@ -35,11 +35,16 @@ struct mfconn {
uint32_t secret_key; uint32_t secret_key;
char *secret_time; char *secret_time;
char *session_token; char *session_token;
char *username;
char *password;
int app_id;
char *app_key;
int max_num_retries;
}; };
mfconn *mfconn_create(const char *server, const char *username, mfconn *mfconn_create(const char *server, const char *username,
const char *password, int app_id, const char *password, int app_id,
const char *app_key) const char *app_key, int max_num_retries)
{ {
mfconn *conn; mfconn *conn;
int retval; int retval;
@@ -59,24 +64,59 @@ mfconn *mfconn_create(const char *server, const char *username,
conn = (mfconn *) calloc(1, sizeof(mfconn)); conn = (mfconn *) calloc(1, sizeof(mfconn));
conn->server = strdup(server); conn->server = strdup(server);
conn->username = strdup(username);
conn->password = strdup(password);
conn->app_id = app_id;
if (app_key != NULL)
conn->app_key = strdup(app_key);
else
conn->app_key = NULL;
conn->max_num_retries = max_num_retries;
conn->secret_time = NULL;
conn->session_token = NULL;
retval = mfconn_api_user_get_session_token(conn, conn->server, retval = mfconn_api_user_get_session_token(conn, conn->server,
username, password, app_id, conn->username, conn->password,
app_key, conn->app_id, conn->app_key,
&(conn->secret_key), &(conn->secret_key),
&(conn->secret_time), &(conn->secret_time),
&(conn->session_token)); &(conn->session_token));
if (retval == 0) if (retval != 0) {
return conn;
else {
fprintf(stderr, "error: mfconn_api_user_get_session_token\n"); fprintf(stderr, "error: mfconn_api_user_get_session_token\n");
return NULL; return NULL;
} }
return conn;
}
int mfconn_refresh_token(mfconn * conn)
{
int retval;
free(conn->secret_time);
conn->secret_time = NULL;
free(conn->session_token);
conn->session_token = NULL;
retval = mfconn_api_user_get_session_token(conn, conn->server,
conn->username, conn->password,
conn->app_id, conn->app_key,
&(conn->secret_key),
&(conn->secret_time),
&(conn->session_token));
if (retval != 0) {
fprintf(stderr, "user/get_session_token failed\n");
return -1;
}
return 0;
} }
void mfconn_destroy(mfconn * conn) void mfconn_destroy(mfconn * conn)
{ {
free(conn->server); free(conn->server);
free(conn->username);
free(conn->password);
if (conn->app_key != NULL)
free(conn->app_key);
free(conn->secret_time); free(conn->secret_time);
free(conn->session_token); free(conn->session_token);
free(conn); free(conn);
@@ -334,3 +374,8 @@ uint32_t mfconn_get_secret_key(mfconn * conn)
{ {
return conn->secret_key; return conn->secret_key;
} }
int mfconn_get_max_num_retries(mfconn * conn)
{
return conn->max_num_retries;
}

View File

@@ -28,7 +28,9 @@ typedef struct mfconn mfconn;
mfconn *mfconn_create(const char *server, const char *username, mfconn *mfconn_create(const char *server, const char *username,
const char *password, int app_id, const char *password, int app_id,
const char *app_key); const char *app_key, int max_num_retries);
int mfconn_refresh_token(mfconn * conn);
void mfconn_destroy(mfconn * conn); void mfconn_destroy(mfconn * conn);
@@ -54,4 +56,7 @@ const char *mfconn_get_session_token(mfconn * conn);
const char *mfconn_get_secret_time(mfconn * conn); const char *mfconn_get_secret_time(mfconn * conn);
uint32_t mfconn_get_secret_key(mfconn * conn); uint32_t mfconn_get_secret_key(mfconn * conn);
int mfconn_get_max_num_retries(mfconn * conn);
#endif #endif