Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 039dc641b3 |
Generated
+1
-1
@@ -436,7 +436,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dosh"
|
name = "dosh"
|
||||||
version = "1.0.0-rc9"
|
version = "1.0.0-rc10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "dosh"
|
name = "dosh"
|
||||||
version = "1.0.0-rc9"
|
version = "1.0.0-rc10"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
|||||||
@@ -2498,11 +2498,15 @@ fn download_file(
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
let mut file = if offset > 0 {
|
let mut file = if offset > 0 {
|
||||||
fs::OpenOptions::new()
|
let file = fs::OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
|
.write(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(local)
|
.open(local)
|
||||||
.with_context(|| format!("open {}", local.display()))?
|
.with_context(|| format!("open {}", local.display()))?;
|
||||||
|
file.set_len(offset)
|
||||||
|
.with_context(|| format!("truncate {}", local.display()))?;
|
||||||
|
file
|
||||||
} else {
|
} else {
|
||||||
fs::OpenOptions::new()
|
fs::OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
|
|||||||
@@ -2667,10 +2667,13 @@ async fn handle_file_request(
|
|||||||
let (file, temp_path, written, atomic) = if resume && final_path.exists() {
|
let (file, temp_path, written, atomic) = if resume && final_path.exists() {
|
||||||
let mut file = fs::OpenOptions::new()
|
let mut file = fs::OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
|
.write(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(&final_path)
|
.open(&final_path)
|
||||||
.with_context(|| format!("open {}", final_path.display()))?;
|
.with_context(|| format!("open {}", final_path.display()))?;
|
||||||
let written = file.metadata()?.len().min(size);
|
let written = file.metadata()?.len().min(size);
|
||||||
|
file.set_len(written)
|
||||||
|
.with_context(|| format!("truncate {}", final_path.display()))?;
|
||||||
if written > 0 {
|
if written > 0 {
|
||||||
let mut prefix = fs::File::open(&final_path)?;
|
let mut prefix = fs::File::open(&final_path)?;
|
||||||
hash_exact_prefix(&mut prefix, written, &mut hasher)?;
|
hash_exact_prefix(&mut prefix, written, &mut hasher)?;
|
||||||
|
|||||||
@@ -1108,6 +1108,117 @@ fn native_file_copy_recursive_round_trip() {
|
|||||||
let _ = server.wait();
|
let _ = server.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn native_file_copy_resume_truncates_oversized_destinations() {
|
||||||
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
let port = free_udp_port();
|
||||||
|
let config = write_server_config(&dir, port);
|
||||||
|
write_native_client_auth(&dir, &config);
|
||||||
|
let mut server = start_server(&dir, &config);
|
||||||
|
let client_bin = env!("CARGO_BIN_EXE_dosh-client");
|
||||||
|
|
||||||
|
let local_short = dir.path().join("short.txt");
|
||||||
|
fs::write(&local_short, b"short\n").unwrap();
|
||||||
|
|
||||||
|
let seed_remote = Command::new(client_bin)
|
||||||
|
.arg("--dosh-host")
|
||||||
|
.arg("127.0.0.1")
|
||||||
|
.arg("--dosh-port")
|
||||||
|
.arg(port.to_string())
|
||||||
|
.arg("exec")
|
||||||
|
.arg("local")
|
||||||
|
.arg("printf 'short\\nSTALE' > \"$HOME/resume-upload.txt\"")
|
||||||
|
.env("HOME", dir.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
seed_remote.status.success(),
|
||||||
|
"seed remote failed: stdout={} stderr={}",
|
||||||
|
String::from_utf8_lossy(&seed_remote.stdout),
|
||||||
|
String::from_utf8_lossy(&seed_remote.stderr)
|
||||||
|
);
|
||||||
|
|
||||||
|
let resume_upload = Command::new(client_bin)
|
||||||
|
.arg("--dosh-host")
|
||||||
|
.arg("127.0.0.1")
|
||||||
|
.arg("--dosh-port")
|
||||||
|
.arg(port.to_string())
|
||||||
|
.arg("cp")
|
||||||
|
.arg("--resume")
|
||||||
|
.arg(&local_short)
|
||||||
|
.arg("local:resume-upload.txt")
|
||||||
|
.env("HOME", dir.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
resume_upload.status.success(),
|
||||||
|
"resume upload failed: stdout={} stderr={}",
|
||||||
|
String::from_utf8_lossy(&resume_upload.stdout),
|
||||||
|
String::from_utf8_lossy(&resume_upload.stderr)
|
||||||
|
);
|
||||||
|
|
||||||
|
let cat_upload = Command::new(client_bin)
|
||||||
|
.arg("--dosh-host")
|
||||||
|
.arg("127.0.0.1")
|
||||||
|
.arg("--dosh-port")
|
||||||
|
.arg(port.to_string())
|
||||||
|
.arg("cat")
|
||||||
|
.arg("local:resume-upload.txt")
|
||||||
|
.env("HOME", dir.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
cat_upload.status.success(),
|
||||||
|
"cat upload failed: stdout={} stderr={}",
|
||||||
|
String::from_utf8_lossy(&cat_upload.stdout),
|
||||||
|
String::from_utf8_lossy(&cat_upload.stderr)
|
||||||
|
);
|
||||||
|
assert_eq!(String::from_utf8_lossy(&cat_upload.stdout), "short\n");
|
||||||
|
|
||||||
|
let seed_download = Command::new(client_bin)
|
||||||
|
.arg("--dosh-host")
|
||||||
|
.arg("127.0.0.1")
|
||||||
|
.arg("--dosh-port")
|
||||||
|
.arg(port.to_string())
|
||||||
|
.arg("exec")
|
||||||
|
.arg("local")
|
||||||
|
.arg("printf 'tiny\\n' > \"$HOME/resume-download.txt\"")
|
||||||
|
.env("HOME", dir.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
seed_download.status.success(),
|
||||||
|
"seed download failed: stdout={} stderr={}",
|
||||||
|
String::from_utf8_lossy(&seed_download.stdout),
|
||||||
|
String::from_utf8_lossy(&seed_download.stderr)
|
||||||
|
);
|
||||||
|
|
||||||
|
let local_download = dir.path().join("resume-download-local.txt");
|
||||||
|
fs::write(&local_download, b"tiny\nSTALE").unwrap();
|
||||||
|
let resume_download = Command::new(client_bin)
|
||||||
|
.arg("--dosh-host")
|
||||||
|
.arg("127.0.0.1")
|
||||||
|
.arg("--dosh-port")
|
||||||
|
.arg(port.to_string())
|
||||||
|
.arg("cp")
|
||||||
|
.arg("--resume")
|
||||||
|
.arg("local:resume-download.txt")
|
||||||
|
.arg(&local_download)
|
||||||
|
.env("HOME", dir.path())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
resume_download.status.success(),
|
||||||
|
"resume download failed: stdout={} stderr={}",
|
||||||
|
String::from_utf8_lossy(&resume_download.stdout),
|
||||||
|
String::from_utf8_lossy(&resume_download.stderr)
|
||||||
|
);
|
||||||
|
assert_eq!(fs::read_to_string(&local_download).unwrap(), "tiny\n");
|
||||||
|
|
||||||
|
let _ = server.kill();
|
||||||
|
let _ = server.wait();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn native_exec_command_smoke() {
|
fn native_exec_command_smoke() {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user