public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Stefan Reiter <s.reiter@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [RFC proxmox-backup 2/2] http_client: add timeouts for critical connects
Date: Mon, 21 Dec 2020 14:56:11 +0100	[thread overview]
Message-ID: <20201221135611.14456-3-s.reiter@proxmox.com> (raw)
In-Reply-To: <20201221135611.14456-1-s.reiter@proxmox.com>

Use timeout futures for sections that might hang in certain error
conditions. This is mostly intended to be used as a safeguard, not a
first line of defense - i.e. best-effort avoidance of total hangs.

Not every future used for the HttpClient/H2Client is changed, only those
where a quick response is to be expected. For example, the response
reading futures are left alone, so data transfer is never capped with
timeout, only the initial server connect.

It is also used for upgrading to H2 connections, as that can take a long
time on overloaded servers.

Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
---
 src/client/http_client.rs | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/client/http_client.rs b/src/client/http_client.rs
index a9b9c06c..92df9572 100644
--- a/src/client/http_client.rs
+++ b/src/client/http_client.rs
@@ -18,6 +18,7 @@ use proxmox::{
     api::error::HttpError,
     sys::linux::tty,
     tools::fs::{file_get_json, replace_file, CreateOptions},
+    tools::future::TimeoutFutureExt,
 };
 
 use super::pipe_to_stream::PipeToSendStream;
@@ -29,6 +30,10 @@ use crate::tools::{
     http::HttpsConnector,
 };
 
+/// Timeout used for several HTTP operations that are expected to finish quickly but may block in
+/// certain error conditions.
+const HTTP_TIMEOUT: Duration = Duration::from_secs(20);
+
 #[derive(Clone)]
 pub struct AuthInfo {
     pub auth_id: Authid,
@@ -557,7 +562,10 @@ impl HttpClient {
         let enc_ticket = format!("PBSAuthCookie={}", percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET));
         req.headers_mut().insert("Cookie", HeaderValue::from_str(&enc_ticket).unwrap());
 
-        let resp = client.request(req).await?;
+        let resp = client
+            .request(req)
+            .or_timeout_err(HTTP_TIMEOUT, format_err!("http download request timed out"))
+            .await?;
         let status = resp.status();
         if !status.is_success() {
             HttpClient::api_response(resp)
@@ -624,7 +632,10 @@ impl HttpClient {
 
         req.headers_mut().insert("UPGRADE", HeaderValue::from_str(&protocol_name).unwrap());
 
-        let resp = client.request(req).await?;
+        let resp = client
+            .request(req)
+            .or_timeout_err(HTTP_TIMEOUT, format_err!("http upgrade request timed out"))
+            .await?;
         let status = resp.status();
 
         if status != http::StatusCode::SWITCHING_PROTOCOLS {
@@ -705,7 +716,7 @@ impl HttpClient {
     ) -> Result<Value, Error> {
 
         client.request(req)
-            .map_err(Error::from)
+            .or_timeout_err(HTTP_TIMEOUT, format_err!("http request timed out"))
             .and_then(Self::api_response)
             .await
     }
-- 
2.20.1





  parent reply	other threads:[~2020-12-21 13:56 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-21 13:56 [pbs-devel] [RFC 0/2] backup client: implement some HTTP timeouts Stefan Reiter
2020-12-21 13:56 ` [pbs-devel] [RFC proxmox 1/2] add tools::future with TimeoutFutureExt Stefan Reiter
2020-12-21 13:56 ` Stefan Reiter [this message]
2020-12-21 15:36 ` [pbs-devel] [RFC 0/2] backup client: implement some HTTP timeouts Dietmar Maurer
2020-12-21 15:45   ` Dietmar Maurer
2020-12-21 15:49   ` Stefan Reiter
2020-12-21 16:40     ` Dietmar Maurer
2020-12-22  8:47       ` Stefan Reiter
2020-12-22 10:40         ` Dietmar Maurer
2020-12-22 12:32 ` [pbs-devel] applied: " Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201221135611.14456-3-s.reiter@proxmox.com \
    --to=s.reiter@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal