new http client implementation SimpleHttp (avoid static HTTP_CLIENT)
This one will have proxy support.
This commit is contained in:
parent
17b3e4451f
commit
26153589ba
|
@ -7,7 +7,7 @@ use proxmox::api::{api, RpcEnvironment, RpcEnvironmentType, Permission};
|
|||
use proxmox::api::router::{Router, SubdirMap};
|
||||
|
||||
use crate::server::WorkerTask;
|
||||
use crate::tools::{apt, http, subscription};
|
||||
use crate::tools::{apt, http::SimpleHttp, subscription};
|
||||
|
||||
use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
|
||||
use crate::api2::types::{Authid, APTUpdateInfo, NODE_SCHEMA, UPID_SCHEMA};
|
||||
|
@ -194,10 +194,12 @@ fn apt_get_changelog(
|
|||
bail!("Package '{}' not found", name);
|
||||
}
|
||||
|
||||
let mut client = SimpleHttp::new();
|
||||
|
||||
let changelog_url = &pkg_info[0].change_log_url;
|
||||
// FIXME: use 'apt-get changelog' for proxmox packages as well, once repo supports it
|
||||
if changelog_url.starts_with("http://download.proxmox.com/") {
|
||||
let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url, None))
|
||||
let changelog = crate::tools::runtime::block_on(client.get_string(changelog_url, None))
|
||||
.map_err(|err| format_err!("Error downloading changelog from '{}': {}", changelog_url, err))?;
|
||||
Ok(json!(changelog))
|
||||
|
||||
|
@ -221,7 +223,7 @@ fn apt_get_changelog(
|
|||
auth_header.insert("Authorization".to_owned(),
|
||||
format!("Basic {}", base64::encode(format!("{}:{}", key, id))));
|
||||
|
||||
let changelog = crate::tools::runtime::block_on(http::get_string(changelog_url, Some(&auth_header)))
|
||||
let changelog = crate::tools::runtime::block_on(client.get_string(changelog_url, Some(&auth_header)))
|
||||
.map_err(|err| format_err!("Error downloading changelog from '{}': {}", changelog_url, err))?;
|
||||
Ok(json!(changelog))
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use anyhow::{Error, format_err, bail};
|
||||
use lazy_static::lazy_static;
|
||||
use std::task::{Context, Poll};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::collections::HashMap;
|
||||
|
@ -21,68 +20,85 @@ use crate::tools::{
|
|||
},
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
static ref HTTP_CLIENT: Client<HttpsConnector, Body> = {
|
||||
let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
||||
let httpc = HttpConnector::new();
|
||||
let https = HttpsConnector::with_connector(httpc, connector);
|
||||
Client::builder().build(https)
|
||||
};
|
||||
/// Asyncrounous HTTP client implementation
|
||||
pub struct SimpleHttp {
|
||||
client: Client<HttpsConnector, Body>,
|
||||
}
|
||||
|
||||
pub async fn get_string(uri: &str, extra_headers: Option<&HashMap<String, String>>) -> Result<String, Error> {
|
||||
let mut request = Request::builder()
|
||||
.method("GET")
|
||||
.uri(uri)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0");
|
||||
impl SimpleHttp {
|
||||
|
||||
if let Some(hs) = extra_headers {
|
||||
for (h, v) in hs.iter() {
|
||||
request = request.header(h, v);
|
||||
pub fn new() -> Self {
|
||||
let ssl_connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
|
||||
Self::with_ssl_connector(ssl_connector)
|
||||
}
|
||||
|
||||
pub fn with_ssl_connector(ssl_connector: SslConnector) -> Self {
|
||||
let connector = HttpConnector::new();
|
||||
let https = HttpsConnector::with_connector(connector, ssl_connector);
|
||||
let client = Client::builder().build(https);
|
||||
Self { client }
|
||||
}
|
||||
|
||||
pub async fn post(
|
||||
&mut self,
|
||||
uri: &str,
|
||||
body: Option<String>,
|
||||
content_type: Option<&str>,
|
||||
) -> Result<Response<Body>, Error> {
|
||||
|
||||
let body = if let Some(body) = body {
|
||||
Body::from(body)
|
||||
} else {
|
||||
Body::empty()
|
||||
};
|
||||
let content_type = content_type.unwrap_or("application/json");
|
||||
|
||||
let request = Request::builder()
|
||||
.method("POST")
|
||||
.uri(uri)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0")
|
||||
.header(hyper::header::CONTENT_TYPE, content_type)
|
||||
.body(body)?;
|
||||
|
||||
self.client.request(request)
|
||||
.map_err(Error::from)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_string(
|
||||
&mut self,
|
||||
uri: &str,
|
||||
extra_headers: Option<&HashMap<String, String>>,
|
||||
) -> Result<String, Error> {
|
||||
|
||||
let mut request = Request::builder()
|
||||
.method("GET")
|
||||
.uri(uri)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0");
|
||||
|
||||
if let Some(hs) = extra_headers {
|
||||
for (h, v) in hs.iter() {
|
||||
request = request.header(h, v);
|
||||
}
|
||||
}
|
||||
|
||||
let request = request.body(Body::empty())?;
|
||||
|
||||
let res = self.client.request(request).await?;
|
||||
|
||||
let status = res.status();
|
||||
if !status.is_success() {
|
||||
bail!("Got bad status '{}' from server", status)
|
||||
}
|
||||
|
||||
Self::response_body_string(res).await
|
||||
}
|
||||
|
||||
let request = request.body(Body::empty())?;
|
||||
|
||||
let res = HTTP_CLIENT.request(request).await?;
|
||||
|
||||
let status = res.status();
|
||||
if !status.is_success() {
|
||||
bail!("Got bad status '{}' from server", status)
|
||||
pub async fn response_body_string(res: Response<Body>) -> Result<String, Error> {
|
||||
let buf = hyper::body::to_bytes(res).await?;
|
||||
String::from_utf8(buf.to_vec())
|
||||
.map_err(|err| format_err!("Error converting HTTP result data: {}", err))
|
||||
}
|
||||
|
||||
response_body_string(res).await
|
||||
}
|
||||
|
||||
pub async fn response_body_string(res: Response<Body>) -> Result<String, Error> {
|
||||
let buf = hyper::body::to_bytes(res).await?;
|
||||
String::from_utf8(buf.to_vec())
|
||||
.map_err(|err| format_err!("Error converting HTTP result data: {}", err))
|
||||
}
|
||||
|
||||
pub async fn post(
|
||||
uri: &str,
|
||||
body: Option<String>,
|
||||
content_type: Option<&str>,
|
||||
) -> Result<Response<Body>, Error> {
|
||||
let body = if let Some(body) = body {
|
||||
Body::from(body)
|
||||
} else {
|
||||
Body::empty()
|
||||
};
|
||||
let content_type = content_type.unwrap_or("application/json");
|
||||
|
||||
let request = Request::builder()
|
||||
.method("POST")
|
||||
.uri(uri)
|
||||
.header("User-Agent", "proxmox-backup-client/1.0")
|
||||
.header(hyper::header::CONTENT_TYPE, content_type)
|
||||
.body(body)?;
|
||||
|
||||
|
||||
HTTP_CLIENT.request(request)
|
||||
.map_err(Error::from)
|
||||
.await
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
@ -6,8 +6,7 @@ use regex::Regex;
|
|||
|
||||
use proxmox::api::api;
|
||||
|
||||
use crate::tools;
|
||||
use crate::tools::http;
|
||||
use crate::tools::{self, http::SimpleHttp};
|
||||
use proxmox::tools::fs::{replace_file, CreateOptions};
|
||||
|
||||
/// How long the local key is valid for in between remote checks
|
||||
|
@ -102,10 +101,13 @@ async fn register_subscription(
|
|||
"ip": "localhost",
|
||||
"check_token": challenge,
|
||||
});
|
||||
|
||||
let mut client = SimpleHttp::new();
|
||||
|
||||
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?;
|
||||
let body = http::response_body_string(response).await?;
|
||||
let response = client.post(uri, Some(query), Some("application/x-www-form-urlencoded")).await?;
|
||||
let body = SimpleHttp::response_body_string(response).await?;
|
||||
|
||||
Ok((body, challenge))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue