Kaynağa Gözat

Make timeout configurable

timvisee 6 yıl önce
ebeveyn
işleme
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
 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
 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
         // 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
         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();
 
         // 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
         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();
 
         // Create a reqwest client
-        let client = create_client();
+        let client = create_client(&matcher_main);
 
         // Parse the remote file based on the share URL
         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();
 
         // 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
         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();
 
         // 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
         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();
 
         // 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
         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
-        let client = create_transfer_client();
+        let client = create_transfer_client(&matcher_main);
 
         // Create a progress bar reporter
         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 config::{CLIENT_TIMEOUT, CLIENT_TRANSFER_TIMEOUT};
+use cmd::matcher::MainMatcher;
 
 /// Create the default client, which is used for generic Send requests.
 ///
 /// 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.
 ///
 /// 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.
@@ -25,3 +25,12 @@ fn create_custom_client(timeout: Option<Duration>) -> Client {
         .build()
         .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 config::{CLIENT_TIMEOUT, CLIENT_TRANSFER_TIMEOUT};
 #[cfg(feature = "history")]
 use super::matcher::HistoryMatcher;
 use super::matcher::{
@@ -20,6 +21,12 @@ use util::app_history_file_path_string;
 lazy_static! {
     /// The default history file
     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.
@@ -69,6 +76,51 @@ impl<'a: 'b, 'b> Handler<'a> {
                     .global(true)
                     .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::with_name("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.
     #[cfg(feature = "history")]
     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.
-/// 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;