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

@@ -19,7 +19,6 @@
#include <jansson.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.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,
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,
mffolder *** folder_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;
int retval;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "device/get_changes.php",
"?revision=%" PRIu64
"&response_format=json", revision);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (*changes != NULL) {
free(*changes);
*changes = NULL;
}
http = http_create();
retval =
http_get_buf(http, api_call, _decode_device_get_changes,
(void *)changes);
http_destroy(http);
mfconn_update_secret_key(conn);
api_call = mfconn_create_signed_get(conn, 0, "device/get_changes.php",
"?revision=%" PRIu64
"&response_format=json", revision);
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;
}

View File

@@ -38,6 +38,7 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
int len;
mfhttp *http;
int retval;
int i;
if (conn == NULL)
return -1;
@@ -53,20 +54,38 @@ int mfconn_api_device_get_patch(mfconn * conn, mfpatch * patch,
if (len != 15)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "device/get_patch.php",
"?quick_key=%s"
"&source_revision=%" PRIu64
"&target_revision=%" PRIu64
"&response_format=json", quickkey,
source_revision, target_revision);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "device/get_patch.php",
"?quick_key=%s"
"&source_revision=%" PRIu64
"&target_revision=%" PRIu64
"&response_format=json", quickkey,
source_revision, target_revision);
http = http_create();
retval = http_get_buf(http, api_call, _decode_device_get_patch,
(void *)patch);
http_destroy(http);
mfconn_update_secret_key(conn);
http = http_create();
retval = http_get_buf(http, api_call, _decode_device_get_patch,
(void *)patch);
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;
}

View File

@@ -33,23 +33,40 @@ int mfconn_api_device_get_status(mfconn * conn, uint64_t * revision)
const char *api_call;
int retval;
mfhttp *http;
// char *rx_buffer;
int i;
if (conn == NULL)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php",
"?response_format=json");
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "device/get_status.php",
"?response_format=json");
http = http_create();
retval =
http_get_buf(http, api_call, _decode_device_get_status,
(void *)revision);
http_destroy(http);
mfconn_update_secret_key(conn);
http = http_create();
retval =
http_get_buf(http, api_call, _decode_device_get_status,
(void *)revision);
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;
}

View File

@@ -39,6 +39,8 @@ int mfconn_api_device_get_updates(mfconn * conn, const char *quickkey,
int len;
mfhttp *http;
int retval;
int i,
j;
if (conn == NULL)
return -1;
@@ -54,27 +56,56 @@ int mfconn_api_device_get_updates(mfconn * conn, const char *quickkey,
if (len != 15)
return -1;
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);
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;
}
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;
}

View File

@@ -30,6 +30,7 @@ int mfconn_api_file_delete(mfconn * conn, const char *quickkey)
const char *api_call;
int retval;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
@@ -40,16 +41,35 @@ int mfconn_api_file_delete(mfconn * conn, const char *quickkey)
if (strlen(quickkey) != 15)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "file/delete.php",
"?quick_key=%s&response_format=json",
quickkey);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "file/delete.php",
"?quick_key=%s"
"&response_format=json", quickkey);
http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common, "file/delete");
http_destroy(http);
mfconn_update_secret_key(conn);
http = http_create();
retval =
http_get_buf(http, api_call, mfapi_decode_common, "file/delete");
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;
}

View File

@@ -38,6 +38,7 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file,
int retval;
int len;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
@@ -53,16 +54,34 @@ int mfconn_api_file_get_info(mfconn * conn, mffile * file,
if (len != 11 && len != 15)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "file/get_info.php",
"?quick_key=%s&response_format=json",
quickkey);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "file/get_info.php",
"?quick_key=%s"
"&response_format=json", quickkey);
http = http_create();
retval = http_get_buf(http, api_call, _decode_file_get_info, file);
http_destroy(http);
mfconn_update_secret_key(conn);
http = http_create();
retval = http_get_buf(http, api_call, _decode_file_get_info, file);
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;
}

