96 lines
2.5 KiB
Rust
96 lines
2.5 KiB
Rust
//! 独立回环协议对端验证客户端按需拉取与连接所有权。
|
|
|
|
use super::*;
|
|
use bytes::Bytes;
|
|
use dever_runtime::{
|
|
async_stream::AsyncStream,
|
|
http::{HttpClient, PoolLimits, StreamRequest},
|
|
io::Error,
|
|
tls,
|
|
};
|
|
use std::net::TcpListener;
|
|
|
|
mod download;
|
|
mod protocol;
|
|
mod upload;
|
|
|
|
type Event = Result<Bytes, Error>;
|
|
|
|
fn event(value: Event) -> Event {
|
|
value
|
|
}
|
|
|
|
fn message() -> Request {
|
|
Request {
|
|
method: "POST".into(),
|
|
target: "/stream".into(),
|
|
headers: vec![],
|
|
body: bytes::Bytes::new(),
|
|
}
|
|
}
|
|
|
|
fn client(scope: &Scope<'_>, port: u16, limits: &Limits, pool: &PoolLimits) -> HttpClient {
|
|
http::client(
|
|
&format!("http://127.0.0.1:{port}"),
|
|
&tls::system(),
|
|
limits,
|
|
pool,
|
|
scope,
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
fn peer(work: impl FnOnce(TcpListener) + Send + 'static) -> (u16, std::thread::JoinHandle<()>) {
|
|
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
|
let port = listener.local_addr().unwrap().port();
|
|
(port, std::thread::spawn(move || work(listener)))
|
|
}
|
|
|
|
fn accept(listener: &TcpListener) -> BufReader<TcpStream> {
|
|
listener.set_nonblocking(true).unwrap();
|
|
let start = std::time::Instant::now();
|
|
let socket = loop {
|
|
match listener.accept() {
|
|
Ok((socket, _)) => break socket,
|
|
Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => {
|
|
assert!(
|
|
start.elapsed() < Duration::from_secs(5),
|
|
"peer accept timed out"
|
|
);
|
|
std::thread::sleep(Duration::from_millis(2));
|
|
}
|
|
Err(error) => panic!("{error}"),
|
|
}
|
|
};
|
|
socket
|
|
.set_read_timeout(Some(Duration::from_secs(5)))
|
|
.unwrap();
|
|
socket
|
|
.set_write_timeout(Some(Duration::from_secs(5)))
|
|
.unwrap();
|
|
BufReader::new(socket)
|
|
}
|
|
|
|
fn headers(socket: &mut BufReader<TcpStream>) -> String {
|
|
let mut headers = String::new();
|
|
loop {
|
|
let mut line = String::new();
|
|
assert!(socket.read_line(&mut line).unwrap() > 0);
|
|
if line == "\r\n" {
|
|
return headers;
|
|
}
|
|
headers.push_str(&line);
|
|
}
|
|
}
|
|
|
|
async fn collect(body: &AsyncStream<Event>, chunk: usize) -> Vec<u8> {
|
|
let _guard = body.close_on_drop();
|
|
let mut bytes = vec![];
|
|
while let Some(event) = body.next().await.unwrap() {
|
|
let part = event.unwrap();
|
|
assert!(!part.is_empty() && part.len() <= chunk);
|
|
bytes.extend_from_slice(&part);
|
|
}
|
|
bytes
|
|
}
|