cloud sync: clean up directory/filename mapping, log errors (#15561)

This commit is contained in:
Eric Warmenhoven 2023-08-07 14:43:22 -04:00 committed by GitHub
parent fa80e5e6be
commit 3ef31d2eee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 36 deletions

View File

@ -439,6 +439,16 @@ static char *webdav_get_auth_header(const char *method, const char *url)
return webdav_st->digest_auth_header;
}
static void webdav_log_http_failure(const char *path, http_transfer_data_t *data)
{
int i;
RARCH_WARN("webdav failed: %s: HTTP %d\n", path, data->status);
for (i = 0; data->headers && i < data->headers->size; i++)
RARCH_WARN("%s\n", data->headers->elems[i].data);
if (data->data)
RARCH_WARN("%s\n", data->data);
}
static void webdav_stat_cb(retro_task_t *task, void *task_data, void *user_data, const char *err)
{
webdav_state_t *webdav_st = webdav_state_get_ptr();
@ -465,9 +475,14 @@ static void webdav_stat_cb(retro_task_t *task, void *task_data, void *user_data,
webdav_stat_cb, webdav_cb_st);
return;
}
else
RARCH_WARN("failure creating WWW-Authenticate: Digest header\n");
}
}
if (!success && data)
webdav_log_http_failure(webdav_st->url, data);
webdav_cb_st->cb(webdav_cb_st->user_data, NULL, success, NULL);
free(webdav_cb_st);
}
@ -477,6 +492,7 @@ static bool webdav_sync_begin(cloud_sync_complete_handler_t cb, void *user_data)
settings_t *settings = config_get_ptr();
const char *url = settings->arrays.webdav_url;
webdav_state_t *webdav_st = webdav_state_get_ptr();
size_t len = 0;
const char *auth_header;
if (string_is_empty(url))
@ -484,7 +500,9 @@ static bool webdav_sync_begin(cloud_sync_complete_handler_t cb, void *user_data)
// TODO: LOCK?
strlcpy(webdav_st->url, url, sizeof(webdav_st->url));
if (!strstr(url, "://"))
len += strlcpy(webdav_st->url, "http://", STRLEN_CONST("http://"));
strlcpy(webdav_st->url + len, url, sizeof(webdav_st->url) - len);
fill_pathname_slash(webdav_st->url, sizeof(webdav_st->url));
/* url/username/password may have changed, redo auth check */
@ -529,8 +547,11 @@ static void webdav_read_cb(retro_task_t *task, void *task_data, void *user_data,
success = (data &&
((data->status >= 200 && data->status < 300) || data->status == 404));
if (!success && data)
webdav_log_http_failure(webdav_cb_st->path, data);
// TODO: it's possible we get a 401 here and need to redo the auth check with this request
if (data && data->data && webdav_cb_st)
if (success && data->data && webdav_cb_st)
{
// TODO: it would be better if writing to the file happened during the network reads
file = filestream_open(webdav_cb_st->file,
@ -582,6 +603,8 @@ static void webdav_mkdir_cb(retro_task_t *task, void *task_data, void *user_data
// TODO: it's possible we get a 401 here and need to redo the auth check with this request
if (!data || data->status < 200 || data->status >= 400)
{
if (data)
webdav_log_http_failure(webdav_mkdir_st->url, data);
webdav_mkdir_st->cb(false, webdav_mkdir_st->cb_st);
free(webdav_mkdir_st);
return;
@ -627,6 +650,9 @@ static void webdav_update_cb(retro_task_t *task, void *task_data, void *user_dat
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
bool success = (data && data->status >= 200 && data->status < 300);
if (!success && data)
webdav_log_http_failure(webdav_cb_st->path, data);
// TODO: it's possible we get a 401 here and need to redo the auth check with this request
if (webdav_cb_st)
{
@ -697,6 +723,9 @@ static void webdav_delete_cb(retro_task_t *task, void *task_data, void *user_dat
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
bool success = (data != NULL && data->status >= 200 && data->status < 300);
if (!success && data)
webdav_log_http_failure(webdav_cb_st->path, data);
// TODO: it's possible we get a 401 here and need to redo the auth check with this request
if (webdav_cb_st)
{
@ -711,6 +740,9 @@ static void webdav_backup_cb(retro_task_t *task, void *task_data, void *user_dat
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
bool success = (data != NULL && data->status >= 200 && data->status < 300);
if (!success && data)
webdav_log_http_failure(webdav_cb_st->path, data);
// TODO: it's possible we get a 401 here and need to redo the auth check with this request
if (webdav_cb_st)
{

View File

@ -274,9 +274,33 @@ static void task_cloud_sync_manifest_append_dir(file_list_t *manifest,
}
}
static struct string_list *task_cloud_sync_directory_map(void)
{
static struct string_list *list = NULL;
if (!list)
{
union string_list_elem_attr attr = {0};
char dir[PATH_MAX_LENGTH];
list = string_list_new();
string_list_append(list, "config", attr);
fill_pathname_application_special(dir,
sizeof(dir), APPLICATION_SPECIAL_DIRECTORY_CONFIG);
list->elems[list->size - 1].userdata = strdup(dir);
string_list_append(list, "saves", attr);
list->elems[list->size - 1].userdata = strdup(dir_get_ptr(RARCH_DIR_SAVEFILE));
string_list_append(list, "states", attr);
list->elems[list->size - 1].userdata = strdup(dir_get_ptr(RARCH_DIR_SAVESTATE));
}
return list;
}
static void task_cloud_sync_build_current_manifest(task_cloud_sync_state_t *sync_state)
{
char config_dir[PATH_MAX_LENGTH];
struct string_list *dirlist = task_cloud_sync_directory_map();
int i;
sync_state->current_manifest = (file_list_t *)calloc(1, sizeof(file_list_t));
if (!sync_state->current_manifest)
@ -297,13 +321,9 @@ static void task_cloud_sync_build_current_manifest(task_cloud_sync_state_t *sync
return;
}
fill_pathname_application_special(config_dir,
sizeof(config_dir),
APPLICATION_SPECIAL_DIRECTORY_CONFIG);
task_cloud_sync_manifest_append_dir(sync_state->current_manifest, config_dir, "config");
task_cloud_sync_manifest_append_dir(sync_state->current_manifest, dir_get_ptr(RARCH_DIR_SAVEFILE), "saves");
task_cloud_sync_manifest_append_dir(sync_state->current_manifest, dir_get_ptr(RARCH_DIR_SAVESTATE), "states");
for (i = 0; i < dirlist->size; i++)
task_cloud_sync_manifest_append_dir(sync_state->current_manifest,
dirlist->elems[i].userdata, dirlist->elems[i].data);
file_list_sort_on_alt(sync_state->current_manifest);
sync_state->phase = CLOUD_SYNC_PHASE_DIFF;
@ -431,19 +451,11 @@ static void task_cloud_sync_fetch_cb(void *user_data, const char *path, bool suc
hash = task_cloud_sync_md5_rfile(file);
filestream_close(file);
RARCH_LOG(CSPFX "successfully fetched %s\n", path);
task_cloud_sync_add_to_updated_manifest(sync_state, path, hash, true);
task_cloud_sync_add_to_updated_manifest(sync_state, path, hash, false);
/* no need to mark need_manifest_uploaded, nothing changed */
}
else
{
/* on failure, don't add it to local manifest, that will cause a fetch again next time */
size_t idx;
if (file_list_search(sync_state->server_manifest, path, &idx))
{
struct item_file *server_file = &sync_state->server_manifest->list[idx];
task_cloud_sync_add_to_updated_manifest(sync_state, path, CS_FILE_HASH(server_file), true);
}
if (!success)
RARCH_WARN(CSPFX "failed to fetch %s\n", path);
else
@ -455,27 +467,34 @@ static void task_cloud_sync_fetch_cb(void *user_data, const char *path, bool suc
static void task_cloud_sync_fetch_server_file(task_cloud_sync_state_t *sync_state)
{
char filename[PATH_MAX_LENGTH];
struct item_file *server_file = &sync_state->server_manifest->list[sync_state->server_idx];
const char *key = CS_FILE_KEY(server_file);
const char *path = strchr(key, PATH_DEFAULT_SLASH_C()) + 1;
char directory[PATH_MAX_LENGTH];
settings_t *settings = config_get_ptr();
struct string_list *dirlist = task_cloud_sync_directory_map();
struct item_file *server_file = &sync_state->server_manifest->list[sync_state->server_idx];
const char *key = CS_FILE_KEY(server_file);
const char *path = strchr(key, PATH_DEFAULT_SLASH_C()) + 1;
char directory[PATH_MAX_LENGTH];
char filename[PATH_MAX_LENGTH];
settings_t *settings = config_get_ptr();
int i;
RARCH_LOG(CSPFX "fetching %s\n", key);
/* we're just fetching a file the server has, we can update this now */
task_cloud_sync_add_to_updated_manifest(sync_state, key, CS_FILE_HASH(server_file), true);
/* no need to mark need_manifest_uploaded, nothing changed */
if (string_starts_with(key, "config"))
filename[0] = '\0';
for (i = 0; i < dirlist->size; i++)
{
char config_dir[PATH_MAX_LENGTH];
fill_pathname_application_special(config_dir,
sizeof(config_dir),
APPLICATION_SPECIAL_DIRECTORY_CONFIG);
fill_pathname_join_special(filename, config_dir, path, sizeof(filename));
if (!string_starts_with(key, dirlist->elems[i].data))
continue;
fill_pathname_join_special(filename, dirlist->elems[i].userdata, path, sizeof(filename));
break;
}
if (string_is_empty(filename))
{
/* how did this end up here? we don't know where to put it... */
RARCH_WARN(CSPFX "don't know where to put %s!\n", key);
return;
}
else if (string_starts_with(key, "saves"))
fill_pathname_join_special(filename, dir_get_ptr(RARCH_DIR_SAVEFILE), path, sizeof(filename));
else if (string_starts_with(key, "states"))
fill_pathname_join_special(filename, dir_get_ptr(RARCH_DIR_SAVESTATE), path, sizeof(filename));
if (!settings->bools.cloud_sync_destructive && path_is_valid(filename))
{
@ -492,8 +511,6 @@ static void task_cloud_sync_fetch_server_file(task_cloud_sync_state_t *sync_stat
{
RARCH_WARN(CSPFX "wanted to fetch %s but failed\n", key);
sync_state->failures = true;
task_cloud_sync_add_to_updated_manifest(sync_state, key, CS_FILE_HASH(server_file), true);
/* no need to mark need_manifest_uploaded, nothing changed */
}
}