This commit is contained in:
Mateusz Gruszczyński committed 2026-10-08 22:22:46 +02:00
1 parent 76cb4acef0
commit 68678e98be
84 files changed
+1519 -325

No files matched your search

+57 -1
View File
@@ -20,6 +20,35 @@ use http::{
};
use std::{io, path::PathBuf};
async fn resolve_php_path_info(
service: &CompiledService,
components: &[String],
) -> Option<(String, String)> {
let php = service.php.as_ref().filter(|php| php.path_info)?;
if components.len() < 2 {
return None;
}
for script_end in 0..components.len() - 1 {
let script_path = format!("/{}", components[..=script_end].join("/"));
if !php.extensions.iter().any(|extension| {
PathBuf::from(&script_path)
.extension()
.and_then(|value| value.to_str())
.is_some_and(|value| value.eq_ignore_ascii_case(extension))
}) {
continue;
}
match open_components(service, components[..=script_end].to_vec()).await {
Ok(opened) if opened.metadata.is_file() => {
let path_info = format!("/{}", components[script_end + 1..].join("/"));
return Some((script_path, path_info));
}
_ => continue,
}
}
None
}
async fn serve_inner(
service: &CompiledService,
method: Method,
@@ -104,11 +133,34 @@ async fn serve_inner(
{
return builtin_error_response(StatusCode::FORBIDDEN, &method);
}
let mut request_body = Some(body);
let opened = match open_components(service, components.clone()).await {
Ok(opened) => opened,
Err(error)
if matches!(error.kind(), io::ErrorKind::NotFound | io::ErrorKind::NotADirectory) =>
{
if let Some((script_path, path_info)) = resolve_php_path_info(service, &components).await {
let public_path = PathBuf::from(&script_path);
if let Some(php) = php_for_path(service, &public_path) {
return php_response(
service,
php,
method,
headers,
uri,
script_path,
Some(path_info),
effective_query,
request_body.take().unwrap_or_else(Body::empty),
context,
)
.await;
}
}
return io_response(&error);
}
Err(error) => return io_response(&error),
};
let mut request_body = Some(body);
if opened.metadata.is_file() {
let public_path = PathBuf::from(&effective_path);
@@ -120,6 +172,7 @@ async fn serve_inner(
headers,
uri,
effective_path,
None,
effective_query,
request_body.take().unwrap_or_else(Body::empty),
context,
@@ -172,6 +225,7 @@ async fn serve_inner(
headers,
uri,
script_path,
None,
effective_query,
request_body.take().unwrap_or_else(Body::empty),
context,
@@ -289,9 +343,11 @@ pub async fn serve(
body: Body,
context: RequestContext,
) -> Response {
let start = std::time::Instant::now();
let mut response = serve_inner(service, method, headers, uri, path, body, context).await;
add_service_headers(&mut response, service);
htaccess::apply_response(service.htaccess.as_ref(), &mut response, path);
strip_unnecessary_headers(&mut response, service);
service.web_metrics.record(response.status(), start.elapsed().as_micros().min(u64::MAX as u128) as u64);
response
}