Add extra debugging & http protocol downgrade (Issue #314) (#327)

* Add --force-http-1.1 flag to downgrade any HTTP/2 curl operations to HTTP 1.1 protocol
* Explicitly set all bool items to false at initialisation
* Update --display-config to display sync_list if configured
* Add debug handling to display when sync_list is loaded
* Add debug handling to output the handling of OneDrive changes
This commit is contained in:
abraunegg 2019-01-06 05:43:44 +11:00 committed by GitHub
parent ddc5d602da
commit 1fa7e5f20c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 22 deletions

View file

@ -17,7 +17,7 @@ int main(string[] args)
// Application Option Variables
// Add a check mounts option to resolve https://github.com/abraunegg/onedrive/issues/8
bool checkMount;
bool checkMount = false;
// configuration directory
string configDirName;
// Create a single root directory on OneDrive
@ -25,7 +25,7 @@ int main(string[] args)
// The destination directory if we are using the OneDrive client to rename a directory
string destinationDirectory;
// Debug the HTTPS submit operations if required
bool debugHttp;
bool debugHttp = false;
// Do not use notifications in monitor mode
bool disableNotifications = false;
// Display application configuration but do not sync
@ -33,45 +33,49 @@ int main(string[] args)
// Display sync status
bool displaySyncStatus = false;
// only download remote changes
bool downloadOnly;
bool downloadOnly = false;
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
bool disableUploadValidation = false;
// Do we enable a log file
bool enableLogFile = false;
// Force the use of HTTP 1.1 to overcome curl => 7.62.0 where some operations are now sent via HTTP/2
// Whilst HTTP/2 operations are handled, in some cases the handling of this outside of the client is not being done correctly (router, other) thus the client breaks
// This flag then allows the user to downgrade all HTTP operations to HTTP 1.1 for maximum network path compatibility
bool forceHTTP11 = false;
// SharePoint / Office 365 Shared Library name to query
string o365SharedLibraryName;
// Local sync - Upload local changes first before downloading changes from OneDrive
bool localFirst;
bool localFirst = false;
// remove the current user and sync state
bool logout;
bool logout = false;
// enable monitor mode
bool monitor;
bool monitor = false;
// Add option for no remote delete
bool noRemoteDelete;
bool noRemoteDelete = false;
// print the access token
bool printAccessToken;
bool printAccessToken = false;
// force a full resync
bool resync;
bool resync = false;
// Remove a single directory on OneDrive
string removeDirectory;
// This allows for selective directory syncing instead of everything under ~/OneDrive/
string singleDirectory;
// Add option to skip symlinks
bool skipSymlinks;
bool skipSymlinks = false;
// The source directory if we are using the OneDrive client to rename a directory
string sourceDirectory;
// override the sync directory
string syncDirName;
// Configure a flag to perform a sync
// This is beneficial so that if just running the client itself - without any options, or sync check, the client does not perform a sync
bool synchronize;
bool synchronize = false;
// Upload Only
bool uploadOnly;
bool uploadOnly = false;
// enable verbose logging
bool verbose;
bool verbose = false;
// print the version and exit
bool printVersion;
bool printVersion = false;
// Application Startup option validation
try {
@ -90,6 +94,7 @@ int main(string[] args)
"download-only|d", "Only download remote changes", &downloadOnly,
"disable-upload-validation", "Disable upload validation when uploading to OneDrive", &disableUploadValidation,
"enable-logging", "Enable client activity to a separate log file", &enableLogFile,
"force-http-1.1", "Force the use of HTTP 1.1 for all operations", &forceHTTP11,
"get-O365-drive-id", "Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library", &o365SharedLibraryName,
"local-first", "Synchronize from the local directory source first, before downloading changes from OneDrive.", &localFirst,
"logout", "Logout the current user", &logout,
@ -276,6 +281,8 @@ int main(string[] args)
if (displayConfiguration){
string userConfigFilePath = configDirName ~ "/config";
string userSyncList = configDirName ~ "/sync_list";
// Display application version
std.stdio.write("onedrive version = ", import("version"));
// Display all of the pertinent configuration options
writeln("Config path = ", configDirName);
@ -301,6 +308,14 @@ int main(string[] args)
// Is sync_list configured?
if (exists(userSyncList)){
writeln("Selective sync configured = true");
writeln("sync_list contents:");
// Output the sync_list contents
auto syncListFile = File(userSyncList);
auto range = syncListFile.byLine();
foreach (line; range)
{
writeln(line);
}
} else {
writeln("Selective sync configured = false");
}
@ -320,7 +335,7 @@ int main(string[] args)
}
// Initialize OneDrive, check for authorization
oneDrive = new OneDriveApi(cfg, debugHttp);
oneDrive = new OneDriveApi(cfg, debugHttp, forceHTTP11);
oneDrive.printAccessToken = printAccessToken;
if (!oneDrive.init()) {
log.error("Could not initialize the OneDrive API");
@ -362,6 +377,16 @@ int main(string[] args)
// Configure selective sync by parsing and getting a regex for skip_file config component
auto selectiveSync = new SelectiveSync();
if (exists(cfg.syncListFilePath)){
log.vdebug("Loading user configured sync_list file ...");
// list what will be synced
auto syncListFile = File(cfg.syncListFilePath);
auto range = syncListFile.byLine();
foreach (line; range)
{
log.vdebug("sync_list: ", line);
}
}
selectiveSync.load(cfg.syncListFilePath);
selectiveSync.setMask(cfg.getValue("skip_file"));

View file

@ -64,7 +64,7 @@ final class OneDriveApi
// if true, every new access token is printed
bool printAccessToken;
this(Config cfg, bool debugHttp)
this(Config cfg, bool debugHttp, bool forceHTTP11)
{
this.cfg = cfg;
http = HTTP();
@ -91,10 +91,19 @@ final class OneDriveApi
// Specify how many redirects should be allowed
http.maxRedirects(5);
// Do we enable curl debugging?
if (debugHttp) {
http.verbose = true;
.debugResponse = true;
}
// What version of HTTP protocol do we use?
// Curl >= 7.62.0 defaults to http2 for a significant number of operations
if (forceHTTP11) {
log.vdebug("Downgrading all HTTP operations to HTTP 1.1");
// Downgrade to HTTP 1.1 - yes version = 2 is HTTP 1.1
http.handle.set(CurlOption.http_version,2);
}
}
bool init()

View file

@ -491,6 +491,14 @@ final class SyncEngine
syncFolderChildPath = "";
}
}
// Debug Output
log.vdebug("Sync Folder Name: ", syncFolderName);
// Debug Output of path if only set, generally only set if using --single-directory
if (hasParentReferencePath(idDetails)) {
log.vdebug("Sync Folder Path: ", syncFolderPath);
log.vdebug("Sync Folder Child Path: ", syncFolderChildPath);
}
}
for (;;) {
@ -542,6 +550,8 @@ final class SyncEngine
// Are there any changes to process?
if (("value" in changes) != null) {
// There are valid changes
log.vdebug("Number of changes from OneDrive to process: ", count(changes["value"].array));
foreach (item; changes["value"].array) {
bool isRoot = false;
string thisItemPath;
@ -642,7 +652,9 @@ final class SyncEngine
// Reset the downloadFailed flag for this item
downloadFailed = false;
// Is the change from OneDrive a 'root' item
if (isItemRoot(driveItem) || !item.parentId || isRoot) {
log.vdebug("Handing a OneDrive 'root' change");
item.parentId = null; // ensures that it has no parent
item.driveId = driveId; // HACK: makeItem() cannot set the driveId property of the root
itemdb.upsert(item);
@ -656,11 +668,11 @@ final class SyncEngine
// check the item type
if (!unwanted) {
if (isItemFile(driveItem)) {
//log.vlog("The item we are syncing is a file");
log.vdebug("The item we are syncing is a file");
} else if (isItemFolder(driveItem)) {
//log.vlog("The item we are syncing is a folder");
log.vdebug("The item we are syncing is a folder");
} else if (isItemRemote(driveItem)) {
//log.vlog("The item we are syncing is a remote item");
log.vdebug("The item we are syncing is a remote item");
assert(isItemFolder(driveItem["remoteItem"]), "The remote item is not a folder");
} else {
log.vlog("This item type (", item.name, ") is not supported");
@ -676,6 +688,9 @@ final class SyncEngine
path = itemdb.computePath(item.driveId, item.parentId) ~ "/" ~ item.name;
path = buildNormalizedPath(path);
unwanted = selectiveSync.isPathExcluded(path);
if (unwanted) {
log.vdebug("OneDrive change path is to be excluded by user configuration: ", path);
}
} else {
unwanted = true;
}
@ -683,7 +698,7 @@ final class SyncEngine
// skip unwanted items early
if (unwanted) {
//log.vlog("Filtered out");
log.vdebug("Skipping OneDrive change as this is determined to be unwanted");
skippedItems ~= item.id;
return;
}
@ -695,8 +710,7 @@ final class SyncEngine
// check if the item is going to be deleted
if (isItemDeleted(driveItem)) {
// item.name is not available, so we get a bunch of meaningless log output
// will fix this with wider logging changes being worked on
//log.vlog("This item is marked for deletion:", item.name);
// Item name we will attempt to delete will be printed out later
if (cached) {
// flag to delete
idsToDelete ~= [item.driveId, item.id];
@ -723,8 +737,10 @@ final class SyncEngine
// update the item
if (cached) {
log.vdebug("OneDrive change is an update to an existing local item");
applyChangedItem(oldItem, oldPath, item, path);
} else {
log.vdebug("OneDrive change is a new local item");
applyNewItem(item, path);
}