Put and Read: content on the socket, for clients that share no files
The system daemon runs as its own user behind ProtectHome, so it can neither read a file a desktop app wrote for Add nor write one back for Materialize - redoal on the system varde failed every get with EACCES. Put imports base64 bytes carried in the request and Read returns a raw blob's bytes in the reply, both up to MAX_INLINE_BYTES (16 MiB). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c9dbc4a576
commit
687af8bd2a
@@ -276,3 +276,45 @@ fn reflink_when_supported() {
|
||||
drop(daemon);
|
||||
let _ = std::fs::remove_dir_all(&base);
|
||||
}
|
||||
|
||||
/// Put and Read carry the bytes on the socket: a client that shares no
|
||||
/// filesystem with the daemon (a desktop app and the system daemon, which
|
||||
/// runs as its own user behind ProtectHome) stores and reads back without
|
||||
/// a path either side must reach. A Put blob reads back by Materialize too.
|
||||
#[test]
|
||||
fn bytes_round_trip_inline() {
|
||||
use base64::Engine as _;
|
||||
let b64 = base64::engine::general_purpose::STANDARD;
|
||||
let daemon = support::spawn_daemon();
|
||||
let mut client = support::Client::connect(&daemon.socket);
|
||||
let payload: Vec<u8> = (0..50_000u32).flat_map(|i| i.to_le_bytes()).collect();
|
||||
|
||||
let reply = client.request(&Request::Put { data: b64.encode(&payload) });
|
||||
assert!(reply.ok, "put failed: {:?}", reply.error);
|
||||
let hash = match reply.data {
|
||||
Some(ResponseData::Added { hash, bytes }) => {
|
||||
assert_eq!(bytes, payload.len() as u64);
|
||||
hash
|
||||
}
|
||||
other => panic!("unexpected put reply: {other:?}"),
|
||||
};
|
||||
|
||||
let reply = client.request(&Request::Read { hash: hash.clone() });
|
||||
assert!(reply.ok, "read failed: {:?}", reply.error);
|
||||
match reply.data {
|
||||
Some(ResponseData::Bytes { data }) => assert_eq!(b64.decode(data).unwrap(), payload),
|
||||
other => panic!("unexpected read reply: {other:?}"),
|
||||
}
|
||||
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let dest = dir.path().join("out.bin");
|
||||
materialize(&mut client, &hash, &dest, MaterializeMode::Copy).unwrap();
|
||||
assert_eq!(std::fs::read(&dest).unwrap(), payload);
|
||||
|
||||
// Not base64: refused, not stored.
|
||||
let reply = client.request(&Request::Put { data: "not base64!".into() });
|
||||
assert_eq!(reply.error.expect("error body").code, ErrorCode::InvalidArgument);
|
||||
// Unknown hash: not found.
|
||||
let reply = client.request(&Request::Read { hash: "0".repeat(64) });
|
||||
assert!(!reply.ok);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user