Browse Source

Make timeout configurable

timvisee 6 years ago
parent
commit
f693ff42d3

+ 6 - 4
README.md

@@ -254,10 +254,12 @@ The following environment variables may be used to configure the following
 defaults. The CLI flag is shown along with it, to better describe the relation
 defaults. The CLI flag is shown along with it, to better describe the relation
 to command line arguments:
 to command line arguments:
 
 
-| Variable         | CLI flag           | Description       |
-| :--------------- | :----------------: | :---------------- |
-| `FFSEND_HISTORY` | `--history <FILE>` | History file path |
-| `FFSEND_HOST`    | `--host <URL>`     | Upload host       |
+| Variable                  | CLI flag                       | Description                     |
+| :------------------------ | :----------------------------: | :------------------------------ |
+| `FFSEND_HISTORY`          | `--history <FILE>`             | History file path               |
+| `FFSEND_HOST`             | `--host <URL>`                 | Upload host                     |
+| `FFSEND_TIMEOUT`          | `--timeout <SECONDS>`          | Request timeout (0 to disable)  |
+| `FFSEND_TRANSFER_TIMEOUT` | `--transfer-timeout <SECONDS>` | Transfer timeout (0 to disable) |
 
 
 These environment variables may be used to toggle a flag, simply by making them
 These environment variables may be used to toggle a flag, simply by making them
 available. The actual value of these variables is ignored, and variables may be
 available. The actual value of these variables is ignored, and variables may be

+ 1 - 1
src/action/delete.rs

