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