]> git.proxmox.com Git - proxmox-backup.git/blobdiff - src/client/http_client.rs
update to nix 0.14, use code from proxmox:tools
[proxmox-backup.git] / src / client / http_client.rs
index db7cea3d162d3ab0487317c48832bdeb6d64f4fe..741fbfac3d70eed1d428c0d6aca8b3e803b5f1c5 100644 (file)
@@ -4,7 +4,7 @@ use http::Uri;
 use hyper::Body;
 use hyper::client::Client;
 use xdg::BaseDirectories;
-use chrono::{DateTime, Local, Utc};
+use chrono::{DateTime, Utc};
 use std::collections::HashSet;
 use std::sync::{Arc, Mutex};
 use std::io::Write;
@@ -21,6 +21,11 @@ use openssl::ssl::{SslConnector, SslMethod};
 use serde_json::{json, Value};
 use url::percent_encoding::{percent_encode,  DEFAULT_ENCODE_SET};
 
+use proxmox::tools::{
+    digest_to_hex,
+    fs::{file_get_json, file_set_contents},
+};
+
 use crate::tools::{self, BroadcastFuture, tty};
 use crate::tools::futures::{cancellable, Canceller};
 use super::pipe_to_stream::*;
@@ -51,7 +56,7 @@ fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) ->
 
     let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
 
-    let mut data = tools::file_get_json(&path, Some(json!({})))?;
+    let mut data = file_get_json(&path, Some(json!({})))?;
 
     let now = Utc::now().timestamp();
 
@@ -73,7 +78,7 @@ fn store_ticket_info(server: &str, username: &str, ticket: &str, token: &str) ->
         }
     }
 
-    tools::file_set_contents(path, new_data.to_string().as_bytes(), Some(mode))?;
+    file_set_contents(path, new_data.to_string().as_bytes(), Some(mode))?;
 
     Ok(())
 }
@@ -90,7 +95,7 @@ fn load_ticket_info(server: &str, username: &str) -> Option<(String, String)> {
         _ => return None,
     };
 
-    let data = match tools::file_get_json(&path, None) {
+    let data = match file_get_json(&path, None) {
         Ok(v) => v,
         _ => return None,
     };
@@ -165,7 +170,7 @@ impl HttpClient {
 
         let mut httpc = hyper::client::HttpConnector::new(1);
         httpc.set_nodelay(true); // important for h2 download performance!
-        httpc.set_recv_buf_size(Some(1024*1024)); //important for h2 download performance!
+        httpc.set_recv_buffer_size(Some(1024*1024)); //important for h2 download performance!
         httpc.enforce_http(false); // we want https...
 
         let https = hyper_openssl::HttpsConnector::with_connector(httpc,  ssl_connector_builder).unwrap();
@@ -248,10 +253,24 @@ impl HttpClient {
         })
     }
 