View File

@@ -36,6 +36,7 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
int retval;
int len;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
@@ -51,16 +52,34 @@ int mfconn_api_file_get_links(mfconn * conn, mffile * file,
if (len != 11 && len != 15)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php",
"?quick_key=%s&response_format=json",
quickkey);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "file/get_links.php",
"?quick_key=%s"
"&response_format=json", quickkey);
http = http_create();
retval = http_get_buf(http, api_call, _decode_file_get_links, file);
http_destroy(http);
mfconn_update_secret_key(conn);
http = http_create();
retval = http_get_buf(http, api_call, _decode_file_get_links, file);
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;
}

View File

@@ -31,6 +31,7 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
const char *api_call;
int retval;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
@@ -45,25 +46,44 @@ int mfconn_api_folder_create(mfconn * conn, const char *parent,
return -1;
}
if (parent != NULL) {
api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php",
"?parent_key=%s&foldername=%s"
"&response_format=json", parent, name);
} else {
api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php",
"?foldername=%s&response_format=json",
name);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (parent != NULL) {
api_call =
mfconn_create_signed_get(conn, 0, "folder/create.php",
"?parent_key=%s&foldername=%s"
"&response_format=json", parent,
name);
} else {
api_call =
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;
}

View File

@@ -30,6 +30,7 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
const char *api_call;
int retval;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
@@ -40,17 +41,36 @@ int mfconn_api_folder_delete(mfconn * conn, const char *folderkey)
if (strlen(folderkey) != 13)
return -1;
api_call = mfconn_create_signed_get(conn, 0, "folder/delete.php",
"?folder_key=%s&response_format=json",
folderkey);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
api_call = mfconn_create_signed_get(conn, 0, "folder/delete.php",
"?folder_key=%s"
"&response_format=json",
folderkey);
http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common,
"folder/delete");
http_destroy(http);
mfconn_update_secret_key(conn);
http = http_create();
retval = http_get_buf(http, api_call, mfapi_decode_common,
"folder/delete");
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;
}

View File

@@ -46,7 +46,8 @@ static int _decode_folder_get_content_files(mfhttp * conn, void *data);
* pointers to them.
*/
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,
mffile *** mffile_result)
{
@@ -54,6 +55,8 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
int retval;
char *content_type;
mfhttp *http;
int i,
j;
if (conn == NULL)
return -1;
@@ -63,35 +66,71 @@ mfconn_api_folder_get_content(mfconn * conn, int mode, const char *folderkey,
else
content_type = "files";
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);
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) {
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;
}

View File

@@ -38,6 +38,7 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
const char *api_call;
int retval;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
@@ -50,23 +51,41 @@ mfconn_api_folder_get_info(mfconn * conn, mffolder * folder,
return -1;
}
if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
"?response_format=json");
} else {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
"?folder_key=%s"
"&response_format=json",
folderkey);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
"?response_format=json");
} else {
api_call = mfconn_create_signed_get(conn, 0, "folder/get_info.php",
"?folder_key=%s"
"&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;
}

View File

@@ -42,6 +42,7 @@ mfconn_api_upload_poll_upload(mfconn * conn, const char *upload_key,
int retval;
mfhttp *http;
struct upload_poll_upload_response response;
int i;
if (conn == NULL)
return -1;
@@ -49,18 +50,36 @@ mfconn_api_upload_poll_upload(mfconn * conn, const char *upload_key,
if (upload_key == NULL)
return -1;
// make an UNSIGNED get
api_call = mfconn_create_unsigned_get(conn, 0,
"upload/poll_upload.php",
"?response_format=json"
"&key=%s", upload_key);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
// make an UNSIGNED get
api_call = mfconn_create_unsigned_get(conn, 0,
"upload/poll_upload.php",
"?response_format=json"
"&key=%s", upload_key);
http = http_create();
retval = http_get_buf(http, api_call, _decode_upload_poll_upload,
&response);
http_destroy(http);
http = http_create();
retval = http_get_buf(http, api_call, _decode_upload_poll_upload,
&response);
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;
*fileerror = response.fileerror;

View File

@@ -44,6 +44,7 @@ mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
unsigned char hash[SHA256_DIGEST_LENGTH];
char *file_hash;
uint64_t file_size;
int i;
if (conn == NULL)
return -1;
@@ -64,29 +65,53 @@ mfconn_api_upload_simple(mfconn * conn, const char *folderkey,
file_hash = binary2hex(hash, SHA256_DIGEST_LENGTH);
if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0,
"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);
for (i = 0; i < mfconn_get_max_num_retries(conn); i++) {
if (*upload_key != NULL) {
free(*upload_key);
*upload_key = NULL;
}
if (folderkey == NULL) {
api_call = mfconn_create_signed_get(conn, 0,
"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((void *)api_call);
return retval;
}

View File

@@ -51,38 +51,65 @@ mfconn_api_user_get_session_token(mfconn * conn, const char *server,
int retval;
struct user_get_session_token_response response;
mfhttp *http;
int i;
if (conn == NULL)
return -1;
// configure url for operation
login_url = strdup_printf("https://%s/api/user/get_session_token.php",
server);
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
login_url = strdup_printf("https://%s/api/user/get_session_token.php",
server);
// create user signature
user_signature =
mfconn_create_user_signature(conn, username, password, app_id,
app_key);
// create user signature
user_signature =
mfconn_create_user_signature(conn, username, password, app_id,
app_key);
// FIXME: username and password have to be urlencoded (maybe using
// curl_easy_escape)
post_args = strdup_printf("email=%s"
"&password=%s"
"&application_id=%d"
"&signature=%s"
"&token_version=2"
"&response_format=json",
username, password, app_id, user_signature);
free((void *)user_signature);
// FIXME: username and password have to be urlencoded (maybe using
// curl_easy_escape)
post_args = strdup_printf("email=%s"
"&password=%s"
"&application_id=%d"
"&signature=%s"
"&token_version=2"
"&response_format=json",
username, password, app_id, user_signature);
free((void *)user_signature);
http = http_create();
retval =
http_post_buf(http, login_url, post_args,
_decode_get_session_token, (void *)(&response));
http_destroy(http);
http = http_create();
retval =
http_post_buf(http, login_url, post_args,
_decode_get_session_token, (void *)(&response));
http_destroy(http);
free(login_url);
free(post_args);
free(login_url);
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_time = response.secret_time;

View File

@@ -35,11 +35,16 @@ struct mfconn {
uint32_t secret_key;
char *secret_time;
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,
const char *password, int app_id,
const char *app_key)
const char *app_key, int max_num_retries)
{
mfconn *conn;
int retval;
@@ -59,24 +64,59 @@ mfconn *mfconn_create(const char *server, const char *username,
conn = (mfconn *) calloc(1, sizeof(mfconn));
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,
username, password, app_id,
app_key,
conn->username, conn->password,
conn->app_id, conn->app_key,
&(conn->secret_key),
&(conn->secret_time),
&(conn->session_token));
if (retval == 0)
return conn;
else {
if (retval != 0) {
fprintf(stderr, "error: mfconn_api_user_get_session_token\n");
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)
{
free(conn->server);
free(conn->username);
free(conn->password);
if (conn->app_key != NULL)
free(conn->app_key);
free(conn->secret_time);
free(conn->session_token);
free(conn);
@@ -334,3 +374,8 @@ uint32_t mfconn_get_secret_key(mfconn * conn)
{
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,
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);
@@ -54,4 +56,7 @@ const char *mfconn_get_session_token(mfconn * conn);
const char *mfconn_get_secret_time(mfconn * conn);
uint32_t mfconn_get_secret_key(mfconn * conn);
int mfconn_get_max_num_retries(mfconn * conn);
#endif