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