[pbs-devel] [PATCH v2 proxmox-backup 1/2] fix #3296: allow set subscription through proxy

Dylan Whyte d.whyte at proxmox.com
Tue Mar 30 16:47:24 CEST 2021


when setting a subscription key from the cli, use http(s)_proxy as tunnel if
evironment variable is set.

Note: adds hyper-proxy crate and bumps bumps base64 to v0.13, due to a
dependency of hyper-proxy.

Signed-off-by: Dylan Whyte <d.whyte at proxmox.com>
---
Changes v1 -> v2:
- Accept proxy as optional argument to post function
- Create proxy client in separate function
- Read proxy env variable in register_subscription(..)
    - Include fixme note to change to config file later
- Code cleanup

Notes:
v2:
- This is currently just for the command line. To do this over the API,
  it would be better to have a config file.
- I am also leaving the apt configuration until the plan for this config
  file is confirmed.

v1:
* required packages can be found in nasi/iso/packages/hyper-proxy

Note that proxy authorization/authentication is not implemented yet.
hyper-proxy implements it using the 'headers' crate, which we do
not have as a direct dependency. I figured i'd leave it for a
follow up patch, just in case we decide not to use hyper-proxy afterall.


 Cargo.toml                |  3 ++-
 src/tools/http.rs         | 29 ++++++++++++++++++++++++++---
 src/tools/subscription.rs |  6 +++++-
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index b0ef56bd..044bcd48 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,7 +24,7 @@ path = "src/lib.rs"
 
 [dependencies]
 apt-pkg-native = "0.3.2"
-base64 = "0.12"
+base64 = "0.13"
 bitflags = "1.2.1"
 bytes = "1.0"
 crc32fast = "1"
@@ -74,6 +74,7 @@ xdg = "2.2"
 zstd = { version = "0.4", features = [ "bindgen" ] }
 nom = "5.1"
 crossbeam-channel = "0.5"
+hyper-proxy = { version = "0.9", default-features = false, features = ["openssl-tls"] }
 
 [features]
 default = []
diff --git a/src/tools/http.rs b/src/tools/http.rs
index d08ce451..8d940d01 100644
--- a/src/tools/http.rs
+++ b/src/tools/http.rs
@@ -7,6 +7,7 @@ use std::pin::Pin;
 
 use hyper::{Uri, Body};
 use hyper::client::{Client, HttpConnector};
+use hyper_proxy::{Proxy, ProxyConnector, Intercept};
 use http::{Request, Response};
 use openssl::ssl::{SslConnector, SslMethod};
 use futures::*;
@@ -62,6 +63,7 @@ pub async fn post(
     uri: &str,
     body: Option<String>,
     content_type: Option<&str>,
+    proxy: Option<String>
 ) -> Result<Response<Body>, Error> {
     let body = if let Some(body) = body {
         Body::from(body)
@@ -77,10 +79,31 @@ pub async fn post(
         .header(hyper::header::CONTENT_TYPE, content_type)
         .body(body)?;
 
+    if let Some(proxy) = proxy {
+        let client = proxy_connector(proxy)?;
+        client.request(request)
+            .map_err(Error::from)
+            .await
+    } else {
+        HTTP_CLIENT.request(request)
+            .map_err(Error::from)
+            .await
+    }
+}
+
+fn proxy_connector(proxy_addr: String) -> Result<Client<ProxyConnector<HttpConnector>, Body>, Error> {
+    let proxy = format!("http://{}/", proxy_addr);
+    let proxy = {
+        let proxy_uri = proxy.parse()?;
+        let proxy = Proxy::new(Intercept::All, proxy_uri);
+        let connector = HttpConnector::new();
+        let proxy_connector = ProxyConnector::from_proxy(connector, proxy)?;
+        proxy_connector
+    };
+
+    let client = Client::builder().build(proxy);
 
-    HTTP_CLIENT.request(request)
-        .map_err(Error::from)
-        .await
+    Ok(client)
 }
 
 #[derive(Clone)]
diff --git a/src/tools/subscription.rs b/src/tools/subscription.rs
index 9b9534ac..d7ff6eeb 100644
--- a/src/tools/subscription.rs
+++ b/src/tools/subscription.rs
@@ -104,7 +104,11 @@ async fn register_subscription(
     });
     let uri = "https://shop.maurer-it.com/modules/servers/licensing/verify.php";
     let query = tools::json_object_to_query(params)?;
-    let response = http::post(uri, Some(query), Some("application/x-www-form-urlencoded")).await?;
+
+    // FIXME: get proxy from config file rather than environment variable
+    let http_proxy = std::env::var("https_proxy").or(std::env::var("http_proxy")).ok();
+
+    let response = http::post(uri, Some(query), Some("application/x-www-form-urlencoded"), http_proxy).await?;
     let body = http::response_body_string(response).await?;
 
     Ok((body, challenge))
-- 
2.20.1






More information about the pbs-devel mailing list