ferron/
request_handler.rs

1use std::convert::Infallible;
2use std::net::{IpAddr, SocketAddr};
3use std::str::FromStr;
4use std::sync::Arc;
5use std::time::Duration;
6
7use crate::ferron_res::server_software::SERVER_SOFTWARE;
8use crate::ferron_util::combine_config::combine_config;
9use crate::ferron_util::error_pages::generate_default_error_page;
10use crate::ferron_util::url_sanitizer::sanitize_url;
11
12use crate::ferron_common::{
13  ErrorLogger, LogMessage, RequestData, ServerModuleHandlers, SocketData,
14};
15use async_channel::Sender;
16use chrono::prelude::*;
17use futures_util::TryStreamExt;
18use http::header::CONTENT_TYPE;
19use http_body_util::combinators::BoxBody;
20use http_body_util::{BodyExt, Empty, Full, StreamBody};
21use hyper::body::{Body, Bytes, Frame};
22use hyper::header::{self, HeaderName, HeaderValue};
23use hyper::{HeaderMap, Method, Request, Response, StatusCode};
24use hyper_tungstenite::is_upgrade_request;
25use rustls_acme::ResolvesServerCertAcme;
26use tokio::fs;
27use tokio::io::BufReader;
28use tokio::time::timeout;
29use tokio_util::io::ReaderStream;
30use yaml_rust2::Yaml;
31
32async fn generate_error_response(
33  status_code: StatusCode,
34  config: &Yaml,
35  headers: &Option<HeaderMap>,
36) -> Response<BoxBody<Bytes, std::io::Error>> {
37  let bare_body =
38    generate_default_error_page(status_code, config["serverAdministratorEmail"].as_str());
39  let mut content_length: Option<u64> = bare_body.len().try_into().ok();
40  let mut response_body = Full::new(Bytes::from(bare_body))
41    .map_err(|e| match e {})
42    .boxed();
43
44  if let Some(error_pages) = config["errorPages"].as_vec() {
45    for error_page_yaml in error_pages {
46      if let Some(page_status_code) = error_page_yaml["scode"].as_i64() {
47        let page_status_code = match StatusCode::from_u16(match page_status_code.try_into() {
48          Ok(status_code) => status_code,
49          Err(_) => continue,
50        }) {
51          Ok(status_code) => status_code,
52          Err(_) => continue,
53        };
54        if status_code != page_status_code {
55          continue;
56        }
57        if let Some(page_path) = error_page_yaml["path"].as_str() {
58          let file = fs::File::open(page_path).await;
59
60          let file = match file {
61            Ok(file) => file,
62            Err(_) => continue,
63          };
64
65          content_length = match file.metadata().await {
66            Ok(metadata) => Some(metadata.len()),
67            Err(_) => None,
68          };
69
70          // Use BufReader for better performance.
71          let reader_stream = ReaderStream::new(BufReader::with_capacity(12800, file));
72
73          let stream_body = StreamBody::new(reader_stream.map_ok(Frame::data));
74          let boxed_body = stream_body.boxed();
75
76          response_body = boxed_body;
77
78          break;
79        }
80      }
81    }
82  }
83
84  let mut response_builder = Response::builder().status(status_code);
85
86  if let Some(headers) = headers {
87    let headers_iter = headers.iter();
88    for (name, value) in headers_iter {
89      if name != header::CONTENT_TYPE && name != header::CONTENT_LENGTH {
90        response_builder = response_builder.header(name, value);
91      }
92    }
93  }
94
95  if let Some(content_length) = content_length {
96    response_builder = response_builder.header(header::CONTENT_LENGTH, content_length);
97  }
98  response_builder = response_builder.header(header::CONTENT_TYPE, "text/html");
99
100  response_builder.body(response_body).unwrap_or_default()
101}
102
103#[allow(clippy::too_many_arguments)]
104async fn log_combined(
105  logger: &Sender<LogMessage>,
106  client_ip: IpAddr,
107  auth_user: Option<String>,
108  method: String,
109  request_path: String,
110  protocol: String,
111  status_code: u16,
112  content_length: Option<u64>,
113  referrer: Option<String>,
114  user_agent: Option<String>,
115) {
116  let now: DateTime<Local> = Local::now();
117  let formatted_time = now.format("%d/%b/%Y:%H:%M:%S %z").to_string();
118  logger
119    .send(LogMessage::new(
120      format!(
121        "{} - {} [{}] \"{} {} {}\" {} {} {} {}",
122        client_ip,
123        match auth_user {
124          Some(auth_user) => auth_user,
125          None => String::from("-"),
126        },
127        formatted_time,
128        method,
129        request_path,
130        protocol,
131        status_code,
132        match content_length {
133          Some(content_length) => format!("{}", content_length),
134          None => String::from("-"),
135        },
136        match referrer {
137          Some(referrer) => format!(
138            "\"{}\"",
139            referrer.replace("\\", "\\\\").replace("\"", "\\\"")
140          ),
141          None => String::from("-"),
142        },
143        match user_agent {
144          Some(user_agent) => format!(
145            "\"{}\"",
146            user_agent.replace("\\", "\\\\").replace("\"", "\\\"")
147          ),
148          None => String::from("-"),
149        },
150      ),
151      false,
152    ))
153    .await
154    .unwrap_or_default();
155}
156
157#[allow(clippy::too_many_arguments)]
158async fn request_handler_wrapped(
159  mut request: Request<BoxBody<Bytes, std::io::Error>>,
160  remote_address: SocketAddr,
161  local_address: SocketAddr,
162  encrypted: bool,
163  config: Arc<Yaml>,
164  logger: Sender<LogMessage>,
165  handlers_vec: Vec<Box<dyn ServerModuleHandlers + Send>>,
166  acme_http01_resolver_option: Option<Arc<ResolvesServerCertAcme>>,
167  http3_alt_port: Option<u16>,
168) -> Result<Response<BoxBody<Bytes, std::io::Error>>, Infallible> {
169  let is_proxy_request = match request.version() {
170    hyper::Version::HTTP_2 | hyper::Version::HTTP_3 => {
171      request.method() == hyper::Method::CONNECT && request.uri().host().is_some()
172    }
173    _ => request.uri().host().is_some(),
174  };
175  let is_connect_proxy_request = request.method() == hyper::Method::CONNECT;
176
177  // Collect request data for logging
178  let log_method = String::from(request.method().as_str());
179  let log_request_path = match is_proxy_request {
180    true => request.uri().to_string(),
181    false => format!(
182      "{}{}",
183      request.uri().path(),
184      match request.uri().query() {
185        Some(query) => format!("?{}", query),
186        None => String::from(""),
187      }
188    ),
189  };
190  let log_protocol = String::from(match request.version() {
191    hyper::Version::HTTP_09 => "HTTP/0.9",
192    hyper::Version::HTTP_10 => "HTTP/1.0",
193    hyper::Version::HTTP_11 => "HTTP/1.1",
194    hyper::Version::HTTP_2 => "HTTP/2.0",
195    hyper::Version::HTTP_3 => "HTTP/3.0",
196    _ => "HTTP/Unknown",
197  });
198  let log_referrer = match request.headers().get(header::REFERER) {
199    Some(header_value) => match header_value.to_str() {
200      Ok(header_value) => Some(String::from(header_value)),
201      Err(_) => None,
202    },
203    None => None,
204  };
205  let log_user_agent = match request.headers().get(header::USER_AGENT) {
206    Some(header_value) => match header_value.to_str() {
207      Ok(header_value) => Some(String::from(header_value)),
208      Err(_) => None,
209    },
210    None => None,
211  };
212  let log_enabled = config["global"]["logFilePath"].as_str().is_some();
213  let error_log_enabled = config["global"]["errorLogFilePath"].as_str().is_some();
214
215  // Construct SocketData
216  let mut socket_data = SocketData::new(remote_address, local_address, encrypted);
217
218  match request.version() {
219    hyper::Version::HTTP_2 | hyper::Version::HTTP_3 => {
220      // Set "Host" request header for HTTP/2 and HTTP/3 connections
221      if let Some(authority) = request.uri().authority() {
222        let authority = authority.to_owned();
223        let headers = request.headers_mut();
224        if !headers.contains_key(header::HOST) {
225          if let Ok(authority_value) = HeaderValue::from_bytes(authority.as_str().as_bytes()) {
226            headers.append(header::HOST, authority_value);
227          }
228        }
229      }
230
231      // Normalize the Cookie header for HTTP/2 and HTTP/3
232      let mut cookie_normalized = String::new();
233      let mut cookie_set = false;
234      let headers = request.headers_mut();
235      for cookie in headers.get_all(header::COOKIE) {
236        if let Ok(cookie) = cookie.to_str() {
237          if cookie_set {
238            cookie_normalized.push_str("; ");
239          }
240          cookie_set = true;
241          cookie_normalized.push_str(cookie);
242        }
243      }
244      if cookie_set {
245        if let Ok(cookie_value) = HeaderValue::from_bytes(cookie_normalized.as_bytes()) {
246          headers.insert(header::COOKIE, cookie_value);
247        }
248      }
249    }
250    _ => (),
251  }
252
253  let host_header_option = request.headers().get(header::HOST);
254  if let Some(header_data) = host_header_option {
255    match header_data.to_str() {
256      Ok(host_header) => {
257        let host_header_lower_case = host_header.to_lowercase();
258        if host_header_lower_case != *host_header {
259          let host_header_value = match HeaderValue::from_str(&host_header_lower_case) {
260            Ok(host_header_value) => host_header_value,
261            Err(err) => {
262              if error_log_enabled {
263                logger
264                  .send(LogMessage::new(
265                    format!("Host header sanitation error: {}", err),
266                    true,
267                  ))
268                  .await
269                  .unwrap_or_default();
270              }
271              let response = Response::builder()
272                .status(StatusCode::BAD_REQUEST)
273                .header(header::CONTENT_TYPE, "text/html")
274                .body(
275                  Full::new(Bytes::from(generate_default_error_page(
276                    StatusCode::BAD_REQUEST,
277                    None,
278                  )))
279                  .map_err(|e| match e {})
280                  .boxed(),
281                )
282                .unwrap_or_default();
283
284              if log_enabled {
285                log_combined(
286                  &logger,
287                  socket_data.remote_addr.ip(),
288                  None,
289                  log_method,
290                  log_request_path,
291                  log_protocol,
292                  response.status().as_u16(),
293                  match response.headers().get(header::CONTENT_LENGTH) {
294                    Some(header_value) => match header_value.to_str() {
295                      Ok(header_value) => match header_value.parse::<u64>() {
296                        Ok(content_length) => Some(content_length),
297                        Err(_) => response.body().size_hint().exact(),
298                      },
299                      Err(_) => response.body().size_hint().exact(),
300                    },
301                    None => response.body().size_hint().exact(),
302                  },
303                  log_referrer,
304                  log_user_agent,
305                )
306                .await;
307              }
308              let (mut response_parts, response_body) = response.into_parts();
309              if let Some(http3_alt_port) = http3_alt_port {
310                if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
311                  Some(value) => HeaderValue::from_bytes(
312                    format!(
313                      "{}, h3=\":{}\", h3-29=\":{}\"",
314                      String::from_utf8_lossy(value.as_bytes()),
315                      http3_alt_port,
316                      http3_alt_port
317                    )
318                    .as_bytes(),
319                  ),
320                  None => HeaderValue::from_bytes(
321                    format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
322                  ),
323                } {
324                  response_parts.headers.insert(header::ALT_SVC, header_value);
325                }
326              }
327              response_parts
328                .headers
329                .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
330
331              return Ok(Response::from_parts(response_parts, response_body));
332            }
333          };
334
335          request
336            .headers_mut()
337            .insert(header::HOST, host_header_value);
338        }
339      }
340      Err(err) => {
341        if error_log_enabled {
342          logger
343            .send(LogMessage::new(
344              format!("Host header sanitation error: {}", err),
345              true,
346            ))
347            .await
348            .unwrap_or_default();
349        }
350        let response = Response::builder()
351          .status(StatusCode::BAD_REQUEST)
352          .header(header::CONTENT_TYPE, "text/html")
353          .body(
354            Full::new(Bytes::from(generate_default_error_page(
355              StatusCode::BAD_REQUEST,
356              None,
357            )))
358            .map_err(|e| match e {})
359            .boxed(),
360          )
361          .unwrap_or_default();
362        if log_enabled {
363          log_combined(
364            &logger,
365            socket_data.remote_addr.ip(),
366            None,
367            log_method,
368            log_request_path,
369            log_protocol,
370            response.status().as_u16(),
371            match response.headers().get(header::CONTENT_LENGTH) {
372              Some(header_value) => match header_value.to_str() {
373                Ok(header_value) => match header_value.parse::<u64>() {
374                  Ok(content_length) => Some(content_length),
375                  Err(_) => response.body().size_hint().exact(),
376                },
377                Err(_) => response.body().size_hint().exact(),
378              },
379              None => response.body().size_hint().exact(),
380            },
381            log_referrer,
382            log_user_agent,
383          )
384          .await;
385        }
386        let (mut response_parts, response_body) = response.into_parts();
387        if let Some(http3_alt_port) = http3_alt_port {
388          if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
389            Some(value) => HeaderValue::from_bytes(
390              format!(
391                "{}, h3=\":{}\", h3-29=\":{}\"",
392                String::from_utf8_lossy(value.as_bytes()),
393                http3_alt_port,
394                http3_alt_port
395              )
396              .as_bytes(),
397            ),
398            None => HeaderValue::from_bytes(
399              format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
400            ),
401          } {
402            response_parts.headers.insert(header::ALT_SVC, header_value);
403          }
404        }
405        response_parts
406          .headers
407          .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
408
409        return Ok(Response::from_parts(response_parts, response_body));
410      }
411    }
412  };
413
414  // Combine the server configuration
415  let combined_config = match combine_config(
416    config,
417    match is_proxy_request || is_connect_proxy_request {
418      false => match request.headers().get(header::HOST) {
419        Some(value) => value.to_str().ok(),
420        None => None,
421      },
422      true => None,
423    },
424    local_address.ip(),
425    request.uri().path(),
426  ) {
427    Some(config) => config,
428    None => {
429      if error_log_enabled {
430        logger
431          .send(LogMessage::new(
432            String::from("Cannot determine server configuration"),
433            true,
434          ))
435          .await
436          .unwrap_or_default();
437      }
438      let response = Response::builder()
439        .status(StatusCode::INTERNAL_SERVER_ERROR)
440        .header(header::CONTENT_TYPE, "text/html")
441        .body(
442          Full::new(Bytes::from(generate_default_error_page(
443            StatusCode::INTERNAL_SERVER_ERROR,
444            None,
445          )))
446          .map_err(|e| match e {})
447          .boxed(),
448        )
449        .unwrap_or_default();
450      if log_enabled {
451        log_combined(
452          &logger,
453          socket_data.remote_addr.ip(),
454          None,
455          log_method,
456          log_request_path,
457          log_protocol,
458          response.status().as_u16(),
459          match response.headers().get(header::CONTENT_LENGTH) {
460            Some(header_value) => match header_value.to_str() {
461              Ok(header_value) => match header_value.parse::<u64>() {
462                Ok(content_length) => Some(content_length),
463                Err(_) => response.body().size_hint().exact(),
464              },
465              Err(_) => response.body().size_hint().exact(),
466            },
467            None => response.body().size_hint().exact(),
468          },
469          log_referrer,
470          log_user_agent,
471        )
472        .await;
473      }
474      let (mut response_parts, response_body) = response.into_parts();
475      if let Some(http3_alt_port) = http3_alt_port {
476        if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
477          Some(value) => HeaderValue::from_bytes(
478            format!(
479              "{}, h3=\":{}\", h3-29=\":{}\"",
480              String::from_utf8_lossy(value.as_bytes()),
481              http3_alt_port,
482              http3_alt_port
483            )
484            .as_bytes(),
485          ),
486          None => HeaderValue::from_bytes(
487            format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
488          ),
489        } {
490          response_parts.headers.insert(header::ALT_SVC, header_value);
491        }
492      }
493      response_parts
494        .headers
495        .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
496
497      return Ok(Response::from_parts(response_parts, response_body));
498    }
499  };
500
501  let url_pathname = request.uri().path();
502  let sanitized_url_pathname = match sanitize_url(
503    url_pathname,
504    combined_config["allowDoubleSlashes"]
505      .as_bool()
506      .unwrap_or_default(),
507  ) {
508    Ok(sanitized_url) => sanitized_url,
509    Err(err) => {
510      if error_log_enabled {
511        logger
512          .send(LogMessage::new(
513            format!("URL sanitation error: {}", err),
514            true,
515          ))
516          .await
517          .unwrap_or_default();
518      }
519      let response =
520        generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
521      if log_enabled {
522        log_combined(
523          &logger,
524          socket_data.remote_addr.ip(),
525          None,
526          log_method,
527          log_request_path,
528          log_protocol,
529          response.status().as_u16(),
530          match response.headers().get(header::CONTENT_LENGTH) {
531            Some(header_value) => match header_value.to_str() {
532              Ok(header_value) => match header_value.parse::<u64>() {
533                Ok(content_length) => Some(content_length),
534                Err(_) => response.body().size_hint().exact(),
535              },
536              Err(_) => response.body().size_hint().exact(),
537            },
538            None => response.body().size_hint().exact(),
539          },
540          log_referrer,
541          log_user_agent,
542        )
543        .await;
544      }
545      let (mut response_parts, response_body) = response.into_parts();
546      if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
547        let custom_headers_hash_iter = custom_headers_hash.iter();
548        for (header_name, header_value) in custom_headers_hash_iter {
549          if let Some(header_name) = header_name.as_str() {
550            if let Some(header_value) = header_value.as_str() {
551              if !response_parts.headers.contains_key(header_name) {
552                if let Ok(header_value) =
553                  HeaderValue::from_str(&header_value.replace("{path}", url_pathname))
554                {
555                  if let Ok(header_name) = HeaderName::from_str(header_name) {
556                    response_parts.headers.insert(header_name, header_value);
557                  }
558                }
559              }
560            }
561          }
562        }
563      }
564      if let Some(http3_alt_port) = http3_alt_port {
565        if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
566          Some(value) => HeaderValue::from_bytes(
567            format!(
568              "{}, h3=\":{}\", h3-29=\":{}\"",
569              String::from_utf8_lossy(value.as_bytes()),
570              http3_alt_port,
571              http3_alt_port
572            )
573            .as_bytes(),
574          ),
575          None => HeaderValue::from_bytes(
576            format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
577          ),
578        } {
579          response_parts.headers.insert(header::ALT_SVC, header_value);
580        }
581      }
582      response_parts
583        .headers
584        .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
585
586      return Ok(Response::from_parts(response_parts, response_body));
587    }
588  };
589
590  if sanitized_url_pathname != url_pathname {
591    let (mut parts, body) = request.into_parts();
592    let mut url_parts = parts.uri.into_parts();
593    url_parts.path_and_query = Some(
594      match format!(
595        "{}{}",
596        sanitized_url_pathname,
597        match url_parts.path_and_query {
598          Some(path_and_query) => {
599            match path_and_query.query() {
600              Some(query) => format!("?{}", query),
601              None => String::from(""),
602            }
603          }
604          None => String::from(""),
605        }
606      )
607      .parse()
608      {
609        Ok(path_and_query) => path_and_query,
610        Err(err) => {
611          if error_log_enabled {
612            logger
613              .send(LogMessage::new(
614                format!("URL sanitation error: {}", err),
615                true,
616              ))
617              .await
618              .unwrap_or_default();
619          }
620          let response =
621            generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
622          if log_enabled {
623            log_combined(
624              &logger,
625              socket_data.remote_addr.ip(),
626              None,
627              log_method,
628              log_request_path,
629              log_protocol,
630              response.status().as_u16(),
631              match response.headers().get(header::CONTENT_LENGTH) {
632                Some(header_value) => match header_value.to_str() {
633                  Ok(header_value) => match header_value.parse::<u64>() {
634                    Ok(content_length) => Some(content_length),
635                    Err(_) => response.body().size_hint().exact(),
636                  },
637                  Err(_) => response.body().size_hint().exact(),
638                },
639                None => response.body().size_hint().exact(),
640              },
641              log_referrer,
642              log_user_agent,
643            )
644            .await;
645          }
646          let (mut response_parts, response_body) = response.into_parts();
647          if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
648            let custom_headers_hash_iter = custom_headers_hash.iter();
649            for (header_name, header_value) in custom_headers_hash_iter {
650              if let Some(header_name) = header_name.as_str() {
651                if let Some(header_value) = header_value.as_str() {
652                  if !response_parts.headers.contains_key(header_name) {
653                    if let Ok(header_value) = HeaderValue::from_str(
654                      &header_value.replace("{path}", &sanitized_url_pathname),
655                    ) {
656                      if let Ok(header_name) = HeaderName::from_str(header_name) {
657                        response_parts.headers.insert(header_name, header_value);
658                      }
659                    }
660                  }
661                }
662              }
663            }
664          }
665          if let Some(http3_alt_port) = http3_alt_port {
666            if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
667              Some(value) => HeaderValue::from_bytes(
668                format!(
669                  "{}, h3=\":{}\", h3-29=\":{}\"",
670                  String::from_utf8_lossy(value.as_bytes()),
671                  http3_alt_port,
672                  http3_alt_port
673                )
674                .as_bytes(),
675              ),
676              None => HeaderValue::from_bytes(
677                format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
678              ),
679            } {
680              response_parts.headers.insert(header::ALT_SVC, header_value);
681            }
682          }
683          response_parts
684            .headers
685            .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
686
687          return Ok(Response::from_parts(response_parts, response_body));
688        }
689      },
690    );
691    parts.uri = match hyper::Uri::from_parts(url_parts) {
692      Ok(uri) => uri,
693      Err(err) => {
694        if error_log_enabled {
695          logger
696            .send(LogMessage::new(
697              format!("URL sanitation error: {}", err),
698              true,
699            ))
700            .await
701            .unwrap_or_default();
702        }
703        let response =
704          generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &None).await;
705        if log_enabled {
706          log_combined(
707            &logger,
708            socket_data.remote_addr.ip(),
709            None,
710            log_method,
711            log_request_path,
712            log_protocol,
713            response.status().as_u16(),
714            match response.headers().get(header::CONTENT_LENGTH) {
715              Some(header_value) => match header_value.to_str() {
716                Ok(header_value) => match header_value.parse::<u64>() {
717                  Ok(content_length) => Some(content_length),
718                  Err(_) => response.body().size_hint().exact(),
719                },
720                Err(_) => response.body().size_hint().exact(),
721              },
722              None => response.body().size_hint().exact(),
723            },
724            log_referrer,
725            log_user_agent,
726          )
727          .await;
728        }
729        let (mut response_parts, response_body) = response.into_parts();
730        if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
731          let custom_headers_hash_iter = custom_headers_hash.iter();
732          for (header_name, header_value) in custom_headers_hash_iter {
733            if let Some(header_name) = header_name.as_str() {
734              if let Some(header_value) = header_value.as_str() {
735                if !response_parts.headers.contains_key(header_name) {
736                  if let Ok(header_value) =
737                    HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
738                  {
739                    if let Ok(header_name) = HeaderName::from_str(header_name) {
740                      response_parts.headers.insert(header_name, header_value);
741                    }
742                  }
743                }
744              }
745            }
746          }
747        }
748        if let Some(http3_alt_port) = http3_alt_port {
749          if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
750            Some(value) => HeaderValue::from_bytes(
751              format!(
752                "{}, h3=\":{}\", h3-29=\":{}\"",
753                String::from_utf8_lossy(value.as_bytes()),
754                http3_alt_port,
755                http3_alt_port
756              )
757              .as_bytes(),
758            ),
759            None => HeaderValue::from_bytes(
760              format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
761            ),
762          } {
763            response_parts.headers.insert(header::ALT_SVC, header_value);
764          }
765        }
766        response_parts
767          .headers
768          .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
769
770        return Ok(Response::from_parts(response_parts, response_body));
771      }
772    };
773    request = Request::from_parts(parts, body);
774  }
775
776  if request.uri().path() == "*" {
777    let response = match request.method() {
778      &Method::OPTIONS => Response::builder()
779        .status(StatusCode::NO_CONTENT)
780        .header(header::ALLOW, "GET, POST, HEAD, OPTIONS")
781        .body(Empty::new().map_err(|e| match e {}).boxed())
782        .unwrap_or_default(),
783      _ => {
784        let mut header_map = HeaderMap::new();
785        if let Ok(header_value) = HeaderValue::from_str("GET, POST, HEAD, OPTIONS") {
786          header_map.insert(header::ALLOW, header_value);
787        };
788        generate_error_response(StatusCode::BAD_REQUEST, &combined_config, &Some(header_map)).await
789      }
790    };
791    if log_enabled {
792      log_combined(
793        &logger,
794        socket_data.remote_addr.ip(),
795        None,
796        log_method,
797        log_request_path,
798        log_protocol,
799        response.status().as_u16(),
800        match response.headers().get(header::CONTENT_LENGTH) {
801          Some(header_value) => match header_value.to_str() {
802            Ok(header_value) => match header_value.parse::<u64>() {
803              Ok(content_length) => Some(content_length),
804              Err(_) => response.body().size_hint().exact(),
805            },
806            Err(_) => response.body().size_hint().exact(),
807          },
808          None => response.body().size_hint().exact(),
809        },
810        log_referrer,
811        log_user_agent,
812      )
813      .await;
814    }
815    let (mut response_parts, response_body) = response.into_parts();
816    if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
817      let custom_headers_hash_iter = custom_headers_hash.iter();
818      for (header_name, header_value) in custom_headers_hash_iter {
819        if let Some(header_name) = header_name.as_str() {
820          if let Some(header_value) = header_value.as_str() {
821            if !response_parts.headers.contains_key(header_name) {
822              if let Ok(header_value) =
823                HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
824              {
825                if let Ok(header_name) = HeaderName::from_str(header_name) {
826                  response_parts.headers.insert(header_name, header_value);
827                }
828              }
829            }
830          }
831        }
832      }
833    }
834    if let Some(http3_alt_port) = http3_alt_port {
835      if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
836        Some(value) => HeaderValue::from_bytes(
837          format!(
838            "{}, h3=\":{}\", h3-29=\":{}\"",
839            String::from_utf8_lossy(value.as_bytes()),
840            http3_alt_port,
841            http3_alt_port
842          )
843          .as_bytes(),
844        ),
845        None => HeaderValue::from_bytes(
846          format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
847        ),
848      } {
849        response_parts.headers.insert(header::ALT_SVC, header_value);
850      }
851    }
852    response_parts
853      .headers
854      .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
855
856    return Ok(Response::from_parts(response_parts, response_body));
857  }
858
859  // HTTP-01 ACME challenge for automatic TLS
860  if let Some(acme_http01_resolver) = acme_http01_resolver_option {
861    if let Some(challenge_token) = request
862      .uri()
863      .path()
864      .strip_prefix("/.well-known/acme-challenge/")
865    {
866      if let Some(acme_response) = acme_http01_resolver.get_http_01_key_auth(challenge_token) {
867        let response = Response::builder()
868          .status(StatusCode::OK)
869          .header(
870            CONTENT_TYPE,
871            HeaderValue::from_static("application/octet-stream"),
872          )
873          .body(
874            Full::new(Bytes::from(acme_response))
875              .map_err(|e| match e {})
876              .boxed(),
877          )
878          .unwrap_or_default();
879
880        let (mut response_parts, response_body) = response.into_parts();
881        if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
882          let custom_headers_hash_iter = custom_headers_hash.iter();
883          for (header_name, header_value) in custom_headers_hash_iter {
884            if let Some(header_name) = header_name.as_str() {
885              if let Some(header_value) = header_value.as_str() {
886                if !response_parts.headers.contains_key(header_name) {
887                  if let Ok(header_value) =
888                    HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
889                  {
890                    if let Ok(header_name) = HeaderName::from_str(header_name) {
891                      response_parts.headers.insert(header_name, header_value);
892                    }
893                  }
894                }
895              }
896            }
897          }
898        }
899        if let Some(http3_alt_port) = http3_alt_port {
900          if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
901            Some(value) => HeaderValue::from_bytes(
902              format!(
903                "{}, h3=\":{}\", h3-29=\":{}\"",
904                String::from_utf8_lossy(value.as_bytes()),
905                http3_alt_port,
906                http3_alt_port
907              )
908              .as_bytes(),
909            ),
910            None => HeaderValue::from_bytes(
911              format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
912            ),
913          } {
914            response_parts.headers.insert(header::ALT_SVC, header_value);
915          }
916        }
917        response_parts
918          .headers
919          .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
920
921        let response = Response::from_parts(response_parts, response_body);
922
923        if log_enabled {
924          log_combined(
925            &logger,
926            socket_data.remote_addr.ip(),
927            None,
928            log_method,
929            log_request_path,
930            log_protocol,
931            response.status().as_u16(),
932            match response.headers().get(header::CONTENT_LENGTH) {
933              Some(header_value) => match header_value.to_str() {
934                Ok(header_value) => match header_value.parse::<u64>() {
935                  Ok(content_length) => Some(content_length),
936                  Err(_) => response.body().size_hint().exact(),
937                },
938                Err(_) => response.body().size_hint().exact(),
939              },
940              None => response.body().size_hint().exact(),
941            },
942            log_referrer,
943            log_user_agent,
944          )
945          .await;
946        }
947        return Ok(response);
948      }
949    }
950  };
951
952  let cloned_logger = logger.clone();
953  let error_logger = match error_log_enabled {
954    true => ErrorLogger::new(cloned_logger),
955    false => ErrorLogger::without_logger(),
956  };
957
958  if is_connect_proxy_request {
959    let mut connect_proxy_handlers = None;
960    for mut handlers in handlers_vec {
961      if handlers.does_connect_proxy_requests() {
962        connect_proxy_handlers = Some(handlers);
963        break;
964      }
965    }
966
967    if let Some(mut connect_proxy_handlers) = connect_proxy_handlers {
968      if let Some(connect_address) = request.uri().authority().map(|auth| auth.to_string()) {
969        // Variables moved to before "tokio::spawn" to avoid issues with moved values
970        let client_ip = socket_data.remote_addr.ip();
971        let custom_headers_yaml = combined_config["customHeaders"].clone();
972
973        tokio::spawn(async move {
974          match hyper::upgrade::on(request).await {
975            Ok(upgraded_request) => {
976              let result = connect_proxy_handlers
977                .connect_proxy_request_handler(
978                  upgraded_request,
979                  &connect_address,
980                  &combined_config,
981                  &socket_data,
982                  &error_logger,
983                )
984                .await;
985              match result {
986                Ok(_) => (),
987                Err(err) => {
988                  error_logger
989                    .log(&format!("Unexpected error for CONNECT request: {}", err))
990                    .await;
991                }
992              }
993            }
994            Err(err) => {
995              error_logger
996                .log(&format!(
997                  "Error while upgrading HTTP CONNECT request: {}",
998                  err
999                ))
1000                .await
1001            }
1002          }
1003        });
1004
1005        let response = Response::builder()
1006          .body(Empty::new().map_err(|e| match e {}).boxed())
1007          .unwrap_or_default();
1008
1009        if log_enabled {
1010          log_combined(
1011            &logger,
1012            client_ip,
1013            None,
1014            log_method,
1015            log_request_path,
1016            log_protocol,
1017            response.status().as_u16(),
1018            match response.headers().get(header::CONTENT_LENGTH) {
1019              Some(header_value) => match header_value.to_str() {
1020                Ok(header_value) => match header_value.parse::<u64>() {
1021                  Ok(content_length) => Some(content_length),
1022                  Err(_) => response.body().size_hint().exact(),
1023                },
1024                Err(_) => response.body().size_hint().exact(),
1025              },
1026              None => response.body().size_hint().exact(),
1027            },
1028            log_referrer,
1029            log_user_agent,
1030          )
1031          .await;
1032        }
1033
1034        let (mut response_parts, response_body) = response.into_parts();
1035        if let Some(custom_headers_hash) = custom_headers_yaml.as_hash() {
1036          let custom_headers_hash_iter = custom_headers_hash.iter();
1037          for (header_name, header_value) in custom_headers_hash_iter {
1038            if let Some(header_name) = header_name.as_str() {
1039              if let Some(header_value) = header_value.as_str() {
1040                if !response_parts.headers.contains_key(header_name) {
1041                  if let Ok(header_value) =
1042                    HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1043                  {
1044                    if let Ok(header_name) = HeaderName::from_str(header_name) {
1045                      response_parts.headers.insert(header_name, header_value);
1046                    }
1047                  }
1048                }
1049              }
1050            }
1051          }
1052        }
1053        if let Some(http3_alt_port) = http3_alt_port {
1054          if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1055            Some(value) => HeaderValue::from_bytes(
1056              format!(
1057                "{}, h3=\":{}\", h3-29=\":{}\"",
1058                String::from_utf8_lossy(value.as_bytes()),
1059                http3_alt_port,
1060                http3_alt_port
1061              )
1062              .as_bytes(),
1063            ),
1064            None => HeaderValue::from_bytes(
1065              format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1066            ),
1067          } {
1068            response_parts.headers.insert(header::ALT_SVC, header_value);
1069          }
1070        }
1071        response_parts
1072          .headers
1073          .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1074
1075        Ok(Response::from_parts(response_parts, response_body))
1076      } else {
1077        let response = Response::builder()
1078          .status(StatusCode::BAD_REQUEST)
1079          .body(Empty::new().map_err(|e| match e {}).boxed())
1080          .unwrap_or_default();
1081
1082        if log_enabled {
1083          log_combined(
1084            &logger,
1085            socket_data.remote_addr.ip(),
1086            None,
1087            log_method,
1088            log_request_path,
1089            log_protocol,
1090            response.status().as_u16(),
1091            match response.headers().get(header::CONTENT_LENGTH) {
1092              Some(header_value) => match header_value.to_str() {
1093                Ok(header_value) => match header_value.parse::<u64>() {
1094                  Ok(content_length) => Some(content_length),
1095                  Err(_) => response.body().size_hint().exact(),
1096                },
1097                Err(_) => response.body().size_hint().exact(),
1098              },
1099              None => response.body().size_hint().exact(),
1100            },
1101            log_referrer,
1102            log_user_agent,
1103          )
1104          .await;
1105        }
1106        let (mut response_parts, response_body) = response.into_parts();
1107        if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1108          let custom_headers_hash_iter = custom_headers_hash.iter();
1109          for (header_name, header_value) in custom_headers_hash_iter {
1110            if let Some(header_name) = header_name.as_str() {
1111              if let Some(header_value) = header_value.as_str() {
1112                if !response_parts.headers.contains_key(header_name) {
1113                  if let Ok(header_value) =
1114                    HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1115                  {
1116                    if let Ok(header_name) = HeaderName::from_str(header_name) {
1117                      response_parts.headers.insert(header_name, header_value);
1118                    }
1119                  }
1120                }
1121              }
1122            }
1123          }
1124        }
1125        if let Some(http3_alt_port) = http3_alt_port {
1126          if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1127            Some(value) => HeaderValue::from_bytes(
1128              format!(
1129                "{}, h3=\":{}\", h3-29=\":{}\"",
1130                String::from_utf8_lossy(value.as_bytes()),
1131                http3_alt_port,
1132                http3_alt_port
1133              )
1134              .as_bytes(),
1135            ),
1136            None => HeaderValue::from_bytes(
1137              format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1138            ),
1139          } {
1140            response_parts.headers.insert(header::ALT_SVC, header_value);
1141          }
1142        }
1143        response_parts
1144          .headers
1145          .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1146
1147        Ok(Response::from_parts(response_parts, response_body))
1148      }
1149    } else {
1150      let response = Response::builder()
1151        .status(StatusCode::NOT_IMPLEMENTED)
1152        .body(Empty::new().map_err(|e| match e {}).boxed())
1153        .unwrap_or_default();
1154
1155      if log_enabled {
1156        log_combined(
1157          &logger,
1158          socket_data.remote_addr.ip(),
1159          None,
1160          log_method,
1161          log_request_path,
1162          log_protocol,
1163          response.status().as_u16(),
1164          match response.headers().get(header::CONTENT_LENGTH) {
1165            Some(header_value) => match header_value.to_str() {
1166              Ok(header_value) => match header_value.parse::<u64>() {
1167                Ok(content_length) => Some(content_length),
1168                Err(_) => response.body().size_hint().exact(),
1169              },
1170              Err(_) => response.body().size_hint().exact(),
1171            },
1172            None => response.body().size_hint().exact(),
1173          },
1174          log_referrer,
1175          log_user_agent,
1176        )
1177        .await;
1178      }
1179      let (mut response_parts, response_body) = response.into_parts();
1180      if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1181        let custom_headers_hash_iter = custom_headers_hash.iter();
1182        for (header_name, header_value) in custom_headers_hash_iter {
1183          if let Some(header_name) = header_name.as_str() {
1184            if let Some(header_value) = header_value.as_str() {
1185              if !response_parts.headers.contains_key(header_name) {
1186                if let Ok(header_value) =
1187                  HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1188                {
1189                  if let Ok(header_name) = HeaderName::from_str(header_name) {
1190                    response_parts.headers.insert(header_name, header_value);
1191                  }
1192                }
1193              }
1194            }
1195          }
1196        }
1197      }
1198      if let Some(http3_alt_port) = http3_alt_port {
1199        if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1200          Some(value) => HeaderValue::from_bytes(
1201            format!(
1202              "{}, h3=\":{}\", h3-29=\":{}\"",
1203              String::from_utf8_lossy(value.as_bytes()),
1204              http3_alt_port,
1205              http3_alt_port
1206            )
1207            .as_bytes(),
1208          ),
1209          None => HeaderValue::from_bytes(
1210            format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1211          ),
1212        } {
1213          response_parts.headers.insert(header::ALT_SVC, header_value);
1214        }
1215      }
1216      response_parts
1217        .headers
1218        .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1219
1220      Ok(Response::from_parts(response_parts, response_body))
1221    }
1222  } else {
1223    let is_websocket_request = is_upgrade_request(&request);
1224    let mut request_data = RequestData::new(request, None, None);
1225    let mut latest_auth_data = None;
1226    let mut executed_handlers = Vec::new();
1227    for mut handlers in handlers_vec {
1228      if is_websocket_request && handlers.does_websocket_requests(&combined_config, &socket_data) {
1229        let (request, _, _) = request_data.into_parts();
1230
1231        // Variables moved to before "tokio::spawn" to avoid issues with moved values
1232        let client_ip = socket_data.remote_addr.ip();
1233        let custom_headers_yaml = combined_config["customHeaders"].clone();
1234        let request_uri = request.uri().to_owned();
1235
1236        let (original_response, websocket) = match hyper_tungstenite::upgrade(request, None) {
1237          Ok(data) => data,
1238          Err(err) => {
1239            error_logger
1240              .log(&format!("Error while upgrading WebSocket request: {}", err))
1241              .await;
1242            let response = Response::builder()
1243              .status(StatusCode::INTERNAL_SERVER_ERROR)
1244              .body(
1245                Full::new(Bytes::from(generate_default_error_page(
1246                  StatusCode::INTERNAL_SERVER_ERROR,
1247                  None,
1248                )))
1249                .map_err(|e| match e {})
1250                .boxed(),
1251              )
1252              .unwrap_or_default();
1253
1254            if log_enabled {
1255              log_combined(
1256                &logger,
1257                socket_data.remote_addr.ip(),
1258                None,
1259                log_method,
1260                log_request_path,
1261                log_protocol,
1262                response.status().as_u16(),
1263                match response.headers().get(header::CONTENT_LENGTH) {
1264                  Some(header_value) => match header_value.to_str() {
1265                    Ok(header_value) => match header_value.parse::<u64>() {
1266                      Ok(content_length) => Some(content_length),
1267                      Err(_) => response.body().size_hint().exact(),
1268                    },
1269                    Err(_) => response.body().size_hint().exact(),
1270                  },
1271                  None => response.body().size_hint().exact(),
1272                },
1273                log_referrer,
1274                log_user_agent,
1275              )
1276              .await;
1277            }
1278            let (mut response_parts, response_body) = response.into_parts();
1279            if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1280              let custom_headers_hash_iter = custom_headers_hash.iter();
1281              for (header_name, header_value) in custom_headers_hash_iter {
1282                if let Some(header_name) = header_name.as_str() {
1283                  if let Some(header_value) = header_value.as_str() {
1284                    if !response_parts.headers.contains_key(header_name) {
1285                      if let Ok(header_value) = HeaderValue::from_str(
1286                        &header_value.replace("{path}", &sanitized_url_pathname),
1287                      ) {
1288                        if let Ok(header_name) = HeaderName::from_str(header_name) {
1289                          response_parts.headers.insert(header_name, header_value);
1290                        }
1291                      }
1292                    }
1293                  }
1294                }
1295              }
1296            }
1297            if let Some(http3_alt_port) = http3_alt_port {
1298              if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1299                Some(value) => HeaderValue::from_bytes(
1300                  format!(
1301                    "{}, h3=\":{}\", h3-29=\":{}\"",
1302                    String::from_utf8_lossy(value.as_bytes()),
1303                    http3_alt_port,
1304                    http3_alt_port
1305                  )
1306                  .as_bytes(),
1307                ),
1308                None => HeaderValue::from_bytes(
1309                  format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1310                ),
1311              } {
1312                response_parts.headers.insert(header::ALT_SVC, header_value);
1313              }
1314            }
1315            response_parts
1316              .headers
1317              .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1318
1319            return Ok(Response::from_parts(response_parts, response_body));
1320          }
1321        };
1322
1323        tokio::spawn(async move {
1324          let result = handlers
1325            .websocket_request_handler(
1326              websocket,
1327              &request_uri,
1328              &combined_config,
1329              &socket_data,
1330              &error_logger,
1331            )
1332            .await;
1333          match result {
1334            Ok(_) => (),
1335            Err(err) => {
1336              error_logger
1337                .log(&format!("Unexpected error for WebSocket request: {}", err))
1338                .await;
1339            }
1340          }
1341        });
1342
1343        let response = original_response.map(|body| body.map_err(|err| match err {}).boxed());
1344
1345        if log_enabled {
1346          log_combined(
1347            &logger,
1348            client_ip,
1349            None,
1350            log_method,
1351            log_request_path,
1352            log_protocol,
1353            response.status().as_u16(),
1354            match response.headers().get(header::CONTENT_LENGTH) {
1355              Some(header_value) => match header_value.to_str() {
1356                Ok(header_value) => match header_value.parse::<u64>() {
1357                  Ok(content_length) => Some(content_length),
1358                  Err(_) => response.body().size_hint().exact(),
1359                },
1360                Err(_) => response.body().size_hint().exact(),
1361              },
1362              None => response.body().size_hint().exact(),
1363            },
1364            log_referrer,
1365            log_user_agent,
1366          )
1367          .await;
1368        }
1369
1370        let (mut response_parts, response_body) = response.into_parts();
1371        if let Some(custom_headers_hash) = custom_headers_yaml.as_hash() {
1372          let custom_headers_hash_iter = custom_headers_hash.iter();
1373          for (header_name, header_value) in custom_headers_hash_iter {
1374            if let Some(header_name) = header_name.as_str() {
1375              if let Some(header_value) = header_value.as_str() {
1376                if !response_parts.headers.contains_key(header_name) {
1377                  if let Ok(header_value) =
1378                    HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
1379                  {
1380                    if let Ok(header_name) = HeaderName::from_str(header_name) {
1381                      response_parts.headers.insert(header_name, header_value);
1382                    }
1383                  }
1384                }
1385              }
1386            }
1387          }
1388        }
1389        if let Some(http3_alt_port) = http3_alt_port {
1390          if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1391            Some(value) => HeaderValue::from_bytes(
1392              format!(
1393                "{}, h3=\":{}\", h3-29=\":{}\"",
1394                String::from_utf8_lossy(value.as_bytes()),
1395                http3_alt_port,
1396                http3_alt_port
1397              )
1398              .as_bytes(),
1399            ),
1400            None => HeaderValue::from_bytes(
1401              format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1402            ),
1403          } {
1404            response_parts.headers.insert(header::ALT_SVC, header_value);
1405          }
1406        }
1407        response_parts
1408          .headers
1409          .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1410
1411        return Ok(Response::from_parts(response_parts, response_body));
1412      }
1413
1414      let response_result = match is_proxy_request {
1415        true => {
1416          handlers
1417            .proxy_request_handler(request_data, &combined_config, &socket_data, &error_logger)
1418            .await
1419        }
1420        false => {
1421          handlers
1422            .request_handler(request_data, &combined_config, &socket_data, &error_logger)
1423            .await
1424        }
1425      };
1426
1427      executed_handlers.push(handlers);
1428      match response_result {
1429        Ok(response) => {
1430          let (
1431            request_option,
1432            auth_data,
1433            original_url,
1434            response,
1435            status,
1436            headers,
1437            new_remote_address,
1438            parallel_fn,
1439          ) = response.into_parts();
1440          latest_auth_data = auth_data.clone();
1441          if let Some(new_remote_address) = new_remote_address {
1442            socket_data.remote_addr = new_remote_address;
1443          };
1444          if let Some(parallel_fn) = parallel_fn {
1445            // Spawn the function in the web server's Tokio runtime.
1446            // We have implemented parallel_fn parameter in the ResponseData
1447            // because tokio::spawn doesn't work on dynamic libraries,
1448            // see https://github.com/tokio-rs/tokio/issues/6927
1449            tokio::spawn(parallel_fn);
1450          }
1451          match response {
1452            Some(response) => {
1453              let (mut response_parts, response_body) = response.into_parts();
1454              if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1455                let custom_headers_hash_iter = custom_headers_hash.iter();
1456                for (header_name, header_value) in custom_headers_hash_iter {
1457                  if let Some(header_name) = header_name.as_str() {
1458                    if let Some(header_value) = header_value.as_str() {
1459                      if !response_parts.headers.contains_key(header_name) {
1460                        if let Ok(header_value) = HeaderValue::from_str(
1461                          &header_value.replace("{path}", &sanitized_url_pathname),
1462                        ) {
1463                          if let Ok(header_name) = HeaderName::from_str(header_name) {
1464                            response_parts.headers.insert(header_name, header_value);
1465                          }
1466                        }
1467                      }
1468                    }
1469                  }
1470                }
1471              }
1472              if let Some(http3_alt_port) = http3_alt_port {
1473                if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1474                  Some(value) => HeaderValue::from_bytes(
1475                    format!(
1476                      "{}, h3=\":{}\", h3-29=\":{}\"",
1477                      String::from_utf8_lossy(value.as_bytes()),
1478                      http3_alt_port,
1479                      http3_alt_port
1480                    )
1481                    .as_bytes(),
1482                  ),
1483                  None => HeaderValue::from_bytes(
1484                    format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1485                  ),
1486                } {
1487                  response_parts.headers.insert(header::ALT_SVC, header_value);
1488                }
1489              }
1490              response_parts
1491                .headers
1492                .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1493
1494              let mut response = Response::from_parts(response_parts, response_body);
1495
1496              while let Some(mut executed_handler) = executed_handlers.pop() {
1497                let response_status = match is_proxy_request {
1498                  true => {
1499                    executed_handler
1500                      .proxy_response_modifying_handler(response)
1501                      .await
1502                  }
1503                  false => executed_handler.response_modifying_handler(response).await,
1504                };
1505                response = match response_status {
1506                  Ok(response) => response,
1507                  Err(err) => {
1508                    if error_log_enabled {
1509                      logger
1510                        .send(LogMessage::new(
1511                          format!("Unexpected error while serving a request: {}", err),
1512                          true,
1513                        ))
1514                        .await
1515                        .unwrap_or_default();
1516                    }
1517
1518                    let response = generate_error_response(
1519                      StatusCode::INTERNAL_SERVER_ERROR,
1520                      &combined_config,
1521                      &headers,
1522                    )
1523                    .await;
1524                    if log_enabled {
1525                      log_combined(
1526                        &logger,
1527                        socket_data.remote_addr.ip(),
1528                        auth_data,
1529                        log_method,
1530                        log_request_path,
1531                        log_protocol,
1532                        response.status().as_u16(),
1533                        match response.headers().get(header::CONTENT_LENGTH) {
1534                          Some(header_value) => match header_value.to_str() {
1535                            Ok(header_value) => match header_value.parse::<u64>() {
1536                              Ok(content_length) => Some(content_length),
1537                              Err(_) => response.body().size_hint().exact(),
1538                            },
1539                            Err(_) => response.body().size_hint().exact(),
1540                          },
1541                          None => response.body().size_hint().exact(),
1542                        },
1543                        log_referrer,
1544                        log_user_agent,
1545                      )
1546                      .await;
1547                    }
1548                    let (mut response_parts, response_body) = response.into_parts();
1549                    if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1550                      let custom_headers_hash_iter = custom_headers_hash.iter();
1551                      for (header_name, header_value) in custom_headers_hash_iter {
1552                        if let Some(header_name) = header_name.as_str() {
1553                          if let Some(header_value) = header_value.as_str() {
1554                            if !response_parts.headers.contains_key(header_name) {
1555                              if let Ok(header_value) = HeaderValue::from_str(
1556                                &header_value.replace("{path}", &sanitized_url_pathname),
1557                              ) {
1558                                if let Ok(header_name) = HeaderName::from_str(header_name) {
1559                                  response_parts.headers.insert(header_name, header_value);
1560                                }
1561                              }
1562                            }
1563                          }
1564                        }
1565                      }
1566                    }
1567                    if let Some(http3_alt_port) = http3_alt_port {
1568                      if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1569                        Some(value) => HeaderValue::from_bytes(
1570                          format!(
1571                            "{}, h3=\":{}\", h3-29=\":{}\"",
1572                            String::from_utf8_lossy(value.as_bytes()),
1573                            http3_alt_port,
1574                            http3_alt_port
1575                          )
1576                          .as_bytes(),
1577                        ),
1578                        None => HeaderValue::from_bytes(
1579                          format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1580                            .as_bytes(),
1581                        ),
1582                      } {
1583                        response_parts.headers.insert(header::ALT_SVC, header_value);
1584                      }
1585                    }
1586                    response_parts
1587                      .headers
1588                      .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1589
1590                    return Ok(Response::from_parts(response_parts, response_body));
1591                  }
1592                };
1593              }
1594
1595              if log_enabled {
1596                log_combined(
1597                  &logger,
1598                  socket_data.remote_addr.ip(),
1599                  auth_data,
1600                  log_method,
1601                  log_request_path,
1602                  log_protocol,
1603                  response.status().as_u16(),
1604                  match response.headers().get(header::CONTENT_LENGTH) {
1605                    Some(header_value) => match header_value.to_str() {
1606                      Ok(header_value) => match header_value.parse::<u64>() {
1607                        Ok(content_length) => Some(content_length),
1608                        Err(_) => response.body().size_hint().exact(),
1609                      },
1610                      Err(_) => response.body().size_hint().exact(),
1611                    },
1612                    None => response.body().size_hint().exact(),
1613                  },
1614                  log_referrer,
1615                  log_user_agent,
1616                )
1617                .await;
1618              }
1619
1620              return Ok(response);
1621            }
1622            None => match status {
1623              Some(status) => {
1624                let response = generate_error_response(status, &combined_config, &headers).await;
1625                let (mut response_parts, response_body) = response.into_parts();
1626                if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1627                  let custom_headers_hash_iter = custom_headers_hash.iter();
1628                  for (header_name, header_value) in custom_headers_hash_iter {
1629                    if let Some(header_name) = header_name.as_str() {
1630                      if let Some(header_value) = header_value.as_str() {
1631                        if !response_parts.headers.contains_key(header_name) {
1632                          if let Ok(header_value) = HeaderValue::from_str(
1633                            &header_value.replace("{path}", &sanitized_url_pathname),
1634                          ) {
1635                            if let Ok(header_name) = HeaderName::from_str(header_name) {
1636                              response_parts.headers.insert(header_name, header_value);
1637                            }
1638                          }
1639                        }
1640                      }
1641                    }
1642                  }
1643                }
1644                if let Some(http3_alt_port) = http3_alt_port {
1645                  if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1646                    Some(value) => HeaderValue::from_bytes(
1647                      format!(
1648                        "{}, h3=\":{}\", h3-29=\":{}\"",
1649                        String::from_utf8_lossy(value.as_bytes()),
1650                        http3_alt_port,
1651                        http3_alt_port
1652                      )
1653                      .as_bytes(),
1654                    ),
1655                    None => HeaderValue::from_bytes(
1656                      format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1657                        .as_bytes(),
1658                    ),
1659                  } {
1660                    response_parts.headers.insert(header::ALT_SVC, header_value);
1661                  }
1662                }
1663                response_parts
1664                  .headers
1665                  .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1666
1667                let mut response = Response::from_parts(response_parts, response_body);
1668
1669                while let Some(mut executed_handler) = executed_handlers.pop() {
1670                  let response_status = match is_proxy_request {
1671                    true => {
1672                      executed_handler
1673                        .proxy_response_modifying_handler(response)
1674                        .await
1675                    }
1676                    false => executed_handler.response_modifying_handler(response).await,
1677                  };
1678                  response = match response_status {
1679                    Ok(response) => response,
1680                    Err(err) => {
1681                      if error_log_enabled {
1682                        logger
1683                          .send(LogMessage::new(
1684                            format!("Unexpected error while serving a request: {}", err),
1685                            true,
1686                          ))
1687                          .await
1688                          .unwrap_or_default();
1689                      }
1690
1691                      let response = generate_error_response(
1692                        StatusCode::INTERNAL_SERVER_ERROR,
1693                        &combined_config,
1694                        &headers,
1695                      )
1696                      .await;
1697                      if log_enabled {
1698                        log_combined(
1699                          &logger,
1700                          socket_data.remote_addr.ip(),
1701                          auth_data,
1702                          log_method,
1703                          log_request_path,
1704                          log_protocol,
1705                          response.status().as_u16(),
1706                          match response.headers().get(header::CONTENT_LENGTH) {
1707                            Some(header_value) => match header_value.to_str() {
1708                              Ok(header_value) => match header_value.parse::<u64>() {
1709                                Ok(content_length) => Some(content_length),
1710                                Err(_) => response.body().size_hint().exact(),
1711                              },
1712                              Err(_) => response.body().size_hint().exact(),
1713                            },
1714                            None => response.body().size_hint().exact(),
1715                          },
1716                          log_referrer,
1717                          log_user_agent,
1718                        )
1719                        .await;
1720                      }
1721                      let (mut response_parts, response_body) = response.into_parts();
1722                      if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash()
1723                      {
1724                        let custom_headers_hash_iter = custom_headers_hash.iter();
1725                        for (header_name, header_value) in custom_headers_hash_iter {
1726                          if let Some(header_name) = header_name.as_str() {
1727                            if let Some(header_value) = header_value.as_str() {
1728                              if !response_parts.headers.contains_key(header_name) {
1729                                if let Ok(header_value) = HeaderValue::from_str(
1730                                  &header_value.replace("{path}", &sanitized_url_pathname),
1731                                ) {
1732                                  if let Ok(header_name) = HeaderName::from_str(header_name) {
1733                                    response_parts.headers.insert(header_name, header_value);
1734                                  }
1735                                }
1736                              }
1737                            }
1738                          }
1739                        }
1740                      }
1741                      if let Some(http3_alt_port) = http3_alt_port {
1742                        if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC)
1743                        {
1744                          Some(value) => HeaderValue::from_bytes(
1745                            format!(
1746                              "{}, h3=\":{}\", h3-29=\":{}\"",
1747                              String::from_utf8_lossy(value.as_bytes()),
1748                              http3_alt_port,
1749                              http3_alt_port
1750                            )
1751                            .as_bytes(),
1752                          ),
1753                          None => HeaderValue::from_bytes(
1754                            format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1755                              .as_bytes(),
1756                          ),
1757                        } {
1758                          response_parts.headers.insert(header::ALT_SVC, header_value);
1759                        }
1760                      }
1761                      response_parts
1762                        .headers
1763                        .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1764
1765                      return Ok(Response::from_parts(response_parts, response_body));
1766                    }
1767                  };
1768                }
1769
1770                if log_enabled {
1771                  log_combined(
1772                    &logger,
1773                    socket_data.remote_addr.ip(),
1774                    auth_data,
1775                    log_method,
1776                    log_request_path,
1777                    log_protocol,
1778                    response.status().as_u16(),
1779                    match response.headers().get(header::CONTENT_LENGTH) {
1780                      Some(header_value) => match header_value.to_str() {
1781                        Ok(header_value) => match header_value.parse::<u64>() {
1782                          Ok(content_length) => Some(content_length),
1783                          Err(_) => response.body().size_hint().exact(),
1784                        },
1785                        Err(_) => response.body().size_hint().exact(),
1786                      },
1787                      None => response.body().size_hint().exact(),
1788                    },
1789                    log_referrer,
1790                    log_user_agent,
1791                  )
1792                  .await;
1793                }
1794                return Ok(response);
1795              }
1796              None => match request_option {
1797                Some(request) => {
1798                  request_data = RequestData::new(request, auth_data, original_url);
1799                  continue;
1800                }
1801                None => {
1802                  break;
1803                }
1804              },
1805            },
1806          }
1807        }
1808        Err(err) => {
1809          let response =
1810            generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &combined_config, &None)
1811              .await;
1812
1813          let (mut response_parts, response_body) = response.into_parts();
1814          if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1815            let custom_headers_hash_iter = custom_headers_hash.iter();
1816            for (header_name, header_value) in custom_headers_hash_iter {
1817              if let Some(header_name) = header_name.as_str() {
1818                if let Some(header_value) = header_value.as_str() {
1819                  if !response_parts.headers.contains_key(header_name) {
1820                    if let Ok(header_value) = HeaderValue::from_str(
1821                      &header_value.replace("{path}", &sanitized_url_pathname),
1822                    ) {
1823                      if let Ok(header_name) = HeaderName::from_str(header_name) {
1824                        response_parts.headers.insert(header_name, header_value);
1825                      }
1826                    }
1827                  }
1828                }
1829              }
1830            }
1831          }
1832          if let Some(http3_alt_port) = http3_alt_port {
1833            if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1834              Some(value) => HeaderValue::from_bytes(
1835                format!(
1836                  "{}, h3=\":{}\", h3-29=\":{}\"",
1837                  String::from_utf8_lossy(value.as_bytes()),
1838                  http3_alt_port,
1839                  http3_alt_port
1840                )
1841                .as_bytes(),
1842              ),
1843              None => HeaderValue::from_bytes(
1844                format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
1845              ),
1846            } {
1847              response_parts.headers.insert(header::ALT_SVC, header_value);
1848            }
1849          }
1850          response_parts
1851            .headers
1852            .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1853
1854          let mut response = Response::from_parts(response_parts, response_body);
1855
1856          while let Some(mut executed_handler) = executed_handlers.pop() {
1857            let response_status = match is_proxy_request {
1858              true => {
1859                executed_handler
1860                  .proxy_response_modifying_handler(response)
1861                  .await
1862              }
1863              false => executed_handler.response_modifying_handler(response).await,
1864            };
1865            response = match response_status {
1866              Ok(response) => response,
1867              Err(err) => {
1868                if error_log_enabled {
1869                  logger
1870                    .send(LogMessage::new(
1871                      format!("Unexpected error while serving a request: {}", err),
1872                      true,
1873                    ))
1874                    .await
1875                    .unwrap_or_default();
1876                }
1877
1878                let response = generate_error_response(
1879                  StatusCode::INTERNAL_SERVER_ERROR,
1880                  &combined_config,
1881                  &None,
1882                )
1883                .await;
1884                if log_enabled {
1885                  log_combined(
1886                    &logger,
1887                    socket_data.remote_addr.ip(),
1888                    latest_auth_data,
1889                    log_method,
1890                    log_request_path,
1891                    log_protocol,
1892                    response.status().as_u16(),
1893                    match response.headers().get(header::CONTENT_LENGTH) {
1894                      Some(header_value) => match header_value.to_str() {
1895                        Ok(header_value) => match header_value.parse::<u64>() {
1896                          Ok(content_length) => Some(content_length),
1897                          Err(_) => response.body().size_hint().exact(),
1898                        },
1899                        Err(_) => response.body().size_hint().exact(),
1900                      },
1901                      None => response.body().size_hint().exact(),
1902                    },
1903                    log_referrer,
1904                    log_user_agent,
1905                  )
1906                  .await;
1907                }
1908                let (mut response_parts, response_body) = response.into_parts();
1909                if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1910                  let custom_headers_hash_iter = custom_headers_hash.iter();
1911                  for (header_name, header_value) in custom_headers_hash_iter {
1912                    if let Some(header_name) = header_name.as_str() {
1913                      if let Some(header_value) = header_value.as_str() {
1914                        if !response_parts.headers.contains_key(header_name) {
1915                          if let Ok(header_value) = HeaderValue::from_str(
1916                            &header_value.replace("{path}", &sanitized_url_pathname),
1917                          ) {
1918                            if let Ok(header_name) = HeaderName::from_str(header_name) {
1919                              response_parts.headers.insert(header_name, header_value);
1920                            }
1921                          }
1922                        }
1923                      }
1924                    }
1925                  }
1926                }
1927                if let Some(http3_alt_port) = http3_alt_port {
1928                  if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
1929                    Some(value) => HeaderValue::from_bytes(
1930                      format!(
1931                        "{}, h3=\":{}\", h3-29=\":{}\"",
1932                        String::from_utf8_lossy(value.as_bytes()),
1933                        http3_alt_port,
1934                        http3_alt_port
1935                      )
1936                      .as_bytes(),
1937                    ),
1938                    None => HeaderValue::from_bytes(
1939                      format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port)
1940                        .as_bytes(),
1941                    ),
1942                  } {
1943                    response_parts.headers.insert(header::ALT_SVC, header_value);
1944                  }
1945                }
1946                response_parts
1947                  .headers
1948                  .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
1949
1950                return Ok(Response::from_parts(response_parts, response_body));
1951              }
1952            };
1953          }
1954
1955          if error_log_enabled {
1956            logger
1957              .send(LogMessage::new(
1958                format!("Unexpected error while serving a request: {}", err),
1959                true,
1960              ))
1961              .await
1962              .unwrap_or_default();
1963          }
1964
1965          if log_enabled {
1966            log_combined(
1967              &logger,
1968              socket_data.remote_addr.ip(),
1969              latest_auth_data,
1970              log_method,
1971              log_request_path,
1972              log_protocol,
1973              response.status().as_u16(),
1974              match response.headers().get(header::CONTENT_LENGTH) {
1975                Some(header_value) => match header_value.to_str() {
1976                  Ok(header_value) => match header_value.parse::<u64>() {
1977                    Ok(content_length) => Some(content_length),
1978                    Err(_) => response.body().size_hint().exact(),
1979                  },
1980                  Err(_) => response.body().size_hint().exact(),
1981                },
1982                None => response.body().size_hint().exact(),
1983              },
1984              log_referrer,
1985              log_user_agent,
1986            )
1987            .await;
1988          }
1989          return Ok(response);
1990        }
1991      }
1992    }
1993
1994    let response = generate_error_response(StatusCode::NOT_FOUND, &combined_config, &None).await;
1995
1996    let (mut response_parts, response_body) = response.into_parts();
1997    if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
1998      let custom_headers_hash_iter = custom_headers_hash.iter();
1999      for (header_name, header_value) in custom_headers_hash_iter {
2000        if let Some(header_name) = header_name.as_str() {
2001          if let Some(header_value) = header_value.as_str() {
2002            if !response_parts.headers.contains_key(header_name) {
2003              if let Ok(header_value) =
2004                HeaderValue::from_str(&header_value.replace("{path}", &sanitized_url_pathname))
2005              {
2006                if let Ok(header_name) = HeaderName::from_str(header_name) {
2007                  response_parts.headers.insert(header_name, header_value);
2008                }
2009              }
2010            }
2011          }
2012        }
2013      }
2014    }
2015    if let Some(http3_alt_port) = http3_alt_port {
2016      if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2017        Some(value) => HeaderValue::from_bytes(
2018          format!(
2019            "{}, h3=\":{}\", h3-29=\":{}\"",
2020            String::from_utf8_lossy(value.as_bytes()),
2021            http3_alt_port,
2022            http3_alt_port
2023          )
2024          .as_bytes(),
2025        ),
2026        None => HeaderValue::from_bytes(
2027          format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
2028        ),
2029      } {
2030        response_parts.headers.insert(header::ALT_SVC, header_value);
2031      }
2032    }
2033    response_parts
2034      .headers
2035      .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2036
2037    let mut response = Response::from_parts(response_parts, response_body);
2038
2039    while let Some(mut executed_handler) = executed_handlers.pop() {
2040      let response_status = match is_proxy_request {
2041        true => {
2042          executed_handler
2043            .proxy_response_modifying_handler(response)
2044            .await
2045        }
2046        false => executed_handler.response_modifying_handler(response).await,
2047      };
2048      response = match response_status {
2049        Ok(response) => response,
2050        Err(err) => {
2051          if error_log_enabled {
2052            logger
2053              .send(LogMessage::new(
2054                format!("Unexpected error while serving a request: {}", err),
2055                true,
2056              ))
2057              .await
2058              .unwrap_or_default();
2059          }
2060
2061          let response =
2062            generate_error_response(StatusCode::INTERNAL_SERVER_ERROR, &combined_config, &None)
2063              .await;
2064          if log_enabled {
2065            log_combined(
2066              &logger,
2067              socket_data.remote_addr.ip(),
2068              latest_auth_data,
2069              log_method,
2070              log_request_path,
2071              log_protocol,
2072              response.status().as_u16(),
2073              match response.headers().get(header::CONTENT_LENGTH) {
2074                Some(header_value) => match header_value.to_str() {
2075                  Ok(header_value) => match header_value.parse::<u64>() {
2076                    Ok(content_length) => Some(content_length),
2077                    Err(_) => response.body().size_hint().exact(),
2078                  },
2079                  Err(_) => response.body().size_hint().exact(),
2080                },
2081                None => response.body().size_hint().exact(),
2082              },
2083              log_referrer,
2084              log_user_agent,
2085            )
2086            .await;
2087          }
2088          let (mut response_parts, response_body) = response.into_parts();
2089          if let Some(custom_headers_hash) = combined_config["customHeaders"].as_hash() {
2090            let custom_headers_hash_iter = custom_headers_hash.iter();
2091            for (header_name, header_value) in custom_headers_hash_iter {
2092              if let Some(header_name) = header_name.as_str() {
2093                if let Some(header_value) = header_value.as_str() {
2094                  if !response_parts.headers.contains_key(header_name) {
2095                    if let Ok(header_value) = HeaderValue::from_str(
2096                      &header_value.replace("{path}", &sanitized_url_pathname),
2097                    ) {
2098                      if let Ok(header_name) = HeaderName::from_str(header_name) {
2099                        response_parts.headers.insert(header_name, header_value);
2100                      }
2101                    }
2102                  }
2103                }
2104              }
2105            }
2106          }
2107          if let Some(http3_alt_port) = http3_alt_port {
2108            if let Ok(header_value) = match response_parts.headers.get(header::ALT_SVC) {
2109              Some(value) => HeaderValue::from_bytes(
2110                format!(
2111                  "{}, h3=\":{}\", h3-29=\":{}\"",
2112                  String::from_utf8_lossy(value.as_bytes()),
2113                  http3_alt_port,
2114                  http3_alt_port
2115                )
2116                .as_bytes(),
2117              ),
2118              None => HeaderValue::from_bytes(
2119                format!("h3=\":{}\", h3-29=\":{}\"", http3_alt_port, http3_alt_port).as_bytes(),
2120              ),
2121            } {
2122              response_parts.headers.insert(header::ALT_SVC, header_value);
2123            }
2124          }
2125          response_parts
2126            .headers
2127            .insert(header::SERVER, HeaderValue::from_static(SERVER_SOFTWARE));
2128
2129          return Ok(Response::from_parts(response_parts, response_body));
2130        }
2131      };
2132    }
2133
2134    if log_enabled {
2135      log_combined(
2136        &logger,
2137        socket_data.remote_addr.ip(),
2138        latest_auth_data,
2139        log_method,
2140        log_request_path,
2141        log_protocol,
2142        response.status().as_u16(),
2143        match response.headers().get(header::CONTENT_LENGTH) {
2144          Some(header_value) => match header_value.to_str() {
2145            Ok(header_value) => match header_value.parse::<u64>() {
2146              Ok(content_length) => Some(content_length),
2147              Err(_) => response.body().size_hint().exact(),
2148            },
2149            Err(_) => response.body().size_hint().exact(),
2150          },
2151          None => response.body().size_hint().exact(),
2152        },
2153        log_referrer,
2154        log_user_agent,
2155      )
2156      .await;
2157    }
2158    Ok(response)
2159  }
2160}
2161
2162#[allow(clippy::too_many_arguments)]
2163pub async fn request_handler(
2164  request: Request<BoxBody<Bytes, std::io::Error>>,
2165  remote_address: SocketAddr,
2166  local_address: SocketAddr,
2167  encrypted: bool,
2168  config: Arc<Yaml>,
2169  logger: Sender<LogMessage>,
2170  handlers_vec: Vec<Box<dyn ServerModuleHandlers + Send>>,
2171  acme_http01_resolver_option: Option<Arc<ResolvesServerCertAcme>>,
2172  http3_alt_port: Option<u16>,
2173) -> Result<Response<BoxBody<Bytes, std::io::Error>>, anyhow::Error> {
2174  let timeout_yaml = &config["global"]["timeout"];
2175  if timeout_yaml.is_null() {
2176    request_handler_wrapped(
2177      request,
2178      remote_address,
2179      local_address,
2180      encrypted,
2181      config,
2182      logger,
2183      handlers_vec,
2184      acme_http01_resolver_option,
2185      http3_alt_port,
2186    )
2187    .await
2188    .map_err(|e| anyhow::anyhow!(e))
2189  } else {
2190    let timeout_millis = timeout_yaml.as_i64().unwrap_or(300000) as u64;
2191    match timeout(
2192      Duration::from_millis(timeout_millis),
2193      request_handler_wrapped(
2194        request,
2195        remote_address,
2196        local_address,
2197        encrypted,
2198        config,
2199        logger,
2200        handlers_vec,
2201        acme_http01_resolver_option,
2202        http3_alt_port,
2203      ),
2204    )
2205    .await
2206    {
2207      Ok(response) => response.map_err(|e| anyhow::anyhow!(e)),
2208      Err(_) => Err(anyhow::anyhow!("The client or server has timed out")),
2209    }
2210  }
2211}