-    pub fn upload(&mut self, content_type: &str, body: Body, path: &str) -> impl Future<Item=Value, Error=Error> {
+    pub fn upload(
+        &mut self,
+        content_type: &str,
+        body: Body,
+        path: &str,
+        data: Option<Value>,
+    ) -> impl Future<Item=Value, Error=Error> {
 
         let path = path.trim_matches('/');
-        let url: Uri = format!("https://{}:8007/{}", &self.server, path).parse().unwrap();
+        let mut url = format!("https://{}:8007/{}", &self.server, path);
+
+        if let Some(data) = data {
+            let query = tools::json_object_to_query(data).unwrap();
+            url.push('?');
+            url.push_str(&query);
+        }
+
+        let url: Uri = url.parse().unwrap();
 
         let req = Request::builder()
             .method("POST")
@@ -268,10 +287,18 @@ impl HttpClient {
         datastore: &str,
         backup_type: &str,
         backup_id: &str,
+        backup_time: DateTime<Utc>,
         debug: bool,
     ) -> impl Future<Item=Arc<BackupClient>, Error=Error> {
 
-        let param = json!({"backup-type": backup_type, "backup-id": backup_id, "store": datastore, "debug": debug});
+        let param = json!({
+            "backup-type": backup_type,
+            "backup-id": backup_id,
+            "backup-time": backup_time.timestamp(),
+            "store": datastore,
+            "debug": debug
+        });
+
         let req = Self::request_builder(&self.server, "GET", "/api2/json/backup", Some(param)).unwrap();
 
         self.start_h2_connection(req, String::from(PROXMOX_BACKUP_PROTOCOL_ID_V1!()))
@@ -283,7 +310,7 @@ impl HttpClient {
         datastore: &str,
         backup_type: &str,
         backup_id: &str,
-        backup_time: DateTime<Local>,
+        backup_time: DateTime<Utc>,
         debug: bool,
     ) -> impl Future<Item=Arc<BackupReader>, Error=Error> {
 
@@ -514,7 +541,7 @@ impl BackupReader {
         output: W,
     ) -> impl Future<Item=W, Error=Error> {
         let path = "chunk";
-        let param = json!({ "digest": proxmox::tools::digest_to_hex(digest) });
+        let param = json!({ "digest": digest_to_hex(digest) });
         self.h2.download(path, Some(param), output)
     }
 
@@ -535,6 +562,10 @@ impl Drop for BackupClient {
     }
 }
 
+pub struct BackupStats {
+    pub size: u64,
+}
+
 impl BackupClient {
 
     pub fn new(h2: H2Client, canceller: Canceller) -> Arc<Self> {
@@ -554,11 +585,11 @@ impl BackupClient {
     }
 
     pub fn finish(self: Arc<Self>) -> impl Future<Item=(), Error=Error> {
-        let canceller = self.canceller.clone();
-        self.h2.clone().post("finish", None).map(move |_| {
-            canceller.cancel();
-            ()
-        })
+        self.h2.clone()
+            .post("finish", None)
+            .map(move |_| {
+                self.canceller.cancel();
+            })
     }
 
     pub fn force_close(self) {
@@ -571,15 +602,21 @@ impl BackupClient {
         file_name: &str,
         crypt_config: Option<Arc<CryptConfig>>,
         compress: bool,
-     ) -> impl Future<Item=(), Error=Error> {
+        sign_only: bool,
+     ) -> impl Future<Item=BackupStats, Error=Error> {
 
         let h2 = self.h2.clone();
         let file_name = file_name.to_owned();
+        let size = data.len() as u64;
 
         futures::future::ok(())
             .and_then(move |_| {
                 let blob = if let Some(ref crypt_config) = crypt_config {
-                    DataBlob::encode(&data, Some(crypt_config), compress)?
+                    if sign_only {
+                        DataBlob::create_signed(&data, crypt_config, compress)?
+                    } else {
+                        DataBlob::encode(&data, Some(crypt_config), compress)?
+                    }
                 } else {
                     DataBlob::encode(&data, None, compress)?
                 };
@@ -590,7 +627,9 @@ impl BackupClient {
             .and_then(move |raw_data| {
                 let param = json!({"encoded-size": raw_data.len(), "file-name": file_name });
                 h2.upload("blob", Some(param), raw_data)
-                    .map(|_| {})
+                    .map(move |_| {
+                        BackupStats { size: size }
+                    })
             })
     }
 
@@ -600,7 +639,7 @@ impl BackupClient {
         file_name: &str,
         crypt_config: Option<Arc<CryptConfig>>,
         compress: bool,
-     ) -> impl Future<Item=(), Error=Error> {
+     ) -> impl Future<Item=BackupStats, Error=Error> {
 
         let h2 = self.h2.clone();
         let file_name = file_name.to_owned();
@@ -619,12 +658,14 @@ impl BackupClient {
                             DataBlob::encode(&contents, None, compress)?
                         };
                         let raw_data = blob.into_inner();
-                        Ok(raw_data)
+                        Ok((raw_data, contents.len()))
                     })
-                    .and_then(move |raw_data| {
+                    .and_then(move |(raw_data, size)| {
                         let param = json!({"encoded-size": raw_data.len(), "file-name": file_name });
                         h2.upload("blob", Some(param), raw_data)
-                            .map(|_| {})
+                            .map(move |_| {
+                                BackupStats { size: size as u64 }
+                            })
                     })
             });
 
@@ -638,7 +679,7 @@ impl BackupClient {
         prefix: &str,
         fixed_size: Option<u64>,
         crypt_config: Option<Arc<CryptConfig>>,
-    ) -> impl Future<Item=(), Error=Error> {
+    ) -> impl Future<Item=BackupStats, Error=Error> {
 
         let known_chunks = Arc::new(Mutex::new(HashSet::new()));
 
@@ -664,15 +705,17 @@ impl BackupClient {
             .and_then(move |res| {
                 let wid = res.as_u64().unwrap();
                 Self::upload_chunk_info_stream(h2_3, wid, stream, &prefix, known_chunks.clone(), crypt_config)
-                     .and_then(move |(chunk_count, size, _speed)| {
+                    .and_then(move |(chunk_count, size, _speed)| {
                         let param = json!({
                             "wid": wid ,
                             "chunk-count": chunk_count,
                             "size": size,
                         });
                         h2_4.post(&close_path, Some(param))
-                     })
-                    .map(|_| ())
+                            .map(move |_| {
+                                BackupStats { size: size as u64 }
+                            })
+                    })
             })
     }
 
@@ -743,7 +786,7 @@ impl BackupClient {
                             let mut offset_list = vec![];
                             for (offset, digest) in chunk_list {
                                 //println!("append chunk {} (offset {})", proxmox::tools::digest_to_hex(&digest), offset);
-                                digest_list.push(proxmox::tools::digest_to_hex(&digest));
+                                digest_list.push(digest_to_hex(&digest));
                                 offset_list.push(offset);
                             }
                             println!("append chunks list len ({})", digest_list.len());
@@ -804,7 +847,7 @@ impl BackupClient {
                         DigestListDecoder::new(body.map_err(Error::from))
                             .for_each(move |chunk| {
                                 let _ = release_capacity.release_capacity(chunk.len());
-                                println!("GOT DOWNLOAD {}", proxmox::tools::digest_to_hex(&chunk));
+                                println!("GOT DOWNLOAD {}", digest_to_hex(&chunk));
                                 known_chunks.lock().unwrap().insert(chunk);
                                 Ok(())
                             })
@@ -866,7 +909,7 @@ impl BackupClient {
                 if let MergedChunkInfo::New(chunk_info) = merged_chunk_info {
                     let offset = chunk_info.offset;
                     let digest = *chunk_info.chunk.digest();
-                    let digest_str = proxmox::tools::digest_to_hex(&digest);
+                    let digest_str = digest_to_hex(&digest);
                     let upload_queue = upload_queue.clone();
 
                     println!("upload new chunk {} ({} bytes, offset {})", digest_str,
@@ -901,7 +944,7 @@ impl BackupClient {
                 }
             })
             .then(move |result| {
-                println!("RESULT {:?}", result);
+                //println!("RESULT {:?}", result);
                 upload_result.map_err(Error::from).and_then(|upload1_result| {
                     Ok(upload1_result.and(result))
                 })