1use std::convert::Infallible;
2use std::net::SocketAddr;
3use std::str::FromStr;
4use std::sync::Arc;
5use std::time::Duration;
6
7use async_channel::Sender;
8use chrono::{DateTime, Local};
9use futures_util::stream::TryStreamExt;
10use http_body_util::combinators::BoxBody;
11use http_body_util::{BodyExt, Empty, Full, StreamBody};
12use hyper::body::{Body, Bytes, Frame};
13use hyper::header::{HeaderName, HeaderValue};
14use hyper::{header, HeaderMap, Method, Request, Response, StatusCode};
15#[cfg(feature = "runtime-tokio")]
16use tokio::io::BufReader;
17#[cfg(feature = "runtime-tokio")]
18use tokio_util::io::ReaderStream;
19
20use crate::config::{ServerConfiguration, ServerConfigurations};
21use crate::get_value;
22use crate::logging::{ErrorLogger, LogMessage, Loggers};
23use crate::runtime::timeout;
24#[cfg(feature = "runtime-monoio")]
25use crate::util::MonoioFileStream;
26use crate::util::{
27 generate_default_error_page, replace_header_placeholders, replace_log_placeholders, sanitize_url, SERVER_SOFTWARE,
28};
29
30use ferron_common::modules::{ModuleHandlers, RequestData, SocketData};
31use ferron_common::{get_entries, get_entry};
32
33async fn generate_error_response(
35 status_code: StatusCode,
36 config: &ServerConfiguration,
37 headers: &Option<HeaderMap>,
38) -> Response<BoxBody<Bytes, std::io::Error>> {
39 let bare_body = generate_default_error_page(
40 status_code,
41 get_value!("server_administrator_email", config).and_then(|v| v.as_str()),
42 );
43 let mut content_length: Option<u64> = bare_body.len().try_into().ok();
44 let mut response_body = Full::new(Bytes::from(bare_body)).map_err(|e| match e {}).boxed();
45
46 if let Some(error_pages) = get_entries!("error_page", config) {
47 for error_page in &error_pages.inner {
48 if let Some(page_status_code) = error_page.values.first().and_then(|v| v.as_i128()) {
49 let page_status_code = match StatusCode::from_u16(match page_status_code.try_into() {
50 Ok(status_code) => status_code,
51 Err(_) => continue,
52 }) {
53 Ok(status_code) => status_code,
54 Err(_) => continue,
55 };
56 if status_code != page_status_code {
57 continue;
58 }
59 if let Some(page_path) = error_page.values.get(1).and_then(|v| v.as_str()) {
60 #[cfg(feature = "runtime-monoio")]
61 let file = monoio::fs::File::open(page_path).await;
62 #[cfg(feature = "runtime-tokio")]
63 let file = tokio::fs::File::open(page_path).await;
64
65 let file = match file {
66 Ok(file) => file,
67 Err(_) => continue,
68 };
69
70 #[cfg(any(feature = "runtime-tokio", all(feature = "runtime-monoio", unix)))]
72 let metadata = file.metadata().await;
73 #[cfg(all(feature = "runtime-monoio", windows))]
74 let metadata = {
75 let page_path = page_path.to_owned();
76 monoio::spawn_blocking(move || std::fs::metadata(page_path))
77 .await
78 .unwrap_or(Err(std::io::Error::other(
79 "Can't spawn a blocking task to obtain the file metadata",
80 )))
81 };
82
83 content_length = match metadata {
84 Ok(metadata) => Some(metadata.len()),
85 Err(_) => None,
86 };
87
88 #[cfg(feature = "runtime-monoio")]
89 let file_stream = MonoioFileStream::new(file, None, content_length);
90 #[cfg(feature = "runtime-tokio")]
91 let file_stream = ReaderStream::new(BufReader::with_capacity(12800, file));
92
93 let stream_body = StreamBody::new(file_stream.map_ok(Frame::data));
94 let boxed_body = stream_body.boxed();
95
96 response_body = boxed_body;
97
98 break;
99 }
100 }
101 }
102 }
103
104 let mut response_builder = Response::builder().status(status_code);
105
106 if let Some(headers) = headers {
107 let headers_iter = headers.iter();
108 for (name, value) in headers_iter {
109 if name != header::CONTENT_TYPE && name != header::CONTENT_LENGTH {
110 response_builder = response_builder.header(name, value);
111 }
112 }
113 }
114
115 if let Some(content_length) = content_length {
116 response_builder = response_builder.header(header::CONTENT_LENGTH, content_length);
117 }
118 response_builder = response_builder.header(header::CONTENT_TYPE, "text/html");
119
120 response_builder.body(response_body).unwrap_or_default()
121}
122
123#[allow(clippy::too_many_arguments)]
125async fn log_access(
126 logger: &Sender<LogMessage>,
127 request_parts: &hyper::http::request::Parts,
128 socket_data: &SocketData,
129 auth_user: Option<&str>,
130 status_code: u16,
131 content_length: Option<u64>,
132 date_format: Option<&str>,
133 log_format: Option<&str>,
134) {
135 let now: DateTime<Local> = Local::now();
136 let formatted_time = now.format(date_format.unwrap_or("%d/%b/%Y:%H:%M:%S %z")).to_string();
137 logger
138 .send(LogMessage::new(
139 replace_log_placeholders(
140 log_format.unwrap_or(
141 "{client_ip} - {auth_user} [{timestamp}] \"{method} {path_and_query} {version}\" \
142 {status_code} {content_length} \"{header:Referer}\" \"{header:User-Agent}\"",
143 ),
144 request_parts,
145 socket_data,
146 auth_user,
147 &formatted_time,
148 status_code,
149 content_length,
150 ),
151 false,
152 ))
153 .await
154 .unwrap_or_default();
155}
156
157fn add_custom_headers(
159 response_parts: &mut hyper::http::response::Parts,
160 headers_to_add: &HeaderMap,
161 headers_to_replace: &HeaderMap,
162 headers_to_remove: &[HeaderName],
163) {
164 for (header_name, header_value) in headers_to_add {
165 if !response_parts.headers.contains_key(header_name) {
166 response_parts.headers.insert(header_name, header_value.to_owned());
167 }
168 }
169
170 for (header_name, header_value) in headers_to_replace {
171 response_parts.headers.insert(header_name, header_value.to_owned());
172 }
173
174 for header_to_remove in headers_to_remove.iter().rev() {
175 if response_parts.headers.contains_key(header_to_remove) {
176 while response_parts.headers.remove(header_to_remove).is_some() {}
177 }
178 }
179}
180
181fn add_http3_alt_svc_header(response_parts: &mut hyper::http::response::Parts, http3_alt_port: Option<u16>) {
183 if let Some(http3_alt_port) = http3_alt_port {
184 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
185 Some(value) => {
186 let header_value_old = String::from_utf8_lossy(value.as_bytes());
187 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
188
189 if header_value_old != header_value_new {
190 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
191 } else {
192 HeaderValue::from_bytes(header_value_old.as_bytes())
193 }
194 }
195 None => HeaderValue::from_bytes(format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes()),
196 } {
197 response_parts.headers.insert(header::ALT_SVC, header_value);
198 }
199 }
200}
201
202fn add_server_header(response_parts: &mut hyper::http::response::Parts) {
204 response_parts
205 .headers
206 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
207}
208
209fn extract_content_length(response: &Response<BoxBody<Bytes, std::io::Error>>) -> Option<u64> {
211 match response.headers().get(header::CONTENT_LENGTH) {
212 Some(header_value) => match header_value.to_str() {
213 Ok(header_value) => match header_value.parse::<u64>() {
214 Ok(content_length) => Some(content_length),
215 Err(_) => response.body().size_hint().exact(),
216 },
217 Err(_) => response.body().size_hint().exact(),
218 },
219 None => response.body().size_hint().exact(),
220 }
221}
222
223#[allow(clippy::too_many_arguments)]
225async fn finalize_response_and_log(
226 response: Response<BoxBody<Bytes, std::io::Error>>,
227 http3_alt_port: Option<u16>,
228 headers_to_add: HeaderMap,
229 headers_to_replace: HeaderMap,
230 headers_to_remove: Vec<HeaderName>,
231 logger: &Option<Sender<LogMessage>>,
232 request_parts: &Option<hyper::http::request::Parts>,
233 socket_data: &SocketData,
234 latest_auth_data: Option<&str>,
235 date_format: Option<&str>,
236 log_format: Option<&str>,
237) -> Response<BoxBody<Bytes, std::io::Error>> {
238 let (mut response_parts, response_body) = response.into_parts();
239
240 add_custom_headers(
241 &mut response_parts,
242 &headers_to_add,
243 &headers_to_replace,
244 &headers_to_remove,
245 );
246 add_http3_alt_svc_header(&mut response_parts, http3_alt_port);
247 add_server_header(&mut response_parts);
248
249 let response = Response::from_parts(response_parts, response_body);
250
251 if let Some(request_parts) = request_parts {
252 if let Some(logger) = &logger {
253 log_access(
254 logger,
255 request_parts,
256 socket_data,
257 latest_auth_data,
258 response.status().as_u16(),
259 extract_content_length(&response),
260 date_format,
261 log_format,
262 )
263 .await;
264 }
265 }
266
267 response
268}
269
270#[allow(clippy::too_many_arguments)]
272async fn execute_response_modifying_handlers(
273 mut response: Response<BoxBody<Bytes, std::io::Error>>,
274 mut executed_handlers: Vec<Box<dyn ModuleHandlers>>,
275 configuration: &ServerConfiguration,
276 http3_alt_port: Option<u16>,
277 headers_to_add: HeaderMap,
278 headers_to_replace: HeaderMap,
279 headers_to_remove: Vec<HeaderName>,
280 logger: &Option<Sender<LogMessage>>,
281 error_log_enabled: bool,
282 request_parts: &Option<hyper::http::request::Parts>,
283 socket_data: &SocketData,
284 latest_auth_data: Option<&str>,
285 date_format: Option<&str>,
286 log_format: Option<&str>,
287) -> Result<Response<BoxBody<Bytes, std::io::Error>>, Response<BoxBody<Bytes, std::io::Error>>> {
288 while let Some(mut executed_handler) = executed_handlers.pop() {
289 let response_status = executed_handler.response_modifying_handler(response).await;
290 response = match response_status {
291 Ok(response) => response,
292 Err(err) => {
293 if error_log_enabled {
294 if let Some(logger) = &logger {
295 logger
296 .send(LogMessage::new(
297 format!("Unexpected error while serving a request: {err}"),
298 true,
299 ))
300 .await
301 .unwrap_or_default();
302 }
303 }
304
305 let error_response = generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, configuration, &None).await;
306
307 let final_response = finalize_response_and_log(
308 error_response,
309 http3_alt_port,
310 headers_to_add,
311 headers_to_replace,
312 headers_to_remove,
313 logger,
314 request_parts,
315 socket_data,
316 latest_auth_data,
317 date_format,
318 log_format,
319 )
320 .await;
321
322 return Err(final_response);
323 }
324 };
325 }
326 Ok(response)
327}
328
329#[allow(clippy::too_many_arguments)]
331async fn request_handler_wrapped(
332 mut request: Request<BoxBody<Bytes, std::io::Error>>,
333 client_address: SocketAddr,
334 server_address: SocketAddr,
335 encrypted: bool,
336 configurations: Arc<ServerConfigurations>,
337 loggers: Loggers,
338 http3_alt_port: Option<u16>,
339 acme_http_01_resolvers: Arc<tokio::sync::RwLock<Vec<crate::acme::Http01DataLock>>>,
340 proxy_protocol_client_address: Option<SocketAddr>,
341 proxy_protocol_server_address: Option<SocketAddr>,
342) -> Result<Response<BoxBody<Bytes, std::io::Error>>, Infallible> {
343 let global_configuration = configurations.find_global_configuration();
345
346 let log_enabled = !global_configuration
348 .as_deref()
349 .and_then(|c| get_value!("log", c))
350 .is_none_or(|v| v.is_null());
351 let error_log_enabled = !global_configuration
352 .as_deref()
353 .and_then(|c| get_value!("error_log", c))
354 .is_none_or(|v| v.is_null());
355
356 match request.version() {
358 hyper::Version::HTTP_2 | hyper::Version::HTTP_3 => {
359 if let Some(authority) = request.uri().authority() {
361 let authority = authority.to_owned();
362 let headers = request.headers_mut();
363 if !headers.contains_key(header::HOST) {
364 if let Ok(authority_value) = HeaderValue::from_bytes(authority.as_str().as_bytes()) {
365 headers.append(header::HOST, authority_value);
366 }
367 }
368 }
369
370 let mut cookie_normalized = String::new();
372 let mut cookie_set = false;
373 let headers = request.headers_mut();
374 for cookie in headers.get_all(header::COOKIE) {
375 if let Ok(cookie) = cookie.to_str() {
376 if cookie_set {
377 cookie_normalized.push_str("; ");
378 }
379 cookie_set = true;
380 cookie_normalized.push_str(cookie);
381 }
382 }
383 if cookie_set {
384 if let Ok(cookie_value) = HeaderValue::from_bytes(cookie_normalized.as_bytes()) {
385 headers.insert(header::COOKIE, cookie_value);
386 }
387 }
388 }
389 _ => (),
390 }
391
392 let mut socket_data = SocketData {
394 remote_addr: proxy_protocol_client_address.unwrap_or(client_address),
395 local_addr: proxy_protocol_server_address.unwrap_or(server_address),
396 encrypted,
397 };
398
399 let host_header_option = request.headers().get(header::HOST);
401 if let Some(header_data) = host_header_option {
402 match header_data.to_str() {
403 Ok(host_header) => {
404 let host_header_lower_case = host_header.to_lowercase();
405 let host_header_without_dot = host_header_lower_case
406 .strip_suffix('.')
407 .unwrap_or(host_header_lower_case.as_str());
408 if host_header_without_dot != host_header {
409 let host_header_value = match HeaderValue::from_str(host_header_without_dot) {
410 Ok(host_header_value) => host_header_value,
411 Err(err) => {
412 if error_log_enabled {
413 if let Some(logger) = loggers.find_global_logger() {
414 logger
415 .send(LogMessage::new(format!("Host header sanitation error: {err}"), true))
416 .await
417 .unwrap_or_default();
418 }
419 }
420 let response = Response::builder()
421 .status(StatusCode::BAD_REQUEST)
422 .header(header::CONTENT_TYPE, "text/html")
423 .body(
424 Full::new(Bytes::from(generate_default_error_page(StatusCode::BAD_REQUEST, None)))
425 .map_err(|e| match e {})
426 .boxed(),
427 )
428 .unwrap_or_default();
429
430 if log_enabled {
431 let (request_parts, _) = request.into_parts();
432 if let Some(logger) = loggers.find_global_logger() {
433 log_access(
434 &logger,
435 &request_parts,
436 &socket_data,
437 None,
438 response.status().as_u16(),
439 match response.headers().get(header::CONTENT_LENGTH) {
440 Some(header_value) => match header_value.to_str() {
441 Ok(header_value) => match header_value.parse::<u64>() {
442 Ok(content_length) => Some(content_length),
443 Err(_) => response.body().size_hint().exact(),
444 },
445 Err(_) => response.body().size_hint().exact(),
446 },
447 None => response.body().size_hint().exact(),
448 },
449 global_configuration
450 .as_deref()
451 .and_then(|c| get_value!("log_date_format", c))
452 .and_then(|v| v.as_str()),
453 global_configuration
454 .as_deref()
455 .and_then(|c| get_value!("log_format", c))
456 .and_then(|v| v.as_str()),
457 )
458 .await;
459 }
460 }
461 let (mut response_parts, response_body) = response.into_parts();
462 if let Some(http3_alt_port) = http3_alt_port {
463 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
464 Some(value) => {
465 let header_value_old = String::from_utf8_lossy(value.as_bytes());
466 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
467
468 if header_value_old != header_value_new {
469 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
470 } else {
471 HeaderValue::from_bytes(header_value_old.as_bytes())
472 }
473 }
474 None => {
475 HeaderValue::from_bytes(format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes())
476 }
477 } {
478 response_parts.headers.insert(header::ALT_SVC, header_value);
479 }
480 }
481 response_parts
482 .headers
483 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
484
485 return Ok(Response::from_parts(response_parts, response_body));
486 }
487 };
488
489 request.headers_mut().insert(header::HOST, host_header_value);
490 }
491 }
492 Err(err) => {
493 if error_log_enabled {
494 if let Some(logger) = loggers.find_global_logger() {
495 logger
496 .send(LogMessage::new(format!("Host header sanitation error: {err}"), true))
497 .await
498 .unwrap_or_default();
499 }
500 }
501 let response = Response::builder()
502 .status(StatusCode::BAD_REQUEST)
503 .header(header::CONTENT_TYPE, "text/html")
504 .body(
505 Full::new(Bytes::from(generate_default_error_page(StatusCode::BAD_REQUEST, None)))
506 .map_err(|e| match e {})
507 .boxed(),
508 )
509 .unwrap_or_default();
510 if log_enabled {
511 let (request_parts, _) = request.into_parts();
512 if let Some(logger) = loggers.find_global_logger() {
513 log_access(
514 &logger,
515 &request_parts,
516 &socket_data,
517 None,
518 response.status().as_u16(),
519 match response.headers().get(header::CONTENT_LENGTH) {
520 Some(header_value) => match header_value.to_str() {
521 Ok(header_value) => match header_value.parse::<u64>() {
522 Ok(content_length) => Some(content_length),
523 Err(_) => response.body().size_hint().exact(),
524 },
525 Err(_) => response.body().size_hint().exact(),
526 },
527 None => response.body().size_hint().exact(),
528 },
529 global_configuration
530 .as_deref()
531 .and_then(|c| get_value!("log_date_format", c))
532 .and_then(|v| v.as_str()),
533 global_configuration
534 .as_deref()
535 .and_then(|c| get_value!("log_format", c))
536 .and_then(|v| v.as_str()),
537 )
538 .await;
539 }
540 }
541 let (mut response_parts, response_body) = response.into_parts();
542 if let Some(http3_alt_port) = http3_alt_port {
543 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
544 Some(value) => {
545 let header_value_old = String::from_utf8_lossy(value.as_bytes());
546 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
547
548 if header_value_old != header_value_new {
549 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
550 } else {
551 HeaderValue::from_bytes(header_value_old.as_bytes())
552 }
553 }
554 None => {
555 HeaderValue::from_bytes(format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes())
556 }
557 } {
558 response_parts.headers.insert(header::ALT_SVC, header_value);
559 }
560 }
561 response_parts
562 .headers
563 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
564
565 return Ok(Response::from_parts(response_parts, response_body));
566 }
567 }
568 };
569
570 let hostname_determinant = match request.headers().get(header::HOST) {
571 Some(value) => value.to_str().ok().map(|h| {
572 if let Some((left, right)) = h.rsplit_once(':') {
573 if right.parse::<u16>().is_ok() {
574 left.to_string()
575 } else {
576 h.to_string()
577 }
578 } else {
579 h.to_string()
580 }
581 }),
582 None => None,
583 };
584
585 let (request_parts, request_body) = request.into_parts();
586 let log_request_parts = if log_enabled { Some(request_parts.clone()) } else { None };
587 let request = Request::from_parts(request_parts, request_body);
588
589 let (request_parts, request_body) = request.into_parts();
591 let configuration_option =
592 configurations.find_configuration(&request_parts, hostname_determinant.as_deref(), &socket_data);
593 let mut request = Request::from_parts(request_parts, request_body);
594 let mut configuration = match configuration_option {
595 Ok(Some(configuration)) => configuration,
596 Ok(None) => {
597 if error_log_enabled {
598 if let Some(logger) = loggers.find_global_logger() {
599 logger
600 .send(LogMessage::new(
601 String::from("Cannot determine server configuration"),
602 true,
603 ))
604 .await
605 .unwrap_or_default()
606 }
607 }
608 let response = Response::builder()
609 .status(StatusCode::INTERNAL_SERVER_ERROR)
610 .header(header::CONTENT_TYPE, "text/html")
611 .body(
612 Full::new(Bytes::from(generate_default_error_page(
613 StatusCode::INTERNAL_SERVER_ERROR,
614 None,
615 )))
616 .map_err(|e| match e {})
617 .boxed(),
618 )
619 .unwrap_or_default();
620 if log_enabled {
621 let (request_parts, _) = request.into_parts();
622 if let Some(logger) = loggers.find_global_logger() {
623 log_access(
624 &logger,
625 &request_parts,
626 &socket_data,
627 None,
628 response.status().as_u16(),
629 match response.headers().get(header::CONTENT_LENGTH) {
630 Some(header_value) => match header_value.to_str() {
631 Ok(header_value) => match header_value.parse::<u64>() {
632 Ok(content_length) => Some(content_length),
633 Err(_) => response.body().size_hint().exact(),
634 },
635 Err(_) => response.body().size_hint().exact(),
636 },
637 None => response.body().size_hint().exact(),
638 },
639 global_configuration
640 .as_deref()
641 .and_then(|c| get_value!("log_date_format", c))
642 .and_then(|v| v.as_str()),
643 global_configuration
644 .as_deref()
645 .and_then(|c| get_value!("log_format", c))
646 .and_then(|v| v.as_str()),
647 )
648 .await;
649 }
650 }
651 let (mut response_parts, response_body) = response.into_parts();
652 if let Some(http3_alt_port) = http3_alt_port {
653 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
654 Some(value) => {
655 let header_value_old = String::from_utf8_lossy(value.as_bytes());
656 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
657
658 if header_value_old != header_value_new {
659 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
660 } else {
661 HeaderValue::from_bytes(header_value_old.as_bytes())
662 }
663 }
664 None => HeaderValue::from_bytes(format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes()),
665 } {
666 response_parts.headers.insert(header::ALT_SVC, header_value);
667 }
668 }
669 response_parts
670 .headers
671 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
672
673 return Ok(Response::from_parts(response_parts, response_body));
674 }
675 Err(err) => {
676 if error_log_enabled {
677 if let Some(logger) = loggers.find_global_logger() {
678 logger
679 .send(LogMessage::new(
680 format!("Cannot determine server configuration: {err}"),
681 true,
682 ))
683 .await
684 .unwrap_or_default()
685 }
686 }
687 let response = Response::builder()
688 .status(StatusCode::INTERNAL_SERVER_ERROR)
689 .header(header::CONTENT_TYPE, "text/html")
690 .body(
691 Full::new(Bytes::from(generate_default_error_page(
692 StatusCode::INTERNAL_SERVER_ERROR,
693 None,
694 )))
695 .map_err(|e| match e {})
696 .boxed(),
697 )
698 .unwrap_or_default();
699 if log_enabled {
700 let (request_parts, _) = request.into_parts();
701 if let Some(logger) = loggers.find_global_logger() {
702 log_access(
703 &logger,
704 &request_parts,
705 &socket_data,
706 None,
707 response.status().as_u16(),
708 match response.headers().get(header::CONTENT_LENGTH) {
709 Some(header_value) => match header_value.to_str() {
710 Ok(header_value) => match header_value.parse::<u64>() {
711 Ok(content_length) => Some(content_length),
712 Err(_) => response.body().size_hint().exact(),
713 },
714 Err(_) => response.body().size_hint().exact(),
715 },
716 None => response.body().size_hint().exact(),
717 },
718 global_configuration
719 .as_deref()
720 .and_then(|c| get_value!("log_date_format", c))
721 .and_then(|v| v.as_str()),
722 global_configuration
723 .as_deref()
724 .and_then(|c| get_value!("log_format", c))
725 .and_then(|v| v.as_str()),
726 )
727 .await;
728 }
729 }
730 let (mut response_parts, response_body) = response.into_parts();
731 if let Some(http3_alt_port) = http3_alt_port {
732 if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
733 Some(value) => {
734 let header_value_old = String::from_utf8_lossy(value.as_bytes());
735 let header_value_new = format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"");
736
737 if header_value_old != header_value_new {
738 HeaderValue::from_bytes(format!("{header_value_old}, {header_value_new}").as_bytes())
739 } else {
740 HeaderValue::from_bytes(header_value_old.as_bytes())
741 }
742 }
743 None => HeaderValue::from_bytes(format!("h3=\":{http3_alt_port}\", h3-29=\":{http3_alt_port}\"").as_bytes()),
744 } {
745 response_parts.headers.insert(header::ALT_SVC, header_value);
746 }
747 }
748 response_parts
749 .headers
750 .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
751
752 return Ok(Response::from_parts(response_parts, response_body));
753 }
754 };
755
756 let mut log_date_format = get_value!("log_date_format", configuration).and_then(|v| v.as_str());
758 let mut log_format = get_value!("log_format", configuration).and_then(|v| v.as_str());
759
760 let logger = loggers.find_logger(
762 hostname_determinant.as_deref(),
763 socket_data.local_addr.ip(),
764 socket_data.local_addr.port(),
765 );
766 let log_enabled = !get_value!("log", configuration).is_none_or(|v| v.is_null());
767 let error_log_enabled = !get_value!("error_log", configuration).is_none_or(|v| v.is_null());
768
769 let url_pathname = request.uri().path();
771 let sanitized_url_pathname = match sanitize_url(
772 url_pathname,
773 get_value!("allow_double_slashes", configuration)
774 .and_then(|v| v.as_bool())
775 .unwrap_or(false),
776 ) {
777 Ok(sanitized_url) => sanitized_url,
778 Err(err) => {
779 if error_log_enabled {
780 if let Some(logger) = &logger {
781 logger
782 .send(LogMessage::new(format!("URL sanitation error: {err}"), true))
783 .await
784 .unwrap_or_default();
785 }
786 }
787 let response = generate_error_response(StatusCode::BAD_REQUEST, &configuration, &None).await;
788
789 let mut headers_to_add = HeaderMap::new();
791 let mut headers_to_replace = HeaderMap::new();
792 let mut headers_to_remove = Vec::new();
793 let (request_parts, _) = request.into_parts();
794 if let Some(custom_headers) = get_entries!("header", configuration) {
795 for custom_header in custom_headers.inner.iter().rev() {
796 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
797 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
798 if !headers_to_add.contains_key(header_name) {
799 if let Ok(header_name) = HeaderName::from_str(header_name) {
800 if let Ok(header_value) =
801 HeaderValue::from_str(&replace_header_placeholders(header_value, &request_parts, None))
802 {
803 headers_to_add.insert(header_name, header_value);
804 }
805 }
806 }
807 }
808 }
809 }
810 }
811 if let Some(custom_headers) = get_entries!("header_replace", configuration) {
812 for custom_header in custom_headers.inner.iter().rev() {
813 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
814 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
815 if let Ok(header_name) = HeaderName::from_str(header_name) {
816 if let Ok(header_value) =
817 HeaderValue::from_str(&replace_header_placeholders(header_value, &request_parts, None))
818 {
819 headers_to_replace.insert(header_name, header_value);
820 }
821 }
822 }
823 }
824 }
825 }
826 if let Some(custom_headers_to_remove) = get_entries!("header_remove", configuration) {
827 for custom_header in custom_headers_to_remove.inner.iter().rev() {
828 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
829 if let Ok(header_name) = HeaderName::from_str(header_name) {
830 headers_to_remove.push(header_name);
831 }
832 }
833 }
834 }
835
836 return Ok(
837 finalize_response_and_log(
838 response,
839 http3_alt_port,
840 headers_to_add,
841 headers_to_replace,
842 headers_to_remove,
843 &logger,
844 &log_request_parts,
845 &socket_data,
846 None,
847 log_date_format,
848 log_format,
849 )
850 .await,
851 );
852 }
853 };
854
855 if sanitized_url_pathname != url_pathname {
856 let (mut parts, body) = request.into_parts();
857 let orig_uri = parts.uri.clone();
858 let mut url_parts = parts.uri.into_parts();
859 url_parts.path_and_query = Some(
860 match format!(
861 "{}{}",
862 sanitized_url_pathname,
863 match url_parts.path_and_query {
864 Some(path_and_query) => {
865 match path_and_query.query() {
866 Some(query) => format!("?{query}"),
867 None => String::from(""),
868 }
869 }
870 None => String::from(""),
871 }
872 )
873 .parse()
874 {
875 Ok(path_and_query) => path_and_query,
876 Err(err) => {
877 if error_log_enabled {
878 if let Some(logger) = &logger {
879 logger
880 .send(LogMessage::new(format!("URL sanitation error: {err}"), true))
881 .await
882 .unwrap_or_default();
883 }
884 }
885 let response = generate_error_response(StatusCode::BAD_REQUEST, &configuration, &None).await;
886
887 parts.uri = orig_uri;
888
889 let mut headers_to_add = HeaderMap::new();
891 let mut headers_to_replace = HeaderMap::new();
892 let mut headers_to_remove = Vec::new();
893 if let Some(custom_headers) = get_entries!("header", configuration) {
894 for custom_header in custom_headers.inner.iter().rev() {
895 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
896 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
897 if !headers_to_add.contains_key(header_name) {
898 if let Ok(header_name) = HeaderName::from_str(header_name) {
899 if let Ok(header_value) =
900 HeaderValue::from_str(&replace_header_placeholders(header_value, &parts, None))
901 {
902 headers_to_add.insert(header_name, header_value);
903 }
904 }
905 }
906 }
907 }
908 }
909 }
910 if let Some(custom_headers) = get_entries!("header_replace", configuration) {
911 for custom_header in custom_headers.inner.iter().rev() {
912 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
913 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
914 if let Ok(header_name) = HeaderName::from_str(header_name) {
915 if let Ok(header_value) =
916 HeaderValue::from_str(&replace_header_placeholders(header_value, &parts, None))
917 {
918 headers_to_replace.insert(header_name, header_value);
919 }
920 }
921 }
922 }
923 }
924 }
925 if let Some(custom_headers_to_remove) = get_entries!("header_remove", configuration) {
926 for custom_header in custom_headers_to_remove.inner.iter().rev() {
927 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
928 if let Ok(header_name) = HeaderName::from_str(header_name) {
929 headers_to_remove.push(header_name);
930 }
931 }
932 }
933 }
934
935 return Ok(
936 finalize_response_and_log(
937 response,
938 http3_alt_port,
939 headers_to_add,
940 headers_to_replace,
941 headers_to_remove,
942 &logger,
943 &log_request_parts,
944 &socket_data,
945 None,
946 log_date_format,
947 log_format,
948 )
949 .await,
950 );
951 }
952 },
953 );
954 parts.uri = match hyper::Uri::from_parts(url_parts) {
955 Ok(uri) => uri,
956 Err(err) => {
957 if error_log_enabled {
958 if let Some(logger) = &logger {
959 logger
960 .send(LogMessage::new(format!("URL sanitation error: {err}"), true))
961 .await
962 .unwrap_or_default();
963 }
964 }
965 let response = generate_error_response(StatusCode::BAD_REQUEST, &configuration, &None).await;
966
967 parts.uri = orig_uri;
968
969 let mut headers_to_add = HeaderMap::new();
971 let mut headers_to_replace = HeaderMap::new();
972 let mut headers_to_remove = Vec::new();
973 if let Some(custom_headers) = get_entries!("header", configuration) {
974 for custom_header in custom_headers.inner.iter().rev() {
975 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
976 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
977 if !headers_to_add.contains_key(header_name) {
978 if let Ok(header_name) = HeaderName::from_str(header_name) {
979 if let Ok(header_value) =
980 HeaderValue::from_str(&replace_header_placeholders(header_value, &parts, None))
981 {
982 headers_to_add.insert(header_name, header_value);
983 }
984 }
985 }
986 }
987 }
988 }
989 }
990 if let Some(custom_headers) = get_entries!("header_replace", configuration) {
991 for custom_header in custom_headers.inner.iter().rev() {
992 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
993 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
994 if let Ok(header_name) = HeaderName::from_str(header_name) {
995 if let Ok(header_value) =
996 HeaderValue::from_str(&replace_header_placeholders(header_value, &parts, None))
997 {
998 headers_to_replace.insert(header_name, header_value);
999 }
1000 }
1001 }
1002 }
1003 }
1004 }
1005 if let Some(custom_headers_to_remove) = get_entries!("header_remove", configuration) {
1006 for custom_header in custom_headers_to_remove.inner.iter().rev() {
1007 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1008 if let Ok(header_name) = HeaderName::from_str(header_name) {
1009 headers_to_remove.push(header_name);
1010 }
1011 }
1012 }
1013 }
1014
1015 return Ok(
1016 finalize_response_and_log(
1017 response,
1018 http3_alt_port,
1019 headers_to_add,
1020 headers_to_replace,
1021 headers_to_remove,
1022 &logger,
1023 &log_request_parts,
1024 &socket_data,
1025 None,
1026 log_date_format,
1027 log_format,
1028 )
1029 .await,
1030 );
1031 }
1032 };
1033 let configuration_option = configurations.find_configuration(&parts, hostname_determinant.as_deref(), &socket_data);
1034 request = Request::from_parts(parts, body);
1035 match configuration_option {
1036 Ok(Some(new_configuration)) => {
1037 configuration = new_configuration;
1038 log_date_format = get_value!("log_date_format", configuration).and_then(|v| v.as_str());
1039 log_format = get_value!("log_format", configuration).and_then(|v| v.as_str());
1040 }
1041 Ok(None) => {}
1042 Err(err) => {
1043 if error_log_enabled {
1044 if let Some(logger) = &logger {
1045 logger
1046 .send(LogMessage::new(
1047 format!("Cannot determine server configuration: {err}"),
1048 true,
1049 ))
1050 .await
1051 .unwrap_or_default();
1052 }
1053 }
1054 let response = generate_error_response(StatusCode::BAD_REQUEST, &configuration, &None).await;
1055
1056 let mut headers_to_add = HeaderMap::new();
1058 let mut headers_to_replace = HeaderMap::new();
1059 let mut headers_to_remove = Vec::new();
1060 let (request_parts, _) = request.into_parts();
1061 if let Some(custom_headers) = get_entries!("header", configuration) {
1062 for custom_header in custom_headers.inner.iter().rev() {
1063 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1064 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
1065 if !headers_to_add.contains_key(header_name) {
1066 if let Ok(header_name) = HeaderName::from_str(header_name) {
1067 if let Ok(header_value) =
1068 HeaderValue::from_str(&replace_header_placeholders(header_value, &request_parts, None))
1069 {
1070 headers_to_add.insert(header_name, header_value);
1071 }
1072 }
1073 }
1074 }
1075 }
1076 }
1077 }
1078 if let Some(custom_headers) = get_entries!("header_replace", configuration) {
1079 for custom_header in custom_headers.inner.iter().rev() {
1080 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1081 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
1082 if let Ok(header_name) = HeaderName::from_str(header_name) {
1083 if let Ok(header_value) =
1084 HeaderValue::from_str(&replace_header_placeholders(header_value, &request_parts, None))
1085 {
1086 headers_to_replace.insert(header_name, header_value);
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093 if let Some(custom_headers_to_remove) = get_entries!("header_remove", configuration) {
1094 for custom_header in custom_headers_to_remove.inner.iter().rev() {
1095 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1096 if let Ok(header_name) = HeaderName::from_str(header_name) {
1097 headers_to_remove.push(header_name);
1098 }
1099 }
1100 }
1101 }
1102
1103 return Ok(
1104 finalize_response_and_log(
1105 response,
1106 http3_alt_port,
1107 headers_to_add,
1108 headers_to_replace,
1109 headers_to_remove,
1110 &logger,
1111 &log_request_parts,
1112 &socket_data,
1113 None,
1114 log_date_format,
1115 log_format,
1116 )
1117 .await,
1118 );
1119 }
1120 }
1121 }
1122
1123 let mut headers_to_add = HeaderMap::new();
1125 let mut headers_to_replace = HeaderMap::new();
1126 let mut headers_to_remove = Vec::new();
1127 let (request_parts, request_body) = request.into_parts();
1128 if let Some(custom_headers) = get_entries!("header", configuration) {
1129 for custom_header in custom_headers.inner.iter().rev() {
1130 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1131 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
1132 if !headers_to_add.contains_key(header_name) {
1133 if let Ok(header_name) = HeaderName::from_str(header_name) {
1134 if let Ok(header_value) =
1135 HeaderValue::from_str(&replace_header_placeholders(header_value, &request_parts, None))
1136 {
1137 headers_to_add.insert(header_name, header_value);
1138 }
1139 }
1140 }
1141 }
1142 }
1143 }
1144 }
1145 if let Some(custom_headers) = get_entries!("header_replace", configuration) {
1146 for custom_header in custom_headers.inner.iter().rev() {
1147 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1148 if let Some(header_value) = custom_header.values.get(1).and_then(|v| v.as_str()) {
1149 if let Ok(header_name) = HeaderName::from_str(header_name) {
1150 if let Ok(header_value) =
1151 HeaderValue::from_str(&replace_header_placeholders(header_value, &request_parts, None))
1152 {
1153 headers_to_replace.insert(header_name, header_value);
1154 }
1155 }
1156 }
1157 }
1158 }
1159 }
1160 if let Some(custom_headers_to_remove) = get_entries!("header_remove", configuration) {
1161 for custom_header in custom_headers_to_remove.inner.iter().rev() {
1162 if let Some(header_name) = custom_header.values.first().and_then(|v| v.as_str()) {
1163 if let Ok(header_name) = HeaderName::from_str(header_name) {
1164 headers_to_remove.push(header_name);
1165 }
1166 }
1167 }
1168 }
1169 let mut request = Request::from_parts(request_parts, request_body);
1170
1171 if request.uri().path() == "*" {
1172 let response = match request.method() {
1173 &Method::OPTIONS => Response::builder()
1174 .status(StatusCode::NO_CONTENT)
1175 .header(header::ALLOW, "GET, POST, HEAD, OPTIONS")
1176 .body(Empty::new().map_err(|e| match e {}).boxed())
1177 .unwrap_or_default(),
1178 _ => {
1179 let mut header_map = HeaderMap::new();
1180 if let Ok(header_value) = HeaderValue::from_str("GET, POST, HEAD, OPTIONS") {
1181 header_map.insert(header::ALLOW, header_value);
1182 };
1183 generate_error_response(StatusCode::BAD_REQUEST, &configuration, &Some(header_map)).await
1184 }
1185 };
1186 return Ok(
1187 finalize_response_and_log(
1188 response,
1189 http3_alt_port,
1190 headers_to_add,
1191 headers_to_replace,
1192 headers_to_remove,
1193 &logger,
1194 &log_request_parts,
1195 &socket_data,
1196 None,
1197 log_date_format,
1198 log_format,
1199 )
1200 .await,
1201 );
1202 }
1203
1204 let acme_http_01_resolvers_inner = acme_http_01_resolvers.read().await;
1206 if !acme_http_01_resolvers_inner.is_empty() {
1207 if let Some(challenge_token) = request.uri().path().strip_prefix("/.well-known/acme-challenge/") {
1208 for acme_http01_resolver in &*acme_http_01_resolvers_inner {
1209 if let Some(http01_acme_data) = &*acme_http01_resolver.read().await {
1210 let acme_response = http01_acme_data.1.clone();
1211 if challenge_token == http01_acme_data.0 {
1212 let response = Response::builder()
1213 .status(StatusCode::OK)
1214 .header(
1215 header::CONTENT_TYPE,
1216 HeaderValue::from_static("application/octet-stream"),
1217 )
1218 .body(Full::new(Bytes::from(acme_response)).map_err(|e| match e {}).boxed())
1219 .unwrap_or_default();
1220
1221 return Ok(
1222 finalize_response_and_log(
1223 response,
1224 http3_alt_port,
1225 headers_to_add,
1226 headers_to_replace,
1227 headers_to_remove,
1228 &logger,
1229 &log_request_parts,
1230 &socket_data,
1231 None,
1232 log_date_format,
1233 log_format,
1234 )
1235 .await,
1236 );
1237 }
1238 }
1239 }
1240 }
1241 };
1242 drop(acme_http_01_resolvers_inner);
1243
1244 let cloned_logger = logger.clone();
1246 let error_logger = match (cloned_logger, error_log_enabled) {
1247 (Some(cloned_logger), true) => ErrorLogger::new(cloned_logger),
1248 _ => ErrorLogger::without_logger(),
1249 };
1250
1251 let mut module_handlers = Vec::new();
1253 for module in &configuration.modules {
1254 module_handlers.push(module.get_module_handlers());
1255 }
1256
1257 request.extensions_mut().insert(RequestData {
1259 auth_user: None,
1260 original_url: None,
1261 error_status_code: None,
1262 });
1263 let mut executed_handlers = Vec::new();
1264 let (request_parts, request_body) = request.into_parts();
1265 let request_parts_cloned = if configurations.inner.iter().rev().any(|c| {
1266 c.filters.is_host
1267 && c.filters.hostname == configuration.filters.hostname
1268 && c.filters.ip == configuration.filters.ip
1269 && c.filters.port == configuration.filters.port
1270 && (c.filters.condition.is_none() || c.filters.condition == configuration.filters.condition)
1271 && c.filters.error_handler_status.is_some()
1272 }) {
1273 let mut request_parts_cloned = request_parts.clone();
1274 request_parts_cloned
1275 .headers
1276 .insert(header::CONTENT_LENGTH, HeaderValue::from_static("0"));
1277 Some(request_parts_cloned)
1278 } else {
1279 None
1281 };
1282 let mut request = Request::from_parts(request_parts, request_body);
1283 let mut latest_auth_data = None;
1284 let mut is_error_handler = false;
1285 let mut handlers_iter: Box<dyn Iterator<Item = Box<dyn ModuleHandlers>>> = Box::new(module_handlers.into_iter());
1286 while let Some(mut handlers) = handlers_iter.next() {
1287 let response_result = handlers
1288 .request_handler(request, &configuration, &socket_data, &error_logger)
1289 .await;
1290
1291 executed_handlers.push(handlers);
1292 match response_result {
1293 Ok(response) => {
1294 let status = response.response_status;
1295 let headers = response.response_headers;
1296 let new_remote_address = response.new_remote_address;
1297 let request_option = response.request;
1298 let response = response.response;
1299 let request_extensions = request_option
1300 .as_ref()
1301 .and_then(|r| r.extensions().get::<RequestData>());
1302 if let Some(request_extensions) = request_extensions {
1303 latest_auth_data = request_extensions.auth_user.clone();
1304 }
1305 if let Some(new_remote_address) = new_remote_address {
1306 socket_data.remote_addr = new_remote_address;
1307 };
1308
1309 match response {
1310 Some(response) => {
1311 let (mut response_parts, response_body) = response.into_parts();
1312 add_custom_headers(
1313 &mut response_parts,
1314 &headers_to_add,
1315 &headers_to_replace,
1316 &headers_to_remove,
1317 );
1318 add_http3_alt_svc_header(&mut response_parts, http3_alt_port);
1319 add_server_header(&mut response_parts);
1320
1321 let response = Response::from_parts(response_parts, response_body);
1322
1323 match execute_response_modifying_handlers(
1324 response,
1325 executed_handlers,
1326 &configuration,
1327 http3_alt_port,
1328 headers_to_add,
1329 headers_to_replace,
1330 headers_to_remove,
1331 &logger,
1332 error_log_enabled,
1333 &log_request_parts,
1334 &socket_data,
1335 latest_auth_data.as_deref(),
1336 log_date_format,
1337 log_format,
1338 )
1339 .await
1340 {
1341 Ok(response) => {
1342 if log_enabled {
1343 if let Some(request_parts) = log_request_parts {
1344 if let Some(logger) = loggers.find_global_logger() {
1345 log_access(
1346 &logger,
1347 &request_parts,
1348 &socket_data,
1349 latest_auth_data.as_deref(),
1350 response.status().as_u16(),
1351 extract_content_length(&response),
1352 log_date_format,
1353 log_format,
1354 )
1355 .await;
1356 }
1357 }
1358 }
1359 return Ok(response);
1360 }
1361 Err(error_response) => {
1362 return Ok(error_response);
1363 }
1364 }
1365 }
1366 None => match status {
1367 Some(status) => {
1368 if !is_error_handler {
1369 if let Some(error_configuration) =
1370 configurations.find_error_configuration(&configuration.filters, status.as_u16())
1371 {
1372 let request_option = if let Some(request) = request_option {
1373 Some(request)
1374 } else {
1375 request_parts_cloned.clone().map(|request_parts_cloned| {
1376 Request::from_parts(request_parts_cloned, Empty::new().map_err(|e| match e {}).boxed())
1377 })
1378 };
1379 if let Some(request_cloned) = request_option {
1380 configuration = error_configuration;
1381 handlers_iter = Box::new(executed_handlers.into_iter().chain(handlers_iter));
1382 executed_handlers = Vec::new();
1383 request = request_cloned;
1384 if let Some(request_data) = request.extensions_mut().get_mut::<RequestData>() {
1385 request_data.error_status_code = Some(status);
1386 }
1387 is_error_handler = true;
1388 log_date_format = get_value!("log_date_format", configuration).and_then(|v| v.as_str());
1389 log_format = get_value!("log_format", configuration).and_then(|v| v.as_str());
1390 continue;
1391 }
1392 }
1393 }
1394 let response = generate_error_response(status, &configuration, &headers).await;
1395
1396 let (mut response_parts, response_body) = response.into_parts();
1397 add_custom_headers(
1398 &mut response_parts,
1399 &headers_to_add,
1400 &headers_to_replace,
1401 &headers_to_remove,
1402 );
1403 add_http3_alt_svc_header(&mut response_parts, http3_alt_port);
1404 add_server_header(&mut response_parts);
1405
1406 let response = Response::from_parts(response_parts, response_body);
1407
1408 match execute_response_modifying_handlers(
1409 response,
1410 executed_handlers,
1411 &configuration,
1412 http3_alt_port,
1413 headers_to_add,
1414 headers_to_replace,
1415 headers_to_remove,
1416 &logger,
1417 error_log_enabled,
1418 &log_request_parts,
1419 &socket_data,
1420 latest_auth_data.as_deref(),
1421 log_date_format,
1422 log_format,
1423 )
1424 .await
1425 {
1426 Ok(response) => {
1427 if log_enabled {
1428 if let Some(request_parts) = log_request_parts {
1429 if let Some(logger) = loggers.find_global_logger() {
1430 log_access(
1431 &logger,
1432 &request_parts,
1433 &socket_data,
1434 latest_auth_data.as_deref(),
1435 response.status().as_u16(),
1436 extract_content_length(&response),
1437 log_date_format,
1438 log_format,
1439 )
1440 .await;
1441 }
1442 }
1443 }
1444 return Ok(response);
1445 }
1446 Err(error_response) => {
1447 return Ok(error_response);
1448 }
1449 }
1450 }
1451 None => match request_option {
1452 Some(request_obtained) => {
1453 request = request_obtained;
1454 continue;
1455 }
1456 None => {
1457 break;
1458 }
1459 },
1460 },
1461 }
1462 }
1463 Err(err) => {
1464 let response = generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &configuration, &None).await;
1465
1466 if error_log_enabled {
1467 if let Some(logger) = &logger {
1468 logger
1469 .send(LogMessage::new(
1470 format!("Unexpected error while serving a request: {err}"),
1471 true,
1472 ))
1473 .await
1474 .unwrap_or_default();
1475 }
1476 }
1477
1478 let (mut response_parts, response_body) = response.into_parts();
1479 add_custom_headers(
1480 &mut response_parts,
1481 &headers_to_add,
1482 &headers_to_replace,
1483 &headers_to_remove,
1484 );
1485 add_http3_alt_svc_header(&mut response_parts, http3_alt_port);
1486 add_server_header(&mut response_parts);
1487
1488 let response = Response::from_parts(response_parts, response_body);
1489
1490 match execute_response_modifying_handlers(
1491 response,
1492 executed_handlers,
1493 &configuration,
1494 http3_alt_port,
1495 headers_to_add,
1496 headers_to_replace,
1497 headers_to_remove,
1498 &logger,
1499 error_log_enabled,
1500 &log_request_parts,
1501 &socket_data,
1502 latest_auth_data.as_deref(),
1503 log_date_format,
1504 log_format,
1505 )
1506 .await
1507 {
1508 Ok(response) => {
1509 if log_enabled {
1510 if let Some(request_parts) = log_request_parts {
1511 if let Some(logger) = loggers.find_global_logger() {
1512 log_access(
1513 &logger,
1514 &request_parts,
1515 &socket_data,
1516 latest_auth_data.as_deref(),
1517 response.status().as_u16(),
1518 extract_content_length(&response),
1519 log_date_format,
1520 log_format,
1521 )
1522 .await;
1523 }
1524 }
1525 }
1526 return Ok(response);
1527 }
1528 Err(error_response) => {
1529 return Ok(error_response);
1530 }
1531 }
1532 }
1533 }
1534 }
1535
1536 let response = generate_error_response(StatusCode::NOT_FOUND, &configuration, &None).await;
1537
1538 let (mut response_parts, response_body) = response.into_parts();
1539 add_custom_headers(
1540 &mut response_parts,
1541 &headers_to_add,
1542 &headers_to_replace,
1543 &headers_to_remove,
1544 );
1545 add_http3_alt_svc_header(&mut response_parts, http3_alt_port);
1546 add_server_header(&mut response_parts);
1547
1548 let response = Response::from_parts(response_parts, response_body);
1549
1550 match execute_response_modifying_handlers(
1551 response,
1552 executed_handlers,
1553 &configuration,
1554 http3_alt_port,
1555 headers_to_add,
1556 headers_to_replace,
1557 headers_to_remove,
1558 &logger,
1559 error_log_enabled,
1560 &log_request_parts,
1561 &socket_data,
1562 latest_auth_data.as_deref(),
1563 log_date_format,
1564 log_format,
1565 )
1566 .await
1567 {
1568 Ok(response) => {
1569 if log_enabled {
1570 if let Some(request_parts) = log_request_parts {
1571 if let Some(logger) = &logger {
1572 log_access(
1573 logger,
1574 &request_parts,
1575 &socket_data,
1576 latest_auth_data.as_deref(),
1577 response.status().as_u16(),
1578 extract_content_length(&response),
1579 log_date_format,
1580 log_format,
1581 )
1582 .await;
1583 }
1584 }
1585 }
1586 Ok(response)
1587 }
1588 Err(error_response) => Ok(error_response),
1589 }
1590}
1591
1592#[allow(clippy::too_many_arguments)]
1594pub async fn request_handler(
1595 request: Request<BoxBody<Bytes, std::io::Error>>,
1596 client_address: SocketAddr,
1597 server_address: SocketAddr,
1598 encrypted: bool,
1599 configurations: Arc<ServerConfigurations>,
1600 loggers: Loggers,
1601 http3_alt_port: Option<u16>,
1602 acme_http_01_resolvers: Arc<tokio::sync::RwLock<Vec<crate::acme::Http01DataLock>>>,
1603 proxy_protocol_client_address: Option<SocketAddr>,
1604 proxy_protocol_server_address: Option<SocketAddr>,
1605) -> Result<Response<BoxBody<Bytes, std::io::Error>>, anyhow::Error> {
1606 let global_configuration = configurations.find_global_configuration();
1607 let timeout_from_config = global_configuration
1608 .as_deref()
1609 .and_then(|c| get_entry!("timeout", c))
1610 .and_then(|e| e.values.last());
1611 let request_handler_future = request_handler_wrapped(
1612 request,
1613 client_address,
1614 server_address,
1615 encrypted,
1616 configurations,
1617 loggers,
1618 http3_alt_port,
1619 acme_http_01_resolvers,
1620 proxy_protocol_client_address,
1621 proxy_protocol_server_address,
1622 );
1623 if timeout_from_config.is_some_and(|v| v.is_null()) {
1624 request_handler_future.await.map_err(|e| anyhow::anyhow!(e))
1625 } else {
1626 let timeout_millis = timeout_from_config.and_then(|v| v.as_i128()).unwrap_or(300000) as u64;
1627 match timeout(Duration::from_millis(timeout_millis), request_handler_future).await {
1628 Ok(response) => response.map_err(|e| anyhow::anyhow!(e)),
1629 Err(_) => Err(anyhow::anyhow!("The client or server has timed out")),
1630 }
1631 }
1632}