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,10 +43,17 @@ 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;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (*changes != NULL) {
free(*changes);
*changes = NULL;
}
api_call = mfconn_create_signed_get(conn, 0, "device/get_changes.php", api_call = mfconn_create_signed_get(conn, 0, "device/get_changes.php",
"?revision=%" PRIu64 "?revision=%" PRIu64
"&response_format=json", revision); "&response_format=json", revision);
@@ -60,6 +67,23 @@ int mfconn_api_device_get_changes(mfconn * conn, uint64_t revision,
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_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,6 +54,7 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
if (len != 15) if (len != 15)
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "device/get_patch.php", api_call = mfconn_create_signed_get(conn, 0, "device/get_patch.php",
"?quick_key=%s" "?quick_key=%s"
"&source_revision=%" PRIu64 "&source_revision=%" PRIu64
@@ -68,6 +70,23 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
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,12 +33,12 @@ 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;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php", api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php",
"?response_format=json"); "?response_format=json");
@@ -51,6 +51,23 @@ int mfconn_api_device_get_status(mfconn * conn, uint64_t * revision)
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,19 +56,31 @@ int mfconn_api_device_get_updates(mfconn * conn, const char *quickkey,
if (len != 15) if (len != 15)
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (*patches != NULL) {
for (j = 0; (*patches)[j] != NULL; j++) {
patch_free((*patches)[j]);
}
free(*patches);
*patches = NULL;
}
if (target_revision == 0) { if (target_revision == 0) {
api_call = mfconn_create_signed_get(conn, 0, "device/get_updates.php", api_call = mfconn_create_signed_get(conn, 0,
"device/get_updates.php",
"?quick_key=%s" "?quick_key=%s"
"&revision=%" PRIu64 "&revision=%" PRIu64
"&response_format=json", quickkey, "&response_format=json",
revision); quickkey, revision);
} else { } else {
api_call = mfconn_create_signed_get(conn, 0, "device/get_updates.php", api_call = mfconn_create_signed_get(conn, 0,
"device/get_updates.php",
"?quick_key=%s" "?quick_key=%s"
"&revision=%" PRIu64 "&revision=%" PRIu64
"&target_revision=%" PRIu64 "&target_revision=%" PRIu64
"&response_format=json", quickkey, "&response_format=json",
revision, target_revision); quickkey, revision,
target_revision);
} }
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, _decode_device_get_updates, retval = http_get_buf(http, api_call, _decode_device_get_updates,
@@ -76,6 +90,23 @@ int mfconn_api_device_get_updates(mfconn * conn, const char *quickkey,
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

@@ -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;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "file/delete.php", api_call = mfconn_create_signed_get(conn, 0, "file/delete.php",
"?quick_key=%s&response_format=json", "?quick_key=%s"
quickkey); "&response_format=json", quickkey);
http = http_create(); http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common, "file/delete"); retval =
http_get_buf(http, api_call, mfapi_decode_common, "file/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

@@ -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,9 +54,10 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file,
if (len != 11 && len != 15) if (len != 11 && len != 15)
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "file/get_info.php", api_call = mfconn_create_signed_get(conn, 0, "file/get_info.php",
"?quick_key=%s&response_format=json", "?quick_key=%s"
quickkey); "&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);
@@ -64,6 +66,23 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file,
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,9 +52,10 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
if (len != 11 && len != 15) if (len != 11 && len != 15)
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php", api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php",
"?quick_key=%s&response_format=json", "?quick_key=%s"
quickkey); "&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);
@@ -62,6 +64,23 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
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,11 +46,13 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
return -1; return -1;
} }
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (parent != NULL) { if (parent != NULL) {
api_call = api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php", mfconn_create_signed_get(conn, 0, "folder/create.php",
"?parent_key=%s&foldername=%s" "?parent_key=%s&foldername=%s"
"&response_format=json", parent, name); "&response_format=json", parent,
name);
} else { } else {
api_call = api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php", mfconn_create_signed_get(conn, 0, "folder/create.php",
@@ -65,5 +68,22 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
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

@@ -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,8 +41,10 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
if (strlen(folderkey) != 13) if (strlen(folderkey) != 13)
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "folder/delete.php", api_call = mfconn_create_signed_get(conn, 0, "folder/delete.php",
"?folder_key=%s&response_format=json", "?folder_key=%s"
"&response_format=json",
folderkey); folderkey);
http = http_create(); http = http_create();
@@ -52,5 +55,22 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
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,13 +66,34 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
else else
content_type = "files"; content_type = "files";
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (mode == 0) {
if (*mffolder_result != NULL) {
for (j = 0; (*mffolder_result)[j] != NULL; j++) {
folder_free((*mffolder_result)[j]);
}
free(*mffolder_result);
*mffolder_result = NULL;
}
} else {
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) { if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_content.php", api_call = mfconn_create_signed_get(conn, 0,
"folder/get_content.php",
"?content_type=%s" "?content_type=%s"
"&response_format=json", "&response_format=json",
content_type); content_type);
} else { } else {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_content.php", api_call = mfconn_create_signed_get(conn, 0,
"folder/get_content.php",
"?folder_key=%s" "?folder_key=%s"
"&content_type=%s" "&content_type=%s"
"&response_format=json", "&response_format=json",
@@ -78,13 +102,11 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
http = http_create(); http = http_create();
if (mode == 0) if (mode == 0)
retval = retval = http_get_buf(http, api_call,
http_get_buf(http, api_call,
_decode_folder_get_content_folders, _decode_folder_get_content_folders,
(void *)mffolder_result); (void *)mffolder_result);
else else
retval = retval = http_get_buf(http, api_call,
http_get_buf(http, api_call,
_decode_folder_get_content_files, _decode_folder_get_content_files,
(void *)mffile_result); (void *)mffile_result);
http_destroy(http); http_destroy(http);
@@ -92,6 +114,23 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
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 @@ 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,6 +51,7 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
return -1; return -1;
} }
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (folderkey == NULL) { if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php", api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
"?response_format=json"); "?response_format=json");
@@ -67,6 +69,23 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
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

@@ -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,6 +50,7 @@ mfconn_api_upload_poll_upload(mfconn * conn, const char *upload_key,
if (upload_key == NULL) if (upload_key == NULL)
return -1; return -1;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
// make an UNSIGNED get // make an UNSIGNED get
api_call = mfconn_create_unsigned_get(conn, 0, api_call = mfconn_create_unsigned_get(conn, 0,
"upload/poll_upload.php", "upload/poll_upload.php",
@@ -62,6 +64,23 @@ mfconn_api_upload_poll_upload(mfconn * conn, const char *upload_key,
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,6 +65,12 @@ mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
file_hash = binary2hex(hash, SHA256_DIGEST_LENGTH); file_hash = binary2hex(hash, SHA256_DIGEST_LENGTH);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (*upload_key != NULL) {
free(*upload_key);
*upload_key = NULL;
}
if (folderkey == NULL) { if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0, api_call = mfconn_create_signed_get(conn, 0,
"upload/simple.php", "upload/simple.php",
@@ -85,9 +92,27 @@ mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
http_destroy(http); http_destroy(http);
mfconn_update_secret_key(conn); mfconn_update_secret_key(conn);
free(file_hash);
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;
}
}
free(file_hash);
return retval; return retval;
} }

View File

@@ -51,10 +51,20 @@ 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;
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (*secret_time != NULL) {
free(*secret_time);
*secret_time = NULL;
}
if (*session_token != NULL) {
free(*session_token);
*session_token = NULL;
}
// configure url for operation // configure url for operation
login_url = strdup_printf("https://%s/api/user/get_session_token.php", login_url = strdup_printf("https://%s/api/user/get_session_token.php",
server); server);
@@ -84,6 +94,23 @@ mfconn_api_user_get_session_token(mfconn * conn, const char *server,
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;
*session_token = response.session_token; *session_token = response.session_token;

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