Connection handling not a method of context anymore
This commit is contained in:
parent
337ca0149e
commit
34b8307426
208
src/main.rs
208
src/main.rs
@ -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>>>,
|
infos: HashMap<Box<str>, Arc<Mutex<SiteInfo>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
fn handle_connection(context: &mut Context, path: &Path, mut stream: TcpStream, pool: &ThreadPool) {
|
||||||
fn handle_connection(&mut self, path: &Path, mut stream: TcpStream, pool: &ThreadPool) {
|
let Some(request) = Request::from(&stream) else {
|
||||||
let Some(request) = Request::from(&stream) else {
|
eprintln!("Invalid request!");
|
||||||
eprintln!("Invalid request!");
|
return;
|
||||||
return;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
eprintln!();
|
eprintln!();
|
||||||
eprintln!("Request:");
|
eprintln!("Request:");
|
||||||
eprintln!("- Method: {}", request.method);
|
eprintln!("- Method: {}", request.method);
|
||||||
eprintln!("- Path: {}", request.path);
|
eprintln!("- Path: {}", request.path);
|
||||||
eprintln!("- Version: {}", request.version);
|
eprintln!("- Version: {}", request.version);
|
||||||
eprintln!("- Headers:");
|
eprintln!("- Headers:");
|
||||||
for header in request.headers {
|
for header in request.headers {
|
||||||
eprintln!(" - {header}");
|
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!("- 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) {
|
fn reply_image(mut stream: TcpStream, relative_path: &str, mut path: PathBuf) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user