Connection handling not a method of context anymore

This commit is contained in:
p11 2023-09-16 16:34:53 +02:00
parent 337ca0149e
commit 34b8307426

View File

@ -52,7 +52,7 @@ fn main() {
}
}
context.handle_connection(&path, stream, &pool);
handle_connection(&mut context, &path, stream, &pool);
}
}
@ -133,112 +133,110 @@ struct Context {
infos: HashMap<Box<str>, Arc<Mutex<SiteInfo>>>,
}
impl Context {
fn handle_connection(&mut self, path: &Path, mut stream: TcpStream, pool: &ThreadPool) {
let Some(request) = Request::from(&stream) else {
eprintln!("Invalid request!");
return;
};
fn handle_connection(context: &mut Context, path: &Path, mut stream: TcpStream, pool: &ThreadPool) {
let Some(request) = Request::from(&stream) else {
eprintln!("Invalid request!");
return;
};
eprintln!();
eprintln!("Request:");
eprintln!("- Method: {}", request.method);
eprintln!("- Path: {}", request.path);
eprintln!("- Version: {}", request.version);
eprintln!("- Headers:");
for header in request.headers {
eprintln!(" - {header}");
}
eprintln!("- Body: {}", request.body);
eprintln!();
let (mut relative_path, _) = request
.path
.split_once('?')
.unwrap_or((&request.path, Default::default()));
if relative_path.contains("//") {
fail(stream);
return;
}
if let Some(path) = relative_path.strip_prefix('/') {
relative_path = path;
}
let mut pk_path = path.to_path_buf();
let mut data_path = path.to_path_buf();
let (pki_path, start_level, relative_path) = if relative_path.is_empty() {
pk_path.push("index.pk");
data_path.push("index.dat");
(None, 0, String::new())
} else {
let mut pki_path = path.to_path_buf();
let path = percent_decode_str(relative_path).decode_utf8_lossy();
if path.contains('_') {
let path = path.replace('_', " ");
let _ = write!(stream, "HTTP/1.1 308 Permanent Redirect\r\n");
let _ = write!(stream, "Location: /{path}\r\n\r\n");
return;
}
pk_path.push(format!("{path}.pk"));
pki_path.push(format!("{path}.pki"));
data_path.push(format!("{path}.dat"));
(Some(pki_path), 1, path.to_string())
};
if relative_path.split('/').any(|name| name == "Images") {
let path = path.to_path_buf();
pool.execute(move || reply_image(stream, &relative_path, path));
return;
}
if !Path::is_file(&pk_path) {
fail(stream);
return;
}
if let Some(pki_path) = &pki_path {
if !Path::is_file(pki_path) {
fail(stream);
return;
}
}
use Entry::*;
let info = match self.infos.entry(relative_path.clone().into_boxed_str()) {
Occupied(o) => o.get().clone(),
Vacant(v) => v
.insert(Arc::new(Mutex::new(
File::open(&data_path)
.map(|mut file| {
from_stream::<PortableSettings, _, _>(&mut file).unwrap_or_default()
})
.unwrap_or_default(),
)))
.clone(),
};
let path = path.to_path_buf();
pool.execute(move || {
handle_relative_connection(
info,
stream,
&request.body,
&relative_path,
&path,
&pk_path,
pki_path.as_ref().map(|path| path.as_ref()),
&data_path,
start_level,
)
});
eprintln!();
eprintln!("Request:");
eprintln!("- Method: {}", request.method);
eprintln!("- Path: {}", request.path);
eprintln!("- Version: {}", request.version);
eprintln!("- Headers:");
for header in request.headers {
eprintln!(" - {header}");
}
eprintln!("- Body: {}", request.body);
eprintln!();
let (mut relative_path, _) = request
.path
.split_once('?')
.unwrap_or((&request.path, Default::default()));
if relative_path.contains("//") {
fail(stream);
return;
}
if let Some(path) = relative_path.strip_prefix('/') {
relative_path = path;
}
let mut pk_path = path.to_path_buf();
let mut data_path = path.to_path_buf();
let (pki_path, start_level, relative_path) = if relative_path.is_empty() {
pk_path.push("index.pk");
data_path.push("index.dat");
(None, 0, String::new())
} else {
let mut pki_path = path.to_path_buf();
let path = percent_decode_str(relative_path).decode_utf8_lossy();
if path.contains('_') {
let path = path.replace('_', " ");
let _ = write!(stream, "HTTP/1.1 308 Permanent Redirect\r\n");
let _ = write!(stream, "Location: /{path}\r\n\r\n");
return;
}
pk_path.push(format!("{path}.pk"));
pki_path.push(format!("{path}.pki"));
data_path.push(format!("{path}.dat"));
(Some(pki_path), 1, path.to_string())
};
if relative_path.split('/').any(|name| name == "Images") {
let path = path.to_path_buf();
pool.execute(move || reply_image(stream, &relative_path, path));
return;
}
if !Path::is_file(&pk_path) {
fail(stream);
return;
}
if let Some(pki_path) = &pki_path {
if !Path::is_file(pki_path) {
fail(stream);
return;
}
}
use Entry::*;
let info = match context.infos.entry(relative_path.clone().into_boxed_str()) {
Occupied(o) => o.get().clone(),
Vacant(v) => v
.insert(Arc::new(Mutex::new(
File::open(&data_path)
.map(|mut file| {
from_stream::<PortableSettings, _, _>(&mut file).unwrap_or_default()
})
.unwrap_or_default(),
)))
.clone(),
};
let path = path.to_path_buf();
pool.execute(move || {
handle_relative_connection(
info,
stream,
&request.body,
&relative_path,
&path,
&pk_path,
pki_path.as_ref().map(|path| path.as_ref()),
&data_path,
start_level,
)
});
}
fn reply_image(mut stream: TcpStream, relative_path: &str, mut path: PathBuf) {