ferron/
request_handler.rs

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
33/// Generates an error response
34async 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          // Monoio's `File` doesn't expose `metadata()` on Windows, so we have to spawn a blocking task to obtain the metadata on this platform
71          #[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/// Sends a log message formatted according to the Combined Log Format
124#[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
157/// Helper function to add custom headers to response
158fn 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
181/// Helper function to add HTTP/3 Alt-Svc header
182fn 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
202/// Helper function to add server header
203fn 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
209/// Helper function to extract content length for logging
210fn 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/// Helper function to apply all response headers and log if needed
224#[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/// Helper function to execute response modifying handlers
271#[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/// The HTTP request handler
330#[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  // Global configuration
344  let global_configuration = configurations.find_global_configuration();
345
346  // Check if logging is enabled
347  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  // Normalize HTTP/2 and HTTP/3 request objects
357  match request.version() {
358    hyper::Version::HTTP_2 | hyper::Version::HTTP_3 => {
359      // Set "Host" request header for HTTP/2 and HTTP/3 connections
360      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      // Normalize the Cookie header for HTTP/2 and HTTP/3
371      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  // Construct socket data
393  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  // Sanitize "Host" header
400  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  // Find the server configuration
590  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  // Determine the log formats
757  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  // Determine the logger
761  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  // Sanitize the URL
770  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      // Determine headers to add/remove/replace
790      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          // Determine headers to add/remove/replace
890          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        // Determine headers to add/remove/replace
970        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        // Determine headers to add/remove/replace
1057        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  // Determine headers to add/remove/replace
1124  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  // HTTP-01 ACME challenge for automatic TLS
1205  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  // Create an error logger
1245  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  // Obtain module handlers
1252  let mut module_handlers = Vec::new();
1253  for module in &configuration.modules {
1254    module_handlers.push(module.get_module_handlers());
1255  }
1256
1257  // Execute modules!
1258  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    // If the error configuration is not specified, don't clone the request parts to improve performance
1280    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/// The HTTP request handler, with timeout
1593#[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}