mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-29 12:19:03 +03:00
Merge pull request #4159 from owncloud/fix_3490
csync updater: Handle file firewall reply codes correctly: Ignore the files. Fixes #3490
This commit is contained in:
commit
b0c29d5c66
5 changed files with 46 additions and 16 deletions
|
@ -102,7 +102,8 @@ enum csync_status_codes_e {
|
||||||
CYSNC_STATUS_FILE_LOCKED_OR_OPEN,
|
CYSNC_STATUS_FILE_LOCKED_OR_OPEN,
|
||||||
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN,
|
CSYNC_STATUS_INDIVIDUAL_EXCLUDE_HIDDEN,
|
||||||
CSYNC_STATUS_INVALID_CHARACTERS,
|
CSYNC_STATUS_INVALID_CHARACTERS,
|
||||||
CSYNC_STATUS_INDIVIDUAL_STAT_FAILED
|
CSYNC_STATUS_INDIVIDUAL_STAT_FAILED,
|
||||||
|
CSYNC_STATUS_FORBIDDEN
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum csync_status_codes_e CSYNC_STATUS;
|
typedef enum csync_status_codes_e CSYNC_STATUS;
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#define ERRNO_SERVICE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+14
|
#define ERRNO_SERVICE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+14
|
||||||
#define ERRNO_USER_ABORT CSYNC_CUSTOM_ERRNO_BASE+16
|
#define ERRNO_USER_ABORT CSYNC_CUSTOM_ERRNO_BASE+16
|
||||||
#define ERRNO_STORAGE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+17
|
#define ERRNO_STORAGE_UNAVAILABLE CSYNC_CUSTOM_ERRNO_BASE+17
|
||||||
|
#define ERRNO_FORBIDDEN CSYNC_CUSTOM_ERRNO_BASE+18
|
||||||
|
|
||||||
#endif /* _CSYNC_MACROS_H */
|
#endif /* _CSYNC_MACROS_H */
|
||||||
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
/* vim: set ft=c.doxygen ts=8 sw=2 et cindent: */
|
||||||
|
|
|
@ -573,6 +573,26 @@ static bool fill_tree_from_db(CSYNC *ctx, const char *uri)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set the current item to an ignored state.
|
||||||
|
* If the item is set to ignored, the update phase continues, ie. its not a hard error */
|
||||||
|
static bool mark_current_item_ignored( CSYNC *ctx, csync_file_stat_t *previous_fs, CSYNC_STATUS status )
|
||||||
|
{
|
||||||
|
if(!ctx) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->current_fs) {
|
||||||
|
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
|
||||||
|
ctx->current_fs->error_status = status;
|
||||||
|
/* If a directory has ignored files, put the flag on the parent directory as well */
|
||||||
|
if( previous_fs ) {
|
||||||
|
previous_fs->has_ignored_files = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* File tree walker */
|
/* File tree walker */
|
||||||
int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||||
unsigned int depth) {
|
unsigned int depth) {
|
||||||
|
@ -625,13 +645,8 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||||
/* permission denied */
|
/* permission denied */
|
||||||
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
|
ctx->status_code = csync_errno_to_status(errno, CSYNC_STATUS_OPENDIR_ERROR);
|
||||||
if (errno == EACCES) {
|
if (errno == EACCES) {
|
||||||
if (ctx->current_fs) {
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Permission denied.");
|
||||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
|
if (mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_PERMISSION_DENIED)) {
|
||||||
ctx->current_fs->error_status = CSYNC_STATUS_PERMISSION_DENIED;
|
|
||||||
/* If a directory has ignored files, put the flag on the parent directory as well */
|
|
||||||
if( previous_fs ) {
|
|
||||||
previous_fs->has_ignored_files = true;
|
|
||||||
}
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
} else if(errno == ENOENT) {
|
} else if(errno == ENOENT) {
|
||||||
|
@ -640,19 +655,22 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn,
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "asprintf failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 403 Forbidden can be sent by the server if the file firewall is active.
|
||||||
|
// A file or directory should be ignored and sync must continue. See #3490
|
||||||
|
else if(errno == ERRNO_FORBIDDEN) {
|
||||||
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Directory access Forbidden (File Firewall?)");
|
||||||
|
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_FORBIDDEN) ) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* if current_fs is not defined here, better throw an error */
|
||||||
|
}
|
||||||
// The server usually replies with the custom "503 Storage not available"
|
// The server usually replies with the custom "503 Storage not available"
|
||||||
// if some path is temporarily unavailable. But in some cases a standard 503
|
// if some path is temporarily unavailable. But in some cases a standard 503
|
||||||
// is returned too. Thus we can't distinguish the two and will treat any
|
// is returned too. Thus we can't distinguish the two and will treat any
|
||||||
// 503 as request to ignore the folder. See #3113 #2884.
|
// 503 as request to ignore the folder. See #3113 #2884.
|
||||||
else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
|
else if(errno == ERRNO_STORAGE_UNAVAILABLE || errno == ERRNO_SERVICE_UNAVAILABLE) {
|
||||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
|
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Storage was not available!");
|
||||||
if (ctx->current_fs) {
|
if( mark_current_item_ignored(ctx, previous_fs, CSYNC_STATUS_STORAGE_UNAVAILABLE ) ) {
|
||||||
ctx->current_fs->instruction = CSYNC_INSTRUCTION_IGNORE;
|
|
||||||
ctx->current_fs->error_status = CSYNC_STATUS_STORAGE_UNAVAILABLE;
|
|
||||||
/* If a directory has ignored files, put the flag on the parent directory as well */
|
|
||||||
if( previous_fs ) {
|
|
||||||
previous_fs->has_ignored_files = true;
|
|
||||||
}
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* if current_fs is not defined here, better throw an error */
|
/* if current_fs is not defined here, better throw an error */
|
||||||
|
|
|
@ -160,8 +160,10 @@ int get_errno_from_http_errcode( int err, const QString & reason ) {
|
||||||
case 423: /* Locked */
|
case 423: /* Locked */
|
||||||
new_errno = EACCES;
|
new_errno = EACCES;
|
||||||
break;
|
break;
|
||||||
case 400: /* Bad Request */
|
|
||||||
case 403: /* Forbidden */
|
case 403: /* Forbidden */
|
||||||
|
new_errno = ERRNO_FORBIDDEN;
|
||||||
|
break;
|
||||||
|
case 400: /* Bad Request */
|
||||||
case 409: /* Conflict */
|
case 409: /* Conflict */
|
||||||
case 411: /* Length Required */
|
case 411: /* Length Required */
|
||||||
case 412: /* Precondition Failed */
|
case 412: /* Precondition Failed */
|
||||||
|
|
|
@ -161,6 +161,9 @@ QString SyncEngine::csyncErrorToString(CSYNC_STATUS err)
|
||||||
case CSYNC_STATUS_STORAGE_UNAVAILABLE:
|
case CSYNC_STATUS_STORAGE_UNAVAILABLE:
|
||||||
errStr = tr("The mounted folder is temporarily not available on the server");
|
errStr = tr("The mounted folder is temporarily not available on the server");
|
||||||
break;
|
break;
|
||||||
|
case CSYNC_STATUS_FORBIDDEN:
|
||||||
|
errStr = tr("Access is forbidden");
|
||||||
|
break;
|
||||||
case CSYNC_STATUS_OPENDIR_ERROR:
|
case CSYNC_STATUS_OPENDIR_ERROR:
|
||||||
errStr = tr("An error occurred while opening a folder");
|
errStr = tr("An error occurred while opening a folder");
|
||||||
break;
|
break;
|
||||||
|
@ -412,6 +415,11 @@ int SyncEngine::treewalkFile( TREE_WALK_FILE *file, bool remote )
|
||||||
item->_status = SyncFileItem::SoftError;
|
item->_status = SyncFileItem::SoftError;
|
||||||
_temporarilyUnavailablePaths.insert(item->_file);
|
_temporarilyUnavailablePaths.insert(item->_file);
|
||||||
break;
|
break;
|
||||||
|
case CSYNC_STATUS_FORBIDDEN:
|
||||||
|
item->_errorString = QLatin1String("Access forbidden.");
|
||||||
|
item->_status = SyncFileItem::SoftError;
|
||||||
|
_temporarilyUnavailablePaths.insert(item->_file);
|
||||||
|
break;
|
||||||
case CSYNC_STATUS_PERMISSION_DENIED:
|
case CSYNC_STATUS_PERMISSION_DENIED:
|
||||||
item->_errorString = QLatin1String("Directory not accessible on client, permission denied.");
|
item->_errorString = QLatin1String("Directory not accessible on client, permission denied.");
|
||||||
item->_status = SyncFileItem::SoftError;
|
item->_status = SyncFileItem::SoftError;
|
||||||
|
|
Loading…
Reference in a new issue