Skip to content

Commit

Permalink
Make webhooks more resilient
Browse files Browse the repository at this point in the history
* Do not quit on subscription API errors. Instead, wait a configurable interval before retrying.
* Shorten default webhook expiration and renewal intervals to reduce the chance of http 409 errors.
* Handle http 409 on subscription creation by taking over the existing subscription.
* Handle http 404 on subscription renewal by creating a new subscription(current behavior, listed for completeness).
* Log other known http errors include 400 (bad webhook endpoint), 401 (auth failed), and 403 (too many subscriptions).
* Log detailed messages when encoutering unknown http errors to assist with future debugging.
  • Loading branch information
Lyncredible committed Oct 16, 2023
1 parent 4a60654 commit 6fc4bbf
Show file tree
Hide file tree
Showing 6 changed files with 357 additions and 192 deletions.
5 changes: 3 additions & 2 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,9 @@
# webhook_public_url = ""
# webhook_listening_host = ""
# webhook_listening_port = "8888"
# webhook_expiration_interval = "86400"
# webhook_renewal_interval = "43200"
# webhook_expiration_interval = "600"
# webhook_renewal_interval = "300"
# webhook_retry_interval = "60"
# space_reservation = "50"
# display_running_config = "false"
# read_only_auth_scope = "false"
Expand Down
31 changes: 18 additions & 13 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ Before reading this document, please ensure you are running application version
- [Running 'onedrive' in 'monitor' mode](#running-onedrive-in-monitor-mode)
* [Use webhook to subscribe to remote updates in 'monitor' mode](#use-webhook-to-subscribe-to-remote-updates-in-monitor-mode)
* [More webhook configuration options](#more-webhook-configuration-options)
+ [webhook_listening_host and webhook_listening_port](#webhook_listening_host-and-webhook_listening_port)
+ [webhook_expiration_interval and webhook_renewal_interval](#webhook_expiration_interval-and-webhook_renewal_interval)
+ [Webhook listening host and port](#webhook-listening-host-and-port)
+ [Webhook expiration, renewal and retry intervals](#webhook-expiration-renewal-and-retry-intervals)
- [Running 'onedrive' as a system service](#running-onedrive-as-a-system-service)
* [OneDrive service running as root user via init.d](#onedrive-service-running-as-root-user-via-initd)
* [OneDrive service running as root user via systemd (Arch, Ubuntu, Debian, OpenSuSE, Fedora)](#onedrive-service-running-as-root-user-via-systemd-arch-ubuntu-debian-opensuse-fedora)
Expand Down Expand Up @@ -524,8 +524,8 @@ See the [config](https://raw.githubusercontent.com/abraunegg/onedrive/master/con
# webhook_public_url = ""
# webhook_listening_host = ""
# webhook_listening_port = "8888"
# webhook_expiration_interval = "86400"
# webhook_renewal_interval = "43200"
# webhook_expiration_interval = "600"
# webhook_renewal_interval = "300"
# space_reservation = "50"
# display_running_config = "false"
# read_only_auth_scope = "false"
Expand Down Expand Up @@ -891,8 +891,8 @@ By default, the application will reserve 50MB of disk space to prevent your file
Example:
```text
...
# webhook_expiration_interval = "86400"
# webhook_renewal_interval = "43200"
# webhook_expiration_interval = "600"
# webhook_renewal_interval = "300"
space_reservation = "10"
```

Expand Down Expand Up @@ -1059,7 +1059,7 @@ For any further nginx configuration assistance, please refer to: https://docs.ng

Below options can be optionally configured. The default is usually good enough.

#### webhook_listening_host and webhook_listening_port
#### Webhook listening host and port

Set `webhook_listening_host` and `webhook_listening_port` to change the webhook listening endpoint. If `webhook_listening_host` is left empty, which is the default, the webhook will bind to `0.0.0.0`. The default `webhook_listening_port` is `8888`.

Expand All @@ -1068,16 +1068,21 @@ webhook_listening_host = ""
webhook_listening_port = "8888"
```

#### webhook_expiration_interval and webhook_renewal_interval
#### Webhook expiration, renewal and retry intervals

Set `webhook_expiration_interval` and `webhook_renewal_interval` to change the frequency of subscription renewal. By default, the webhook asks Microsoft to keep subscriptions alive for 24 hours, and it renews subscriptions when it is less than 12 hours before their expiration.
Set `webhook_expiration_interval` and `webhook_renewal_interval` to change the frequency of subscription renewal. Set `webhook_retry_interval` to change the delay before retrying after an error happens while communicating with Microsoft's subscription endpoints.

By default, the webhook asks Microsoft to keep subscriptions alive for 10 minutes, and it renews subscriptions when it is less than 5 minutes before their expiration. When errors happen, it waits 1 minute before retrying.

```
# Default expiration interval is 24 hours
webhook_expiration_interval = "86400"
# Default expiration interval is 10 minutes
webhook_expiration_interval = "600"
# Default renewal interval is 5 minutes
webhook_renewal_interval = "300"
# Default renewal interval is 12 hours
webhook_renewal_interval = "43200"
# Default retry interval is 1 minute
webhook_retry_interval = "60"
```

## Running 'onedrive' as a system service
Expand Down
33 changes: 17 additions & 16 deletions src/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ final class Config
// Default file permission mode
public long defaultFilePermissionMode = 600;
public int configuredFilePermissionMode;

// Bring in v2.5.0 config items

// HTTP Struct items, used for configuring HTTP()
// Curl Timeout Handling
// libcurl dns_cache_timeout timeout
Expand All @@ -70,8 +70,8 @@ final class Config
immutable int defaultMaxRedirects = 5;
// Specify what IP protocol version should be used when communicating with OneDrive
immutable int defaultIpProtocol = 0; // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only



this(string confdirOption)
{
Expand Down Expand Up @@ -106,7 +106,7 @@ final class Config
longValues["min_notify_changes"] = 5;
longValues["monitor_log_frequency"] = 6;
// Number of N sync runs before performing a full local scan of sync_dir
// By default 12 which means every ~60 minutes a full disk scan of sync_dir will occur
// By default 12 which means every ~60 minutes a full disk scan of sync_dir will occur
// 'monitor_interval' * 'monitor_fullscan_frequency' = 3600 = 1 hour
longValues["monitor_fullscan_frequency"] = 12;
// Number of children in a path that is locally removed which will be classified as a 'big data delete'
Expand Down Expand Up @@ -158,8 +158,9 @@ final class Config
stringValues["webhook_public_url"] = "";
stringValues["webhook_listening_host"] = "";
longValues["webhook_listening_port"] = 8888;
longValues["webhook_expiration_interval"] = 3600 * 24;
longValues["webhook_renewal_interval"] = 3600 * 12;
longValues["webhook_expiration_interval"] = 60 * 10;
longValues["webhook_renewal_interval"] = 60 * 5;
longValues["webhook_retry_interval"] = 60;
// Log to application output running configuration values
boolValues["display_running_config"] = false;
// Configure read-only authentication scope
Expand Down Expand Up @@ -187,7 +188,7 @@ final class Config
// - Enabling this option will add function processing times to the console output
// - This then enables tracking of where the application is spending most amount of time when processing data when users have questions re performance
boolValues["display_processing_time"] = false;

// HTTPS & CURL Operation Settings
// - Maximum time an operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
Expand All @@ -200,7 +201,7 @@ final class Config
longValues["data_timeout"] = defaultDataTimeout;
// What IP protocol version should be used when communicating with OneDrive
longValues["ip_protocol_version"] = defaultIpProtocol; // 0 = IPv4 + IPv6, 1 = IPv4 Only, 2 = IPv6 Only

// EXPAND USERS HOME DIRECTORY
// Determine the users home directory.
// Need to avoid using ~ here as expandTilde() below does not interpret correctly when running under init.d or systemd scripts
Expand Down Expand Up @@ -282,7 +283,7 @@ final class Config
writeln("ERROR: ~/.config/onedrive is a file rather than a directory");
}
// Must exit
exit(EXIT_FAILURE);
exit(EXIT_FAILURE);
}
}

Expand Down Expand Up @@ -405,7 +406,7 @@ final class Config
&longValues["classify_as_big_delete"],
"cleanup-local-files",
"Cleanup additional local files when using --download-only. This will remove local data.",
&boolValues["cleanup_local_files"],
&boolValues["cleanup_local_files"],
"create-directory",
"Create a directory on OneDrive - no sync will be performed.",
&stringValues["create_directory"],
Expand Down Expand Up @@ -642,11 +643,11 @@ final class Config
// Use exit scopes to shutdown API
return false;
}

// We were able to readText the config file - so, we should be able to open and read it
auto file = File(filename, "r");
string lineBuffer;

// configure scopes
// - failure
scope(failure) {
Expand Down Expand Up @@ -711,7 +712,7 @@ final class Config
setValueString("skip_dir", configFileSkipDir);
}
}
// --single-directory Strip quotation marks from path
// --single-directory Strip quotation marks from path
// This is an issue when using ONEDRIVE_SINGLE_DIRECTORY with Docker
if (key == "single_directory") {
// Strip quotation marks from provided path
Expand Down Expand Up @@ -751,7 +752,7 @@ final class Config
if (key == "space_reservation") {
// temp value
ulong tempValue = to!long(c.front.dup);
// a value of 0 needs to be made at least 1MB ..
// a value of 0 needs to be made at least 1MB ..
if (tempValue == 0) {
tempValue = 1;
}
Expand Down Expand Up @@ -823,7 +824,7 @@ final class Config
}
return configuredFilePermissionMode;
}

void resetSkipToDefaults() {
// reset skip_file and skip_dir to application defaults
// skip_file
Expand Down
Loading

0 comments on commit 6fc4bbf

Please sign in to comment.