mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2025-12-11 20:15:30 +01:00
[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:
parent
ff40f67018
commit
267f16aa0f
1
.gitignore
vendored
1
.gitignore
vendored
@ -69,6 +69,7 @@ prisma*.rs
|
|||||||
playwright-report
|
playwright-report
|
||||||
|
|
||||||
/sdserver_data
|
/sdserver_data
|
||||||
|
/sdserver_data2
|
||||||
.spacedrive
|
.spacedrive
|
||||||
dev.db-journal
|
dev.db-journal
|
||||||
.build/
|
.build/
|
||||||
|
|||||||
@ -136,15 +136,18 @@ impl P2PManager {
|
|||||||
info!("spacedrop({id}): received from peer '{}' for file '{}' with file length '{}'", event.peer_id, req.name, req.size);
|
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);
|
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) => {
|
_ = sleep(SPACEDROP_TIMEOUT) => {
|
||||||
info!("spacedrop({id}): timeout, rejecting!");
|
info!("spacedrop({id}): timeout, rejecting!");
|
||||||
|
|
||||||
@ -154,7 +157,14 @@ impl P2PManager {
|
|||||||
match file_path {
|
match file_path {
|
||||||
Ok(Some(file_path)) => {
|
Ok(Some(file_path)) => {
|
||||||
info!("spacedrop({id}): accepted saving to '{:?}'", 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) => {
|
Ok(None) => {
|
||||||
info!("spacedrop({id}): rejected");
|
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) => {
|
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
|
let mut buf = vec![0; len as usize]; // TODO: Designed for easily being able to be DOS the current Node
|
||||||
|
|||||||
@ -30,7 +30,13 @@ impl BlockSize {
|
|||||||
Self(131072) // 128 KiB
|
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
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,17 +136,12 @@ impl<'a> Block<'a> {
|
|||||||
stream.read_exact(&mut size).await.map_err(|_| ())?; // TODO: Error handling
|
stream.read_exact(&mut size).await.map_err(|_| ())?; // TODO: Error handling
|
||||||
let size = u64::from_le_bytes(size);
|
let size = u64::from_le_bytes(size);
|
||||||
|
|
||||||
// TODO: Handle overflow of `data_buf`
|
// TODO: Ensure `size` is `block_size` or smaller else buffer overflow
|
||||||
// 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;
|
|
||||||
|
|
||||||
if read_offset == size {
|
stream
|
||||||
break;
|
.read_exact(&mut data_buf[..size as usize])
|
||||||
}
|
.await
|
||||||
}
|
.map_err(|_| ())?; // TODO: Error handling
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
offset,
|
offset,
|
||||||
@ -156,7 +157,7 @@ pub async fn send(
|
|||||||
req: &SpacedropRequest,
|
req: &SpacedropRequest,
|
||||||
) {
|
) {
|
||||||
// We manually implement what is basically a `BufReader` so we have more control
|
// 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;
|
let mut offset: u64 = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -190,9 +191,10 @@ pub async fn receive(
|
|||||||
req: &SpacedropRequest,
|
req: &SpacedropRequest,
|
||||||
) {
|
) {
|
||||||
// We manually implement what is basically a `BufReader` so we have more control
|
// 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;
|
let mut offset: u64 = 0;
|
||||||
|
|
||||||
|
// TODO: Prevent loop being a DOS vector
|
||||||
loop {
|
loop {
|
||||||
// TODO: Timeout if nothing is being received
|
// TODO: Timeout if nothing is being received
|
||||||
let block = Block::from_stream(stream, &mut data_buf).await.unwrap(); // TODO: Error handling
|
let block = Block::from_stream(stream, &mut data_buf).await.unwrap(); // TODO: Error handling
|
||||||
@ -237,7 +239,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_spaceblock() {
|
async fn test_spaceblock_single_block() {
|
||||||
let (mut client, mut server) = tokio::io::duplex(64);
|
let (mut client, mut server) = tokio::io::duplex(64);
|
||||||
|
|
||||||
// This is sent out of band of Spaceblock
|
// This is sent out of band of Spaceblock
|
||||||
@ -265,4 +267,38 @@ mod tests {
|
|||||||
receive(&mut server, &mut result, &req).await;
|
receive(&mut server, &mut result, &req).await;
|
||||||
assert_eq!(result, data);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -90,7 +90,7 @@ export const Categories = (props: { selected: Category; onSelectedChanged(c: Cat
|
|||||||
<motion.div
|
<motion.div
|
||||||
onViewportEnter={() => lastCategoryVisibleHandler(index)}
|
onViewportEnter={() => lastCategoryVisibleHandler(index)}
|
||||||
onViewportLeave={() => 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"
|
className="min-w-fit"
|
||||||
key={category}
|
key={category}
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user