@@ -32,7 +32,7 @@ impl<'a> Delete<'a> {
 
 
         // Create a reqwest client
         // Create a reqwest client
         // TODO: create transfer client when draining downloads
         // TODO: create transfer client when draining downloads
-        let client = create_client();
+        let client = create_client(&matcher_main);
 
 
         // Parse the remote file based on the share link, derive the owner token from history
         // Parse the remote file based on the share link, derive the owner token from history
         let mut file = RemoteFile::parse_url(url, matcher_delete.owner())?;
         let mut file = RemoteFile::parse_url(url, matcher_delete.owner())?;

+ 1 - 1
src/action/download.rs

@@ -48,7 +48,7 @@ impl<'a> Download<'a> {
         let url = matcher_download.url();
         let url = matcher_download.url();
 
 
         // Create a reqwest client capable for downloading files
         // Create a reqwest client capable for downloading files
-        let client = create_transfer_client();
+        let client = create_transfer_client(&matcher_main);
 
 
         // Parse the remote file based on the share URL
         // Parse the remote file based on the share URL
         let file = RemoteFile::parse_url(url, None)?;
         let file = RemoteFile::parse_url(url, None)?;

+ 1 - 1
src/action/exists.rs

@@ -33,7 +33,7 @@ impl<'a> Exists<'a> {
         let url = matcher_exists.url();
         let url = matcher_exists.url();
 
 
         // Create a reqwest client
         // Create a reqwest client
-        let client = create_client();
+        let client = create_client(&matcher_main);
 
 
         // Parse the remote file based on the share URL
         // Parse the remote file based on the share URL
         let file = RemoteFile::parse_url(url, None)?;
         let file = RemoteFile::parse_url(url, None)?;

+ 1 - 1
src/action/info.rs

@@ -35,7 +35,7 @@ impl<'a> Info<'a> {
         let url = matcher_info.url();
         let url = matcher_info.url();
 
 
         // Create a reqwest client
         // Create a reqwest client
-        let client = create_client();
+        let client = create_client(&matcher_main);
 
 
         // Parse the remote file based on the share URL, derive the owner token from history
         // Parse the remote file based on the share URL, derive the owner token from history
         let mut file = RemoteFile::parse_url(url, matcher_info.owner())?;
         let mut file = RemoteFile::parse_url(url, matcher_info.owner())?;

+ 1 - 1
src/action/params.rs

@@ -31,7 +31,7 @@ impl<'a> Params<'a> {
         let url = matcher_params.url();
         let url = matcher_params.url();
 
 
         // Create a reqwest client
         // Create a reqwest client
-        let client = create_client();
+        let client = create_client(&matcher_main);
 
 
         // Parse the remote file based on the share URL, derive the owner token from history
         // Parse the remote file based on the share URL, derive the owner token from history
         let mut file = RemoteFile::parse_url(url, matcher_params.owner())?;
         let mut file = RemoteFile::parse_url(url, matcher_params.owner())?;

+ 1 - 1
src/action/password.rs

@@ -32,7 +32,7 @@ impl<'a> Password<'a> {
         let url = matcher_password.url();
         let url = matcher_password.url();
 
 
         // Create a reqwest client
         // Create a reqwest client
-        let client = create_client();
+        let client = create_client(&matcher_main);
 
 
         // Parse the remote file based on the share URL, derive the owner token from history
         // Parse the remote file based on the share URL, derive the owner token from history
         let mut file = RemoteFile::parse_url(url, matcher_password.owner())?;
         let mut file = RemoteFile::parse_url(url, matcher_password.owner())?;

+ 1 - 1
src/action/upload.rs

@@ -91,7 +91,7 @@ impl<'a> Upload<'a> {
         }
         }
 
 
         // Create a reqwest client capable for uploading files
         // Create a reqwest client capable for uploading files
-        let client = create_transfer_client();
+        let client = create_transfer_client(&matcher_main);
 
 
         // Create a progress bar reporter
         // Create a progress bar reporter
         let progress_bar = Arc::new(Mutex::new(ProgressBar::new_upload()));
         let progress_bar = Arc::new(Mutex::new(ProgressBar::new_upload()));

+ 14 - 5
src/client.rs

@@ -2,20 +2,20 @@ use std::time::Duration;
 
 
 use ffsend_api::reqwest::{Client, ClientBuilder};
 use ffsend_api::reqwest::{Client, ClientBuilder};
 
 
-use config::{CLIENT_TIMEOUT, CLIENT_TRANSFER_TIMEOUT};
+use cmd::matcher::MainMatcher;
 
 
 /// Create the default client, which is used for generic Send requests.
 /// Create the default client, which is used for generic Send requests.
 ///
 ///
 /// Note: use `create_transfer_client()` instead for clients that upload/download.
 /// Note: use `create_transfer_client()` instead for clients that upload/download.
-pub fn create_client() -> Client {
-    create_custom_client(CLIENT_TIMEOUT)
+pub fn create_client(matcher_main: &MainMatcher) -> Client {
+    create_custom_client(to_duration(matcher_main.timeout()))
 }
 }
 
 
 /// Create the default client, which is used for generic Send requests.
 /// Create the default client, which is used for generic Send requests.
 ///
 ///
 /// Note: use `create_transfer_client()` instead for clients that upload/download.
 /// Note: use `create_transfer_client()` instead for clients that upload/download.
-pub fn create_transfer_client() -> Client {
-    create_custom_client(CLIENT_TRANSFER_TIMEOUT)
+pub fn create_transfer_client(matcher_main: &MainMatcher) -> Client {
+    create_custom_client(to_duration(matcher_main.transfer_timeout()))
 }
 }
 
 
 /// Create the Send client with a custom timeout.
 /// Create the Send client with a custom timeout.
@@ -25,3 +25,12 @@ fn create_custom_client(timeout: Option<Duration>) -> Client {
         .build()
         .build()
         .expect("failed to build custom reqwest client")
         .expect("failed to build custom reqwest client")
 }
 }
+
+/// Convert the given number of seconds into an optional duration, used for clients.
+fn to_duration(secs: u64) -> Option<Duration> {
+    if secs > 0 {
+        Some(Duration::from_secs(secs))
+    } else {
+        None
+    }
+}

+ 52 - 0
src/cmd/handler.rs

@@ -2,6 +2,7 @@ extern crate directories;
 
 
 use clap::{App, AppSettings, Arg, ArgMatches};
 use clap::{App, AppSettings, Arg, ArgMatches};
 
 
+use config::{CLIENT_TIMEOUT, CLIENT_TRANSFER_TIMEOUT};
 #[cfg(feature = "history")]
 #[cfg(feature = "history")]
 use super::matcher::HistoryMatcher;
 use super::matcher::HistoryMatcher;
 use super::matcher::{
 use super::matcher::{
@@ -20,6 +21,12 @@ use util::app_history_file_path_string;
 lazy_static! {
 lazy_static! {
     /// The default history file
     /// The default history file
     static ref DEFAULT_HISTORY_FILE: String = app_history_file_path_string();
     static ref DEFAULT_HISTORY_FILE: String = app_history_file_path_string();
+
+    /// The default client timeout in seconds as a string
+    static ref DEFAULT_TIMEOUT: String = format!("{}", CLIENT_TIMEOUT);
+
+    /// The default client transfer timeout in seconds as a string
+    static ref DEFAULT_TRANSFER_TIMEOUT: String = format!("{}", CLIENT_TRANSFER_TIMEOUT);
 }
 }
 
 
 /// CLI argument handler.
 /// CLI argument handler.
@@ -69,6 +76,51 @@ impl<'a: 'b, 'b> Handler<'a> {
                     .global(true)
                     .global(true)
                     .help("Assume yes for prompts"),
                     .help("Assume yes for prompts"),
             )
             )
+            .arg(
+                Arg::with_name("timeout")
+                    .long("timeout")
+                    .short("t")
+                    .alias("time")
+                    .global(true)
+                    .value_name("SECONDS")
+                    .help("Request timeout (0 to disable)")
+                    .default_value(&DEFAULT_TIMEOUT)
+                    .hide_default_value(true)
+                    .env("FFSEND_TIMEOUT")
+                    .hide_env_values(true)
+                    .validator(|arg| arg
+                        .parse::<u64>()
+                        .map(|_| ())
+                        .map_err(|_| String::from(
+                                "Timeout time must be a positive number of seconds, or 0 to disable."
+                        ))
+                    ),
+            )
+            .arg(
+                Arg::with_name("transfer-timeout")
+                    .long("transfer-timeout")
+                    .short("T")
+                    .alias("trans-time")
+                    .alias("trans-timeout")
+                    .alias("transfer-time")
+                    .alias("time-trans")
+                    .alias("timeout-trans")
+                    .alias("time-transfer")
+                    .global(true)
+                    .value_name("SECONDS")
+                    .help("Transfer timeout (0 to disable)")
+                    .default_value(&DEFAULT_TRANSFER_TIMEOUT)
+                    .hide_default_value(true)
+                    .env("FFSEND_TRANSFER_TIMEOUT")
+                    .hide_env_values(true)
+                    .validator(|arg| arg
+                        .parse::<u64>()
+                        .map(|_| ())
+                        .map_err(|_| String::from(
+                                "Timeout time must be a positive number of seconds, or 0 to disable."
+                        ))
+                    ),
+            )
             .arg(
             .arg(
                 Arg::with_name("verbose")
                 Arg::with_name("verbose")
                     .long("verbose")
                     .long("verbose")

+ 16 - 0
src/cmd/matcher/main.rs

@@ -49,6 +49,22 @@ impl<'a: 'b, 'b> MainMatcher<'a> {
         }
         }
     }
     }
 
 
+    /// Get the timeout in seconds
+    pub fn timeout(&self) -> u64 {
+        self.matches
+            .value_of("timeout")
+            .and_then(|arg| arg.parse().ok())
+            .expect("invalid timeout value")
+    }
+
+    /// Get the transfer timeout in seconds
+    pub fn transfer_timeout(&self) -> u64 {
+        self.matches
+            .value_of("transfer-timeout")
+            .and_then(|arg| arg.parse().ok())
+            .expect("invalid transfer-timeout value")
+    }
+
     /// Check whether we are incognito from the file history.
     /// Check whether we are incognito from the file history.
     #[cfg(feature = "history")]
     #[cfg(feature = "history")]
     pub fn incognito(&self) -> bool {
     pub fn incognito(&self) -> bool {

+ 4 - 6
src/config.rs

@@ -1,8 +1,6 @@
-use std::time::Duration;
-
-/// The timeout for the Send client for generic requests, `None` to disable.
-pub const CLIENT_TIMEOUT: Option<Duration> = Some(Duration::from_secs(30));
+/// The timeout for the Send client for generic requests, `0` to disable.
+pub const CLIENT_TIMEOUT: u64 = 30;
 
 
 /// The timeout for the Send client used to transfer (upload/download) files.
 /// The timeout for the Send client used to transfer (upload/download) files.
-/// Make sure this is big enough, or file uploads will be dropped. `None` to disable.
-pub const CLIENT_TRANSFER_TIMEOUT: Option<Duration> = Some(Duration::from_secs(24 * 60 * 60));
+/// Make sure this is big enough, or file uploads will be dropped. `0` to disable.
+pub const CLIENT_TRANSFER_TIMEOUT: u64 = 24 * 60 * 60;