Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bae0d0ed56 |
Generated
+1
-1
@@ -436,7 +436,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dosh"
|
name = "dosh"
|
||||||
version = "1.0.0-rc23"
|
version = "1.0.0-rc24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
"base64",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "dosh"
|
name = "dosh"
|
||||||
version = "1.0.0-rc23"
|
version = "1.0.0-rc24"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
|
|||||||
@@ -6253,7 +6253,9 @@ async fn flush_stream_pending_data(
|
|||||||
if credit < bytes.len() {
|
if credit < bytes.len() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let bytes = pending.pop_front().expect("pending front exists");
|
let Some(bytes) = pending.pop_front() else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
*stream_send_credit.entry(stream_id).or_default() -= bytes.len();
|
*stream_send_credit.entry(stream_id).or_default() -= bytes.len();
|
||||||
let offset = *stream_next_send_offset.entry(stream_id).or_default();
|
let offset = *stream_next_send_offset.entry(stream_id).or_default();
|
||||||
stream_next_send_offset.insert(stream_id, offset.saturating_add(bytes.len() as u64));
|
stream_next_send_offset.insert(stream_id, offset.saturating_add(bytes.len() as u64));
|
||||||
|
|||||||
+10
-4
@@ -2752,10 +2752,13 @@ async fn handle_file_request(
|
|||||||
atomic,
|
atomic,
|
||||||
});
|
});
|
||||||
if let Some(mode) = mode {
|
if let Some(mode) = mode {
|
||||||
let target = upload
|
let Some(active_upload) = upload.as_ref() else {
|
||||||
|
return Err(anyhow!("upload state missing after start"));
|
||||||
|
};
|
||||||
|
let target = active_upload
|
||||||
|
.temp_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|state| state.temp_path.as_ref())
|
.unwrap_or(&active_upload.final_path)
|
||||||
.unwrap_or_else(|| &upload.as_ref().unwrap().final_path)
|
|
||||||
.clone();
|
.clone();
|
||||||
set_mode(&target, mode)?;
|
set_mode(&target, mode)?;
|
||||||
}
|
}
|
||||||
@@ -3243,7 +3246,10 @@ async fn flush_stream_pending_data_to_client(
|
|||||||
if credit < bytes.len() {
|
if credit < bytes.len() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let bytes = pending.pop_front().expect("pending front exists");
|
let Some(bytes) = pending.pop_front() else {
|
||||||
|
client.stream_pending_data.remove(&stream_id);
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
if pending.is_empty() {
|
if pending.is_empty() {
|
||||||
client.stream_pending_data.remove(&stream_id);
|
client.stream_pending_data.remove(&stream_id);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -596,11 +596,13 @@ impl StreamMux {
|
|||||||
if self.send_credit.get(&stream_id).copied().unwrap_or(0) < front_len {
|
if self.send_credit.get(&stream_id).copied().unwrap_or(0) < front_len {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let bytes = self
|
let Some(bytes) = self
|
||||||
.pending_data
|
.pending_data
|
||||||
.get_mut(&stream_id)
|
.get_mut(&stream_id)
|
||||||
.and_then(VecDeque::pop_front)
|
.and_then(VecDeque::pop_front)
|
||||||
.expect("pending front exists");
|
else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
if self
|
if self
|
||||||
.pending_data
|
.pending_data
|
||||||
.get(&stream_id)
|
.get(&stream_id)
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use std::io::{Read, Write};
|
|||||||
use std::net::{SocketAddr, TcpListener, UdpSocket};
|
use std::net::{SocketAddr, TcpListener, UdpSocket};
|
||||||
use std::process::{Child, Command, Stdio};
|
use std::process::{Child, Command, Stdio};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, Ordering};
|
||||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
@@ -49,9 +49,20 @@ use ed25519_dalek::{SigningKey, VerifyingKey};
|
|||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
|
|
||||||
|
const TEST_UDP_PORT_START: u16 = 31_000;
|
||||||
|
const TEST_UDP_PORT_END: u16 = 60_999;
|
||||||
|
static NEXT_UDP_PORT: AtomicU32 = AtomicU32::new(TEST_UDP_PORT_START as u32);
|
||||||
|
|
||||||
fn free_udp_port() -> u16 {
|
fn free_udp_port() -> u16 {
|
||||||
let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
|
let span = u32::from(TEST_UDP_PORT_END - TEST_UDP_PORT_START) + 1;
|
||||||
socket.local_addr().unwrap().port()
|
for _ in TEST_UDP_PORT_START..=TEST_UDP_PORT_END {
|
||||||
|
let offset = NEXT_UDP_PORT.fetch_add(1, Ordering::SeqCst) % span;
|
||||||
|
let port = TEST_UDP_PORT_START + offset as u16;
|
||||||
|
if UdpSocket::bind(("127.0.0.1", port)).is_ok() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("no free UDP test port in {TEST_UDP_PORT_START}-{TEST_UDP_PORT_END}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_server_config(dir: &tempfile::TempDir, port: u16) -> std::path::PathBuf {
|
fn write_server_config(dir: &tempfile::TempDir, port: u16) -> std::path::PathBuf {
|
||||||
|
|||||||
Reference in New Issue
Block a user