mirror of
https://github.com/YGGverse/titanit.git
synced 2026-03-31 17:15:30 +00:00
prevent server fault on handshake issues, fix size conditions, begin response implementation
This commit is contained in:
parent
5e2b90a39e
commit
61f5e22da3
1 changed files with 71 additions and 46 deletions
59
src/main.rs
59
src/main.rs
|
|
@ -4,11 +4,12 @@ mod storage;
|
|||
use anyhow::Result;
|
||||
use argument::Argument;
|
||||
|
||||
use native_tls::{Identity, TlsAcceptor, TlsStream};
|
||||
use native_tls::{HandshakeError, Identity, TlsAcceptor, TlsStream};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
net::{SocketAddr, TcpListener, TcpStream},
|
||||
os::unix::fs::FileExt,
|
||||
sync::Arc,
|
||||
thread,
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
|
|
@ -40,8 +41,8 @@ fn main() -> Result<()> {
|
|||
thread::spawn({
|
||||
let argument = argument.clone();
|
||||
let peer = stream.peer_addr()?;
|
||||
let mut stream = acceptor.accept(stream)?;
|
||||
move || handle(argument, peer, &mut stream)
|
||||
let connection = acceptor.accept(stream);
|
||||
move || handle(argument, peer, connection)
|
||||
});
|
||||
}
|
||||
Err(e) => println!("[{}] [error] {e}", now()),
|
||||
|
|
@ -50,23 +51,29 @@ fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle(argument: Arc<Argument>, peer: SocketAddr, stream: &mut TlsStream<TcpStream>) {
|
||||
fn handle(
|
||||
argument: Arc<Argument>,
|
||||
peer: SocketAddr,
|
||||
connection: Result<TlsStream<TcpStream>, HandshakeError<TcpStream>>,
|
||||
) {
|
||||
use titanite::*;
|
||||
//println!("[{}] [info] [{peer}] New connection", now());
|
||||
match connection {
|
||||
Ok(mut stream) => {
|
||||
let mut input = vec![0; titanite::HEADER_MAX_LEN];
|
||||
match stream.read(&mut input) {
|
||||
Ok(0) => println!("[{}] [warning] [{peer}] Peer closed connection", now()),
|
||||
Ok(s) => match Request::from_bytes(&input[..s]) {
|
||||
Ok(request) => match request {
|
||||
Request::Gemini(this) => gemini(this, argument, peer, stream),
|
||||
Request::Titan(this) => titan(this, argument, peer, stream),
|
||||
Request::Gemini(this) => gemini(this, argument, peer, &mut stream),
|
||||
Request::Titan(this) => titan(this, argument, peer, &mut stream),
|
||||
},
|
||||
Err(e) => send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
&mut stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
|
|
@ -78,7 +85,7 @@ fn handle(argument: Arc<Argument>, peer: SocketAddr, stream: &mut TlsStream<TcpS
|
|||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
&mut stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
|
|
@ -86,6 +93,9 @@ fn handle(argument: Arc<Argument>, peer: SocketAddr, stream: &mut TlsStream<TcpS
|
|||
),
|
||||
}
|
||||
}
|
||||
Err(e) => println!("[{}] [warning] [{peer}] Handshake issue: {e}", now()),
|
||||
}
|
||||
}
|
||||
|
||||
fn gemini(
|
||||
gemini: titanite::request::Gemini,
|
||||
|
|
@ -94,19 +104,34 @@ fn gemini(
|
|||
stream: &mut TlsStream<TcpStream>,
|
||||
) {
|
||||
use titanite::*;
|
||||
println!("[{}] [info] [{peer}] Request: {}", now(), gemini.url);
|
||||
match storage::Item::from_url(gemini.url.as_str(), &argument.directory) {
|
||||
Ok(item) => send(
|
||||
Ok(item) => {
|
||||
let mut read: usize = 0;
|
||||
match stream.write_all(
|
||||
&response::success::Default {
|
||||
mime: item.mime,
|
||||
//data: item.file.read(vec![1000]),
|
||||
data: &[], // init empty
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [info] [{peer}] Request: {}", now(), gemini.url),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
) {
|
||||
Ok(()) => loop {
|
||||
let mut data = vec![0; argument.chunk];
|
||||
let l = item.file.read_at(&mut data, read as u64).unwrap();
|
||||
stream.write_all(&data[..l]).unwrap();
|
||||
read += l;
|
||||
println!("[{}] [info] [{peer}] Chunk sent: {l} ({read} total)", now());
|
||||
// EOF
|
||||
if l == 0 {
|
||||
stream.flush().unwrap();
|
||||
stream.shutdown().unwrap();
|
||||
println!("[{}] [info] [{peer}] Response: {read} bytes", now());
|
||||
break;
|
||||
}
|
||||
},
|
||||
),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
}
|
||||
}
|
||||
Err(e) => send(
|
||||
&response::failure::permanent::NotFound {
|
||||
message: Some("Not found".to_string()),
|
||||
|
|
@ -184,7 +209,7 @@ fn titan(
|
|||
}
|
||||
|
||||
// validate client-side limits (from header)
|
||||
if titan.size > total {
|
||||
if total > titan.size {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
|
|
@ -227,7 +252,7 @@ fn titan(
|
|||
}
|
||||
|
||||
// just to make sure
|
||||
if titan.size > total {
|
||||
if total > titan.size {
|
||||
panic!()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue