mirror of
https://github.com/YGGverse/titanit.git
synced 2026-03-31 09:05:45 +00:00
update handlers
This commit is contained in:
parent
71d75bc22f
commit
7bf68725db
1 changed files with 155 additions and 113 deletions
268
src/main.rs
268
src/main.rs
|
|
@ -55,11 +55,11 @@ fn handle(argument: Arc<Argument>, peer: SocketAddr, stream: &mut TlsStream<TcpS
|
|||
println!("[{}] [info] [{peer}] New connection", now());
|
||||
let mut input = vec![0; titanite::HEADER_MAX_LEN];
|
||||
match stream.read(&mut input) {
|
||||
Ok(0) => println!("[{}] [warning] [{peer}] Connection closed by peer", now()),
|
||||
Ok(0) => println!("[{}] [warning] [{peer}] Peer closed connection", now()),
|
||||
Ok(s) => match Request::from_bytes(&input[..s]) {
|
||||
Ok(request) => match request {
|
||||
Request::Gemini(this) => handle_gemini(this, argument, peer, stream),
|
||||
Request::Titan(this) => handle_titan(this, argument, peer, stream),
|
||||
Request::Gemini(this) => gemini(this, argument, peer, stream),
|
||||
Request::Titan(this) => titan(this, argument, peer, stream),
|
||||
},
|
||||
Err(e) => send(
|
||||
&response::failure::temporary::General {
|
||||
|
|
@ -87,14 +87,14 @@ fn handle(argument: Arc<Argument>, peer: SocketAddr, stream: &mut TlsStream<TcpS
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_gemini(
|
||||
fn gemini(
|
||||
gemini: titanite::request::Gemini,
|
||||
argument: Arc<Argument>,
|
||||
peer: SocketAddr,
|
||||
stream: &mut TlsStream<TcpStream>,
|
||||
) {
|
||||
use titanite::*;
|
||||
match storage::Item::from_url(&gemini.url.as_str(), &argument.directory) {
|
||||
match storage::Item::from_url(gemini.url.as_str(), &argument.directory) {
|
||||
Ok(item) => send(
|
||||
&response::success::Default {
|
||||
mime: "text/gemini".to_string(),
|
||||
|
|
@ -121,7 +121,7 @@ fn handle_gemini(
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_titan(
|
||||
fn titan(
|
||||
titan: titanite::request::Titan,
|
||||
argument: Arc<Argument>,
|
||||
peer: SocketAddr,
|
||||
|
|
@ -134,143 +134,185 @@ fn handle_titan(
|
|||
let mut input = vec![0; argument.chunk];
|
||||
match stream.read(&mut input) {
|
||||
Ok(0) => {
|
||||
println!("[{}] [warning] [{peer}] Connection closed by peer", now());
|
||||
println!("[{}] [warning] [{peer}] Peer closed connection", now());
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
break;
|
||||
}
|
||||
Ok(l) => match tmp.file.write(&input[..l]) {
|
||||
Ok(s) => {
|
||||
total += s;
|
||||
if s != l {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
const MESSAGE: &str = "File sizes mismatch";
|
||||
return send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some(MESSAGE.to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [error] [{peer}] {MESSAGE}", now()),
|
||||
Err(e) => {
|
||||
println!("[{}] [error] [{peer}] {e}", now())
|
||||
}
|
||||
},
|
||||
);
|
||||
Ok(read) => {
|
||||
total += read;
|
||||
|
||||
// validate server-side limits
|
||||
if argument.size.is_some_and(|limit| total > limit) {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
// validate server-side limits
|
||||
if argument.size.is_some_and(|limit| total > limit) {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
const MESSAGE: &str = "Allowed max length limit reached";
|
||||
return send(
|
||||
&response::failure::permanent::BadRequest {
|
||||
message: Some(MESSAGE.to_string()),
|
||||
}
|
||||
const MESSAGE: &str = "Allowed max length limit reached";
|
||||
return send(
|
||||
&response::failure::permanent::BadRequest {
|
||||
message: Some(MESSAGE.to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {MESSAGE}", now()),
|
||||
Err(e) => {
|
||||
println!("[{}] [error] [{peer}] {e}", now())
|
||||
}
|
||||
},
|
||||
);
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {MESSAGE}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// validate client-side limits (from header)
|
||||
if titan.size > total {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
// all expected data received
|
||||
if titan.size >= total {
|
||||
// validate client-side limits
|
||||
if titan.size > total {
|
||||
const MESSAGE: &str = "Data size mismatch header declaration";
|
||||
return send(
|
||||
&response::failure::permanent::BadRequest {
|
||||
message: Some(MESSAGE.to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {MESSAGE}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// begin chunk recording into the temporary file
|
||||
match tmp.file.write(&input[..read]) {
|
||||
Ok(write) => {
|
||||
// validate file bytes recorded match stream bytes received
|
||||
if write != read {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
const MESSAGE: &str = "Data size mismatch header declaration";
|
||||
const MESSAGE: &str = "File size mismatch";
|
||||
return send(
|
||||
&response::failure::permanent::BadRequest {
|
||||
&response::failure::temporary::General {
|
||||
message: Some(MESSAGE.to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => {
|
||||
println!("[{}] [warning] [{peer}] {MESSAGE}", now())
|
||||
println!("[{}] [error] [{peer}] {MESSAGE}", now())
|
||||
}
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
},
|
||||
);
|
||||
}
|
||||
// @TODO detect/validate/cache mime based on data received
|
||||
// success
|
||||
match tmp.commit() {
|
||||
Ok(pmt) => send(
|
||||
&response::redirect::Permanent {
|
||||
target: match argument.redirect {
|
||||
Some(ref target) => format!(
|
||||
"{}/{}",
|
||||
target.trim_end_matches("/"),
|
||||
pmt.to_uri(&argument.directory)
|
||||
),
|
||||
None => format!(
|
||||
"gemini://{}/{}",
|
||||
argument.bind,
|
||||
pmt.to_uri(&argument.directory)
|
||||
),
|
||||
},
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!(
|
||||
"[{}] [info] [{peer}] Data saved to {}",
|
||||
now(),
|
||||
pmt.path.to_string_lossy()
|
||||
),
|
||||
Err(e) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
},
|
||||
),
|
||||
Err((tmp, e)) => send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| {
|
||||
match result {
|
||||
Ok(()) => {
|
||||
println!("[{}] [warning] [{peer}] {e}", now())
|
||||
}
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
};
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
|
||||
// all data received
|
||||
if titan.size >= total {
|
||||
// @TODO detect/validate/cache mime based on data received
|
||||
// success
|
||||
return match tmp.commit() {
|
||||
Ok(pmt) => send(
|
||||
&response::redirect::Permanent {
|
||||
target: match argument.redirect {
|
||||
Some(ref target) => format!(
|
||||
"{}/{}",
|
||||
target.trim_end_matches("/"),
|
||||
pmt.to_uri(&argument.directory)
|
||||
),
|
||||
None => format!(
|
||||
"gemini://{}/{}",
|
||||
argument.bind,
|
||||
pmt.to_uri(&argument.directory)
|
||||
),
|
||||
},
|
||||
}
|
||||
},
|
||||
),
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!(
|
||||
"[{}] [info] [{peer}] Data saved to {}",
|
||||
now(),
|
||||
pmt.path.to_string_lossy()
|
||||
),
|
||||
Err(e) => {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
if let Err(e) = pmt.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
Err((tmp, e)) => send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| {
|
||||
match result {
|
||||
Ok(()) => {
|
||||
println!("[{}] [warning] [{peer}] {e}", now())
|
||||
}
|
||||
Err(e) => {
|
||||
println!("[{}] [error] [{peer}] {e}", now())
|
||||
}
|
||||
};
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
},
|
||||
),
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
Err(e) => {
|
||||
return send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| {
|
||||
match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
};
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
Err(e) => todo!(),
|
||||
},
|
||||
Err(e) => send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
Err(e) => {
|
||||
if let Err(e) = tmp.delete() {
|
||||
println!("[{}] [error] [{peer}] {e}", now());
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
},
|
||||
),
|
||||
return send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => todo!(),
|
||||
Err(e) => send(
|
||||
&response::failure::temporary::General {
|
||||
message: Some("Internal server error".to_string()),
|
||||
}
|
||||
.into_bytes(),
|
||||
stream,
|
||||
|result| match result {
|
||||
Ok(()) => println!("[{}] [warning] [{peer}] {e}", now()),
|
||||
Err(e) => println!("[{}] [error] [{peer}] {e}", now()),
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue