aboutsummaryrefslogtreecommitdiff
path: root/src/client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.rs')
-rw-r--r--src/client.rs58
1 files changed, 55 insertions, 3 deletions
diff --git a/src/client.rs b/src/client.rs
index 492008a..0f86712 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,6 +1,7 @@
use anyhow::{anyhow, bail, Result};
+use log::debug;
use std::{
- io::{BufRead, BufReader, BufWriter, Write},
+ io::{copy, BufRead, BufReader, BufWriter, Read, Write},
net::{TcpStream, ToSocketAddrs},
};
@@ -25,8 +26,9 @@ impl Client {
let mut line = String::new();
let mut out = Vec::new();
loop {
+ line.clear();
self.rsock.read_line(&mut line)?;
- if line.trim().is_empty() || line.ends_with("\n\n") {
+ if line.trim().is_empty() {
break Ok(out);
}
check_error(&line)?;
@@ -35,6 +37,56 @@ impl Client {
out.push((mtime.parse()?, size.parse()?, serial.parse()?));
}
}
+ pub fn upload(&mut self, size: u64, mut reader: impl Read) -> Result<()> {
+ debug!("announcing upload of {size} bytes");
+ writeln!(self.wsock, "upload,{size}")?;
+ self.wsock.flush()?;
+
+ let mut line = String::new();
+ self.rsock.read_line(&mut line)?;
+ check_error(&line)?;
+ if line.trim() != "ready" {
+ bail!("invalid response, not ready");
+ }
+ debug!("server ready");
+
+ copy(&mut reader, &mut self.wsock)?;
+
+ line.clear();
+ self.rsock.read_line(&mut line)?;
+ check_error(&line)?;
+ if line.trim() != "done" {
+ bail!("invalid response, not done");
+ }
+ debug!("server done");
+ Ok(())
+ }
+ pub fn download(&mut self, serial: Serial, mut writer: impl Write) -> Result<()> {
+ debug!("requesting download for serial={serial}");
+ writeln!(self.wsock, "download,{serial}")?;
+ self.wsock.flush()?;
+
+ let mut line = String::new();
+ self.rsock.read_line(&mut line)?;
+ check_error(&line)?;
+ let Some(size) = line.trim().strip_prefix("ready,") else {
+ bail!("server not ready")
+ };
+ eprintln!("{size:?}");
+ let size = size.parse()?;
+ debug!("server ready");
+
+ copy(&mut self.rsock.by_ref().take(size), &mut writer)?;
+
+ line.clear();
+ self.rsock.read_line(&mut line)?;
+ check_error(&line)?;
+ if line.trim() != "done" {
+ bail!("invalid response, not done");
+ }
+ debug!("server done");
+ Ok(())
+ }
pub fn quit(mut self) -> Result<()> {
writeln!(self.wsock, "quit")?;
self.wsock.flush()?;
@@ -43,7 +95,7 @@ impl Client {
}
fn check_error(line: &str) -> Result<()> {
- if let Some(message) = line.trim().strip_prefix("error") {
+ if let Some(message) = line.trim().strip_prefix("error,") {
bail!("server error: {message}")
}
Ok(())