[ENG-675] Spacedrop is 0kb (#942)

* fix sd-web

* pain

* unit tests are pog

* Ignore `sdserver_data2`

* Update mod.rs
This commit is contained in:
Oscar Beaumont 2023-06-15 02:32:54 +02:00 committed by GitHub
parent ff40f67018
commit 267f16aa0f
4 changed files with 71 additions and 32 deletions

1
.gitignore vendored
View File

@ -69,6 +69,7 @@ prisma*.rs
playwright-report
/sdserver_data
/sdserver_data2
.spacedrive
dev.db-journal
.build/

View File

@ -136,15 +136,18 @@ impl P2PManager {
info!("spacedrop({id}): received from peer '{}' for file '{}' with file length '{}'", event.peer_id, req.name, req.size);
spacedrop_pairing_reqs.lock().await.insert(id, tx);
events
.send(P2PEvent::SpacedropRequest {
id,
peer_id: event.peer_id,
name: req.name.clone(),
})
.unwrap();
let file_path = tokio::select! {
if let Err(_) = events.send(P2PEvent::SpacedropRequest {
id,
peer_id: event.peer_id,
name: req.name.clone(),
}) {
// No frontend's are active
todo!("Outright reject Spacedrop");
}
tokio::select! {
_ = sleep(SPACEDROP_TIMEOUT) => {
info!("spacedrop({id}): timeout, rejecting!");
@ -154,7 +157,14 @@ impl P2PManager {
match file_path {
Ok(Some(file_path)) => {
info!("spacedrop({id}): accepted saving to '{:?}'", file_path);
file_path
stream.write_all(&[1]).await.unwrap();
let f = File::create(file_path).await.unwrap();
spaceblock::receive(&mut stream, f, &req).await;
info!("spacedrop({id}): complete");
}
Ok(None) => {
info!("spacedrop({id}): rejected");
@ -167,14 +177,6 @@ impl P2PManager {
}
}
};
stream.write_all(&[1]).await.unwrap();
let f = File::create(file_path).await.unwrap();
spaceblock::receive(&mut stream, f, &req).await;
info!("spacedrop({id}): complete");
}
Header::Sync(library_id, len) => {
let mut buf = vec![0; len as usize]; // TODO: Designed for easily being able to be DOS the current Node

View File

@ -30,7 +30,13 @@ impl BlockSize {
Self(131072) // 128 KiB
}
pub fn to_size(&self) -> u32 {
/// This is super dangerous as it doesn't enforce any assumptions of the protocol and is designed just for tests.
#[cfg(test)]
pub fn dangerously_new(size: u32) -> Self {
Self(size)
}
pub fn size(&self) -> u32 {
self.0
}
}
@ -130,17 +136,12 @@ impl<'a> Block<'a> {
stream.read_exact(&mut size).await.map_err(|_| ())?; // TODO: Error handling
let size = u64::from_le_bytes(size);
// TODO: Handle overflow of `data_buf`
// TODO: Prevent this being used as a DoS cause I think it can
let mut read_offset = 0u64;
loop {
let read = stream.read(data_buf).await.map_err(|_| ())?; // TODO: Error handling
read_offset += read as u64;
// TODO: Ensure `size` is `block_size` or smaller else buffer overflow
if read_offset == size {
break;
}
}
stream
.read_exact(&mut data_buf[..size as usize])
.await
.map_err(|_| ())?; // TODO: Error handling
Ok(Self {
offset,
@ -156,7 +157,7 @@ pub async fn send(
req: &SpacedropRequest,
) {
// We manually implement what is basically a `BufReader` so we have more control
let mut buf = vec![0u8; req.block_size.to_size() as usize];
let mut buf = vec![0u8; req.block_size.size() as usize];
let mut offset: u64 = 0;
loop {
@ -190,9 +191,10 @@ pub async fn receive(
req: &SpacedropRequest,
) {
// We manually implement what is basically a `BufReader` so we have more control
let mut data_buf = vec![0u8; req.block_size.to_size() as usize];
let mut data_buf = vec![0u8; req.block_size.size() as usize];
let mut offset: u64 = 0;
// TODO: Prevent loop being a DOS vector
loop {
// TODO: Timeout if nothing is being received
let block = Block::from_stream(stream, &mut data_buf).await.unwrap(); // TODO: Error handling
@ -237,7 +239,7 @@ mod tests {
}
#[tokio::test]
async fn test_spaceblock() {
async fn test_spaceblock_single_block() {
let (mut client, mut server) = tokio::io::duplex(64);
// This is sent out of band of Spaceblock
@ -265,4 +267,38 @@ mod tests {
receive(&mut server, &mut result, &req).await;
assert_eq!(result, data);
}
// https://github.com/spacedriveapp/spacedrive/pull/942
#[tokio::test]
async fn test_spaceblock_multiple_blocks() {
let (mut client, mut server) = tokio::io::duplex(64);
// This is sent out of band of Spaceblock
let block_size = 131072u32;
let data = vec![0u8; block_size as usize * 4]; // Let's pacman some RAM
let block_size = BlockSize::dangerously_new(block_size);
let req = SpacedropRequest {
name: "Demo".to_string(),
size: data.len() as u64,
block_size,
};
let (tx, rx) = oneshot::channel();
tokio::spawn({
let req = req.clone();
let data = data.clone();
async move {
let file = BufReader::new(Cursor::new(data));
tx.send(()).unwrap();
send(&mut client, file, &req).await;
}
});
rx.await.unwrap();
let mut result = Vec::new();
receive(&mut server, &mut result, &req).await;
assert_eq!(result, data);
}
}

View File

@ -90,7 +90,7 @@ export const Categories = (props: { selected: Category; onSelectedChanged(c: Cat
<motion.div
onViewportEnter={() => lastCategoryVisibleHandler(index)}
onViewportLeave={() => lastCategoryVisibleHandler(index)}
viewport={{ root: ref, margin: '0 -120px 0 0' }}
viewport={{ root: ref, margin: '0% -120px 0% 0%' }}
className="min-w-fit"
key={category}
>